diff --git a/Makefile b/Makefile index d002ca767e9c..d324c7dba9e3 100644 --- a/Makefile +++ b/Makefile @@ -498,3 +498,11 @@ universe_epilogue: buildLINT: ${MAKE} -C ${.CURDIR}/sys/${_TARGET}/conf LINT + +.if defined(.PARSEDIR) +.if make(universe) +# we do not want a failure of one branch abort all. +MAKE_JOB_ERROR_TOKEN= no +.export MAKE_JOB_ERROR_TOKEN +.endif +.endif diff --git a/Makefile.inc1 b/Makefile.inc1 index 5185706a7bd4..bbb9d89b746b 100644 --- a/Makefile.inc1 +++ b/Makefile.inc1 @@ -382,6 +382,7 @@ LIB32WMAKEENV+= MAKEOBJDIRPREFIX=${OBJTREE}/lib32 \ PATH=${TMPPATH} \ LIBDIR=/usr/lib32 \ SHLIBDIR=/usr/lib32 \ + LIBPRIVATEDIR=/usr/lib32/private \ COMPILER_TYPE=${WMAKE_COMPILER_TYPE} LIB32WMAKEFLAGS+= \ CC="${XCC} ${LIB32FLAGS}" \ diff --git a/ObsoleteFiles.inc b/ObsoleteFiles.inc index 30ec49b844d0..e53fa87f8ad4 100644 --- a/ObsoleteFiles.inc +++ b/ObsoleteFiles.inc @@ -38,6 +38,9 @@ # xargs -n1 | sort | uniq -d; # done +# 20130908: libssh becomes private +OLD_LIBS+=usr/lib/libssh.so.5 +OLD_LIBS+=usr/lib32/libssh.so.5 # 20130903: gnupatch is no more OLD_FILES+=usr/bin/gnupatch OLD_FILES+=usr/share/man/man1/gnupatch.1.gz diff --git a/UPDATING b/UPDATING index aafbcf8d8f74..ae92e96b1c83 100644 --- a/UPDATING +++ b/UPDATING @@ -31,6 +31,31 @@ NOTE TO PEOPLE WHO THINK THAT FreeBSD 10.x IS SLOW: disable the most expensive debugging functionality run "ln -s 'abort:false,junk:false' /etc/malloc.conf".) +20130906: + The GNU Compiler Collection and C++ standard library (libstdc++) + are no longer built by default on platforms where clang is the system + compiler. You can enable them with the WITH_GCC and WITH_GNUCXX + options in src.conf. + +20130905: + The PROCDESC kernel option is now part of the GENERIC kernel + configuration and is required for the rwhod(8) to work. + If you are using custom kernel configuration, you should include + 'options PROCDESC'. + +20130905: + The API and ABI related to the Capsicum framework was modified + in backward incompatible way. The userland libraries and programs + have to be recompiled to work with the new kernel. This includes the + following libraries and programs, but the whole buildworld is + advised: libc, libprocstat, dhclient, tcpdump, hastd, hastctl, + kdump, procstat, rwho, rwhod, uniq. + +20130903: + AES-NI intrinsic support has been added to gcc. The AES-NI module + has been updated to use this support. A new gcc is required to build + the aesni module on both i386 and amd64. + 20130827: Thomas Dickey (vendor author thereof) reports that dialog(1) since 2011/10/18 has a bug in handling --hline. Testers and I noticed the diff --git a/bin/sh/eval.c b/bin/sh/eval.c index 655bf81306f9..b8f76d57f3d8 100644 --- a/bin/sh/eval.c +++ b/bin/sh/eval.c @@ -324,7 +324,7 @@ skipping: if (evalskip == SKIPCONT && --skipcount <= 0) { } if (evalskip == SKIPBREAK && --skipcount <= 0) evalskip = 0; - if (evalskip == SKIPFUNC || evalskip == SKIPFILE) + if (evalskip == SKIPRETURN) status = exitstatus; break; } @@ -1068,7 +1068,7 @@ evalcommand(union node *cmd, int flags, struct backcmd *backcmd) funcnest--; popredir(); INTON; - if (evalskip == SKIPFUNC) { + if (evalskip == SKIPRETURN) { evalskip = 0; skipcount = 0; } @@ -1305,14 +1305,8 @@ returncmd(int argc, char **argv) { int ret = argc > 1 ? number(argv[1]) : oexitstatus; - if (funcnest) { - evalskip = SKIPFUNC; - skipcount = 1; - } else { - /* skip the rest of the file */ - evalskip = SKIPFILE; - skipcount = 1; - } + evalskip = SKIPRETURN; + skipcount = 1; return ret; } diff --git a/bin/sh/eval.h b/bin/sh/eval.h index a6e87b237cb9..4129757e9f01 100644 --- a/bin/sh/eval.h +++ b/bin/sh/eval.h @@ -67,5 +67,4 @@ extern int skipcount; /* reasons for skipping commands (see comment on breakcmd routine) */ #define SKIPBREAK 1 #define SKIPCONT 2 -#define SKIPFUNC 3 -#define SKIPFILE 4 +#define SKIPRETURN 3 diff --git a/bin/sh/main.c b/bin/sh/main.c index 295f27708bd5..e4974ea7f455 100644 --- a/bin/sh/main.c +++ b/bin/sh/main.c @@ -231,7 +231,7 @@ cmdloop(int top) popstackmark(&smark); setstackmark(&smark); if (evalskip != 0) { - if (evalskip == SKIPFILE) + if (evalskip == SKIPRETURN) evalskip = 0; break; } diff --git a/bin/sh/sh.1 b/bin/sh/sh.1 index 174788ddc7cb..ea1d899ed8e1 100644 --- a/bin/sh/sh.1 +++ b/bin/sh/sh.1 @@ -1145,8 +1145,10 @@ command is .Pp .D1 Ic return Op Ar exitstatus .Pp -It terminates the current executional scope, returning from the previous -nested function, sourced script, or shell instance, in that order. +It terminates the current executional scope, returning from the closest +nested function or sourced script; +if no function or sourced script is being executed, +it exits the shell instance. The .Ic return command is implemented as a special built-in command. diff --git a/cddl/contrib/opensolaris/lib/libzpool/common/kernel.c b/cddl/contrib/opensolaris/lib/libzpool/common/kernel.c index 71c3dceaa0f1..c4e2d2e78aaa 100644 --- a/cddl/contrib/opensolaris/lib/libzpool/common/kernel.c +++ b/cddl/contrib/opensolaris/lib/libzpool/common/kernel.c @@ -349,6 +349,41 @@ cv_timedwait(kcondvar_t *cv, kmutex_t *mp, clock_t abstime) return (1); } +/*ARGSUSED*/ +clock_t +cv_timedwait_hires(kcondvar_t *cv, kmutex_t *mp, hrtime_t tim, hrtime_t res, + int flag) +{ + int error; + timestruc_t ts; + hrtime_t delta; + + ASSERT(flag == 0); + +top: + delta = tim - gethrtime(); + if (delta <= 0) + return (-1); + + ts.tv_sec = delta / NANOSEC; + ts.tv_nsec = delta % NANOSEC; + + ASSERT(mutex_owner(mp) == curthread); + mp->m_owner = NULL; + error = pthread_cond_timedwait(cv, &mp->m_lock, &ts); + mp->m_owner = curthread; + + if (error == ETIMEDOUT) + return (-1); + + if (error == EINTR) + goto top; + + ASSERT(error == 0); + + return (1); +} + void cv_signal(kcondvar_t *cv) { diff --git a/cddl/contrib/opensolaris/lib/libzpool/common/sys/zfs_context.h b/cddl/contrib/opensolaris/lib/libzpool/common/sys/zfs_context.h index da153c7c1668..15c181e204a5 100644 --- a/cddl/contrib/opensolaris/lib/libzpool/common/sys/zfs_context.h +++ b/cddl/contrib/opensolaris/lib/libzpool/common/sys/zfs_context.h @@ -313,6 +313,8 @@ extern void cv_init(kcondvar_t *cv, char *name, int type, void *arg); extern void cv_destroy(kcondvar_t *cv); extern void cv_wait(kcondvar_t *cv, kmutex_t *mp); extern clock_t cv_timedwait(kcondvar_t *cv, kmutex_t *mp, clock_t abstime); +extern clock_t cv_timedwait_hires(kcondvar_t *cvp, kmutex_t *mp, hrtime_t tim, + hrtime_t res, int flag); extern void cv_signal(kcondvar_t *cv); extern void cv_broadcast(kcondvar_t *cv); diff --git a/contrib/bmake/ChangeLog b/contrib/bmake/ChangeLog index 21ab78e57216..251998fd79c4 100644 --- a/contrib/bmake/ChangeLog +++ b/contrib/bmake/ChangeLog @@ -1,3 +1,24 @@ +2013-09-04 Simon J. Gerraty + + * Makefile (MAKE_VERSION): 20130904 + Merge with NetBSD make, pick up + o Add VAR_INTERNAL context, so that internal setting of + MAKEFILE does not override value set by makefiles. + +2013-09-02 Simon J. Gerraty + + * Makefile (MAKE_VERSION): 20130902 + Merge with NetBSD make, pick up + o CompatRunCommand: only apply shellErrFlag when errCheck is true + +2013-08-28 Simon J. Gerraty + + * Makefile (MAKE_VERSION): 20130828 + Merge with NetBSD make, pick up + o Fix VAR :sh = syntax from Will Andrews at freebsd.org + o Call Job_SetPrefix() from Job_Init() so makefiles have + opportunity to set .MAKE.JOB.PREFIX + 2013-07-30 Simon J. Gerraty * Makefile (MAKE_VERSION): 20130730 diff --git a/contrib/bmake/FILES b/contrib/bmake/FILES index b0d8b2ed6954..d4b5dca38c89 100644 --- a/contrib/bmake/FILES +++ b/contrib/bmake/FILES @@ -114,6 +114,7 @@ unit-tests/order unit-tests/phony-end unit-tests/posix unit-tests/qequals +unit-tests/sunshcmd unit-tests/sysv unit-tests/ternary unit-tests/test.exp diff --git a/contrib/bmake/Makefile b/contrib/bmake/Makefile index 1b1cd5944d4b..98df1e264a80 100644 --- a/contrib/bmake/Makefile +++ b/contrib/bmake/Makefile @@ -1,7 +1,7 @@ -# $Id: Makefile,v 1.17 2013/07/30 19:13:53 sjg Exp $ +# $Id: Makefile,v 1.20 2013/09/04 15:42:03 sjg Exp $ # Base version on src date -MAKE_VERSION= 20130730 +MAKE_VERSION= 20130904 PROG= bmake diff --git a/contrib/bmake/bmake.1 b/contrib/bmake/bmake.1 index 021a94ad24ac..df604e7c940f 100644 --- a/contrib/bmake/bmake.1 +++ b/contrib/bmake/bmake.1 @@ -1,4 +1,4 @@ -.\" $NetBSD: make.1,v 1.220 2013/07/30 19:09:57 sjg Exp $ +.\" $NetBSD: make.1,v 1.222 2013/08/11 09:53:49 apb Exp $ .\" .\" Copyright (c) 1990, 1993 .\" The Regents of the University of California. All rights reserved. @@ -29,7 +29,7 @@ .\" .\" from: @(#)make.1 8.4 (Berkeley) 3/19/94 .\" -.Dd July 30, 2013 +.Dd August 11, 2013 .Dt MAKE 1 .Os .Sh NAME @@ -1971,6 +1971,12 @@ If the source is the special .Ic .DOTLAST target, then the current working directory is searched last. +.It Ic .PATH. Ns Va suffix +Like +.Ic .PATH +but applies only to files with a particular suffix. +The suffix must have been previously declared with +.Ic .SUFFIXES . .It Ic .PHONY Apply the .Ic .PHONY diff --git a/contrib/bmake/bmake.cat1 b/contrib/bmake/bmake.cat1 index e18c26729145..ca49bb63c03c 100644 --- a/contrib/bmake/bmake.cat1 +++ b/contrib/bmake/bmake.cat1 @@ -1257,6 +1257,10 @@ SSPPEECCIIAALL TTAARRGGEETTSS source is the special ..DDOOTTLLAASSTT target, then the current working directory is searched last. + ..PPAATTHH.._s_u_f_f_i_x + Like ..PPAATTHH but applies only to files with a particular suffix. + The suffix must have been previously declared with ..SSUUFFFFIIXXEESS. + ..PPHHOONNYY Apply the ..PPHHOONNYY attribute to any specified sources. ..PPRREECCIIOOUUSS @@ -1374,4 +1378,4 @@ BBUUGGSS There is no way of escaping a space character in a filename. -NetBSD 5.1 July 30, 2013 NetBSD 5.1 +NetBSD 5.1 August 11, 2013 NetBSD 5.1 diff --git a/contrib/bmake/compat.c b/contrib/bmake/compat.c index 797862eb8031..b0bbc936f595 100644 --- a/contrib/bmake/compat.c +++ b/contrib/bmake/compat.c @@ -1,4 +1,4 @@ -/* $NetBSD: compat.c,v 1.92 2013/07/05 22:14:56 sjg Exp $ */ +/* $NetBSD: compat.c,v 1.93 2013/09/02 19:26:42 sjg Exp $ */ /* * Copyright (c) 1988, 1989, 1990 The Regents of the University of California. @@ -70,14 +70,14 @@ */ #ifndef MAKE_NATIVE -static char rcsid[] = "$NetBSD: compat.c,v 1.92 2013/07/05 22:14:56 sjg Exp $"; +static char rcsid[] = "$NetBSD: compat.c,v 1.93 2013/09/02 19:26:42 sjg Exp $"; #else #include #ifndef lint #if 0 static char sccsid[] = "@(#)compat.c 8.2 (Berkeley) 3/19/94"; #else -__RCSID("$NetBSD: compat.c,v 1.92 2013/07/05 22:14:56 sjg Exp $"); +__RCSID("$NetBSD: compat.c,v 1.93 2013/09/02 19:26:42 sjg Exp $"); #endif #endif /* not lint */ #endif diff --git a/contrib/bmake/job.c b/contrib/bmake/job.c index 4d901b0c4710..4e2295908bc0 100644 --- a/contrib/bmake/job.c +++ b/contrib/bmake/job.c @@ -1,4 +1,4 @@ -/* $NetBSD: job.c,v 1.175 2013/07/30 19:09:57 sjg Exp $ */ +/* $NetBSD: job.c,v 1.176 2013/08/04 16:48:15 sjg Exp $ */ /* * Copyright (c) 1988, 1989, 1990 The Regents of the University of California. @@ -70,14 +70,14 @@ */ #ifndef MAKE_NATIVE -static char rcsid[] = "$NetBSD: job.c,v 1.175 2013/07/30 19:09:57 sjg Exp $"; +static char rcsid[] = "$NetBSD: job.c,v 1.176 2013/08/04 16:48:15 sjg Exp $"; #else #include #ifndef lint #if 0 static char sccsid[] = "@(#)job.c 8.2 (Berkeley) 3/19/94"; #else -__RCSID("$NetBSD: job.c,v 1.175 2013/07/30 19:09:57 sjg Exp $"); +__RCSID("$NetBSD: job.c,v 1.176 2013/08/04 16:48:15 sjg Exp $"); #endif #endif /* not lint */ #endif @@ -178,6 +178,14 @@ __RCSID("$NetBSD: job.c,v 1.175 2013/07/30 19:09:57 sjg Exp $"); */ #define MAKE_ALWAYS_PASS_JOB_QUEUE ".MAKE.ALWAYS_PASS_JOB_QUEUE" static int Always_pass_job_queue = TRUE; +/* + * FreeBSD: aborting entire parallel make isn't always + * desired. When doing tinderbox for example, failure of + * one architecture should not stop all. + * We still want to bail on interrupt though. + */ +#define MAKE_JOB_ERROR_TOKEN "MAKE_JOB_ERROR_TOKEN" +static int Job_error_token = TRUE; /* * error handling variables @@ -2237,6 +2245,9 @@ Job_Init(void) Always_pass_job_queue = getBoolean(MAKE_ALWAYS_PASS_JOB_QUEUE, Always_pass_job_queue); + Job_error_token = getBoolean(MAKE_JOB_ERROR_TOKEN, Job_error_token); + + /* * There is a non-zero chance that we already have children. * eg after 'make -f- < #ifndef lint @@ -81,7 +81,7 @@ __COPYRIGHT("@(#) Copyright (c) 1988, 1989, 1990, 1993\ #if 0 static char sccsid[] = "@(#)main.c 8.3 (Berkeley) 3/19/94"; #else -__RCSID("$NetBSD: main.c,v 1.222 2013/07/18 15:31:49 sjg Exp $"); +__RCSID("$NetBSD: main.c,v 1.224 2013/09/04 15:38:26 sjg Exp $"); #endif #endif /* not lint */ #endif @@ -1414,7 +1414,7 @@ ReadMakefile(const void *p, const void *q MAKE_ATTR_UNUSED) if (!strcmp(fname, "-")) { Parse_File(NULL /*stdin*/, -1); - Var_Set("MAKEFILE", "", VAR_GLOBAL, 0); + Var_Set("MAKEFILE", "", VAR_INTERNAL, 0); } else { /* if we've chdir'd, rebuild the path name */ if (strcmp(curdir, objdir) && *fname != '/') { @@ -1463,7 +1463,7 @@ ReadMakefile(const void *p, const void *q MAKE_ATTR_UNUSED) */ found: if (!doing_depend) - Var_Set("MAKEFILE", fname, VAR_GLOBAL, 0); + Var_Set("MAKEFILE", fname, VAR_INTERNAL, 0); Parse_File(fname, fd); } free(path); diff --git a/contrib/bmake/make.1 b/contrib/bmake/make.1 index 0dec8ef58529..c4b647da134b 100644 --- a/contrib/bmake/make.1 +++ b/contrib/bmake/make.1 @@ -1,4 +1,4 @@ -.\" $NetBSD: make.1,v 1.220 2013/07/30 19:09:57 sjg Exp $ +.\" $NetBSD: make.1,v 1.222 2013/08/11 09:53:49 apb Exp $ .\" .\" Copyright (c) 1990, 1993 .\" The Regents of the University of California. All rights reserved. @@ -29,7 +29,7 @@ .\" .\" from: @(#)make.1 8.4 (Berkeley) 3/19/94 .\" -.Dd July 30, 2013 +.Dd August 11, 2013 .Dt MAKE 1 .Os .Sh NAME @@ -1982,6 +1982,12 @@ If the source is the special .Ic .DOTLAST target, then the current working directory is searched last. +.It Ic .PATH. Ns Va suffix +Like +.Ic .PATH +but applies only to files with a particular suffix. +The suffix must have been previously declared with +.Ic .SUFFIXES . .It Ic .PHONY Apply the .Ic .PHONY diff --git a/contrib/bmake/make.h b/contrib/bmake/make.h index c51fbe5ef629..b13716fd3b48 100644 --- a/contrib/bmake/make.h +++ b/contrib/bmake/make.h @@ -1,4 +1,4 @@ -/* $NetBSD: make.h,v 1.91 2013/06/18 20:06:09 sjg Exp $ */ +/* $NetBSD: make.h,v 1.92 2013/09/04 15:38:26 sjg Exp $ */ /* * Copyright (c) 1988, 1989, 1990, 1993 @@ -404,6 +404,10 @@ extern Boolean varNoExportEnv; /* TRUE if we should not export variables extern GNode *DEFAULT; /* .DEFAULT rule */ +extern GNode *VAR_INTERNAL; /* Variables defined internally by make + * which should not override those set by + * makefiles. + */ extern GNode *VAR_GLOBAL; /* Variables defined in a global context, e.g * in the Makefile itself */ extern GNode *VAR_CMD; /* Variables defined on the command line */ diff --git a/contrib/bmake/mk/ChangeLog b/contrib/bmake/mk/ChangeLog index db1e289f92b1..b5471975a010 100644 --- a/contrib/bmake/mk/ChangeLog +++ b/contrib/bmake/mk/ChangeLog @@ -1,3 +1,14 @@ +2013-09-04 Simon J. Gerraty + + * gendirdeps.mk (_objtops): fix typo also + while processing M2D_OBJROOTS to gather qualdir_list + qualify $ql with loop iterator to ensure correct results. + +2013-08-01 Simon J. Gerraty + + * install-mk (MK_VERSION): 20130801 + * libs.mk: update to match progs.mk + 2013-07-26 Simon J. Gerraty * install-mk (MK_VERSION): 20130726 diff --git a/contrib/bmake/mk/gendirdeps.mk b/contrib/bmake/mk/gendirdeps.mk index 9be367369f57..20e2b152a3fa 100644 --- a/contrib/bmake/mk/gendirdeps.mk +++ b/contrib/bmake/mk/gendirdeps.mk @@ -1,4 +1,4 @@ -# $Id: gendirdeps.mk,v 1.22 2013/05/11 05:16:26 sjg Exp $ +# $Id: gendirdeps.mk,v 1.23 2013/09/04 17:49:20 sjg Exp $ # Copyright (c) 2010-2013, Juniper Networks, Inc. # All rights reserved. @@ -162,7 +162,7 @@ dir_list != cd ${_OBJDIR} && \ .warning Skipping ${_DEPENDFILE:S,${SRCTOP}/,,} # we are not going to update anything .else - +dpadd_dir_list= .if !empty(DPADD) _nonlibs := ${DPADD:T:Nlib*:N*include} .if !empty(_nonlibs) @@ -174,6 +174,7 @@ ddep_list += $f.dirdep ddep_list += ${f:H}.dirdep .else dir_list += ${f:H:tA} +dpadd_dir_list += ${f:H:tA} .endif .endfor .if !empty(ddep_list) @@ -197,7 +198,7 @@ dir_list += ${ddeps} # so we add # ${"${dir_list:M*bsd/sys/${MACHINE_ARCH}/include}":?bsd/include:} # to GENDIRDEPS_DIR_LIST_XTRAS -_objtops = ${OBJTOP} ${_OBJTOP} ${_obtop} +_objtops = ${OBJTOP} ${_OBJTOP} ${_objtop} _objtops := ${_objtops:O:u} dirdep_list = \ ${_objtops:@o@${dir_list:M$o*/*:C,$o[^/]*/,,}@} \ @@ -212,8 +213,11 @@ M2D_OBJROOTS := ${M2D_OBJROOTS:O:u:[-1..1]} skip_ql= ${SRCTOP}* ${_objtops:@o@$o*@} .for o in ${M2D_OBJROOTS:${skip_ql:${M_ListToSkip}}} # we need := so only skip_ql to this point applies -ql := ${dir_list:${skip_ql:${M_ListToSkip}}:M$o*/*/*:C,$o([^/]+)/(.*),\2.\1,:S,.${HOST_TARGET},.host,} -qualdir_list += ${ql} +ql.$o := ${dir_list:${skip_ql:${M_ListToSkip}}:M$o*/*/*:C,$o([^/]+)/(.*),\2.\1,:S,.${HOST_TARGET},.host,} +qualdir_list += ${ql.$o} +.if ${DEBUG_GENDIRDEPS:Uno:@x@${RELDIR:M$x}@} != "" +.info ${RELDIR}: o=$o ${ql.$o qualdir_list:L:@v@$v=${$v}@} +.endif skip_ql+= $o* .endfor @@ -241,6 +245,7 @@ DIRDEPS := ${DIRDEPS:${GENDIRDEPS_FILTER:UNno:ts:}:O:u} .if ${DEBUG_GENDIRDEPS:Uno:@x@${RELDIR:M$x}@} != "" .info ${RELDIR}: M2D_OBJROOTS=${M2D_OBJROOTS} .info ${RELDIR}: dir_list='${dir_list}' +.info ${RELDIR}: dpadd_dir_list='${dpadd_dir_list}' .info ${RELDIR}: dirdep_list='${dirdep_list}' .info ${RELDIR}: qualdir_list='${qualdir_list}' .info ${RELDIR}: SKIP_GENDIRDEPS='${SKIP_GENDIRDEPS}' diff --git a/contrib/bmake/mk/install-mk b/contrib/bmake/mk/install-mk index 59b1b0151fee..0640906a2438 100644 --- a/contrib/bmake/mk/install-mk +++ b/contrib/bmake/mk/install-mk @@ -55,7 +55,7 @@ # Simon J. Gerraty # RCSid: -# $Id: install-mk,v 1.92 2013/07/27 05:37:37 sjg Exp $ +# $Id: install-mk,v 1.93 2013/08/02 18:28:47 sjg Exp $ # # @(#) Copyright (c) 1994 Simon J. Gerraty # @@ -70,7 +70,7 @@ # sjg@crufty.net # -MK_VERSION=20130726 +MK_VERSION=20130801 OWNER= GROUP= MODE=444 diff --git a/contrib/bmake/mk/libs.mk b/contrib/bmake/mk/libs.mk index 05b450689b11..7f974bfa86b9 100644 --- a/contrib/bmake/mk/libs.mk +++ b/contrib/bmake/mk/libs.mk @@ -1,4 +1,4 @@ -# $Id: libs.mk,v 1.2 2007/04/30 17:39:27 sjg Exp $ +# $Id: libs.mk,v 1.3 2013/08/02 18:28:48 sjg Exp $ # # @(#) Copyright (c) 2006, Simon J. Gerraty # @@ -17,7 +17,15 @@ .if defined(LIBS) +# In meta mode, we can capture dependenices for _one_ of the progs. +# if makefile doesn't nominate one, we use the first. +.ifndef UPDATE_DEPENDFILE_LIB +UPDATE_DEPENDFILE_LIB = ${LIBS:[1]} +.export UPDATE_DEPENDFILE_LIB +.endif + .ifndef LIB +# They may have asked us to build just one .for t in ${LIBS:R:T:S,^lib,,} .if make(lib$t) LIB?= $t @@ -28,14 +36,41 @@ lib$t: all .if defined(LIB) # just one of many -.for v in DPADD SRCS CFLAGS ${LIB_VARS} -$v += ${${v}_lib${LIB}} +LIB_VARS += \ + LIBDIR \ + CFLAGS \ + COPTS \ + CPPFLAGS \ + CXXFLAGS \ + DPADD \ + DPLIBS \ + LDADD \ + LDFLAGS \ + MAN \ + SRCS + +.for v in ${LIB_VARS:O:u} +.if defined(${v}.${LIB}) || defined(${v}_${LIB}) +$v += ${${v}_${LIB}:U${${v}.${LIB}}} +.endif .endfor + +# for meta mode, there can be only one! +.if ${LIB} == ${UPDATE_DEPENDFILE_LIB:Uno} +UPDATE_DEPENDFILE ?= yes +.endif +UPDATE_DEPENDFILE ?= NO + # ensure that we don't clobber each other's dependencies DEPENDFILE?= .depend.${LIB} # lib.mk will do the rest .else all: ${LIBS:S,^lib,,:@t@lib$t.a@} .MAKE + +# We cannot capture dependencies for meta mode here +UPDATE_DEPENDFILE = NO +# nor can we safely run in parallel. +.NOTPARALLEL: .endif .endif @@ -43,12 +78,16 @@ all: ${LIBS:S,^lib,,:@t@lib$t.a@} .MAKE .include <${.PARSEFILE:S,libs,lib,}> .ifndef LIB -.for t in ${LIBS:R:T:S,^lib,,} -lib$t.a: ${SRCS} ${DPADD} ${SRCS_lib$t} ${DPADD_lib$t} - (cd ${.CURDIR} && ${.MAKE} -f ${MAKEFILE} LIB=$t) +# tell libs.mk we might want to install things +LIBS_TARGETS+= cleandepend cleandir cleanobj depend install -clean: $t.clean -$t.clean: - (cd ${.CURDIR} && ${.MAKE} -f ${MAKEFILE} LIB=$t ${@:E}) +.for b in ${LIBS:R:T:S,^lib,,} +lib$b.a: ${SRCS} ${DPADD} ${SRCS_lib$b} ${DPADD_lib$b} + (cd ${.CURDIR} && ${.MAKE} -f ${MAKEFILE} LIB=$b) + +.for t in ${LIBS_TARGETS:O:u} +$b.$t: .PHONY .MAKE + (cd ${.CURDIR} && ${.MAKE} -f ${MAKEFILE} LIB=$b ${@:E}) +.endfor .endfor .endif diff --git a/contrib/bmake/mk/progs.mk b/contrib/bmake/mk/progs.mk index f74f64012849..7ccebbffb44c 100644 --- a/contrib/bmake/mk/progs.mk +++ b/contrib/bmake/mk/progs.mk @@ -1,4 +1,4 @@ -# $Id: progs.mk,v 1.12 2013/04/22 18:10:04 sjg Exp $ +# $Id: progs.mk,v 1.13 2013/08/02 18:28:48 sjg Exp $ # # @(#) Copyright (c) 2006, Simon J. Gerraty # @@ -35,9 +35,21 @@ PROG ?= $t .if defined(PROG) # just one of many -PROG_VARS += BINDIR CFLAGS CPPFLAGS CXXFLAGS DPADD DPLIBS LDADD MAN SRCS +PROG_VARS += \ + BINDIR \ + CFLAGS \ + COPTS \ + CPPFLAGS \ + CXXFLAGS \ + DPADD \ + DPLIBS \ + LDADD \ + LDFLAGS \ + MAN \ + SRCS + .for v in ${PROG_VARS:O:u} -.if defined(${v}.${PROG}) +.if defined(${v}.${PROG}) || defined(${v}_${PROG}) $v += ${${v}_${PROG}:U${${v}.${PROG}}} .endif .endfor diff --git a/contrib/bmake/parse.c b/contrib/bmake/parse.c index 5096767958a4..41323b51fa8b 100644 --- a/contrib/bmake/parse.c +++ b/contrib/bmake/parse.c @@ -1,4 +1,4 @@ -/* $NetBSD: parse.c,v 1.189 2013/06/18 19:31:27 sjg Exp $ */ +/* $NetBSD: parse.c,v 1.191 2013/08/28 21:56:49 sjg Exp $ */ /* * Copyright (c) 1988, 1989, 1990, 1993 @@ -69,14 +69,14 @@ */ #ifndef MAKE_NATIVE -static char rcsid[] = "$NetBSD: parse.c,v 1.189 2013/06/18 19:31:27 sjg Exp $"; +static char rcsid[] = "$NetBSD: parse.c,v 1.191 2013/08/28 21:56:49 sjg Exp $"; #else #include #ifndef lint #if 0 static char sccsid[] = "@(#)parse.c 8.3 (Berkeley) 3/19/94"; #else -__RCSID("$NetBSD: parse.c,v 1.189 2013/06/18 19:31:27 sjg Exp $"); +__RCSID("$NetBSD: parse.c,v 1.191 2013/08/28 21:56:49 sjg Exp $"); #endif #endif /* not lint */ #endif @@ -1751,6 +1751,12 @@ Parse_IsVar(char *line) ch = *line++; wasSpace = TRUE; } +#ifdef SUNSHCMD + if (ch == ':' && strncmp(line, "sh", 2) == 0) { + line += 2; + continue; + } +#endif if (ch == '=') return TRUE; if (*line == '=' && ISEQOPERATOR(ch)) diff --git a/contrib/bmake/unit-tests/Makefile.in b/contrib/bmake/unit-tests/Makefile.in index 78ca92faa1d9..3f70f8a4d9fa 100644 --- a/contrib/bmake/unit-tests/Makefile.in +++ b/contrib/bmake/unit-tests/Makefile.in @@ -1,6 +1,6 @@ -# $Id: Makefile.in,v 1.43 2013/07/16 21:14:30 sjg Exp $ +# $Id: Makefile.in,v 1.44 2013/08/28 22:09:29 sjg Exp $ # -# $NetBSD: Makefile,v 1.37 2013/07/16 19:59:28 sjg Exp $ +# $NetBSD: Makefile,v 1.38 2013/08/28 21:56:50 sjg Exp $ # # Unit tests for make(1) # The main targets are: @@ -45,6 +45,7 @@ SUBFILES= \ phony-end \ posix \ qequals \ + sunshcmd \ sysv \ ternary \ unexport \ diff --git a/contrib/bmake/unit-tests/sunshcmd b/contrib/bmake/unit-tests/sunshcmd new file mode 100644 index 000000000000..e3baf901e51d --- /dev/null +++ b/contrib/bmake/unit-tests/sunshcmd @@ -0,0 +1,10 @@ +BYECMD = echo bye +LATERCMD = echo later +TEST1 :sh = echo hello +TEST2 :sh = ${BYECMD} +TEST3 = ${LATERCMD:sh} + +all: + @echo "TEST1=${TEST1}" + @echo "TEST2=${TEST2}" + @echo "TEST3=${TEST3}" diff --git a/contrib/bmake/unit-tests/test.exp b/contrib/bmake/unit-tests/test.exp index b6fad78d21bc..aaecb960fc99 100644 --- a/contrib/bmake/unit-tests/test.exp +++ b/contrib/bmake/unit-tests/test.exp @@ -349,6 +349,9 @@ Now we expect an error... *** Error code 1 (continuing) `all' not remade because of errors. V.i386 ?= OK +TEST1=hello +TEST2=bye +TEST3=later FOOBAR = FOOBAR = foobar fubar fun diff --git a/contrib/bmake/var.c b/contrib/bmake/var.c index c4a6735827b9..dd911f92bb4e 100644 --- a/contrib/bmake/var.c +++ b/contrib/bmake/var.c @@ -1,4 +1,4 @@ -/* $NetBSD: var.c,v 1.183 2013/07/16 20:00:56 sjg Exp $ */ +/* $NetBSD: var.c,v 1.184 2013/09/04 15:38:26 sjg Exp $ */ /* * Copyright (c) 1988, 1989, 1990, 1993 @@ -69,14 +69,14 @@ */ #ifndef MAKE_NATIVE -static char rcsid[] = "$NetBSD: var.c,v 1.183 2013/07/16 20:00:56 sjg Exp $"; +static char rcsid[] = "$NetBSD: var.c,v 1.184 2013/09/04 15:38:26 sjg Exp $"; #else #include #ifndef lint #if 0 static char sccsid[] = "@(#)var.c 8.3 (Berkeley) 3/19/94"; #else -__RCSID("$NetBSD: var.c,v 1.183 2013/07/16 20:00:56 sjg Exp $"); +__RCSID("$NetBSD: var.c,v 1.184 2013/09/04 15:38:26 sjg Exp $"); #endif #endif /* not lint */ #endif @@ -187,6 +187,7 @@ static char varNoError[] = ""; * The four contexts are searched in the reverse order from which they are * listed. */ +GNode *VAR_INTERNAL; /* variables from make itself */ GNode *VAR_GLOBAL; /* variables from the makefile */ GNode *VAR_CMD; /* variables defined on the command-line */ @@ -419,6 +420,10 @@ VarFind(const char *name, GNode *ctxt, int flags) (ctxt != VAR_GLOBAL)) { var = Hash_FindEntry(&VAR_GLOBAL->context, name); + if ((var == NULL) && (ctxt != VAR_INTERNAL)) { + /* VAR_INTERNAL is subordinate to VAR_GLOBAL */ + var = Hash_FindEntry(&VAR_INTERNAL->context, name); + } } if ((var == NULL) && (flags & FIND_ENV)) { char *env; @@ -440,6 +445,9 @@ VarFind(const char *name, GNode *ctxt, int flags) (ctxt != VAR_GLOBAL)) { var = Hash_FindEntry(&VAR_GLOBAL->context, name); + if ((var == NULL) && (ctxt != VAR_INTERNAL)) { + var = Hash_FindEntry(&VAR_INTERNAL->context, name); + } if (var == NULL) { return NULL; } else { @@ -4182,6 +4190,7 @@ Var_GetHead(char *file) void Var_Init(void) { + VAR_INTERNAL = Targ_NewGN("Internal"); VAR_GLOBAL = Targ_NewGN("Global"); VAR_CMD = Targ_NewGN("Command"); diff --git a/contrib/gcc/config/arm/ieee754-df.S b/contrib/gcc/config/arm/ieee754-df.S index 74d9f0d9c4c9..70262a282aa9 100644 --- a/contrib/gcc/config/arm/ieee754-df.S +++ b/contrib/gcc/config/arm/ieee754-df.S @@ -43,7 +43,7 @@ @ For FPA, float words are always big-endian. @ For VFP, floats words follow the memory system mode. -#if defined(__VFP_FP__) && !defined(__ARMEB__) +#if (defined(__ARM_EABI__) || defined(__VFP_FP__)) && !defined(__ARMEB__) #define xl r0 #define xh r1 #define yl r2 diff --git a/contrib/ipfilter/.cvsignore b/contrib/ipfilter/.cvsignore deleted file mode 100644 index 616828f4144d..000000000000 --- a/contrib/ipfilter/.cvsignore +++ /dev/null @@ -1,28 +0,0 @@ -ipf -sparcv7 -sparcv9 -h -ipf-darren -bugs -ipftest -patches -state -cbits -CVS -old -new -netinet -import -bak -streams -cvs.diff -threads -glibc -hp -windows -ipnat -opt_inet6.h -ippool -ipmon -ip_rules.c -ip_rules.h diff --git a/contrib/ipfilter/BNF b/contrib/ipfilter/BNF index 404cc281fccf..ef35d25e9f8a 100644 --- a/contrib/ipfilter/BNF +++ b/contrib/ipfilter/BNF @@ -67,7 +67,7 @@ facility = "kern" | "user" | "mail" | "daemon" | "auth" | "syslog" | "audit" | "logalert" | "local0" | "local1" | "local2" | "local3" | "local4" | "local5" | "local6" | "local7" . priority = "emerg" | "alert" | "crit" | "err" | "warn" | "notice" | - "info" | "debug" . + "info" | "debug" . hexnumber = "0" "x" hexstring . hexstring = hexdigit [ hexstring ] . diff --git a/contrib/ipfilter/BSD/.cvsignore b/contrib/ipfilter/BSD/.cvsignore deleted file mode 100644 index c149a0043f45..000000000000 --- a/contrib/ipfilter/BSD/.cvsignore +++ /dev/null @@ -1,22 +0,0 @@ -ipf -ipfs -ipfstat -ipftest -ipmon -ipnat -ipresend -ipsend -iptest -vnode_if.h -if_ipl -i386 -amiga -FreeBSD* -BSDOS* -NetBSD* -OpenBSD* -*_lex_var.h -*_y.c -*_l.c -*_y.h -ip_rules.* diff --git a/contrib/ipfilter/BSD/Makefile b/contrib/ipfilter/BSD/Makefile index fe8a4d4e567f..4f2c2b9dcd41 100644 --- a/contrib/ipfilter/BSD/Makefile +++ b/contrib/ipfilter/BSD/Makefile @@ -1,9 +1,8 @@ # -# Copyright (C) 1993-1998 by Darren Reed. +# Copyright (C) 2012 by Darren Reed. # # See the IPFILTER.LICENCE file for details on licencing. # -TOP=../.. BINDEST=/usr/sbin SBINDEST=/sbin MANDIR=/usr/share/man @@ -17,13 +16,14 @@ CFLAGS=-g -I$(TOP) # DEVFS!=/usr/bin/lsvfs 2>&1 | sed -n 's/.*devfs.*/-DDEVFS/p' CPU!=uname -m -INC=-I/usr/include -I/sys -I/sys/sys -I/sys/arch +COMPDIR!=/bin/ls -1tr /usr/src/sys/arch/${CPU}/compile | tail -1 +INC=-I/usr/include -I/sys -I/sys/sys -I/sys/arch -I/usr/src/sys/arch/${CPU}/compile/${COMPDIR} DEF=-D$(CPU) -D__$(CPU)__ -DINET -DKERNEL -D_KERNEL $(INC) $(DEVFS) -fno-builtin IPDEF=$(DEF) -DGATEWAY -DDIRECTED_BROADCAST VNODESHDIR=/sys/kern MLD=$(ML) ML=mln_ipl.c -LKM=if_ipl.o +LKM=ipflkm.o LKMR=ipfrule.o DLKM= OBJ=. @@ -44,15 +44,15 @@ INSTALL=install # MODOBJS=ip_fil.o fil.o ml_ipl.o ip_nat.o ip_frag.o ip_state.o ip_proxy.o \ ip_auth.o ip_log.o ip_pool.o ip_htable.o ip_lookup.o ip_rules.o \ - ip_scan.o ip_sync.o + ip_scan.o ip_sync.o ip_nat6.o ip_dstlist.o radix_ipf.o # ip_trafcon.o DFLAGS=$(IPFLKM) $(IPFLOG) $(LOOKUP) $(SYNC) $(DEF) $(DLKM) $(IPFBPF) -IPF=ipf.o ipfcomp.o ipf_y.o ipf_l.o bpf_filter_u.o -IPT=ipftest.o fil_u.o ip_frag_u.o ip_state_u.o ip_nat_u.o \ +IPF=ipf.o ipfcomp.o ipf_y.o ipf_l.o +IPT=ipftest.o fil_u.o ip_frag_u.o ip_state_u.o ip_nat_u.o ip_nat6_u.o \ ip_proxy_u.o ip_auth_u.o ip_htable_u.o ip_lookup_u.o ip_pool_u.o \ ip_scan_u.o ip_sync_u.o ip_rules_u.o ip_fil_u.o ip_log_u.o \ ippool_y.o ippool_l.o ipf_y.o ipf_l.o ipnat_y.o ipnat_l.o \ - md5_u.o radix_u.o bpf_filter_u.o + md5_u.o radix_ipf_u.o ip_dstlist_u.o # ip_syn_u.o #ip_trafcon_u.o TOOL=$(TOP)/tools @@ -60,9 +60,9 @@ IPNAT=ipnat.o ipnat_y.o ipnat_l.o IPMON=ipmon.o ipmon_y.o ipmon_l.o IPPOOL=ippool_y.o ippool_l.o kmem.o ippool.o IPTRAFCON=iptrafcon.o -PROXYLIST=$(TOP)/ip_ftp_pxy.c $(TOP)/ip_ipsec_pxy.c $(TOP)/ip_irc_pxy.c \ - $(TOP)/ip_netbios_pxy.c $(TOP)/ip_raudio_pxy.c $(TOP)/ip_rcmd_pxy.c \ - $(TOP)/ip_rpcb_pxy.c $(TOP)/ip_pptp_pxy.c +PROXYLIST=$(TOP)/ip_dns_pxy.c $(TOP)/ip_ftp_pxy.c $(TOP)/ip_ipsec_pxy.c \ + $(TOP)/ip_irc_pxy.c $(TOP)/ip_netbios_pxy.c $(TOP)/ip_raudio_pxy.c \ + $(TOP)/ip_rcmd_pxy.c $(TOP)/ip_rpcb_pxy.c $(TOP)/ip_pptp_pxy.c FILS=ipfstat.o LIBSRC=$(TOP)/lib RANLIB=ranlib @@ -70,6 +70,11 @@ AROPTS=cq HERE!=pwd CCARGS=-I. $(DEBUG) $(CFLAGS) $(UFLAGS) KCARGS=-I. $(DEBUG) $(CFLAGS) +.if ${MACHINE_ARCH} == amd64 +KCARGS+=-mcmodel=kernel -mno-red-zone -fno-omit-frame-pointer \ + -mfpmath=387 -mno-sse -mno-sse2 -mno-mmx -mno-3dnow \ + -msoft-float -fno-asynchronous-unwind-tables +.endif # # Extra is option kernel things we always want in user space. # @@ -77,9 +82,11 @@ EXTRA=$(ALLOPTS) include $(TOP)/lib/Makefile -build all: machine $(OBJ)/libipf.a ipf ipfs ipfstat ipftest ipmon ipnat \ - ippool ipscan ipsyncm ipsyncs $(LKM) $(LKMR) - -sh -c 'for i in ipf ipftest ipmon ippool ipnat ipscan ipsyncm ipsyncs; do /bin/rm -f $(TOP)/$$i; ln -s `pwd`/$$i $(TOP); done' +build all: machine $(OBJ)/libipf.a tools $(LKM) $(LKMR) + +tools: ipf ipfs ipfstat ipftest ipmon ipnat ippool ipscan ipsyncm \ + ipsyncs ipfsyncd + -sh -c 'for i in ipf ipftest ipmon ippool ipnat ipscan ipsyncm ipsyncs ipfsyncd; do /bin/rm -f $(TOP)/$$i; ln -s `pwd`/$$i $(TOP); done' -/bin/rm -f ../tools ./tools -ln -s ../tools . -ln -s ../tools .. @@ -122,12 +129,18 @@ ipsyncm: ipsyncm.o $(OBJ)/libipf.a ipsyncs: ipsyncs.o $(OBJ)/libipf.a $(CC) $(CCARGS) ipsyncs.o -o $@ $(LIBS) +ipfsyncd: ipfsyncd.o $(OBJ)/libipf.a + $(CC) $(CCARGS) ipfsyncd.o -o $@ $(LIBS) + ipsyncm.o: $(TOOL)/ipsyncm.c $(TOP)/ip_sync.h $(CC) $(CCARGS) -c $(TOOL)/ipsyncm.c -o $@ ipsyncs.o: $(TOOL)/ipsyncs.c $(TOP)/ip_sync.h $(CC) $(CCARGS) -c $(TOOL)/ipsyncs.c -o $@ +ipfsyncd.o: $(TOOL)/ipfsyncd.c $(TOP)/ip_sync.h + $(CC) $(CCARGS) -c $(TOOL)/ipfsyncd.c -o $@ + tests: (cd test; make ) @@ -146,7 +159,7 @@ fil_u.o: $(TOP)/fil.c $(TOP)/ip_fil.h $(TOP)/ipf.h $(TOP)/ip_compat.h \ fil.o: $(TOP)/fil.c $(TOP)/ip_fil.h $(TOP)/ip_compat.h $(TOP)/ipl.h \ $(TOP)/ip_rules.h - $(CC) $(KCARGS) $(POLICY) $(DFLAGS) $(IPFBPF) $(COMPIPF) \ + $(CC) $(KCARGS) $(POLICY) $(DFLAGS) $(IPFBPF) $(COMPIPF) $(COMPATIPF) \ -c $(TOP)/fil.c -o $@ ipf.o: $(TOOL)/ipf.c $(TOP)/ip_fil.h $(TOP)/ipf.h $(TOP)/opts.h @@ -163,7 +176,7 @@ ipnat.o: $(TOOL)/ipnat.c $(TOP)/ip_fil.h $(TOP)/ipf.h $(TOP)/ip_nat.h \ $(TOP)/opts.h $(CC) $(CCARGS) -c $(TOOL)/ipnat.c -o $@ -ipnat_y.o: ipnat_y.c ipnat_y.h ipnat_l.h +ipnat_y.o: ipnat_y.c ipnat_y.h ipnat_l.h $(TOP)/ip_fil.h $(TOP)/ip_nat.h $(CC) $(CCARGS) -c ipnat_y.c -o $@ ipnat_l.o: ipnat_l.c ipnat_y.h @@ -183,6 +196,9 @@ ipnat_l.h: $(TOOL)/lexer.h ip_nat_u.o: $(TOP)/ip_nat.c $(TOP)/ip_nat.h $(TOP)/ip_compat.h $(TOP)/ip_fil.h $(CC) $(CCARGS) $(EXTRA) -c $(TOP)/ip_nat.c -o $@ +ip_nat6_u.o: $(TOP)/ip_nat6.c $(TOP)/ip_nat.h $(TOP)/ip_compat.h $(TOP)/ip_fil.h + $(CC) $(CCARGS) $(EXTRA) -c $(TOP)/ip_nat6.c -o $@ + ip_proxy_u.o: $(TOP)/ip_proxy.c $(TOP)/ip_proxy.h $(TOP)/ip_compat.h \ $(TOP)/ip_fil.h $(PROXYLIST) $(TOP)/ip_nat.h $(CC) $(CCARGS) $(EXTRA) -c $(TOP)/ip_proxy.c -o $@ @@ -222,8 +238,13 @@ ip_htable_u.o: $(TOP)/ip_htable.c $(TOP)/ip_compat.h $(TOP)/ip_fil.h \ $(TOP)/ip_htable.h $(CC) $(CCARGS) $(EXTRA) -c $(TOP)/ip_htable.c -o $@ +ip_dstlist_u.o: $(TOP)/ip_dstlist.c $(TOP)/ip_compat.h $(TOP)/ip_fil.h \ + $(TOP)/ip_dstlist.h + $(CC) $(CCARGS) $(EXTRA) -c $(TOP)/ip_dstlist.c -o $@ + ip_lookup_u.o: $(TOP)/ip_lookup.c $(TOP)/ip_compat.h $(TOP)/ip_fil.h \ - $(TOP)/ip_lookup.h $(TOP)/ip_pool.h $(TOP)/ip_htable.h + $(TOP)/ip_lookup.h $(TOP)/ip_pool.h $(TOP)/ip_htable.h \ + $(TOP)/ip_dstlist.h $(CC) $(CCARGS) $(EXTRA) -c $(TOP)/ip_lookup.c -o $@ ip_trafcon_u.o: $(TOP)/ip_trafcon.c $(TOP)/ip_compat.h $(TOP)/ip_fil.h \ @@ -236,19 +257,28 @@ ip_log_u.o: $(TOP)/ip_log.c $(TOP)/ip_fil.h $(TOP)/ip_compat.h md5_u.o: $(TOP)/md5.c $(TOP)/md5.h $(CC) $(CCARGS) $(EXTRA) -c $(TOP)/md5.c -o $@ -radix_u.o: $(TOP)/md5.c $(TOP)/radix_ipf.h - $(CC) $(CCARGS) $(EXTRA) -c $(TOP)/radix.c -o $@ +radix_ipf_u.o: $(TOP)/md5.c $(TOP)/radix_ipf.h + $(CC) $(CCARGS) $(EXTRA) -c $(TOP)/radix_ipf.c -o $@ bpf_filter_u.o: $(TOP)/bpf_filter.c $(TOP)/pcap-ipf.h $(CC) $(CCARGS) $(EXTRA) -c $(TOP)/bpf_filter.c -o $@ -if_ipl.o: $(MODOBJS) +ipflkm.o: $(MODOBJS) ld -r $(MODOBJS) -o $(LKM) - ${RM} -f if_ipl + ${RM} -f ipflkm ipfrule.ko.5: ip_rulesx.o $(MLR) +.if ${MACHINE_ARCH} != amd64 ld -warn-common -r -d -o $(.TARGET:S/.ko/.kld/) ip_rulesx.o $(MLR) - ld -Bshareable -d -warn-common -o $(LKMR:S/.5$//) $(.TARGET:S/.ko/.kld/) + ld -Bshareable -d -warn-common -o $(LKMR:S/.5$//) $(.TARGET:S/.ko/.kld/) +.else + ld -warn-common -r -d -o $(.TARGET:S/.5$//) ip_rulesx.o $(MLR) + nm -g $(.TARGET:S/.5$//) | \ + awk '/^[^[:space:]]+ [^AU] (.*)$$/ { print ($$2=="C" ? "-N" : "-L") $$3 }' | \ + xargs -J% objcopy % $(.TARGET:S/.5$//) + +.endif + ipfrule.ko: ip_rulesx.o $(MLR) gensetdefs ip_rulesx.o $(MLR) $(CC) $(KCARGS) -c setdef0.c @@ -256,10 +286,17 @@ ipfrule.ko: ip_rulesx.o $(MLR) ld -Bshareable -o $@ setdef0.o ip_rulesx.o $(MLR) setdef1.o ipf.ko.5 ipl.ko.5: $(MODOBJS) +.if ${MACHINE_ARCH} != amd64 ld -warn-common -r -d -o $(.TARGET:S/.ko/.kld/) $(MODOBJS) ld -Bshareable -d -warn-common -o $(LKM:S/.5$//) $(.TARGET:S/.ko/.kld/) +.else + ld -warn-common -r -d -o $(.TARGET:S/.5$//) $(MODOBJS) + nm -g $(.TARGET:S/.5$//) | \ + awk '/^[^[:space:]]+ [^AU] (.*)$$/ { print ($$2=="C" ? "-N" : "-L") $$3 }' | \ + xargs -J% objcopy % $(.TARGET:S/.5$//) +.endif -ipf.ko ipl.ko: $(MODOBJS) +ipf.ko ipl.ko: $(MODOBJS) gensetdefs $(MODOBJS) $(CC) $(KCARGS) -c setdef0.c $(CC) $(KCARGS) -c setdef1.c @@ -268,6 +305,9 @@ ipf.ko ipl.ko: $(MODOBJS) ip_nat.o: $(TOP)/ip_nat.c $(TOP)/ip_nat.h $(TOP)/ip_compat.h $(TOP)/ip_fil.h $(CC) $(KCARGS) $(DFLAGS) -c $(TOP)/ip_nat.c -o $@ +ip_nat6.o: $(TOP)/ip_nat6.c $(TOP)/ip_nat.h $(TOP)/ip_compat.h $(TOP)/ip_fil.h + $(CC) $(KCARGS) $(DFLAGS) -c $(TOP)/ip_nat6.c -o $@ + ip_frag.o: $(TOP)/ip_frag.c $(TOP)/ip_frag.h $(TOP)/ip_compat.h $(TOP)/ip_fil.h $(CC) $(KCARGS) $(DFLAGS) -c $(TOP)/ip_frag.c -o $@ @@ -290,6 +330,11 @@ ip_fil.c: ip_fil.o: ip_fil.c $(TOP)/ip_fil.h $(TOP)/ip_compat.h $(TOP)/ip_nat.h $(CC) $(KCARGS) $(DFLAGS) $(COMPIPF) -c ip_fil.c -o $@ +ip_fil_compat.o: $(TOP)/ip_fil_compat.c $(TOP)/ipl.h $(TOP)/ip_fil.h \ + $(TOP)/ip_compat.h $(TOP)/ip_nat.h $(TOP)/ip_state.h + $(CC) $(KCARGS) $(DFLAGS) $(COMPIPF) $(COMPATIPF) \ + -c $(TOP)/ip_fil_compat.c -o $@ + ip_log.o: $(TOP)/ip_log.c $(TOP)/ip_compat.h $(TOP)/ip_fil.h $(CC) $(KCARGS) $(DFLAGS) -c $(TOP)/ip_log.c -o $@ @@ -307,16 +352,26 @@ ip_htable.o: $(TOP)/ip_htable.c $(TOP)/ip_compat.h $(TOP)/ip_fil.h \ $(TOP)/ip_lookup.h $(TOP)/ip_htable.h $(CC) $(KCARGS) $(DFLAGS) -c $(TOP)/ip_htable.c -o $@ +ip_dstlist.o: $(TOP)/ip_dstlist.c $(TOP)/ip_compat.h $(TOP)/ip_fil.h \ + $(TOP)/ip_lookup.h $(TOP)/ip_dstlist.h + $(CC) $(KCARGS) $(DFLAGS) -c $(TOP)/ip_dstlist.c -o $@ + ip_lookup.o: $(TOP)/ip_lookup.c $(TOP)/ip_compat.h $(TOP)/ip_fil.h \ - $(TOP)/ip_pool.h $(TOP)/ip_htable.h $(TOP)/ip_lookup.h + $(TOP)/ip_pool.h $(TOP)/ip_htable.h $(TOP)/ip_lookup.h \ + $(TOP)/ip_dstlist.h $(CC) $(KCARGS) $(DFLAGS) -c $(TOP)/ip_lookup.c -o $@ +radix_ipf.o: $(TOP)/md5.c $(TOP)/radix_ipf.h + $(CC) $(KCARGS) $(DFLAGS) -c $(TOP)/radix_ipf.c -o $@ + ip_trafcon.o: $(TOP)/ip_trafcon.c $(TOP)/ip_compat.h $(TOP)/ip_fil.h \ $(TOP)/ip_trafcon.h $(CC) $(KCARGS) $(DFLAGS) -c $(TOP)/ip_trafcon.c -o $@ vnode_if.h: $(VNODESHDIR)/vnode_if.src mkdir -p ../sys + mkdir -p ../rump/include/rump + mkdir -p ../rump/librump/rumpvfs if [ -f $(VNODESHDIR)/vnode_if.sh ] ; then \ sh $(VNODESHDIR)/vnode_if.sh $(VNODESHDIR)/vnode_if.src; \ fi @@ -325,10 +380,11 @@ vnode_if.h: $(VNODESHDIR)/vnode_if.src fi if [ -f ../sys/vnode_if.h ] ; then mv ../sys/vnode_if.h .; fi rmdir ../sys + rm -rf ../rump ml_ipl.o: vnode_if.h $(TOP)/$(MLD) $(TOP)/ipl.h -/bin/rm -f vnode_if.c - $(CC) -I. $(CFLAGS) $(DFLAGS) -c $(TOP)/$(ML) -o $@ + $(CC) -I. $(KCARGS) $(DFLAGS) -c $(TOP)/$(ML) -o $@ ip_rules.o: ip_rules.c $(TOP)/ip_rules.h $(CC) -I. $(CFLAGS) $(DFLAGS) $(COMPIPF) -c ip_rules.c -o $@ @@ -344,7 +400,7 @@ $(TOP)/ip_rules.h: ip_rules.c fi ip_rulesx.o: ip_rules.c $(TOP)/ip_rules.h - $(CC) -I. $(CFLAGS) $(DFLAGS) -DIPFILTER_COMPILED -c ip_rules.c -o $@ + $(CC) -I. $(KCARGS) $(DFLAGS) -DIPFILTER_COMPILED -c ip_rules.c -o $@ mlf_rule.o: $(TOP)/mlf_rule.c $(TOP)/ip_rules.h $(CC) -I. $(CFLAGS) $(DFLAGS) -c $(TOP)/mlf_rule.c -o $@ @@ -356,7 +412,7 @@ mlo_rule.o: $(TOP)/mlo_rule.c $(TOP)/ip_rules.h $(CC) -I. $(CFLAGS) $(DFLAGS) -c $(TOP)/mlo_rule.c -o $@ mlfk_rule.o: $(TOP)/mlfk_rule.c $(TOP)/ip_rules.h - $(CC) -I. $(CFLAGS) $(DFLAGS) -c $(TOP)/mlfk_rule.c -o $@ + $(CC) -I. $(KCARGS) $(DFLAGS) -c $(TOP)/mlfk_rule.c -o $@ ipf_y.o: ipf_y.c ipf_y.h $(TOP)/ipf.h ipf_l.h $(TOP)/opts.h $(CC) $(CCARGS) $(IPFBPF) -c ipf_y.c -o $@ @@ -427,10 +483,11 @@ ippool_y.o: ippool_y.c ippool_y.h $(TOP)/ip_pool.h ippool_l.h ippool_l.o: ippool_l.c ippool_y.h $(TOP)/ip_pool.h $(CC) $(CCARGS) -I. -c ippool_l.c -o $@ -ippool_y.c: $(TOOL)/ippool_y.y $(TOP)/ip_pool.h ippool_l.h +ippool_y.c: $(TOOL)/ippool_y.y $(TOP)/ip_pool.h ippool_l.h ippool_y.h (cd $(TOOL); make "DEST=$(HERE)" $(HERE)/$@) -ippool_y.h: ippool_y.c +ippool_y.h: $(TOOL)/ippool_y.y + (cd $(TOOL); make "DEST=$(HERE)" $(HERE)/$@) ippool_l.c: $(TOOL)/lexer.c $(TOP)/ip_pool.h (cd $(TOOL); make "DEST=$(HERE)" $(HERE)/$@) @@ -449,10 +506,10 @@ iptrafcon: $(IPTRAFCON) $(OBJ)/libipf.a .l.c: clean: - ${RM} -f ../ipf ../ipnat ../ipmon ../ippool ../ipftest + ${RM} -f ../ipf ../ipnat ../ipmon ../ippool ../ipftest ${RM} -f ../ipscan ../ipsyncm ../ipsyncs ${RM} -f *.core *.o *.a ipt ipfstat ipf ipfstat ipftest ipmon - ${RM} -f if_ipl ipnat ipfrule.ko* ipf.kld* ipfrule.kld* + ${RM} -f ipflkm ipnat ipfrule.ko* ipf.kld* ipfrule.kld* ${RM} -f vnode_if.h $(LKM) ioconf.h *.ko setdef1.c setdef0.c setdefs.h ${RM} -f ip_fil.c ipf_l.c ipf_y.c ipf_y.h ipf_l.h ${RM} -f ipscan ipscan_y.c ipscan_y.h ipscan_l.c ipscan_l.h @@ -481,8 +538,8 @@ install: /bin/cp $(TOP)/$$i /usr/include/netinet/; \ $(CHMOD) 444 /usr/include/netinet/$$i; \ done - -if [ -d /lkm -a -f if_ipl.o ] ; then \ - cp if_ipl.o /lkm; \ + -if [ -d /lkm -a -f ipflkm.o ] ; then \ + cp ipflkm.o /lkm; \ fi -if [ -d /modules -a -f ipf.ko ] ; then \ if [ -f /modules/ipl.ko ] ; then \ @@ -494,6 +551,7 @@ install: -if [ -d /modules -a -f ipfrule.ko ] ; then \ cp ipfrule.ko /modules; \ fi +.if ${MACHINE_ARCH} != amd64 -if [ -d /boot/kernel -a -f ipf.ko ] ; then \ if [ -f /boot/kernel/ipl.ko ] ; then \ cp ipf.ko /boot/kernel/ipl.ko; \ @@ -504,8 +562,29 @@ install: -if [ -d /boot/kernel -a -f ipfrule.ko ] ; then \ cp ipfrule.ko /boot/kernel; \ fi - -if [ -d /usr/lkm -a -f if_ipl.o ] ; then \ - cp if_ipl.o /usr/lkm; \ +.else + -if [ -d /boot/kernel -a -f ipf.ko ] ; then \ + if [ -f /boot/kernel/ipl.ko ] ; then \ + objcopy --only-keep-debug ipf.ko + /boot/kernel/ipl.ko.symbols; \ + objcopy --strip-debug \ + --add-gnu-debuglink=ipl.ko.symbols \ + ipf.ko /boot/kernel/ipl.ko; \ + else \ + objcopy --only-keep-debug ipf.ko \ + /boot/kernel/ipf.ko.symbols; \ + objcopy --strip-debug \ + --add-gnu-debuglink=ipl.ko.symbols \ + ipf.ko /boot/kernel/ipf.ko; \ + fi \ + fi + -if [ -d /boot/kernel -a -f ipfrule.ko ] ; then \ + objcopy --only-keep-debug ipfrule.ko /boot/kernel/ipfrule.ko.symbols; \ + objcopy --strip-debug --add-gnu-debuglink=ipfrule.ko.symbols ipfrule.ko /boot/kernel/ipfrule.ko; \ + fi +.endif + -if [ -d /usr/lkm -a -f ipflkm.o ] ; then \ + cp ipflkm.o /usr/lkm; \ fi -$(INSTALL) -cs -g wheel -m 755 -o root ipscan $(SBINDEST) (cd $(TOP)/man; make INSTALL=$(INSTALL) MANDIR=$(MANDIR) install; cd $(TOP)) @@ -533,8 +612,8 @@ install: (cd $(TOP)/man; make INSTALL=$(INSTALL) MANDIR=$(MANDIR) install; cd $(TOP)) coverage: - ksh -c 'for i in *.da; do j=$${i%%.da}.c; gcov $$j 2>&1 | egrep -v "y.tab.c|Could|Creating|_l\.c|\.h"; done' | sort -k 1n -k 3n > report - sort -k 1n -k 3n report | perl -e 'while(<>) { next if (/^0.00/); s/\%//g; @F=split;$$lc+=$$F[2];$$t += ($$F[0]/100)*$$F[2];} printf "%d of %d = %d%%\n", $$t, $$lc,($$t/$$lc)*100;' >> report + ksh -c 'for i in *.da; do j=$${i%%.da}.c; gcov $$j 2>&1 | egrep -v "y.tab.c|Could|Creating|_l\.c|\.h"; done' | sort -n > report + sort -n report | perl -e 'while(<>) { next if (/^0.00/); s/\%//g; @F=split;$$lc+=$$F[2];$$t += $$F[0]/100*$$F[2];} printf "%d of %d = %d%%\n", $$t, $$lc,$$t/$$lc*100;' >> report clean-coverage: /bin/rm -f *.gcov *.da diff --git a/contrib/ipfilter/BSD/Makefile.ipsend b/contrib/ipfilter/BSD/Makefile.ipsend index a83de1c6a92c..68edf1a0c656 100644 --- a/contrib/ipfilter/BSD/Makefile.ipsend +++ b/contrib/ipfilter/BSD/Makefile.ipsend @@ -1,5 +1,5 @@ # -# $Id: Makefile.ipsend,v 2.8 2002/05/22 16:15:36 darrenr Exp $ +# $Id$ # BINDEST=/usr/sbin @@ -23,7 +23,8 @@ MFLAGS="BINDEST=$(BINDEST)" "SBINDEST=$(SBINDEST)" "MANDIR=$(MANDIR)" \ "SOLARIS2=$(SOLARIS2)" "DEBUG=$(DEBUG)" "DCPU=$(CPU)" \ "CPUDIR=$(CPUDIR)" "LOOKUP=$(LOOKUP)" # -all build bsd-bpf : ipsend ipresend iptest +build: +all bsd-bpf : ipsend ipresend iptest iplang_y.o: $(TOP)/iplang/iplang_y.y (cd $(TOP)/iplang; $(MAKE) ../BSD/$(CPUDIR)/$@ $(MFLAGS) 'DESTDIR=../BSD/$(CPUDIR)' ) @@ -103,6 +104,6 @@ dlcommon.o: $(TOP)/ipsend/dlcommon.c sdlpi.o: $(TOP)/ipsend/sdlpi.c $(CC) $(DEBUG) $(CFLAGS) -c $(TOP)/ipsend/sdlpi.c -o $@ -install: +install: -$(INSTALL) -cs -g wheel -m 755 -o root ipsend ipresend iptest $(BINDEST) diff --git a/contrib/ipfilter/BSD/ipfadm-rcd b/contrib/ipfilter/BSD/ipfadm-rcd index 41f62b0223df..dbbd151b97e3 100755 --- a/contrib/ipfilter/BSD/ipfadm-rcd +++ b/contrib/ipfilter/BSD/ipfadm-rcd @@ -1,6 +1,6 @@ #!/bin/sh # -# Copyright (C) 2006 by Darren Reed. +# Copyright (C) 2012 by Darren Reed. # # See the IPFILTER.LICENCE file for details on licencing. # diff --git a/contrib/ipfilter/BSD/kupgrade b/contrib/ipfilter/BSD/kupgrade index 04b257d7ca60..30df4545f294 100644 --- a/contrib/ipfilter/BSD/kupgrade +++ b/contrib/ipfilter/BSD/kupgrade @@ -2,7 +2,7 @@ # PATH=/sbin:/usr/sbin:/bin:/usr/bin; export PATH argv0=`basename $0` - + os=`uname -s` rev=`uname -r` maj=`expr $rev : '\([0-9]*\)\.'` @@ -23,6 +23,7 @@ fi if [ -d /sys/dist/ipf ] ; then ipfdir=/sys/dist/ipf/netinet fi +mkdir -m 755 -p $ipfdir/../net confdir="$archdir/conf" if [ -f /dev/ipnat ] ; then major=`ls -l /dev/ipnat | sed -e 's/.* \([0-9]*\),.*/\1/'` @@ -30,7 +31,7 @@ if [ -f /dev/ipnat ] ; then else major=x fi - + if [ ! -f ip_rules.c -o ! -f ip_rules.h ] ; then echo "Trying to build ip_rules.c and ip_rules.h" make ip_rules.c @@ -43,8 +44,9 @@ if [ ! -f ip_rules.c -o ! -f ip_rules.h ] ; then fi fi -echo -n "Installing " -for j in auth frag nat proxy scan state sync pool htable lookup rules; do +echo -n "Installing into $ipfdir" +for j in auth frag nat proxy scan state sync pool dstlist htable lookup rules \ + dstlist; do for i in ip_$j.[ch]; do if [ -f "$i" ] ; then echo -n " $i" @@ -53,6 +55,12 @@ for j in auth frag nat proxy scan state sync pool htable lookup rules; do fi done done +echo -n " net/radix_ipf.h" +cp radix_ipf.h $ipfdir +chmod 644 $ipfdir/radix_ipf.h +echo -n " radix_ipf.c -> $ipfdir/radix_ipf.c" +cp radix_ipf.c $ipfdir/radix_ipf.c +chmod 644 $ipfdir/radix_ipf.c case $os in SunOS) @@ -88,14 +96,16 @@ if [ -f $ipfdir/ip_fil.c ] ; then chmod 644 $ipfdir/ip_fil.c fi -for i in ip_fil.h fil.c ip_log.c ip_compat.h ipl.h ip_*_pxy.c; do +for i in ip_nat6.c ip_fil.h fil.c ip_log.c ip_compat.h ipl.h ip_*_pxy.c \ + ip_fil_compat.c ipf_rb.h; do echo -n " $i" cp $i $ipfdir chmod 644 $ipfdir/$i done echo "" echo -n "Installing into /usr/include/netinet" -for j in auth compat fil frag nat proxy scan state sync pool htable lookup; do +for j in auth compat fil frag nat proxy scan state sync pool htable dstlist \ + lookup; do i=ip_$j.h if [ -f "$i" ] ; then echo -n " $i" @@ -103,7 +113,7 @@ for j in auth compat fil frag nat proxy scan state sync pool htable lookup; do chmod 644 /usr/include/netinet/$i fi done -for j in ipl.h; do +for j in ipl.h ipf_rb.h; do if [ -f "$j" ] ; then echo -n " $j" cp $j /usr/include/netinet/$j @@ -157,15 +167,19 @@ if [ $os = FreeBSD -a -f /sys/conf/files ] ; then mv files files.preipf4 cp -p files.preipf4 files fi - for i in htable pool lookup; do + for i in dstlist htable pool lookup; do grep ip_$i.c files >/dev/null 2>&1 if [ $? -ne 0 ] ; then echo "contrib/ipfilter/netinet/ip_$i.c optional ipfilter inet ipfilter_lookup" >> files fi done + grep ip_fil_compat.c files >/dev/null 2>&1 + if [ $? -ne 0 ] ; then + echo 'contrib/ipfilter/netinet/ip_fil_compat.c optional ipfilter inet ipfilter_compat' >> files + fi grep ip_sync.c files >/dev/null 2>&1 if [ $? -ne 0 ] ; then - echo 'contrib/ipfilter/netinet/ip_sync.c optional ipfilter inet ipfilter_sync' >> files + echo 'contrib/ipfilter/netinet/ip_sync.c optional ipfilter inet' >> files fi grep ip_scan.c files >/dev/null 2>&1 if [ $? -ne 0 ] ; then @@ -177,13 +191,19 @@ if [ $os = FreeBSD -a -f /sys/conf/files ] ; then fi fi if [ $os = NetBSD -a -f /sys/conf/files ] ; then + if [ -f /sys/netinet/files.ipfilter ] ; then + if ! grep -q ip_fil_compat.c /sys/netinet/files.ipfilter; then + echo 'file dist/ipf/netinet/ip_fil_compat.c ipfilter & ipfilter_compat' >> /sys/netinet/files.ipfilter + echo 'defflag opt_ipfilter.h IPFILTER_COMPAT' >> /sys/netinet/files.ipfilter + fi + fi cd /sys/conf if [ ! -f files.preipf4 ] ; then mv files files.preipf4 cp -p files.preipf4 files fi if [ $fullrev -ge 010600 -a $fullrev -lt 020000 ] ; then - for i in htable pool lookup; do + for i in dstlist htable pool lookup; do grep ip_$i.c files >/dev/null 2>&1 if [ $? -ne 0 ] ; then echo "file netinet/ip_$i.c ipfilter & ipfilter_lookup" >> files @@ -191,7 +211,7 @@ if [ $os = NetBSD -a -f /sys/conf/files ] ; then done grep ip_sync.c files >/dev/null 2>&1 if [ $? -ne 0 ] ; then - echo 'file netinet/ip_sync.c ipfilter & ipfilter_sync' >> files + echo 'file netinet/ip_sync.c ipfilter' >> files fi grep ip_scan.c files >/dev/null 2>&1 if [ $? -ne 0 ] ; then @@ -210,15 +230,18 @@ if [ $os = OpenBSD -a -f /sys/conf/files ] ; then cp -p files.preipf4 files fi if [ $fullrev -ge 030400 ] ; then - for i in htable pool lookup; do + for i in dstlist htable pool lookup; do grep ip_$i.c files >/dev/null 2>&1 if [ $? -ne 0 ] ; then echo "file netinet/ip_$i.c ipfilter & ipfilter_lookup" >> files fi done - grep ip_sync.c files >/dev/null 2>&1 + grep ip_fil_compat.c files >/dev/null 2>&1 if [ $? -ne 0 ] ; then - echo 'file netinet/ip_sync.c ipfilter & ipfilter_sync' >> files + echo 'file netinet/ip_fil_compat.c ipfilter & ipfilter_compat' >> files + fi + if [ $? -ne 0 ] ; then + echo 'file netinet/ip_sync.c ipfilter' >> files fi grep ip_scan.c files >/dev/null 2>&1 if [ $? -ne 0 ] ; then @@ -241,7 +264,7 @@ cat | (cd /usr/src/sys/modules/ipfilter; patch) <<__EOF__ KMOD= ipl SRCS= mlfk_ipl.c ip_nat.c ip_frag.c ip_state.c ip_proxy.c ip_auth.c \\ ! ip_log.c ip_fil.c fil.c - + .if !defined(NOINET6) CFLAGS+= -DUSE_INET6 .endif @@ -249,10 +272,10 @@ cat | (cd /usr/src/sys/modules/ipfilter; patch) <<__EOF__ ! CFLAGS+= -DIPFILTER=1 -DIPFILTER_LKM -DIPFILTER_LOG -DPFIL_HOOKS --- 5,15 ---- KMOD= ipl - SRCS= mlfk_ipl.c ip_nat.c ip_frag.c ip_state.c ip_proxy.c ip_auth.c \\ -! ip_log.c ip_fil.c fil.c ip_lookup.c ip_pool.c ip_htable.c \\ -! ip_sync.c ip_scan.c ip_rules.c - + SRCS= mlfk_ipl.c ip_nat.c ip_nat6.c ip_frag.c ip_state.c ip_proxy.c ip_auth.c \\ +! ip_log.c ip_fil.c fil.c ip_lookup.c ip_pool.c ip_dstlist.c ip_htable.c \\ +! ip_sync.c ip_scan.c ip_rules.c ip_fil_compat.c + .if !defined(NOINET6) CFLAGS+= -DUSE_INET6 .endif @@ -261,4 +284,29 @@ cat | (cd /usr/src/sys/modules/ipfilter; patch) <<__EOF__ ! -DIPFILTER_LOOKUP -DIPFILTER_COMPILED __EOF__ fi + +CONF=/sys/netinet/files.ipfilter +if [ -f $CONF -a $os = NetBSD ] ; then + for i in ip_nat6.c ip_dstlist.c radix_ipf.c; do + echo "Checking for $i in $CONF" + grep $i $CONF >/dev/null 2>&1 + if [ $? -ne 0 ] ; then + echo "Adding $i to $CONF" + sed -n -e /ip_nat.c/s/ip_nat.c/$i/p $CONF >> $CONF + fi + done +fi + +CONF=/sys/conf/files +if [ -f $CONF -a $os = FreeBSD ] ; then + for i in ip_nat6.c ip_dstlist.c radix_ipf.c; do + echo "Checking for $i in $CONF" + grep $i $CONF >/dev/null 2>&1 + if [ $? -ne 0 ] ; then + echo "Adding $i to $CONF" + sed -n -e /ip_nat.c/,/NORMAL/p $CONF | \ + sed -e s/ip_nat.c/$i/p >> $CONF + fi + done +fi exit 0 diff --git a/contrib/ipfilter/BSD/upgrade b/contrib/ipfilter/BSD/upgrade new file mode 100755 index 000000000000..d5f815438656 --- /dev/null +++ b/contrib/ipfilter/BSD/upgrade @@ -0,0 +1,46 @@ +#!/bin/sh +# +PATH=/sbin:/usr/sbin:/bin:/usr/bin; export PATH +argv0=`basename $0` + +case `pwd` in +*BSD) + ;; +*) + cd BSD + ;; +esac +os=`uname -s` +rev=`uname -r` +maj=`expr $rev : '\([0-9]*\)\.'` +min=`expr $rev : '[0-9]*\.\([0-9]*\)'` +sub=`expr $rev : '[0-9]*\.[0-9]*\.\([0-9]*\)'` +plat=`uname -p` +objdir=${os}-${rev}-${plat} + +# try to bomb out fast if anything fails.... +set -e + +for i in ipf ipfstat ipmon ipnat ippool; do + if [ ! -f /sbin/${i}.dist -a -f /sbin/${i} ] ; then + mv /sbin/${i} /sbin/${i}.dist + cp -p /sbin/${i}.dist /sbin/${i} + cp ${objdir}/${i} /sbin/ + fi + if [ ! -f /usr/sbin/${i}.dist -a -f /usr/sbin/${i} ] ; then + mv /usr/sbin/${i} /usr/sbin/${i}.dist + cp -p /usr/sbin/${i}.dist /usr/sbin/${i} + cp ${objdir}/${i} /usr/sbin/ + fi +done +if [ -f /boot/kernel/ipl.ko ] ; then + if [ ! -f /boot/kernel/ipl.ko.dist ] ; then + mv /boot/kernel/ipl.ko /boot/kernel/ipl.ko.dist + cp -p /boot/kernel/ipl.ko.dist /boot/kernel/ipl.ko + fi + if [ ! -f /boot/kernel/ipl.ko.symbols.dist ] ; then + mv /boot/kernel/ipl.ko.symbols /boot/kernel/ipl.ko.symbols.dist + fi + cp ${objdir}/ipf.ko /boot/kernel/ipl.ko +fi +exit 0 diff --git a/contrib/ipfilter/FAQ.FreeBSD b/contrib/ipfilter/FAQ.FreeBSD index 3b069c9f4b53..6539b4fc61be 100644 --- a/contrib/ipfilter/FAQ.FreeBSD +++ b/contrib/ipfilter/FAQ.FreeBSD @@ -1,4 +1,4 @@ -These are Instructions for Configuring A FreeBSD Box For NAT +These are Instructions for Configuring A FreeBSD Box For NAT After you have installed IP-Filter. You will need to change three files: @@ -54,7 +54,7 @@ fpx0 is the interface with the real internet address. /32 is the subnet mask 255.255.255.255, ie only use this ip address. -portmap tcp/udp 10000:65000 +portmap tcp/udp 10000:65000 tells it to use the ports to redirect the tcp/udp calls through @@ -67,7 +67,7 @@ reboots. In your /etc/rc.local put the line: -ipnat -f /etc/natrules +ipnat -f /etc/natrules To check and see if it is loaded, as root type ipnat -ls diff --git a/contrib/ipfilter/FWTK/ftp-gw.diff b/contrib/ipfilter/FWTK/ftp-gw.diff index be613423c86f..a47eba05e719 100644 --- a/contrib/ipfilter/FWTK/ftp-gw.diff +++ b/contrib/ipfilter/FWTK/ftp-gw.diff @@ -4,7 +4,7 @@ *** 11,31 **** --- 11,41 ---- */ - static char RcsId[] = "$Header: /devel/CVS/IP-Filter/FWTK/ftp-gw.diff,v 2.1 1999/08/04 17:30:30 darrenr Exp $"; + static char RcsId[] = "$Header$"; + /* + * Patches for IP Filter NAT extensions written by Darren Reed, 7/7/96 diff --git a/contrib/ipfilter/FWTK/fwtk_transparent.diff b/contrib/ipfilter/FWTK/fwtk_transparent.diff index a6c21fa1f1d1..8f0aeb46e123 100644 --- a/contrib/ipfilter/FWTK/fwtk_transparent.diff +++ b/contrib/ipfilter/FWTK/fwtk_transparent.diff @@ -124,7 +124,7 @@ diff -cr ../TIS.orig/fwtk/Makefile.config.solaris fwtk/Makefile.config.solaris *************** *** 11,30 **** # - # RcsId: "$Header: /devel/CVS/IP-Filter/FWTK/fwtk_transparent.diff,v 2.2 2001/02/28 09:36:06 darrenr Exp $" + # RcsId: "$Header$" # Your C compiler (eg, "cc" or "gcc") @@ -145,7 +145,7 @@ diff -cr ../TIS.orig/fwtk/Makefile.config.solaris fwtk/Makefile.config.solaris -Dgethostbyaddr=res_gethostbyaddr -Dgetnetbyname=res_getnetbyname \ --- 11,34 ---- # - # RcsId: "$Header: /devel/CVS/IP-Filter/FWTK/fwtk_transparent.diff,v 2.2 2001/02/28 09:36:06 darrenr Exp $" + # RcsId: "$Header$" + # + # Path to sources of ip_filter (ip_nat.h required in lib/hnam.c) diff --git a/contrib/ipfilter/FreeBSD-2.2/kinstall b/contrib/ipfilter/FreeBSD-2.2/kinstall index 5a4368eba122..421681fc0081 100755 --- a/contrib/ipfilter/FreeBSD-2.2/kinstall +++ b/contrib/ipfilter/FreeBSD-2.2/kinstall @@ -17,8 +17,8 @@ foreach i (ip_{auth,fil,frag,nat,pool,proxy,scan,state,sync}.[ch] fil.c \ case *.h: /bin/cp $i /usr/include/netinet/$i chmod 644 /usr/include/netinet/$i - breaksw - endsw + breaksw + endsw end echo "" echo "Copying /usr/include/osreldate.h to /sys/sys" diff --git a/contrib/ipfilter/FreeBSD-3/INST.FreeBSD-3 b/contrib/ipfilter/FreeBSD-3/INST.FreeBSD-3 index 5c30b57821f2..5b9de7ca0afb 100644 --- a/contrib/ipfilter/FreeBSD-3/INST.FreeBSD-3 +++ b/contrib/ipfilter/FreeBSD-3/INST.FreeBSD-3 @@ -10,7 +10,7 @@ To build a kernel with the IP filter, follow these seven steps: 4. build a new kernel 5. install the new kernel - + 6. If not using DEVFS, create devices for IP Filter as follows: mknod /dev/ipl c 79 0 mknod /dev/ipnat c 79 1 @@ -18,7 +18,7 @@ To build a kernel with the IP filter, follow these seven steps: mknod /dev/ipauth c 79 3 mknod /dev/ipsync c 79 4 mknod /dev/ipscan c 79 5 - + 7. reboot diff --git a/contrib/ipfilter/FreeBSD-3/kinstall b/contrib/ipfilter/FreeBSD-3/kinstall index 20f0369d6eaf..294e795ee4b5 100755 --- a/contrib/ipfilter/FreeBSD-3/kinstall +++ b/contrib/ipfilter/FreeBSD-3/kinstall @@ -18,8 +18,8 @@ foreach i (ip_fil.[ch] ip_nat.[ch] ip_frag.[ch] ip_state.[ch] fil.c \ case *.h: /bin/cp $i /usr/include/netinet/$i chmod 644 /usr/include/netinet/$i - breaksw - endsw + breaksw + endsw end echo "" echo "Linking /usr/include/osreldate.h to /sys/sys/osreldate.h" diff --git a/contrib/ipfilter/FreeBSD-4.0/kinstall b/contrib/ipfilter/FreeBSD-4.0/kinstall index ebd6e2e8a075..9233199215bf 100755 --- a/contrib/ipfilter/FreeBSD-4.0/kinstall +++ b/contrib/ipfilter/FreeBSD-4.0/kinstall @@ -20,8 +20,8 @@ foreach i (ip_{auth,fil,nat,pool,proxy,scan,state,sync}.[ch] fil.c \ case *.h: /bin/cp $i /usr/include/netinet/$i chmod 644 /usr/include/netinet/$i - breaksw - endsw + breaksw + endsw end echo "" echo "Linking /usr/include/osreldate.h to /sys/sys/osreldate.h" diff --git a/contrib/ipfilter/FreeBSD/kinstall b/contrib/ipfilter/FreeBSD/kinstall index 2b67b9ad995c..7d08503ed989 100755 --- a/contrib/ipfilter/FreeBSD/kinstall +++ b/contrib/ipfilter/FreeBSD/kinstall @@ -17,8 +17,8 @@ foreach i (ip_{auth,fil,frag,nat,pool,proxy,scan,state,sync}.[ch] fil.c \ case *.h: /bin/cp $i /usr/include/netinet/$i chmod 644 /usr/include/netinet/$i - breaksw - endsw + breaksw + endsw end echo "" grep iplopen $archdir/$karch/conf.c >& /dev/null diff --git a/contrib/ipfilter/HISTORY b/contrib/ipfilter/HISTORY index b500c20632ca..8b67de7bfe47 100644 --- a/contrib/ipfilter/HISTORY +++ b/contrib/ipfilter/HISTORY @@ -10,745 +10,268 @@ # and especially those who have found the time to port IP Filter to new # platforms. # -4.1.28 - Release 16 October 2007 - -backout changes (B1) & (B2) as they've caused NAT entries to persist for -too long and possibly other side effects. - -Still need to compile in our own radix.c for Solaris as the one in S10U4 -has a different alignment of structure members (causes panic) - -keep state doesn't work with multicast/broadcast packets (makes UPnP easier) - -ippool -l may only lists every 2nd pool's contents - -4.1.27 - Released 29 September 2007 - -SunOS5/replace script does not deal with i386 systems that have the -i86/amd64 directory pair. - -make BSD/kupgrade try to build ip_rules.[ch] before complaining - -Need to look for ipl.ko LKM on FreeBSD, not just ipf.ko - -Cleanup SunOS5 Makefile pieces, removing CPU, sunos5x86; buildsunos needs -to drive 32bit cc builds differently for sparc/i386 now. - -Update instructions for rebuilding FreeBSD kernels - -Make the target "freebsd" work for building ipfilter - -destroying NAT entries for blocked packets can lead to NAT table entry leak, -provide a counter of orphan'd NAT entries to track this problem. - -4.1.26 - Released 24 September 2007 - -Fix build problem for Solaris prior to S10U4 - -4.1.25 - Released 20 September 2007 - -stepping through structures with ioctls can lead to the wrong things -being free'd and panics - -if a NAT entry (such as an rdr) is created but the packet ends up being -blocked, tear down the NAT entry. - -fix fragment cache preventing keep state from functioning - -fix handling of \ to indicate a continued line in .conf files - -include port ranges in the allowed input for ipf when using "port = ()" - -only advance TCP state for packets on the leading edge of the window. (B1) - -using ipnat -l can lead to memory corruption in high stress situations - -track TCP sequence numbers with NAT so that it can do timeout advances -correctly inline with state - -ICMP checksums for some redirect'd packets are not adjusted correctly. - -IPv6 address components need to be explicitly cast to a 32bit pointer -boundary so that compilers don't try to access them as two 64bit -pieces (no guarantee is made that an Ipv6 address is on a 64bit -aligned address) - -filling up the ipauth packet queue can lead to no more packets being -processed. - -locking used to deref a nat entry causes a significant performance hit - -m_pulldown isn't properly handled, leading to possible panics with ICMPv6 -packets - -IPv6 fragment handling doesn't allow for "keep frag" to work - -build on Solaris10 Update4 with pfhooks in the kernel - -logging of Ipv6 packets with extension headers fix - Miroslaw Luc - -4.1.24 - Released 8 July 2007 - -patch from Stuart Remphrey to address recursive mutex lock with TCP state - -add hash table bucket stats display to ipnat -s - -give ASSERT some teeth for user compiles - -initialising ipf_global, ipf_frcache, ipf_mutex should all be done very -early on - -do some caddr_t cleanup, where possible - -fr_ref no longer tracks the number of children rules in a group for head rules - -make sure all BCOPY* have a value assigned to something - -fix possible use of icmp pointer after pullup makes it invalid - -resolve compile problems related to FreeBSD tree - -4.1.23 - Released 31 May 2007 - -NAT was not always correctly fixing ICMP headers for errors - -some TCP state steps when closing do not update timeouts, leading to -them being removed prematurely. (B2) - -fix compilation problems for netbsd 4.99 - -protect enumeration of lists in the kernel from callout interrupts on -BSD without locking - -fix various problems with IPv6 header checks: TCP/UDP checksum validation -was not being done, fragmentation header parsed dangerously and routing -header prevented others from being seen - -fix gcc 4.2 compiler warnings - -fix TCP/UDP checksum calculation for IPv6 - -fix reference after free'ing ipftoken memory - -4.1.22 - Released 13 May 2007 - -fix endless loop when flushing state/NAT by idle time - -4.1.21 - Released 12 May 2007 - -show the number of states created against a rule with "-v" for ipfstat - -fix build problems with FreeBSD - -make it possible to flush the state table by idle time and TCP state - -fix flushing out idle connections when state/NAT tables fill - -print out the TCP state population with ipfstat/ipnat - -stop creation of state table orphans via return-*/fastroute - -fix printing out of rule groups - they now only appear once - -4.1.20 - Released 30 April 2007 - -adjust TCP state numbers, making 11 closed (was 0) to better facilitate -detecting closing connections that we can wipe out when a SYN arrives -that matches the old - -make it compile on Solaris10 Update3 - -structures used for ipf command ioctls weren't being freed in timeout -fashion on solairs - -use NL_EXPIRE, not ISL_EXPIRE, for expiring NAT sessions - -adjust TCP timeout values and introduce a time-wait specifc timeout -to get a better TCP FSM emulation and one that can hopefully do a better -job of cleaning up in a speedy fashion than previous - -refactor the automatic flushing of TCP state entries when we fill up, -but use the same algorithm as before but now it hopefully works - -only 2 out of 4 interface names were being changed by ipfs when -interface renaming was being used for state entries - -add ipf_proxy_debug to ipf-T - -matching of last fragments that had a number of bytes that wasn't a -multiple of 8 failed - -some combinations of TCP flags are considered bad aren't picked up as such, -but these may be possible with T/TCP - -4.1.19 - Released 22 February 2007 - -Fix up compilation problems with NetBSD and Solaris. - -4.1.18 - Released 18 February 2007 - -fix compiling on Tru64 - -fix listing out filter rules with ipfstat (delete token at end of -the list and detect zero rule being returned.) - -fix extended flushing of NAT tables (was clearing out state tables) - -fix null-pointer deref in hash table lookup - -fix NAT and stateful filtering with to/reply-to on destination interface - -4.1.17 - Released 20 January 2007 - -make flushing pools that are still in use mark them for deletion and -have attempting to recreate them clear the delete flag - -walking through the NAT tables with ioctls caused lock recursion - -fix tracking TCP window scaling in the state code - -4.1.16 - Released 20 December 2006 - -allow rdr rules to only differ on the new port number - -when creating state entry orphans, leave them on the linked list but not -attached to the hash table and mark them visible as orphans in "ipfstat -sl" - -log state removed when unloading differently to allow visible cues - -return ipf ticks via SIOCGETGS for /dev/ipnat so "ipnat -l" can display ttl - -abort logging a packet if the mbuf pointer is null when ipflog is called - -Some NetBSD's have a selinfo.h instead of select.h - -SIOCIPFFL was using copyoutptr and should have been using bcopy for /dev/ipauth - -listing accounting rules using ioctl interface wasn't possible - -fix leakage of state entries due to packets not matching up with NAT - -improve ICMP error packet matching with state/NAT - -fix problems with parsing and printing "-" as an interface name in ipnat.conf - -4.1.15 - Released 03 November 2006 - -Add in automatic flushing of NAT, like state, table if it fills up too much - -Update comments in the code for NAT checksum adjustments - -Fix compiling on FreeBSD 5.4 and 6.0 - -prevent panics from read/write IOs trying to use uninitialised structures - -Newer NetBSD should use malloc() instead of MALLOC() in the kernel where -the size is not staticly defined - -Some gcc warning message cleanup from NetBSD - -Missing include for on Solaris for poll work - -NetBSD now uses opt_ipfilter.h, not opt_ipfilter_log.h - -4.1.14 - Released 04 October 2006 - -rewrite checksum alteration for ICMP packets being NAT'd to use a sane -algorithm that can be understood...now it needs better comments - -fix 1 byte error in checksum validation perl script - -remove unused files in lib directory - -ipftest will say "bad-packet" if it has been freed rather than just "blocked" - -make it possible to load IP address pools from external files in ippool.conf - -update copyright messages in tools directory - -consolidate ioctl hanlding source code into fil.c - -make ipfstat, ippool, ipnat retrieve information via ioctls rather than /dev/kmem - -4.1.13 - Released 4 April 2006 - -fix bug where null pointers introduced by proxies could cause a crash - -pass out the rule flags with SIOCAUTHW - -force loading NAT rules with bad proxy labels to cause an error - -nat_state is used unsafely in calls to fr_addstate - -make return-rst and return-icmp* work with auth rules - -4.1.12 - Released 28 March 2006 - -poll support on FreeBSD/NetBSD needs to use selrecord/selwakeup - -make the fastroute code used by ipftest invoke state/NAT - -move verbose/debug macros out of fil.c and into ip_fil.h (for wider use) - -remove unused code in fr_fastroute - -fix NAT with rules that specify forward and reverise interfaces - -add missing ipfsync_canread() and ipfsync_canwrite() - -behaviour of \ on the end of a line in ipf.conf does not match older behaviour - -remove duplicate statistics line output with "ipfstat -s" - -4.1.11 - Released 19 March 2006 - -Patch for NAT with ipfsync from N. Ersen (SESCI) - www.enderunix.org - -NetBSD coverity report fixes (from run 5) - -Possible to reacquire ipf_auth without releasing it in some circumstances - -Locking in FreeBSD's iplioctl for ipf_global isn't present like it shoudl be - -Add poll support for platforms I can build on: NetBSD, FreeBSD, Solaris, Linux - -Using auth rules to return "keep state" got broken with pushing fr_addstate -call into fr_firewall - -all use of '!' in map/rdr rules to match use in ipf configs - -add -L command line option to ipmon to set the default syslog facility - -looking up a port number is more complex than needed in ipft_tx.c - -allow lib/getport to work when neither tcp or udp are specified in a rule - -remove some dead code from lib/addicmpc, lib/facpri.c, lib/icmpcode.c - -program in some more cases where TCP packets fail an initial in-window -check but should be allowed to match - -filter rule added with NAT/state handling of SIOCSTPUT doesn't properly -initialise all fields, making it possible to panic - -simplify NAT ICMP error handling where it updates checksums - -rename "min" variables to "xmin" on NetBSD to avoid problems with the -macro "min" - -#ifdef's for NetBSD compile incorrect for pfil interface - -support select/poll on NetBSD - -copying out a packet with an auth rule fails (EFAULT) because the wrong -pointer is passed to copyoutptr - -ip_len/ip_off where byte swapped twice instead of once for packets -going to be stored on the auth queue - -change timeout queue manipulation functions to make fewer mutex calls - -fix use of skip rules with groups -fix coding problems discovered by the coverity project for FreeBSD - -update BPF program validation with FreeBSD changes - -4.1.10 - Released 6 December 2005 - -Expand regression testing to cover more features - -Add "coverage" build target for BSD - -Fix building 64bit sparc target for Solaris - -Add IPv6 mobility header to list of accepted keywords for V6 headers - -Resolve locking problems on Solaris when sending RST/icmp packets - -#ifdef's for IPFILTER_BPF need to check if words are defined before -using them in comparisons - -Add checking for SACK permitted option in TCP SYN packets - -Fix loading anonymous pools from inline rule configuration groups - -Add -C command line option to ipftest - -Include extra "const" from NetBSD - -Don't require SIOCKSTLCK for SIOCSTPUT - -Fix some use of "sticky" on NAT rules - -Fix statistical counting of deleting state for TCP connections - -Fix compile problems caused by changes to is_opt/is_optmsk in ip_sync.c - -Fix TCP out-of-window (OOW) problems: -- window scaling turned off if one chose for its scale factor -- Microsoft Windows TCP sends the "next packet" to the right of the window - when using SACK and filling in a hole - -4.1.9 - Released 13 August 2005 - -make ipfilter fix IPv4 header checksums for outgoing packets if BRIDGE_IPF -is defined when compiled. - -move the definition of SIOCPROXY from ip_nat.h to ip_proxy.h - -make the BSD/upgrade script more instructive about the requiements for -ip_rules.[ch] when it is run - -register for interface events on FreeBSD (>5.2.1) and NetBSD so that -"ipf -y" is not not requried to tell ipfilter about interface changes. - -for "quick" rules that do "keep state", move the state adding into the rule -evaluation so that we can detect it failing as rules are evaluated and -continue on to the next rather than wait until we're done and it's too late -to recover for more rule processing. - -mark ICMP packets advertising an MTU that's too small as being bad - -rework ipv6 header parsing to get better code reuse and fix logic errors -in dealing with ipv6 packets containing fragment headers. Also, where a -protocol handler was doing both v4 & v6, make a seperate function for each. - -build for both amd64 and i86pc (32bit) on Solaris10 and later, if possible - -include start of work to get IPFilter working on AIX 5.3 - -Use FI_ICMPERR flag rather than try to compute its equivalent all the time - -Rewrork IPv6 extension header parsing to get better code reuse - -Add missing timeout on Linux - -Fix for locking when reading from ipsync (Frank Volf) - -Fix insertion/appending of rules that use a collection number - -Somehow turning up the spl knob to splnet disappeared on platforms that still -use the spl interface. - -fix problems with "ipf -T" not listing multiple variables properly - -4.1.8 - Released 29 March 2005 - -include path from Phil Dibowitz for sorting ipfstat -t output by source or -destination port. - -fix a bug in printing rules where interface names could not be printed, -even if they're in the rule structure. - -fix BSD/kupgrade to correctly change ipfilter lkm Makefile for FreeBSD - -add 2 new features to SIOCGNATL: -- if IPN_FINDFORWARD is set, check if the respective MAP is already - present in the outbound table -- if IPN_IN is set, search for a matching MAP entry instead of RDR - (Peter Potsma) - -turn off function inlining for freebsd 5.3+ - -UDP doesn't pullup enough data which can sometimes cause a panic. -Fix other protocols, as required, where a similar problem may exist. - -overhaul the timeout queue management, especially that for user defined queues -which are now only freed in an orderly manner. - -4.1.7 - Released 13 March 2005 - -Using the GRE call field is almost impossible because it is unbalanced and -both call fields are not present in each v1 header. - -Fix a problem where it was possible to load duplicate rules into ipf - -patch from John Wehle to address problems with fastroute on solaris - -Copying data out for ipf -z failed because it tried to copy out to an address -that is a kernel pointer in user space. - -add "ip" timeout for both NAT & state that's for non-TCP/UDP/ICMP - -synch up with NetBSD's changes - -fix problems parsing long lines of text in the ftp proxy where they would not -be parsed properly and stop the session from working - -enhance the PPTP proxy so that it tries to decode messages in the TCP stream -so it knows when to create and destroy the state/nat sessions for GRE. There -are also 4 new regression tests for it, testing map/rdr rules. - -impose some limits on the size of data that can be moved with SIOCSTPUT in -the NAT code and also prevent a duplicate session entry from being created -using this method. - -add a new flag (IPN_FINDFORWARD) to NAT code that can be used with SIOCGNATL -to check if it is possible to create an outgoing transparent NAT mapping to -compliment the redirect being investigated. - -Linux requires that the checksums in the IP header get adjusted - -only resolve unknown interfaces in fr_stinsert, and nuke all interface pointers -in SIOCSTPUT to prevent bad data being loaded from userspace. - -make the byte counting for state correct (was counting data from ICMP packet -twice) - -print out the keyword "frag-body" if the flag is set. - -fix ipfs loading/restoring NAT sessions - -patch from Frank to correctly format IP addresses in ipfstat -t output - -parsing port numbers in ipf/ipnat was confusing as the port number was returned -in an int that was also overloaded to be the suceess/failure. instead, change -the port using pass by reference and only use the return value for indicating -success or failure. - -4.1.6 - Released 19 February 2005 - -add a new timeout number to NAT (fr_defnatipage) that is used for all -non-TCP/UDP/ICMP protocols - default 60 seconds. - -buffer leak with bad nat - David Gueluy - -fix memory leak with state entries created by proxies - -eliminate copying too much data into a scan buffer - -allow a trailing protocol name for map rules as well as rdr ones - -fix bug in parsing of <= and > for NAT rules (two were crossed over) - -FreeBSD's iplwrite hasn't kept pace with iplread's prototype - -expand documention on the karma of using "auto" in ipnat map rules - -add matching on IP protocol to ipnat map rules - -allow ippool definitions to contain no addresses to start with - -Linux NAT needs to modify the IP header checksum as it gets called after it -has been computed by IP. - -UDP was missing a pullup for packet header information before examining -the header - -4.1.5 - Released 9 January 2005 - -all rules were being converted into "dup-to" rules in the kernel - -fix two ftp proxy problems: 1st, buffer needs to be bigger for fitting in -complete RETR/CWD commands, 2nd is () use in 227 messages isn't copied -over correctly. - -response to CWDs -revert ip_off back to network byte order in the ICMP error packet that -gets generated. - -4.1.4 - Released 9 January 2005 - -force NAT rules to only match ipv4 NAT rules (which all are, currently, -by default) - -include state synchronisation fixes from Frank Volf - -make the maximum log size for internally buffered log entries accessible -via "ipf -T" - -redesign start of fr_check() to avoid putting duplicate information in -ipfilter about how much data needs to be pulled up for a protocol to be -properly filtered. - -tidy up sending ICMP error messages - some bad inputs could result in -data not being freed and/or no error returned. - -make the maximum size of the log buffer run-time tunable - -fix bug in parsing TCP header when looking for MSS option that could make -the system hang - -change pool lookups that fail to find a match to return "no match" -rather than fail. - -add run-time tunable debugging for proxy support code and FTP proxy. - -fix state table updates for entries where the first packet as an ICMPv6 -multicast message - -fix hang when flushing state for v4/v6 and other (v6/v4) entries are present -too - -attaching filtering to ipv6 pfil hook wasn't present for solaris - -don't allow rules with "keep state" and "with oow" - -move a bunch of userland only code from fil.c to ip_fil.c - -make fr_coalesce() more resiliant to bad input, just returning an error -instead of crashing, making calling it easier in many places - -When m_pulldown doesn't return NULL, it doesn't necessarily return a pointer -to the same mbuf passed in as the first arg. - -remove fr_unreach and use ENETUNREACH by default. - -printing out of tag data in ipf rules doesn't match input syntax - -ipftest(1) man page update - -ipfs command line option parsing still rejects some valid syntaxes - -SIGHUP handling by ipmon was not as safe as it could be - -fix various parsing regressions, including "", "tcpudp", ordering -of "keep" options - -patches from Frank Volk: add udp_acktimeout to sysctl list for FreeBSD, -ICMP packet length not calculated correctly in send_icmp_err, reply-to -not printed by ipfstat, keep state with icmp passing (mtrr) - -patches for return-rst and return-icmp from Attila Fueloep -(lichtscheu@gesindel.org) - -4.1.3 - Released 18 July 2004 - -do some more fine tuning on NAT checksum adjustments - -correct IP address byte order in proxy setup for ipsec/pptp - -man page updates - -fix numerous problems with ipfs operation - -complete new syntax for ipmon.conf in its parser and update the sample file - -assign error value consistantly in fastroute code - -rewrite allocation of mbufs in send_reset/send_icmp_err to better use -mbuf clusters and size calculations - -resolve problem with linux panic'ing because the wrong flag was being -passed to skb_clone/skb_alloc - -enable use of shared/exclusive locks on freebsd5 and above - -do not rely on m_pkthdr.len to be valid all the time for mbufs on modern BSD -and so use mbufchainlen to get the mbuf length instead - -replace lots of COPYIN/COPYOUT with BCOPYIN/BCOPYOUT where the data is -going to be on the stack and not in userland - -packet buffer pointers were not refreshed & used properly in fr_check() - -include extra bits for OpenBSD 3.4 & 3.5. - -fix ipf/ipnat parsing regression problems with v3.4 - -4.1.2 - RELEASED - 27 May 2004 - -add state top for ipv6 - -fix numerous parsing regressions - -change sample proxies to use SIOCGNATL with the new API - -allow macro names to contain underscores (_) - -split the parser into a collection of dictionaries so that keywords do -not interfere with resolving hostnames and portnames - -fix ipfrule LKM loading on freebsd - -support mapping a fixed range of ports to a single port - -fix timeout queue use by proxies with private queues - -handle space-led ftp server replies properly - -fix timeout queue management - -fix fastroute, generation of RST & ICMP packets and operation with to/fastroute - -resolve further linux compatibility problems - -replace the use of COPYIN with BCOPYIN for platforms that provide ioctl -args on the stack - -allow flushing of ipv6 rules independant of ipv4 rules - -correct internal ipv6 checksum calculations - -if a 'keep state' rule fails to create state, block the packet rather -than let it through - -correct all checksums in regression tests and correct NAT code to adjust -checksums correctly. - -fix ipfs -R/-W - -4.1.1 - RELEASED - 24 March 2004 - -allow new connections with the same port numbers as an existing one -in the state table if the creating packet is a SYN - -timeout values have drifted, incorrectly, from what they were in 3.4 - -FreeBSD - compatibility changes for 5.2 - -don't match on sequence number (as well) for ICMO ECHO/REPLY, just the -ICMP Id. field as otherwise thre is a state/NAT entry per packet pair -rather than per "flow" - -fr_cksum() returned the wrong answer for ICMP - -Linux: -- get return-rst and return-icmp working -- treat the interface name the same as if_xname on BSD - -adjust expectations for TCP urgent bits based on observed traffic in the -wild - -openbsd3.4 has ip_len/ip_off in network byte order when ipfilter is called - -fix flushing of hash pool gorups (ippool -F) as well as displaying them -(ippool -l) - -passing of pointers to interface structures wrong for HP-UX/Solaris with -return-* rules. - -Make the solaris boot script able to run on 2.5.1 - -ippool related files missing from Solaris packages - -The name /dev/ippool should be /dev/iplookup - -add regression testing for parsing long interface names in nat rules, -along with mssclamp and tags. Also add test for mssclamp operation. - -ttl displayed for "ipfstat -t" is wrong because ttl is not computed. - -parse logical interface names (Sun) - -unloading LKMs was only working if they were enabled. - -sync'ing up NAT sessions when NICs change should cause NAT rules to -re-lookup name->pointer mappings - -not all of the ippool ioctl's are IOWR and they should be because they -use the ipfobj_t for passing information in/out of the kernel. leave the -old values defined and handle them, for compatibility. - -pool stats wrong: ippoolstate used where ipoolstat should be, hash table - statistics not reported at all - -fr_running not set correctly for OpenBSD when compiled into the kernel - -Allow SIOCGETFF while disabled - -Fix mssclamp with NAT (pasing and printing of the word, plus wrong bytes -altered. How do you say "untested" ?) +5.1.2 - RELEASED - 22 Jul 2012 + +3546266 macro letters could be more consistent +3546265 not all of the state statistics are displayed +3546261 scripts for updating BSD environment out of date +3546260 compiler warnings about non-integer array subscript +3546259 asserting numdereflists == 0 is not correct +3546258 expression matching does not see IPF_EXP_END +3544317 ipnat/ipfstat are not using ipfexp_t +3545324 proxy checksum calculation is not hardware aware +3545321 FTP sequence number adjustment incorrectly applied +3545320 EPSV is not recognised +3545319 move nat rule creation to ip_proxy.c +3545317 better feedback of checksum requirements for proxies +3545314 ftp proxy levels do not make sense +3545312 EPRT is not supported by ftp proxy +3544318 ipnat.conf parsing ignores LHS address family +3545309 non-ipv6 safe proxies do not fail with ipv6 +3545323 NAT updates the source port twice +3545322 ipv6 nat rules cannot start proxies +3544314 bucket copyout tries to copy too much data +3544313 remove nat encap feature +3546248 compat rule pointer type mismatch +3546247 UDP hardware checksum offload not recognised +3545311 ifp_ifaddr does not find the first set address +3545310 ipmon needs ipl_sec on 64bit boundary +3545326 reference count changes made without lock +3544315 stateful matching does not use ipfexp_t +3543493 tokens are not flushed when disabled +3543487 NAT rules do not always release lookup objects +3543491 function comments in ip_state.c are old +3543404 ipnat.conf parsing uses family/ip version badly +3543403 incorrect line number printed in ipnat parsing errors +3543402 Not all NAT statistics are printed +3542979 NAT session list management is too simple +3542978 ipv4 and ipv6 nat insert have common hash insertion +3542977 ipnat_t refence tracking incomplete +3542975 proxies must use ipnat_t separately +3542980 printing ipv6 expressions is wrong +3542983 ippool cannot handle more than one ipv6 address +3543018 mask array shifted incorrectly. +3542974 reason for dropping packet is lost +3542982 line numbers not recorded/displayed correctly by ipf +3542981 exclamation mark cuases trouble with pools +3541655 test suite checksums incorrect +3541653 display proxy fail status correctly +3540993 IP header offset excluded in pullup calculations +3540994 pullupmsg does not work as required +3540992 pointer to ipv6 frag header not updated on pullup +3541645 netmask management adds /32 for /0 +3541637 ipnat parser does not zero port fields for non-port protocol +3541635 pool names cannot by numbers +3540995 IPv6 fragment tracking does not always work +3540996 printing of nextip for ipv6 nat rules is wrong +3540999 ipnat.conf parsing has trouble with icmpidmap for ipv6 +3540825 whois output parsing error for ipv6 +3540814 ipfd_lock serves no purpose +3540810 lookup objects need tail pointers +3540809 refactor hash table lookups for nat +3540819 radix tree does not work with ipv6 +3540820 mutex emulation should be logged +3540828 ipfstat filtering with -m fails tests +3536480 ippool could be more like the others +3536477 pool printing not uniform +3536483 flushing empty destination lists causes panic +3536481 more use of bzero after KMALLOC required +3536479 ipnat.conf line numbers not stored +3536484 Makefile missing dependency for ippool +3536199 TFTP proxy requires something extra +3536198 ICMP checksum out by one +3536203 ipnat does not return an error +3536201 ipf.conf parsing too address friendly +3536200 printing of bytes/packets not indented +3497941 ipv4 multicast detection incorrect on little endian +3535361 to interfaces printed out of order +3535363 ipf parser is inconsistent +3532306 deleting ipnat rules does not work +3532054 new error required for ipf_rx_create +3532053 icmp6 checksums wrong +3532052 icmpv6 state check with incorrect length +3531871 checksum verification wants too many icmp6 bytes +3531870 ipnat.conf parsing needs to support inet6 +3532048 error in ipf group parsing +3531868 ICMPV6 checksum not validated +3531893 ipftest exits without error for bad input +3531890 whois pool parsing builds bad structures +3531891 icmpv6 text parsing ignorant of icmp types +3531653 rewrite with icmp does not work +3530563 NAT operations fail with EPERM +3530544 first pass at gcc -Wextra cleanup +3530540 lookup create functions do not set error properly +3530539 ipf_main_soft_destroy doesn't need 2nd arg +3530541 reorder structure for better packing +3530543 ipnat purge needs documentation +3530515 BSD upgrade script required +3528029 ipmon bad-mutex panic +3530247 loading address pools light on input validation +3530255 radix tree delete uses wrong lookup +3530254 radix tree allocation support wrong +3530264 ipmon prints qd for some 64bit numbers +3530260 decapsulate rules not printed correctly. +3530266 ipfstat -v/-d flags confused +2939220 why a packet is blocked is not discernable +2939218 output interface not recorded +2941850 use of destination lists with to/dup-to beneficial +3457747 build errors introduced with radix change +3535360 timeout groups leak +3535359 memory leak with tokens +3535358 listing rules in groups requires tracking groups +3535357 rule head removal is problematic +3530259 not all ioctl error checked wth SIOCIPFINTERROR +3530258 error routine that uses fd required +3530253 inadequate function comment blocks +3530249 walking lookup tables leaks memory +3530241 extra lock padding required for freebsd +3529901 ipf returns 0 when rules fail to load +3529491 checksum validation could be better +3529486 tcp checksum wrong for ipv6 +3533779 ipv6 nat rules missing inet6 keyword +3532693 ipnat.conf rejects some ipv6 addresses +3532691 ipv4 should not be forced for icmp +3532689 ipv6 nat rules do not print inet6 +3532688 ipv6 address always printed with "to " +3532687 with v6hdrs not supported like with ipopts +3532686 ipf expressions do not work with ipv6 +3540825 whois output parsing error for ipv6 +3540818 NAT for certain IPv6 ICMP packets should not be allowed +3540815 memory leak with destination lists +3540814 ipfd_lock serves no purpose +3540810 lookup objects need tail pointers +3540809 refactor hash table lookups for nat +3540808 completed tokens do not stop iteration +3530492 address hash table name not used +3528029 ipmon bad-mutex panic +3530256 hook memory leaked +3530271 pools parsing produces badly formed address structures +3488061 cleanup for illumos build +3484434 SIOCIPFINTERROR must work for all devices +3484067 mandoc -Tlint warnings to be fixed +3483343 compile warning in ipfcomp.c +3482893 building without IPFILTER_LOG fails +3482765 building netbsd kernel without inet6 fails +3482116 ipf_check frees packet from ipftest +3481663 does not compile on solaris 11 + +5.1.1 - RELEASED - 9 May 2012 + +3481322 ip_fil_compat.c needs a cleanup +3481211 add user errors to dtrace +3481152 compatibility for 4.1 needs more work +3481153 PRIu64 problems on FreeBSD +3481155 ipnat listing incorrect +3480543 change leads to compat problems +3480538 compiler errors from earlier patch +3480537 ipf_instance_destroy is incomplete +3480536 _fini order leads to panic +3479991 compiler warnings about size mismatches +3479974 copyright dates are wrong (fix) +3479464 add support for leaks testing +3479457 %qu is not the prefered way +3479451 iterators leak memory +3479453 nat rules with pools leak +3479454 memory leak in hostmap table +3479461 load_hash uses memory after free +3479462 printpool leaks memory +3479452 missing FREE_MB_T to freembt leaks +3479450 ipfdetach is called when detached +3479448 group mapping rules memory leak +3479455 memory leak from tuning +3479458 ipf must be running in global zone +3479460 driver replace is wrong +3479459 radix tree tries to free null pointer +3479463 rwlock emulation does not free memory +3479465 parser leaks memory +3475959 hardware checksum not correctly used +3475426 ip pseudo checksum wrong +3473566 radix tree does not delete dups right +3472987 compile is not clean +3472337 not everything is zero'd +3472344 interface setup needs to be after insert +3472340 wildcard counter drops twice +3472338 change fastroute interface +3472335 kernel lock defines not placed correctly +3472324 ICMP INFOREQ/REPLY not handled +3472330 multicast packets tagged by address +3472333 ipf_deliverlocal called incorrectly +3472345 mutex debug could be more granular +3472761 building i19 regression is flawed +3456457 use of bsd tree.h needs to be removed +3460522 code cleanup required for building on freebsd +3459734 trade some cpu for memory +3457747 build errors introduced with radix change +3457804 build errors from removal of pcap-int,h +3440163 rewrite radix tree +3428004 snoop, tcpdump, etherfind readers are unused +3439495 ipf_rand_push never called (fix brackets) +3437732 getnattype does not need to use ipnat_t (fix variable name) +3437696 fr_cksum is a nightmare +3439061 ipf_send_ip doesn't need 3rd arg +3439059 ipid needs to be file local +3437740 complete buildout of fnew +3438575 add dtrace probes to block events +3438347 comment blocks missing softc +3437687 description of ipf_makefrip wrong +3438340 more stats as dtrace probes +3438316 free on nat structure uses fixed size +3437745 nat iterator using the wrong size +3437710 fail checksum verification if packet is short +3437696 fr_cksum is a nightmare +3437732 getnattype does not need to use ipnat_t +3437735 rename ipf_allocmbt to allocmbt +3437697 fr_family to version assignment is wrong +3437746 ap_session_t has unused fields +3437747 move softc structure to .h file (ip_state.c) +3437704 there is no DTRACE_PROBE5 +3437748 wrong interface in qpktinfo_t +3437729 create function to hexdump mb_t +3438273 msgdsize should be easier to read +3437683 object direction not set for 32bit +3433767 calling ip_cksum could be easier +3433764 left over locking +3428015 printing proxy data size is useless +3428013 add M_ADJ to hide adjmsg/m_adj +3428012 interface name is not always returned correctly +3428002 ip_ttl is too low +3427997 ipft readers do not set buffer length +3426558 resistence is futile +3424495 various copy-paste errors +1826936 shall we allow ipf to be as dumb as its admin +3424477 specfuncs needs to go +3424484 missing fr_checkv6sum +3424478 one entry at a time +2998760 auth rules do not mix well with to/dup-to/fastroute +3424195 add ctfmerge to sunos5 makefile +3424132 some dtrace probes to start with +3423812 makefile needs ip_frag.h for some files +3423817 reference count useful in verbose output +3423800 walking lists does not drop reference +3423805 fragmentation stats not reported correclty +3423808 ip addresses reportied incorrectly with ipfstat -f +3423821 track packets and bytes for fragmentation +3423803 attempt to double free rule +3423805 fragmentation stats not reported correctly +3422712 system panic with ipfstat -f +3422619 pullup counter bumped for every packet +3422608 dummy rtentry required to build +3422018 frflush next to ipf_fini_all is redundant +3422012 instance cleanup is not clean +3421845 instance name not set +3005622 ip_fil5.1.0 does not load on Solaris 10 U8 +2976332 stateful filtering is incompatible with ipv4 options +3387509 ipftest needs help construction ip packets with options +2998746 passp can never be null +3064034 mbuf clobbering problem with ipv6 +3105725 ipnat divide by zero panic +2998750 ipf_htent_insert can leak memory +3064034 mbuf clobbering problem with ipv6 +3105725 ipnat divie by zero panic + +5.1 - RELEASED - 9 May 2010 + +* See WhatsNew50.txt 4.1 - RELEASED - 12 February 2004 @@ -1744,7 +1267,7 @@ loop forms in frag cache table - Yury Pshenychny should use SPLNET/SPLX around expire routines in NAT/frag/state code. -redeclared malloc in 44arp.c - +redeclared malloc in 44arp.c - 3.1.7 8/2/97 - Released diff --git a/contrib/ipfilter/INSTALL.FreeBSD b/contrib/ipfilter/INSTALL.FreeBSD index a4a787ac42be..2a16942c15f0 100644 --- a/contrib/ipfilter/INSTALL.FreeBSD +++ b/contrib/ipfilter/INSTALL.FreeBSD @@ -1,8 +1,11 @@ -This file is for use with FreeBSD 4.x and 5.x only. +Thi file is for use with FreeBSD 4.x and 5.x only. To build a kernel for use with the loadable kernel module, follow these steps: + 0. Run "config GENERIC" or similar in /sys/i386/conf or the + appropriate directory for your kernel. + 1. For FreeBSD version: 4.* do make freebsd4 5.* do make freebsd5 @@ -16,10 +19,12 @@ steps: 5. install and reboot with the new kernel - 6. use modload(8) to load the packet filter with: + 6. use modload(8)/kldload(8) to load the packet filter with: modload if_ipl.o + kldload ipf.ko - 7. do "modstat" to confirm that it has been loaded successfully. + 7. do "modstat" or "kldstat" to confirm that it has been loaded + successfully. There is no need to use mknod to create the device in /dev; - upon loading the module, it will create itself with the correct values, diff --git a/contrib/ipfilter/Makefile b/contrib/ipfilter/Makefile index 334cd4512188..1ac9c94a75dc 100644 --- a/contrib/ipfilter/Makefile +++ b/contrib/ipfilter/Makefile @@ -1,5 +1,5 @@ # -# Copyright (C) 1993-2001 by Darren Reed. +# Copyright (C) 2012 by Darren Reed. # # Redistribution and use in source and binary forms are permitted # provided that this notice is preserved and due credit is given @@ -13,8 +13,7 @@ BINDEST=/usr/local/bin SBINDEST=/sbin MANDIR=/usr/local/man #To test prototyping -#CC=gcc -Wstrict-prototypes -Wmissing-prototypes -# -Wunused -Wuninitialized +CC=gcc -Wstrict-prototypes -Wmissing-prototypes -Wunused -Wuninitialized #CC=gcc #CC=cc -Dconst= DEBUG=-g @@ -36,14 +35,14 @@ IPFLOG=-DIPFILTER_LOG # #COMPIPF=-DIPFILTER_COMPILED # +# To enable IPFilter compatibility with older CLI utilities +# +#COMPATIPF=-DIPFILTER_COMPAT +# # To enable synchronisation between IPFilter hosts # #SYNC=-DIPFILTER_SYNC # -# To enable extended IPFilter functionality -# -LOOKUP=-DIPFILTER_LOOKUP -DIPFILTER_SCAN -# # The facility you wish to log messages from ipmon to syslogd with. # LOGFAC=-DLOGFAC=LOG_SECURITY @@ -65,22 +64,27 @@ LOGFAC=-DLOGFAC=LOG_SECURITY # By default IPFilter looks for /usr/src/linux, but you may have to change # it to /usr/src/linux-2.4 or similar. # -LINUXKERNEL=/usr/src/linux +LINUXKERNEL=/usr/src/kernels/2.6.29.5-191.fc11.i586 LINUX=`uname -r | awk -F. ' { printf"%d",$$1;for(i=1;i opt_inet6.h; \ else \ @@ -212,7 +213,7 @@ freebsd5 freebsd6 freebsd7: include make setup "TARGOS=BSD" "CPUDIR=$(CPUDIR)" (cd BSD/$(CPUDIR); make build TOP=../.. $(MFLAGS) "ML=mlfk_ipl.c" "MLD=mlfk_ipl.c" "LKM=ipf.ko.5" "LKMR=ipfrule.ko.5" "DLKM=-DKLD_MODULE" "MLR=mlfk_rule.o"; cd ..) - (cd BSD/$(CPUDIR); make -f Makefile.ipsend build TOP=../.. $(MFLAGS1); cd ..) +# (cd BSD/$(CPUDIR); make -f Makefile.ipsend build TOP=../.. $(MFLAGS1); cd ..) freebsd4 : include if [ x$(INET6) = x ] ; then \ @@ -241,7 +242,7 @@ netbsd: include exit 1; \ fi (cd BSD/$(CPUDIR); make build TOP=../.. $(MFLAGS) 'DLKM=-D_LKM' "ML=mln_ipl.c" LKMR= "MLR=mln_rule.o"; cd ..) - (cd BSD/$(CPUDIR); make -f Makefile.ipsend build TOP=../.. $(MFLAGS); cd ..) +# (cd BSD/$(CPUDIR); make -f Makefile.ipsend build TOP=../.. $(MFLAGS); cd ..) openbsd: include make setup "TARGOS=BSD" "CPUDIR=$(CPUDIR)" @@ -294,7 +295,7 @@ setup: clean: clean-include /bin/rm -rf h y.output - ${RM} -f core *.o ipt fils ipf ipfstat ipftest ipmon if_ipl \ + ${RM} -f core *.o ipt fils ipf ipfstat ipftest ipmon if_ipl ipflkm \ vnode_if.h $(LKM) *~ /bin/rm -rf sparcv7 sparcv9 mdbgen_build (cd SunOS4; $(MAKE) TOP=.. clean) @@ -352,7 +353,7 @@ sunos4 solaris1: (cd SunOS4; make -f Makefile.ipsend build "CC=$(CC)" TOP=.. $(DEST) $(MFLAGS); cd ..) sunos5 solaris2: null - (cd SunOS5/$(CPUDIR); $(MAKE) build TOP=../.. "CC=$(CC)" $(DEST) $(MFLAGS) "SOLARIS2=$(SOLARIS2)"; cd ..) + (cd SunOS5/$(CPUDIR); $(MAKE) build TOP=../.. "CC=$(CC)" $(DEST) $(MFLAGS) "SOLARIS2=$(SOLARIS2)" INSTANCE=$(INSTANCE); cd ..) (cd SunOS5/$(CPUDIR); $(MAKE) -f Makefile.ipsend build TOP=../.. "CC=$(CC)" $(DEST) $(MFLAGS); cd ..) linux: include @@ -361,7 +362,7 @@ linux: include # (cd Linux; make -f Makefile.ipsend build LINUX=$(LINUX) TOP=.. "CC=$(CC)" $(MFLAGS); cd ..) install-linux: linux - (cd Linux/; make LINUX=$(LINUX) TOP=.. "DEBUG=-g" "CC=$(CC)" $(MFLAGS) OBJ=$(CPUDIR) install ; cd ..) + (cd Linux/; make LINUX=$(LINUX) TOP=.. "DEBUG=-g" "CC=$(CC)" $(MFLAGS) OBJ=$(CPUDIR) ROOTDIR=$(BUILDROOT) install ; cd ..) install-bsd: (cd BSD/$(CPUDIR); make install "TOP=../.." $(MFLAGS); cd ..) @@ -407,4 +408,3 @@ mdb: -DIPFILTER_SCAN -DIPFILTER_LKM -DSOLARIS2=10 -n ipf_mdb -k \ -I/home/dr146992/pfil -I/home/dr146992/ipf -f \ /usr/include/netinet/in_systm.h,/usr/include/sys/ethernet.h,/usr/include/netinet/in.h,/usr/include/netinet/ip.h,/usr/include/netinet/ip_var.h,/usr/include/netinet/tcp.h,/usr/include/netinet/tcpip.h,/usr/include/netinet/ip_icmp.h,/usr/include/netinet/udp.h,ip_compat.h,ip_fil.h,ip_nat.h,ip_state.h,ip_proxy.h,ip_scan.h - diff --git a/contrib/ipfilter/NAT.FreeBSD b/contrib/ipfilter/NAT.FreeBSD index 8a7e95262f7c..4a1a7ede543c 100644 --- a/contrib/ipfilter/NAT.FreeBSD +++ b/contrib/ipfilter/NAT.FreeBSD @@ -1,4 +1,4 @@ -These are Instructions for Configuring A FreeBSD Box For NAT +These are Instructions for Configuring A FreeBSD Box For NAT After you have installed IpFilter. You will need to change three files: @@ -54,7 +54,7 @@ fpx0 is the interface with the real internet address. /32 is the subnet mask 255.255.255.255, ie only use this ip address. -portmap tcp/udp 10000:65000 +portmap tcp/udp 10000:65000 tells it to use the ports to redirect the tcp/udp calls through @@ -67,7 +67,7 @@ reboots. In your /etc/rc.local put the line: -ipnat -f /etc/natrules +ipnat -f /etc/natrules To check and see if it is loaded, as root type ipnat -ls diff --git a/contrib/ipfilter/WhatsNew50.txt b/contrib/ipfilter/WhatsNew50.txt new file mode 100644 index 000000000000..adbf0a99b4e0 --- /dev/null +++ b/contrib/ipfilter/WhatsNew50.txt @@ -0,0 +1,83 @@ +What's new in 5.1 +================= + +General +------- +* all of the tuneables can now be set at any time, not just whilst disabled + or prior to loading rules; + +* group identifiers may now be a number or name (universal); + +* man pages rewritten + +* tunables can now be set via ipf.conf; + +Logging +------- +* ipmon.conf can now be used to generate SNMPv1 and SNMPv2 traps using + information from log entries from the kernel; + +NAT changes +----------- +* DNS proxy for the kernel that can block queries based on domain names; + +* FTP proxy can be configured to limit data connections to one or many + connections per client; + +* NAT on IPv6 is now supported; + +* rewrite command allows changing both the source and destination address + in a single NAT rule; + +* simple encapsulation can now be configured with ipnat.conf, + +* TFTP proxy now included; + +Packet Filtering +---------------- +* acceptance of ICMP packets for "keep state" rules can be refined through + the use of filtering rules; + +* alternative form for writing rules using simple filtering expressions; + +* CIPSO headers now recognised and analysed for filtering on DOI; + +* comments can now be a part of a rule and loaded into the kernel and + thus displayed with ipfstat; + +* decapsulation rules allow filtering on inner headers, providing they + are not encrypted; + +* interface names, aside from that the packet is on, can be present in + filter rules; + +* internally now a single list of filter rules, there is no longer an + IPv4 and IPv6 list; + +* rules can now be added with an expiration time, allowing for their + automatic removal after some period of time; + +* single file, ipf.conf, can now be used for both IPv4 and IPv6 rules; + +* stateful filtering now allows for limits to be placed on the number + of distinct hosts allowed per rule; + +Pools +----- +* addresses added to a pool via the command line (only!) can be given + an expiration timeout; + +* destination lists are a new type of address pool, primarily for use with + NAT rdr rules, supporting newer algorithms for target selection; + +* raw whois information saved to a file can be used to populate a pool; + +Solaris +------- +* support for use in zones with exclusive IP instances fully supported. + +Tools +----- +* use of matching expressions allows for refining what is displayed or + flushed; + diff --git a/contrib/ipfilter/arc4random.c b/contrib/ipfilter/arc4random.c new file mode 100644 index 000000000000..04b0797c78f8 --- /dev/null +++ b/contrib/ipfilter/arc4random.c @@ -0,0 +1,277 @@ +/*- + * THE BEER-WARE LICENSE + * + * wrote this file. As long as you retain this notice you + * can do whatever you want with this stuff. If we meet some day, and you + * think this stuff is worth it, you can buy me a beer in return. + * + * Dan Moschuk + */ +#if !defined(SOLARIS2) && !defined(__osf__) +# include +#endif + +#include +#include +#ifdef __FreeBSD__ +# include +#endif +#if !defined(__osf__) +# include +#endif +#ifdef __FreeBSD__ +# include +#endif +#include +#ifndef __osf__ +# include +#endif +#include + +#if defined(SOLARIS2) && (SOLARIS2 < 9) +# include +#endif +#include +#include +#ifdef __osf__ +# include +#endif +#include +#include +#include "netinet/ip_compat.h" +#ifdef HAS_SYS_MD5_H +# include +#else +# include "md5.h" +#endif + +#ifdef NEED_LOCAL_RAND +#if !defined(__GNUC__) +# define __inline +#endif + +#define ARC4_RESEED_BYTES 65536 +#define ARC4_RESEED_SECONDS 300 +#define ARC4_KEYBYTES (256 / 8) + +static u_int8_t arc4_i, arc4_j; +static int arc4_numruns = 0; +static u_int8_t arc4_sbox[256]; +static time_t arc4_t_reseed; +static ipfmutex_t arc4_mtx; +static MD5_CTX md5ctx; + +static u_int8_t arc4_randbyte(void); +static int ipf_read_random(void *dest, int length); + +static __inline void +arc4_swap(u_int8_t *a, u_int8_t *b) +{ + u_int8_t c; + + c = *a; + *a = *b; + *b = c; +} + +/* + * Stir our S-box. + */ +static void +arc4_randomstir (void) +{ + u_int8_t key[256]; + int r, n; + struct timeval tv_now; + + /* + * XXX read_random() returns unsafe numbers if the entropy + * device is not loaded -- MarkM. + */ + r = ipf_read_random(key, ARC4_KEYBYTES); + GETKTIME(&tv_now); + MUTEX_ENTER(&arc4_mtx); + /* If r == 0 || -1, just use what was on the stack. */ + if (r > 0) { + for (n = r; n < sizeof(key); n++) + key[n] = key[n % r]; + } + + for (n = 0; n < 256; n++) { + arc4_j = (arc4_j + arc4_sbox[n] + key[n]) % 256; + arc4_swap(&arc4_sbox[n], &arc4_sbox[arc4_j]); + } + + /* Reset for next reseed cycle. */ + arc4_t_reseed = tv_now.tv_sec + ARC4_RESEED_SECONDS; + arc4_numruns = 0; + + /* + * Throw away the first N words of output, as suggested in the + * paper "Weaknesses in the Key Scheduling Algorithm of RC4" + * by Fluher, Mantin, and Shamir. (N = 256 in our case.) + */ + for (n = 0; n < 256*4; n++) + arc4_randbyte(); + MUTEX_EXIT(&arc4_mtx); +} + +/* + * Initialize our S-box to its beginning defaults. + */ +static void +arc4_init(void) +{ + int n; + + MD5Init(&md5ctx); + + MUTEX_INIT(&arc4_mtx, "arc4_mtx"); + arc4_i = arc4_j = 0; + for (n = 0; n < 256; n++) + arc4_sbox[n] = (u_int8_t) n; + + arc4_t_reseed = 0; +} + + +/* + * Generate a random byte. + */ +static u_int8_t +arc4_randbyte(void) +{ + u_int8_t arc4_t; + + arc4_i = (arc4_i + 1) % 256; + arc4_j = (arc4_j + arc4_sbox[arc4_i]) % 256; + + arc4_swap(&arc4_sbox[arc4_i], &arc4_sbox[arc4_j]); + + arc4_t = (arc4_sbox[arc4_i] + arc4_sbox[arc4_j]) % 256; + return arc4_sbox[arc4_t]; +} + +/* + * MPSAFE + */ +void +arc4rand(void *ptr, u_int len, int reseed) +{ + u_int8_t *p; + struct timeval tv; + + GETKTIME(&tv); + if (reseed || + (arc4_numruns > ARC4_RESEED_BYTES) || + (tv.tv_sec > arc4_t_reseed)) + arc4_randomstir(); + + MUTEX_ENTER(&arc4_mtx); + arc4_numruns += len; + p = ptr; + while (len--) + *p++ = arc4_randbyte(); + MUTEX_EXIT(&arc4_mtx); +} + +uint32_t +ipf_random(void) +{ + uint32_t ret; + + arc4rand(&ret, sizeof ret, 0); + return ret; +} + + +static u_char pot[ARC4_RESEED_BYTES]; +static u_char *pothead = pot, *pottail = pot; +static int inpot = 0; + +/* + * This is not very strong, and this is understood, but the aim isn't to + * be cryptographically strong - it is just to make up something that is + * pseudo random. + */ +void +ipf_rand_push(void *src, int length) +{ + static int arc4_inited = 0; + u_char *nsrc; + int mylen; + + if (arc4_inited == 0) { + arc4_init(); + arc4_inited = 1; + } + + if (length < 64) { + MD5Update(&md5ctx, src, length); + return; + } + + nsrc = src; + mylen = length; + +#if defined(_SYS_MD5_H) && defined(SOLARIS2) +# define buf buf_un.buf8 +#endif + MUTEX_ENTER(&arc4_mtx); + while ((mylen > 64) && (sizeof(pot) - inpot > sizeof(md5ctx.buf))) { + MD5Update(&md5ctx, nsrc, 64); + mylen -= 64; + nsrc += 64; + if (pottail + sizeof(md5ctx.buf) > pot + sizeof(pot)) { + int left, numbytes; + + numbytes = pot + sizeof(pot) - pottail; + bcopy(md5ctx.buf, pottail, numbytes); + left = sizeof(md5ctx.buf) - numbytes; + pottail = pot; + bcopy(md5ctx.buf + sizeof(md5ctx.buf) - left, + pottail, left); + pottail += left; + } else { + bcopy(md5ctx.buf, pottail, sizeof(md5ctx.buf)); + pottail += sizeof(md5ctx.buf); + } + inpot += 64; + } + MUTEX_EXIT(&arc4_mtx); +#if defined(_SYS_MD5_H) && defined(SOLARIS2) +# undef buf +#endif +} + + +static int +ipf_read_random(void *dest, int length) +{ + if (length > inpot) + return 0; + + MUTEX_ENTER(&arc4_mtx); + if (pothead + length > pot + sizeof(pot)) { + int left, numbytes; + + left = length; + numbytes = pot + sizeof(pot) - pothead; + bcopy(pothead, dest, numbytes); + left -= numbytes; + pothead = pot; + bcopy(pothead, dest + length - left, left); + pothead += left; + } else { + bcopy(pothead, dest, length); + pothead += length; + } + inpot -= length; + if (inpot == 0) + pothead = pottail = pot; + MUTEX_EXIT(&arc4_mtx); + + return length; +} + +#endif /* NEED_LOCAL_RAND */ diff --git a/contrib/ipfilter/etc/protocols b/contrib/ipfilter/etc/protocols index 30c5b7647f17..dec8fb9f6232 100644 --- a/contrib/ipfilter/etc/protocols +++ b/contrib/ipfilter/etc/protocols @@ -101,4 +101,4 @@ any 99 any # private encryption scheme gmtp 100 GMTP # GMTP pim 103 PIM # Protocol Independant Multicast ipcomp 108 IPCOMP # IP Payload Compression Protocol -reserved 255 Reserved # +reserved 255 Reserved # diff --git a/contrib/ipfilter/etc/services b/contrib/ipfilter/etc/services index d8aa0d5ae223..ad83348caf26 100644 --- a/contrib/ipfilter/etc/services +++ b/contrib/ipfilter/etc/services @@ -228,7 +228,7 @@ qmtp 209/tcp # The Quick Mail Transfer Protocol qmtp 209/udp # The Quick Mail Transfer Protocol anet 212/tcp # ATEXSSTR anet 212/udp # ATEXSSTR -ipx 213/tcp # IPX +ipx 213/tcp # IPX ipx 213/udp # IPX vmpwscs 214/tcp # VM PWSCS vmpwscs 214/udp # VM PWSCS @@ -1104,8 +1104,8 @@ shockwave 1626/tcp # Shockwave shockwave 1626/udp # Shockwave oraclenet8cman 1630/tcp # Oracle Net8 Cman oraclenet8cman 1630/udp # Oracle Net8 Cman -visitview 1631/tcp # Visit view -visitview 1631/udp # Visit view +visitview 1631/tcp # Visit view +visitview 1631/udp # Visit view pammratc 1632/tcp # PAMMRATC pammratc 1632/udp # PAMMRATC pammrpc 1633/tcp # PAMMRPC diff --git a/contrib/ipfilter/genmask.c b/contrib/ipfilter/genmask.c new file mode 100644 index 000000000000..75193e3ea398 --- /dev/null +++ b/contrib/ipfilter/genmask.c @@ -0,0 +1,68 @@ +/* + * Copyright (C) 2012 by Darren Reed. + * + * See the IPFILTER.LICENCE file for details on licencing. + * + * $Id$ + */ + +#include "ipf.h" + + +int genmask(family, msk, mskp) + int family; + char *msk; + i6addr_t *mskp; +{ + char *endptr = 0L; + u_32_t addr; + int bits; + + if (strchr(msk, '.') || strchr(msk, 'x') || strchr(msk, ':')) { + /* possibly of the form xxx.xxx.xxx.xxx + * or 0xYYYYYYYY */ + switch (family) + { +#ifdef USE_INET6 + case AF_INET6 : + if (inet_pton(AF_INET6, msk, &mskp->in4) != 1) + return -1; + break; +#endif + case AF_INET : + if (inet_aton(msk, &mskp->in4) == 0) + return -1; + break; + default : + return -1; + /*NOTREACHED*/ + } + } else { + /* + * set x most significant bits + */ + bits = (int)strtol(msk, &endptr, 0); + + switch (family) + { + case AF_INET6 : + if ((*endptr != '\0') || (bits < 0) || (bits > 128)) + return -1; + fill6bits(bits, mskp->i6); + break; + case AF_INET : + if (*endptr != '\0' || bits > 32 || bits < 0) + return -1; + if (bits == 0) + addr = 0; + else + addr = htonl(0xffffffff << (32 - bits)); + mskp->in4.s_addr = addr; + break; + default : + return -1; + /*NOTREACHED*/ + } + } + return 0; +} diff --git a/contrib/ipfilter/ip_dstlist.c b/contrib/ipfilter/ip_dstlist.c new file mode 100644 index 000000000000..ce2e72e8130f --- /dev/null +++ b/contrib/ipfilter/ip_dstlist.c @@ -0,0 +1,1351 @@ +/* + * Copyright (C) 2012 by Darren Reed. + * + * See the IPFILTER.LICENCE file for details on licencing. + */ +#if defined(KERNEL) || defined(_KERNEL) +# undef KERNEL +# undef _KERNEL +# define KERNEL 1 +# define _KERNEL 1 +#endif +#if defined(__osf__) +# define _PROTO_NET_H_ +#endif +#include +#include +#include +#include +#if !defined(_KERNEL) && !defined(__KERNEL__) +# include +# include +# include +# define _KERNEL +# ifdef __OpenBSD__ +struct file; +# endif +# include +# undef _KERNEL +#else +# include +# if defined(NetBSD) && (__NetBSD_Version__ >= 104000000) +# include +# endif +#endif +#include +#if !defined(linux) +# include +#endif +#include +#if defined(_KERNEL) && (!defined(__SVR4) && !defined(__svr4__)) +# include +#endif +#if defined(__SVR4) || defined(__svr4__) +# include +# include +# ifdef _KERNEL +# include +# endif +# include +# include +#endif +#if defined(__FreeBSD_version) && (__FreeBSD_version >= 300000) +# include +#endif + +#include +#include + +#include "netinet/ip_compat.h" +#include "netinet/ip_fil.h" +#include "netinet/ip_nat.h" +#include "netinet/ip_lookup.h" +#include "netinet/ip_dstlist.h" + +/* END OF INCLUDES */ + +#ifdef HAS_SYS_MD5_H +# include +#else +# include "md5.h" +#endif + +#if !defined(lint) +static const char rcsid[] = "@(#)$Id: ip_dstlist.c,v 1.13.2.12 2012/07/20 08:40:19 darren_r Exp $"; +#endif + +typedef struct ipf_dstl_softc_s { + ippool_dst_t *dstlist[LOOKUP_POOL_SZ]; + ippool_dst_t **tails[LOOKUP_POOL_SZ]; + ipf_dstl_stat_t stats; +} ipf_dstl_softc_t; + + +static void *ipf_dstlist_soft_create __P((ipf_main_softc_t *)); +static void ipf_dstlist_soft_destroy __P((ipf_main_softc_t *, void *)); +static int ipf_dstlist_soft_init __P((ipf_main_softc_t *, void *)); +static void ipf_dstlist_soft_fini __P((ipf_main_softc_t *, void *)); +static int ipf_dstlist_addr_find __P((ipf_main_softc_t *, void *, int, + void *, u_int)); +static size_t ipf_dstlist_flush __P((ipf_main_softc_t *, void *, + iplookupflush_t *)); +static int ipf_dstlist_iter_deref __P((ipf_main_softc_t *, void *, int, int, + void *)); +static int ipf_dstlist_iter_next __P((ipf_main_softc_t *, void *, ipftoken_t *, + ipflookupiter_t *)); +static int ipf_dstlist_node_add __P((ipf_main_softc_t *, void *, + iplookupop_t *, int)); +static int ipf_dstlist_node_del __P((ipf_main_softc_t *, void *, + iplookupop_t *, int)); +static int ipf_dstlist_stats_get __P((ipf_main_softc_t *, void *, + iplookupop_t *)); +static int ipf_dstlist_table_add __P((ipf_main_softc_t *, void *, + iplookupop_t *)); +static int ipf_dstlist_table_del __P((ipf_main_softc_t *, void *, + iplookupop_t *)); +static int ipf_dstlist_table_deref __P((ipf_main_softc_t *, void *, void *)); +static void *ipf_dstlist_table_find __P((void *, int, char *)); +static void ipf_dstlist_table_free __P((ipf_dstl_softc_t *, ippool_dst_t *)); +static void ipf_dstlist_table_remove __P((ipf_main_softc_t *, + ipf_dstl_softc_t *, ippool_dst_t *)); +static void ipf_dstlist_table_clearnodes __P((ipf_dstl_softc_t *, + ippool_dst_t *)); +static ipf_dstnode_t *ipf_dstlist_select __P((fr_info_t *, ippool_dst_t *)); +static void *ipf_dstlist_select_ref __P((void *, int, char *)); +static void ipf_dstlist_node_free __P((ipf_dstl_softc_t *, ippool_dst_t *, ipf_dstnode_t *)); +static int ipf_dstlist_node_deref __P((void *, ipf_dstnode_t *)); +static void ipf_dstlist_expire __P((ipf_main_softc_t *, void *)); +static void ipf_dstlist_sync __P((ipf_main_softc_t *, void *)); + +ipf_lookup_t ipf_dstlist_backend = { + IPLT_DSTLIST, + ipf_dstlist_soft_create, + ipf_dstlist_soft_destroy, + ipf_dstlist_soft_init, + ipf_dstlist_soft_fini, + ipf_dstlist_addr_find, + ipf_dstlist_flush, + ipf_dstlist_iter_deref, + ipf_dstlist_iter_next, + ipf_dstlist_node_add, + ipf_dstlist_node_del, + ipf_dstlist_stats_get, + ipf_dstlist_table_add, + ipf_dstlist_table_del, + ipf_dstlist_table_deref, + ipf_dstlist_table_find, + ipf_dstlist_select_ref, + ipf_dstlist_select_node, + ipf_dstlist_expire, + ipf_dstlist_sync +}; + + +/* ------------------------------------------------------------------------ */ +/* Function: ipf_dstlist_soft_create */ +/* Returns: int - 0 = success, else error */ +/* Parameters: softc(I) - pointer to soft context main structure */ +/* */ +/* Allocating a chunk of memory filled with 0's is enough for the current */ +/* soft context used with destination lists. */ +/* ------------------------------------------------------------------------ */ +static void * +ipf_dstlist_soft_create(softc) + ipf_main_softc_t *softc; +{ + ipf_dstl_softc_t *softd; + int i; + + KMALLOC(softd, ipf_dstl_softc_t *); + if (softd == NULL) { + IPFERROR(120028); + return NULL; + } + + bzero((char *)softd, sizeof(*softd)); + for (i = 0; i <= IPL_LOGMAX; i++) + softd->tails[i] = &softd->dstlist[i]; + + return softd; +} + + +/* ------------------------------------------------------------------------ */ +/* Function: ipf_dstlist_soft_destroy */ +/* Returns: Nil */ +/* Parameters: softc(I) - pointer to soft context main structure */ +/* arg(I) - pointer to local context to use */ +/* */ +/* For destination lists, the only thing we have to do when destroying the */ +/* soft context is free it! */ +/* ------------------------------------------------------------------------ */ +static void +ipf_dstlist_soft_destroy(softc, arg) + ipf_main_softc_t *softc; + void *arg; +{ + ipf_dstl_softc_t *softd = arg; + + KFREE(softd); +} + + +/* ------------------------------------------------------------------------ */ +/* Function: ipf_dstlist_soft_init */ +/* Returns: int - 0 = success, else error */ +/* Parameters: softc(I) - pointer to soft context main structure */ +/* arg(I) - pointer to local context to use */ +/* */ +/* There is currently no soft context for destination list management. */ +/* ------------------------------------------------------------------------ */ +static int +ipf_dstlist_soft_init(softc, arg) + ipf_main_softc_t *softc; + void *arg; +{ + return 0; +} + + +/* ------------------------------------------------------------------------ */ +/* Function: ipf_dstlist_soft_fini */ +/* Returns: Nil */ +/* Parameters: softc(I) - pointer to soft context main structure */ +/* arg(I) - pointer to local context to use */ +/* */ +/* There is currently no soft context for destination list management. */ +/* ------------------------------------------------------------------------ */ +static void +ipf_dstlist_soft_fini(softc, arg) + ipf_main_softc_t *softc; + void *arg; +{ + ipf_dstl_softc_t *softd = arg; + int i; + + for (i = -1; i <= IPL_LOGMAX; i++) { + while (softd->dstlist[i + 1] != NULL) { + ipf_dstlist_table_remove(softc, softd, + softd->dstlist[i + 1]); + } + } + + ASSERT(softd->stats.ipls_numderefnodes == 0); +} + + +/* ------------------------------------------------------------------------ */ +/* Function: ipf_dstlist_addr_find */ +/* Returns: int - 0 = success, else error */ +/* Parameters: softc(I) - pointer to soft context main structure */ +/* arg1(I) - pointer to local context to use */ +/* arg2(I) - pointer to local context to use */ +/* arg3(I) - pointer to local context to use */ +/* arg4(I) - pointer to local context to use */ +/* */ +/* There is currently no such thing as searching a destination list for an */ +/* address so this function becomes a no-op. Its presence is required as */ +/* ipf_lookup_res_name() stores the "addr_find" function pointer in the */ +/* pointer passed in to it as funcptr, although it could be a generic null- */ +/* op function rather than a specific one. */ +/* ------------------------------------------------------------------------ */ +/*ARGSUSED*/ +static int +ipf_dstlist_addr_find(softc, arg1, arg2, arg3, arg4) + ipf_main_softc_t *softc; + void *arg1, *arg3; + int arg2; + u_int arg4; +{ + return -1; +} + + +/* ------------------------------------------------------------------------ */ +/* Function: ipf_dstlist_flush */ +/* Returns: int - number of objects deleted */ +/* Parameters: softc(I) - pointer to soft context main structure */ +/* arg(I) - pointer to local context to use */ +/* fop(I) - pointer to lookup flush operation data */ +/* */ +/* Flush all of the destination tables that match the data passed in with */ +/* the iplookupflush_t. There are two ways to match objects: the device for */ +/* which they are to be used with and their name. */ +/* ------------------------------------------------------------------------ */ +static size_t +ipf_dstlist_flush(softc, arg, fop) + ipf_main_softc_t *softc; + void *arg; + iplookupflush_t *fop; +{ + ipf_dstl_softc_t *softd = arg; + ippool_dst_t *node, *next; + int n, i; + + for (n = 0, i = -1; i <= IPL_LOGMAX; i++) { + if (fop->iplf_unit != IPLT_ALL && fop->iplf_unit != i) + continue; + for (node = softd->dstlist[i + 1]; node != NULL; node = next) { + next = node->ipld_next; + + if ((*fop->iplf_name != '\0') && + strncmp(fop->iplf_name, node->ipld_name, + FR_GROUPLEN)) + continue; + + ipf_dstlist_table_remove(softc, softd, node); + n++; + } + } + return n; +} + + +/* ------------------------------------------------------------------------ */ +/* Function: ipf_dstlist_iter_deref */ +/* Returns: int - 0 = success, else error */ +/* Parameters: softc(I) - pointer to soft context main structure */ +/* arg(I) - pointer to local context to use */ +/* otype(I) - type of data structure to iterate through */ +/* unit(I) - device we are working with */ +/* data(I) - address of object in kernel space */ +/* */ +/* This function is called when the iteration token is being free'd and is */ +/* responsible for dropping the reference count of the structure it points */ +/* to. */ +/* ------------------------------------------------------------------------ */ +static int +ipf_dstlist_iter_deref(softc, arg, otype, unit, data) + ipf_main_softc_t *softc; + void *arg; + int otype, unit; + void *data; +{ + if (data == NULL) { + IPFERROR(120001); + return EINVAL; + } + + if (unit < -1 || unit > IPL_LOGMAX) { + IPFERROR(120002); + return EINVAL; + } + + switch (otype) + { + case IPFLOOKUPITER_LIST : + ipf_dstlist_table_deref(softc, arg, (ippool_dst_t *)data); + break; + + case IPFLOOKUPITER_NODE : + ipf_dstlist_node_deref(arg, (ipf_dstnode_t *)data); + break; + } + + return 0; +} + + +/* ------------------------------------------------------------------------ */ +/* Function: ipf_dstlist_iter_next */ +/* Returns: int - 0 = success, else error */ +/* Parameters: softc(I) - pointer to soft context main structure */ +/* arg(I) - pointer to local context to use */ +/* op(I) - pointer to lookup operation data */ +/* uid(I) - uid of process doing the ioctl */ +/* */ +/* This function is responsible for either selecting the next destination */ +/* list or node on a destination list to be returned as a user process */ +/* iterates through the list of destination lists or nodes. */ +/* ------------------------------------------------------------------------ */ +static int +ipf_dstlist_iter_next(softc, arg, token, iter) + ipf_main_softc_t *softc; + void *arg; + ipftoken_t *token; + ipflookupiter_t *iter; +{ + ipf_dstnode_t zn, *nextnode = NULL, *node = NULL; + ippool_dst_t zero, *next = NULL, *dsttab = NULL; + ipf_dstl_softc_t *softd = arg; + int err = 0; + void *hint; + + switch (iter->ili_otype) + { + case IPFLOOKUPITER_LIST : + dsttab = token->ipt_data; + if (dsttab == NULL) { + next = softd->dstlist[(int)iter->ili_unit + 1]; + } else { + next = dsttab->ipld_next; + } + + if (next != NULL) { + ATOMIC_INC32(next->ipld_ref); + token->ipt_data = next; + hint = next->ipld_next; + } else { + bzero((char *)&zero, sizeof(zero)); + next = &zero; + token->ipt_data = NULL; + hint = NULL; + } + break; + + case IPFLOOKUPITER_NODE : + node = token->ipt_data; + if (node == NULL) { + dsttab = ipf_dstlist_table_find(arg, iter->ili_unit, + iter->ili_name); + if (dsttab == NULL) { + IPFERROR(120004); + err = ESRCH; + nextnode = NULL; + } else { + if (dsttab->ipld_dests == NULL) + nextnode = NULL; + else + nextnode = *dsttab->ipld_dests; + dsttab = NULL; + } + } else { + nextnode = node->ipfd_next; + } + + if (nextnode != NULL) { + MUTEX_ENTER(&nextnode->ipfd_lock); + nextnode->ipfd_ref++; + MUTEX_EXIT(&nextnode->ipfd_lock); + token->ipt_data = nextnode; + hint = nextnode->ipfd_next; + } else { + bzero((char *)&zn, sizeof(zn)); + nextnode = &zn; + token->ipt_data = NULL; + hint = NULL; + } + break; + default : + IPFERROR(120003); + err = EINVAL; + break; + } + + if (err != 0) + return err; + + switch (iter->ili_otype) + { + case IPFLOOKUPITER_LIST : + if (dsttab != NULL) + ipf_dstlist_table_deref(softc, arg, dsttab); + err = COPYOUT(next, iter->ili_data, sizeof(*next)); + if (err != 0) { + IPFERROR(120005); + err = EFAULT; + } + break; + + case IPFLOOKUPITER_NODE : + if (node != NULL) + ipf_dstlist_node_deref(arg, node); + err = COPYOUT(nextnode, iter->ili_data, sizeof(*nextnode)); + if (err != 0) { + IPFERROR(120006); + err = EFAULT; + } + break; + } + + if (hint == NULL) + ipf_token_mark_complete(token); + + return err; +} + + +/* ------------------------------------------------------------------------ */ +/* Function: ipf_dstlist_node_add */ +/* Returns: int - 0 = success, else error */ +/* Parameters: softc(I) - pointer to soft context main structure */ +/* arg(I) - pointer to local context to use */ +/* op(I) - pointer to lookup operation data */ +/* uid(I) - uid of process doing the ioctl */ +/* Locks: WRITE(ipf_poolrw) */ +/* */ +/* Add a new node to a destination list. To do this, we only copy in the */ +/* frdest_t structure because that contains the only data required from the */ +/* application to create a new node. The frdest_t doesn't contain the name */ +/* itself. When loading filter rules, fd_name is a 'pointer' to the name. */ +/* In this case, the 'pointer' does not work, instead it is the length of */ +/* the name and the name is immediately following the frdest_t structure. */ +/* fd_name must include the trailing \0, so it should be strlen(str) + 1. */ +/* For simple sanity checking, an upper bound on the size of fd_name is */ +/* imposed - 128. */ +/* ------------------------------------------------------------------------ */ +static int +ipf_dstlist_node_add(softc, arg, op, uid) + ipf_main_softc_t *softc; + void *arg; + iplookupop_t *op; + int uid; +{ + ipf_dstl_softc_t *softd = arg; + ipf_dstnode_t *node, **nodes; + ippool_dst_t *d; + frdest_t dest; + int err; + + if (op->iplo_size < sizeof(frdest_t)) { + IPFERROR(120007); + return EINVAL; + } + + err = COPYIN(op->iplo_struct, &dest, sizeof(dest)); + if (err != 0) { + IPFERROR(120009); + return EFAULT; + } + + d = ipf_dstlist_table_find(arg, op->iplo_unit, op->iplo_name); + if (d == NULL) { + IPFERROR(120010); + return ESRCH; + } + + switch (dest.fd_addr.adf_family) + { + case AF_INET : + case AF_INET6 : + break; + default : + IPFERROR(120019); + return EINVAL; + } + + if (dest.fd_name < -1 || dest.fd_name > 128) { + IPFERROR(120018); + return EINVAL; + } + + KMALLOCS(node, ipf_dstnode_t *, sizeof(*node) + dest.fd_name); + if (node == NULL) { + softd->stats.ipls_nomem++; + IPFERROR(120008); + return ENOMEM; + } + bzero((char *)node, sizeof(*node) + dest.fd_name); + + bcopy(&dest, &node->ipfd_dest, sizeof(dest)); + node->ipfd_size = sizeof(*node) + dest.fd_name; + + if (dest.fd_name > 0) { + /* + * fd_name starts out as the length of the string to copy + * in (including \0) and ends up being the offset from + * fd_names (0). + */ + err = COPYIN((char *)op->iplo_struct + sizeof(dest), + node->ipfd_names, dest.fd_name); + if (err != 0) { + IPFERROR(120017); + KFREES(node, node->ipfd_size); + return EFAULT; + } + node->ipfd_dest.fd_name = 0; + } else { + node->ipfd_dest.fd_name = -1; + } + + if (d->ipld_nodes == d->ipld_maxnodes) { + KMALLOCS(nodes, ipf_dstnode_t **, + sizeof(*nodes) * (d->ipld_maxnodes + 1)); + if (nodes == NULL) { + softd->stats.ipls_nomem++; + IPFERROR(120022); + KFREES(node, node->ipfd_size); + return ENOMEM; + } + if (d->ipld_dests != NULL) { + bcopy(d->ipld_dests, nodes, + sizeof(*nodes) * d->ipld_maxnodes); + KFREES(d->ipld_dests, sizeof(*nodes) * d->ipld_nodes); + nodes[0]->ipfd_pnext = nodes; + } + d->ipld_dests = nodes; + d->ipld_maxnodes++; + } + d->ipld_dests[d->ipld_nodes] = node; + d->ipld_nodes++; + + if (d->ipld_nodes == 1) { + node->ipfd_pnext = d->ipld_dests; + } else if (d->ipld_nodes > 1) { + node->ipfd_pnext = &d->ipld_dests[d->ipld_nodes - 2]->ipfd_next; + } + *node->ipfd_pnext = node; + + MUTEX_INIT(&node->ipfd_lock, "ipf dst node lock"); + node->ipfd_uid = uid; + node->ipfd_ref = 1; + if (node->ipfd_dest.fd_name == 0) + (void) ipf_resolvedest(softc, node->ipfd_names, + &node->ipfd_dest, AF_INET); +#ifdef USE_INET6 + if (node->ipfd_dest.fd_name == 0 && + node->ipfd_dest.fd_ptr == (void *)-1) + (void) ipf_resolvedest(softc, node->ipfd_names, + &node->ipfd_dest, AF_INET6); +#endif + + softd->stats.ipls_numnodes++; + + return 0; +} + + +/* ------------------------------------------------------------------------ */ +/* Function: ipf_dstlist_node_deref */ +/* Returns: int - 0 = success, else error */ +/* Parameters: arg(I) - pointer to local context to use */ +/* node(I) - pointer to destionation node to free */ +/* */ +/* Dereference the use count by one. If it drops to zero then we can assume */ +/* that it has been removed from any lists/tables and is ripe for freeing. */ +/* The pointer to context is required for the purpose of maintaining */ +/* statistics. */ +/* ------------------------------------------------------------------------ */ +static int +ipf_dstlist_node_deref(arg, node) + void *arg; + ipf_dstnode_t *node; +{ + ipf_dstl_softc_t *softd = arg; + int ref; + + MUTEX_ENTER(&node->ipfd_lock); + ref = --node->ipfd_ref; + MUTEX_EXIT(&node->ipfd_lock); + + if (ref > 0) + return 0; + + if ((node->ipfd_flags & IPDST_DELETE) != 0) + softd->stats.ipls_numderefnodes--; + MUTEX_DESTROY(&node->ipfd_lock); + KFREES(node, node->ipfd_size); + softd->stats.ipls_numnodes--; + + return 0; +} + + +/* ------------------------------------------------------------------------ */ +/* Function: ipf_dstlist_node_del */ +/* Returns: int - 0 = success, else error */ +/* Parameters: softc(I) - pointer to soft context main structure */ +/* arg(I) - pointer to local context to use */ +/* op(I) - pointer to lookup operation data */ +/* uid(I) - uid of process doing the ioctl */ +/* */ +/* Look for a matching destination node on the named table and free it if */ +/* found. Because the name embedded in the frdest_t is variable in length, */ +/* it is necessary to allocate some memory locally, to complete this op. */ +/* ------------------------------------------------------------------------ */ +static int +ipf_dstlist_node_del(softc, arg, op, uid) + ipf_main_softc_t *softc; + void *arg; + iplookupop_t *op; + int uid; +{ + ipf_dstl_softc_t *softd = arg; + ipf_dstnode_t *node; + frdest_t frd, *temp; + ippool_dst_t *d; + size_t size; + int err; + + d = ipf_dstlist_table_find(arg, op->iplo_unit, op->iplo_name); + if (d == NULL) { + IPFERROR(120012); + return ESRCH; + } + + err = COPYIN(op->iplo_struct, &frd, sizeof(frd)); + if (err != 0) { + IPFERROR(120011); + return EFAULT; + } + + size = sizeof(*temp) + frd.fd_name; + KMALLOCS(temp, frdest_t *, size); + if (temp == NULL) { + softd->stats.ipls_nomem++; + IPFERROR(120026); + return ENOMEM; + } + + err = COPYIN(op->iplo_struct, temp, size); + if (err != 0) { + IPFERROR(120027); + return EFAULT; + } + + MUTEX_ENTER(&d->ipld_lock); + for (node = *d->ipld_dests; node != NULL; node = node->ipfd_next) { + if ((uid != 0) && (node->ipfd_uid != uid)) + continue; + if (node->ipfd_size != size) + continue; + if (!bcmp(&node->ipfd_dest.fd_ip6, &frd.fd_ip6, + size - offsetof(frdest_t, fd_ip6))) { + ipf_dstlist_node_free(softd, d, node); + MUTEX_EXIT(&d->ipld_lock); + KFREES(temp, size); + return 0; + } + } + MUTEX_EXIT(&d->ipld_lock); + KFREES(temp, size); + + return ESRCH; +} + + +/* ------------------------------------------------------------------------ */ +/* Function: ipf_dstlist_node_free */ +/* Returns: Nil */ +/* Parameters: softd(I) - pointer to the destination list context */ +/* d(I) - pointer to destination list */ +/* node(I) - pointer to node to free */ +/* Locks: MUTEX(ipld_lock) or WRITE(ipf_poolrw) */ +/* */ +/* Free the destination node by first removing it from any lists and then */ +/* checking if this was the last reference held to the object. While the */ +/* array of pointers to nodes is compacted, its size isn't reduced (by way */ +/* of allocating a new smaller one and copying) because the belief is that */ +/* it is likely the array will again reach that size. */ +/* ------------------------------------------------------------------------ */ +static void +ipf_dstlist_node_free(softd, d, node) + ipf_dstl_softc_t *softd; + ippool_dst_t *d; + ipf_dstnode_t *node; +{ + int i; + + /* + * Compact the array of pointers to nodes. + */ + for (i = 0; i < d->ipld_nodes; i++) + if (d->ipld_dests[i] == node) + break; + if (d->ipld_nodes - i > 1) { + bcopy(&d->ipld_dests[i + 1], &d->ipld_dests[i], + sizeof(*d->ipld_dests) * (d->ipld_nodes - i - 1)); + } + d->ipld_nodes--; + + if (node->ipfd_pnext != NULL) + *node->ipfd_pnext = node->ipfd_next; + if (node->ipfd_next != NULL) + node->ipfd_next->ipfd_pnext = node->ipfd_pnext; + node->ipfd_pnext = NULL; + node->ipfd_next = NULL; + + if ((node->ipfd_flags & IPDST_DELETE) == 0) { + softd->stats.ipls_numderefnodes++; + node->ipfd_flags |= IPDST_DELETE; + } + + ipf_dstlist_node_deref(softd, node); +} + + +/* ------------------------------------------------------------------------ */ +/* Function: ipf_dstlist_stats_get */ +/* Returns: int - 0 = success, else error */ +/* Parameters: softc(I) - pointer to soft context main structure */ +/* arg(I) - pointer to local context to use */ +/* op(I) - pointer to lookup operation data */ +/* */ +/* Return the current statistics for destination lists. This may be for all */ +/* of them or just information pertaining to a particular table. */ +/* ------------------------------------------------------------------------ */ +/*ARGSUSED*/ +static int +ipf_dstlist_stats_get(softc, arg, op) + ipf_main_softc_t *softc; + void *arg; + iplookupop_t *op; +{ + ipf_dstl_softc_t *softd = arg; + ipf_dstl_stat_t stats; + int unit, i, err = 0; + + if (op->iplo_size != sizeof(ipf_dstl_stat_t)) { + IPFERROR(120023); + return EINVAL; + } + + stats = softd->stats; + unit = op->iplo_unit; + if (unit == IPL_LOGALL) { + for (i = 0; i <= IPL_LOGMAX; i++) + stats.ipls_list[i] = softd->dstlist[i]; + } else if (unit >= 0 && unit <= IPL_LOGMAX) { + void *ptr; + + if (op->iplo_name[0] != '\0') + ptr = ipf_dstlist_table_find(softd, unit, + op->iplo_name); + else + ptr = softd->dstlist[unit + 1]; + stats.ipls_list[unit] = ptr; + } else { + IPFERROR(120024); + err = EINVAL; + } + + if (err == 0) { + err = COPYOUT(&stats, op->iplo_struct, sizeof(stats)); + if (err != 0) { + IPFERROR(120025); + return EFAULT; + } + } + return 0; +} + + +/* ------------------------------------------------------------------------ */ +/* Function: ipf_dstlist_table_add */ +/* Returns: int - 0 = success, else error */ +/* Parameters: softc(I) - pointer to soft context main structure */ +/* arg(I) - pointer to local context to use */ +/* op(I) - pointer to lookup operation data */ +/* */ +/* Add a new destination table to the list of those available for the given */ +/* device. Because we seldom operate on these objects (find/add/delete), */ +/* they are just kept in a simple linked list. */ +/* ------------------------------------------------------------------------ */ +static int +ipf_dstlist_table_add(softc, arg, op) + ipf_main_softc_t *softc; + void *arg; + iplookupop_t *op; +{ + ipf_dstl_softc_t *softd = arg; + ippool_dst_t user, *d, *new; + int unit, err; + + d = ipf_dstlist_table_find(arg, op->iplo_unit, op->iplo_name); + if (d != NULL) { + IPFERROR(120013); + return EEXIST; + } + + err = COPYIN(op->iplo_struct, &user, sizeof(user)); + if (err != 0) { + IPFERROR(120021); + return EFAULT; + } + + KMALLOC(new, ippool_dst_t *); + if (new == NULL) { + softd->stats.ipls_nomem++; + IPFERROR(120014); + return ENOMEM; + } + bzero((char *)new, sizeof(*new)); + + MUTEX_INIT(&new->ipld_lock, "ipf dst table lock"); + + strncpy(new->ipld_name, op->iplo_name, FR_GROUPLEN); + unit = op->iplo_unit; + new->ipld_unit = unit; + new->ipld_policy = user.ipld_policy; + new->ipld_seed = ipf_random(); + new->ipld_ref = 1; + + new->ipld_pnext = softd->tails[unit + 1]; + *softd->tails[unit + 1] = new; + softd->tails[unit + 1] = &new->ipld_next; + softd->stats.ipls_numlists++; + + return 0; +} + + +/* ------------------------------------------------------------------------ */ +/* Function: ipf_dstlist_table_del */ +/* Returns: int - 0 = success, else error */ +/* Parameters: softc(I) - pointer to soft context main structure */ +/* arg(I) - pointer to local context to use */ +/* op(I) - pointer to lookup operation data */ +/* */ +/* Find a named destinstion list table and delete it. If there are other */ +/* references to it, the caller isn't told. */ +/* ------------------------------------------------------------------------ */ +static int +ipf_dstlist_table_del(softc, arg, op) + ipf_main_softc_t *softc; + void *arg; + iplookupop_t *op; +{ + ippool_dst_t *d; + + d = ipf_dstlist_table_find(arg, op->iplo_unit, op->iplo_name); + if (d == NULL) { + IPFERROR(120015); + return ESRCH; + } + + if (d->ipld_dests != NULL) { + IPFERROR(120016); + return EBUSY; + } + + ipf_dstlist_table_remove(softc, arg, d); + + return 0; +} + + +/* ------------------------------------------------------------------------ */ +/* Function: ipf_dstlist_table_remove */ +/* Returns: Nil */ +/* Parameters: softc(I) - pointer to soft context main structure */ +/* softd(I) - pointer to the destination list context */ +/* d(I) - pointer to destination list */ +/* */ +/* Remove a given destination list from existance. While the IPDST_DELETE */ +/* flag is set every time we call this function and the reference count is */ +/* non-zero, the "numdereflists" counter is always incremented because the */ +/* decision about whether it will be freed or not is not made here. This */ +/* means that the only action the code can take here is to treat it as if */ +/* it will become a detached. */ +/* ------------------------------------------------------------------------ */ +static void +ipf_dstlist_table_remove(softc, softd, d) + ipf_main_softc_t *softc; + ipf_dstl_softc_t *softd; + ippool_dst_t *d; +{ + + if (softd->tails[d->ipld_unit + 1] == &d->ipld_next) + softd->tails[d->ipld_unit + 1] = d->ipld_pnext; + + if (d->ipld_pnext != NULL) + *d->ipld_pnext = d->ipld_next; + if (d->ipld_next != NULL) + d->ipld_next->ipld_pnext = d->ipld_pnext; + d->ipld_pnext = NULL; + d->ipld_next = NULL; + + ipf_dstlist_table_clearnodes(softd, d); + + softd->stats.ipls_numdereflists++; + d->ipld_flags |= IPDST_DELETE; + + ipf_dstlist_table_deref(softc, softd, d); +} + + +/* ------------------------------------------------------------------------ */ +/* Function: ipf_dstlist_table_free */ +/* Returns: Nil */ +/* Parameters: softd(I) - pointer to the destination list context */ +/* d(I) - pointer to destination list */ +/* */ +/* Free up a destination list data structure and any other memory that was */ +/* directly allocated as part of creating it. Individual destination list */ +/* nodes are not freed. It is assumed the caller will have already emptied */ +/* the destination list. */ +/* ------------------------------------------------------------------------ */ +static void +ipf_dstlist_table_free(softd, d) + ipf_dstl_softc_t *softd; + ippool_dst_t *d; +{ + MUTEX_DESTROY(&d->ipld_lock); + + if ((d->ipld_flags & IPDST_DELETE) != 0) + softd->stats.ipls_numdereflists--; + softd->stats.ipls_numlists--; + + if (d->ipld_dests != NULL) { + KFREES(d->ipld_dests, + d->ipld_maxnodes * sizeof(*d->ipld_dests)); + } + + KFREE(d); +} + + +/* ------------------------------------------------------------------------ */ +/* Function: ipf_dstlist_table_deref */ +/* Returns: int - 0 = success, else error */ +/* Parameters: softc(I) - pointer to soft context main structure */ +/* arg(I) - pointer to local context to use */ +/* op(I) - pointer to lookup operation data */ +/* */ +/* Drops the reference count on a destination list table object and free's */ +/* it if 0 has been reached. */ +/* ------------------------------------------------------------------------ */ +static int +ipf_dstlist_table_deref(softc, arg, table) + ipf_main_softc_t *softc; + void *arg; + void *table; +{ + ippool_dst_t *d = table; + + d->ipld_ref--; + if (d->ipld_ref > 0) + return d->ipld_ref; + + ipf_dstlist_table_free(arg, d); + + return 0; +} + + +/* ------------------------------------------------------------------------ */ +/* Function: ipf_dstlist_table_clearnodes */ +/* Returns: Nil */ +/* Parameters: softd(I) - pointer to the destination list context */ +/* dst(I) - pointer to destination list */ +/* */ +/* Free all of the destination nodes attached to the given table. */ +/* ------------------------------------------------------------------------ */ +static void +ipf_dstlist_table_clearnodes(softd, dst) + ipf_dstl_softc_t *softd; + ippool_dst_t *dst; +{ + ipf_dstnode_t *node; + + if (dst->ipld_dests == NULL) + return; + + while ((node = *dst->ipld_dests) != NULL) { + ipf_dstlist_node_free(softd, dst, node); + } +} + + +/* ------------------------------------------------------------------------ */ +/* Function: ipf_dstlist_table_find */ +/* Returns: int - 0 = success, else error */ +/* Parameters: arg(I) - pointer to local context to use */ +/* unit(I) - device we are working with */ +/* name(I) - destination table name to find */ +/* */ +/* Return a pointer to a destination table that matches the unit+name that */ +/* is passed in. */ +/* ------------------------------------------------------------------------ */ +static void * +ipf_dstlist_table_find(arg, unit, name) + void *arg; + int unit; + char *name; +{ + ipf_dstl_softc_t *softd = arg; + ippool_dst_t *d; + + for (d = softd->dstlist[unit + 1]; d != NULL; d = d->ipld_next) { + if ((d->ipld_unit == unit) && + !strncmp(d->ipld_name, name, FR_GROUPLEN)) { + return d; + } + } + + return NULL; +} + + +/* ------------------------------------------------------------------------ */ +/* Function: ipf_dstlist_select_ref */ +/* Returns: void * - NULL = failure, else pointer to table */ +/* Parameters: arg(I) - pointer to local context to use */ +/* unit(I) - device we are working with */ +/* name(I) - destination table name to find */ +/* */ +/* Attempt to find a destination table that matches the name passed in and */ +/* if successful, bump up the reference count on it because we intend to */ +/* store the pointer to it somewhere else. */ +/* ------------------------------------------------------------------------ */ +static void * +ipf_dstlist_select_ref(arg, unit, name) + void *arg; + int unit; + char *name; +{ + ippool_dst_t *d; + + d = ipf_dstlist_table_find(arg, unit, name); + if (d != NULL) { + MUTEX_ENTER(&d->ipld_lock); + d->ipld_ref++; + MUTEX_EXIT(&d->ipld_lock); + } + return d; +} + + +/* ------------------------------------------------------------------------ */ +/* Function: ipf_dstlist_select */ +/* Returns: void * - NULL = failure, else pointer to table */ +/* Parameters: fin(I) - pointer to packet information */ +/* d(I) - pointer to destination list */ +/* */ +/* Find the next node in the destination list to be used according to the */ +/* defined policy. Of these, "connection" is the most expensive policy to */ +/* implement as it always looks for the node with the least number of */ +/* connections associated with it. */ +/* */ +/* The hashes exclude the port numbers so that all protocols map to the */ +/* same destination. Otherwise, someone doing a ping would target a */ +/* different server than their TCP connection, etc. MD-5 is used to */ +/* transform the addressese into something random that the other end could */ +/* not easily guess and use in an attack. ipld_seed introduces an unknown */ +/* into the hash calculation to increase the difficult of an attacker */ +/* guessing the bucket. */ +/* */ +/* One final comment: mixing different address families in a single pool */ +/* will currently result in failures as the address family of the node is */ +/* only matched up with that in the packet as the last step. While this can */ +/* be coded around for the weighted connection and round-robin models, it */ +/* cannot be supported for the hash/random models as they do not search and */ +/* nor is the algorithm conducive to searching. */ +/* ------------------------------------------------------------------------ */ +static ipf_dstnode_t * +ipf_dstlist_select(fin, d) + fr_info_t *fin; + ippool_dst_t *d; +{ + ipf_dstnode_t *node, *sel; + int connects; + u_32_t hash[4]; + MD5_CTX ctx; + int family; + int x; + + if (d->ipld_dests == NULL || *d->ipld_dests == NULL) + return NULL; + + family = fin->fin_family; + + MUTEX_ENTER(&d->ipld_lock); + + switch (d->ipld_policy) + { + case IPLDP_ROUNDROBIN: + sel = d->ipld_selected; + if (sel == NULL) { + sel = *d->ipld_dests; + } else { + sel = sel->ipfd_next; + if (sel == NULL) + sel = *d->ipld_dests; + } + break; + + case IPLDP_CONNECTION: + if (d->ipld_selected == NULL) { + sel = *d->ipld_dests; + break; + } + + sel = d->ipld_selected; + connects = 0x7fffffff; + node = sel->ipfd_next; + if (node == NULL) + node = *d->ipld_dests; + while (node != d->ipld_selected) { + if (node->ipfd_states == 0) { + sel = node; + break; + } + if (node->ipfd_states < connects) { + sel = node; + connects = node->ipfd_states; + } + node = node->ipfd_next; + if (node == NULL) + node = *d->ipld_dests; + } + break; + + case IPLDP_RANDOM : + x = ipf_random() % d->ipld_nodes; + sel = d->ipld_dests[x]; + break; + + case IPLDP_HASHED : + MD5Init(&ctx); + MD5Update(&ctx, (u_char *)&d->ipld_seed, sizeof(d->ipld_seed)); + MD5Update(&ctx, (u_char *)&fin->fin_src6, + sizeof(fin->fin_src6)); + MD5Update(&ctx, (u_char *)&fin->fin_dst6, + sizeof(fin->fin_dst6)); + MD5Final((u_char *)hash, &ctx); + x = hash[0] % d->ipld_nodes; + sel = d->ipld_dests[x]; + break; + + case IPLDP_SRCHASH : + MD5Init(&ctx); + MD5Update(&ctx, (u_char *)&d->ipld_seed, sizeof(d->ipld_seed)); + MD5Update(&ctx, (u_char *)&fin->fin_src6, + sizeof(fin->fin_src6)); + MD5Final((u_char *)hash, &ctx); + x = hash[0] % d->ipld_nodes; + sel = d->ipld_dests[x]; + break; + + case IPLDP_DSTHASH : + MD5Init(&ctx); + MD5Update(&ctx, (u_char *)&d->ipld_seed, sizeof(d->ipld_seed)); + MD5Update(&ctx, (u_char *)&fin->fin_dst6, + sizeof(fin->fin_dst6)); + MD5Final((u_char *)hash, &ctx); + x = hash[0] % d->ipld_nodes; + sel = d->ipld_dests[x]; + break; + + default : + sel = NULL; + break; + } + + if (sel->ipfd_dest.fd_addr.adf_family != family) + sel = NULL; + d->ipld_selected = sel; + + MUTEX_EXIT(&d->ipld_lock); + + return sel; +} + + +/* ------------------------------------------------------------------------ */ +/* Function: ipf_dstlist_select_node */ +/* Returns: int - -1 == failure, 0 == success */ +/* Parameters: fin(I) - pointer to packet information */ +/* group(I) - destination pool to search */ +/* addr(I) - pointer to store selected address */ +/* pfdp(O) - pointer to storage for selected destination node */ +/* */ +/* This function is only responsible for obtaining the next IP address for */ +/* use and storing it in the caller's address space (addr). "addr" is only */ +/* used for storage if pfdp is NULL. No permanent reference is currently */ +/* kept on the node. */ +/* ------------------------------------------------------------------------ */ +int +ipf_dstlist_select_node(fin, group, addr, pfdp) + fr_info_t *fin; + void *group; + u_32_t *addr; + frdest_t *pfdp; +{ +#ifdef USE_MUTEXES + ipf_main_softc_t *softc = fin->fin_main_soft; +#endif + ippool_dst_t *d = group; + ipf_dstnode_t *node; + frdest_t *fdp; + + READ_ENTER(&softc->ipf_poolrw); + + node = ipf_dstlist_select(fin, d); + if (node == NULL) { + RWLOCK_EXIT(&softc->ipf_poolrw); + return -1; + } + + if (pfdp != NULL) { + bcopy(&node->ipfd_dest, pfdp, sizeof(*pfdp)); + } else { + if (fin->fin_family == AF_INET) { + addr[0] = node->ipfd_dest.fd_addr.adf_addr.i6[0]; + } else if (fin->fin_family == AF_INET6) { + addr[0] = node->ipfd_dest.fd_addr.adf_addr.i6[0]; + addr[1] = node->ipfd_dest.fd_addr.adf_addr.i6[1]; + addr[2] = node->ipfd_dest.fd_addr.adf_addr.i6[2]; + addr[3] = node->ipfd_dest.fd_addr.adf_addr.i6[3]; + } + } + + fdp = &node->ipfd_dest; + if (fdp->fd_ptr == NULL) + fdp->fd_ptr = fin->fin_ifp; + + MUTEX_ENTER(&node->ipfd_lock); + node->ipfd_states++; + MUTEX_EXIT(&node->ipfd_lock); + + RWLOCK_EXIT(&softc->ipf_poolrw); + + return 0; +} + + +/* ------------------------------------------------------------------------ */ +/* Function: ipf_dstlist_expire */ +/* Returns: Nil */ +/* Parameters: softc(I) - pointer to soft context main structure */ +/* arg(I) - pointer to local context to use */ +/* */ +/* There are currently no objects to expire in destination lists. */ +/* ------------------------------------------------------------------------ */ +static void +ipf_dstlist_expire(softc, arg) + ipf_main_softc_t *softc; + void *arg; +{ + return; +} + + +/* ------------------------------------------------------------------------ */ +/* Function: ipf_dstlist_sync */ +/* Returns: Nil */ +/* Parameters: softc(I) - pointer to soft context main structure */ +/* arg(I) - pointer to local context to use */ +/* */ +/* When a network interface appears or disappears, we need to revalidate */ +/* all of the network interface names that have been configured as a target */ +/* in a destination list. */ +/* ------------------------------------------------------------------------ */ +void +ipf_dstlist_sync(softc, arg) + ipf_main_softc_t *softc; + void *arg; +{ + ipf_dstl_softc_t *softd = arg; + ipf_dstnode_t *node; + ippool_dst_t *list; + int i; + int j; + + for (i = 0; i < IPL_LOGMAX; i++) { + for (list = softd->dstlist[i]; list != NULL; + list = list->ipld_next) { + for (j = 0; j < list->ipld_maxnodes; j++) { + node = list->ipld_dests[j]; + if (node == NULL) + continue; + if (node->ipfd_dest.fd_name == -1) + continue; + (void) ipf_resolvedest(softc, + node->ipfd_names, + &node->ipfd_dest, + AF_INET); + } + } + } +} diff --git a/contrib/ipfilter/ip_dstlist.h b/contrib/ipfilter/ip_dstlist.h new file mode 100644 index 000000000000..e2885e5c47ad --- /dev/null +++ b/contrib/ipfilter/ip_dstlist.h @@ -0,0 +1,68 @@ +/* + * Copyright (C) 2012 by Darren Reed. + * + * See the IPFILTER.LICENCE file for details on licencing. + * + * $Id: ip_dstlist.h,v 1.5.2.6 2012/07/22 08:04:23 darren_r Exp $ + */ + +#ifndef __IP_DSTLIST_H__ +#define __IP_DSTLIST_H__ + +typedef struct ipf_dstnode { + struct ipf_dstnode *ipfd_next; + struct ipf_dstnode **ipfd_pnext; + ipfmutex_t ipfd_lock; + frdest_t ipfd_dest; + u_long ipfd_syncat; + int ipfd_flags; + int ipfd_size; + int ipfd_states; + int ipfd_ref; + int ipfd_uid; + char ipfd_names[1]; +} ipf_dstnode_t; + +typedef enum ippool_policy_e { + IPLDP_NONE = 0, + IPLDP_ROUNDROBIN, + IPLDP_CONNECTION, + IPLDP_RANDOM, + IPLDP_HASHED, + IPLDP_SRCHASH, + IPLDP_DSTHASH +} ippool_policy_t; + +typedef struct ippool_dst { + struct ippool_dst *ipld_next; + struct ippool_dst **ipld_pnext; + ipfmutex_t ipld_lock; + int ipld_seed; + int ipld_unit; + int ipld_ref; + int ipld_flags; + int ipld_nodes; + int ipld_maxnodes; + ippool_policy_t ipld_policy; + ipf_dstnode_t **ipld_dests; + ipf_dstnode_t *ipld_selected; + char ipld_name[FR_GROUPLEN]; +} ippool_dst_t; + +#define IPDST_DELETE 0x01 + +typedef struct dstlist_stat_s { + void *ipls_list[LOOKUP_POOL_SZ]; + int ipls_numlists; + u_long ipls_nomem; + int ipls_numnodes; + int ipls_numdereflists; + int ipls_numderefnodes; +} ipf_dstl_stat_t; + +extern ipf_lookup_t ipf_dstlist_backend; + +extern int ipf_dstlist_select_node __P((fr_info_t *, void *, u_32_t *, + frdest_t *)); + +#endif /* __IP_DSTLIST_H__ */ diff --git a/contrib/ipfilter/ip_fil.c b/contrib/ipfilter/ip_fil.c index 051867220339..208602a02057 100644 --- a/contrib/ipfilter/ip_fil.c +++ b/contrib/ipfilter/ip_fil.c @@ -1,154 +1,29 @@ /* $FreeBSD$ */ /* - * Copyright (C) 1993-2001 by Darren Reed. + * Copyright (C) 2012 by Darren Reed. * * See the IPFILTER.LICENCE file for details on licencing. + * + * $Id$ */ #if !defined(lint) static const char sccsid[] = "@(#)ip_fil.c 2.41 6/5/96 (C) 1993-2000 Darren Reed"; -static const char rcsid[] = "@(#)$Id: ip_fil.c,v 2.133.2.18 2007/09/09 11:32:05 darrenr Exp $"; +static const char rcsid[] = "@(#)$Id$"; #endif -#ifndef SOLARIS -#define SOLARIS (defined(sun) && (defined(__svr4__) || defined(__SVR4))) -#endif - -#include -#if defined(__FreeBSD__) && !defined(__FreeBSD_version) -# if defined(IPFILTER_LKM) -# ifndef __FreeBSD_cc_version -# include -# else -# if __FreeBSD_cc_version < 430000 -# include -# endif -# endif -# endif -#endif -#include -#if defined(__hpux) && (HPUXREV >= 1111) && !defined(_KERNEL) -# include -#endif -#include -#define _KERNEL -#define KERNEL -#ifdef __OpenBSD__ -struct file; -#endif -#include -#undef _KERNEL -#undef KERNEL -#include -#include -#ifdef __sgi -# include -#endif -#include -#if !SOLARIS -# if (NetBSD > 199609) || (OpenBSD > 199603) || (__FreeBSD_version >= 300000) -# include -# else -# include -# endif -#else -# include -#endif -#ifndef linux -# include -#endif -#include - -#include -#include -#include -#include -#include - -#ifdef __hpux -# define _NET_ROUTE_INCLUDED -#endif -#include -#ifdef sun -# include -#endif -#if __FreeBSD_version >= 300000 -# include -#endif -#ifdef __sgi -#include -# ifdef IFF_DRVRLOCK /* IRIX6 */ -#include -# endif -#endif -#if defined(__FreeBSD__) || defined(SOLARIS2) -# include "radix_ipf.h" -#endif -#ifndef __osf__ -# include -#endif -#include -#if !(defined(__sgi) && !defined(IFF_DRVRLOCK)) /* IRIX < 6 */ && \ - !defined(__hpux) && !defined(linux) -# include -#endif -#include -#include -#if !defined(linux) -# include -#endif -#include -#if defined(__osf__) -# include -#endif -#if defined(__osf__) || defined(__hpux) || defined(__sgi) -# include "radix_ipf_local.h" -# define _RADIX_H_ -#endif -#include -#include -#include -#include -#include -#include -#ifdef __hpux -# undef _NET_ROUTE_INCLUDED -#endif -#include "netinet/ip_compat.h" -#include "netinet/ip_fil.h" -#include "netinet/ip_nat.h" -#include "netinet/ip_frag.h" -#include "netinet/ip_state.h" -#include "netinet/ip_proxy.h" -#include "netinet/ip_auth.h" -#ifdef IPFILTER_SYNC -#include "netinet/ip_sync.h" -#endif -#ifdef IPFILTER_SCAN -#include "netinet/ip_scan.h" -#endif -#include "netinet/ip_pool.h" -#ifdef IPFILTER_COMPILED -# include "netinet/ip_rules.h" -#endif -#if defined(__FreeBSD_version) && (__FreeBSD_version >= 300000) -# include -#endif -#ifdef __hpux -struct rtentry; -#endif +#include "ipf.h" #include "md5.h" - - -#if !defined(__osf__) && !defined(__linux__) -extern struct protosw inetsw[]; -#endif - #include "ipt.h" + +ipf_main_softc_t ipfmain; + static struct ifnet **ifneta = NULL; static int nifs = 0; -static void fr_setifpaddr __P((struct ifnet *, char *)); +struct rtentry; + +static void ipf_setifpaddr __P((struct ifnet *, char *)); void init_ifp __P((void)); #if defined(__sgi) && (IRIX < 60500) static int no_output __P((struct ifnet *, struct mbuf *, @@ -170,16 +45,18 @@ static int write_output __P((struct ifnet *, struct mbuf *, #endif -int ipfattach() +int +ipfattach(softc) + ipf_main_softc_t *softc; { - fr_running = 1; return 0; } -int ipfdetach() +int +ipfdetach(softc) + ipf_main_softc_t *softc; { - fr_running = -1; return 0; } @@ -187,101 +64,96 @@ int ipfdetach() /* * Filter ioctl interface. */ -int iplioctl(dev, cmd, data, mode) -int dev; -ioctlcmd_t cmd; -caddr_t data; -int mode; +int +ipfioctl(softc, dev, cmd, data, mode) + ipf_main_softc_t *softc; + int dev; + ioctlcmd_t cmd; + caddr_t data; + int mode; { int error = 0, unit = 0, uid; - SPL_INT(s); uid = getuid(); unit = dev; SPL_NET(s); - error = fr_ioctlswitch(unit, data, cmd, mode, uid, NULL); + error = ipf_ioctlswitch(softc, unit, data, cmd, mode, uid, NULL); if (error != -1) { SPL_X(s); return error; } - SPL_X(s); return error; } -void fr_forgetifp(ifp) -void *ifp; +void +ipf_forgetifp(softc, ifp) + ipf_main_softc_t *softc; + void *ifp; { register frentry_t *f; - WRITE_ENTER(&ipf_mutex); - for (f = ipacct[0][fr_active]; (f != NULL); f = f->fr_next) + WRITE_ENTER(&softc->ipf_mutex); + for (f = softc->ipf_acct[0][softc->ipf_active]; (f != NULL); + f = f->fr_next) if (f->fr_ifa == ifp) f->fr_ifa = (void *)-1; - for (f = ipacct[1][fr_active]; (f != NULL); f = f->fr_next) + for (f = softc->ipf_acct[1][softc->ipf_active]; (f != NULL); + f = f->fr_next) if (f->fr_ifa == ifp) f->fr_ifa = (void *)-1; - for (f = ipfilter[0][fr_active]; (f != NULL); f = f->fr_next) + for (f = softc->ipf_rules[0][softc->ipf_active]; (f != NULL); + f = f->fr_next) if (f->fr_ifa == ifp) f->fr_ifa = (void *)-1; - for (f = ipfilter[1][fr_active]; (f != NULL); f = f->fr_next) + for (f = softc->ipf_rules[1][softc->ipf_active]; (f != NULL); + f = f->fr_next) if (f->fr_ifa == ifp) f->fr_ifa = (void *)-1; -#ifdef USE_INET6 - for (f = ipacct6[0][fr_active]; (f != NULL); f = f->fr_next) - if (f->fr_ifa == ifp) - f->fr_ifa = (void *)-1; - for (f = ipacct6[1][fr_active]; (f != NULL); f = f->fr_next) - if (f->fr_ifa == ifp) - f->fr_ifa = (void *)-1; - for (f = ipfilter6[0][fr_active]; (f != NULL); f = f->fr_next) - if (f->fr_ifa == ifp) - f->fr_ifa = (void *)-1; - for (f = ipfilter6[1][fr_active]; (f != NULL); f = f->fr_next) - if (f->fr_ifa == ifp) - f->fr_ifa = (void *)-1; -#endif - RWLOCK_EXIT(&ipf_mutex); - fr_natsync(ifp); + RWLOCK_EXIT(&softc->ipf_mutex); + ipf_nat_sync(softc, ifp); + ipf_lookup_sync(softc, ifp); } +static int #if defined(__sgi) && (IRIX < 60500) -static int no_output(ifp, m, s) +no_output(ifp, m, s) #else # if TRU64 >= 1885 -static int no_output (ifp, m, s, rt, cp) -char *cp; +no_output (ifp, m, s, rt, cp) + char *cp; # else -static int no_output(ifp, m, s, rt) +no_output(ifp, m, s, rt) # endif -struct rtentry *rt; + struct rtentry *rt; #endif -struct ifnet *ifp; -struct mbuf *m; -struct sockaddr *s; + struct ifnet *ifp; + struct mbuf *m; + struct sockaddr *s; { return 0; } +static int #if defined(__sgi) && (IRIX < 60500) -static int write_output(ifp, m, s) +write_output(ifp, m, s) #else # if TRU64 >= 1885 -static int write_output (ifp, m, s, rt, cp) -char *cp; +write_output (ifp, m, s, rt, cp) + char *cp; # else -static int write_output(ifp, m, s, rt) +write_output(ifp, m, s, rt) # endif -struct rtentry *rt; + struct rtentry *rt; #endif -struct ifnet *ifp; -struct mbuf *m; -struct sockaddr *s; + struct ifnet *ifp; + struct mbuf *m; + struct sockaddr *s; { char fname[32]; mb_t *mb; @@ -309,9 +181,10 @@ struct sockaddr *s; } -static void fr_setifpaddr(ifp, addr) -struct ifnet *ifp; -char *addr; +static void +ipf_setifpaddr(ifp, addr) + struct ifnet *ifp; + char *addr; { #ifdef __sgi struct in_ifaddr *ifa; @@ -349,15 +222,28 @@ char *addr; #else sin = (struct sockaddr_in *)&ifa->ifa_addr; #endif - sin->sin_addr.s_addr = inet_addr(addr); - if (sin->sin_addr.s_addr == 0) - abort(); +#ifdef USE_INET6 + if (index(addr, ':') != NULL) { + struct sockaddr_in6 *sin6; + + sin6 = (struct sockaddr_in6 *)&ifa->ifa_addr; + sin6->sin6_family = AF_INET6; + inet_pton(AF_INET6, addr, &sin6->sin6_addr); + } else +#endif + { + sin->sin_family = AF_INET; + sin->sin_addr.s_addr = inet_addr(addr); + if (sin->sin_addr.s_addr == 0) + abort(); + } } } -struct ifnet *get_unit(name, v) -char *name; -int v; +struct ifnet * +get_unit(name, family) + char *name; + int family; { struct ifnet *ifp, **ifpp, **old_ifneta; char *addr; @@ -365,6 +251,9 @@ int v; (defined(OpenBSD) && (OpenBSD >= 199603)) || defined(linux) || \ (defined(__FreeBSD__) && (__FreeBSD_version >= 501113)) + if (!*name) + return NULL; + if (name == NULL) name = "anon0"; @@ -375,7 +264,7 @@ int v; for (ifpp = ifneta; ifpp && (ifp = *ifpp); ifpp++) { if (!strcmp(name, ifp->if_xname)) { if (addr != NULL) - fr_setifpaddr(ifp, addr); + ipf_setifpaddr(ifp, addr); return ifp; } } @@ -390,10 +279,10 @@ int v; *addr++ = '\0'; for (ifpp = ifneta; ifpp && (ifp = *ifpp); ifpp++) { - COPYIFNAME(v, ifp, ifname); + COPYIFNAME(family, ifp, ifname); if (!strcmp(name, ifname)) { if (addr != NULL) - fr_setifpaddr(ifp, addr); + ipf_setifpaddr(ifp, addr); return ifp; } } @@ -437,9 +326,15 @@ int v; (defined(__FreeBSD__) && (__FreeBSD_version >= 501113)) (void) strncpy(ifp->if_xname, name, sizeof(ifp->if_xname)); #else - for (s = name; *s && !ISDIGIT(*s); s++) - ; - if (*s && ISDIGIT(*s)) { + s = name + strlen(name) - 1; + for (; s > name; s--) { + if (!ISDIGIT(*s)) { + s++; + break; + } + } + + if ((s > name) && (*s != 0) && ISDIGIT(*s)) { ifp->if_unit = atoi(s); ifp->if_name = (char *)malloc(s - name + 1); (void) strncpy(ifp->if_name, name, s - name); @@ -452,15 +347,16 @@ int v; ifp->if_output = (void *)no_output; if (addr != NULL) { - fr_setifpaddr(ifp, addr); + ipf_setifpaddr(ifp, addr); } return ifp; } -char *get_ifname(ifp) -struct ifnet *ifp; +char * +get_ifname(ifp) + struct ifnet *ifp; { static char ifname[LIFNAMSIZ]; @@ -468,14 +364,18 @@ struct ifnet *ifp; (defined(__FreeBSD__) && (__FreeBSD_version >= 501113)) sprintf(ifname, "%s", ifp->if_xname); #else - sprintf(ifname, "%s%d", ifp->if_name, ifp->if_unit); + if (ifp->if_unit != -1) + sprintf(ifname, "%s%d", ifp->if_name, ifp->if_unit); + else + strcpy(ifname, ifp->if_name); #endif return ifname; } -void init_ifp() +void +init_ifp() { struct ifnet *ifp, **ifpp; char fname[32]; @@ -496,7 +396,7 @@ void init_ifp() #else for (ifpp = ifneta; ifpp && (ifp = *ifpp); ifpp++) { - ifp->if_output = write_output; + ifp->if_output = (void *)write_output; sprintf(fname, "/tmp/%s%d", ifp->if_name, ifp->if_unit); fd = open(fname, O_WRONLY|O_CREAT|O_EXCL|O_TRUNC, 0600); if (fd == -1) @@ -508,36 +408,48 @@ void init_ifp() } -int fr_fastroute(m, mpp, fin, fdp) -mb_t *m, **mpp; -fr_info_t *fin; -frdest_t *fdp; +int +ipf_fastroute(m, mpp, fin, fdp) + mb_t *m, **mpp; + fr_info_t *fin; + frdest_t *fdp; { - struct ifnet *ifp = fdp->fd_ifp; + struct ifnet *ifp; ip_t *ip = fin->fin_ip; + frdest_t node; int error = 0; frentry_t *fr; void *sifp; + int sout; - if (!ifp) - return 0; /* no routing table out here */ - + sifp = fin->fin_ifp; + sout = fin->fin_out; fr = fin->fin_fr; ip->ip_sum = 0; + if (!(fr->fr_flags & FR_KEEPSTATE) && (fdp != NULL) && + (fdp->fd_type == FRD_DSTLIST)) { + bzero(&node, sizeof(node)); + ipf_dstlist_select_node(fin, fdp->fd_ptr, NULL, &node); + fdp = &node; + } + ifp = fdp->fd_ptr; + + if (ifp == NULL) + return 0; /* no routing table out here */ + if (fin->fin_out == 0) { - sifp = fin->fin_ifp; fin->fin_ifp = ifp; fin->fin_out = 1; - (void) fr_acctpkt(fin, NULL); + (void) ipf_acctpkt(fin, NULL); fin->fin_fr = NULL; if (!fr || !(fr->fr_flags & FR_RETMASK)) { u_32_t pass; - (void) fr_checkstate(fin, &pass); + (void) ipf_state_check(fin, &pass); } - switch (fr_checknatout(fin, NULL)) + switch (ipf_nat_checkout(fin, NULL)) { case 0 : break; @@ -550,10 +462,11 @@ frdest_t *fdp; break; } - fin->fin_ifp = sifp; - fin->fin_out = 0; } + m->mb_ifp = ifp; + printpacket(fin->fin_out, m); + #if defined(__sgi) && (IRIX < 60500) (*ifp->if_output)(ifp, (void *)ip, NULL); # if TRU64 >= 1885 @@ -563,55 +476,55 @@ frdest_t *fdp; # endif #endif done: + fin->fin_ifp = sifp; + fin->fin_out = sout; return error; } -int fr_send_reset(fin) -fr_info_t *fin; +int +ipf_send_reset(fin) + fr_info_t *fin; { - verbose("- TCP RST sent\n"); + ipfkverbose("- TCP RST sent\n"); return 0; } -int fr_send_icmp_err(type, fin, dst) -int type; -fr_info_t *fin; -int dst; +int +ipf_send_icmp_err(type, fin, dst) + int type; + fr_info_t *fin; + int dst; { - verbose("- ICMP unreachable sent\n"); + ipfkverbose("- ICMP unreachable sent\n"); return 0; } -void frsync(ifp) -void *ifp; +void +m_freem(m) + mb_t *m; { return; } -void m_freem(m) -mb_t *m; -{ - return; -} - - -void m_copydata(m, off, len, cp) -mb_t *m; -int off, len; -caddr_t cp; +void +m_copydata(m, off, len, cp) + mb_t *m; + int off, len; + caddr_t cp; { bcopy((char *)m + off, cp, len); } -int ipfuiomove(buf, len, rwflag, uio) -caddr_t buf; -int len, rwflag; -struct uio *uio; +int +ipfuiomove(buf, len, rwflag, uio) + caddr_t buf; + int len, rwflag; + struct uio *uio; { int left, ioc, num, offset; struct iovec *io; @@ -648,8 +561,9 @@ struct uio *uio; } -u_32_t fr_newisn(fin) -fr_info_t *fin; +u_32_t +ipf_newisn(fin) + fr_info_t *fin; { static int iss_seq_off = 0; u_char hash[16]; @@ -688,50 +602,76 @@ fr_info_t *fin; /* ------------------------------------------------------------------------ */ -/* Function: fr_nextipid */ +/* Function: ipf_nextipid */ /* Returns: int - 0 == success, -1 == error (packet should be droppped) */ /* Parameters: fin(I) - pointer to packet information */ /* */ /* Returns the next IPv4 ID to use for this packet. */ /* ------------------------------------------------------------------------ */ -INLINE u_short fr_nextipid(fin) -fr_info_t *fin; +INLINE u_short +ipf_nextipid(fin) + fr_info_t *fin; { static u_short ipid = 0; + ipf_main_softc_t *softc = fin->fin_main_soft; u_short id; - MUTEX_ENTER(&ipf_rw); - id = ipid++; - MUTEX_EXIT(&ipf_rw); + MUTEX_ENTER(&softc->ipf_rw); + if (fin->fin_pktnum != 0) { + /* + * The -1 is for aligned test results. + */ + id = (fin->fin_pktnum - 1) & 0xffff; + } else { + } + id = ipid++; + MUTEX_EXIT(&softc->ipf_rw); return id; } -INLINE void fr_checkv4sum(fin) -fr_info_t *fin; +INLINE int +ipf_checkv4sum(fin) + fr_info_t *fin; { - if (fr_checkl4sum(fin) == -1) + + if (fin->fin_flx & FI_SHORT) + return 1; + + if (ipf_checkl4sum(fin) == -1) { fin->fin_flx |= FI_BAD; + return -1; + } + return 0; } #ifdef USE_INET6 -INLINE void fr_checkv6sum(fin) -fr_info_t *fin; +INLINE int +ipf_checkv6sum(fin) + fr_info_t *fin; { - if (fr_checkl4sum(fin) == -1) + if (fin->fin_flx & FI_SHORT) + return 1; + + if (ipf_checkl4sum(fin) == -1) { fin->fin_flx |= FI_BAD; + return -1; + } + return 0; } #endif +#if 0 /* * See above for description, except that all addressing is in user space. */ -int copyoutptr(src, dst, size) -void *src, *dst; -size_t size; +int +copyoutptr(softc, src, dst, size) + void *src, *dst; + size_t size; { caddr_t ca; @@ -744,9 +684,10 @@ size_t size; /* * See above for description, except that all addressing is in user space. */ -int copyinptr(src, dst, size) -void *src, *dst; -size_t size; +int +copyinptr(src, dst, size) + void *src, *dst; + size_t size; { caddr_t ca; @@ -754,15 +695,18 @@ size_t size; bcopy(ca, dst, size); return 0; } +#endif /* * return the first IP Address associated with an interface */ -int fr_ifpaddr(v, atype, ifptr, inp, inpmask) -int v, atype; -void *ifptr; -struct in_addr *inp, *inpmask; +int +ipf_ifpaddr(softc, v, atype, ifptr, inp, inpmask) + ipf_main_softc_t *softc; + int v, atype; + void *ifptr; + i6addr_t *inp, *inpmask; { struct ifnet *ifp = ifptr; #ifdef __sgi @@ -781,40 +725,145 @@ struct in_addr *inp, *inpmask; # endif #endif if (ifa != NULL) { - struct sockaddr_in *sin, mask; + if (v == 4) { + struct sockaddr_in *sin, mask; - mask.sin_addr.s_addr = 0xffffffff; + mask.sin_addr.s_addr = 0xffffffff; #ifdef __sgi - sin = (struct sockaddr_in *)&ifa->ia_addr; + sin = (struct sockaddr_in *)&ifa->ia_addr; #else - sin = (struct sockaddr_in *)&ifa->ifa_addr; + sin = (struct sockaddr_in *)&ifa->ifa_addr; #endif - return fr_ifpfillv4addr(atype, sin, &mask, inp, inpmask); + return ipf_ifpfillv4addr(atype, sin, &mask, + &inp->in4, &inpmask->in4); + } +#ifdef USE_INET6 + if (v == 6) { + struct sockaddr_in6 *sin6, mask; + + sin6 = (struct sockaddr_in6 *)&ifa->ifa_addr; + ((i6addr_t *)&mask.sin6_addr)->i6[0] = 0xffffffff; + ((i6addr_t *)&mask.sin6_addr)->i6[1] = 0xffffffff; + ((i6addr_t *)&mask.sin6_addr)->i6[2] = 0xffffffff; + ((i6addr_t *)&mask.sin6_addr)->i6[3] = 0xffffffff; + return ipf_ifpfillv6addr(atype, sin6, &mask, + inp, inpmask); + } +#endif } return 0; } -int ipfsync() +/* + * This function is not meant to be random, rather just produce a + * sequence of numbers that isn't linear to show "randomness". + */ +u_32_t +ipf_random() { - return 0; -} + static unsigned int last = 0xa5a5a5a5; + static int calls = 0; + int number; - -#ifndef ipf_random -u_32_t ipf_random() -{ - static int seeded = 0; + calls++; /* - * Choose a non-random seed so that "randomness" can be "tested." + * These are deliberately chosen to ensure that there is some + * attempt to test whether the output covers the range in test n18. */ - if (seeded == 0) { - srand(0); - seeded = 1; + switch (calls) + { + case 1 : + number = 0; + break; + case 2 : + number = 4; + break; + case 3 : + number = 3999; + break; + case 4 : + number = 4000; + break; + case 5 : + number = 48999; + break; + case 6 : + number = 49000; + break; + default : + number = last; + last *= calls; + last++; + number ^= last; + break; } - return rand(); + return number; +} + + +int +ipf_verifysrc(fin) + fr_info_t *fin; +{ + return 1; +} + + +int +ipf_inject(fin, m) + fr_info_t *fin; + mb_t *m; +{ + FREE_MB_T(m); + + return 0; +} + + +u_int +ipf_pcksum(fin, hlen, sum) + fr_info_t *fin; + int hlen; + u_int sum; +{ + u_short *sp; + u_int sum2; + int slen; + + slen = fin->fin_plen - hlen; + sp = (u_short *)((u_char *)fin->fin_ip + hlen); + + for (; slen > 1; slen -= 2) + sum += *sp++; + if (slen) + sum += ntohs(*(u_char *)sp << 8); + while (sum > 0xffff) + sum = (sum & 0xffff) + (sum >> 16); + sum2 = (u_short)(~sum & 0xffff); + + return sum2; +} + + +void * +ipf_pullup(m, fin, plen) + mb_t *m; + fr_info_t *fin; + int plen; +{ + if (M_LEN(m) >= plen) + return fin->fin_ip; + + /* + * Fake ipf_pullup failing + */ + fin->fin_reason = FRB_PULLUP; + *fin->fin_mp = NULL; + fin->fin_m = NULL; + fin->fin_ip = NULL; + return NULL; } -#endif diff --git a/contrib/ipfilter/ip_fil_compat.c b/contrib/ipfilter/ip_fil_compat.c new file mode 100644 index 000000000000..d0b356f76904 --- /dev/null +++ b/contrib/ipfilter/ip_fil_compat.c @@ -0,0 +1,4854 @@ +/* + * Copyright (C) 2002-2012 by Darren Reed. + * + * See the IPFILTER.LICENCE file for details on licencing. + */ +#if defined(KERNEL) || defined(_KERNEL) +# undef KERNEL +# undef _KERNEL +# define KERNEL 1 +# define _KERNEL 1 +#endif +#if defined(__osf__) +# define _PROTO_NET_H_ +#endif +#include +#include +#include +#include +#include +#if __FreeBSD_version >= 220000 && defined(_KERNEL) +# include +# include +#else +# include +#endif +#if !defined(_KERNEL) +# include +# define _KERNEL +# ifdef __OpenBSD__ +struct file; +# endif +# include +# undef _KERNEL +#endif +#include +#if (defined(__osf__) || defined(AIX) || defined(__hpux) || defined(__sgi)) && defined(_KERNEL) +# include "radix_ipf_local.h" +# define _RADIX_H_ +#endif +#include +#if defined(__FreeBSD__) +# include +# include +#endif +#if defined(_KERNEL) +# include +# if !defined(__SVR4) && !defined(__svr4__) +# include +# endif +#endif +#include + +#include "netinet/ip_compat.h" +#include "netinet/ip_fil.h" +#include "netinet/ip_pool.h" +#include "netinet/ip_htable.h" +#include "netinet/ip_lookup.h" +#include "netinet/ip_nat.h" +#include "netinet/ip_state.h" +#include "netinet/ip_proxy.h" +#include "netinet/ip_auth.h" +/* END OF INCLUDES */ + +/* + * NetBSD has moved to 64bit time_t for all architectures. + * For some, such as sparc64, there is no change because long is already + * 64bit, but for others (i386), there is... + */ +#ifdef IPFILTER_COMPAT + +# ifdef __NetBSD__ +typedef struct timeval_l { + long tv_sec; + long tv_usec; +} timeval_l_t; +# endif + +/* ------------------------------------------------------------------------ */ + +typedef struct tcpinfo4 { + u_short ts_sport; + u_short ts_dport; + tcpdata_t ts_data[2]; +} tcpinfo4_t; + +static void ipf_v5tcpinfoto4 __P((tcpinfo_t *, tcpinfo4_t *)); + +static void +ipf_v5tcpinfoto4(v5, v4) + tcpinfo_t *v5; + tcpinfo4_t *v4; +{ + v4->ts_sport = v5->ts_sport; + v4->ts_dport = v5->ts_dport; + v4->ts_data[0] = v5->ts_data[0]; + v4->ts_data[1] = v5->ts_data[1]; +} + +typedef struct fr_ip4 { + u_32_t fi_v:4; + u_32_t fi_xx:4; + u_32_t fi_tos:8; + u_32_t fi_ttl:8; + u_32_t fi_p:8; + u_32_t fi_optmsk; + i6addr_t fi_src; + i6addr_t fi_dst; + u_short ofi_secmsk; + u_short ofi_auth; + u_32_t fi_flx; + u_32_t fi_tcpmsk; + u_32_t fi_res1; +} frip4_t; + +typedef struct frpcmp4 { + int frp_cmp; + u_short frp_port; + u_short frp_top; +} frpcmp4_t; + +typedef struct frtuc4 { + u_char ftu_tcpfm; + u_char ftu_tcpf; + frpcmp4_t ftu_src; + frpcmp4_t ftu_dst; +} frtuc4_t; + +typedef struct fripf4 { + frip4_t fri_ip; + frip4_t fri_mip; + + u_short fri_icmpm; + u_short fri_icmp; + + frtuc4_t fri_tuc; + int fri_satype; + int fri_datype; + int fri_sifpidx; + int fri_difpidx; +} fripf4_t; + +typedef struct frdest_4 { + void *fd_ifp; + i6addr_t ofd_ip6; + char fd_ifname[LIFNAMSIZ]; +} frdest_4_t; + +/* ------------------------------------------------------------------------ */ + +/* 5.1.0 new release (current) + * 4.1.34 changed the size of the time structure used for pps + * 4.1.16 moved the location of fr_flineno + * 4.1.0 base version + */ +typedef struct frentry_4_1_34 { + ipfmutex_t fr_lock; + struct frentry *fr_next; + struct frentry **fr_grp; + struct ipscan *fr_isc; + void *fr_ifas[4]; + void *fr_ptr; /* for use with fr_arg */ + char *fr_comment; /* text comment for rule */ + int fr_ref; /* reference count - for grouping */ + int fr_statecnt; /* state count - for limit rules */ + int fr_flineno; /* line number from conf file */ + U_QUAD_T fr_hits; + U_QUAD_T fr_bytes; + union { + struct timeval frp_lastpkt; + char frp_bytes[12]; + } fr_lpu; + int fr_curpps; + union { + void *fru_data; + char *fru_caddr; + fripf4_t *fru_ipf; + frentfunc_t fru_func; + } fr_dun; + ipfunc_t fr_func; /* call this function */ + int fr_dsize; + int fr_pps; + int fr_statemax; /* max reference count */ + u_32_t fr_type; + u_32_t fr_flags; /* per-rule flags && options (see below) */ + u_32_t fr_logtag; /* user defined log tag # */ + u_32_t fr_collect; /* collection number */ + u_int fr_arg; /* misc. numeric arg for rule */ + u_int fr_loglevel; /* syslog log facility + priority */ + u_int fr_age[2]; /* non-TCP timeouts */ + u_char fr_v; + u_char fr_icode; /* return ICMP code */ + char fr_group[FR_GROUPLEN]; /* group to which this rule belongs */ + char fr_grhead[FR_GROUPLEN]; /* group # which this rule starts */ + ipftag_t fr_nattag; + char fr_ifnames[4][LIFNAMSIZ]; + char fr_isctag[16]; + frdest_4_t fr_tifs[2]; /* "to"/"reply-to" interface */ + frdest_4_t fr_dif; /* duplicate packet interface */ + u_int fr_cksum; /* checksum on filter rules for performance */ +} frentry_4_1_34_t; + +typedef struct frentry_4_1_16 { + ipfmutex_t fr_lock; + struct frentry *fr_next; + struct frentry **fr_grp; + struct ipscan *fr_isc; + void *fr_ifas[4]; + void *fr_ptr; + char *fr_comment; + int fr_ref; + int fr_statecnt; + int fr_flineno; + U_QUAD_T fr_hits; + U_QUAD_T fr_bytes; + union { +#ifdef __NetBSD__ + timeval_l_t frp_lastpkt; +#else + struct timeval frp_lastpkt; +#endif + } fr_lpu; + int fr_curpps; + union { + void *fru_data; + caddr_t fru_caddr; + fripf4_t *fru_ipf; + frentfunc_t fru_func; + } fr_dun; + ipfunc_t fr_func; + int fr_dsize; + int fr_pps; + int fr_statemax; + u_32_t fr_type; + u_32_t fr_flags; + u_32_t fr_logtag; + u_32_t fr_collect; + u_int fr_arg; + u_int fr_loglevel; + u_int fr_age[2]; + u_char fr_v; + u_char fr_icode; + char fr_group[FR_GROUPLEN]; + char fr_grhead[FR_GROUPLEN]; + ipftag_t fr_nattag; + char fr_ifnames[4][LIFNAMSIZ]; + char fr_isctag[16]; + frdest_4_t fr_tifs[2]; + frdest_4_t fr_dif; + u_int fr_cksum; +} frentry_4_1_16_t; + +typedef struct frentry_4_1_0 { + ipfmutex_t fr_lock; + struct frentry *fr_next; + struct frentry **fr_grp; + struct ipscan *fr_isc; + void *fr_ifas[4]; + void *fr_ptr; + char *fr_comment; + int fr_ref; + int fr_statecnt; + U_QUAD_T fr_hits; + U_QUAD_T fr_bytes; + union { +#ifdef __NetBSD__ + timeval_l_t frp_lastpkt; +#else + struct timeval frp_lastpkt; +#endif + } fr_lpu; + int fr_curpps; + + union { + void *fru_data; + caddr_t fru_caddr; + fripf4_t *fru_ipf; + frentfunc_t fru_func; + } fr_dun; + /* + * Fields after this may not change whilst in the kernel. + */ + ipfunc_t fr_func; + int fr_dsize; + int fr_pps; + int fr_statemax; + int fr_flineno; + u_32_t fr_type; + u_32_t fr_flags; + u_32_t fr_logtag; + u_32_t fr_collect; + u_int fr_arg; + u_int fr_loglevel; + u_int fr_age[2]; + u_char fr_v; + u_char fr_icode; + char fr_group[FR_GROUPLEN]; + char fr_grhead[FR_GROUPLEN]; + ipftag_t fr_nattag; + char fr_ifnames[4][LIFNAMSIZ]; + char fr_isctag[16]; + frdest_4_t fr_tifs[2]; + frdest_4_t fr_dif; + u_int fr_cksum; +} frentry_4_1_0_t; + +/* ------------------------------------------------------------------------ */ + +/* + * 5.1.0 new release (current) + * 4.1.32 removed both fin_state and fin_nat, added fin_pktnum + * 4.1.24 added fin_cksum + * 4.1.23 added fin_exthdr + * 4.1.11 added fin_ifname + * 4.1.4 added fin_hbuf + */ +typedef struct fr_info_4_1_32 { + void *fin_ifp; /* interface packet is `on' */ + frip4_t fin_fi; /* IP Packet summary */ + union { + u_short fid_16[2]; /* TCP/UDP ports, ICMP code/type */ + u_32_t fid_32; + } fin_dat; + int fin_out; /* in or out ? 1 == out, 0 == in */ + int fin_rev; /* state only: 1 = reverse */ + u_short fin_hlen; /* length of IP header in bytes */ + u_char ofin_tcpf; /* TCP header flags (SYN, ACK, etc) */ + u_char fin_icode; /* ICMP error to return */ + u_32_t fin_rule; /* rule # last matched */ + char fin_group[FR_GROUPLEN]; /* group number, -1 for none */ + struct frentry *fin_fr; /* last matching rule */ + void *fin_dp; /* start of data past IP header */ + int fin_dlen; /* length of data portion of packet */ + int fin_plen; + int fin_ipoff; /* # bytes from buffer start to hdr */ + u_short fin_id; /* IP packet id field */ + u_short fin_off; + int fin_depth; /* Group nesting depth */ + int fin_error; /* Error code to return */ + int fin_cksum; /* -1 bad, 1 good, 0 not done */ + u_int fin_pktnum; + void *fin_nattag; + void *fin_exthdr; + ip_t *ofin_ip; + mb_t **fin_mp; /* pointer to pointer to mbuf */ + mb_t *fin_m; /* pointer to mbuf */ +#ifdef MENTAT + mb_t *fin_qfm; /* pointer to mblk where pkt starts */ + void *fin_qpi; + char fin_ifname[LIFNAMSIZ]; +#endif +#ifdef __sgi + void *fin_hbuf; +#endif +} fr_info_4_1_32_t; + +typedef struct fr_info_4_1_24 { + void *fin_ifp; + frip4_t fin_fi; + union { + u_short fid_16[2]; + u_32_t fid_32; + } fin_dat; + int fin_out; + int fin_rev; + u_short fin_hlen; + u_char ofin_tcpf; + u_char fin_icode; + u_32_t fin_rule; + char fin_group[FR_GROUPLEN]; + struct frentry *fin_fr; + void *fin_dp; + int fin_dlen; + int fin_plen; + int fin_ipoff; + u_short fin_id; + u_short fin_off; + int fin_depth; + int fin_error; + int fin_cksum; + void *fin_state; + void *fin_nat; + void *fin_nattag; + void *fin_exthdr; + ip_t *ofin_ip; + mb_t **fin_mp; + mb_t *fin_m; +#ifdef MENTAT + mb_t *fin_qfm; + void *fin_qpi; + char fin_ifname[LIFNAMSIZ]; +#endif +#ifdef __sgi + void *fin_hbuf; +#endif +} fr_info_4_1_24_t; + +typedef struct fr_info_4_1_23 { + void *fin_ifp; + frip4_t fin_fi; + union { + u_short fid_16[2]; + u_32_t fid_32; + } fin_dat; + int fin_out; + int fin_rev; + u_short fin_hlen; + u_char ofin_tcpf; + u_char fin_icode; + u_32_t fin_rule; + char fin_group[FR_GROUPLEN]; + struct frentry *fin_fr; + void *fin_dp; + int fin_dlen; + int fin_plen; + int fin_ipoff; + u_short fin_id; + u_short fin_off; + int fin_depth; + int fin_error; + void *fin_state; + void *fin_nat; + void *fin_nattag; + void *fin_exthdr; + ip_t *ofin_ip; + mb_t **fin_mp; + mb_t *fin_m; +#ifdef MENTAT + mb_t *fin_qfm; + void *fin_qpi; + char fin_ifname[LIFNAMSIZ]; +#endif +#ifdef __sgi + void *fin_hbuf; +#endif +} fr_info_4_1_23_t; + +typedef struct fr_info_4_1_11 { + void *fin_ifp; + frip4_t fin_fi; + union { + u_short fid_16[2]; + u_32_t fid_32; + } fin_dat; + int fin_out; + int fin_rev; + u_short fin_hlen; + u_char ofin_tcpf; + u_char fin_icode; + u_32_t fin_rule; + char fin_group[FR_GROUPLEN]; + struct frentry *fin_fr; + void *fin_dp; + int fin_dlen; + int fin_plen; + int fin_ipoff; + u_short fin_id; + u_short fin_off; + int fin_depth; + int fin_error; + void *fin_state; + void *fin_nat; + void *fin_nattag; + ip_t *ofin_ip; + mb_t **fin_mp; + mb_t *fin_m; +#ifdef MENTAT + mb_t *fin_qfm; + void *fin_qpi; + char fin_ifname[LIFNAMSIZ]; +#endif +#ifdef __sgi + void *fin_hbuf; +#endif +} fr_info_4_1_11_t; + +/* ------------------------------------------------------------------------ */ + +typedef struct filterstats_4_1 { + u_long fr_pass; /* packets allowed */ + u_long fr_block; /* packets denied */ + u_long fr_nom; /* packets which don't match any rule */ + u_long fr_short; /* packets which are short */ + u_long fr_ppkl; /* packets allowed and logged */ + u_long fr_bpkl; /* packets denied and logged */ + u_long fr_npkl; /* packets unmatched and logged */ + u_long fr_pkl; /* packets logged */ + u_long fr_skip; /* packets to be logged but buffer full */ + u_long fr_ret; /* packets for which a return is sent */ + u_long fr_acct; /* packets for which counting was performed */ + u_long fr_bnfr; /* bad attempts to allocate fragment state */ + u_long fr_nfr; /* new fragment state kept */ + u_long fr_cfr; /* add new fragment state but complete pkt */ + u_long fr_bads; /* bad attempts to allocate packet state */ + u_long fr_ads; /* new packet state kept */ + u_long fr_chit; /* cached hit */ + u_long fr_tcpbad; /* TCP checksum check failures */ + u_long fr_pull[2]; /* good and bad pullup attempts */ + u_long fr_badsrc; /* source received doesn't match route */ + u_long fr_badttl; /* TTL in packet doesn't reach minimum */ + u_long fr_bad; /* bad IP packets to the filter */ + u_long fr_ipv6; /* IPv6 packets in/out */ + u_long fr_ppshit; /* dropped because of pps ceiling */ + u_long fr_ipud; /* IP id update failures */ +} filterstats_4_1_t; + +/* + * 5.1.0 new release (current) + * 4.1.33 changed the size of f_locks from IPL_LOGMAX to IPL_LOGSIZE + */ +typedef struct friostat_4_1_33 { + struct filterstats_4_1 of_st[2]; + struct frentry *f_ipf[2][2]; + struct frentry *f_acct[2][2]; + struct frentry *f_ipf6[2][2]; + struct frentry *f_acct6[2][2]; + struct frentry *f_auth; + struct frgroup *f_groups[IPL_LOGSIZE][2]; + u_long f_froute[2]; + u_long f_ticks; + int f_locks[IPL_LOGSIZE]; + size_t f_kmutex_sz; + size_t f_krwlock_sz; + int f_defpass; /* default pass - from fr_pass */ + int f_active; /* 1 or 0 - active rule set */ + int f_running; /* 1 if running, else 0 */ + int f_logging; /* 1 if enabled, else 0 */ + int f_features; + char f_version[32]; /* version string */ +} friostat_4_1_33_t; + +typedef struct friostat_4_1_0 { + struct filterstats_4_1 of_st[2]; + struct frentry *f_ipf[2][2]; + struct frentry *f_acct[2][2]; + struct frentry *f_ipf6[2][2]; + struct frentry *f_acct6[2][2]; + struct frentry *f_auth; + struct frgroup *f_groups[IPL_LOGSIZE][2]; + u_long f_froute[2]; + u_long f_ticks; + int f_locks[IPL_LOGMAX]; + size_t f_kmutex_sz; + size_t f_krwlock_sz; + int f_defpass; + int f_active; + int f_running; + int f_logging; + int f_features; + char f_version[32]; +} friostat_4_1_0_t; + +/* ------------------------------------------------------------------------ */ + +/* + * 5.1.0 new release (current) + * 4.1.14 added in_lock + */ +typedef struct ipnat_4_1_14 { + ipfmutex_t in_lock; + struct ipnat *in_next; /* NAT rule list next */ + struct ipnat *in_rnext; /* rdr rule hash next */ + struct ipnat **in_prnext; /* prior rdr next ptr */ + struct ipnat *in_mnext; /* map rule hash next */ + struct ipnat **in_pmnext; /* prior map next ptr */ + struct ipftq *in_tqehead[2]; + void *in_ifps[2]; + void *in_apr; + char *in_comment; + i6addr_t in_next6; + u_long in_space; + u_long in_hits; + u_int in_use; + u_int in_hv; + int in_flineno; /* conf. file line number */ + u_short in_pnext; + u_char in_v; + u_char in_xxx; + /* From here to the end is covered by IPN_CMPSIZ */ + u_32_t in_flags; + u_32_t in_mssclamp; /* if != 0 clamp MSS to this */ + u_int in_age[2]; + int in_redir; /* see below for values */ + int in_p; /* protocol. */ + i6addr_t in_in[2]; + i6addr_t in_out[2]; + i6addr_t in_src[2]; + frtuc4_t in_tuc; + u_short in_port[2]; + u_short in_ppip; /* ports per IP. */ + u_short in_ippip; /* IP #'s per IP# */ + char in_ifnames[2][LIFNAMSIZ]; + char in_plabel[APR_LABELLEN]; /* proxy label. */ + ipftag_t in_tag; +} ipnat_4_1_14_t; + +typedef struct ipnat_4_1_0 { + struct ipnat *in_next; + struct ipnat *in_rnext; + struct ipnat **in_prnext; + struct ipnat *in_mnext; + struct ipnat **in_pmnext; + struct ipftq *in_tqehead[2]; + void *in_ifps[2]; + void *in_apr; + char *in_comment; + i6addr_t in_next6; + u_long in_space; + u_long in_hits; + u_int in_use; + u_int in_hv; + int in_flineno; + u_short in_pnext; + u_char in_v; + u_char in_xxx; + u_32_t in_flags; + u_32_t in_mssclamp; + u_int in_age[2]; + int in_redir; + int in_p; + i6addr_t in_in[2]; + i6addr_t in_out[2]; + i6addr_t in_src[2]; + frtuc4_t in_tuc; + u_short in_port[2]; + u_short in_ppip; + u_short in_ippip; + char in_ifnames[2][LIFNAMSIZ]; + char in_plabel[APR_LABELLEN]; + ipftag_t in_tag; +} ipnat_4_1_0_t; + +/* ------------------------------------------------------------------------ */ + +typedef struct natlookup_4_1_1 { + struct in_addr onl_inip; + struct in_addr onl_outip; + struct in_addr onl_realip; + int nl_flags; + u_short nl_inport; + u_short nl_outport; + u_short nl_realport; +} natlookup_4_1_1_t; + +/* ------------------------------------------------------------------------ */ + +/* + * 4.1.25 added nat_seqnext (current) + * 4.1.14 added nat_redir + * 4.1.3 moved nat_rev + * 4.1.2 added nat_rev + */ +typedef struct nat_4_1_25 { + ipfmutex_t nat_lock; + struct nat_4_1_25 *nat_next; + struct nat_4_1_25 **nat_pnext; + struct nat_4_1_25 *nat_hnext[2]; + struct nat_4_1_25 **nat_phnext[2]; + struct hostmap *nat_hm; + void *nat_data; + struct nat_4_1_25 **nat_me; + struct ipstate *nat_state; + struct ap_session *nat_aps; + frentry_t *nat_fr; + struct ipnat_4_1_14 *nat_ptr; + void *nat_ifps[2]; + void *nat_sync; + ipftqent_t nat_tqe; + u_32_t nat_flags; + u_32_t nat_sumd[2]; + u_32_t nat_ipsumd; + u_32_t nat_mssclamp; + i6addr_t nat_inip6; + i6addr_t nat_outip6; + i6addr_t nat_oip6; + U_QUAD_T nat_pkts[2]; + U_QUAD_T nat_bytes[2]; + union { + udpinfo_t nat_unu; + tcpinfo4_t nat_unt; + icmpinfo_t nat_uni; + greinfo_t nat_ugre; + } nat_un; + u_short nat_oport; + u_short nat_use; + u_char nat_p; + int nat_dir; + int nat_ref; + int nat_hv[2]; + char nat_ifnames[2][LIFNAMSIZ]; + int nat_rev; + int nat_redir; + u_32_t nat_seqnext[2]; +} nat_4_1_25_t; + +typedef struct nat_4_1_14 { + ipfmutex_t nat_lock; + struct nat *nat_next; + struct nat **nat_pnext; + struct nat *nat_hnext[2]; + struct nat **nat_phnext[2]; + struct hostmap *nat_hm; + void *nat_data; + struct nat **nat_me; + struct ipstate *nat_state; + struct ap_session *nat_aps; + frentry_t *nat_fr; + struct ipnat *nat_ptr; + void *nat_ifps[2]; + void *nat_sync; + ipftqent_t nat_tqe; + u_32_t nat_flags; + u_32_t nat_sumd[2]; + u_32_t nat_ipsumd; + u_32_t nat_mssclamp; + i6addr_t nat_inip6; + i6addr_t nat_outip6; + i6addr_t nat_oip6; + U_QUAD_T nat_pkts[2]; + U_QUAD_T nat_bytes[2]; + union { + udpinfo_t nat_unu; + tcpinfo4_t nat_unt; + icmpinfo_t nat_uni; + greinfo_t nat_ugre; + } nat_un; + u_short nat_oport; + u_short nat_use; + u_char nat_p; + int nat_dir; + int nat_ref; + int nat_hv[2]; + char nat_ifnames[2][LIFNAMSIZ]; + int nat_rev; + int nat_redir; +} nat_4_1_14_t; + +typedef struct nat_4_1_3 { + ipfmutex_t nat_lock; + struct nat *nat_next; + struct nat **nat_pnext; + struct nat *nat_hnext[2]; + struct nat **nat_phnext[2]; + struct hostmap *nat_hm; + void *nat_data; + struct nat **nat_me; + struct ipstate *nat_state; + struct ap_session *nat_aps; + frentry_t *nat_fr; + struct ipnat *nat_ptr; + void *nat_ifps[2]; + void *nat_sync; + ipftqent_t nat_tqe; + u_32_t nat_flags; + u_32_t nat_sumd[2]; + u_32_t nat_ipsumd; + u_32_t nat_mssclamp; + i6addr_t nat_inip6; + i6addr_t nat_outip6; + i6addr_t nat_oip6; + U_QUAD_T nat_pkts[2]; + U_QUAD_T nat_bytes[2]; + union { + udpinfo_t nat_unu; + tcpinfo4_t nat_unt; + icmpinfo_t nat_uni; + greinfo_t nat_ugre; + } nat_un; + u_short nat_oport; + u_short nat_use; + u_char nat_p; + int nat_dir; + int nat_ref; + int nat_hv[2]; + char nat_ifnames[2][LIFNAMSIZ]; + int nat_rev; +} nat_4_1_3_t; + + + +typedef struct nat_save_4_1_34 { + void *ipn_next; + struct nat_4_1_25 ipn_nat; + struct ipnat_4_1_14 ipn_ipnat; + struct frentry_4_1_34 ipn_fr; + int ipn_dsize; + char ipn_data[4]; +} nat_save_4_1_34_t; + +typedef struct nat_save_4_1_16 { + void *ipn_next; + nat_4_1_14_t ipn_nat; + ipnat_t ipn_ipnat; + frentry_4_1_16_t ipn_fr; + int ipn_dsize; + char ipn_data[4]; +} nat_save_4_1_16_t; + +typedef struct nat_save_4_1_14 { + void *ipn_next; + nat_4_1_14_t ipn_nat; + ipnat_t ipn_ipnat; + frentry_4_1_0_t ipn_fr; + int ipn_dsize; + char ipn_data[4]; +} nat_save_4_1_14_t; + +typedef struct nat_save_4_1_3 { + void *ipn_next; + nat_4_1_3_t ipn_nat; + ipnat_4_1_0_t ipn_ipnat; + frentry_4_1_0_t ipn_fr; + int ipn_dsize; + char ipn_data[4]; +} nat_save_4_1_3_t; + +/* ------------------------------------------------------------------------ */ + +/* + * 5.1.0 new release (current) + * 4.1.32 added ns_uncreate + * 4.1.27 added ns_orphans + * 4.1.16 added ns_ticks + */ +typedef struct natstat_4_1_32 { + u_long ns_mapped[2]; + u_long ns_rules; + u_long ns_added; + u_long ns_expire; + u_long ns_inuse; + u_long ns_logged; + u_long ns_logfail; + u_long ns_memfail; + u_long ns_badnat; + u_long ns_addtrpnt; + nat_t **ns_table[2]; + hostmap_t **ns_maptable; + ipnat_t *ns_list; + void *ns_apslist; + u_int ns_wilds; + u_int ns_nattab_sz; + u_int ns_nattab_max; + u_int ns_rultab_sz; + u_int ns_rdrtab_sz; + u_int ns_trpntab_sz; + u_int ns_hostmap_sz; + nat_t *ns_instances; + hostmap_t *ns_maplist; + u_long *ns_bucketlen[2]; + u_long ns_ticks; + u_int ns_orphans; + u_long ns_uncreate[2][2]; +} natstat_4_1_32_t; + +typedef struct natstat_4_1_27 { + u_long ns_mapped[2]; + u_long ns_rules; + u_long ns_added; + u_long ns_expire; + u_long ns_inuse; + u_long ns_logged; + u_long ns_logfail; + u_long ns_memfail; + u_long ns_badnat; + u_long ns_addtrpnt; + nat_t **ns_table[2]; + hostmap_t **ns_maptable; + ipnat_t *ns_list; + void *ns_apslist; + u_int ns_wilds; + u_int ns_nattab_sz; + u_int ns_nattab_max; + u_int ns_rultab_sz; + u_int ns_rdrtab_sz; + u_int ns_trpntab_sz; + u_int ns_hostmap_sz; + nat_t *ns_instances; + hostmap_t *ns_maplist; + u_long *ns_bucketlen[2]; + u_long ns_ticks; + u_int ns_orphans; +} natstat_4_1_27_t; + +typedef struct natstat_4_1_16 { + u_long ns_mapped[2]; + u_long ns_rules; + u_long ns_added; + u_long ns_expire; + u_long ns_inuse; + u_long ns_logged; + u_long ns_logfail; + u_long ns_memfail; + u_long ns_badnat; + u_long ns_addtrpnt; + nat_t **ns_table[2]; + hostmap_t **ns_maptable; + ipnat_t *ns_list; + void *ns_apslist; + u_int ns_wilds; + u_int ns_nattab_sz; + u_int ns_nattab_max; + u_int ns_rultab_sz; + u_int ns_rdrtab_sz; + u_int ns_trpntab_sz; + u_int ns_hostmap_sz; + nat_t *ns_instances; + hostmap_t *ns_maplist; + u_long *ns_bucketlen[2]; + u_long ns_ticks; +} natstat_4_1_16_t; + +typedef struct natstat_4_1_0 { + u_long ns_mapped[2]; + u_long ns_rules; + u_long ns_added; + u_long ns_expire; + u_long ns_inuse; + u_long ns_logged; + u_long ns_logfail; + u_long ns_memfail; + u_long ns_badnat; + u_long ns_addtrpnt; + nat_t **ns_table[2]; + hostmap_t **ns_maptable; + ipnat_t *ns_list; + void *ns_apslist; + u_int ns_wilds; + u_int ns_nattab_sz; + u_int ns_nattab_max; + u_int ns_rultab_sz; + u_int ns_rdrtab_sz; + u_int ns_trpntab_sz; + u_int ns_hostmap_sz; + nat_t *ns_instances; + hostmap_t *ns_maplist; + u_long *ns_bucketlen[2]; +} natstat_4_1_0_t; + +/* ------------------------------------------------------------------------ */ + +/* + * 5.1.0 new release (current) + * 4.1.32 fra_info:removed both fin_state & fin_nat, added fin_pktnum + * 4.1.29 added fra_flx + * 4.1.24 fra_info:added fin_cksum + * 4.1.23 fra_info:added fin_exthdr + * 4.1.11 fra_info:added fin_ifname + * 4.1.4 fra_info:added fin_hbuf + */ + +typedef struct frauth_4_1_32 { + int fra_age; + int fra_len; + int fra_index; + u_32_t fra_pass; + fr_info_4_1_32_t fra_info; + char *fra_buf; + u_32_t fra_flx; +#ifdef MENTAT + queue_t *fra_q; + mb_t *fra_m; +#endif +} frauth_4_1_32_t; + +typedef struct frauth_4_1_29 { + int fra_age; + int fra_len; + int fra_index; + u_32_t fra_pass; + fr_info_4_1_24_t fra_info; + char *fra_buf; + u_32_t fra_flx; +#ifdef MENTAT + queue_t *fra_q; + mb_t *fra_m; +#endif +} frauth_4_1_29_t; + +typedef struct frauth_4_1_24 { + int fra_age; + int fra_len; + int fra_index; + u_32_t fra_pass; + fr_info_4_1_24_t fra_info; + char *fra_buf; +#ifdef MENTAT + queue_t *fra_q; + mb_t *fra_m; +#endif +} frauth_4_1_24_t; + +typedef struct frauth_4_1_23 { + int fra_age; + int fra_len; + int fra_index; + u_32_t fra_pass; + fr_info_4_1_23_t fra_info; + char *fra_buf; +#ifdef MENTAT + queue_t *fra_q; + mb_t *fra_m; +#endif +} frauth_4_1_23_t; + +typedef struct frauth_4_1_11 { + int fra_age; + int fra_len; + int fra_index; + u_32_t fra_pass; + fr_info_4_1_11_t fra_info; + char *fra_buf; +#ifdef MENTAT + queue_t *fra_q; + mb_t *fra_m; +#endif +} frauth_4_1_11_t; + +/* ------------------------------------------------------------------------ */ + +/* + * 5.1.0 new release (current) + * 4.1.16 removed is_nat + */ +typedef struct ipstate_4_1_16 { + ipfmutex_t is_lock; + struct ipstate *is_next; + struct ipstate **is_pnext; + struct ipstate *is_hnext; + struct ipstate **is_phnext; + struct ipstate **is_me; + void *is_ifp[4]; + void *is_sync; + frentry_t *is_rule; + struct ipftq *is_tqehead[2]; + struct ipscan *is_isc; + U_QUAD_T is_pkts[4]; + U_QUAD_T is_bytes[4]; + U_QUAD_T is_icmppkts[4]; + struct ipftqent is_sti; + u_int is_frage[2]; + int is_ref; /* reference count */ + int is_isninc[2]; + u_short is_sumd[2]; + i6addr_t is_src; + i6addr_t is_dst; + u_int is_pass; + u_char is_p; /* Protocol */ + u_char is_v; + u_32_t is_hv; + u_32_t is_tag; + u_32_t is_opt[2]; /* packet options set */ + u_32_t is_optmsk[2]; /* " " mask */ + u_short is_sec; /* security options set */ + u_short is_secmsk; /* " " mask */ + u_short is_auth; /* authentication options set */ + u_short is_authmsk; /* " " mask */ + union { + icmpinfo_t is_ics; + tcpinfo4_t is_ts; + udpinfo_t is_us; + greinfo_t is_ug; + } is_ps; + u_32_t is_flags; + int is_flx[2][2]; + u_32_t is_rulen; /* rule number when created */ + u_32_t is_s0[2]; + u_short is_smsk[2]; + char is_group[FR_GROUPLEN]; + char is_sbuf[2][16]; + char is_ifname[4][LIFNAMSIZ]; +} ipstate_4_1_16_t; + +typedef struct ipstate_4_1_0 { + ipfmutex_t is_lock; + struct ipstate *is_next; + struct ipstate **is_pnext; + struct ipstate *is_hnext; + struct ipstate **is_phnext; + struct ipstate **is_me; + void *is_ifp[4]; + void *is_sync; + void *is_nat[2]; + frentry_t *is_rule; + struct ipftq *is_tqehead[2]; + struct ipscan *is_isc; + U_QUAD_T is_pkts[4]; + U_QUAD_T is_bytes[4]; + U_QUAD_T is_icmppkts[4]; + struct ipftqent is_sti; + u_int is_frage[2]; + int is_ref; + int is_isninc[2]; + u_short is_sumd[2]; + i6addr_t is_src; + i6addr_t is_dst; + u_int is_pass; + u_char is_p; + u_char is_v; + u_32_t is_hv; + u_32_t is_tag; + u_32_t is_opt[2]; + u_32_t is_optmsk[2]; + u_short is_sec; + u_short is_secmsk; + u_short is_auth; + u_short is_authmsk; + union { + icmpinfo_t is_ics; + tcpinfo4_t is_ts; + udpinfo_t is_us; + greinfo_t is_ug; + } is_ps; + u_32_t is_flags; + int is_flx[2][2]; + u_32_t is_rulen; + u_32_t is_s0[2]; + u_short is_smsk[2]; + char is_group[FR_GROUPLEN]; + char is_sbuf[2][16]; + char is_ifname[4][LIFNAMSIZ]; +} ipstate_4_1_0_t; + +typedef struct ipstate_save_4_1_34 { + void *ips_next; + struct ipstate_4_1_16 ips_is; + struct frentry_4_1_34 ips_fr; +} ipstate_save_4_1_34_t; + +typedef struct ipstate_save_4_1_16 { + void *ips_next; + ipstate_4_1_0_t ips_is; + frentry_4_1_16_t ips_fr; +} ipstate_save_4_1_16_t; + +typedef struct ipstate_save_4_1_0 { + void *ips_next; + ipstate_4_1_0_t ips_is; + frentry_4_1_0_t ips_fr; +} ipstate_save_4_1_0_t; + +/* ------------------------------------------------------------------------ */ + +/* + * 5.1.0 new release (current) + * 4.1.21 added iss_tcptab + */ +typedef struct ips_stat_4_1_21 { + u_long iss_hits; + u_long iss_miss; + u_long iss_max; + u_long iss_maxref; + u_long iss_tcp; + u_long iss_udp; + u_long iss_icmp; + u_long iss_nomem; + u_long iss_expire; + u_long iss_fin; + u_long iss_active; + u_long iss_logged; + u_long iss_logfail; + u_long iss_inuse; + u_long iss_wild; + u_long iss_killed; + u_long iss_ticks; + u_long iss_bucketfull; + int iss_statesize; + int iss_statemax; + ipstate_t **iss_table; + ipstate_t *iss_list; + u_long *iss_bucketlen; + ipftq_t *iss_tcptab; +} ips_stat_4_1_21_t; + +typedef struct ips_stat_4_1_0 { + u_long iss_hits; + u_long iss_miss; + u_long iss_max; + u_long iss_maxref; + u_long iss_tcp; + u_long iss_udp; + u_long iss_icmp; + u_long iss_nomem; + u_long iss_expire; + u_long iss_fin; + u_long iss_active; + u_long iss_logged; + u_long iss_logfail; + u_long iss_inuse; + u_long iss_wild; + u_long iss_killed; + u_long iss_ticks; + u_long iss_bucketfull; + int iss_statesize; + int iss_statemax; + ipstate_t **iss_table; + ipstate_t *iss_list; + u_long *iss_bucketlen; +} ips_stat_4_1_0_t; + +/* ------------------------------------------------------------------------ */ + +typedef struct ipfrstat_4_1_1 { + u_long ifs_exists; /* add & already exists */ + u_long ifs_nomem; + u_long ifs_new; + u_long ifs_hits; + u_long ifs_expire; + u_long ifs_inuse; + u_long ifs_retrans0; + u_long ifs_short; + struct ipfr **ifs_table; + struct ipfr **ifs_nattab; +} ipfrstat_4_1_1_t; + +/* ------------------------------------------------------------------------ */ +static int ipf_addfrstr __P((char *, int, char *, int)); +static void ipf_v4iptov5 __P((frip4_t *, fr_ip_t *)); +static void ipf_v5iptov4 __P((fr_ip_t *, frip4_t *)); +static void ipfv4tuctov5 __P((frtuc4_t *, frtuc_t *)); +static void ipfv5tuctov4 __P((frtuc_t *, frtuc4_t *)); +static int ipf_v4fripftov5 __P((fripf4_t *, char *)); +static void ipf_v5fripftov4 __P((fripf_t *, fripf4_t *)); +static int fr_frflags4to5 __P((u_32_t)); +static int fr_frflags5to4 __P((u_32_t)); + +static void friostat_current_to_4_1_0 __P((void *, friostat_4_1_0_t *, int)); +static void friostat_current_to_4_1_33 __P((void *, friostat_4_1_33_t *, int)); +static void ipstate_current_to_4_1_0 __P((void *, ipstate_4_1_0_t *)); +static void ipstate_current_to_4_1_16 __P((void *, ipstate_4_1_16_t *)); +static void ipnat_current_to_4_1_0 __P((void *, ipnat_4_1_0_t *)); +static void ipnat_current_to_4_1_14 __P((void *, ipnat_4_1_14_t *)); +static void frauth_current_to_4_1_11 __P((void *, frauth_4_1_11_t *)); +static void frauth_current_to_4_1_23 __P((void *, frauth_4_1_23_t *)); +static void frauth_current_to_4_1_24 __P((void *, frauth_4_1_24_t *)); +static void frauth_current_to_4_1_29 __P((void *, frauth_4_1_29_t *)); +static void frentry_current_to_4_1_0 __P((void *, frentry_4_1_0_t *)); +static void frentry_current_to_4_1_16 __P((void *, frentry_4_1_16_t *)); +static void frentry_current_to_4_1_34 __P((void *, frentry_4_1_34_t *)); +static void fr_info_current_to_4_1_11 __P((void *, fr_info_4_1_11_t *)); +static void fr_info_current_to_4_1_23 __P((void *, fr_info_4_1_23_t *)); +static void fr_info_current_to_4_1_24 __P((void *, fr_info_4_1_24_t *)); +static void nat_save_current_to_4_1_3 __P((void *, nat_save_4_1_3_t *)); +static void nat_save_current_to_4_1_14 __P((void *, nat_save_4_1_14_t *)); +static void nat_save_current_to_4_1_16 __P((void *, nat_save_4_1_16_t *)); +static void ipstate_save_current_to_4_1_0 __P((void *, ipstate_save_4_1_0_t *)); +static void ipstate_save_current_to_4_1_16 __P((void *, ipstate_save_4_1_16_t *)); +static void ips_stat_current_to_4_1_0 __P((void *, ips_stat_4_1_0_t *)); +static void ips_stat_current_to_4_1_21 __P((void *, ips_stat_4_1_21_t *)); +static void natstat_current_to_4_1_0 __P((void *, natstat_4_1_0_t *)); +static void natstat_current_to_4_1_16 __P((void *, natstat_4_1_16_t *)); +static void natstat_current_to_4_1_27 __P((void *, natstat_4_1_27_t *)); +static void natstat_current_to_4_1_32 __P((void *, natstat_4_1_32_t *)); +static void nat_current_to_4_1_3 __P((void *, nat_4_1_3_t *)); +static void nat_current_to_4_1_14 __P((void *, nat_4_1_14_t *)); +static void nat_current_to_4_1_25 __P((void *, nat_4_1_25_t *)); + +static void friostat_4_1_0_to_current __P((friostat_4_1_0_t *, void *)); +static void friostat_4_1_33_to_current __P((friostat_4_1_33_t *, void *)); +static void ipnat_4_1_0_to_current __P((ipnat_4_1_0_t *, void *, int)); +static void ipnat_4_1_14_to_current __P((ipnat_4_1_14_t *, void *, int)); +static void frauth_4_1_11_to_current __P((frauth_4_1_11_t *, void *)); +static void frauth_4_1_23_to_current __P((frauth_4_1_23_t *, void *)); +static void frauth_4_1_24_to_current __P((frauth_4_1_24_t *, void *)); +static void frauth_4_1_29_to_current __P((frauth_4_1_29_t *, void *)); +static void frauth_4_1_32_to_current __P((frauth_4_1_32_t *, void *)); +static void frentry_4_1_0_to_current __P((ipf_main_softc_t *, frentry_4_1_0_t *, void *, int)); +static void frentry_4_1_16_to_current __P((ipf_main_softc_t *, frentry_4_1_16_t *, void *, int)); +static void frentry_4_1_34_to_current __P((ipf_main_softc_t *, frentry_4_1_34_t *, void *, int)); +static void fr_info_4_1_11_to_current __P((fr_info_4_1_11_t *, void *)); +static void fr_info_4_1_23_to_current __P((fr_info_4_1_23_t *, void *)); +static void fr_info_4_1_24_to_current __P((fr_info_4_1_24_t *, void *)); +static void fr_info_4_1_32_to_current __P((fr_info_4_1_32_t *, void *)); +static void nat_save_4_1_3_to_current __P((ipf_main_softc_t *, nat_save_4_1_3_t *, void *)); +static void nat_save_4_1_14_to_current __P((ipf_main_softc_t *, nat_save_4_1_14_t *, void *)); +static void nat_save_4_1_16_to_current __P((ipf_main_softc_t *, nat_save_4_1_16_t *, void *)); + +/* ------------------------------------------------------------------------ */ +/* In this section is a series of short routines that deal with translating */ +/* the smaller data structures used above as their internal changes make */ +/* them inappropriate for simple assignment. */ +/* ------------------------------------------------------------------------ */ + + +static int +ipf_addfrstr(char *names, int namelen, char *str, int maxlen) +{ + char *t; + int i; + + for (i = maxlen, t = str; (*t != '\0') && (i > 0); i--) { + names[namelen++] = *t++; + } + names[namelen++] = '\0'; + return namelen; +} + + +static void +ipf_v4iptov5(v4, v5) + frip4_t *v4; + fr_ip_t *v5; +{ + v5->fi_v = v4->fi_v; + v5->fi_p = v4->fi_p; + v5->fi_xx = v4->fi_xx; + v5->fi_tos = v4->fi_tos; + v5->fi_ttl = v4->fi_ttl; + v5->fi_p = v4->fi_p; + v5->fi_optmsk = v4->fi_optmsk; + v5->fi_src = v4->fi_src; + v5->fi_dst = v4->fi_dst; + v5->fi_secmsk = v4->ofi_secmsk; + v5->fi_auth = v4->ofi_auth; + v5->fi_flx = v4->fi_flx; + v5->fi_tcpmsk = v4->fi_tcpmsk; +} + +static void +ipf_v5iptov4(v5, v4) + fr_ip_t *v5; + frip4_t *v4; +{ + v4->fi_v = v5->fi_v; + v4->fi_p = v5->fi_p; + v4->fi_xx = v5->fi_xx; + v4->fi_tos = v5->fi_tos; + v4->fi_ttl = v5->fi_ttl; + v4->fi_p = v5->fi_p; + v4->fi_optmsk = v5->fi_optmsk; + v4->fi_src = v5->fi_src; + v4->fi_dst = v5->fi_dst; + v4->ofi_secmsk = v5->fi_secmsk; + v4->ofi_auth = v5->fi_auth; + v4->fi_flx = v5->fi_flx; + v4->fi_tcpmsk = v5->fi_tcpmsk; +} + + +static void +ipfv4tuctov5(v4, v5) + frtuc4_t *v4; + frtuc_t *v5; +{ + v5->ftu_src.frp_cmp = v4->ftu_src.frp_cmp; + v5->ftu_src.frp_port = v4->ftu_src.frp_port; + v5->ftu_src.frp_top = v4->ftu_src.frp_top; + v5->ftu_dst.frp_cmp = v4->ftu_dst.frp_cmp; + v5->ftu_dst.frp_port = v4->ftu_dst.frp_port; + v5->ftu_dst.frp_top = v4->ftu_dst.frp_top; +} + + +static void +ipfv5tuctov4(v5, v4) + frtuc_t *v5; + frtuc4_t *v4; +{ + v4->ftu_src.frp_cmp = v5->ftu_src.frp_cmp; + v4->ftu_src.frp_port = v5->ftu_src.frp_port; + v4->ftu_src.frp_top = v5->ftu_src.frp_top; + v4->ftu_dst.frp_cmp = v5->ftu_dst.frp_cmp; + v4->ftu_dst.frp_port = v5->ftu_dst.frp_port; + v4->ftu_dst.frp_top = v5->ftu_dst.frp_top; +} + + +static int +ipf_v4fripftov5(frp4, dst) + fripf4_t *frp4; + char *dst; +{ + fripf_t *frp; + + frp = (fripf_t *)dst; + + ipf_v4iptov5(&frp4->fri_ip, &frp->fri_ip); + ipf_v4iptov5(&frp4->fri_mip, &frp->fri_mip); + frp->fri_icmpm = frp4->fri_icmpm; + frp->fri_icmp = frp4->fri_icmp; + frp->fri_tuc.ftu_tcpfm = frp4->fri_tuc.ftu_tcpfm; + frp->fri_tuc.ftu_tcpf = frp4->fri_tuc.ftu_tcpf; + ipfv4tuctov5(&frp4->fri_tuc, &frp->fri_tuc); + frp->fri_satype = frp4->fri_satype; + frp->fri_datype = frp4->fri_datype; + frp->fri_sifpidx = frp4->fri_sifpidx; + frp->fri_difpidx = frp4->fri_difpidx; + return 0; +} + + +static void +ipf_v5fripftov4(frp, frp4) + fripf_t *frp; + fripf4_t *frp4; +{ + + ipf_v5iptov4(&frp->fri_ip, &frp4->fri_ip); + ipf_v5iptov4(&frp->fri_mip, &frp4->fri_mip); + frp4->fri_icmpm = frp->fri_icmpm; + frp4->fri_icmp = frp->fri_icmp; + frp4->fri_tuc.ftu_tcpfm = frp->fri_tuc.ftu_tcpfm; + frp4->fri_tuc.ftu_tcpf = frp->fri_tuc.ftu_tcpf; + ipfv5tuctov4(&frp->fri_tuc, &frp4->fri_tuc); + frp4->fri_satype = frp->fri_satype; + frp4->fri_datype = frp->fri_datype; + frp4->fri_sifpidx = frp->fri_sifpidx; + frp4->fri_difpidx = frp->fri_difpidx; +} + + +/* ------------------------------------------------------------------------ */ +/* ipf_in_compat is the first of two service routines. It is responsible for*/ +/* converting data structures from user space into what's required by the */ +/* kernel module. */ +/* ------------------------------------------------------------------------ */ +int +ipf_in_compat(softc, obj, ptr, size) + ipf_main_softc_t *softc; + ipfobj_t *obj; + void *ptr; + int size; +{ + int error; + int sz; + + IPFERROR(140000); + error = EINVAL; + + switch (obj->ipfo_type) + { + default : + break; + + case IPFOBJ_FRENTRY : + if (obj->ipfo_rev >= 4013400) { + frentry_4_1_34_t *old; + + KMALLOC(old, frentry_4_1_34_t *); + if (old == NULL) { + IPFERROR(140001); + error = ENOMEM; + break; + } + error = COPYIN(obj->ipfo_ptr, old, sizeof(*old)); + if (error == 0) { + if (old->fr_type != FR_T_NONE && + old->fr_type != FR_T_IPF) { + IPFERROR(140002); + error = EINVAL; + KFREE(old); + break; + } + frentry_4_1_34_to_current(softc, old, + ptr, size); + } else { + IPFERROR(140003); + } + KFREE(old); + } else if (obj->ipfo_rev >= 4011600) { + frentry_4_1_16_t *old; + + KMALLOC(old, frentry_4_1_16_t *); + if (old == NULL) { + IPFERROR(140004); + error = ENOMEM; + break; + } + error = COPYIN(obj->ipfo_ptr, old, sizeof(*old)); + if (error == 0) { + if (old->fr_type != FR_T_NONE && + old->fr_type != FR_T_IPF) { + IPFERROR(140005); + error = EINVAL; + KFREE(old); + break; + } + frentry_4_1_16_to_current(softc, old, + ptr, size); + } else { + IPFERROR(140006); + } + KFREE(old); + } else { + frentry_4_1_0_t *old; + + KMALLOC(old, frentry_4_1_0_t *); + if (old == NULL) { + IPFERROR(140007); + error = ENOMEM; + break; + } + error = COPYIN(obj->ipfo_ptr, old, sizeof(*old)); + if (error == 0) { + if (old->fr_type != FR_T_NONE && + old->fr_type != FR_T_IPF) { + IPFERROR(140008); + error = EINVAL; + KFREE(old); + break; + } + frentry_4_1_0_to_current(softc, old, ptr, size); + } else { + IPFERROR(140009); + } + KFREE(old); + } + break; + + case IPFOBJ_IPFSTAT : + if (obj->ipfo_rev >= 4013300) { + friostat_4_1_33_t *old; + + KMALLOC(old, friostat_4_1_33_t *); + if (old == NULL) { + IPFERROR(140010); + error = ENOMEM; + break; + } + error = COPYIN(obj->ipfo_ptr, old, sizeof(*old)); + if (error == 0) { + friostat_4_1_33_to_current(old, ptr); + } else { + IPFERROR(140011); + } + } else { + friostat_4_1_0_t *old; + + KMALLOC(old, friostat_4_1_0_t *); + if (old == NULL) { + IPFERROR(140012); + error = ENOMEM; + break; + } + error = COPYIN(obj->ipfo_ptr, old, sizeof(*old)); + if (error == 0) { + friostat_4_1_0_to_current(old, ptr); + } else { + IPFERROR(140013); + } + } + break; + + case IPFOBJ_IPFINFO : /* unused */ + break; + + case IPFOBJ_IPNAT : + if (obj->ipfo_rev >= 4011400) { + ipnat_4_1_14_t *old; + + KMALLOC(old, ipnat_4_1_14_t *); + if (old == NULL) { + IPFERROR(140014); + error = ENOMEM; + break; + } + error = COPYIN(obj->ipfo_ptr, old, sizeof(*old)); + if (error == 0) { + ipnat_4_1_14_to_current(old, ptr, size); + } else { + IPFERROR(140015); + } + KFREE(old); + } else { + ipnat_4_1_0_t *old; + + KMALLOC(old, ipnat_4_1_0_t *); + if (old == NULL) { + IPFERROR(140016); + error = ENOMEM; + break; + } + error = COPYIN(obj->ipfo_ptr, old, sizeof(*old)); + if (error == 0) { + ipnat_4_1_0_to_current(old, ptr, size); + } else { + IPFERROR(140017); + } + KFREE(old); + } + break; + + case IPFOBJ_NATSTAT : + /* + * Statistics are not copied in. + */ + break; + + case IPFOBJ_NATSAVE : + if (obj->ipfo_rev >= 4011600) { + nat_save_4_1_16_t *old16; + + KMALLOC(old16, nat_save_4_1_16_t *); + if (old16 == NULL) { + IPFERROR(140018); + error = ENOMEM; + break; + } + error = COPYIN(obj->ipfo_ptr, old16, sizeof(*old16)); + if (error == 0) { + nat_save_4_1_16_to_current(softc, old16, ptr); + } else { + IPFERROR(140019); + } + KFREE(old16); + } else if (obj->ipfo_rev >= 4011400) { + nat_save_4_1_14_t *old14; + + KMALLOC(old14, nat_save_4_1_14_t *); + if (old14 == NULL) { + IPFERROR(140020); + error = ENOMEM; + break; + } + error = COPYIN(obj->ipfo_ptr, old14, sizeof(*old14)); + if (error == 0) { + nat_save_4_1_14_to_current(softc, old14, ptr); + } else { + IPFERROR(140021); + } + KFREE(old14); + } else if (obj->ipfo_rev >= 4010300) { + nat_save_4_1_3_t *old3; + + KMALLOC(old3, nat_save_4_1_3_t *); + if (old3 == NULL) { + IPFERROR(140022); + error = ENOMEM; + break; + } + error = COPYIN(obj->ipfo_ptr, old3, sizeof(*old3)); + if (error == 0) { + nat_save_4_1_3_to_current(softc, old3, ptr); + } else { + IPFERROR(140023); + } + KFREE(old3); + } + break; + + case IPFOBJ_STATESAVE : + if (obj->ipfo_rev >= 4013400) { + ipstate_save_4_1_34_t *old; + + KMALLOC(old, ipstate_save_4_1_34_t *); + if (old == NULL) { + IPFERROR(140024); + error = ENOMEM; + break; + } + error = COPYIN(obj->ipfo_ptr, old, sizeof(*old)); + if (error != 0) { + IPFERROR(140025); + } + KFREE(old); + } else if (obj->ipfo_rev >= 4011600) { + ipstate_save_4_1_16_t *old; + + KMALLOC(old, ipstate_save_4_1_16_t *); + if (old == NULL) { + IPFERROR(140026); + error = ENOMEM; + break; + } + error = COPYIN(obj->ipfo_ptr, old, sizeof(*old)); + if (error != 0) { + IPFERROR(140027); + } + KFREE(old); + } else { + ipstate_save_4_1_0_t *old; + + KMALLOC(old, ipstate_save_4_1_0_t *); + if (old == NULL) { + IPFERROR(140028); + error = ENOMEM; + break; + } + error = COPYIN(obj->ipfo_ptr, old, sizeof(*old)); + if (error != 0) { + IPFERROR(140029); + } + KFREE(old); + } + break; + + case IPFOBJ_IPSTATE : + /* + * This structure is not copied in by itself. + */ + break; + + case IPFOBJ_STATESTAT : + /* + * Statistics are not copied in. + */ + break; + + case IPFOBJ_FRAUTH : + if (obj->ipfo_rev >= 4013200) { + frauth_4_1_32_t *old32; + + KMALLOC(old32, frauth_4_1_32_t *); + if (old32 == NULL) { + IPFERROR(140030); + error = ENOMEM; + break; + } + error = COPYIN(obj->ipfo_ptr, old32, sizeof(*old32)); + if (error == 0) { + frauth_4_1_32_to_current(old32, ptr); + } else { + IPFERROR(140031); + } + KFREE(old32); + } else if (obj->ipfo_rev >= 4012900) { + frauth_4_1_29_t *old29; + + KMALLOC(old29, frauth_4_1_29_t *); + if (old29 == NULL) { + IPFERROR(140032); + error = ENOMEM; + break; + } + error = COPYIN(obj->ipfo_ptr, old29, sizeof(*old29)); + if (error == 0) { + frauth_4_1_29_to_current(old29, ptr); + } else { + IPFERROR(140033); + } + KFREE(old29); + } else if (obj->ipfo_rev >= 4012400) { + frauth_4_1_24_t *old24; + + KMALLOC(old24, frauth_4_1_24_t *); + if (old24 == NULL) { + IPFERROR(140034); + error = ENOMEM; + break; + } + error = COPYIN(obj->ipfo_ptr, old24, sizeof(*old24)); + if (error == 0) { + frauth_4_1_24_to_current(old24, ptr); + } else { + IPFERROR(140035); + } + KFREE(old24); + } else if (obj->ipfo_rev >= 4012300) { + frauth_4_1_23_t *old23; + + KMALLOC(old23, frauth_4_1_23_t *); + if (old23 == NULL) { + IPFERROR(140036); + error = ENOMEM; + break; + } + error = COPYIN(obj->ipfo_ptr, old23, sizeof(*old23)); + if (error == 0) + frauth_4_1_23_to_current(old23, ptr); + KFREE(old23); + } else if (obj->ipfo_rev >= 4011100) { + frauth_4_1_11_t *old11; + + KMALLOC(old11, frauth_4_1_11_t *); + if (old11 == NULL) { + IPFERROR(140037); + error = ENOMEM; + break; + } + error = COPYIN(obj->ipfo_ptr, old11, sizeof(*old11)); + if (error == 0) { + frauth_4_1_11_to_current(old11, ptr); + } else { + IPFERROR(140038); + } + KFREE(old11); + } + break; + + case IPFOBJ_NAT : + if (obj->ipfo_rev >= 4011400) { + sz = sizeof(nat_4_1_14_t); + } else if (obj->ipfo_rev >= 4010300) { + sz = sizeof(nat_4_1_3_t); + } else { + break; + } + bzero(ptr, sizeof(nat_t)); + error = COPYIN(obj->ipfo_ptr, ptr, sz); + if (error != 0) { + IPFERROR(140039); + } + break; + + case IPFOBJ_FRIPF : + if (obj->ipfo_rev < 5000000) { + fripf4_t *old; + + KMALLOC(old, fripf4_t *); + if (old == NULL) { + IPFERROR(140040); + error = ENOMEM; + break; + } + error = COPYIN(obj->ipfo_ptr, old, sizeof(*old)); + if (error == 0) { + ipf_v4fripftov5(old, ptr); + } else { + IPFERROR(140041); + } + KFREE(old); + } + break; + } + + return error; +} +/* ------------------------------------------------------------------------ */ + + +/* + * flags is v4 flags, returns v5 flags. + */ +static int +fr_frflags4to5(flags) + u_32_t flags; +{ + u_32_t nflags = 0; + + switch (flags & 0xf) { + case 0x0 : + nflags |= FR_CALL; + break; + case 0x1 : + nflags |= FR_BLOCK; + break; + case 0x2 : + nflags |= FR_PASS; + break; + case 0x3 : + nflags |= FR_AUTH; + break; + case 0x4 : + nflags |= FR_PREAUTH; + break; + case 0x5 : + nflags |= FR_ACCOUNT; + break; + case 0x6 : + nflags |= FR_SKIP; + break; + default : + break; + } + + if (flags & 0x00010) + nflags |= FR_LOG; + if (flags & 0x00020) + nflags |= FR_CALLNOW; + if (flags & 0x00080) + nflags |= FR_NOTSRCIP; + if (flags & 0x00040) + nflags |= FR_NOTDSTIP; + if (flags & 0x00100) + nflags |= FR_QUICK; + if (flags & 0x00200) + nflags |= FR_KEEPFRAG; + if (flags & 0x00400) + nflags |= FR_KEEPSTATE; + if (flags & 0x00800) + nflags |= FR_FASTROUTE; + if (flags & 0x01000) + nflags |= FR_RETRST; + if (flags & 0x02000) + nflags |= FR_RETICMP; + if (flags & 0x03000) + nflags |= FR_FAKEICMP; + if (flags & 0x04000) + nflags |= FR_OUTQUE; + if (flags & 0x08000) + nflags |= FR_INQUE; + if (flags & 0x10000) + nflags |= FR_LOGBODY; + if (flags & 0x20000) + nflags |= FR_LOGFIRST; + if (flags & 0x40000) + nflags |= FR_LOGORBLOCK; + if (flags & 0x100000) + nflags |= FR_FRSTRICT; + if (flags & 0x200000) + nflags |= FR_STSTRICT; + if (flags & 0x400000) + nflags |= FR_NEWISN; + if (flags & 0x800000) + nflags |= FR_NOICMPERR; + if (flags & 0x1000000) + nflags |= FR_STATESYNC; + if (flags & 0x8000000) + nflags |= FR_NOMATCH; + if (flags & 0x40000000) + nflags |= FR_COPIED; + if (flags & 0x80000000) + nflags |= FR_INACTIVE; + + return nflags; +} + +static void +frentry_4_1_34_to_current(softc, old, current, size) + ipf_main_softc_t *softc; + frentry_4_1_34_t *old; + void *current; + int size; +{ + frentry_t *fr = (frentry_t *)current; + + fr->fr_comment = -1; + fr->fr_ref = old->fr_ref; + fr->fr_statecnt = old->fr_statecnt; + fr->fr_hits = old->fr_hits; + fr->fr_bytes = old->fr_bytes; + fr->fr_lastpkt.tv_sec = old->fr_lastpkt.tv_sec; + fr->fr_lastpkt.tv_usec = old->fr_lastpkt.tv_usec; + bcopy(&old->fr_dun, &fr->fr_dun, sizeof(old->fr_dun)); + fr->fr_func = old->fr_func; + fr->fr_dsize = old->fr_dsize; + fr->fr_pps = old->fr_pps; + fr->fr_statemax = old->fr_statemax; + fr->fr_flineno = old->fr_flineno; + fr->fr_type = old->fr_type; + fr->fr_flags = fr_frflags4to5(old->fr_flags); + fr->fr_logtag = old->fr_logtag; + fr->fr_collect = old->fr_collect; + fr->fr_arg = old->fr_arg; + fr->fr_loglevel = old->fr_loglevel; + fr->fr_age[0] = old->fr_age[0]; + fr->fr_age[1] = old->fr_age[1]; + fr->fr_tifs[0].fd_ip6 = old->fr_tifs[0].ofd_ip6; + fr->fr_tifs[0].fd_type = FRD_NORMAL; + fr->fr_tifs[1].fd_ip6 = old->fr_tifs[1].ofd_ip6; + fr->fr_tifs[1].fd_type = FRD_NORMAL; + fr->fr_dif.fd_ip6 = old->fr_dif.ofd_ip6; + fr->fr_dif.fd_type = FRD_NORMAL; + if (old->fr_v == 4) + fr->fr_family = AF_INET; + if (old->fr_v == 6) + fr->fr_family = AF_INET6; + fr->fr_icode = old->fr_icode; + fr->fr_cksum = old->fr_cksum; + fr->fr_namelen = 0; + fr->fr_ifnames[0] = -1; + fr->fr_ifnames[1] = -1; + fr->fr_ifnames[2] = -1; + fr->fr_ifnames[3] = -1; + fr->fr_dif.fd_name = -1; + fr->fr_tifs[0].fd_name = -1; + fr->fr_tifs[1].fd_name = -1; + fr->fr_group = -1; + fr->fr_grhead = -1; + fr->fr_icmphead = -1; + if (size == 0) { + fr->fr_size = sizeof(*fr) + LIFNAMSIZ * 7 + FR_GROUPLEN * 2; + fr->fr_size += sizeof(fripf_t) + 16; + fr->fr_size += 9; /* room for \0's */ + } else { + char *names = fr->fr_names; + int nlen = fr->fr_namelen; + + fr->fr_size = size; + if (old->fr_ifnames[0][0] != '\0') { + fr->fr_ifnames[0] = nlen; + nlen = ipf_addfrstr(names, nlen, old->fr_ifnames[0], + LIFNAMSIZ); + } + if (old->fr_ifnames[1][0] != '\0') { + fr->fr_ifnames[1] = nlen; + nlen = ipf_addfrstr(names, nlen, old->fr_ifnames[1], + LIFNAMSIZ); + } + if (old->fr_ifnames[2][0] != '\0') { + fr->fr_ifnames[2] = nlen; + nlen = ipf_addfrstr(names, nlen, old->fr_ifnames[2], + LIFNAMSIZ); + } + if (old->fr_ifnames[3][0] != '\0') { + fr->fr_ifnames[3] = nlen; + nlen = ipf_addfrstr(names, nlen, old->fr_ifnames[3], + LIFNAMSIZ); + } + if (old->fr_tifs[0].fd_ifname[0] != '\0') { + fr->fr_tifs[0].fd_name = nlen; + nlen = ipf_addfrstr(names, nlen, + old->fr_tifs[0].fd_ifname, + LIFNAMSIZ); + } + if (old->fr_tifs[1].fd_ifname[0] != '\0') { + fr->fr_tifs[1].fd_name = nlen; + nlen = ipf_addfrstr(names, nlen, + old->fr_tifs[1].fd_ifname, + LIFNAMSIZ); + } + if (old->fr_dif.fd_ifname[0] != '\0') { + fr->fr_dif.fd_name = nlen; + nlen = ipf_addfrstr(names, nlen, + old->fr_dif.fd_ifname, LIFNAMSIZ); + } + if (old->fr_group[0] != '\0') { + fr->fr_group = nlen; + nlen = ipf_addfrstr(names, nlen, + old->fr_group, LIFNAMSIZ); + } + if (old->fr_grhead[0] != '\0') { + fr->fr_grhead = nlen; + nlen = ipf_addfrstr(names, nlen, + old->fr_grhead, LIFNAMSIZ); + } + fr->fr_namelen = nlen; + + if (old->fr_type == FR_T_IPF) { + int offset = fr->fr_namelen; + ipfobj_t obj; + int error; + + obj.ipfo_type = IPFOBJ_FRIPF; + obj.ipfo_rev = 4010100; + obj.ipfo_ptr = old->fr_data; + + if ((offset & 7) != 0) + offset += 8 - (offset & 7); + error = ipf_in_compat(softc, &obj, + fr->fr_names + offset, 0); + if (error == 0) { + fr->fr_data = fr->fr_names + offset; + fr->fr_dsize = sizeof(fripf_t); + } + } + } +} + +static void +frentry_4_1_16_to_current(softc, old, current, size) + ipf_main_softc_t *softc; + frentry_4_1_16_t *old; + void *current; + int size; +{ + frentry_t *fr = (frentry_t *)current; + + fr->fr_comment = -1; + fr->fr_ref = old->fr_ref; + fr->fr_statecnt = old->fr_statecnt; + fr->fr_hits = old->fr_hits; + fr->fr_bytes = old->fr_bytes; + fr->fr_lastpkt.tv_sec = old->fr_lastpkt.tv_sec; + fr->fr_lastpkt.tv_usec = old->fr_lastpkt.tv_usec; + bcopy(&old->fr_dun, &fr->fr_dun, sizeof(old->fr_dun)); + fr->fr_func = old->fr_func; + fr->fr_dsize = old->fr_dsize; + fr->fr_pps = old->fr_pps; + fr->fr_statemax = old->fr_statemax; + fr->fr_flineno = old->fr_flineno; + fr->fr_type = old->fr_type; + fr->fr_flags = fr_frflags4to5(old->fr_flags); + fr->fr_logtag = old->fr_logtag; + fr->fr_collect = old->fr_collect; + fr->fr_arg = old->fr_arg; + fr->fr_loglevel = old->fr_loglevel; + fr->fr_age[0] = old->fr_age[0]; + fr->fr_age[1] = old->fr_age[1]; + fr->fr_tifs[0].fd_ip6 = old->fr_tifs[0].ofd_ip6; + fr->fr_tifs[0].fd_type = FRD_NORMAL; + fr->fr_tifs[1].fd_ip6 = old->fr_tifs[1].ofd_ip6; + fr->fr_tifs[1].fd_type = FRD_NORMAL; + fr->fr_dif.fd_ip6 = old->fr_dif.ofd_ip6; + fr->fr_dif.fd_type = FRD_NORMAL; + if (old->fr_v == 4) + fr->fr_family = AF_INET; + if (old->fr_v == 6) + fr->fr_family = AF_INET6; + fr->fr_icode = old->fr_icode; + fr->fr_cksum = old->fr_cksum; + fr->fr_namelen = 0; + fr->fr_ifnames[0] = -1; + fr->fr_ifnames[1] = -1; + fr->fr_ifnames[2] = -1; + fr->fr_ifnames[3] = -1; + fr->fr_dif.fd_name = -1; + fr->fr_tifs[0].fd_name = -1; + fr->fr_tifs[1].fd_name = -1; + fr->fr_group = -1; + fr->fr_grhead = -1; + fr->fr_icmphead = -1; + if (size == 0) { + fr->fr_size = sizeof(*fr) + LIFNAMSIZ * 7 + FR_GROUPLEN * 2; + fr->fr_size += 9; /* room for \0's */ + } else { + char *names = fr->fr_names; + int nlen = fr->fr_namelen; + + fr->fr_size = size; + if (old->fr_ifnames[0][0] != '\0') { + fr->fr_ifnames[0] = nlen; + nlen = ipf_addfrstr(names, nlen, old->fr_ifnames[0], + LIFNAMSIZ); + } + if (old->fr_ifnames[1][0] != '\0') { + fr->fr_ifnames[1] = nlen; + nlen = ipf_addfrstr(names, nlen, old->fr_ifnames[1], + LIFNAMSIZ); + } + if (old->fr_ifnames[2][0] != '\0') { + fr->fr_ifnames[2] = nlen; + nlen = ipf_addfrstr(names, nlen, old->fr_ifnames[2], + LIFNAMSIZ); + } + if (old->fr_ifnames[3][0] != '\0') { + fr->fr_ifnames[3] = nlen; + nlen = ipf_addfrstr(names, nlen, old->fr_ifnames[3], + LIFNAMSIZ); + } + if (old->fr_tifs[0].fd_ifname[0] != '\0') { + fr->fr_tifs[0].fd_name = nlen; + nlen = ipf_addfrstr(names, nlen, + old->fr_tifs[0].fd_ifname, + LIFNAMSIZ); + } + if (old->fr_tifs[1].fd_ifname[0] != '\0') { + fr->fr_tifs[1].fd_name = nlen; + nlen = ipf_addfrstr(names, nlen, + old->fr_tifs[1].fd_ifname, + LIFNAMSIZ); + } + if (old->fr_dif.fd_ifname[0] != '\0') { + fr->fr_dif.fd_name = nlen; + nlen = ipf_addfrstr(names, nlen, + old->fr_dif.fd_ifname, LIFNAMSIZ); + } + if (old->fr_group[0] != '\0') { + fr->fr_group = nlen; + nlen = ipf_addfrstr(names, nlen, + old->fr_group, LIFNAMSIZ); + } + if (old->fr_grhead[0] != '\0') { + fr->fr_grhead = nlen; + nlen = ipf_addfrstr(names, nlen, + old->fr_grhead, LIFNAMSIZ); + } + fr->fr_namelen = nlen; + + if (old->fr_type == FR_T_IPF) { + int offset = fr->fr_namelen; + ipfobj_t obj; + int error; + + obj.ipfo_type = IPFOBJ_FRIPF; + obj.ipfo_rev = 4010100; + obj.ipfo_ptr = old->fr_data; + + if ((offset & 7) != 0) + offset += 8 - (offset & 7); + error = ipf_in_compat(softc, &obj, + fr->fr_names + offset, 0); + if (error == 0) { + fr->fr_data = fr->fr_names + offset; + fr->fr_dsize = sizeof(fripf_t); + } + } + } +} + + +static void +frentry_4_1_0_to_current(softc, old, current, size) + ipf_main_softc_t *softc; + frentry_4_1_0_t *old; + void *current; + int size; +{ + frentry_t *fr = (frentry_t *)current; + + fr->fr_size = sizeof(*fr); + fr->fr_comment = -1; + fr->fr_ref = old->fr_ref; + fr->fr_statecnt = old->fr_statecnt; + fr->fr_hits = old->fr_hits; + fr->fr_bytes = old->fr_bytes; + fr->fr_lastpkt.tv_sec = old->fr_lastpkt.tv_sec; + fr->fr_lastpkt.tv_usec = old->fr_lastpkt.tv_usec; + bcopy(&old->fr_dun, &fr->fr_dun, sizeof(old->fr_dun)); + fr->fr_func = old->fr_func; + fr->fr_dsize = old->fr_dsize; + fr->fr_pps = old->fr_pps; + fr->fr_statemax = old->fr_statemax; + fr->fr_flineno = old->fr_flineno; + fr->fr_type = old->fr_type; + fr->fr_flags = fr_frflags4to5(old->fr_flags); + fr->fr_logtag = old->fr_logtag; + fr->fr_collect = old->fr_collect; + fr->fr_arg = old->fr_arg; + fr->fr_loglevel = old->fr_loglevel; + fr->fr_age[0] = old->fr_age[0]; + fr->fr_age[1] = old->fr_age[1]; + fr->fr_tifs[0].fd_ip6 = old->fr_tifs[0].ofd_ip6; + fr->fr_tifs[0].fd_type = FRD_NORMAL; + fr->fr_tifs[1].fd_ip6 = old->fr_tifs[1].ofd_ip6; + fr->fr_tifs[1].fd_type = FRD_NORMAL; + fr->fr_dif.fd_ip6 = old->fr_dif.ofd_ip6; + fr->fr_dif.fd_type = FRD_NORMAL; + if (old->fr_v == 4) + fr->fr_family = AF_INET; + if (old->fr_v == 6) + fr->fr_family = AF_INET6; + fr->fr_icode = old->fr_icode; + fr->fr_cksum = old->fr_cksum; + fr->fr_namelen = 0; + fr->fr_ifnames[0] = -1; + fr->fr_ifnames[1] = -1; + fr->fr_ifnames[2] = -1; + fr->fr_ifnames[3] = -1; + fr->fr_dif.fd_name = -1; + fr->fr_tifs[0].fd_name = -1; + fr->fr_tifs[1].fd_name = -1; + fr->fr_group = -1; + fr->fr_grhead = -1; + fr->fr_icmphead = -1; + if (size == 0) { + fr->fr_size = sizeof(*fr) + LIFNAMSIZ * 7 + FR_GROUPLEN * 2; + fr->fr_size += 9; /* room for \0's */ + } else { + char *names = fr->fr_names; + int nlen = fr->fr_namelen; + + fr->fr_size = size; + if (old->fr_ifnames[0][0] != '\0') { + fr->fr_ifnames[0] = nlen; + nlen = ipf_addfrstr(names, nlen, old->fr_ifnames[0], + LIFNAMSIZ); + } + if (old->fr_ifnames[1][0] != '\0') { + fr->fr_ifnames[1] = nlen; + nlen = ipf_addfrstr(names, nlen, old->fr_ifnames[1], + LIFNAMSIZ); + } + if (old->fr_ifnames[2][0] != '\0') { + fr->fr_ifnames[2] = nlen; + nlen = ipf_addfrstr(names, nlen, old->fr_ifnames[2], + LIFNAMSIZ); + } + if (old->fr_ifnames[3][0] != '\0') { + fr->fr_ifnames[3] = nlen; + nlen = ipf_addfrstr(names, nlen, old->fr_ifnames[3], + LIFNAMSIZ); + } + if (old->fr_tifs[0].fd_ifname[0] != '\0') { + fr->fr_tifs[0].fd_name = nlen; + nlen = ipf_addfrstr(names, nlen, + old->fr_tifs[0].fd_ifname, + LIFNAMSIZ); + } + if (old->fr_tifs[1].fd_ifname[0] != '\0') { + fr->fr_tifs[1].fd_name = nlen; + nlen = ipf_addfrstr(names, nlen, + old->fr_tifs[1].fd_ifname, + LIFNAMSIZ); + } + if (old->fr_dif.fd_ifname[0] != '\0') { + fr->fr_dif.fd_name = nlen; + nlen = ipf_addfrstr(names, nlen, + old->fr_dif.fd_ifname, LIFNAMSIZ); + } + if (old->fr_group[0] != '\0') { + fr->fr_group = nlen; + nlen = ipf_addfrstr(names, nlen, + old->fr_group, LIFNAMSIZ); + } + if (old->fr_grhead[0] != '\0') { + fr->fr_grhead = nlen; + nlen = ipf_addfrstr(names, nlen, + old->fr_grhead, LIFNAMSIZ); + } + fr->fr_namelen = nlen; + + if (old->fr_type == FR_T_IPF) { + int offset = fr->fr_namelen; + ipfobj_t obj; + int error; + + obj.ipfo_type = IPFOBJ_FRIPF; + obj.ipfo_rev = 4010100; + obj.ipfo_ptr = old->fr_data; + + if ((offset & 7) != 0) + offset += 8 - (offset & 7); + offset += 8 - (offset & 7); + error = ipf_in_compat(softc, &obj, + fr->fr_names + offset, 0); + if (error == 0) { + fr->fr_data = fr->fr_names + offset; + fr->fr_dsize = sizeof(fripf_t); + } + } + } +} + + +static void +friostat_4_1_33_to_current(old, current) + friostat_4_1_33_t *old; + void *current; +{ + friostat_t *fiop = (friostat_t *)current; + + bcopy(&old->of_st[0], &fiop->f_st[0].fr_pass, sizeof(old->of_st[0])); + bcopy(&old->of_st[1], &fiop->f_st[1].fr_pass, sizeof(old->of_st[1])); + + fiop->f_ipf[0][0] = old->f_ipf[0][0]; + fiop->f_ipf[0][1] = old->f_ipf[0][1]; + fiop->f_ipf[1][0] = old->f_ipf[1][0]; + fiop->f_ipf[1][1] = old->f_ipf[1][1]; + fiop->f_acct[0][0] = old->f_acct[0][0]; + fiop->f_acct[0][1] = old->f_acct[0][1]; + fiop->f_acct[1][0] = old->f_acct[1][0]; + fiop->f_acct[1][1] = old->f_acct[1][1]; + fiop->f_auth = fiop->f_auth; + bcopy(&old->f_groups, &fiop->f_groups, sizeof(old->f_groups)); + bcopy(&old->f_froute, &fiop->f_froute, sizeof(old->f_froute)); + fiop->f_ticks = old->f_ticks; + bcopy(&old->f_locks, &fiop->f_locks, sizeof(old->f_locks)); + fiop->f_defpass = old->f_defpass; + fiop->f_active = old->f_active; + fiop->f_running = old->f_running; + fiop->f_logging = old->f_logging; + fiop->f_features = old->f_features; + bcopy(old->f_version, fiop->f_version, sizeof(old->f_version)); +} + + +static void +friostat_4_1_0_to_current(old, current) + friostat_4_1_0_t *old; + void *current; +{ + friostat_t *fiop = (friostat_t *)current; + + bcopy(&old->of_st[0], &fiop->f_st[0].fr_pass, sizeof(old->of_st[0])); + bcopy(&old->of_st[1], &fiop->f_st[1].fr_pass, sizeof(old->of_st[1])); + + fiop->f_ipf[0][0] = old->f_ipf[0][0]; + fiop->f_ipf[0][1] = old->f_ipf[0][1]; + fiop->f_ipf[1][0] = old->f_ipf[1][0]; + fiop->f_ipf[1][1] = old->f_ipf[1][1]; + fiop->f_acct[0][0] = old->f_acct[0][0]; + fiop->f_acct[0][1] = old->f_acct[0][1]; + fiop->f_acct[1][0] = old->f_acct[1][0]; + fiop->f_acct[1][1] = old->f_acct[1][1]; + fiop->f_auth = fiop->f_auth; + bcopy(&old->f_groups, &fiop->f_groups, sizeof(old->f_groups)); + bcopy(&old->f_froute, &fiop->f_froute, sizeof(old->f_froute)); + fiop->f_ticks = old->f_ticks; + bcopy(&old->f_locks, &fiop->f_locks, sizeof(old->f_locks)); + fiop->f_defpass = old->f_defpass; + fiop->f_active = old->f_active; + fiop->f_running = old->f_running; + fiop->f_logging = old->f_logging; + fiop->f_features = old->f_features; + bcopy(old->f_version, fiop->f_version, sizeof(old->f_version)); +} + + +static void +ipnat_4_1_14_to_current(old, current, size) + ipnat_4_1_14_t *old; + void *current; + int size; +{ + ipnat_t *np = (ipnat_t *)current; + + np->in_space = old->in_space; + np->in_hv[0] = old->in_hv; + np->in_hv[1] = old->in_hv; + np->in_flineno = old->in_flineno; + if (old->in_redir == NAT_REDIRECT) + np->in_dpnext = old->in_pnext; + else + np->in_spnext = old->in_pnext; + np->in_v[0] = old->in_v; + np->in_v[1] = old->in_v; + np->in_flags = old->in_flags; + np->in_mssclamp = old->in_mssclamp; + np->in_age[0] = old->in_age[0]; + np->in_age[1] = old->in_age[1]; + np->in_redir = old->in_redir; + np->in_pr[0] = old->in_p; + np->in_pr[1] = old->in_p; + if (np->in_redir == NAT_REDIRECT) { + np->in_ndst.na_nextaddr = old->in_next6; + np->in_ndst.na_addr[0] = old->in_in[0]; + np->in_ndst.na_addr[1] = old->in_in[1]; + np->in_ndst.na_atype = FRI_NORMAL; + np->in_odst.na_addr[0] = old->in_out[0]; + np->in_odst.na_addr[1] = old->in_out[1]; + np->in_odst.na_atype = FRI_NORMAL; + np->in_osrc.na_addr[0] = old->in_src[0]; + np->in_osrc.na_addr[1] = old->in_src[1]; + np->in_osrc.na_atype = FRI_NORMAL; + } else { + np->in_nsrc.na_nextaddr = old->in_next6; + np->in_nsrc.na_addr[0] = old->in_out[0]; + np->in_nsrc.na_addr[1] = old->in_out[1]; + np->in_nsrc.na_atype = FRI_NORMAL; + np->in_osrc.na_addr[0] = old->in_in[0]; + np->in_osrc.na_addr[1] = old->in_in[1]; + np->in_osrc.na_atype = FRI_NORMAL; + np->in_odst.na_addr[0] = old->in_src[0]; + np->in_odst.na_addr[1] = old->in_src[1]; + np->in_odst.na_atype = FRI_NORMAL; + } + ipfv4tuctov5(&old->in_tuc, &np->in_tuc); + if (np->in_redir == NAT_REDIRECT) { + np->in_dpmin = old->in_port[0]; + np->in_dpmax = old->in_port[1]; + } else { + np->in_spmin = old->in_port[0]; + np->in_spmax = old->in_port[1]; + } + np->in_ppip = old->in_ppip; + np->in_ippip = old->in_ippip; + np->in_tag = old->in_tag; + + np->in_namelen = 0; + np->in_plabel = -1; + np->in_ifnames[0] = -1; + np->in_ifnames[1] = -1; + + if (size == 0) { + np->in_size = sizeof(*np); + np->in_size += LIFNAMSIZ * 2 + APR_LABELLEN; + np->in_size += 3; + } else { + int nlen = np->in_namelen; + char *names = np->in_names; + + if (old->in_ifnames[0][0] != '\0') { + np->in_ifnames[0] = nlen; + nlen = ipf_addfrstr(names, nlen, old->in_ifnames[0], + LIFNAMSIZ); + } + if (old->in_ifnames[1][0] != '\0') { + np->in_ifnames[0] = nlen; + nlen = ipf_addfrstr(names, nlen, old->in_ifnames[1], + LIFNAMSIZ); + } + if (old->in_plabel[0] != '\0') { + np->in_plabel = nlen; + nlen = ipf_addfrstr(names, nlen, old->in_plabel, + LIFNAMSIZ); + } + np->in_namelen = nlen; + np->in_size = size; + } +} + + +static void +ipnat_4_1_0_to_current(old, current, size) + ipnat_4_1_0_t *old; + void *current; + int size; +{ + ipnat_t *np = (ipnat_t *)current; + + np->in_space = old->in_space; + np->in_hv[0] = old->in_hv; + np->in_hv[1] = old->in_hv; + np->in_flineno = old->in_flineno; + if (old->in_redir == NAT_REDIRECT) + np->in_dpnext = old->in_pnext; + else + np->in_spnext = old->in_pnext; + np->in_v[0] = old->in_v; + np->in_v[1] = old->in_v; + np->in_flags = old->in_flags; + np->in_mssclamp = old->in_mssclamp; + np->in_age[0] = old->in_age[0]; + np->in_age[1] = old->in_age[1]; + np->in_redir = old->in_redir; + np->in_pr[0] = old->in_p; + np->in_pr[1] = old->in_p; + if (np->in_redir == NAT_REDIRECT) { + np->in_ndst.na_nextaddr = old->in_next6; + bcopy(&old->in_in, &np->in_ndst.na_addr, sizeof(old->in_in)); + bcopy(&old->in_out, &np->in_odst.na_addr, sizeof(old->in_out)); + bcopy(&old->in_src, &np->in_osrc.na_addr, sizeof(old->in_src)); + } else { + np->in_nsrc.na_nextaddr = old->in_next6; + bcopy(&old->in_in, &np->in_osrc.na_addr, sizeof(old->in_in)); + bcopy(&old->in_out, &np->in_nsrc.na_addr, sizeof(old->in_out)); + bcopy(&old->in_src, &np->in_odst.na_addr, sizeof(old->in_src)); + } + ipfv4tuctov5(&old->in_tuc, &np->in_tuc); + if (np->in_redir == NAT_REDIRECT) { + np->in_dpmin = old->in_port[0]; + np->in_dpmax = old->in_port[1]; + } else { + np->in_spmin = old->in_port[0]; + np->in_spmax = old->in_port[1]; + } + np->in_ppip = old->in_ppip; + np->in_ippip = old->in_ippip; + bcopy(&old->in_tag, &np->in_tag, sizeof(np->in_tag)); + + np->in_namelen = 0; + np->in_plabel = -1; + np->in_ifnames[0] = -1; + np->in_ifnames[1] = -1; + + if (size == 0) { + np->in_size = sizeof(*np); + np->in_size += LIFNAMSIZ * 2 + APR_LABELLEN; + np->in_size += 3; + } else { + int nlen = np->in_namelen; + char *names = np->in_names; + + if (old->in_ifnames[0][0] != '\0') { + np->in_ifnames[0] = nlen; + nlen = ipf_addfrstr(names, nlen, old->in_ifnames[0], + LIFNAMSIZ); + } + if (old->in_ifnames[1][0] != '\0') { + np->in_ifnames[0] = nlen; + nlen = ipf_addfrstr(names, nlen, old->in_ifnames[1], + LIFNAMSIZ); + } + if (old->in_plabel[0] != '\0') { + np->in_plabel = nlen; + nlen = ipf_addfrstr(names, nlen, old->in_plabel, + LIFNAMSIZ); + } + np->in_namelen = nlen; + np->in_size = size; + } +} + + +static void +frauth_4_1_32_to_current(old, current) + frauth_4_1_32_t *old; + void *current; +{ + frauth_t *fra = (frauth_t *)current; + + fra->fra_age = old->fra_age; + fra->fra_len = old->fra_len; + fra->fra_index = old->fra_index; + fra->fra_pass = old->fra_pass; + fr_info_4_1_32_to_current(&old->fra_info, &fra->fra_info); + fra->fra_buf = old->fra_buf; + fra->fra_flx = old->fra_flx; +#ifdef MENTAT + fra->fra_q = old->fra_q; + fra->fra_m = old->fra_m; +#endif +} + + +static void +frauth_4_1_29_to_current(old, current) + frauth_4_1_29_t *old; + void *current; +{ + frauth_t *fra = (frauth_t *)current; + + fra->fra_age = old->fra_age; + fra->fra_len = old->fra_len; + fra->fra_index = old->fra_index; + fra->fra_pass = old->fra_pass; + fr_info_4_1_24_to_current(&old->fra_info, &fra->fra_info); + fra->fra_buf = old->fra_buf; + fra->fra_flx = old->fra_flx; +#ifdef MENTAT + fra->fra_q = old->fra_q; + fra->fra_m = old->fra_m; +#endif +} + + +static void +frauth_4_1_24_to_current(old, current) + frauth_4_1_24_t *old; + void *current; +{ + frauth_t *fra = (frauth_t *)current; + + fra->fra_age = old->fra_age; + fra->fra_len = old->fra_len; + fra->fra_index = old->fra_index; + fra->fra_pass = old->fra_pass; + fr_info_4_1_24_to_current(&old->fra_info, &fra->fra_info); + fra->fra_buf = old->fra_buf; +#ifdef MENTAT + fra->fra_q = old->fra_q; + fra->fra_m = old->fra_m; +#endif +} + + +static void +frauth_4_1_23_to_current(old, current) + frauth_4_1_23_t *old; + void *current; +{ + frauth_t *fra = (frauth_t *)current; + + fra->fra_age = old->fra_age; + fra->fra_len = old->fra_len; + fra->fra_index = old->fra_index; + fra->fra_pass = old->fra_pass; + fr_info_4_1_23_to_current(&old->fra_info, &fra->fra_info); + fra->fra_buf = old->fra_buf; +#ifdef MENTAT + fra->fra_q = old->fra_q; + fra->fra_m = old->fra_m; +#endif +} + + +static void +frauth_4_1_11_to_current(old, current) + frauth_4_1_11_t *old; + void *current; +{ + frauth_t *fra = (frauth_t *)current; + + fra->fra_age = old->fra_age; + fra->fra_len = old->fra_len; + fra->fra_index = old->fra_index; + fra->fra_pass = old->fra_pass; + fr_info_4_1_11_to_current(&old->fra_info, &fra->fra_info); + fra->fra_buf = old->fra_buf; +#ifdef MENTAT + fra->fra_q = old->fra_q; + fra->fra_m = old->fra_m; +#endif +} + + +static void +fr_info_4_1_32_to_current(old, current) + fr_info_4_1_32_t *old; + void *current; +{ + fr_info_t *fin = (fr_info_t *)current; + + fin->fin_ifp = old->fin_ifp; + ipf_v4iptov5(&old->fin_fi, &fin->fin_fi); + bcopy(&old->fin_dat, &fin->fin_dat, sizeof(old->fin_dat)); + fin->fin_out = old->fin_out; + fin->fin_rev = old->fin_rev; + fin->fin_hlen = old->fin_hlen; + fin->fin_tcpf = old->ofin_tcpf; + fin->fin_icode = old->fin_icode; + fin->fin_rule = old->fin_rule; + bcopy(old->fin_group, fin->fin_group, sizeof(old->fin_group)); + fin->fin_fr = old->fin_fr; + fin->fin_dp = old->fin_dp; + fin->fin_dlen = old->fin_dlen; + fin->fin_plen = old->fin_plen; + fin->fin_ipoff = old->fin_ipoff; + fin->fin_id = old->fin_id; + fin->fin_off = old->fin_off; + fin->fin_depth = old->fin_depth; + fin->fin_error = old->fin_error; + fin->fin_cksum = old->fin_cksum; + fin->fin_nattag = old->fin_nattag; + fin->fin_ip = old->ofin_ip; + fin->fin_mp = old->fin_mp; + fin->fin_m = old->fin_m; +#ifdef MENTAT + fin->fin_qfm = old->fin_qfm; + fin->fin_qpi = old->fin_qpi; +#endif +#ifdef __sgi + fin->fin_hbuf = old->fin_hbuf; +#endif +} + + +static void +fr_info_4_1_24_to_current(old, current) + fr_info_4_1_24_t *old; + void *current; +{ + fr_info_t *fin = (fr_info_t *)current; + + fin->fin_ifp = old->fin_ifp; + ipf_v4iptov5(&old->fin_fi, &fin->fin_fi); + bcopy(&old->fin_dat, &fin->fin_dat, sizeof(old->fin_dat)); + fin->fin_out = old->fin_out; + fin->fin_rev = old->fin_rev; + fin->fin_hlen = old->fin_hlen; + fin->fin_tcpf = old->ofin_tcpf; + fin->fin_icode = old->fin_icode; + fin->fin_rule = old->fin_rule; + bcopy(old->fin_group, fin->fin_group, sizeof(old->fin_group)); + fin->fin_fr = old->fin_fr; + fin->fin_dp = old->fin_dp; + fin->fin_dlen = old->fin_dlen; + fin->fin_plen = old->fin_plen; + fin->fin_ipoff = old->fin_ipoff; + fin->fin_id = old->fin_id; + fin->fin_off = old->fin_off; + fin->fin_depth = old->fin_depth; + fin->fin_error = old->fin_error; + fin->fin_cksum = old->fin_cksum; + fin->fin_nattag = old->fin_nattag; + fin->fin_ip = old->ofin_ip; + fin->fin_mp = old->fin_mp; + fin->fin_m = old->fin_m; +#ifdef MENTAT + fin->fin_qfm = old->fin_qfm; + fin->fin_qpi = old->fin_qpi; +#endif +#ifdef __sgi + fin->fin_hbuf = old->fin_hbuf; +#endif +} + + +static void +fr_info_4_1_23_to_current(old, current) + fr_info_4_1_23_t *old; + void *current; +{ + fr_info_t *fin = (fr_info_t *)current; + + fin->fin_ifp = old->fin_ifp; + ipf_v4iptov5(&old->fin_fi, &fin->fin_fi); + bcopy(&old->fin_dat, &fin->fin_dat, sizeof(old->fin_dat)); + fin->fin_out = old->fin_out; + fin->fin_rev = old->fin_rev; + fin->fin_hlen = old->fin_hlen; + fin->fin_tcpf = old->ofin_tcpf; + fin->fin_icode = old->fin_icode; + fin->fin_rule = old->fin_rule; + bcopy(old->fin_group, fin->fin_group, sizeof(old->fin_group)); + fin->fin_fr = old->fin_fr; + fin->fin_dp = old->fin_dp; + fin->fin_dlen = old->fin_dlen; + fin->fin_plen = old->fin_plen; + fin->fin_ipoff = old->fin_ipoff; + fin->fin_id = old->fin_id; + fin->fin_off = old->fin_off; + fin->fin_depth = old->fin_depth; + fin->fin_error = old->fin_error; + fin->fin_nattag = old->fin_nattag; + fin->fin_ip = old->ofin_ip; + fin->fin_mp = old->fin_mp; + fin->fin_m = old->fin_m; +#ifdef MENTAT + fin->fin_qfm = old->fin_qfm; + fin->fin_qpi = old->fin_qpi; +#endif +#ifdef __sgi + fin->fin_hbuf = fin->fin_hbuf; +#endif +} + + +static void +fr_info_4_1_11_to_current(old, current) + fr_info_4_1_11_t *old; + void *current; +{ + fr_info_t *fin = (fr_info_t *)current; + + fin->fin_ifp = old->fin_ifp; + ipf_v4iptov5(&old->fin_fi, &fin->fin_fi); + bcopy(&old->fin_dat, &fin->fin_dat, sizeof(old->fin_dat)); + fin->fin_out = old->fin_out; + fin->fin_rev = old->fin_rev; + fin->fin_hlen = old->fin_hlen; + fin->fin_tcpf = old->ofin_tcpf; + fin->fin_icode = old->fin_icode; + fin->fin_rule = old->fin_rule; + bcopy(old->fin_group, fin->fin_group, sizeof(old->fin_group)); + fin->fin_fr = old->fin_fr; + fin->fin_dp = old->fin_dp; + fin->fin_dlen = old->fin_dlen; + fin->fin_plen = old->fin_plen; + fin->fin_ipoff = old->fin_ipoff; + fin->fin_id = old->fin_id; + fin->fin_off = old->fin_off; + fin->fin_depth = old->fin_depth; + fin->fin_error = old->fin_error; + fin->fin_nattag = old->fin_nattag; + fin->fin_ip = old->ofin_ip; + fin->fin_mp = old->fin_mp; + fin->fin_m = old->fin_m; +#ifdef MENTAT + fin->fin_qfm = old->fin_qfm; + fin->fin_qpi = old->fin_qpi; +#endif +#ifdef __sgi + fin->fin_hbuf = fin->fin_hbuf; +#endif +} + + +static void +nat_4_1_3_to_current(nat_4_1_3_t *old, nat_t *current) +{ + bzero((void *)current, sizeof(*current)); + bcopy((void *)old, (void *)current, sizeof(*old)); +} + + +static void +nat_4_1_14_to_current(nat_4_1_14_t *old, nat_t *current) +{ + bzero((void *)current, sizeof(*current)); + bcopy((void *)old, (void *)current, sizeof(*old)); +} + + +static void +nat_save_4_1_16_to_current(softc, old, current) + ipf_main_softc_t *softc; + nat_save_4_1_16_t *old; + void *current; +{ + nat_save_t *nats = (nat_save_t *)current; + + nats->ipn_next = old->ipn_next; + nat_4_1_14_to_current(&old->ipn_nat, &nats->ipn_nat); + bcopy(&old->ipn_ipnat, &nats->ipn_ipnat, sizeof(old->ipn_ipnat)); + frentry_4_1_16_to_current(softc, &old->ipn_fr, &nats->ipn_fr, 0); + nats->ipn_dsize = old->ipn_dsize; + bcopy(old->ipn_data, nats->ipn_data, sizeof(nats->ipn_data)); +} + + +static void +nat_save_4_1_14_to_current(softc, old, current) + ipf_main_softc_t *softc; + nat_save_4_1_14_t *old; + void *current; +{ + nat_save_t *nats = (nat_save_t *)current; + + nats->ipn_next = old->ipn_next; + nat_4_1_14_to_current(&old->ipn_nat, &nats->ipn_nat); + bcopy(&old->ipn_ipnat, &nats->ipn_ipnat, sizeof(old->ipn_ipnat)); + frentry_4_1_0_to_current(softc, &old->ipn_fr, &nats->ipn_fr, 0); + nats->ipn_dsize = old->ipn_dsize; + bcopy(old->ipn_data, nats->ipn_data, sizeof(nats->ipn_data)); +} + + +static void +nat_save_4_1_3_to_current(softc, old, current) + ipf_main_softc_t *softc; + nat_save_4_1_3_t *old; + void *current; +{ + nat_save_t *nats = (nat_save_t *)current; + + nats->ipn_next = old->ipn_next; + nat_4_1_3_to_current(&old->ipn_nat, &nats->ipn_nat); + ipnat_4_1_0_to_current(&old->ipn_ipnat, &nats->ipn_ipnat, 0); + frentry_4_1_0_to_current(softc, &old->ipn_fr, &nats->ipn_fr, 0); + nats->ipn_dsize = old->ipn_dsize; + bcopy(old->ipn_data, nats->ipn_data, sizeof(nats->ipn_data)); +} + + +static void +natstat_current_to_4_1_32(current, old) + void *current; + natstat_4_1_32_t *old; +{ + natstat_t *ns = (natstat_t *)current; + + old->ns_mapped[0] = ns->ns_side[0].ns_translated; + old->ns_mapped[1] = ns->ns_side[1].ns_translated; + old->ns_rules = ns->ns_side[0].ns_inuse + ns->ns_side[1].ns_inuse; + old->ns_added = ns->ns_side[0].ns_added + ns->ns_side[1].ns_added; + old->ns_expire = ns->ns_expire; + old->ns_inuse = ns->ns_side[0].ns_inuse + ns->ns_side[1].ns_inuse; + old->ns_logged = ns->ns_log_ok; + old->ns_logfail = ns->ns_log_fail; + old->ns_memfail = ns->ns_side[0].ns_memfail + ns->ns_side[1].ns_memfail; + old->ns_badnat = ns->ns_side[0].ns_badnat + ns->ns_side[1].ns_badnat; + old->ns_addtrpnt = ns->ns_addtrpnt; + old->ns_table[0] = ns->ns_side[0].ns_table; + old->ns_table[1] = ns->ns_side[1].ns_table; + old->ns_maptable = NULL; + old->ns_list = ns->ns_list; + old->ns_apslist = NULL; + old->ns_wilds = ns->ns_wilds; + old->ns_nattab_sz = ns->ns_nattab_sz; + old->ns_nattab_max = ns->ns_nattab_max; + old->ns_rultab_sz = ns->ns_rultab_sz; + old->ns_rdrtab_sz = ns->ns_rdrtab_sz; + old->ns_trpntab_sz = ns->ns_trpntab_sz; + old->ns_hostmap_sz = 0; + old->ns_instances = ns->ns_instances; + old->ns_maplist = ns->ns_maplist; + old->ns_bucketlen[0] = (u_long *)ns->ns_side[0].ns_bucketlen; + old->ns_bucketlen[1] = (u_long *)ns->ns_side[1].ns_bucketlen; + old->ns_ticks = ns->ns_ticks; + old->ns_orphans = ns->ns_orphans; + old->ns_uncreate[0][0] = ns->ns_side[0].ns_uncreate[0]; + old->ns_uncreate[0][1] = ns->ns_side[0].ns_uncreate[1]; + old->ns_uncreate[1][0] = ns->ns_side[1].ns_uncreate[0]; + old->ns_uncreate[1][1] = ns->ns_side[1].ns_uncreate[1]; +} + + +static void +natstat_current_to_4_1_27(current, old) + void *current; + natstat_4_1_27_t *old; +{ + natstat_t *ns = (natstat_t *)current; + + old->ns_mapped[0] = ns->ns_side[0].ns_translated; + old->ns_mapped[1] = ns->ns_side[1].ns_translated; + old->ns_rules = ns->ns_side[0].ns_inuse + ns->ns_side[1].ns_inuse; + old->ns_added = ns->ns_side[0].ns_added + ns->ns_side[1].ns_added; + old->ns_expire = ns->ns_expire; + old->ns_inuse = ns->ns_side[0].ns_inuse + ns->ns_side[1].ns_inuse; + old->ns_logged = ns->ns_log_ok; + old->ns_logfail = ns->ns_log_fail; + old->ns_memfail = ns->ns_side[0].ns_memfail + ns->ns_side[1].ns_memfail; + old->ns_badnat = ns->ns_side[0].ns_badnat + ns->ns_side[1].ns_badnat; + old->ns_addtrpnt = ns->ns_addtrpnt; + old->ns_table[0] = ns->ns_side[0].ns_table; + old->ns_table[1] = ns->ns_side[1].ns_table; + old->ns_maptable = NULL; + old->ns_list = ns->ns_list; + old->ns_apslist = NULL; + old->ns_wilds = ns->ns_wilds; + old->ns_nattab_sz = ns->ns_nattab_sz; + old->ns_nattab_max = ns->ns_nattab_max; + old->ns_rultab_sz = ns->ns_rultab_sz; + old->ns_rdrtab_sz = ns->ns_rdrtab_sz; + old->ns_trpntab_sz = ns->ns_trpntab_sz; + old->ns_hostmap_sz = 0; + old->ns_instances = ns->ns_instances; + old->ns_maplist = ns->ns_maplist; + old->ns_bucketlen[0] = (u_long *)ns->ns_side[0].ns_bucketlen; + old->ns_bucketlen[1] = (u_long *)ns->ns_side[1].ns_bucketlen; + old->ns_ticks = ns->ns_ticks; + old->ns_orphans = ns->ns_orphans; +} + + +static void +natstat_current_to_4_1_16(current, old) + void *current; + natstat_4_1_16_t *old; +{ + natstat_t *ns = (natstat_t *)current; + + old->ns_mapped[0] = ns->ns_side[0].ns_translated; + old->ns_mapped[1] = ns->ns_side[1].ns_translated; + old->ns_rules = ns->ns_side[0].ns_inuse + ns->ns_side[1].ns_inuse; + old->ns_added = ns->ns_side[0].ns_added + ns->ns_side[1].ns_added; + old->ns_expire = ns->ns_expire; + old->ns_inuse = ns->ns_side[0].ns_inuse + ns->ns_side[1].ns_inuse; + old->ns_logged = ns->ns_log_ok; + old->ns_logfail = ns->ns_log_fail; + old->ns_memfail = ns->ns_side[0].ns_memfail + ns->ns_side[1].ns_memfail; + old->ns_badnat = ns->ns_side[0].ns_badnat + ns->ns_side[1].ns_badnat; + old->ns_addtrpnt = ns->ns_addtrpnt; + old->ns_table[0] = ns->ns_side[0].ns_table; + old->ns_table[1] = ns->ns_side[1].ns_table; + old->ns_maptable = NULL; + old->ns_list = ns->ns_list; + old->ns_apslist = NULL; + old->ns_wilds = ns->ns_wilds; + old->ns_nattab_sz = ns->ns_nattab_sz; + old->ns_nattab_max = ns->ns_nattab_max; + old->ns_rultab_sz = ns->ns_rultab_sz; + old->ns_rdrtab_sz = ns->ns_rdrtab_sz; + old->ns_trpntab_sz = ns->ns_trpntab_sz; + old->ns_hostmap_sz = 0; + old->ns_instances = ns->ns_instances; + old->ns_maplist = ns->ns_maplist; + old->ns_bucketlen[0] = (u_long *)ns->ns_side[0].ns_bucketlen; + old->ns_bucketlen[1] = (u_long *)ns->ns_side[1].ns_bucketlen; + old->ns_ticks = ns->ns_ticks; +} + + +static void +natstat_current_to_4_1_0(current, old) + void *current; + natstat_4_1_0_t *old; +{ + natstat_t *ns = (natstat_t *)current; + + old->ns_mapped[0] = ns->ns_side[0].ns_translated; + old->ns_mapped[1] = ns->ns_side[1].ns_translated; + old->ns_rules = ns->ns_side[0].ns_inuse + ns->ns_side[1].ns_inuse; + old->ns_added = ns->ns_side[0].ns_added + ns->ns_side[1].ns_added; + old->ns_expire = ns->ns_expire; + old->ns_inuse = ns->ns_side[0].ns_inuse + ns->ns_side[1].ns_inuse; + old->ns_logged = ns->ns_log_ok; + old->ns_logfail = ns->ns_log_fail; + old->ns_memfail = ns->ns_side[0].ns_memfail + ns->ns_side[1].ns_memfail; + old->ns_badnat = ns->ns_side[0].ns_badnat + ns->ns_side[1].ns_badnat; + old->ns_addtrpnt = ns->ns_addtrpnt; + old->ns_table[0] = ns->ns_side[0].ns_table; + old->ns_table[1] = ns->ns_side[1].ns_table; + old->ns_maptable = NULL; + old->ns_list = ns->ns_list; + old->ns_apslist = NULL; + old->ns_wilds = ns->ns_wilds; + old->ns_nattab_sz = ns->ns_nattab_sz; + old->ns_nattab_max = ns->ns_nattab_max; + old->ns_rultab_sz = ns->ns_rultab_sz; + old->ns_rdrtab_sz = ns->ns_rdrtab_sz; + old->ns_trpntab_sz = ns->ns_trpntab_sz; + old->ns_hostmap_sz = 0; + old->ns_instances = ns->ns_instances; + old->ns_maplist = ns->ns_maplist; + old->ns_bucketlen[0] = (u_long *)ns->ns_side[0].ns_bucketlen; + old->ns_bucketlen[1] = (u_long *)ns->ns_side[1].ns_bucketlen; +} + + +static void +ipstate_save_current_to_4_1_16(current, old) + void *current; + ipstate_save_4_1_16_t *old; +{ + ipstate_save_t *ips = (ipstate_save_t *)current; + + old->ips_next = ips->ips_next; + ipstate_current_to_4_1_0(&ips->ips_is, &old->ips_is); + frentry_current_to_4_1_16(&ips->ips_fr, &old->ips_fr); +} + + +static void +ipstate_save_current_to_4_1_0(current, old) + void *current; + ipstate_save_4_1_0_t *old; +{ + ipstate_save_t *ips = (ipstate_save_t *)current; + + old->ips_next = ips->ips_next; + ipstate_current_to_4_1_0(&ips->ips_is, &old->ips_is); + frentry_current_to_4_1_0(&ips->ips_fr, &old->ips_fr); +} + + +int +ipf_out_compat(softc, obj, ptr) + ipf_main_softc_t *softc; + ipfobj_t *obj; + void *ptr; +{ + frentry_t *fr; + int error; + + IPFERROR(140042); + error = EINVAL; + + switch (obj->ipfo_type) + { + default : + break; + + case IPFOBJ_FRENTRY : + if (obj->ipfo_rev >= 4013400) { + frentry_4_1_34_t *old; + + KMALLOC(old, frentry_4_1_34_t *); + if (old == NULL) { + IPFERROR(140043); + error = ENOMEM; + break; + } + frentry_current_to_4_1_34(ptr, old); + error = COPYOUT(old, obj->ipfo_ptr, sizeof(*old)); + if (error == 0 && old->fr_dsize > 0) { + char *dst = obj->ipfo_ptr; + + fr = ptr; + dst += sizeof(*old); + error = COPYOUT(fr->fr_data, dst, + old->fr_dsize); + if (error != 0) { + IPFERROR(140044); + } + } + KFREE(old); + obj->ipfo_size = sizeof(*old); + } else if (obj->ipfo_rev >= 4011600) { + frentry_4_1_16_t *old; + + KMALLOC(old, frentry_4_1_16_t *); + if (old == NULL) { + IPFERROR(140045); + error = ENOMEM; + break; + } + frentry_current_to_4_1_16(ptr, old); + error = COPYOUT(old, obj->ipfo_ptr, sizeof(*old)); + if (error != 0) { + IPFERROR(140046); + } + KFREE(old); + obj->ipfo_size = sizeof(*old); + } else { + frentry_4_1_0_t *old; + + KMALLOC(old, frentry_4_1_0_t *); + if (old == NULL) { + IPFERROR(140047); + error = ENOMEM; + break; + } + frentry_current_to_4_1_0(ptr, old); + error = COPYOUT(old, obj->ipfo_ptr, sizeof(*old)); + if (error != 0) { + IPFERROR(140048); + } + KFREE(old); + obj->ipfo_size = sizeof(*old); + } + break; + + case IPFOBJ_IPFSTAT : + if (obj->ipfo_rev >= 4013300) { + friostat_4_1_33_t *old; + + KMALLOC(old, friostat_4_1_33_t *); + if (old == NULL) { + IPFERROR(140049); + error = ENOMEM; + break; + } + friostat_current_to_4_1_33(ptr, old, obj->ipfo_rev); + error = COPYOUT(old, obj->ipfo_ptr, sizeof(*old)); + if (error != 0) { + IPFERROR(140050); + } + KFREE(old); + } else { + friostat_4_1_0_t *old; + + KMALLOC(old, friostat_4_1_0_t *); + if (old == NULL) { + IPFERROR(140051); + error = ENOMEM; + break; + } + friostat_current_to_4_1_0(ptr, old, obj->ipfo_rev); + error = COPYOUT(old, obj->ipfo_ptr, sizeof(*old)); + if (error != 0) { + IPFERROR(140052); + } + KFREE(old); + } + break; + + case IPFOBJ_IPFINFO : /* unused */ + break; + + case IPFOBJ_IPNAT : + if (obj->ipfo_rev >= 4011400) { + ipnat_4_1_14_t *old; + + KMALLOC(old, ipnat_4_1_14_t *); + if (old == NULL) { + IPFERROR(140053); + error = ENOMEM; + break; + } + ipnat_current_to_4_1_14(ptr, old); + error = COPYOUT(old, obj->ipfo_ptr, sizeof(*old)); + if (error != 0) { + IPFERROR(140054); + } + KFREE(old); + } else { + ipnat_4_1_0_t *old; + + KMALLOC(old, ipnat_4_1_0_t *); + if (old == NULL) { + IPFERROR(140055); + error = ENOMEM; + break; + } + ipnat_current_to_4_1_0(ptr, old); + error = COPYOUT(old, obj->ipfo_ptr, sizeof(*old)); + if (error != 0) { + IPFERROR(140056); + } + KFREE(old); + } + break; + + case IPFOBJ_NATSTAT : + if (obj->ipfo_rev >= 4013200) { + natstat_4_1_32_t *old; + + KMALLOC(old, natstat_4_1_32_t *); + if (old == NULL) { + IPFERROR(140057); + error = ENOMEM; + break; + } + natstat_current_to_4_1_32(ptr, old); + error = COPYOUT(old, obj->ipfo_ptr, sizeof(*old)); + if (error != 0) { + IPFERROR(140058); + } + KFREE(old); + } else if (obj->ipfo_rev >= 4012700) { + natstat_4_1_27_t *old; + + KMALLOC(old, natstat_4_1_27_t *); + if (old == NULL) { + IPFERROR(140059); + error = ENOMEM; + break; + } + natstat_current_to_4_1_27(ptr, old); + error = COPYOUT(old, obj->ipfo_ptr, sizeof(*old)); + if (error != 0) { + IPFERROR(140060); + } + KFREE(old); + } else if (obj->ipfo_rev >= 4011600) { + natstat_4_1_16_t *old; + + KMALLOC(old, natstat_4_1_16_t *); + if (old == NULL) { + IPFERROR(140061); + error = ENOMEM; + break; + } + natstat_current_to_4_1_16(ptr, old); + error = COPYOUT(old, obj->ipfo_ptr, sizeof(*old)); + if (error != 0) { + IPFERROR(140062); + } + KFREE(old); + } else { + natstat_4_1_0_t *old; + + KMALLOC(old, natstat_4_1_0_t *); + if (old == NULL) { + IPFERROR(140063); + error = ENOMEM; + break; + } + natstat_current_to_4_1_0(ptr, old); + error = COPYOUT(old, obj->ipfo_ptr, sizeof(*old)); + if (error != 0) { + IPFERROR(140064); + } + KFREE(old); + } + break; + + case IPFOBJ_STATESAVE : + if (obj->ipfo_rev >= 4011600) { + ipstate_save_4_1_16_t *old; + + KMALLOC(old, ipstate_save_4_1_16_t *); + if (old == NULL) { + IPFERROR(140065); + error = ENOMEM; + break; + } + ipstate_save_current_to_4_1_16(ptr, old); + error = COPYOUT(old, obj->ipfo_ptr, sizeof(*old)); + if (error != 0) { + IPFERROR(140066); + } + KFREE(old); + } else { + ipstate_save_4_1_0_t *old; + + KMALLOC(old, ipstate_save_4_1_0_t *); + if (old == NULL) { + IPFERROR(140067); + error = ENOMEM; + break; + } + ipstate_save_current_to_4_1_0(ptr, old); + error = COPYOUT(old, obj->ipfo_ptr, sizeof(*old)); + if (error != 0) { + IPFERROR(140068); + } + KFREE(old); + } + break; + + case IPFOBJ_NATSAVE : + if (obj->ipfo_rev >= 4011600) { + nat_save_4_1_16_t *old16; + + KMALLOC(old16, nat_save_4_1_16_t *); + if (old16 == NULL) { + IPFERROR(140069); + error = ENOMEM; + break; + } + nat_save_current_to_4_1_16(ptr, old16); + error = COPYOUT(&old16, obj->ipfo_ptr, sizeof(*old16)); + if (error != 0) { + IPFERROR(140070); + } + KFREE(old16); + } else if (obj->ipfo_rev >= 4011400) { + nat_save_4_1_14_t *old14; + + KMALLOC(old14, nat_save_4_1_14_t *); + if (old14 == NULL) { + IPFERROR(140071); + error = ENOMEM; + break; + } + nat_save_current_to_4_1_14(ptr, old14); + error = COPYOUT(&old14, obj->ipfo_ptr, sizeof(*old14)); + if (error != 0) { + IPFERROR(140072); + } + KFREE(old14); + } else if (obj->ipfo_rev >= 4010300) { + nat_save_4_1_3_t *old3; + + KMALLOC(old3, nat_save_4_1_3_t *); + if (old3 == NULL) { + IPFERROR(140073); + error = ENOMEM; + break; + } + nat_save_current_to_4_1_3(ptr, old3); + error = COPYOUT(&old3, obj->ipfo_ptr, sizeof(*old3)); + if (error != 0) { + IPFERROR(140074); + } + KFREE(old3); + } + break; + + case IPFOBJ_IPSTATE : + if (obj->ipfo_rev >= 4011600) { + ipstate_4_1_16_t *old; + + KMALLOC(old, ipstate_4_1_16_t *); + if (old == NULL) { + IPFERROR(140075); + error = ENOMEM; + break; + } + ipstate_current_to_4_1_16(ptr, old); + error = COPYOUT(old, obj->ipfo_ptr, sizeof(*old)); + if (error != 0) { + IPFERROR(140076); + } + KFREE(old); + } else { + ipstate_4_1_0_t *old; + + KMALLOC(old, ipstate_4_1_0_t *); + if (old == NULL) { + IPFERROR(140077); + error = ENOMEM; + break; + } + ipstate_current_to_4_1_0(ptr, old); + error = COPYOUT(old, obj->ipfo_ptr, sizeof(*old)); + if (error != 0) { + IPFERROR(140078); + } + KFREE(old); + } + break; + + case IPFOBJ_STATESTAT : + if (obj->ipfo_rev >= 4012100) { + ips_stat_4_1_21_t *old; + + KMALLOC(old, ips_stat_4_1_21_t *); + if (old == NULL) { + IPFERROR(140079); + error = ENOMEM; + break; + } + ips_stat_current_to_4_1_21(ptr, old); + error = COPYOUT(old, obj->ipfo_ptr, sizeof(*old)); + if (error != 0) { + IPFERROR(140080); + } + KFREE(old); + } else { + ips_stat_4_1_0_t *old; + + KMALLOC(old, ips_stat_4_1_0_t *); + if (old == NULL) { + IPFERROR(140081); + error = ENOMEM; + break; + } + ips_stat_current_to_4_1_0(ptr, old); + error = COPYOUT(old, obj->ipfo_ptr, sizeof(*old)); + if (error != 0) { + IPFERROR(140082); + } + KFREE(old); + } + break; + + case IPFOBJ_FRAUTH : + if (obj->ipfo_rev >= 4012900) { + frauth_4_1_29_t *old29; + + KMALLOC(old29, frauth_4_1_29_t *); + if (old29 == NULL) { + IPFERROR(140083); + error = ENOMEM; + break; + } + frauth_current_to_4_1_29(ptr, old29); + error = COPYOUT(old29, obj->ipfo_ptr, sizeof(*old29)); + if (error != 0) { + IPFERROR(140084); + } + KFREE(old29); + } else if (obj->ipfo_rev >= 4012400) { + frauth_4_1_24_t *old24; + + KMALLOC(old24, frauth_4_1_24_t *); + if (old24 == NULL) { + IPFERROR(140085); + error = ENOMEM; + break; + } + frauth_current_to_4_1_24(ptr, old24); + error = COPYOUT(old24, obj->ipfo_ptr, sizeof(*old24)); + if (error != 0) { + IPFERROR(140086); + } + KFREE(old24); + } else if (obj->ipfo_rev >= 4012300) { + frauth_4_1_23_t *old23; + + KMALLOC(old23, frauth_4_1_23_t *); + if (old23 == NULL) { + IPFERROR(140087); + error = ENOMEM; + break; + } + frauth_current_to_4_1_23(ptr, old23); + error = COPYOUT(old23, obj->ipfo_ptr, sizeof(*old23)); + if (error != 0) { + IPFERROR(140088); + } + KFREE(old23); + } else if (obj->ipfo_rev >= 4011100) { + frauth_4_1_11_t *old11; + + KMALLOC(old11, frauth_4_1_11_t *); + if (old11 == NULL) { + IPFERROR(140089); + error = ENOMEM; + break; + } + frauth_current_to_4_1_11(ptr, old11); + error = COPYOUT(old11, obj->ipfo_ptr, sizeof(*old11)); + if (error != 0) { + IPFERROR(140090); + } + KFREE(old11); + } + break; + + case IPFOBJ_NAT : + if (obj->ipfo_rev >= 4012500) { + nat_4_1_25_t *old; + + KMALLOC(old, nat_4_1_25_t *); + if (old == NULL) { + IPFERROR(140091); + error = ENOMEM; + break; + } + nat_current_to_4_1_25(ptr, old); + error = COPYOUT(old, obj->ipfo_ptr, sizeof(*old)); + if (error != 0) { + IPFERROR(140092); + } + KFREE(old); + } else if (obj->ipfo_rev >= 4011400) { + nat_4_1_14_t *old; + + KMALLOC(old, nat_4_1_14_t *); + if (old == NULL) { + IPFERROR(140093); + error = ENOMEM; + break; + } + nat_current_to_4_1_14(ptr, old); + error = COPYOUT(old, obj->ipfo_ptr, sizeof(*old)); + if (error != 0) { + IPFERROR(140094); + } + KFREE(old); + } else if (obj->ipfo_rev >= 4010300) { + nat_4_1_3_t *old; + + KMALLOC(old, nat_4_1_3_t *); + if (old == NULL) { + IPFERROR(140095); + error = ENOMEM; + break; + } + nat_current_to_4_1_3(ptr, old); + error = COPYOUT(old, obj->ipfo_ptr, sizeof(*old)); + if (error != 0) { + IPFERROR(140096); + } + KFREE(old); + } + break; + + case IPFOBJ_FRIPF : + if (obj->ipfo_rev < 5000000) { + fripf4_t *old; + + KMALLOC(old, fripf4_t *); + if (old == NULL) { + IPFERROR(140097); + error = ENOMEM; + break; + } + ipf_v5fripftov4(ptr, old); + error = COPYOUT(old, obj->ipfo_ptr, sizeof(*old)); + if (error != 0) { + IPFERROR(140098); + } + KFREE(old); + } + break; + } + return error; +} + + +static void +friostat_current_to_4_1_33(current, old, rev) + void *current; + friostat_4_1_33_t *old; + int rev; +{ + friostat_t *fiop = (friostat_t *)current; + + bcopy(&fiop->f_st[0].fr_pass, &old->of_st[0], sizeof(old->of_st[0])); + bcopy(&fiop->f_st[1].fr_pass, &old->of_st[1], sizeof(old->of_st[1])); + + old->f_ipf[0][0] = fiop->f_ipf[0][0]; + old->f_ipf[0][1] = fiop->f_ipf[0][1]; + old->f_ipf[1][0] = fiop->f_ipf[1][0]; + old->f_ipf[1][1] = fiop->f_ipf[1][1]; + old->f_acct[0][0] = fiop->f_acct[0][0]; + old->f_acct[0][1] = fiop->f_acct[0][1]; + old->f_acct[1][0] = fiop->f_acct[1][0]; + old->f_acct[1][1] = fiop->f_acct[1][1]; + old->f_ipf6[0][0] = NULL; + old->f_ipf6[0][1] = NULL; + old->f_ipf6[1][0] = NULL; + old->f_ipf6[1][1] = NULL; + old->f_acct6[0][0] = NULL; + old->f_acct6[0][1] = NULL; + old->f_acct6[1][0] = NULL; + old->f_acct6[1][1] = NULL; + old->f_auth = fiop->f_auth; + bcopy(&fiop->f_groups, &old->f_groups, sizeof(old->f_groups)); + bcopy(&fiop->f_froute, &old->f_froute, sizeof(old->f_froute)); + old->f_ticks = fiop->f_ticks; + bcopy(&fiop->f_locks, &old->f_locks, sizeof(old->f_locks)); + old->f_kmutex_sz = 0; + old->f_krwlock_sz = 0; + old->f_defpass = fiop->f_defpass; + old->f_active = fiop->f_active; + old->f_running = fiop->f_running; + old->f_logging = fiop->f_logging; + old->f_features = fiop->f_features; + sprintf(old->f_version, "IP Filter: v%d.%d.%d", + (rev / 1000000) % 100, + (rev / 10000) % 100, + (rev / 100) % 100); +} + + +static void +friostat_current_to_4_1_0(current, old, rev) + void *current; + friostat_4_1_0_t *old; + int rev; +{ + friostat_t *fiop = (friostat_t *)current; + + bcopy(&fiop->f_st[0].fr_pass, &old->of_st[0], sizeof(old->of_st[0])); + bcopy(&fiop->f_st[1].fr_pass, &old->of_st[1], sizeof(old->of_st[1])); + + old->f_ipf[0][0] = fiop->f_ipf[0][0]; + old->f_ipf[0][1] = fiop->f_ipf[0][1]; + old->f_ipf[1][0] = fiop->f_ipf[1][0]; + old->f_ipf[1][1] = fiop->f_ipf[1][1]; + old->f_acct[0][0] = fiop->f_acct[0][0]; + old->f_acct[0][1] = fiop->f_acct[0][1]; + old->f_acct[1][0] = fiop->f_acct[1][0]; + old->f_acct[1][1] = fiop->f_acct[1][1]; + old->f_ipf6[0][0] = NULL; + old->f_ipf6[0][1] = NULL; + old->f_ipf6[1][0] = NULL; + old->f_ipf6[1][1] = NULL; + old->f_acct6[0][0] = NULL; + old->f_acct6[0][1] = NULL; + old->f_acct6[1][0] = NULL; + old->f_acct6[1][1] = NULL; + old->f_auth = fiop->f_auth; + bcopy(&fiop->f_groups, &old->f_groups, sizeof(old->f_groups)); + bcopy(&fiop->f_froute, &old->f_froute, sizeof(old->f_froute)); + old->f_ticks = fiop->f_ticks; + old->f_ipf[0][0] = fiop->f_ipf[0][0]; + old->f_ipf[0][1] = fiop->f_ipf[0][1]; + old->f_ipf[1][0] = fiop->f_ipf[1][0]; + old->f_ipf[1][1] = fiop->f_ipf[1][1]; + old->f_acct[0][0] = fiop->f_acct[0][0]; + old->f_acct[0][1] = fiop->f_acct[0][1]; + old->f_acct[1][0] = fiop->f_acct[1][0]; + old->f_acct[1][1] = fiop->f_acct[1][1]; + old->f_ipf6[0][0] = NULL; + old->f_ipf6[0][1] = NULL; + old->f_ipf6[1][0] = NULL; + old->f_ipf6[1][1] = NULL; + old->f_acct6[0][0] = NULL; + old->f_acct6[0][1] = NULL; + old->f_acct6[1][0] = NULL; + old->f_acct6[1][1] = NULL; + old->f_auth = fiop->f_auth; + bcopy(&fiop->f_groups, &old->f_groups, sizeof(old->f_groups)); + bcopy(&fiop->f_froute, &old->f_froute, sizeof(old->f_froute)); + old->f_ticks = fiop->f_ticks; + bcopy(&fiop->f_locks, &old->f_locks, sizeof(old->f_locks)); + old->f_kmutex_sz = 0; + old->f_krwlock_sz = 0; + old->f_defpass = fiop->f_defpass; + old->f_active = fiop->f_active; + old->f_running = fiop->f_running; + old->f_logging = fiop->f_logging; + old->f_features = fiop->f_features; + sprintf(old->f_version, "IP Filter: v%d.%d.%d", + (rev / 1000000) % 100, + (rev / 10000) % 100, + (rev / 100) % 100); +} + + +/* + * nflags is v5 flags, returns v4 flags. + */ +static int +fr_frflags5to4(nflags) + u_32_t nflags; +{ + u_32_t oflags = 0; + + switch (nflags & FR_CMDMASK) { + case FR_CALL : + oflags = 0x0; + break; + case FR_BLOCK : + oflags = 0x1; + break; + case FR_PASS : + oflags = 0x2; + break; + case FR_AUTH : + oflags = 0x3; + break; + case FR_PREAUTH : + oflags = 0x4; + break; + case FR_ACCOUNT : + oflags = 0x5; + break; + case FR_SKIP : + oflags = 0x6; + break; + default : + break; + } + + if (nflags & FR_LOG) + oflags |= 0x00010; + if (nflags & FR_CALLNOW) + oflags |= 0x00020; + if (nflags & FR_NOTSRCIP) + oflags |= 0x00080; + if (nflags & FR_NOTDSTIP) + oflags |= 0x00040; + if (nflags & FR_QUICK) + oflags |= 0x00100; + if (nflags & FR_KEEPFRAG) + oflags |= 0x00200; + if (nflags & FR_KEEPSTATE) + oflags |= 0x00400; + if (nflags & FR_FASTROUTE) + oflags |= 0x00800; + if (nflags & FR_RETRST) + oflags |= 0x01000; + if (nflags & FR_RETICMP) + oflags |= 0x02000; + if (nflags & FR_FAKEICMP) + oflags |= 0x03000; + if (nflags & FR_OUTQUE) + oflags |= 0x04000; + if (nflags & FR_INQUE) + oflags |= 0x08000; + if (nflags & FR_LOGBODY) + oflags |= 0x10000; + if (nflags & FR_LOGFIRST) + oflags |= 0x20000; + if (nflags & FR_LOGORBLOCK) + oflags |= 0x40000; + if (nflags & FR_FRSTRICT) + oflags |= 0x100000; + if (nflags & FR_STSTRICT) + oflags |= 0x200000; + if (nflags & FR_NEWISN) + oflags |= 0x400000; + if (nflags & FR_NOICMPERR) + oflags |= 0x800000; + if (nflags & FR_STATESYNC) + oflags |= 0x1000000; + if (nflags & FR_NOMATCH) + oflags |= 0x8000000; + if (nflags & FR_COPIED) + oflags |= 0x40000000; + if (nflags & FR_INACTIVE) + oflags |= 0x80000000; + + return oflags; +} + + +static void +frentry_current_to_4_1_34(current, old) + void *current; + frentry_4_1_34_t *old; +{ + frentry_t *fr = (frentry_t *)current; + + old->fr_lock = fr->fr_lock; + old->fr_next = fr->fr_next; + old->fr_grp = (void *)fr->fr_grp; + old->fr_isc = fr->fr_isc; + old->fr_ifas[0] = fr->fr_ifas[0]; + old->fr_ifas[1] = fr->fr_ifas[1]; + old->fr_ifas[2] = fr->fr_ifas[2]; + old->fr_ifas[3] = fr->fr_ifas[3]; + old->fr_ptr = fr->fr_ptr; + old->fr_comment = NULL; + old->fr_ref = fr->fr_ref; + old->fr_statecnt = fr->fr_statecnt; + old->fr_hits = fr->fr_hits; + old->fr_bytes = fr->fr_bytes; + old->fr_lastpkt.tv_sec = fr->fr_lastpkt.tv_sec; + old->fr_lastpkt.tv_usec = fr->fr_lastpkt.tv_usec; + old->fr_curpps = fr->fr_curpps; + old->fr_dun.fru_data = fr->fr_dun.fru_data; + old->fr_func = fr->fr_func; + old->fr_dsize = fr->fr_dsize; + old->fr_pps = fr->fr_pps; + old->fr_statemax = fr->fr_statemax; + old->fr_flineno = fr->fr_flineno; + old->fr_type = fr->fr_type; + old->fr_flags = fr_frflags5to4(fr->fr_flags); + old->fr_logtag = fr->fr_logtag; + old->fr_collect = fr->fr_collect; + old->fr_arg = fr->fr_arg; + old->fr_loglevel = fr->fr_loglevel; + old->fr_age[0] = fr->fr_age[0]; + old->fr_age[1] = fr->fr_age[1]; + if (fr->fr_family == AF_INET) + old->fr_v = 4; + if (fr->fr_family == AF_INET6) + old->fr_v = 6; + old->fr_icode = fr->fr_icode; + old->fr_cksum = fr->fr_cksum; + old->fr_tifs[0].ofd_ip6 = fr->fr_tifs[0].fd_ip6; + old->fr_tifs[1].ofd_ip6 = fr->fr_tifs[0].fd_ip6; + old->fr_dif.ofd_ip6 = fr->fr_dif.fd_ip6; + if (fr->fr_ifnames[0] >= 0) { + strncpy(old->fr_ifnames[0], fr->fr_names + fr->fr_ifnames[0], + LIFNAMSIZ); + old->fr_ifnames[0][LIFNAMSIZ - 1] = '\0'; + } + if (fr->fr_ifnames[1] >= 0) { + strncpy(old->fr_ifnames[1], fr->fr_names + fr->fr_ifnames[1], + LIFNAMSIZ); + old->fr_ifnames[1][LIFNAMSIZ - 1] = '\0'; + } + if (fr->fr_ifnames[2] >= 0) { + strncpy(old->fr_ifnames[2], fr->fr_names + fr->fr_ifnames[2], + LIFNAMSIZ); + old->fr_ifnames[2][LIFNAMSIZ - 1] = '\0'; + } + if (fr->fr_ifnames[3] >= 0) { + strncpy(old->fr_ifnames[3], fr->fr_names + fr->fr_ifnames[3], + LIFNAMSIZ); + old->fr_ifnames[3][LIFNAMSIZ - 1] = '\0'; + } + if (fr->fr_tifs[0].fd_name >= 0) { + strncpy(old->fr_tifs[0].fd_ifname, + fr->fr_names + fr->fr_tifs[0].fd_name, LIFNAMSIZ); + old->fr_tifs[0].fd_ifname[LIFNAMSIZ - 1] = '\0'; + } + if (fr->fr_tifs[1].fd_name >= 0) { + strncpy(old->fr_tifs[1].fd_ifname, + fr->fr_names + fr->fr_tifs[1].fd_name, LIFNAMSIZ); + old->fr_tifs[1].fd_ifname[LIFNAMSIZ - 1] = '\0'; + } + if (fr->fr_dif.fd_name >= 0) { + strncpy(old->fr_dif.fd_ifname, + fr->fr_names + fr->fr_dif.fd_name, LIFNAMSIZ); + old->fr_dif.fd_ifname[LIFNAMSIZ - 1] = '\0'; + } + if (fr->fr_group >= 0) { + strncpy(old->fr_group, fr->fr_names + fr->fr_group, + FR_GROUPLEN); + old->fr_group[FR_GROUPLEN - 1] = '\0'; + } + if (fr->fr_grhead >= 0) { + strncpy(old->fr_grhead, fr->fr_names + fr->fr_grhead, + FR_GROUPLEN); + old->fr_grhead[FR_GROUPLEN - 1] = '\0'; + } +} + + +static void +frentry_current_to_4_1_16(current, old) + void *current; + frentry_4_1_16_t *old; +{ + frentry_t *fr = (frentry_t *)current; + + old->fr_lock = fr->fr_lock; + old->fr_next = fr->fr_next; + old->fr_grp = (void *)fr->fr_grp; + old->fr_isc = fr->fr_isc; + old->fr_ifas[0] = fr->fr_ifas[0]; + old->fr_ifas[1] = fr->fr_ifas[1]; + old->fr_ifas[2] = fr->fr_ifas[2]; + old->fr_ifas[3] = fr->fr_ifas[3]; + old->fr_ptr = fr->fr_ptr; + old->fr_comment = NULL; + old->fr_ref = fr->fr_ref; + old->fr_statecnt = fr->fr_statecnt; + old->fr_hits = fr->fr_hits; + old->fr_bytes = fr->fr_bytes; + old->fr_lastpkt.tv_sec = fr->fr_lastpkt.tv_sec; + old->fr_lastpkt.tv_usec = fr->fr_lastpkt.tv_usec; + old->fr_curpps = fr->fr_curpps; + old->fr_dun.fru_data = fr->fr_dun.fru_data; + old->fr_func = fr->fr_func; + old->fr_dsize = fr->fr_dsize; + old->fr_pps = fr->fr_pps; + old->fr_statemax = fr->fr_statemax; + old->fr_flineno = fr->fr_flineno; + old->fr_type = fr->fr_type; + old->fr_flags = fr_frflags5to4(fr->fr_flags); + old->fr_logtag = fr->fr_logtag; + old->fr_collect = fr->fr_collect; + old->fr_arg = fr->fr_arg; + old->fr_loglevel = fr->fr_loglevel; + old->fr_age[0] = fr->fr_age[0]; + old->fr_age[1] = fr->fr_age[1]; + if (old->fr_v == 4) + fr->fr_family = AF_INET; + if (old->fr_v == 6) + fr->fr_family = AF_INET6; + old->fr_icode = fr->fr_icode; + old->fr_cksum = fr->fr_cksum; + old->fr_tifs[0].ofd_ip6 = fr->fr_tifs[0].fd_ip6; + old->fr_tifs[1].ofd_ip6 = fr->fr_tifs[0].fd_ip6; + old->fr_dif.ofd_ip6 = fr->fr_dif.fd_ip6; + if (fr->fr_ifnames[0] >= 0) { + strncpy(old->fr_ifnames[0], fr->fr_names + fr->fr_ifnames[0], + LIFNAMSIZ); + old->fr_ifnames[0][LIFNAMSIZ - 1] = '\0'; + } + if (fr->fr_ifnames[1] >= 0) { + strncpy(old->fr_ifnames[1], fr->fr_names + fr->fr_ifnames[1], + LIFNAMSIZ); + old->fr_ifnames[1][LIFNAMSIZ - 1] = '\0'; + } + if (fr->fr_ifnames[2] >= 0) { + strncpy(old->fr_ifnames[2], fr->fr_names + fr->fr_ifnames[2], + LIFNAMSIZ); + old->fr_ifnames[2][LIFNAMSIZ - 1] = '\0'; + } + if (fr->fr_ifnames[3] >= 0) { + strncpy(old->fr_ifnames[3], fr->fr_names + fr->fr_ifnames[3], + LIFNAMSIZ); + old->fr_ifnames[3][LIFNAMSIZ - 1] = '\0'; + } + if (fr->fr_tifs[0].fd_name >= 0) { + strncpy(old->fr_tifs[0].fd_ifname, + fr->fr_names + fr->fr_tifs[0].fd_name, LIFNAMSIZ); + old->fr_tifs[0].fd_ifname[LIFNAMSIZ - 1] = '\0'; + } + if (fr->fr_tifs[1].fd_name >= 0) { + strncpy(old->fr_tifs[1].fd_ifname, + fr->fr_names + fr->fr_tifs[1].fd_name, LIFNAMSIZ); + old->fr_tifs[1].fd_ifname[LIFNAMSIZ - 1] = '\0'; + } + if (fr->fr_dif.fd_name >= 0) { + strncpy(old->fr_dif.fd_ifname, + fr->fr_names + fr->fr_dif.fd_name, LIFNAMSIZ); + old->fr_dif.fd_ifname[LIFNAMSIZ - 1] = '\0'; + } + if (fr->fr_group >= 0) { + strncpy(old->fr_group, fr->fr_names + fr->fr_group, + FR_GROUPLEN); + old->fr_group[FR_GROUPLEN - 1] = '\0'; + } + if (fr->fr_grhead >= 0) { + strncpy(old->fr_grhead, fr->fr_names + fr->fr_grhead, + FR_GROUPLEN); + old->fr_grhead[FR_GROUPLEN - 1] = '\0'; + } +} + + +static void +frentry_current_to_4_1_0(current, old) + void *current; + frentry_4_1_0_t *old; +{ + frentry_t *fr = (frentry_t *)current; + + old->fr_lock = fr->fr_lock; + old->fr_next = fr->fr_next; + old->fr_grp = (void *)fr->fr_grp; + old->fr_isc = fr->fr_isc; + old->fr_ifas[0] = fr->fr_ifas[0]; + old->fr_ifas[1] = fr->fr_ifas[1]; + old->fr_ifas[2] = fr->fr_ifas[2]; + old->fr_ifas[3] = fr->fr_ifas[3]; + old->fr_ptr = fr->fr_ptr; + old->fr_comment = NULL; + old->fr_ref = fr->fr_ref; + old->fr_statecnt = fr->fr_statecnt; + old->fr_hits = fr->fr_hits; + old->fr_bytes = fr->fr_bytes; + old->fr_lastpkt.tv_sec = fr->fr_lastpkt.tv_sec; + old->fr_lastpkt.tv_usec = fr->fr_lastpkt.tv_usec; + old->fr_curpps = fr->fr_curpps; + old->fr_dun.fru_data = fr->fr_dun.fru_data; + old->fr_func = fr->fr_func; + old->fr_dsize = fr->fr_dsize; + old->fr_pps = fr->fr_pps; + old->fr_statemax = fr->fr_statemax; + old->fr_flineno = fr->fr_flineno; + old->fr_type = fr->fr_type; + old->fr_flags = fr_frflags5to4(fr->fr_flags); + old->fr_logtag = fr->fr_logtag; + old->fr_collect = fr->fr_collect; + old->fr_arg = fr->fr_arg; + old->fr_loglevel = fr->fr_loglevel; + old->fr_age[0] = fr->fr_age[0]; + old->fr_age[1] = fr->fr_age[1]; + if (old->fr_v == 4) + fr->fr_family = AF_INET; + if (old->fr_v == 6) + fr->fr_family = AF_INET6; + old->fr_icode = fr->fr_icode; + old->fr_cksum = fr->fr_cksum; + old->fr_tifs[0].ofd_ip6 = fr->fr_tifs[0].fd_ip6; + old->fr_tifs[1].ofd_ip6 = fr->fr_tifs[0].fd_ip6; + old->fr_dif.ofd_ip6 = fr->fr_dif.fd_ip6; + if (fr->fr_ifnames[0] >= 0) { + strncpy(old->fr_ifnames[0], fr->fr_names + fr->fr_ifnames[0], + LIFNAMSIZ); + old->fr_ifnames[0][LIFNAMSIZ - 1] = '\0'; + } + if (fr->fr_ifnames[1] >= 0) { + strncpy(old->fr_ifnames[1], fr->fr_names + fr->fr_ifnames[1], + LIFNAMSIZ); + old->fr_ifnames[1][LIFNAMSIZ - 1] = '\0'; + } + if (fr->fr_ifnames[2] >= 0) { + strncpy(old->fr_ifnames[2], fr->fr_names + fr->fr_ifnames[2], + LIFNAMSIZ); + old->fr_ifnames[2][LIFNAMSIZ - 1] = '\0'; + } + if (fr->fr_ifnames[3] >= 0) { + strncpy(old->fr_ifnames[3], fr->fr_names + fr->fr_ifnames[3], + LIFNAMSIZ); + old->fr_ifnames[3][LIFNAMSIZ - 1] = '\0'; + } + if (fr->fr_tifs[0].fd_name >= 0) { + strncpy(old->fr_tifs[0].fd_ifname, + fr->fr_names + fr->fr_tifs[0].fd_name, LIFNAMSIZ); + old->fr_tifs[0].fd_ifname[LIFNAMSIZ - 1] = '\0'; + } + if (fr->fr_tifs[1].fd_name >= 0) { + strncpy(old->fr_tifs[1].fd_ifname, + fr->fr_names + fr->fr_tifs[1].fd_name, LIFNAMSIZ); + old->fr_tifs[1].fd_ifname[LIFNAMSIZ - 1] = '\0'; + } + if (fr->fr_dif.fd_name >= 0) { + strncpy(old->fr_dif.fd_ifname, + fr->fr_names + fr->fr_dif.fd_name, LIFNAMSIZ); + old->fr_dif.fd_ifname[LIFNAMSIZ - 1] = '\0'; + } + if (fr->fr_group >= 0) { + strncpy(old->fr_group, fr->fr_names + fr->fr_group, + FR_GROUPLEN); + old->fr_group[FR_GROUPLEN - 1] = '\0'; + } + if (fr->fr_grhead >= 0) { + strncpy(old->fr_grhead, fr->fr_names + fr->fr_grhead, + FR_GROUPLEN); + old->fr_grhead[FR_GROUPLEN - 1] = '\0'; + } +} + + +static void +fr_info_current_to_4_1_24(current, old) + void *current; + fr_info_4_1_24_t *old; +{ + fr_info_t *fin = (fr_info_t *)current; + + old->fin_ifp = fin->fin_ifp; + ipf_v5iptov4(&fin->fin_fi, &old->fin_fi); + bcopy(&fin->fin_dat, &old->fin_dat, sizeof(fin->fin_dat)); + old->fin_out = fin->fin_out; + old->fin_rev = fin->fin_rev; + old->fin_hlen = fin->fin_hlen; + old->ofin_tcpf = fin->fin_tcpf; + old->fin_icode = fin->fin_icode; + old->fin_rule = fin->fin_rule; + bcopy(fin->fin_group, old->fin_group, sizeof(fin->fin_group)); + old->fin_fr = fin->fin_fr; + old->fin_dp = fin->fin_dp; + old->fin_dlen = fin->fin_dlen; + old->fin_plen = fin->fin_plen; + old->fin_ipoff = fin->fin_ipoff; + old->fin_id = fin->fin_id; + old->fin_off = fin->fin_off; + old->fin_depth = fin->fin_depth; + old->fin_error = fin->fin_error; + old->fin_cksum = fin->fin_cksum; + old->fin_state = NULL; + old->fin_nat = NULL; + old->fin_nattag = fin->fin_nattag; + old->fin_exthdr = NULL; + old->ofin_ip = fin->fin_ip; + old->fin_mp = fin->fin_mp; + old->fin_m = fin->fin_m; +#ifdef MENTAT + old->fin_qfm = fin->fin_qfm; + old->fin_qpi = fin->fin_qpi; + old->fin_ifname[0] = '\0'; +#endif +#ifdef __sgi + old->fin_hbuf = fin->fin_hbuf; +#endif +} + + +static void +fr_info_current_to_4_1_23(current, old) + void *current; + fr_info_4_1_23_t *old; +{ + fr_info_t *fin = (fr_info_t *)current; + + old->fin_ifp = fin->fin_ifp; + ipf_v5iptov4(&fin->fin_fi, &old->fin_fi); + bcopy(&fin->fin_dat, &old->fin_dat, sizeof(fin->fin_dat)); + old->fin_out = fin->fin_out; + old->fin_rev = fin->fin_rev; + old->fin_hlen = fin->fin_hlen; + old->ofin_tcpf = fin->fin_tcpf; + old->fin_icode = fin->fin_icode; + old->fin_rule = fin->fin_rule; + bcopy(fin->fin_group, old->fin_group, sizeof(fin->fin_group)); + old->fin_fr = fin->fin_fr; + old->fin_dp = fin->fin_dp; + old->fin_dlen = fin->fin_dlen; + old->fin_plen = fin->fin_plen; + old->fin_ipoff = fin->fin_ipoff; + old->fin_id = fin->fin_id; + old->fin_off = fin->fin_off; + old->fin_depth = fin->fin_depth; + old->fin_error = fin->fin_error; + old->fin_state = NULL; + old->fin_nat = NULL; + old->fin_nattag = fin->fin_nattag; + old->ofin_ip = fin->fin_ip; + old->fin_mp = fin->fin_mp; + old->fin_m = fin->fin_m; +#ifdef MENTAT + old->fin_qfm = fin->fin_qfm; + old->fin_qpi = fin->fin_qpi; + old->fin_ifname[0] = '\0'; +#endif +#ifdef __sgi + old->fin_hbuf = fin->fin_hbuf; +#endif +} + + +static void +fr_info_current_to_4_1_11(current, old) + void *current; + fr_info_4_1_11_t *old; +{ + fr_info_t *fin = (fr_info_t *)current; + + old->fin_ifp = fin->fin_ifp; + ipf_v5iptov4(&fin->fin_fi, &old->fin_fi); + bcopy(&fin->fin_dat, &old->fin_dat, sizeof(fin->fin_dat)); + old->fin_out = fin->fin_out; + old->fin_rev = fin->fin_rev; + old->fin_hlen = fin->fin_hlen; + old->ofin_tcpf = fin->fin_tcpf; + old->fin_icode = fin->fin_icode; + old->fin_rule = fin->fin_rule; + bcopy(fin->fin_group, old->fin_group, sizeof(fin->fin_group)); + old->fin_fr = fin->fin_fr; + old->fin_dp = fin->fin_dp; + old->fin_dlen = fin->fin_dlen; + old->fin_plen = fin->fin_plen; + old->fin_ipoff = fin->fin_ipoff; + old->fin_id = fin->fin_id; + old->fin_off = fin->fin_off; + old->fin_depth = fin->fin_depth; + old->fin_error = fin->fin_error; + old->fin_state = NULL; + old->fin_nat = NULL; + old->fin_nattag = fin->fin_nattag; + old->ofin_ip = fin->fin_ip; + old->fin_mp = fin->fin_mp; + old->fin_m = fin->fin_m; +#ifdef MENTAT + old->fin_qfm = fin->fin_qfm; + old->fin_qpi = fin->fin_qpi; + old->fin_ifname[0] = '\0'; +#endif +#ifdef __sgi + old->fin_hbuf = fin->fin_hbuf; +#endif +} + + +static void +frauth_current_to_4_1_29(current, old) + void *current; + frauth_4_1_29_t *old; +{ + frauth_t *fra = (frauth_t *)current; + + old->fra_age = fra->fra_age; + old->fra_len = fra->fra_len; + old->fra_index = fra->fra_index; + old->fra_pass = fra->fra_pass; + fr_info_current_to_4_1_24(&fra->fra_info, &old->fra_info); + old->fra_buf = fra->fra_buf; + old->fra_flx = fra->fra_flx; +#ifdef MENTAT + old->fra_q = fra->fra_q; + old->fra_m = fra->fra_m; +#endif +} + + +static void +frauth_current_to_4_1_24(current, old) + void *current; + frauth_4_1_24_t *old; +{ + frauth_t *fra = (frauth_t *)current; + + old->fra_age = fra->fra_age; + old->fra_len = fra->fra_len; + old->fra_index = fra->fra_index; + old->fra_pass = fra->fra_pass; + fr_info_current_to_4_1_24(&fra->fra_info, &old->fra_info); + old->fra_buf = fra->fra_buf; +#ifdef MENTAT + old->fra_q = fra->fra_q; + old->fra_m = fra->fra_m; +#endif +} + + +static void +frauth_current_to_4_1_23(current, old) + void *current; + frauth_4_1_23_t *old; +{ + frauth_t *fra = (frauth_t *)current; + + old->fra_age = fra->fra_age; + old->fra_len = fra->fra_len; + old->fra_index = fra->fra_index; + old->fra_pass = fra->fra_pass; + fr_info_current_to_4_1_23(&fra->fra_info, &old->fra_info); + old->fra_buf = fra->fra_buf; +#ifdef MENTAT + old->fra_q = fra->fra_q; + old->fra_m = fra->fra_m; +#endif +} + + +static void +frauth_current_to_4_1_11(current, old) + void *current; + frauth_4_1_11_t *old; +{ + frauth_t *fra = (frauth_t *)current; + + old->fra_age = fra->fra_age; + old->fra_len = fra->fra_len; + old->fra_index = fra->fra_index; + old->fra_pass = fra->fra_pass; + fr_info_current_to_4_1_11(&fra->fra_info, &old->fra_info); + old->fra_buf = fra->fra_buf; +#ifdef MENTAT + old->fra_q = fra->fra_q; + old->fra_m = fra->fra_m; +#endif +} + + +static void +ipnat_current_to_4_1_14(current, old) + void *current; + ipnat_4_1_14_t *old; +{ + ipnat_t *np = (ipnat_t *)current; + + old->in_next = np->in_next; + old->in_rnext = np->in_rnext; + old->in_prnext = np->in_prnext; + old->in_mnext = np->in_mnext; + old->in_pmnext = np->in_pmnext; + old->in_tqehead[0] = np->in_tqehead[0]; + old->in_tqehead[1] = np->in_tqehead[1]; + old->in_ifps[0] = np->in_ifps[0]; + old->in_ifps[1] = np->in_ifps[1]; + old->in_apr = np->in_apr; + old->in_comment = np->in_comment; + old->in_space = np->in_space; + old->in_hits = np->in_hits; + old->in_use = np->in_use; + old->in_hv = np->in_hv[0]; + old->in_flineno = np->in_flineno; + if (old->in_redir == NAT_REDIRECT) + old->in_pnext = np->in_dpnext; + else + old->in_pnext = np->in_spnext; + old->in_v = np->in_v[0]; + old->in_flags = np->in_flags; + old->in_mssclamp = np->in_mssclamp; + old->in_age[0] = np->in_age[0]; + old->in_age[1] = np->in_age[1]; + old->in_redir = np->in_redir; + old->in_p = np->in_pr[0]; + if (np->in_redir == NAT_REDIRECT) { + old->in_next6 = np->in_ndst.na_nextaddr; + old->in_in[0] = np->in_ndst.na_addr[0]; + old->in_in[1] = np->in_ndst.na_addr[1]; + old->in_out[0] = np->in_odst.na_addr[0]; + old->in_out[1] = np->in_odst.na_addr[1]; + old->in_src[0] = np->in_osrc.na_addr[0]; + old->in_src[1] = np->in_osrc.na_addr[1]; + } else { + old->in_next6 = np->in_nsrc.na_nextaddr; + old->in_out[0] = np->in_nsrc.na_addr[0]; + old->in_out[1] = np->in_nsrc.na_addr[1]; + old->in_in[0] = np->in_osrc.na_addr[0]; + old->in_in[1] = np->in_osrc.na_addr[1]; + old->in_src[0] = np->in_odst.na_addr[0]; + old->in_src[1] = np->in_odst.na_addr[1]; + } + ipfv5tuctov4(&np->in_tuc, &old->in_tuc); + if (np->in_redir == NAT_REDIRECT) { + old->in_port[0] = np->in_dpmin; + old->in_port[1] = np->in_dpmax; + } else { + old->in_port[0] = np->in_spmin; + old->in_port[1] = np->in_spmax; + } + old->in_ppip = np->in_ppip; + old->in_ippip = np->in_ippip; + bcopy(&np->in_tag, &old->in_tag, sizeof(np->in_tag)); + + if (np->in_ifnames[0] >= 0) { + strncpy(old->in_ifnames[0], np->in_names + np->in_ifnames[0], + LIFNAMSIZ); + old->in_ifnames[0][LIFNAMSIZ - 1] = '\0'; + } + if (np->in_ifnames[1] >= 0) { + strncpy(old->in_ifnames[1], np->in_names + np->in_ifnames[1], + LIFNAMSIZ); + old->in_ifnames[1][LIFNAMSIZ - 1] = '\0'; + } + if (np->in_plabel >= 0) { + strncpy(old->in_plabel, np->in_names + np->in_plabel, + APR_LABELLEN); + old->in_plabel[APR_LABELLEN - 1] = '\0'; + } +} + + +static void +ipnat_current_to_4_1_0(current, old) + void *current; + ipnat_4_1_0_t *old; +{ + ipnat_t *np = (ipnat_t *)current; + + old->in_next = np->in_next; + old->in_rnext = np->in_rnext; + old->in_prnext = np->in_prnext; + old->in_mnext = np->in_mnext; + old->in_pmnext = np->in_pmnext; + old->in_tqehead[0] = np->in_tqehead[0]; + old->in_tqehead[1] = np->in_tqehead[1]; + old->in_ifps[0] = np->in_ifps[0]; + old->in_ifps[1] = np->in_ifps[1]; + old->in_apr = np->in_apr; + old->in_comment = np->in_comment; + old->in_space = np->in_space; + old->in_hits = np->in_hits; + old->in_use = np->in_use; + old->in_hv = np->in_hv[0]; + old->in_flineno = np->in_flineno; + if (old->in_redir == NAT_REDIRECT) + old->in_pnext = np->in_dpnext; + else + old->in_pnext = np->in_spnext; + old->in_v = np->in_v[0]; + old->in_flags = np->in_flags; + old->in_mssclamp = np->in_mssclamp; + old->in_age[0] = np->in_age[0]; + old->in_age[1] = np->in_age[1]; + old->in_redir = np->in_redir; + old->in_p = np->in_pr[0]; + if (np->in_redir == NAT_REDIRECT) { + old->in_next6 = np->in_ndst.na_nextaddr; + old->in_in[0] = np->in_ndst.na_addr[0]; + old->in_in[1] = np->in_ndst.na_addr[1]; + old->in_out[0] = np->in_odst.na_addr[0]; + old->in_out[1] = np->in_odst.na_addr[1]; + old->in_src[0] = np->in_osrc.na_addr[0]; + old->in_src[1] = np->in_osrc.na_addr[1]; + } else { + old->in_next6 = np->in_nsrc.na_nextaddr; + old->in_out[0] = np->in_nsrc.na_addr[0]; + old->in_out[1] = np->in_nsrc.na_addr[1]; + old->in_in[0] = np->in_osrc.na_addr[0]; + old->in_in[1] = np->in_osrc.na_addr[1]; + old->in_src[0] = np->in_odst.na_addr[0]; + old->in_src[1] = np->in_odst.na_addr[1]; + } + ipfv5tuctov4(&np->in_tuc, &old->in_tuc); + if (np->in_redir == NAT_REDIRECT) { + old->in_port[0] = np->in_dpmin; + old->in_port[1] = np->in_dpmax; + } else { + old->in_port[0] = np->in_spmin; + old->in_port[1] = np->in_spmax; + } + old->in_ppip = np->in_ppip; + old->in_ippip = np->in_ippip; + bcopy(&np->in_tag, &old->in_tag, sizeof(np->in_tag)); + + if (np->in_ifnames[0] >= 0) { + strncpy(old->in_ifnames[0], np->in_names + np->in_ifnames[0], + LIFNAMSIZ); + old->in_ifnames[0][LIFNAMSIZ - 1] = '\0'; + } + if (np->in_ifnames[1] >= 0) { + strncpy(old->in_ifnames[1], np->in_names + np->in_ifnames[1], + LIFNAMSIZ); + old->in_ifnames[1][LIFNAMSIZ - 1] = '\0'; + } + if (np->in_plabel >= 0) { + strncpy(old->in_plabel, np->in_names + np->in_plabel, + APR_LABELLEN); + old->in_plabel[APR_LABELLEN - 1] = '\0'; + } +} + + +static void +ipstate_current_to_4_1_16(current, old) + void *current; + ipstate_4_1_16_t *old; +{ + ipstate_t *is = (ipstate_t *)current; + + old->is_lock = is->is_lock; + old->is_next = is->is_next; + old->is_pnext = is->is_pnext; + old->is_hnext = is->is_hnext; + old->is_phnext = is->is_phnext; + old->is_me = is->is_me; + old->is_ifp[0] = is->is_ifp[0]; + old->is_ifp[1] = is->is_ifp[1]; + old->is_sync = is->is_sync; + old->is_rule = is->is_rule; + old->is_tqehead[0] = is->is_tqehead[0]; + old->is_tqehead[1] = is->is_tqehead[1]; + old->is_isc = is->is_isc; + old->is_pkts[0] = is->is_pkts[0]; + old->is_pkts[1] = is->is_pkts[1]; + old->is_pkts[2] = is->is_pkts[2]; + old->is_pkts[3] = is->is_pkts[3]; + old->is_bytes[0] = is->is_bytes[0]; + old->is_bytes[1] = is->is_bytes[1]; + old->is_bytes[2] = is->is_bytes[2]; + old->is_bytes[3] = is->is_bytes[3]; + old->is_icmppkts[0] = is->is_icmppkts[0]; + old->is_icmppkts[1] = is->is_icmppkts[1]; + old->is_icmppkts[2] = is->is_icmppkts[2]; + old->is_icmppkts[3] = is->is_icmppkts[3]; + old->is_sti = is->is_sti; + old->is_frage[0] = is->is_frage[0]; + old->is_frage[1] = is->is_frage[1]; + old->is_ref = is->is_ref; + old->is_isninc[0] = is->is_isninc[0]; + old->is_isninc[1] = is->is_isninc[1]; + old->is_sumd[0] = is->is_sumd[0]; + old->is_sumd[1] = is->is_sumd[1]; + old->is_src = is->is_src; + old->is_dst = is->is_dst; + old->is_pass = is->is_pass; + old->is_p = is->is_p; + old->is_v = is->is_v; + old->is_hv = is->is_hv; + old->is_tag = is->is_tag; + old->is_opt[0] = is->is_opt[0]; + old->is_opt[1] = is->is_opt[1]; + old->is_optmsk[0] = is->is_optmsk[0]; + old->is_optmsk[1] = is->is_optmsk[1]; + old->is_sec = is->is_sec; + old->is_secmsk = is->is_secmsk; + old->is_auth = is->is_auth; + old->is_authmsk = is->is_authmsk; + ipf_v5tcpinfoto4(&is->is_tcp, &old->is_tcp); + old->is_flags = is->is_flags; + old->is_flx[0][0] = is->is_flx[0][0]; + old->is_flx[0][1] = is->is_flx[0][1]; + old->is_flx[1][0] = is->is_flx[1][0]; + old->is_flx[1][1] = is->is_flx[1][1]; + old->is_rulen = is->is_rulen; + old->is_s0[0] = is->is_s0[0]; + old->is_s0[1] = is->is_s0[1]; + old->is_smsk[0] = is->is_smsk[0]; + old->is_smsk[1] = is->is_smsk[1]; + bcopy(is->is_group, old->is_group, sizeof(is->is_group)); + bcopy(is->is_sbuf, old->is_sbuf, sizeof(is->is_sbuf)); + bcopy(is->is_ifname, old->is_ifname, sizeof(is->is_ifname)); +} + + +static void +ipstate_current_to_4_1_0(current, old) + void *current; + ipstate_4_1_0_t *old; +{ + ipstate_t *is = (ipstate_t *)current; + + old->is_lock = is->is_lock; + old->is_next = is->is_next; + old->is_pnext = is->is_pnext; + old->is_hnext = is->is_hnext; + old->is_phnext = is->is_phnext; + old->is_me = is->is_me; + old->is_ifp[0] = is->is_ifp[0]; + old->is_ifp[1] = is->is_ifp[1]; + old->is_sync = is->is_sync; + bzero(&old->is_nat, sizeof(old->is_nat)); + old->is_rule = is->is_rule; + old->is_tqehead[0] = is->is_tqehead[0]; + old->is_tqehead[1] = is->is_tqehead[1]; + old->is_isc = is->is_isc; + old->is_pkts[0] = is->is_pkts[0]; + old->is_pkts[1] = is->is_pkts[1]; + old->is_pkts[2] = is->is_pkts[2]; + old->is_pkts[3] = is->is_pkts[3]; + old->is_bytes[0] = is->is_bytes[0]; + old->is_bytes[1] = is->is_bytes[1]; + old->is_bytes[2] = is->is_bytes[2]; + old->is_bytes[3] = is->is_bytes[3]; + old->is_icmppkts[0] = is->is_icmppkts[0]; + old->is_icmppkts[1] = is->is_icmppkts[1]; + old->is_icmppkts[2] = is->is_icmppkts[2]; + old->is_icmppkts[3] = is->is_icmppkts[3]; + old->is_sti = is->is_sti; + old->is_frage[0] = is->is_frage[0]; + old->is_frage[1] = is->is_frage[1]; + old->is_ref = is->is_ref; + old->is_isninc[0] = is->is_isninc[0]; + old->is_isninc[1] = is->is_isninc[1]; + old->is_sumd[0] = is->is_sumd[0]; + old->is_sumd[1] = is->is_sumd[1]; + old->is_src = is->is_src; + old->is_dst = is->is_dst; + old->is_pass = is->is_pass; + old->is_p = is->is_p; + old->is_v = is->is_v; + old->is_hv = is->is_hv; + old->is_tag = is->is_tag; + old->is_opt[0] = is->is_opt[0]; + old->is_opt[1] = is->is_opt[1]; + old->is_optmsk[0] = is->is_optmsk[0]; + old->is_optmsk[1] = is->is_optmsk[1]; + old->is_sec = is->is_sec; + old->is_secmsk = is->is_secmsk; + old->is_auth = is->is_auth; + old->is_authmsk = is->is_authmsk; + ipf_v5tcpinfoto4(&is->is_tcp, &old->is_tcp); + old->is_flags = is->is_flags; + old->is_flx[0][0] = is->is_flx[0][0]; + old->is_flx[0][1] = is->is_flx[0][1]; + old->is_flx[1][0] = is->is_flx[1][0]; + old->is_flx[1][1] = is->is_flx[1][1]; + old->is_rulen = is->is_rulen; + old->is_s0[0] = is->is_s0[0]; + old->is_s0[1] = is->is_s0[1]; + old->is_smsk[0] = is->is_smsk[0]; + old->is_smsk[1] = is->is_smsk[1]; + bcopy(is->is_group, old->is_group, sizeof(is->is_group)); + bcopy(is->is_sbuf, old->is_sbuf, sizeof(is->is_sbuf)); + bcopy(is->is_ifname, old->is_ifname, sizeof(is->is_ifname)); +} + + +static void +ips_stat_current_to_4_1_21(current, old) + void *current; + ips_stat_4_1_21_t *old; +{ + ips_stat_t *st = (ips_stat_t *)current; + + old->iss_hits = st->iss_hits; + old->iss_miss = st->iss_check_miss; + old->iss_max = st->iss_max; + old->iss_maxref = st->iss_max_ref; + old->iss_tcp = st->iss_proto[IPPROTO_TCP]; + old->iss_udp = st->iss_proto[IPPROTO_UDP]; + old->iss_icmp = st->iss_proto[IPPROTO_ICMP]; + old->iss_nomem = st->iss_nomem; + old->iss_expire = st->iss_expire; + old->iss_fin = st->iss_fin; + old->iss_active = st->iss_active; + old->iss_logged = st->iss_log_ok; + old->iss_logfail = st->iss_log_fail; + old->iss_inuse = st->iss_inuse; + old->iss_wild = st->iss_wild; + old->iss_ticks = st->iss_ticks; + old->iss_bucketfull = st->iss_bucket_full; + old->iss_statesize = st->iss_state_size; + old->iss_statemax = st->iss_state_max; + old->iss_table = st->iss_table; + old->iss_list = st->iss_list; + old->iss_bucketlen = (void *)st->iss_bucketlen; + old->iss_tcptab = st->iss_tcptab; +} + + +static void +ips_stat_current_to_4_1_0(current, old) + void *current; + ips_stat_4_1_0_t *old; +{ + ips_stat_t *st = (ips_stat_t *)current; + + old->iss_hits = st->iss_hits; + old->iss_miss = st->iss_check_miss; + old->iss_max = st->iss_max; + old->iss_maxref = st->iss_max_ref; + old->iss_tcp = st->iss_proto[IPPROTO_TCP]; + old->iss_udp = st->iss_proto[IPPROTO_UDP]; + old->iss_icmp = st->iss_proto[IPPROTO_ICMP]; + old->iss_nomem = st->iss_nomem; + old->iss_expire = st->iss_expire; + old->iss_fin = st->iss_fin; + old->iss_active = st->iss_active; + old->iss_logged = st->iss_log_ok; + old->iss_logfail = st->iss_log_fail; + old->iss_inuse = st->iss_inuse; + old->iss_wild = st->iss_wild; + old->iss_ticks = st->iss_ticks; + old->iss_bucketfull = st->iss_bucket_full; + old->iss_statesize = st->iss_state_size; + old->iss_statemax = st->iss_state_max; + old->iss_table = st->iss_table; + old->iss_list = st->iss_list; + old->iss_bucketlen = (void *)st->iss_bucketlen; +} + + +static void +nat_save_current_to_4_1_16(current, old) + void *current; + nat_save_4_1_16_t *old; +{ + nat_save_t *nats = (nat_save_t *)current; + + old->ipn_next = nats->ipn_next; + bcopy(&nats->ipn_nat, &old->ipn_nat, sizeof(old->ipn_nat)); + bcopy(&nats->ipn_ipnat, &old->ipn_ipnat, sizeof(old->ipn_ipnat)); + frentry_current_to_4_1_16(&nats->ipn_fr, &old->ipn_fr); + old->ipn_dsize = nats->ipn_dsize; + bcopy(nats->ipn_data, old->ipn_data, sizeof(nats->ipn_data)); +} + + +static void +nat_save_current_to_4_1_14(current, old) + void *current; + nat_save_4_1_14_t *old; +{ + nat_save_t *nats = (nat_save_t *)current; + + old->ipn_next = nats->ipn_next; + bcopy(&nats->ipn_nat, &old->ipn_nat, sizeof(old->ipn_nat)); + bcopy(&nats->ipn_ipnat, &old->ipn_ipnat, sizeof(old->ipn_ipnat)); + frentry_current_to_4_1_0(&nats->ipn_fr, &old->ipn_fr); + old->ipn_dsize = nats->ipn_dsize; + bcopy(nats->ipn_data, old->ipn_data, sizeof(nats->ipn_data)); +} + + +static void +nat_save_current_to_4_1_3(current, old) + void *current; + nat_save_4_1_3_t *old; +{ + nat_save_t *nats = (nat_save_t *)current; + + old->ipn_next = nats->ipn_next; + bcopy(&nats->ipn_nat, &old->ipn_nat, sizeof(old->ipn_nat)); + bcopy(&nats->ipn_ipnat, &old->ipn_ipnat, sizeof(old->ipn_ipnat)); + frentry_current_to_4_1_0(&nats->ipn_fr, &old->ipn_fr); + old->ipn_dsize = nats->ipn_dsize; + bcopy(nats->ipn_data, old->ipn_data, sizeof(nats->ipn_data)); +} + + +static void +nat_current_to_4_1_25(current, old) + void *current; + nat_4_1_25_t *old; +{ + nat_t *nat = (nat_t *)current; + + old->nat_lock = nat->nat_lock; + old->nat_next = (void *)nat->nat_next; + old->nat_pnext = (void *)nat->nat_pnext; + old->nat_hnext[0] = (void *)nat->nat_hnext[0]; + old->nat_hnext[1] = (void *)nat->nat_hnext[1]; + old->nat_phnext[0] = (void *)nat->nat_phnext[0]; + old->nat_phnext[1] = (void *)nat->nat_phnext[1]; + old->nat_hm = nat->nat_hm; + old->nat_data = nat->nat_data; + old->nat_me = (void *)nat->nat_me; + old->nat_state = nat->nat_state; + old->nat_aps = nat->nat_aps; + old->nat_fr = nat->nat_fr; + old->nat_ptr = (void *)nat->nat_ptr; + old->nat_ifps[0] = nat->nat_ifps[0]; + old->nat_ifps[1] = nat->nat_ifps[1]; + old->nat_sync = nat->nat_sync; + old->nat_tqe = nat->nat_tqe; + old->nat_flags = nat->nat_flags; + old->nat_sumd[0] = nat->nat_sumd[0]; + old->nat_sumd[1] = nat->nat_sumd[1]; + old->nat_ipsumd = nat->nat_ipsumd; + old->nat_mssclamp = nat->nat_mssclamp; + old->nat_pkts[0] = nat->nat_pkts[0]; + old->nat_pkts[1] = nat->nat_pkts[1]; + old->nat_bytes[0] = nat->nat_bytes[0]; + old->nat_bytes[1] = nat->nat_bytes[1]; + old->nat_ref = nat->nat_ref; + old->nat_dir = nat->nat_dir; + old->nat_p = nat->nat_pr[0]; + old->nat_use = nat->nat_use; + old->nat_hv[0] = nat->nat_hv[0]; + old->nat_hv[1] = nat->nat_hv[1]; + old->nat_rev = nat->nat_rev; + old->nat_redir = nat->nat_redir; + bcopy(nat->nat_ifnames[0], old->nat_ifnames[0], LIFNAMSIZ); + bcopy(nat->nat_ifnames[1], old->nat_ifnames[1], LIFNAMSIZ); + + if (nat->nat_redir == NAT_REDIRECT) { + old->nat_inip6 = nat->nat_ndst6; + old->nat_outip6 = nat->nat_odst6; + old->nat_oip6 = nat->nat_osrc6; + old->nat_un.nat_unt.ts_sport = nat->nat_ndport; + old->nat_un.nat_unt.ts_dport = nat->nat_odport; + } else { + old->nat_inip6 = nat->nat_osrc6; + old->nat_outip6 = nat->nat_nsrc6; + old->nat_oip6 = nat->nat_odst6; + old->nat_un.nat_unt.ts_sport = nat->nat_osport; + old->nat_un.nat_unt.ts_dport = nat->nat_nsport; + } +} + + +static void +nat_current_to_4_1_14(current, old) + void *current; + nat_4_1_14_t *old; +{ + nat_t *nat = (nat_t *)current; + + old->nat_lock = nat->nat_lock; + old->nat_next = nat->nat_next; + old->nat_pnext = NULL; + old->nat_hnext[0] = NULL; + old->nat_hnext[1] = NULL; + old->nat_phnext[0] = NULL; + old->nat_phnext[1] = NULL; + old->nat_hm = nat->nat_hm; + old->nat_data = nat->nat_data; + old->nat_me = (void *)nat->nat_me; + old->nat_state = nat->nat_state; + old->nat_aps = nat->nat_aps; + old->nat_fr = nat->nat_fr; + old->nat_ptr = nat->nat_ptr; + old->nat_ifps[0] = nat->nat_ifps[0]; + old->nat_ifps[1] = nat->nat_ifps[1]; + old->nat_sync = nat->nat_sync; + old->nat_tqe = nat->nat_tqe; + old->nat_flags = nat->nat_flags; + old->nat_sumd[0] = nat->nat_sumd[0]; + old->nat_sumd[1] = nat->nat_sumd[1]; + old->nat_ipsumd = nat->nat_ipsumd; + old->nat_mssclamp = nat->nat_mssclamp; + old->nat_pkts[0] = nat->nat_pkts[0]; + old->nat_pkts[1] = nat->nat_pkts[1]; + old->nat_bytes[0] = nat->nat_bytes[0]; + old->nat_bytes[1] = nat->nat_bytes[1]; + old->nat_ref = nat->nat_ref; + old->nat_dir = nat->nat_dir; + old->nat_p = nat->nat_pr[0]; + old->nat_use = nat->nat_use; + old->nat_hv[0] = nat->nat_hv[0]; + old->nat_hv[1] = nat->nat_hv[1]; + old->nat_rev = nat->nat_rev; + bcopy(nat->nat_ifnames[0], old->nat_ifnames[0], LIFNAMSIZ); + bcopy(nat->nat_ifnames[1], old->nat_ifnames[1], LIFNAMSIZ); + + if (nat->nat_redir == NAT_REDIRECT) { + old->nat_inip6 = nat->nat_ndst6; + old->nat_outip6 = nat->nat_odst6; + old->nat_oip6 = nat->nat_osrc6; + old->nat_un.nat_unt.ts_sport = nat->nat_ndport; + old->nat_un.nat_unt.ts_dport = nat->nat_odport; + } else { + old->nat_inip6 = nat->nat_osrc6; + old->nat_outip6 = nat->nat_nsrc6; + old->nat_oip6 = nat->nat_odst6; + old->nat_un.nat_unt.ts_sport = nat->nat_osport; + old->nat_un.nat_unt.ts_dport = nat->nat_nsport; + } +} + + +static void +nat_current_to_4_1_3(current, old) + void *current; + nat_4_1_3_t *old; +{ + nat_t *nat = (nat_t *)current; + + old->nat_lock = nat->nat_lock; + old->nat_next = nat->nat_next; + old->nat_pnext = NULL; + old->nat_hnext[0] = NULL; + old->nat_hnext[1] = NULL; + old->nat_phnext[0] = NULL; + old->nat_phnext[1] = NULL; + old->nat_hm = nat->nat_hm; + old->nat_data = nat->nat_data; + old->nat_me = (void *)nat->nat_me; + old->nat_state = nat->nat_state; + old->nat_aps = nat->nat_aps; + old->nat_fr = nat->nat_fr; + old->nat_ptr = nat->nat_ptr; + old->nat_ifps[0] = nat->nat_ifps[0]; + old->nat_ifps[1] = nat->nat_ifps[1]; + old->nat_sync = nat->nat_sync; + old->nat_tqe = nat->nat_tqe; + old->nat_flags = nat->nat_flags; + old->nat_sumd[0] = nat->nat_sumd[0]; + old->nat_sumd[1] = nat->nat_sumd[1]; + old->nat_ipsumd = nat->nat_ipsumd; + old->nat_mssclamp = nat->nat_mssclamp; + old->nat_pkts[0] = nat->nat_pkts[0]; + old->nat_pkts[1] = nat->nat_pkts[1]; + old->nat_bytes[0] = nat->nat_bytes[0]; + old->nat_bytes[1] = nat->nat_bytes[1]; + old->nat_ref = nat->nat_ref; + old->nat_dir = nat->nat_dir; + old->nat_p = nat->nat_pr[0]; + old->nat_use = nat->nat_use; + old->nat_hv[0] = nat->nat_hv[0]; + old->nat_hv[1] = nat->nat_hv[1]; + old->nat_rev = nat->nat_rev; + bcopy(nat->nat_ifnames[0], old->nat_ifnames[0], LIFNAMSIZ); + bcopy(nat->nat_ifnames[1], old->nat_ifnames[1], LIFNAMSIZ); + + if (nat->nat_redir == NAT_REDIRECT) { + old->nat_inip6 = nat->nat_ndst6; + old->nat_outip6 = nat->nat_odst6; + old->nat_oip6 = nat->nat_osrc6; + old->nat_un.nat_unt.ts_sport = nat->nat_ndport; + old->nat_un.nat_unt.ts_dport = nat->nat_odport; + } else { + old->nat_inip6 = nat->nat_osrc6; + old->nat_outip6 = nat->nat_nsrc6; + old->nat_oip6 = nat->nat_odst6; + old->nat_un.nat_unt.ts_sport = nat->nat_osport; + old->nat_un.nat_unt.ts_dport = nat->nat_nsport; + } +} + +#endif /* IPFILTER_COMPAT */ diff --git a/contrib/ipfilter/ipf.h b/contrib/ipfilter/ipf.h index ae05ca75a906..280f98d938c2 100644 --- a/contrib/ipfilter/ipf.h +++ b/contrib/ipfilter/ipf.h @@ -1,12 +1,12 @@ /* $FreeBSD$ */ /* - * Copyright (C) 1993-2001, 2003 by Darren Reed. + * Copyright (C) 2012 by Darren Reed. * * See the IPFILTER.LICENCE file for details on licencing. * * @(#)ipf.h 1.12 6/5/96 - * $Id: ipf.h,v 2.71.2.15 2007/05/11 10:44:14 darrenr Exp $ + * $Id$ */ #ifndef __IPF_H__ @@ -80,6 +80,7 @@ struct file; #include "netinet/ip_scan.h" #include "netinet/ip_htable.h" #include "netinet/ip_sync.h" +#include "netinet/ip_dstlist.h" #include "opts.h" @@ -120,6 +121,9 @@ typedef unsigned int u_32_t; #define MAX_ICMPCODE 16 #define MAX_ICMPTYPE 19 +#define PRINTF (void)printf +#define FPRINTF (void)fprintf + struct ipopt_names { int on_value; @@ -132,6 +136,7 @@ struct ipopt_names { typedef struct alist_s { struct alist_s *al_next; int al_not; + int al_family; i6addr_t al_i6addr; i6addr_t al_i6mask; } alist_t; @@ -142,6 +147,14 @@ typedef struct alist_s { #define al_2 al_mask +typedef struct plist_s { + struct plist_s *pl_next; + int pl_compare; + u_short pl_port1; + u_short pl_port2; +} plist_t; + + typedef struct { u_short fb_c; u_char fb_t; @@ -150,6 +163,35 @@ typedef struct { } fakebpf_t; +typedef struct { + char *it_name; + int it_v4; + int it_v6; +} icmptype_t; + + +typedef struct wordtab { + char *w_word; + int w_value; +} wordtab_t; + + +typedef struct namelist { + struct namelist *na_next; + char *na_name; + int na_value; +} namelist_t; + + +typedef struct proxyrule { + struct proxyrule *pr_next; + char *pr_proxy; + char *pr_conf; + namelist_t *pr_names; + int pr_proto; +} proxyrule_t; + + #if defined(__NetBSD__) || defined(__OpenBSD__) || \ (_BSDI_VERSION >= 199701) || (__FreeBSD_version >= 300000) || \ SOLARIS || defined(__sgi) || defined(__osf__) || defined(linux) @@ -158,7 +200,7 @@ typedef int (* ioctlfunc_t) __P((int, ioctlcmd_t, ...)); #else typedef int (* ioctlfunc_t) __P((dev_t, ioctlcmd_t, void *)); #endif -typedef void (* addfunc_t) __P((int, ioctlfunc_t, void *)); +typedef int (* addfunc_t) __P((int, ioctlfunc_t, void *)); typedef int (* copyfunc_t) __P((void *, void *, size_t)); @@ -178,90 +220,143 @@ extern char *icmpcodes[MAX_ICMPCODE + 1]; extern char *icmptypes[MAX_ICMPTYPE + 1]; extern int use_inet6; extern int lineNum; +extern int debuglevel; extern struct ipopt_names v6ionames[]; +extern icmptype_t icmptypelist[]; +extern wordtab_t statefields[]; +extern wordtab_t natfields[]; +extern wordtab_t poolfields[]; extern int addicmp __P((char ***, struct frentry *, int)); extern int addipopt __P((char *, struct ipopt_names *, int, char *)); -extern void alist_free __P((alist_t *)); +extern int addkeep __P((char ***, struct frentry *, int)); extern alist_t *alist_new __P((int, char *)); +extern void alist_free __P((alist_t *)); +extern void assigndefined __P((char *)); extern void binprint __P((void *, size_t)); -extern void initparse __P((void)); extern u_32_t buildopts __P((char *, char *, int)); extern int checkrev __P((char *)); +extern int connecttcp __P((char *, int)); extern int count6bits __P((u_32_t *)); extern int count4bits __P((u_32_t)); extern char *fac_toname __P((int)); extern int fac_findname __P((char *)); +extern const char *familyname __P((const int)); extern void fill6bits __P((int, u_int *)); -extern int gethost __P((char *, u_32_t *)); -extern int getport __P((struct frentry *, char *, u_short *)); +extern wordtab_t *findword __P((wordtab_t *, char *)); +extern int ftov __P((int)); +extern char *ipf_geterror __P((int, ioctlfunc_t *)); +extern int genmask __P((int, char *, i6addr_t *)); +extern int gethost __P((int, char *, i6addr_t *)); +extern int geticmptype __P((int, char *)); +extern int getport __P((struct frentry *, char *, u_short *, char *)); extern int getportproto __P((char *, int)); extern int getproto __P((char *)); -extern char *getnattype __P((struct nat *, int)); +extern char *getnattype __P((struct nat *)); extern char *getsumd __P((u_32_t)); extern u_32_t getoptbyname __P((char *)); extern u_32_t getoptbyvalue __P((int)); extern u_32_t getv6optbyname __P((char *)); extern u_32_t getv6optbyvalue __P((int)); +extern char *icmptypename __P((int, int)); extern void initparse __P((void)); -extern void ipf_dotuning __P((int, char *, ioctlfunc_t)); -extern void ipf_addrule __P((int, ioctlfunc_t, void *)); +extern void ipf_dotuning __P((int, char *, ioctlfunc_t)); +extern int ipf_addrule __P((int, ioctlfunc_t, void *)); +extern void ipf_mutex_clean __P((void)); extern int ipf_parsefile __P((int, addfunc_t, ioctlfunc_t *, char *)); extern int ipf_parsesome __P((int, addfunc_t, ioctlfunc_t *, FILE *)); +extern void ipf_perror __P((int, char *)); +extern int ipf_perror_fd __P(( int, ioctlfunc_t, char *)); +extern void ipf_rwlock_clean __P((void)); +extern char *ipf_strerror __P((int)); +extern void ipferror __P((int, char *)); extern int ipmon_parsefile __P((char *)); extern int ipmon_parsesome __P((FILE *)); -extern void ipnat_addrule __P((int, ioctlfunc_t, void *)); +extern int ipnat_addrule __P((int, ioctlfunc_t, void *)); extern int ipnat_parsefile __P((int, addfunc_t, ioctlfunc_t, char *)); extern int ipnat_parsesome __P((int, addfunc_t, ioctlfunc_t, FILE *)); extern int ippool_parsefile __P((int, char *, ioctlfunc_t)); extern int ippool_parsesome __P((int, FILE *, ioctlfunc_t)); extern int kmemcpywrap __P((void *, void *, size_t)); extern char *kvatoname __P((ipfunc_t, ioctlfunc_t)); +extern int load_dstlist __P((struct ippool_dst *, ioctlfunc_t, + ipf_dstnode_t *)); +extern int load_dstlistnode __P((int, char *, struct ipf_dstnode *, + ioctlfunc_t)); extern alist_t *load_file __P((char *)); extern int load_hash __P((struct iphtable_s *, struct iphtent_s *, ioctlfunc_t)); -extern int load_hashnode __P((int, char *, struct iphtent_s *, ioctlfunc_t)); +extern int load_hashnode __P((int, char *, struct iphtent_s *, int, + ioctlfunc_t)); extern alist_t *load_http __P((char *)); extern int load_pool __P((struct ip_pool_s *list, ioctlfunc_t)); -extern int load_poolnode __P((int, char *, ip_pool_node_t *, ioctlfunc_t)); +extern int load_poolnode __P((int, char *, ip_pool_node_t *, int, ioctlfunc_t)); extern alist_t *load_url __P((char *)); extern alist_t *make_range __P((int, struct in_addr, struct in_addr)); +extern void mb_hexdump __P((mb_t *, FILE *)); extern ipfunc_t nametokva __P((char *, ioctlfunc_t)); extern void nat_setgroupmap __P((struct ipnat *)); extern int ntomask __P((int, int, u_32_t *)); extern u_32_t optname __P((char ***, u_short *, int)); -extern struct frentry *parse __P((char *, int)); +extern wordtab_t *parsefields __P((wordtab_t *, char *)); +extern int *parseipfexpr __P((char *, char **)); +extern int parsewhoisline __P((char *, addrfamily_t *, addrfamily_t *)); +extern void pool_close __P((void)); +extern int pool_fd __P((void)); +extern int pool_ioctl __P((ioctlfunc_t, ioctlcmd_t, void *)); +extern int pool_open __P((void)); extern char *portname __P((int, int)); extern int pri_findname __P((char *)); extern char *pri_toname __P((int)); -extern void print_toif __P((char *, struct frdest *)); -extern void printaps __P((ap_session_t *, int)); +extern void print_toif __P((int, char *, char *, struct frdest *)); +extern void printaps __P((ap_session_t *, int, int)); +extern void printaddr __P((int, int, char *, int, u_32_t *, u_32_t *)); extern void printbuf __P((char *, int, int)); +extern void printfieldhdr __P((wordtab_t *, wordtab_t *)); extern void printfr __P((struct frentry *, ioctlfunc_t)); -extern void printtunable __P((ipftune_t *)); extern struct iphtable_s *printhash __P((struct iphtable_s *, copyfunc_t, - char *, int)); -extern struct iphtable_s *printhash_live __P((iphtable_t *, int, char *, int)); + char *, int, wordtab_t *)); +extern struct iphtable_s *printhash_live __P((iphtable_t *, int, char *, + int, wordtab_t *)); +extern ippool_dst_t *printdstl_live __P((ippool_dst_t *, int, char *, + int, wordtab_t *)); extern void printhashdata __P((iphtable_t *, int)); extern struct iphtent_s *printhashnode __P((struct iphtable_s *, struct iphtent_s *, - copyfunc_t, int)); + copyfunc_t, int, wordtab_t *)); +extern void printhost __P((int, u_32_t *)); extern void printhostmask __P((int, u_32_t *, u_32_t *)); -extern void printip __P((u_32_t *)); +extern void printip __P((int, u_32_t *)); extern void printlog __P((struct frentry *)); -extern void printlookup __P((i6addr_t *addr, i6addr_t *mask)); -extern void printmask __P((u_32_t *)); -extern void printpacket __P((struct ip *)); -extern void printpacket6 __P((struct ip *)); +extern void printlookup __P((char *, i6addr_t *addr, i6addr_t *mask)); +extern void printmask __P((int, u_32_t *)); +extern void printnataddr __P((int, char *, nat_addr_t *, int)); +extern void printnatfield __P((nat_t *, int)); +extern void printnatside __P((char *, nat_stat_side_t *)); +extern void printpacket __P((int, mb_t *)); +extern void printpacket6 __P((int, mb_t *)); +extern struct ippool_dst *printdstlist __P((struct ippool_dst *, copyfunc_t, + char *, int, ipf_dstnode_t *, + wordtab_t *)); +extern void printdstlistdata __P((ippool_dst_t *, int)); +extern ipf_dstnode_t *printdstlistnode __P((ipf_dstnode_t *, copyfunc_t, + int, wordtab_t *)); +extern void printdstlistpolicy __P((ippool_policy_t)); extern struct ip_pool_s *printpool __P((struct ip_pool_s *, copyfunc_t, - char *, int)); + char *, int, wordtab_t *)); extern struct ip_pool_s *printpool_live __P((struct ip_pool_s *, int, - char *, int)); + char *, int, wordtab_t *)); extern void printpooldata __P((ip_pool_t *, int)); -extern struct ip_pool_node *printpoolnode __P((struct ip_pool_node *, int)); +extern void printpoolfield __P((void *, int, int)); +extern struct ip_pool_node *printpoolnode __P((struct ip_pool_node *, + int, wordtab_t *)); extern void printproto __P((struct protoent *, int, struct ipnat *)); extern void printportcmp __P((int, struct frpcmp *)); +extern void printstatefield __P((ipstate_t *, int)); +extern void printtqtable __P((ipftq_t *)); +extern void printtunable __P((ipftune_t *)); +extern void printunit __P((int)); extern void optprint __P((u_short *, u_long, u_long)); #ifdef USE_INET6 extern void optprintv6 __P((u_short *, u_long, u_long)); @@ -270,7 +365,6 @@ extern int remove_hash __P((struct iphtable_s *, ioctlfunc_t)); extern int remove_hashnode __P((int, char *, struct iphtent_s *, ioctlfunc_t)); extern int remove_pool __P((ip_pool_t *, ioctlfunc_t)); extern int remove_poolnode __P((int, char *, ip_pool_node_t *, ioctlfunc_t)); -extern u_char tcp_flags __P((char *, u_char *, int)); extern u_char tcpflags __P((char *)); extern void printc __P((struct frentry *)); extern void printC __P((int)); @@ -283,14 +377,26 @@ extern char *hostname __P((int, void *)); extern struct ipstate *printstate __P((struct ipstate *, int, u_long)); extern void printsbuf __P((char *)); extern void printnat __P((struct ipnat *, int)); -extern void printactivenat __P((struct nat *, int, int, u_long)); +extern void printactiveaddress __P((int, char *, i6addr_t *, char *)); +extern void printactivenat __P((struct nat *, int, u_long)); extern void printhostmap __P((struct hostmap *, u_int)); -extern void printtqtable __P((ipftq_t *)); +extern void printtcpflags __P((u_32_t, u_32_t)); +extern void printipfexpr __P((int *)); +extern void printstatefield __P((ipstate_t *, int)); +extern void printstatefieldhdr __P((int)); +extern int sendtrap_v1_0 __P((int, char *, char *, int, time_t)); +extern int sendtrap_v2_0 __P((int, char *, char *, int)); +extern int vtof __P((int)); extern void set_variable __P((char *, char *)); extern char *get_variable __P((char *, char **, int)); extern void resetlexer __P((void)); +extern void debug __P((int, char *, ...)); +extern void verbose __P((int, char *, ...)); +extern void ipfkdebug __P((char *, ...)); +extern void ipfkverbose __P((char *, ...)); + #if SOLARIS extern int gethostname __P((char *, int )); extern void sync __P((void)); diff --git a/contrib/ipfilter/ipf_rb.h b/contrib/ipfilter/ipf_rb.h new file mode 100644 index 000000000000..3d7a59d99d36 --- /dev/null +++ b/contrib/ipfilter/ipf_rb.h @@ -0,0 +1,364 @@ +/* + * Copyright (C) 2012 by Darren Reed. + * + * See the IPFILTER.LICENCE file for details on licencing. + * + */ +typedef enum rbcolour_e { + C_BLACK = 0, + C_RED = 1 +} rbcolour_t; + +#define RBI_LINK(_n, _t) \ + struct _n##_rb_link { \ + struct _t *left; \ + struct _t *right; \ + struct _t *parent; \ + rbcolour_t colour; \ + } + +#define RBI_HEAD(_n, _t) \ +struct _n##_rb_head { \ + struct _t top; \ + int count; \ + int (* compare)(struct _t *, struct _t *); \ +} + +#define RBI_CODE(_n, _t, _f, _cmp) \ + \ +typedef void (*_n##_rb_walker_t)(_t *, void *); \ + \ +_t * _n##_rb_delete(struct _n##_rb_head *, _t *); \ +void _n##_rb_init(struct _n##_rb_head *); \ +void _n##_rb_insert(struct _n##_rb_head *, _t *); \ +_t * _n##_rb_search(struct _n##_rb_head *, void *); \ +void _n##_rb_walktree(struct _n##_rb_head *, _n##_rb_walker_t, void *);\ + \ +static void \ +rotate_left(struct _n##_rb_head *head, _t *node) \ +{ \ + _t *parent, *tmp1, *tmp2; \ + \ + parent = node->_f.parent; \ + tmp1 = node->_f.right; \ + tmp2 = tmp1->_f.left; \ + node->_f.right = tmp2; \ + if (tmp2 != & _n##_rb_zero) \ + tmp2->_f.parent = node; \ + if (parent == & _n##_rb_zero) \ + head->top._f.right = tmp1; \ + else if (parent->_f.right == node) \ + parent->_f.right = tmp1; \ + else \ + parent->_f.left = tmp1; \ + tmp1->_f.left = node; \ + tmp1->_f.parent = parent; \ + node->_f.parent = tmp1; \ +} \ + \ +static void \ +rotate_right(struct _n##_rb_head *head, _t *node) \ +{ \ + _t *parent, *tmp1, *tmp2; \ + \ + parent = node->_f.parent; \ + tmp1 = node->_f.left; \ + tmp2 = tmp1->_f.right; \ + node->_f.left = tmp2; \ + if (tmp2 != &_n##_rb_zero) \ + tmp2->_f.parent = node; \ + if (parent == &_n##_rb_zero) \ + head->top._f.right = tmp1; \ + else if (parent->_f.right == node) \ + parent->_f.right = tmp1; \ + else \ + parent->_f.left = tmp1; \ + tmp1->_f.right = node; \ + tmp1->_f.parent = parent; \ + node->_f.parent = tmp1; \ +} \ + \ +void \ +_n##_rb_insert(struct _n##_rb_head *head, _t *node) \ +{ \ + _t *n, *parent, **p, *tmp1, *gparent; \ + \ + parent = &head->top; \ + node->_f.left = &_n##_rb_zero; \ + node->_f.right = &_n##_rb_zero; \ + p = &head->top._f.right; \ + while ((n = *p) != &_n##_rb_zero) { \ + if (_cmp(node, n) < 0) \ + p = &n->_f.left; \ + else \ + p = &n->_f.right; \ + parent = n; \ + } \ + *p = node; \ + node->_f.colour = C_RED; \ + node->_f.parent = parent; \ + \ + while ((node != &_n##_rb_zero) && (parent->_f.colour == C_RED)){\ + gparent = parent->_f.parent; \ + if (parent == gparent->_f.left) { \ + tmp1 = gparent->_f.right; \ + if (tmp1->_f.colour == C_RED) { \ + parent->_f.colour = C_BLACK; \ + tmp1->_f.colour = C_BLACK; \ + gparent->_f.colour = C_RED; \ + node = gparent; \ + } else { \ + if (node == parent->_f.right) { \ + node = parent; \ + rotate_left(head, node); \ + parent = node->_f.parent; \ + } \ + parent->_f.colour = C_BLACK; \ + gparent->_f.colour = C_RED; \ + rotate_right(head, gparent); \ + } \ + } else { \ + tmp1 = gparent->_f.left; \ + if (tmp1->_f.colour == C_RED) { \ + parent->_f.colour = C_BLACK; \ + tmp1->_f.colour = C_BLACK; \ + gparent->_f.colour = C_RED; \ + node = gparent; \ + } else { \ + if (node == parent->_f.left) { \ + node = parent; \ + rotate_right(head, node); \ + parent = node->_f.parent; \ + } \ + parent->_f.colour = C_BLACK; \ + gparent->_f.colour = C_RED; \ + rotate_left(head, parent->_f.parent); \ + } \ + } \ + parent = node->_f.parent; \ + } \ + head->top._f.right->_f.colour = C_BLACK; \ + head->count++; \ +} \ + \ +static void \ +deleteblack(struct _n##_rb_head *head, _t *parent, _t *node) \ +{ \ + _t *tmp; \ + \ + while ((node == &_n##_rb_zero || node->_f.colour == C_BLACK) && \ + node != &head->top) { \ + if (parent->_f.left == node) { \ + tmp = parent->_f.right; \ + if (tmp->_f.colour == C_RED) { \ + tmp->_f.colour = C_BLACK; \ + parent->_f.colour = C_RED; \ + rotate_left(head, parent); \ + tmp = parent->_f.right; \ + } \ + if ((tmp->_f.left == &_n##_rb_zero || \ + tmp->_f.left->_f.colour == C_BLACK) && \ + (tmp->_f.right == &_n##_rb_zero || \ + tmp->_f.right->_f.colour == C_BLACK)) { \ + tmp->_f.colour = C_RED; \ + node = parent; \ + parent = node->_f.parent; \ + } else { \ + if (tmp->_f.right == &_n##_rb_zero || \ + tmp->_f.right->_f.colour == C_BLACK) {\ + _t *tmp2 = tmp->_f.left; \ + \ + if (tmp2 != &_n##_rb_zero) \ + tmp2->_f.colour = C_BLACK;\ + tmp->_f.colour = C_RED; \ + rotate_right(head, tmp); \ + tmp = parent->_f.right; \ + } \ + tmp->_f.colour = parent->_f.colour; \ + parent->_f.colour = C_BLACK; \ + if (tmp->_f.right != &_n##_rb_zero) \ + tmp->_f.right->_f.colour = C_BLACK;\ + rotate_left(head, parent); \ + node = head->top._f.right; \ + } \ + } else { \ + tmp = parent->_f.left; \ + if (tmp->_f.colour == C_RED) { \ + tmp->_f.colour = C_BLACK; \ + parent->_f.colour = C_RED; \ + rotate_right(head, parent); \ + tmp = parent->_f.left; \ + } \ + if ((tmp->_f.left == &_n##_rb_zero || \ + tmp->_f.left->_f.colour == C_BLACK) && \ + (tmp->_f.right == &_n##_rb_zero || \ + tmp->_f.right->_f.colour == C_BLACK)) { \ + tmp->_f.colour = C_RED; \ + node = parent; \ + parent = node->_f.parent; \ + } else { \ + if (tmp->_f.left == &_n##_rb_zero || \ + tmp->_f.left->_f.colour == C_BLACK) {\ + _t *tmp2 = tmp->_f.right; \ + \ + if (tmp2 != &_n##_rb_zero) \ + tmp2->_f.colour = C_BLACK;\ + tmp->_f.colour = C_RED; \ + rotate_left(head, tmp); \ + tmp = parent->_f.left; \ + } \ + tmp->_f.colour = parent->_f.colour; \ + parent->_f.colour = C_BLACK; \ + if (tmp->_f.left != &_n##_rb_zero) \ + tmp->_f.left->_f.colour = C_BLACK;\ + rotate_right(head, parent); \ + node = head->top._f.right; \ + break; \ + } \ + } \ + } \ + if (node != &_n##_rb_zero) \ + node->_f.colour = C_BLACK; \ +} \ + \ +_t * \ +_n##_rb_delete(struct _n##_rb_head *head, _t *node) \ +{ \ + _t *child, *parent, *old = node, *left; \ + rbcolour_t color; \ + \ + if (node->_f.left == &_n##_rb_zero) { \ + child = node->_f.right; \ + } else if (node->_f.right == &_n##_rb_zero) { \ + child = node->_f.left; \ + } else { \ + node = node->_f.right; \ + while ((left = node->_f.left) != &_n##_rb_zero) \ + node = left; \ + child = node->_f.right; \ + parent = node->_f.parent; \ + color = node->_f.colour; \ + if (child != &_n##_rb_zero) \ + child->_f.parent = parent; \ + if (parent != &_n##_rb_zero) { \ + if (parent->_f.left == node) \ + parent->_f.left = child; \ + else \ + parent->_f.right = child; \ + } else { \ + head->top._f.right = child; \ + } \ + if (node->_f.parent == old) \ + parent = node; \ + *node = *old; \ + if (old->_f.parent != &_n##_rb_zero) { \ + if (old->_f.parent->_f.left == old) \ + old->_f.parent->_f.left = node; \ + else \ + old->_f.parent->_f.right = node; \ + } else { \ + head->top._f.right = child; \ + } \ + old->_f.left->_f.parent = node; \ + if (old->_f.right != &_n##_rb_zero) \ + old->_f.right->_f.parent = node; \ + if (parent != &_n##_rb_zero) { \ + left = parent; \ + } \ + goto colour; \ + } \ + parent = node->_f.parent; \ + color= node->_f.colour; \ + if (child != &_n##_rb_zero) \ + child->_f.parent = parent; \ + if (parent != &_n##_rb_zero) { \ + if (parent->_f.left == node) \ + parent->_f.left = child; \ + else \ + parent->_f.right = child; \ + } else { \ + head->top._f.right = child; \ + } \ +colour: \ + if (color == C_BLACK) \ + deleteblack(head, parent, node); \ + head->count--; \ + return old; \ +} \ + \ +void \ +_n##_rb_init(struct _n##_rb_head *head) \ +{ \ + memset(head, 0, sizeof(*head)); \ + memset(&_n##_rb_zero, 0, sizeof(_n##_rb_zero)); \ + head->top._f.left = &_n##_rb_zero; \ + head->top._f.right = &_n##_rb_zero; \ + head->top._f.parent = &head->top; \ + _n##_rb_zero._f.left = &_n##_rb_zero; \ + _n##_rb_zero._f.right = &_n##_rb_zero; \ + _n##_rb_zero._f.parent = &_n##_rb_zero; \ +} \ + \ +void \ +_n##_rb_walktree(struct _n##_rb_head *head, _n##_rb_walker_t func, void *arg)\ +{ \ + _t *prev; \ + _t *next; \ + _t *node = head->top._f.right; \ + _t *base; \ + \ + while (node != &_n##_rb_zero) \ + node = node->_f.left; \ + \ + for (;;) { \ + base = node; \ + prev = node; \ + while ((node->_f.parent->_f.right == node) && \ + (node != &_n##_rb_zero)) { \ + prev = node; \ + node = node->_f.parent; \ + } \ + \ + node = prev; \ + for (node = node->_f.parent->_f.right; node != &_n##_rb_zero;\ + node = node->_f.left) \ + prev = node; \ + next = prev; \ + \ + if (node != &_n##_rb_zero) \ + func(node, arg); \ + \ + node = next; \ + if (node == &_n##_rb_zero) \ + break; \ + } \ +} \ + \ +_t * \ +_n##_rb_search(struct _n##_rb_head *head, void *key) \ +{ \ + int match; \ + _t *node; \ + node = head->top._f.right; \ + while (node != &_n##_rb_zero) { \ + match = _cmp(key, node); \ + if (match == 0) \ + break; \ + if (match< 0) \ + node = node->_f.left; \ + else \ + node = node->_f.right; \ + } \ + if (node == &_n##_rb_zero || match != 0) \ + return (NULL); \ + return (node); \ +} + +#define RBI_DELETE(_n, _h, _v) _n##_rb_delete(_h, _v) +#define RBI_FIELD(_n) struct _n##_rb_link +#define RBI_INIT(_n, _h) _n##_rb_init(_h) +#define RBI_INSERT(_n, _h, _v) _n##_rb_insert(_h, _v) +#define RBI_ISEMPTY(_h) ((_h)->count == 0) +#define RBI_SEARCH(_n, _h, _k) _n##_rb_search(_h, _k) +#define RBI_WALK(_n, _h, _w, _a) _n##_rb_walktree(_h, _w, _a) +#define RBI_ZERO(_n) _n##_rb_zero diff --git a/contrib/ipfilter/iplang/.cvsignore b/contrib/ipfilter/iplang/.cvsignore deleted file mode 100644 index 68b5b4e4e985..000000000000 --- a/contrib/ipfilter/iplang/.cvsignore +++ /dev/null @@ -1,9 +0,0 @@ -y.tab.h -y.output -lex.yy.c -y.tab.c -y.tab.o -lex.yy.o -iplang_y.output -iplang_y.tab.c -iplang_y.tab.h diff --git a/contrib/ipfilter/iplang/Makefile b/contrib/ipfilter/iplang/Makefile index 1d66bb655c5a..5b53e9a43609 100644 --- a/contrib/ipfilter/iplang/Makefile +++ b/contrib/ipfilter/iplang/Makefile @@ -3,21 +3,20 @@ # #CC=gcc -Wuninitialized -Wstrict-prototypes -Werror -O CFLAGS=-I.. -CCARGS=$(DEBUG) -I. -I.. $(CFLAGS) -I$(DESTDIR) -I$(DESTDIR)/.. -I../ipsend all: $(DESTDIR)/iplang_y.o $(DESTDIR)/iplang_l.o $(DESTDIR)/iplang_y.o: $(DESTDIR)/iplang_y.c - $(CC) $(CCARGS) $(LINUX) -c $(DESTDIR)/iplang_y.c -o $@ + $(CC) $(DEBUG) -I. -I.. -I$(DESTDIR) -I../ipsend $(CFLAGS) $(LINUX) -c $(DESTDIR)/iplang_y.c -o $@ $(DESTDIR)/iplang_l.o: $(DESTDIR)/iplang_l.c - $(CC) $(CCARGS) $(LINUX) -c $(DESTDIR)/iplang_l.c -o $@ + $(CC) $(DEBUG) -I. -I.. -I$(DESTDIR) -I../ipsend $(CFLAGS) $(LINUX) -c $(DESTDIR)/iplang_l.c -o $@ iplang_y.o: iplang_y.c - $(CC) $(CCARGS) $< -o $@ + $(CC) $(DEBUG) -I. -I.. -I../ipsend $(CFLAGS) $(LINUX) -c $< -o $@ iplang_l.o: iplang_l.c - $(CC) $(CCARGS) $< -o $@ + $(CC) $(DEBUG) -I. -I.. -I../ipsend $(CFLAGS) $(LINUX) -c $< -o $@ $(DESTDIR)/iplang_l.c: iplang_l.l $(DESTDIR)/iplang_y.h lex iplang_l.l diff --git a/contrib/ipfilter/iplang/iplang.h b/contrib/ipfilter/iplang/iplang.h index 2b2d1db5a6e2..63cc078322a3 100644 --- a/contrib/ipfilter/iplang/iplang.h +++ b/contrib/ipfilter/iplang/iplang.h @@ -1,7 +1,7 @@ /* $FreeBSD$ */ /* - * Copyright (C) 1997-1998 by Darren Reed. + * Copyright (C) 2012 by Darren Reed. * * See the IPFILTER.LICENCE file for details on licencing. */ diff --git a/contrib/ipfilter/iplang/iplang.tst b/contrib/ipfilter/iplang/iplang.tst index a0a2ad3315ae..841c3aed1316 100644 --- a/contrib/ipfilter/iplang/iplang.tst +++ b/contrib/ipfilter/iplang/iplang.tst @@ -4,7 +4,7 @@ interface { ifname le0; mtu 1500; } ; ipv4 { src 1.1.1.1; dst 2.2.2.2; tcp { - seq 12345; ack 0; sport 9999; dport 23; flags S; + seq 12345; ack 0; sport 9999; dport 23; flags S; data { value "abcdef"; } ; } ; } ; diff --git a/contrib/ipfilter/iplang/iplang_l.l b/contrib/ipfilter/iplang/iplang_l.l index f356d0fb4465..029a4175bbec 100644 --- a/contrib/ipfilter/iplang/iplang_l.l +++ b/contrib/ipfilter/iplang/iplang_l.l @@ -2,11 +2,11 @@ %{ /* - * Copyright (C) 1997-1998 by Darren Reed. + * Copyright (C) 2012 by Darren Reed. * * See the IPFILTER.LICENCE file for details on licencing. * - * $Id: iplang_l.l,v 2.8 2003/07/28 01:15:31 darrenr Exp $ + * $Id$ */ #include #include diff --git a/contrib/ipfilter/iplang/iplang_y.y b/contrib/ipfilter/iplang/iplang_y.y index 773f27f2c17e..98c8f1a983ea 100644 --- a/contrib/ipfilter/iplang/iplang_y.y +++ b/contrib/ipfilter/iplang/iplang_y.y @@ -2,7 +2,7 @@ %{ /* - * Copyright (C) 1997-1998 by Darren Reed. + * Copyright (C) 2012 by Darren Reed. * * See the IPFILTER.LICENCE file for details on licencing. * @@ -26,17 +26,13 @@ #include #include #include +#include #include #include #include #ifndef linux # include -#endif -#ifdef __osf__ -# include "radix_ipf_local.h" -#endif -#include -#ifndef linux +# include # include #endif #include @@ -605,7 +601,7 @@ struct statetoopt tosecopts[] = { #ifdef bsdi struct ether_addr * ether_aton(s) - char *s; + char *s; { static struct ether_addr n; u_int i[6]; @@ -1330,7 +1326,7 @@ void packet_done() sprintf((char *)t, " "); t += 8; for (k = 16; k; k--, s++) - *t++ = (ISPRINT(*s) ? *s : '.'); + *t++ = (isprint(*s) ? *s : '.'); s--; } @@ -1348,7 +1344,7 @@ void packet_done() t += 7; s -= j & 0xf; for (k = j & 0xf; k; k--, s++) - *t++ = (ISPRINT(*s) ? *s : '.'); + *t++ = (isprint(*s) ? *s : '.'); *t++ = '\n'; *t = '\0'; } @@ -1840,7 +1836,7 @@ u_long init; { u_long sum = init; int nwords = len >> 1; - + for(; nwords > 0; nwords--) sum += *buf++; sum = (sum>>16) + (sum & 0xffff); @@ -1855,7 +1851,7 @@ u_int len; { u_long sum = 0; int nwords = len >> 1; - + for(; nwords > 0; nwords--) sum += *buf++; return sum; diff --git a/contrib/ipfilter/ipmon.h b/contrib/ipfilter/ipmon.h index afee1f4fb3f7..b469cc80d6b5 100644 --- a/contrib/ipfilter/ipmon.h +++ b/contrib/ipfilter/ipmon.h @@ -1,22 +1,63 @@ /* $FreeBSD$ */ /* - * Copyright (C) 1993-2001 by Darren Reed. + * Copyright (C) 2012 by Darren Reed. * * See the IPFILTER.LICENCE file for details on licencing. * * @(#)ip_fil.h 1.35 6/5/96 - * $Id: ipmon.h,v 2.8.2.1 2006/03/21 16:13:31 darrenr Exp $ + * $Id$ */ +typedef struct ipmon_msg_s { + int imm_msglen; + char *imm_msg; + int imm_dsize; + void *imm_data; + time_t imm_when; + int imm_loglevel; +} ipmon_msg_t; -typedef struct ipmon_action { +typedef void (*ims_destroy_func_t)(void *); +typedef void *(*ims_dup_func_t)(void *); +typedef int (*ims_match_func_t)(void *, void *); +typedef void *(*ims_parse_func_t)(char **); +typedef void (*ims_print_func_t)(void *); +typedef int (*ims_store_func_t)(void *, ipmon_msg_t *); + +typedef struct ipmon_saver_s { + char *ims_name; + ims_destroy_func_t ims_destroy; + ims_dup_func_t ims_dup; + ims_match_func_t ims_match; + ims_parse_func_t ims_parse; + ims_print_func_t ims_print; + ims_store_func_t ims_store; +} ipmon_saver_t; + +typedef struct ipmon_saver_int_s { + struct ipmon_saver_int_s *imsi_next; + ipmon_saver_t *imsi_stor; + void *imsi_handle; +} ipmon_saver_int_t; + +typedef struct ipmon_doing_s { + struct ipmon_doing_s *ipmd_next; + void *ipmd_token; + ipmon_saver_t *ipmd_saver; + /* + * ipmd_store is "cached" in this structure to avoid a double + * deref when doing saves.... + */ + int (*ipmd_store)(void *, ipmon_msg_t *); +} ipmon_doing_t; + + +typedef struct ipmon_action { struct ipmon_action *ac_next; int ac_mflag; /* collection of things to compare */ int ac_dflag; /* flags to compliment the doing fields */ - int ac_syslog; /* = 1 to syslog rules. */ - char *ac_savefile; /* filename to save log records to */ - FILE *ac_savefp; + int ac_logpri; int ac_direction; char ac_group[FR_GROUPLEN]; char ac_nattag[16]; @@ -28,19 +69,21 @@ typedef struct ipmon_action { int ac_second; int ac_result; u_32_t ac_sip; - u_32_t ac_smsk; + u_32_t ac_smsk; u_32_t ac_dip; - u_32_t ac_dmsk; + u_32_t ac_dmsk; u_short ac_sport; u_short ac_dport; - char *ac_exec; /* execute argument */ - char *ac_run; /* actual command that gets run */ char *ac_iface; /* * used with ac_packet/ac_second */ struct timeval ac_last; int ac_pktcnt; + /* + * What to do with matches + */ + ipmon_doing_t *ac_doing; } ipmon_action_t; #define ac_lastsec ac_last.tv_sec @@ -70,19 +113,18 @@ typedef struct ipmon_action { #define IPMR_NOMATCH 3 #define IPMR_LOG 4 -#define IPMDO_SAVERAW 0x0001 - -#define OPT_SYSLOG 0x001 -#define OPT_RESOLVE 0x002 -#define OPT_HEXBODY 0x004 -#define OPT_VERBOSE 0x008 -#define OPT_HEXHDR 0x010 -#define OPT_TAIL 0x020 -#define OPT_NAT 0x080 -#define OPT_STATE 0x100 -#define OPT_FILTER 0x200 -#define OPT_PORTNUM 0x400 -#define OPT_LOGALL (OPT_NAT|OPT_STATE|OPT_FILTER) +#define IPMON_SYSLOG 0x001 +#define IPMON_RESOLVE 0x002 +#define IPMON_HEXBODY 0x004 +#define IPMON_HEXHDR 0x010 +#define IPMON_TAIL 0x020 +#define IPMON_VERBOSE 0x040 +#define IPMON_NAT 0x080 +#define IPMON_STATE 0x100 +#define IPMON_FILTER 0x200 +#define IPMON_PORTNUM 0x400 +#define IPMON_LOGALL (IPMON_NAT|IPMON_STATE|IPMON_FILTER) +#define IPMON_LOGBODY 0x800 #define HOSTNAME_V4(a,b) hostname((a), 4, (u_32_t *)&(b)) @@ -90,8 +132,11 @@ typedef struct ipmon_action { #define LOGFAC LOG_LOCAL0 #endif +extern void dump_config __P((void)); extern int load_config __P((char *)); +extern void unload_config __P((void)); extern void dumphex __P((FILE *, int, char *, int)); extern int check_action __P((char *, char *, int, int)); extern char *getword __P((int)); -extern int fac_findname __P((char *)); +extern void *add_doing __P((ipmon_saver_t *)); + diff --git a/contrib/ipfilter/ipsd/Makefile b/contrib/ipfilter/ipsd/Makefile index 0f3ce08ba229..d5dde8e7eec5 100644 --- a/contrib/ipfilter/ipsd/Makefile +++ b/contrib/ipfilter/ipsd/Makefile @@ -1,5 +1,5 @@ # -# Copyright (C) 1993-1998 by Darren Reed. +# Copyright (C) 2012 by Darren Reed. # # See the IPFILTER.LICENCE file for details on licencing. # diff --git a/contrib/ipfilter/ipsd/ipsd.c b/contrib/ipfilter/ipsd/ipsd.c index ad3dfe20db99..ce51c1b796d0 100644 --- a/contrib/ipfilter/ipsd/ipsd.c +++ b/contrib/ipfilter/ipsd/ipsd.c @@ -34,7 +34,7 @@ #ifndef lint static const char sccsid[] = "@(#)ipsd.c 1.3 12/3/95 (C)1995 Darren Reed"; -static const char rcsid[] = "@(#)$Id: ipsd.c,v 2.2 2001/06/09 17:09:25 darrenr Exp $"; +static const char rcsid[] = "@(#)$Id$"; #endif extern char *optarg; @@ -66,7 +66,7 @@ int writes = 0; int ipcmp(sh1, sh2) -sdhit_t *sh1, *sh2; + sdhit_t *sh1, *sh2; { return sh1->sh_ip.s_addr - sh2->sh_ip.s_addr; } @@ -77,9 +77,9 @@ sdhit_t *sh1, *sh2; * port. */ int findhit(ihp, src, dport) -ipsd_t *ihp; -struct in_addr src; -u_short dport; + ipsd_t *ihp; + struct in_addr src; + u_short dport; { int i, j, k; sdhit_t *sh; @@ -110,8 +110,8 @@ u_short dport; * interested in. */ int detect(ip, tcp) -ip_t *ip; -tcphdr_t *tcp; + ip_t *ip; + tcphdr_t *tcp; { ipsd_t *ihp; sdhit_t *sh; @@ -179,7 +179,7 @@ waiter() * Write statistics out to a file */ writestats(nwrites) -int nwrites; + int nwrites; { ipsd_t **ipsd, *ips; char fname[32]; @@ -219,7 +219,7 @@ void writenow() void usage(prog) -char *prog; + char *prog; { fprintf(stderr, "Usage: %s [-d device]\n", prog); exit(1); @@ -227,7 +227,7 @@ char *prog; void detecthits(fd, writecount) -int fd, writecount; + int fd, writecount; { struct in_addr ip; int hits = 0; @@ -243,8 +243,8 @@ int fd, writecount; main(argc, argv) -int argc; -char *argv[]; + int argc; + char *argv[]; { char *name = argv[0], *dev = NULL; int fd, writeafter = 10000, angelic = 0, c; diff --git a/contrib/ipfilter/ipsd/ipsdr.c b/contrib/ipfilter/ipsd/ipsdr.c index 5a907061c631..e1c0c0aebc95 100644 --- a/contrib/ipfilter/ipsd/ipsdr.c +++ b/contrib/ipfilter/ipsd/ipsdr.c @@ -35,7 +35,7 @@ #ifndef lint static const char sccsid[] = "@(#)ipsdr.c 1.3 12/3/95 (C)1995 Darren Reed"; -static const char rcsid[] = "@(#)$Id: ipsdr.c,v 2.2 2001/06/09 17:09:25 darrenr Exp $"; +static const char rcsid[] = "@(#)$Id$"; #endif extern char *optarg; @@ -57,21 +57,21 @@ int pkts; int ipcmp(sh1, sh2) -sdhit_t *sh1, *sh2; + sdhit_t *sh1, *sh2; { return sh1->sh_ip.s_addr - sh2->sh_ip.s_addr; } int ssipcmp(sh1, sh2) -ipss_t *sh1, *sh2; + ipss_t *sh1, *sh2; { return sh1->ss_ip.s_addr - sh2->ss_ip.s_addr; } int countpbits(num) -u_long num; + u_long num; { int i, j; @@ -87,9 +87,9 @@ u_long num; * port. */ int findhit(ihp, src, dport) -ipsd_t *ihp; -struct in_addr src; -u_short dport; + ipsd_t *ihp; + struct in_addr src; + u_short dport; { int i, j, k; sdhit_t *sh; @@ -120,9 +120,9 @@ u_short dport; * interested in. */ int detect(srcip, dport, date) -struct in_addr srcip; -u_short dport; -time_t date; + struct in_addr srcip; + u_short dport; + time_t date; { ipsd_t *ihp; sdhit_t *sh; @@ -181,7 +181,7 @@ setuphits() * Write statistics out to a file */ addfile(file) -char *file; + char *file; { ipsd_t ipsd, *ips = &ipsd; sdhit_t hit, *hp; @@ -209,7 +209,7 @@ char *file; readfiles(dir) -char *dir; + char *dir; { struct direct **d; int i, j; @@ -226,8 +226,8 @@ char *dir; void printreport(ss, num) -ipss_t *ss; -int num; + ipss_t *ss; + int num; { struct in_addr ip; ipss_t *sp; @@ -301,8 +301,8 @@ collectips() main(argc, argv) -int argc; -char *argv[]; + int argc; + char *argv[]; { char c, *name = argv[0], *dir = NULL; int fd; diff --git a/contrib/ipfilter/ipsd/linux.h b/contrib/ipfilter/ipsd/linux.h index 88eb67aa4cbb..f00ea53605df 100644 --- a/contrib/ipfilter/ipsd/linux.h +++ b/contrib/ipfilter/ipsd/linux.h @@ -1,7 +1,7 @@ /* $FreeBSD$ */ /* - * Copyright (C) 1997-1998 by Darren Reed. + * Copyright (C) 2012 by Darren Reed. * * See the IPFILTER.LICENCE file for details on licencing. * diff --git a/contrib/ipfilter/ipsd/sbpf.c b/contrib/ipfilter/ipsd/sbpf.c index a724ba5dbfeb..74ba1971b85a 100644 --- a/contrib/ipfilter/ipsd/sbpf.c +++ b/contrib/ipfilter/ipsd/sbpf.c @@ -68,7 +68,7 @@ static u_int bufsize = 32768, timeout = 1; int ack_recv(ep) -char *ep; + char *ep; { struct tcpiphdr tip; tcphdr_t *tcp; @@ -89,8 +89,8 @@ char *ep; int readloop(fd, port, dst) -int fd, port; -struct in_addr dst; + int fd, port; + struct in_addr dst; { register u_char *bp, *cp, *bufend; register struct bpf_hdr *bh; @@ -119,8 +119,8 @@ struct in_addr dst; } int initdevice(device, tout) -char *device; -int tout; + char *device; + int tout; { struct bpf_program prog; struct bpf_version bv; diff --git a/contrib/ipfilter/ipsd/sdlpi.c b/contrib/ipfilter/ipsd/sdlpi.c index b7515f1dbac0..00c197bdfb77 100644 --- a/contrib/ipfilter/ipsd/sdlpi.c +++ b/contrib/ipfilter/ipsd/sdlpi.c @@ -60,7 +60,7 @@ void nullbell() int ack_recv(ep) -char *ep; + char *ep; { struct tcpiphdr tip; tcphdr_t *tcp; @@ -80,8 +80,8 @@ char *ep; int readloop(fd, port, dst) -int fd, port; -struct in_addr dst; + int fd, port; + struct in_addr dst; { static u_char buf[BUFSPACE]; register u_char *bp, *cp, *bufend; @@ -145,8 +145,8 @@ struct in_addr dst; } int initdevice(device, tout) -char *device; -int tout; + char *device; + int tout; { struct strioctl si; struct timeval to; diff --git a/contrib/ipfilter/ipsd/slinux.c b/contrib/ipfilter/ipsd/slinux.c index c0847951cd66..95ad8e537b3e 100644 --- a/contrib/ipfilter/ipsd/slinux.c +++ b/contrib/ipfilter/ipsd/slinux.c @@ -43,7 +43,7 @@ static char *eth_dev = NULL; int ack_recv(bp) -char *bp; + char *bp; { struct tcpip tip; tcphdr_t *tcp; @@ -61,8 +61,8 @@ char *bp; void readloop(fd, port, dst) -int fd, port; -struct in_addr dst; + int fd, port; + struct in_addr dst; { static u_char buf[BUFSPACE]; struct sockaddr dest; @@ -102,8 +102,8 @@ struct in_addr dst; } int initdevice(dev, tout) -char *dev; -int tout; + char *dev; + int tout; { int fd; diff --git a/contrib/ipfilter/ipsd/snit.c b/contrib/ipfilter/ipsd/snit.c index 0d5a52a1cee4..855afd53bee8 100644 --- a/contrib/ipfilter/ipsd/snit.c +++ b/contrib/ipfilter/ipsd/snit.c @@ -55,7 +55,7 @@ static int timeout; int ack_recv(ep) -char *ep; + char *ep; { struct tcpiphdr tip; struct tcphdr *tcp; @@ -74,8 +74,8 @@ char *ep; int readloop(fd, dst) -int fd; -struct in_addr dst; + int fd; + struct in_addr dst; { static u_char buf[BUFSPACE]; register u_char *bp, *cp, *bufend; @@ -114,8 +114,8 @@ struct in_addr dst; } int initdevice(device, tout) -char *device; -int tout; + char *device; + int tout; { struct strioctl si; struct timeval to; diff --git a/contrib/ipfilter/ipsend/.cvsignore b/contrib/ipfilter/ipsend/.cvsignore deleted file mode 100644 index b7aea24eb881..000000000000 --- a/contrib/ipfilter/ipsend/.cvsignore +++ /dev/null @@ -1,3 +0,0 @@ -ipsend -ipresend -iptest diff --git a/contrib/ipfilter/ipsend/44arp.c b/contrib/ipfilter/ipsend/44arp.c index 3fbafcc6116f..9033ab9a64ba 100644 --- a/contrib/ipfilter/ipsend/44arp.c +++ b/contrib/ipfilter/ipsend/44arp.c @@ -13,9 +13,6 @@ #endif #include #include -#if defined(__FreeBSD__) -# include "radix_ipf.h" -#endif #ifndef __osf__ # include #endif @@ -44,7 +41,7 @@ * (4 bytes) */ int resolve(host, address) -char *host, *address; + char *host, *address; { struct hostent *hp; u_long add; @@ -66,7 +63,7 @@ char *host, *address; int arp(addr, eaddr) -char *addr, *eaddr; + char *addr, *eaddr; { int mib[6]; size_t needed; diff --git a/contrib/ipfilter/ipsend/Makefile b/contrib/ipfilter/ipsend/Makefile index ed3a51e45370..34485efce0d6 100644 --- a/contrib/ipfilter/ipsend/Makefile +++ b/contrib/ipfilter/ipsend/Makefile @@ -1,5 +1,5 @@ # -# Copyright (C) 1993-1998 by Darren Reed. +# Copyright (C) 2012 by Darren Reed. # # See the IPFILTER.LICENCE file for details on licencing. # diff --git a/contrib/ipfilter/ipsend/README b/contrib/ipfilter/ipsend/README deleted file mode 100644 index 198556d834fb..000000000000 --- a/contrib/ipfilter/ipsend/README +++ /dev/null @@ -1,8 +0,0 @@ - -This distribution contains *ONLY* the code required to build the 'ipsend' -directory of programs (including man pages) found in the IP Filter package: -http://coombs.anu.edu.au/~avalon/ip-filter.html - -Patches, bugs, etc, please send to: - -darrenr@pobox.com diff --git a/contrib/ipfilter/ipsend/arp.c b/contrib/ipfilter/ipsend/arp.c index 8670bda76b46..58a1523e5db5 100644 --- a/contrib/ipfilter/ipsend/arp.c +++ b/contrib/ipfilter/ipsend/arp.c @@ -7,7 +7,7 @@ */ #if !defined(lint) static const char sccsid[] = "@(#)arp.c 1.4 1/11/96 (C)1995 Darren Reed"; -static const char rcsid[] = "@(#)$Id: arp.c,v 2.8.2.2 2007/02/17 12:41:50 darrenr Exp $"; +static const char rcsid[] = "@(#)$Id$"; #endif #include #include @@ -17,9 +17,6 @@ static const char rcsid[] = "@(#)$Id: arp.c,v 2.8.2.2 2007/02/17 12:41:50 darren #include #include #include -#ifdef __osf__ -# include "radix_ipf_local.h" -#endif #include #include #ifndef ultrix @@ -42,7 +39,7 @@ static const char rcsid[] = "@(#)$Id: arp.c,v 2.8.2.2 2007/02/17 12:41:50 darren * (4 bytes) */ int resolve(host, address) -char *host, *address; + char *host, *address; { struct hostent *hp; u_long add; @@ -68,8 +65,8 @@ char *host, *address; * some BSD program, I cant remember which. */ int arp(ip, ether) -char *ip; -char *ether; + char *ip; + char *ether; { static int sfd = -1; static char ethersave[6], ipsave[4]; diff --git a/contrib/ipfilter/ipsend/dlcommon.c b/contrib/ipfilter/ipsend/dlcommon.c index c6b6e8a4858f..55bc9423ab15 100644 --- a/contrib/ipfilter/ipsend/dlcommon.c +++ b/contrib/ipfilter/ipsend/dlcommon.c @@ -32,18 +32,18 @@ typedef unsigned long ulong; #define CASERET(s) case s: return ("s") -char *dlprim(); -char *dlstate(); -char *dlerrno(); -char *dlpromisclevel(); -char *dlservicemode(); -char *dlstyle(); -char *dlmactype(); + char *dlprim(); + char *dlstate(); + char *dlerrno(); + char *dlpromisclevel(); + char *dlservicemode(); + char *dlstyle(); + char *dlmactype(); void dlinforeq(fd) -int fd; + int fd; { dl_info_req_t info_req; struct strbuf ctl; @@ -63,8 +63,8 @@ int fd; void dlinfoack(fd, bufp) -int fd; -char *bufp; + int fd; + char *bufp; { union DL_primitives *dlp; struct strbuf ctl; @@ -92,8 +92,8 @@ char *bufp; void dlattachreq(fd, ppa) -int fd; -u_long ppa; + int fd; + u_long ppa; { dl_attach_req_t attach_req; struct strbuf ctl; @@ -114,9 +114,9 @@ u_long ppa; void dlenabmultireq(fd, addr, length) -int fd; -char *addr; -int length; + int fd; + char *addr; + int length; { long buf[MAXDLBUF]; union DL_primitives *dlp; @@ -143,9 +143,9 @@ int length; void dldisabmultireq(fd, addr, length) -int fd; -char *addr; -int length; + int fd; + char *addr; + int length; { long buf[MAXDLBUF]; union DL_primitives *dlp; @@ -172,8 +172,8 @@ int length; void dlpromisconreq(fd, level) -int fd; -u_long level; + int fd; + u_long level; { dl_promiscon_req_t promiscon_req; struct strbuf ctl; @@ -195,8 +195,8 @@ u_long level; void dlpromiscoff(fd, level) -int fd; -u_long level; + int fd; + u_long level; { dl_promiscoff_req_t promiscoff_req; struct strbuf ctl; @@ -217,8 +217,8 @@ u_long level; void dlphysaddrreq(fd, addrtype) -int fd; -u_long addrtype; + int fd; + u_long addrtype; { dl_phys_addr_req_t phys_addr_req; struct strbuf ctl; @@ -239,9 +239,9 @@ u_long addrtype; void dlsetphysaddrreq(fd, addr, length) -int fd; -char *addr; -int length; + int fd; + char *addr; + int length; { long buf[MAXDLBUF]; union DL_primitives *dlp; @@ -268,7 +268,7 @@ int length; void dldetachreq(fd) -int fd; + int fd; { dl_detach_req_t detach_req; struct strbuf ctl; @@ -288,12 +288,12 @@ int fd; void dlbindreq(fd, sap, max_conind, service_mode, conn_mgmt, xidtest) -int fd; -u_long sap; -u_long max_conind; -u_long service_mode; -u_long conn_mgmt; -u_long xidtest; + int fd; + u_long sap; + u_long max_conind; + u_long service_mode; + u_long conn_mgmt; + u_long xidtest; { dl_bind_req_t bind_req; struct strbuf ctl; @@ -318,12 +318,12 @@ u_long xidtest; void dlunitdatareq(fd, addrp, addrlen, minpri, maxpri, datap, datalen) -int fd; -u_char *addrp; -int addrlen; -u_long minpri, maxpri; -u_char *datap; -int datalen; + int fd; + u_char *addrp; + int addrlen; + u_long minpri, maxpri; + u_char *datap; + int datalen; { long buf[MAXDLBUF]; union DL_primitives *dlp; @@ -353,7 +353,7 @@ int datalen; void dlunbindreq(fd) -int fd; + int fd; { dl_unbind_req_t unbind_req; struct strbuf ctl; @@ -373,8 +373,8 @@ int fd; void dlokack(fd, bufp) -int fd; -char *bufp; + int fd; + char *bufp; { union DL_primitives *dlp; struct strbuf ctl; @@ -402,8 +402,8 @@ char *bufp; void dlerrorack(fd, bufp) -int fd; -char *bufp; + int fd; + char *bufp; { union DL_primitives *dlp; struct strbuf ctl; @@ -431,8 +431,8 @@ char *bufp; void dlbindack(fd, bufp) -int fd; -char *bufp; + int fd; + char *bufp; { union DL_primitives *dlp; struct strbuf ctl; @@ -457,8 +457,8 @@ char *bufp; void dlphysaddrack(fd, bufp) -int fd; -char *bufp; + int fd; + char *bufp; { union DL_primitives *dlp; struct strbuf ctl; @@ -488,10 +488,10 @@ sigalrm() } strgetmsg(fd, ctlp, datap, flagsp, caller) -int fd; -struct strbuf *ctlp, *datap; -int *flagsp; -char *caller; + int fd; + struct strbuf *ctlp, *datap; + int *flagsp; + char *caller; { int rc; static char errmsg[80]; @@ -540,8 +540,8 @@ char *caller; } expecting(prim, dlp) -int prim; -union DL_primitives *dlp; + int prim; + union DL_primitives *dlp; { if (dlp->dl_primitive != (u_long)prim) { printdlprim(dlp); @@ -555,7 +555,7 @@ union DL_primitives *dlp; * Print any DLPI msg in human readable format. */ printdlprim(dlp) -union DL_primitives *dlp; + union DL_primitives *dlp; { switch (dlp->dl_primitive) { case DL_INFO_REQ: @@ -659,13 +659,13 @@ union DL_primitives *dlp; /* ARGSUSED */ printdlinforeq(dlp) -union DL_primitives *dlp; + union DL_primitives *dlp; { (void) printf("DL_INFO_REQ\n"); } printdlinfoack(dlp) -union DL_primitives *dlp; + union DL_primitives *dlp; { u_char addr[MAXDLADDR]; u_char brdcst[MAXDLADDR]; @@ -702,21 +702,21 @@ union DL_primitives *dlp; } printdlattachreq(dlp) -union DL_primitives *dlp; + union DL_primitives *dlp; { (void) printf("DL_ATTACH_REQ: ppa %d\n", dlp->attach_req.dl_ppa); } printdlokack(dlp) -union DL_primitives *dlp; + union DL_primitives *dlp; { (void) printf("DL_OK_ACK: correct_primitive %s\n", dlprim(dlp->ok_ack.dl_correct_primitive)); } printdlerrorack(dlp) -union DL_primitives *dlp; + union DL_primitives *dlp; { (void) printf("DL_ERROR_ACK: error_primitive %s errno %s unix_errno %d: %s\n", dlprim(dlp->error_ack.dl_error_primitive), @@ -726,7 +726,7 @@ union DL_primitives *dlp; } printdlenabmultireq(dlp) -union DL_primitives *dlp; + union DL_primitives *dlp; { u_char addr[MAXDLADDR]; @@ -740,7 +740,7 @@ union DL_primitives *dlp; } printdldisabmultireq(dlp) -union DL_primitives *dlp; + union DL_primitives *dlp; { u_char addr[MAXDLADDR]; @@ -754,28 +754,28 @@ union DL_primitives *dlp; } printdlpromisconreq(dlp) -union DL_primitives *dlp; + union DL_primitives *dlp; { (void) printf("DL_PROMISCON_REQ: level %s\n", dlpromisclevel(dlp->promiscon_req.dl_level)); } printdlpromiscoffreq(dlp) -union DL_primitives *dlp; + union DL_primitives *dlp; { (void) printf("DL_PROMISCOFF_REQ: level %s\n", dlpromisclevel(dlp->promiscoff_req.dl_level)); } printdlphysaddrreq(dlp) -union DL_primitives *dlp; + union DL_primitives *dlp; { (void) printf("DL_PHYS_ADDR_REQ: addr_type 0x%x\n", dlp->physaddr_req.dl_addr_type); } printdlphysaddrack(dlp) -union DL_primitives *dlp; + union DL_primitives *dlp; { u_char addr[MAXDLADDR]; @@ -789,7 +789,7 @@ union DL_primitives *dlp; } printdlsetphysaddrreq(dlp) -union DL_primitives *dlp; + union DL_primitives *dlp; { u_char addr[MAXDLADDR]; @@ -804,13 +804,13 @@ union DL_primitives *dlp; /* ARGSUSED */ printdldetachreq(dlp) -union DL_primitives *dlp; + union DL_primitives *dlp; { (void) printf("DL_DETACH_REQ\n"); } printdlbindreq(dlp) -union DL_primitives *dlp; + union DL_primitives *dlp; { (void) printf("DL_BIND_REQ: sap %d max_conind %d\n", dlp->bind_req.dl_sap, @@ -822,7 +822,7 @@ union DL_primitives *dlp; } printdlbindack(dlp) -union DL_primitives *dlp; + union DL_primitives *dlp; { u_char addr[MAXDLADDR]; @@ -841,13 +841,13 @@ union DL_primitives *dlp; /* ARGSUSED */ printdlunbindreq(dlp) -union DL_primitives *dlp; + union DL_primitives *dlp; { (void) printf("DL_UNBIND_REQ\n"); } printdlsubsbindreq(dlp) -union DL_primitives *dlp; + union DL_primitives *dlp; { u_char sap[MAXDLADDR]; @@ -861,7 +861,7 @@ union DL_primitives *dlp; } printdlsubsbindack(dlp) -union DL_primitives *dlp; + union DL_primitives *dlp; { u_char sap[MAXDLADDR]; @@ -875,7 +875,7 @@ union DL_primitives *dlp; } printdlsubsunbindreq(dlp) -union DL_primitives *dlp; + union DL_primitives *dlp; { u_char sap[MAXDLADDR]; @@ -889,7 +889,7 @@ union DL_primitives *dlp; } printdlunitdatareq(dlp) -union DL_primitives *dlp; + union DL_primitives *dlp; { u_char addr[MAXDLADDR]; @@ -906,7 +906,7 @@ union DL_primitives *dlp; } printdlunitdataind(dlp) -union DL_primitives *dlp; + union DL_primitives *dlp; { u_char dest[MAXDLADDR]; u_char src[MAXDLADDR]; @@ -929,7 +929,7 @@ union DL_primitives *dlp; } printdluderrorind(dlp) -union DL_primitives *dlp; + union DL_primitives *dlp; { u_char addr[MAXDLADDR]; @@ -946,7 +946,7 @@ union DL_primitives *dlp; } printdltestreq(dlp) -union DL_primitives *dlp; + union DL_primitives *dlp; { u_char addr[MAXDLADDR]; @@ -961,7 +961,7 @@ union DL_primitives *dlp; } printdltestind(dlp) -union DL_primitives *dlp; + union DL_primitives *dlp; { u_char dest[MAXDLADDR]; u_char src[MAXDLADDR]; @@ -983,7 +983,7 @@ union DL_primitives *dlp; } printdltestres(dlp) -union DL_primitives *dlp; + union DL_primitives *dlp; { u_char dest[MAXDLADDR]; @@ -998,7 +998,7 @@ union DL_primitives *dlp; } printdltestcon(dlp) -union DL_primitives *dlp; + union DL_primitives *dlp; { u_char dest[MAXDLADDR]; u_char src[MAXDLADDR]; @@ -1020,7 +1020,7 @@ union DL_primitives *dlp; } printdlxidreq(dlp) -union DL_primitives *dlp; + union DL_primitives *dlp; { u_char dest[MAXDLADDR]; @@ -1035,7 +1035,7 @@ union DL_primitives *dlp; } printdlxidind(dlp) -union DL_primitives *dlp; + union DL_primitives *dlp; { u_char dest[MAXDLADDR]; u_char src[MAXDLADDR]; @@ -1057,7 +1057,7 @@ union DL_primitives *dlp; } printdlxidres(dlp) -union DL_primitives *dlp; + union DL_primitives *dlp; { u_char dest[MAXDLADDR]; @@ -1072,7 +1072,7 @@ union DL_primitives *dlp; } printdlxidcon(dlp) -union DL_primitives *dlp; + union DL_primitives *dlp; { u_char dest[MAXDLADDR]; u_char src[MAXDLADDR]; @@ -1094,7 +1094,7 @@ union DL_primitives *dlp; } printdludqosreq(dlp) -union DL_primitives *dlp; + union DL_primitives *dlp; { (void) printf("DL_UDQOS_REQ: qos_length %d qos_offset %d\n", dlp->udqos_req.dl_qos_length, @@ -1105,9 +1105,9 @@ union DL_primitives *dlp; * Return string. */ addrtostring(addr, length, s) -u_char *addr; -u_long length; -u_char *s; + u_char *addr; + u_long length; + u_char *s; { int i; @@ -1123,8 +1123,8 @@ u_char *s; * Return length */ stringtoaddr(sp, addr) -char *sp; -char *addr; + char *sp; + char *addr; { int n = 0; char *p; @@ -1140,14 +1140,14 @@ char *addr; n++; p = NULL; } - + return (n); } static char hexnibble(c) -char c; + char c; { static char hextab[] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', @@ -1159,7 +1159,7 @@ char c; char* dlprim(prim) -u_long prim; + u_long prim; { static char primbuf[80]; @@ -1200,7 +1200,7 @@ u_long prim; char* dlstate(state) -u_long state; + u_long state; { static char statebuf[80]; @@ -1234,7 +1234,7 @@ u_long state; char* dlerrno(errno) -u_long errno; + u_long errno; { static char errnobuf[80]; @@ -1276,7 +1276,7 @@ u_long errno; char* dlpromisclevel(level) -u_long level; + u_long level; { static char levelbuf[80]; @@ -1292,7 +1292,7 @@ u_long level; char* dlservicemode(servicemode) -u_long servicemode; + u_long servicemode; { static char servicemodebuf[80]; @@ -1309,7 +1309,7 @@ u_long servicemode; char* dlstyle(style) -long style; + long style; { static char stylebuf[80]; @@ -1324,7 +1324,7 @@ long style; char* dlmactype(media) -u_long media; + u_long media; { static char mediabuf[80]; @@ -1345,8 +1345,8 @@ u_long media; /*VARARGS1*/ err(fmt, a1, a2, a3, a4) -char *fmt; -char *a1, *a2, *a3, *a4; + char *fmt; + char *a1, *a2, *a3, *a4; { (void) fprintf(stderr, fmt, a1, a2, a3, a4); (void) fprintf(stderr, "\n"); @@ -1354,18 +1354,18 @@ char *a1, *a2, *a3, *a4; } syserr(s) -char *s; + char *s; { (void) perror(s); exit(1); } strioctl(fd, cmd, timout, len, dp) -int fd; -int cmd; -int timout; -int len; -char *dp; + int fd; + int cmd; + int timout; + int len; + char *dp; { struct strioctl sioc; int rc; diff --git a/contrib/ipfilter/ipsend/hpux.c b/contrib/ipfilter/ipsend/hpux.c deleted file mode 100644 index 9cc72995f26b..000000000000 --- a/contrib/ipfilter/ipsend/hpux.c +++ /dev/null @@ -1,114 +0,0 @@ -/* $FreeBSD$ */ - -/* - * (C)opyright 1997-1998 Darren Reed. (from tcplog) - * - * Redistribution and use in source and binary forms are permitted - * provided that this notice is preserved and due credit is given - * to the original author and the contributors. - */ -#include -#include -#include -#include -#include -#include -#include -#include -#include - - -int initdevice(device, sport, tout) -char *device; -int sport, tout; -{ - int fd; - - if ((fd = socket(AF_DLI, SOCK_RAW, 0)) == -1) - perror("socket"); - return fd; -} - - -/* - * output an IP packet onto a fd opened for /dev/bpf - */ -int sendip(fd, pkt, len) -int fd, len; -char *pkt; -{ - if (send(fd, pkt, len, 0) == -1) - { - perror("send"); - return -1; - } - - return len; -} - - -char *strdup(str) -char *str; -{ - char *s; - - if ((s = (char *)malloc(strlen(str) + 1))) - return strcpy(s, str); - return NULL; -} -/* - * (C)opyright 1997 Darren Reed. (from tcplog) - * - * Redistribution and use in source and binary forms are permitted - * provided that this notice is preserved and due credit is given - * to the original author and the contributors. - */ -#include -#include -#include -#include -#include -#include -#include -#include -#include - - -int initdevice(device, sport, tout) -char *device; -int sport, tout; -{ - int fd; - - if ((fd = socket(AF_DLI, SOCK_RAW, 0)) == -1) - perror("socket"); - return fd; -} - - -/* - * output an IP packet onto a fd opened for /dev/bpf - */ -int sendip(fd, pkt, len) -int fd, len; -char *pkt; -{ - if (send(fd, pkt, len, 0) == -1) - { - perror("send"); - return -1; - } - - return len; -} - - -char *strdup(str) -char *str; -{ - char *s; - - if ((s = (char *)malloc(strlen(str) + 1))) - return strcpy(s, str); - return NULL; -} diff --git a/contrib/ipfilter/ipsend/in_var.h b/contrib/ipfilter/ipsend/in_var.h deleted file mode 100644 index 3523f77051fc..000000000000 --- a/contrib/ipfilter/ipsend/in_var.h +++ /dev/null @@ -1,179 +0,0 @@ -/* $FreeBSD$ */ - -/* @(#)in_var.h 1.3 88/08/19 SMI; from UCB 7.1 6/5/86 */ - -/* - * Copyright (c) 1985, 1986 Regents of the University of California. - * All rights reserved. The Berkeley software License Agreement - * specifies the terms and conditions for redistribution. - */ - -/* - * Interface address, Internet version. One of these structures - * is allocated for each interface with an Internet address. - * The ifaddr structure contains the protocol-independent part - * of the structure and is assumed to be first. - */ - -#ifndef _netinet_in_var_h -#define _netinet_in_var_h - -struct in_ifaddr { - struct ifaddr ia_ifa; /* protocol-independent info */ -#define ia_addr ia_ifa.ifa_addr -#define ia_broadaddr ia_ifa.ifa_broadaddr -#define ia_dstaddr ia_ifa.ifa_dstaddr -#define ia_ifp ia_ifa.ifa_ifp - u_long ia_net; /* network number of interface */ - u_long ia_netmask; /* mask of net part */ - u_long ia_subnet; /* subnet number, including net */ - u_long ia_subnetmask; /* mask of net + subnet */ - struct in_addr ia_netbroadcast; /* broadcast addr for (logical) net */ - int ia_flags; - struct in_ifaddr *ia_next; /* next in list of internet addresses */ - struct in_multi *ia_multiaddrs;/* list of multicast addresses */ -}; -/* - * Given a pointer to an in_ifaddr (ifaddr), - * return a pointer to the addr as a sockadd_in. - */ -#define IA_SIN(ia) ((struct sockaddr_in *)(&((struct in_ifaddr *)ia)->ia_addr)) -/* - * ia_flags - */ -#define IFA_ROUTE 0x01 /* routing entry installed */ - -#ifdef KERNEL -struct in_ifaddr *in_ifaddr; -struct in_ifaddr *in_iaonnetof(); -struct ifqueue ipintrq; /* ip packet input queue */ -#endif - -#ifdef KERNEL -/* - * Macro for finding the interface (ifnet structure) corresponding to one - * of our IP addresses. - */ -#define INADDR_TO_IFP(addr, ifp) \ - /* struct in_addr addr; */ \ - /* struct ifnet *ifp; */ \ -{ \ - register struct in_ifaddr *ia; \ - \ - for (ia = in_ifaddr; \ - ia != NULL && IA_SIN(ia)->sin_addr.s_addr != (addr).s_addr; \ - ia = ia->ia_next); \ - (ifp) = (ia == NULL) ? NULL : ia->ia_ifp; \ -} - -/* - * Macro for finding the internet address structure (in_ifaddr) corresponding - * to a given interface (ifnet structure). - */ -#define IFP_TO_IA(ifp, ia) \ - /* struct ifnet *ifp; */ \ - /* struct in_ifaddr *ia; */ \ -{ \ - for ((ia) = in_ifaddr; \ - (ia) != NULL && (ia)->ia_ifp != (ifp); \ - (ia) = (ia)->ia_next); \ -} -#endif /* KERNEL */ - -/* - * Per-interface router version information is kept in this list. - * This information should be part of the ifnet structure but we don't wish - * to change that - as it might break a number of things - */ - -struct router_info { - struct ifnet *ifp; - int type; /* type of router which is querier on this interface */ - int time; /* # of slow timeouts since last old query */ - struct router_info *next; -}; - -/* - * Internet multicast address structure. There is one of these for each IP - * multicast group to which this host belongs on a given network interface. - * They are kept in a linked list, rooted in the interface's in_ifaddr - * structure. - */ - -struct in_multi { - struct in_addr inm_addr; /* IP multicast address */ - struct ifnet *inm_ifp; /* back pointer to ifnet */ - struct in_ifaddr *inm_ia; /* back pointer to in_ifaddr */ - u_int inm_refcount;/* no. membership claims by sockets */ - u_int inm_timer; /* IGMP membership report timer */ - struct in_multi *inm_next; /* ptr to next multicast address */ - u_int inm_state; /* state of the membership */ - struct router_info *inm_rti; /* router info*/ -}; - -#ifdef KERNEL -/* - * Structure used by macros below to remember position when stepping through - * all of the in_multi records. - */ -struct in_multistep { - struct in_ifaddr *i_ia; - struct in_multi *i_inm; -}; - -/* - * Macro for looking up the in_multi record for a given IP multicast address - * on a given interface. If no matching record is found, "inm" returns NULL. - */ -#define IN_LOOKUP_MULTI(addr, ifp, inm) \ - /* struct in_addr addr; */ \ - /* struct ifnet *ifp; */ \ - /* struct in_multi *inm; */ \ -{ \ - register struct in_ifaddr *ia; \ - \ - IFP_TO_IA((ifp), ia); \ - if (ia == NULL) \ - (inm) = NULL; \ - else \ - for ((inm) = ia->ia_multiaddrs; \ - (inm) != NULL && (inm)->inm_addr.s_addr != (addr).s_addr; \ - (inm) = inm->inm_next); \ -} - -/* - * Macro to step through all of the in_multi records, one at a time. - * The current position is remembered in "step", which the caller must - * provide. IN_FIRST_MULTI(), below, must be called to initialize "step" - * and get the first record. Both macros return a NULL "inm" when there - * are no remaining records. - */ -#define IN_NEXT_MULTI(step, inm) \ - /* struct in_multistep step; */ \ - /* struct in_multi *inm; */ \ -{ \ - if (((inm) = (step).i_inm) != NULL) { \ - (step).i_inm = (inm)->inm_next; \ - } \ - else while ((step).i_ia != NULL) { \ - (inm) = (step).i_ia->ia_multiaddrs; \ - (step).i_ia = (step).i_ia->ia_next; \ - if ((inm) != NULL) { \ - (step).i_inm = (inm)->inm_next; \ - break; \ - } \ - } \ -} - -#define IN_FIRST_MULTI(step, inm) \ - /* struct in_multistep step; */ \ - /* struct in_multi *inm; */ \ -{ \ - (step).i_ia = in_ifaddr; \ - (step).i_inm = NULL; \ - IN_NEXT_MULTI((step), (inm)); \ -} - -struct in_multi *in_addmulti(); -#endif /* KERNEL */ -#endif /*!_netinet_in_var_h*/ diff --git a/contrib/ipfilter/ipsend/ip.c b/contrib/ipfilter/ipsend/ip.c index 26a7a892bed3..74d164b6ee85 100644 --- a/contrib/ipfilter/ipsend/ip.c +++ b/contrib/ipfilter/ipsend/ip.c @@ -7,20 +7,18 @@ */ #if !defined(lint) static const char sccsid[] = "%W% %G% (C)1995"; -static const char rcsid[] = "@(#)$Id: ip.c,v 2.8.2.2 2007/02/17 12:41:51 darrenr Exp $"; +static const char rcsid[] = "@(#)$Id$"; #endif #include #include #include #include -#ifdef __osf__ -# include "radix_ipf_local.h" -#endif #include #include #include #include #ifndef linux +# include # include # include # if __FreeBSD_version >= 300000 @@ -39,8 +37,8 @@ static char *ipbuf = NULL, *ethbuf = NULL; u_short chksum(buf,len) -u_short *buf; -int len; + u_short *buf; + int len; { u_long sum = 0; int nwords = len >> 1; @@ -54,9 +52,9 @@ int len; int send_ether(nfd, buf, len, gwip) -int nfd, len; -char *buf; -struct in_addr gwip; + int nfd, len; + char *buf; + struct in_addr gwip; { static struct in_addr last_gw; static char last_arp[6] = { 0, 0, 0, 0, 0, 0}; @@ -89,10 +87,10 @@ struct in_addr gwip; /* */ int send_ip(nfd, mtu, ip, gwip, frag) -int nfd, mtu; -ip_t *ip; -struct in_addr gwip; -int frag; + int nfd, mtu; + ip_t *ip; + struct in_addr gwip; + int frag; { static struct in_addr last_gw, local_ip; static char local_arp[6] = { 0, 0, 0, 0, 0, 0}; @@ -250,9 +248,9 @@ int frag; * send a tcp packet. */ int send_tcp(nfd, mtu, ip, gwip) -int nfd, mtu; -ip_t *ip; -struct in_addr gwip; + int nfd, mtu; + ip_t *ip; + struct in_addr gwip; { static tcp_seq iss = 2; tcphdr_t *t, *t2; @@ -303,9 +301,9 @@ struct in_addr gwip; * send a udp packet. */ int send_udp(nfd, mtu, ip, gwip) -int nfd, mtu; -ip_t *ip; -struct in_addr gwip; + int nfd, mtu; + ip_t *ip; + struct in_addr gwip; { struct tcpiphdr *ti; int thlen; @@ -335,9 +333,9 @@ struct in_addr gwip; * send an icmp packet. */ int send_icmp(nfd, mtu, ip, gwip) -int nfd, mtu; -ip_t *ip; -struct in_addr gwip; + int nfd, mtu; + ip_t *ip; + struct in_addr gwip; { struct icmp *ic; @@ -351,9 +349,9 @@ struct in_addr gwip; int send_packet(nfd, mtu, ip, gwip) -int nfd, mtu; -ip_t *ip; -struct in_addr gwip; + int nfd, mtu; + ip_t *ip; + struct in_addr gwip; { switch (ip->ip_p) { diff --git a/contrib/ipfilter/ipsend/ip_var.h b/contrib/ipfilter/ipsend/ip_var.h deleted file mode 100644 index ab9813ec828e..000000000000 --- a/contrib/ipfilter/ipsend/ip_var.h +++ /dev/null @@ -1,125 +0,0 @@ -/* $FreeBSD$ */ - -/* @(#)ip_var.h 1.11 88/08/19 SMI; from UCB 7.1 6/5/86 */ - -/* - * Copyright (c) 1982, 1986 Regents of the University of California. - * All rights reserved. The Berkeley software License Agreement - * specifies the terms and conditions for redistribution. - */ - -/* - * Overlay for ip header used by other protocols (tcp, udp). - */ - -#ifndef _netinet_ip_var_h -#define _netinet_ip_var_h - -struct ipovly { - caddr_t ih_next, ih_prev; /* for protocol sequence q's */ - u_char ih_x1; /* (unused) */ - u_char ih_pr; /* protocol */ - short ih_len; /* protocol length */ - struct in_addr ih_src; /* source internet address */ - struct in_addr ih_dst; /* destination internet address */ -}; - -/* - * Ip reassembly queue structure. Each fragment - * being reassembled is attached to one of these structures. - * They are timed out after ipq_ttl drops to 0, and may also - * be reclaimed if memory becomes tight. - */ -struct ipq { - struct ipq *next,*prev; /* to other reass headers */ - u_char ipq_ttl; /* time for reass q to live */ - u_char ipq_p; /* protocol of this fragment */ - u_short ipq_id; /* sequence id for reassembly */ - struct ipasfrag *ipq_next,*ipq_prev; - /* to ip headers of fragments */ - struct in_addr ipq_src,ipq_dst; -}; - -/* - * Ip header, when holding a fragment. - * - * Note: ipf_next must be at same offset as ipq_next above - */ -struct ipasfrag { -#if defined(vax) || defined(i386) - u_char ip_hl:4, - ip_v:4; -#endif -#if defined(mc68000) || defined(sparc) - u_char ip_v:4, - ip_hl:4; -#endif - u_char ipf_mff; /* copied from (ip_off&IP_MF) */ - short ip_len; - u_short ip_id; - short ip_off; - u_char ip_ttl; - u_char ip_p; - u_short ip_sum; - struct ipasfrag *ipf_next; /* next fragment */ - struct ipasfrag *ipf_prev; /* previous fragment */ -}; - -/* - * Structure stored in mbuf in inpcb.ip_options - * and passed to ip_output when ip options are in use. - * The actual length of the options (including ipopt_dst) - * is in m_len. - */ -#define MAX_IPOPTLEN 40 - -struct ipoption { - struct in_addr ipopt_dst; /* first-hop dst if source routed */ - char ipopt_list[MAX_IPOPTLEN]; /* options proper */ -}; - -/* - * Structure stored in an mbuf attached to inpcb.ip_moptions and - * passed to ip_output when IP multicast options are in use. - */ -struct ip_moptions { - struct ifnet *imo_multicast_ifp; /* ifp for outgoing multicasts */ - u_char imo_multicast_ttl; /* TTL for outgoing multicasts */ - u_char imo_multicast_loop; /* 1 => hear sends if a member */ - u_short imo_num_memberships;/* no. memberships this socket */ - struct in_multi *imo_membership[IP_MAX_MEMBERSHIPS]; -#ifdef RSVP_ISI - long imo_multicast_vif; /* vif for outgoing multicasts */ -#endif /* RSVP_ISI */ -}; - -struct ipstat { - long ips_total; /* total packets received */ - long ips_badsum; /* checksum bad */ - long ips_tooshort; /* packet too short */ - long ips_toosmall; /* not enough data */ - long ips_badhlen; /* ip header length < data size */ - long ips_badlen; /* ip length < ip header length */ - long ips_fragments; /* fragments received */ - long ips_fragdropped; /* frags dropped (dups, out of space) */ - long ips_fragtimeout; /* fragments timed out */ - long ips_forward; /* packets forwarded */ - long ips_cantforward; /* packets rcvd for unreachable dest */ - long ips_redirectsent; /* packets forwarded on same net */ -}; - -#ifdef KERNEL -/* flags passed to ip_output as last parameter */ -#define IP_FORWARDING 0x1 /* most of ip header exists */ -#define IP_MULTICASTOPTS 0x2 /* multicast opts present */ -#define IP_ROUTETOIF SO_DONTROUTE /* bypass routing tables */ -#define IP_ALLOWBROADCAST SO_BROADCAST /* can send broadcast packets */ - -struct ipstat ipstat; -struct ipq ipq; /* ip reass. queue */ -u_short ip_id; /* ip packet ctr, for ids */ - -struct mbuf *ip_srcroute(); -#endif - -#endif /*!_netinet_ip_var_h*/ diff --git a/contrib/ipfilter/ipsend/ipresend.c b/contrib/ipfilter/ipsend/ipresend.c index 050aecf2093c..7520a0e5bf55 100644 --- a/contrib/ipfilter/ipsend/ipresend.c +++ b/contrib/ipfilter/ipsend/ipresend.c @@ -8,7 +8,7 @@ */ #if !defined(lint) static const char sccsid[] = "%W% %G% (C)1995 Darren Reed"; -static const char rcsid[] = "@(#)$Id: ipresend.c,v 2.4 2004/01/08 13:34:31 darrenr Exp $"; +static const char rcsid[] = "@(#)$Id$"; #endif #include #include @@ -32,7 +32,7 @@ static const char rcsid[] = "@(#)$Id: ipresend.c,v 2.4 2004/01/08 13:34:31 darre extern char *optarg; extern int optind; #ifndef NO_IPF -extern struct ipread snoop, pcap, etherf, iphex, tcpd, iptext; +extern struct ipread pcap, iphex, iptext; #endif int opts = 0; @@ -68,7 +68,7 @@ int main __P((int, char **)); static void usage(prog) -char *prog; + char *prog; { fprintf(stderr, "Usage: %s [options] <-r filename|-R filename>\n\ \t\t-r filename\tsnoop data file to resend\n\ @@ -83,8 +83,8 @@ char *prog; int main(argc, argv) -int argc; -char **argv; + int argc; + char **argv; { struct in_addr gwip; struct ipread *ipr = NULL; @@ -115,21 +115,12 @@ char **argv; opts |= OPT_RAW; break; #ifndef NO_IPF - case 'E' : - ipr = ðerf; - break; case 'H' : ipr = &iphex; break; case 'P' : ipr = &pcap; break; - case 'S' : - ipr = &snoop; - break; - case 'T' : - ipr = &tcpd; - break; case 'X' : ipr = &iptext; break; diff --git a/contrib/ipfilter/ipsend/ipsend.5 b/contrib/ipfilter/ipsend/ipsend.5 index cd5842cbba18..fc8691198247 100644 --- a/contrib/ipfilter/ipsend/ipsend.5 +++ b/contrib/ipfilter/ipsend/ipsend.5 @@ -123,7 +123,7 @@ be adjusted to accommodate data or further protocol headers. sets the fragment offset field of the IP packet. Default is 0. .TP .B ttl -sets the time to live (TTL) field of the IP header. Default is 60. +sets the time to live (TTL) field of the IP header. Default is 60. .TP .B proto sets the protocol field of the IP header. The protocol can either be a diff --git a/contrib/ipfilter/ipsend/ipsend.c b/contrib/ipfilter/ipsend/ipsend.c index 06191ec054b9..3df5c071e2e3 100644 --- a/contrib/ipfilter/ipsend/ipsend.c +++ b/contrib/ipfilter/ipsend/ipsend.c @@ -6,7 +6,7 @@ */ #if !defined(lint) static const char sccsid[] = "@(#)ipsend.c 1.5 12/10/95 (C)1995 Darren Reed"; -static const char rcsid[] = "@(#)$Id: ipsend.c,v 2.8.2.3 2006/03/17 13:45:34 darrenr Exp $"; +static const char rcsid[] = "@(#)$Id$"; #endif #include #include @@ -67,7 +67,7 @@ int main __P((int, char **)); static void usage(prog) -char *prog; + char *prog; { fprintf(stderr, "Usage: %s [options] dest [flags]\n\ \toptions:\n\ @@ -96,8 +96,8 @@ char *prog; static void do_icmp(ip, args) -ip_t *ip; -char *args; + ip_t *ip; + char *args; { struct icmp *ic; char *s; @@ -147,10 +147,10 @@ char *args; int send_packets(dev, mtu, ip, gwip) -char *dev; -int mtu; -ip_t *ip; -struct in_addr gwip; + char *dev; + int mtu; + ip_t *ip; + struct in_addr gwip; { int wfd; @@ -193,8 +193,8 @@ udpcksum(ip_t *ip, struct udphdr *udp, int len) } int main(argc, argv) -int argc; -char **argv; + int argc; + char **argv; { FILE *langfile = NULL; struct in_addr gwip; diff --git a/contrib/ipfilter/ipsend/ipsend.h b/contrib/ipfilter/ipsend/ipsend.h index 91cfa6c085ed..75a0496e7f83 100644 --- a/contrib/ipfilter/ipsend/ipsend.h +++ b/contrib/ipfilter/ipsend/ipsend.h @@ -29,7 +29,9 @@ #ifdef linux #include #endif -#include "tcpip.h" +/* XXX: The following is needed by tcpip.h */ +#include +#include "netinet/tcpip.h" #include "ipt.h" extern int resolve __P((char *, char *)); diff --git a/contrib/ipfilter/ipsend/ipsopt.c b/contrib/ipfilter/ipsend/ipsopt.c index 10f132e6da9a..a2cc4d04aad1 100644 --- a/contrib/ipfilter/ipsend/ipsopt.c +++ b/contrib/ipfilter/ipsend/ipsopt.c @@ -1,14 +1,14 @@ /* $FreeBSD$ */ /* - * Copyright (C) 1995-1998 by Darren Reed. + * Copyright (C) 2012 by Darren Reed. * * See the IPFILTER.LICENCE file for details on licencing. * */ #if !defined(lint) static const char sccsid[] = "@(#)ipsopt.c 1.2 1/11/96 (C)1995 Darren Reed"; -static const char rcsid[] = "@(#)$Id: ipsopt.c,v 2.4.4.1 2004/03/23 12:58:05 darrenr Exp $"; +static const char rcsid[] = "@(#)$Id$"; #endif #include #include @@ -62,7 +62,7 @@ struct ipopt_names secnames[] = { u_short ipseclevel(slevel) -char *slevel; + char *slevel; { struct ipopt_names *so; @@ -79,10 +79,10 @@ char *slevel; int addipopt(op, io, len, class) -char *op; -struct ipopt_names *io; -int len; -char *class; + char *op; + struct ipopt_names *io; + int len; + char *class; { struct in_addr ipadr; int olen = len, srr = 0; @@ -150,8 +150,8 @@ char *class; u_32_t buildopts(cp, op, len) -char *cp, *op; -int len; + char *cp, *op; + int len; { struct ipopt_names *io; u_32_t msk = 0; diff --git a/contrib/ipfilter/ipsend/iptest.c b/contrib/ipfilter/ipsend/iptest.c index cc2ceb8ae2a1..c6cfb1c75a4a 100644 --- a/contrib/ipfilter/ipsend/iptest.c +++ b/contrib/ipfilter/ipsend/iptest.c @@ -8,7 +8,7 @@ */ #if !defined(lint) static const char sccsid[] = "%W% %G% (C)1995 Darren Reed"; -static const char rcsid[] = "@(#)$Id: iptest.c,v 2.6 2004/01/08 13:34:31 darrenr Exp $"; +static const char rcsid[] = "@(#)$Id$"; #endif #include #include @@ -63,7 +63,7 @@ int main __P((int, char **)); static void usage(prog) -char *prog; + char *prog; { fprintf(stderr, "Usage: %s [options] dest\n\ \toptions:\n\ @@ -85,8 +85,8 @@ char *prog; int main(argc, argv) -int argc; -char **argv; + int argc; + char **argv; { struct tcpiphdr *ti; struct in_addr gwip; diff --git a/contrib/ipfilter/ipsend/iptests.c b/contrib/ipfilter/ipsend/iptests.c index 22ef71f5fddc..0ca02db0b04d 100644 --- a/contrib/ipfilter/ipsend/iptests.c +++ b/contrib/ipfilter/ipsend/iptests.c @@ -1,14 +1,14 @@ /* $FreeBSD$ */ /* - * Copyright (C) 1993-1998 by Darren Reed. + * Copyright (C) 2012 by Darren Reed. * * See the IPFILTER.LICENCE file for details on licencing. * */ #if !defined(lint) static const char sccsid[] = "%W% %G% (C)1995 Darren Reed"; -static const char rcsid[] = "@(#)$Id: iptests.c,v 2.8.2.9 2007/09/13 07:19:34 darrenr Exp $"; +static const char rcsid[] = "@(#)$Id$"; #endif #include #include @@ -22,7 +22,7 @@ typedef int boolean_t; #endif #include #if !defined(__osf__) -# ifdef __NetBSD__ +# ifdef __NetBSD__ # include # include # endif @@ -52,8 +52,9 @@ typedef int boolean_t; #endif #if defined(solaris) # include +#else +# include #endif -#include #ifdef sun #include #include @@ -68,9 +69,6 @@ typedef int boolean_t; #ifdef __hpux # define _NET_ROUTE_INCLUDED #endif -#ifdef __osf__ -# include "radix_ipf_local.h" -#endif #include #if defined(linux) && (LINUX >= 0200) # include @@ -79,7 +77,9 @@ typedef int boolean_t; # if defined(__FreeBSD__) # include "radix_ipf.h" # endif -# include +# if !defined(solaris) +# include +# endif #else # define __KERNEL__ /* because there's a macro not wrapped by this */ # include /* in this file :-/ */ @@ -87,12 +87,6 @@ typedef int boolean_t; #include #include #include -#if !defined(linux) -# include -# if !defined(__hpux) -# include -# endif -#endif #if defined(__SVR4) || defined(__svr4__) || defined(__sgi) # include #endif @@ -103,6 +97,12 @@ typedef int boolean_t; #ifdef __hpux # undef _NET_ROUTE_INCLUDED #endif +#if !defined(linux) +# include +# if !defined(__hpux) && !defined(solaris) +# include +# endif +#endif #include "ipsend.h" #if !defined(linux) && !defined(__hpux) # include @@ -123,11 +123,11 @@ typedef int boolean_t; void ip_test1(dev, mtu, ip, gwip, ptest) -char *dev; -int mtu; -ip_t *ip; -struct in_addr gwip; -int ptest; + char *dev; + int mtu; + ip_t *ip; + struct in_addr gwip; + int ptest; { #ifdef USE_NANOSLEEP struct timespec ts; @@ -474,11 +474,11 @@ int ptest; void ip_test2(dev, mtu, ip, gwip, ptest) -char *dev; -int mtu; -ip_t *ip; -struct in_addr gwip; -int ptest; + char *dev; + int mtu; + ip_t *ip; + struct in_addr gwip; + int ptest; { #ifdef USE_NANOSLEEP struct timespec ts; @@ -570,11 +570,11 @@ int ptest; * test 3 (ICMP) */ void ip_test3(dev, mtu, ip, gwip, ptest) -char *dev; -int mtu; -ip_t *ip; -struct in_addr gwip; -int ptest; + char *dev; + int mtu; + ip_t *ip; + struct in_addr gwip; + int ptest; { static int ict1[10] = { 8, 9, 10, 13, 14, 15, 16, 17, 18, 0 }; static int ict2[8] = { 3, 9, 10, 13, 14, 17, 18, 0 }; @@ -771,11 +771,11 @@ int ptest; /* Perform test 4 (UDP) */ void ip_test4(dev, mtu, ip, gwip, ptest) -char *dev; -int mtu; -ip_t *ip; -struct in_addr gwip; -int ptest; + char *dev; + int mtu; + ip_t *ip; + struct in_addr gwip; + int ptest; { #ifdef USE_NANOSLEEP struct timespec ts; @@ -936,11 +936,11 @@ int ptest; /* Perform test 5 (TCP) */ void ip_test5(dev, mtu, ip, gwip, ptest) -char *dev; -int mtu; -ip_t *ip; -struct in_addr gwip; -int ptest; + char *dev; + int mtu; + ip_t *ip; + struct in_addr gwip; + int ptest; { #ifdef USE_NANOSLEEP struct timespec ts; @@ -1286,11 +1286,11 @@ int ptest; /* Perform test 6 (exhaust mbuf test) */ void ip_test6(dev, mtu, ip, gwip, ptest) -char *dev; -int mtu; -ip_t *ip; -struct in_addr gwip; -int ptest; + char *dev; + int mtu; + ip_t *ip; + struct in_addr gwip; + int ptest; { #ifdef USE_NANOSLEEP struct timespec ts; @@ -1368,11 +1368,11 @@ int ptest; static u_long tbuf[64]; void ip_test7(dev, mtu, ip, gwip, ptest) -char *dev; -int mtu; -ip_t *ip; -struct in_addr gwip; -int ptest; + char *dev; + int mtu; + ip_t *ip; + struct in_addr gwip; + int ptest; { ip_t *pip; #ifdef USE_NANOSLEEP diff --git a/contrib/ipfilter/ipsend/larp.c b/contrib/ipfilter/ipsend/larp.c index ccb70cc29368..5b79f7376a12 100644 --- a/contrib/ipfilter/ipsend/larp.c +++ b/contrib/ipfilter/ipsend/larp.c @@ -8,7 +8,7 @@ */ #if !defined(lint) static const char sccsid[] = "@(#)larp.c 1.1 8/19/95 (C)1995 Darren Reed"; -static const char rcsid[] = "@(#)$Id: larp.c,v 2.4 2003/12/01 02:01:16 darrenr Exp $"; +static const char rcsid[] = "@(#)$Id$"; #endif #include #include @@ -30,7 +30,7 @@ static const char rcsid[] = "@(#)$Id: larp.c,v 2.4 2003/12/01 02:01:16 darrenr E * (4 bytes) */ int resolve(host, address) -char *host, *address; + char *host, *address; { struct hostent *hp; u_long add; @@ -56,8 +56,8 @@ char *host, *address; * some BSD program, I cant remember which. */ int arp(ip, ether) -char *ip; -char *ether; + char *ip; + char *ether; { static int s = -1; struct arpreq ar; diff --git a/contrib/ipfilter/ipsend/linux.h b/contrib/ipfilter/ipsend/linux.h index a36d1bfb6a6a..e738f3ba426a 100644 --- a/contrib/ipfilter/ipsend/linux.h +++ b/contrib/ipfilter/ipsend/linux.h @@ -1,7 +1,7 @@ /* $FreeBSD$ */ /* - * Copyright (C) 1995-1998 by Darren Reed. + * Copyright (C) 2012 by Darren Reed. * * This code may be freely distributed as long as it retains this notice * and is not changed in any way. The author accepts no responsibility diff --git a/contrib/ipfilter/ipsend/lsock.c b/contrib/ipfilter/ipsend/lsock.c index a76bbbb15221..5cf2bf7ff3da 100644 --- a/contrib/ipfilter/ipsend/lsock.c +++ b/contrib/ipfilter/ipsend/lsock.c @@ -8,7 +8,7 @@ */ #if !defined(lint) static const char sccsid[] = "@(#)lsock.c 1.2 1/11/96 (C)1995 Darren Reed"; -static const char rcsid[] = "@(#)$Id: lsock.c,v 2.3.4.1 2006/03/17 13:45:34 darrenr Exp $"; +static const char rcsid[] = "@(#)$Id$"; #endif #include #include @@ -66,9 +66,9 @@ struct task_struct *proc; #endif int kmemcpy(buf, pos, n) -char *buf; -void *pos; -int n; + char *buf; + void *pos; + int n; { static int kfd = -1; @@ -150,8 +150,8 @@ struct task_struct *getproc() struct sock *find_tcp(fd, ti) -int fd; -struct tcpiphdr *ti; + int fd; + struct tcpiphdr *ti; { struct sock *s; struct inode *i; @@ -189,10 +189,10 @@ struct tcpiphdr *ti; } int do_socket(dev, mtu, ti, gwip) -char *dev; -int mtu; -struct tcpiphdr *ti; -struct in_addr gwip; + char *dev; + int mtu; + struct tcpiphdr *ti; + struct in_addr gwip; { struct sockaddr_in rsin, lsin; struct sock *s, sk; diff --git a/contrib/ipfilter/ipsend/resend.c b/contrib/ipfilter/ipsend/resend.c index b988e9b20d94..d113af38857e 100644 --- a/contrib/ipfilter/ipsend/resend.c +++ b/contrib/ipfilter/ipsend/resend.c @@ -8,15 +8,12 @@ */ #if !defined(lint) static const char sccsid[] = "@(#)resend.c 1.3 1/11/96 (C)1995 Darren Reed"; -static const char rcsid[] = "@(#)$Id: resend.c,v 2.8.2.3 2007/02/17 12:41:51 darrenr Exp $"; +static const char rcsid[] = "@(#)$Id$"; #endif #include #include #include #include -#ifdef __osf__ -# include "radix_ipf_local.h" -#endif #include #include #include @@ -38,12 +35,11 @@ static const char rcsid[] = "@(#)$Id: resend.c,v 2.8.2.3 2007/02/17 12:41:51 dar extern int opts; -static u_char pbuf[65536]; /* 1 big packet */ -void printpacket __P((ip_t *)); +void dumppacket __P((ip_t *)); -void printpacket(ip) -ip_t *ip; +void dumppacket(ip) + ip_t *ip; { tcphdr_t *t; int i, j; @@ -73,16 +69,17 @@ ip_t *ip; int ip_resend(dev, mtu, r, gwip, datain) -char *dev; -int mtu; -struct in_addr gwip; -struct ipread *r; -char *datain; + char *dev; + int mtu; + struct in_addr gwip; + struct ipread *r; + char *datain; { ether_header_t *eh; char dhost[6]; ip_t *ip; int fd, wfd = initdevice(dev, 5), len, i; + mb_t mb; if (wfd == -1) return -1; @@ -95,7 +92,7 @@ char *datain; if (fd < 0) exit(-1); - ip = (struct ip *)pbuf; + ip = (struct ip *)mb.mb_buf; eh = (ether_header_t *)malloc(sizeof(*eh)); if(!eh) { @@ -111,7 +108,7 @@ char *datain; return -2; } - while ((i = (*r->r_readip)((char *)pbuf, sizeof(pbuf), NULL, NULL)) > 0) + while ((i = (*r->r_readip)(&mb, NULL, NULL)) > 0) { if (!(opts & OPT_RAW)) { len = ntohs(ip->ip_len); @@ -131,9 +128,9 @@ char *datain; IP_HL(ip) << 2); bcopy(ip, (char *)(eh + 1), len); len += sizeof(*eh); - printpacket(ip); + dumppacket(ip); } else { - eh = (ether_header_t *)pbuf; + eh = (ether_header_t *)mb.mb_buf; len = i; } diff --git a/contrib/ipfilter/ipsend/sbpf.c b/contrib/ipfilter/ipsend/sbpf.c index 2b356b6ffd67..fcb66bc9ca2f 100644 --- a/contrib/ipfilter/ipsend/sbpf.c +++ b/contrib/ipfilter/ipsend/sbpf.c @@ -26,7 +26,8 @@ #include #include #include -#include +#include +#include #include #include @@ -44,7 +45,7 @@ #if !defined(lint) static const char sccsid[] = "@(#)sbpf.c 1.3 8/25/95 (C)1995 Darren Reed"; -static const char rcsid[] = "@(#)$Id: sbpf.c,v 2.5.4.1 2006/03/21 16:32:58 darrenr Exp $"; +static const char rcsid[] = "@(#)$Id$"; #endif /* @@ -55,8 +56,8 @@ static int bufsize = 0, timeout = 1; int initdevice(device, tout) -char *device; -int tout; + char *device; + int tout; { struct bpf_version bv; struct timeval to; @@ -139,9 +140,9 @@ int tout; * output an IP packet onto a fd opened for /dev/bpf */ int sendip(fd, pkt, len) -int fd, len; -char *pkt; -{ + int fd, len; + char *pkt; +{ if (write(fd, pkt, len) == -1) { perror("send"); diff --git a/contrib/ipfilter/ipsend/sdlpi.c b/contrib/ipfilter/ipsend/sdlpi.c index f48fd06bbc34..1aee2e4108c6 100644 --- a/contrib/ipfilter/ipsend/sdlpi.c +++ b/contrib/ipfilter/ipsend/sdlpi.c @@ -27,7 +27,6 @@ #endif #ifdef __osf__ # include -# include "radix_ipf_local.h" #else # include #endif @@ -49,7 +48,7 @@ #if !defined(lint) static const char sccsid[] = "@(#)sdlpi.c 1.3 10/30/95 (C)1995 Darren Reed"; -static const char rcsid[] = "@(#)$Id: sdlpi.c,v 2.8.2.2 2007/02/17 12:41:51 darrenr Exp $"; +static const char rcsid[] = "@(#)$Id$"; #endif #define CHUNKSIZE 8192 @@ -61,8 +60,8 @@ static const char rcsid[] = "@(#)$Id: sdlpi.c,v 2.8.2.2 2007/02/17 12:41:51 darr * interface are included in the header size. */ int initdevice(device, tout) -char *device; -int tout; + char *device; + int tout; { char devname[16], *s, buf[256]; int i, fd; @@ -136,9 +135,9 @@ int tout; * output an IP packet onto a fd opened for /dev/nit */ int sendip(fd, pkt, len) -int fd, len; -char *pkt; -{ + int fd, len; + char *pkt; +{ struct strbuf dbuf, *dp = &dbuf, *cp = NULL; int pri = 0; #ifdef DL_HP_RAWDLS diff --git a/contrib/ipfilter/ipsend/sirix.c b/contrib/ipfilter/ipsend/sirix.c index 5057c4f2c871..3b565b19220c 100644 --- a/contrib/ipfilter/ipsend/sirix.c +++ b/contrib/ipfilter/ipsend/sirix.c @@ -60,7 +60,7 @@ int initdevice(char *device, int tout) * output an IP packet */ int sendip(int fd, char *pkt, int len) -{ +{ struct sockaddr_raw sr; int srlen = sizeof(sr); struct ifreq ifr; diff --git a/contrib/ipfilter/ipsend/slinux.c b/contrib/ipfilter/ipsend/slinux.c index 7e37b3087f97..7405d5e503a5 100644 --- a/contrib/ipfilter/ipsend/slinux.c +++ b/contrib/ipfilter/ipsend/slinux.c @@ -30,7 +30,7 @@ #if !defined(lint) static const char sccsid[] = "@(#)slinux.c 1.2 8/25/95"; -static const char rcsid[] = "@(#)$Id: slinux.c,v 2.3 2001/06/09 17:09:26 darrenr Exp $"; +static const char rcsid[] = "@(#)$Id$"; #endif #define CHUNKSIZE 8192 @@ -46,8 +46,8 @@ static char *eth_dev = NULL; int initdevice(dev, spare) -char *dev; -int spare; + char *dev; + int spare; { int fd; @@ -66,8 +66,8 @@ int spare; * output an IP packet onto a fd opened for /dev/nit */ int sendip(fd, pkt, len) -int fd, len; -char *pkt; + int fd, len; + char *pkt; { struct sockaddr s; struct ifreq ifr; diff --git a/contrib/ipfilter/ipsend/snit.c b/contrib/ipfilter/ipsend/snit.c index 0ef7e5444841..0d75b4e616f5 100644 --- a/contrib/ipfilter/ipsend/snit.c +++ b/contrib/ipfilter/ipsend/snit.c @@ -41,7 +41,7 @@ #if !defined(lint) static const char sccsid[] = "@(#)snit.c 1.5 1/11/96 (C)1995 Darren Reed"; -static const char rcsid[] = "@(#)$Id: snit.c,v 2.3 2001/06/09 17:09:26 darrenr Exp $"; +static const char rcsid[] = "@(#)$Id$"; #endif #define CHUNKSIZE 8192 @@ -58,8 +58,8 @@ static int timeout; int initdevice(device, tout) -char *device; -int tout; + char *device; + int tout; { struct strioctl si; struct timeval to; @@ -115,9 +115,9 @@ int tout; * output an IP packet onto a fd opened for /dev/nit */ int sendip(fd, pkt, len) -int fd, len; -char *pkt; -{ + int fd, len; + char *pkt; +{ struct sockaddr sk, *sa = &sk; struct strbuf cbuf, *cp = &cbuf, dbuf, *dp = &dbuf; diff --git a/contrib/ipfilter/ipsend/sock.c b/contrib/ipfilter/ipsend/sock.c index dcff6ebbfcec..6d0f3dbac2bb 100644 --- a/contrib/ipfilter/ipsend/sock.c +++ b/contrib/ipfilter/ipsend/sock.c @@ -7,7 +7,7 @@ */ #if !defined(lint) static const char sccsid[] = "@(#)sock.c 1.2 1/11/96 (C)1995 Darren Reed"; -static const char rcsid[] = "@(#)$Id: sock.c,v 2.8.4.7 2007/09/13 07:19:34 darrenr Exp $"; +static const char rcsid[] = "@(#)$Id$"; #endif #include #include @@ -30,9 +30,8 @@ typedef int boolean_t; # include #endif #if !defined(__osf__) -# ifdef __NetBSD__ +# ifdef __NetBSD__ # include -# include # endif # ifdef __FreeBSD__ # define _WANT_FILE @@ -75,9 +74,6 @@ typedef int boolean_t; #include #include #include -#if defined(__FreeBSD__) -# include "radix_ipf.h" -#endif #ifndef __osf__ # include #endif @@ -123,9 +119,9 @@ static struct kinfo_proc *getproc __P((void)); int kmemcpy(buf, pos, n) -char *buf; -void *pos; -int n; + char *buf; + void *pos; + int n; { static int kfd = -1; off_t offset = (u_long)pos; @@ -203,8 +199,8 @@ static struct proc *getproc() struct tcpcb *find_tcp(fd, ti) -int fd; -struct tcpiphdr *ti; + int fd; + struct tcpiphdr *ti; { struct tcpcb *t; struct inpcb *i; @@ -294,8 +290,8 @@ static struct kinfo_proc *getproc() struct tcpcb *find_tcp(tfd, ti) -int tfd; -struct tcpiphdr *ti; + int tfd; + struct tcpiphdr *ti; { struct tcpcb *t; struct inpcb *i; @@ -390,10 +386,10 @@ struct tcpiphdr *ti; #endif /* BSD < 199301 */ int do_socket(dev, mtu, ti, gwip) -char *dev; -int mtu; -struct tcpiphdr *ti; -struct in_addr gwip; + char *dev; + int mtu; + struct tcpiphdr *ti; + struct in_addr gwip; { struct sockaddr_in rsin, lsin; struct tcpcb *t, tcb; diff --git a/contrib/ipfilter/ipsend/tcpip.h b/contrib/ipfilter/ipsend/tcpip.h deleted file mode 100644 index 34178931a978..000000000000 --- a/contrib/ipfilter/ipsend/tcpip.h +++ /dev/null @@ -1,86 +0,0 @@ -/* $FreeBSD$ */ - -/* - * Copyright (c) 1982, 1986, 1993 - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * @(#)tcpip.h 8.1 (Berkeley) 6/10/93 - * $Id: tcpip.h,v 2.2.2.3 2004/05/26 15:45:48 darrenr Exp $ - */ - -#ifndef _NETINET_TCPIP_H_ -#define _NETINET_TCPIP_H_ - -# if defined(linux) && !defined(LINUX_IPOVLY) -# define LINUX_IPOVLY -struct ipovly { - caddr_t ih_next, ih_prev; /* for protocol sequence q's */ - u_char ih_x1; /* (unused) */ - u_char ih_pr; /* protocol */ - short ih_len; /* protocol length */ - struct in_addr ih_src; /* source internet address */ - struct in_addr ih_dst; /* destination internet address */ -}; -# endif - -/* - * Tcp+ip header, after ip options removed. - */ -struct tcpiphdr { - struct ipovly ti_i; /* overlaid ip structure */ - struct tcphdr ti_t; /* tcp header */ -}; - -#ifdef notyet -/* - * Tcp+ip header, after ip options removed but including TCP options. - */ -struct full_tcpiphdr { - struct ipovly ti_i; /* overlaid ip structure */ - struct tcphdr ti_t; /* tcp header */ - char ti_o[TCP_MAXOLEN]; /* space for tcp options */ -}; -#endif /* notyet */ -#define ti_next ti_i.ih_next -#define ti_prev ti_i.ih_prev -#define ti_x1 ti_i.ih_x1 -#define ti_pr ti_i.ih_pr -#define ti_len ti_i.ih_len -#define ti_src ti_i.ih_src -#define ti_dst ti_i.ih_dst -#define ti_sport ti_t.th_sport -#define ti_dport ti_t.th_dport -#define ti_seq ti_t.th_seq -#define ti_ack ti_t.th_ack -#define ti_x2 ti_t.th_x2 -#define ti_off ti_t.th_off -#define ti_flags ti_t.th_flags -#define ti_win ti_t.th_win -#define ti_sum ti_t.th_sum -#define ti_urp ti_t.th_urp - -#endif diff --git a/contrib/ipfilter/ipt.h b/contrib/ipfilter/ipt.h index f3074a8dc9b9..16d88dfc8809 100644 --- a/contrib/ipfilter/ipt.h +++ b/contrib/ipfilter/ipt.h @@ -1,11 +1,11 @@ /* $FreeBSD$ */ /* - * Copyright (C) 1993-2001 by Darren Reed. + * Copyright (C) 2012 by Darren Reed. * * See the IPFILTER.LICENCE file for details on licencing. * - * $Id: ipt.h,v 2.6.4.2 2006/03/26 23:42:04 darrenr Exp $ + * $Id$ */ #ifndef __IPT_H__ @@ -26,15 +26,12 @@ struct ipread { int (*r_open) __P((char *)); int (*r_close) __P((void)); - int (*r_readip) __P((char *, int, char **, int *)); + int (*r_readip) __P((mb_t *, char **, int *)); int r_flags; }; #define R_DO_CKSUM 0x01 -extern void debug __P((char *, ...)); -extern void verbose __P((char *, ...)); - #ifdef P_DEF # undef __P # undef P_DEF diff --git a/contrib/ipfilter/kmem.h b/contrib/ipfilter/kmem.h index c0864b4fd911..ce6ad56f52d9 100644 --- a/contrib/ipfilter/kmem.h +++ b/contrib/ipfilter/kmem.h @@ -1,10 +1,10 @@ /* $FreeBSD$ */ /* - * Copyright (C) 1993-2001 by Darren Reed. + * Copyright (C) 2012 by Darren Reed. * * See the IPFILTER.LICENCE file for details on licencing. - * $Id: kmem.h,v 2.5 2002/08/21 22:57:36 darrenr Exp $ + * $Id$ */ #ifndef __KMEM_H__ diff --git a/contrib/ipfilter/l4check/Makefile b/contrib/ipfilter/l4check/Makefile index e2bb9f8b3cff..e7366b63ad6a 100644 --- a/contrib/ipfilter/l4check/Makefile +++ b/contrib/ipfilter/l4check/Makefile @@ -4,7 +4,7 @@ all: l4check l4check: l4check.c - $(CC) -g -I.. -Wall $(CFLAGS) $(LIBS) l4check.c -o $@ + $(CC) -g -I.. $(CFLAGS) $(LIBS) l4check.c -o $@ clean: /bin/rm -f l4check diff --git a/contrib/ipfilter/l4check/l4check.c b/contrib/ipfilter/l4check/l4check.c index fd2753ea22be..014446dc6007 100644 --- a/contrib/ipfilter/l4check/l4check.c +++ b/contrib/ipfilter/l4check/l4check.c @@ -1,7 +1,7 @@ /* $FreeBSD$ */ /* - * (C)Copyright March, 2000 - Darren Reed. + * (C)Copyright (C) 2012 by Darren Reed. */ #include #include @@ -27,7 +27,6 @@ #include "ip_compat.h" #include "ip_fil.h" #include "ip_nat.h" -#include "ipl.h" #include "ipf.h" @@ -68,7 +67,7 @@ int opts = 0; char *copystr(dst, src) -char *dst, *src; + char *dst, *src; { register char *s, *t, c; register int esc = 0; @@ -97,44 +96,29 @@ char *dst, *src; } void addnat(l4) -l4cfg_t *l4; + l4cfg_t *l4; { - ipnat_t *ipn = &l4->l4_nat; - printf("Add NAT rule for %s/%#x,%u -> ", inet_ntoa(ipn->in_out[0].in4), + printf("Add NAT rule for %s/%#x,%u -> ", inet_ntoa(ipn->in_out[0]), ipn->in_outmsk, ntohs(ipn->in_pmin)); - printf("%s,%u\n", inet_ntoa(ipn->in_in[0].in4), ntohs(ipn->in_pnext)); + printf("%s,%u\n", inet_ntoa(ipn->in_in[0]), ntohs(ipn->in_pnext)); if (!(opts & OPT_DONOTHING)) { - ipfobj_t obj; - - bzero(&obj, sizeof(obj)); - obj.ipfo_rev = IPFILTER_VERSION; - obj.ipfo_size = sizeof(*ipn); - obj.ipfo_ptr = ipn; - - if (ioctl(natfd, SIOCADNAT, &obj) == -1) + if (ioctl(natfd, SIOCADNAT, &ipn) == -1) perror("ioctl(SIOCADNAT)"); } } void delnat(l4) -l4cfg_t *l4; + l4cfg_t *l4; { ipnat_t *ipn = &l4->l4_nat; printf("Remove NAT rule for %s/%#x,%u -> ", - inet_ntoa(ipn->in_out[0].in4), ipn->in_outmsk, ipn->in_pmin); - printf("%s,%u\n", inet_ntoa(ipn->in_in[0].in4), ipn->in_pnext); + inet_ntoa(ipn->in_out[0]), ipn->in_outmsk, ipn->in_pmin); + printf("%s,%u\n", inet_ntoa(ipn->in_in[0]), ipn->in_pnext); if (!(opts & OPT_DONOTHING)) { - ipfobj_t obj; - - bzero(&obj, sizeof(obj)); - obj.ipfo_rev = IPFILTER_VERSION; - obj.ipfo_size = sizeof(*ipn); - obj.ipfo_ptr = ipn; - if (ioctl(natfd, SIOCRMNAT, &ipn) == -1) perror("ioctl(SIOCRMNAT)"); } @@ -142,7 +126,7 @@ l4cfg_t *l4; void connectl4(l4) -l4cfg_t *l4; + l4cfg_t *l4; { l4->l4_rw = 1; l4->l4_rlen = 0; @@ -156,8 +140,8 @@ l4cfg_t *l4; void closel4(l4, dead) -l4cfg_t *l4; -int dead; + l4cfg_t *l4; + int dead; { close(l4->l4_fd); l4->l4_fd = -1; @@ -170,7 +154,7 @@ int dead; void connectfd(l4) -l4cfg_t *l4; + l4cfg_t *l4; { if (connect(l4->l4_fd, (struct sockaddr *)&l4->l4_sin, sizeof(l4->l4_sin)) == -1) { @@ -192,8 +176,9 @@ l4cfg_t *l4; void writefd(l4) -l4cfg_t *l4; + l4cfg_t *l4; { + char buf[80], *ptr; int n, i, fd; fd = l4->l4_fd; @@ -223,7 +208,7 @@ l4cfg_t *l4; void readfd(l4) -l4cfg_t *l4; + l4cfg_t *l4; { char buf[80], *ptr; int n, i, fd; @@ -417,14 +402,15 @@ int runconfig() int gethostport(str, lnum, ipp, portp) -char *str; -int lnum; -u_32_t *ipp; -u_short *portp; + char *str; + int lnum; + u_32_t *ipp; + u_short *portp; { struct servent *sp; struct hostent *hp; char *host, *port; + struct in_addr ip; host = str; port = strchr(host, ','); @@ -467,8 +453,8 @@ u_short *portp; char *mapfile(file, sizep) -char *file; -size_t *sizep; + char *file; + size_t *sizep; { struct stat sb; caddr_t addr; @@ -499,7 +485,7 @@ size_t *sizep; int readconfig(filename) -char *filename; + char *filename; { char c, buf[512], *s, *t, *errtxt = NULL, *line; int num, err = 0; @@ -569,8 +555,7 @@ char *filename; break; } - strncpy(ipn->in_ifnames[0], s, LIFNAMSIZ); - strncpy(ipn->in_ifnames[1], s, LIFNAMSIZ); + strncpy(ipn->in_ifname, s, sizeof(ipn->in_ifname)); if (!gethostport(t, num, &ipn->in_outip, &ipn->in_pmin)) { errtxt = line; @@ -582,11 +567,11 @@ char *filename; if (opts & OPT_VERBOSE) fprintf(stderr, "Interface %s %s/%#x port %u\n", - ipn->in_ifnames[0], - inet_ntoa(ipn->in_out[0].in4), + ipn->in_ifname, + inet_ntoa(ipn->in_out[0]), ipn->in_outmsk, ipn->in_pmin); } else if (!strcasecmp(t, "remote")) { - if (!*ipn->in_ifnames[0]) { + if (!*ipn->in_ifname) { fprintf(stderr, "%d: ifname not set prior to remote\n", num); @@ -621,7 +606,7 @@ char *filename; break; } bcopy((char *)&template, (char *)l4, sizeof(*l4)); - l4->l4_sin.sin_addr = ipn->in_in[0].in4; + l4->l4_sin.sin_addr = ipn->in_in[0]; l4->l4_sin.sin_port = ipn->in_pnext; l4->l4_next = l4list; l4list = l4; @@ -768,7 +753,7 @@ char *filename; void usage(prog) -char *prog; + char *prog; { fprintf(stderr, "Usage: %s -f \n", prog); exit(1); @@ -776,8 +761,8 @@ char *prog; int main(argc, argv) -int argc; -char *argv[]; + int argc; + char *argv[]; { char *config = NULL; int c; @@ -808,7 +793,7 @@ char *argv[]; } if (!(opts & OPT_DONOTHING)) { - natfd = open(IPNAT_NAME, O_RDWR); + natfd = open(IPL_NAT, O_RDWR); if (natfd == -1) { perror("open(IPL_NAT)"); exit(1); @@ -819,6 +804,4 @@ char *argv[]; fprintf(stderr, "Starting...\n"); while (runconfig() == 0) ; - - exit(1); } diff --git a/contrib/ipfilter/lib/Makefile b/contrib/ipfilter/lib/Makefile index a838063c674c..fdda78ed41a6 100644 --- a/contrib/ipfilter/lib/Makefile +++ b/contrib/ipfilter/lib/Makefile @@ -1,27 +1,37 @@ # -# Copyright (C) 1993-2001 by Darren Reed. -# -# See the IPFILTER.LICENCE file for details on licencing. -# -# $Id: Makefile,v 1.41.2.14 2007/09/21 08:30:43 darrenr Exp $ -# +# Copyright (C) 2012 by Darren Reed. +# +# See the IPFILTER.LICENCE file for details on licencing. +# +# $Id$ +# INCDEP=$(TOP)/ip_compat.h $(TOP)/ip_fil.h $(TOP)/ipf.h LIBOBJS=$(DEST)/addicmp.o \ $(DEST)/addipopt.o \ $(DEST)/alist_free.o \ $(DEST)/alist_new.o \ + $(DEST)/allocmbt.o \ + $(DEST)/assigndefined.o \ $(DEST)/bcopywrap.o \ $(DEST)/binprint.o \ $(DEST)/buildopts.o \ $(DEST)/checkrev.o \ + $(DEST)/connecttcp.o \ $(DEST)/count6bits.o \ $(DEST)/count4bits.o \ $(DEST)/debug.o \ + $(DEST)/dupmbt.o \ + $(DEST)/familyname.o \ $(DEST)/facpri.o \ - $(DEST)/flags.o \ $(DEST)/fill6bits.o \ + $(DEST)/findword.o \ + $(DEST)/flags.o \ + $(DEST)/freembt.o \ + $(DEST)/ftov.o \ + $(DEST)/genmask.o \ $(DEST)/gethost.o \ + $(DEST)/geticmptype.o \ $(DEST)/getifname.o \ $(DEST)/getnattype.o \ $(DEST)/getport.o \ @@ -30,27 +40,30 @@ LIBOBJS=$(DEST)/addicmp.o \ $(DEST)/getsumd.o \ $(DEST)/hostname.o \ $(DEST)/icmpcode.o \ - $(DEST)/inet_addr.o \ + $(DEST)/icmptypename.o \ + $(DEST)/icmptypes.o \ $(DEST)/initparse.o \ + $(DEST)/interror.o \ $(DEST)/ionames.o \ - $(DEST)/ipoptsec.o \ $(DEST)/ipf_dotuning.o \ - $(DEST)/ipft_ef.o \ + $(DEST)/ipf_perror.o \ $(DEST)/ipft_hx.o \ $(DEST)/ipft_pc.o \ - $(DEST)/ipft_sn.o \ - $(DEST)/ipft_td.o \ $(DEST)/ipft_tx.o \ + $(DEST)/ipoptsec.o \ $(DEST)/kmem.o \ $(DEST)/kmemcpywrap.o \ $(DEST)/kvatoname.o \ $(DEST)/load_file.o \ + $(DEST)/load_dstlist.o \ + $(DEST)/load_dstlistnode.o \ $(DEST)/load_hash.o \ $(DEST)/load_hashnode.o \ $(DEST)/load_http.o \ $(DEST)/load_pool.o \ $(DEST)/load_poolnode.o \ $(DEST)/load_url.o \ + $(DEST)/msgdsize.o \ $(DEST)/mutex_emul.o \ $(DEST)/nametokva.o \ $(DEST)/nat_setgroupmap.o \ @@ -59,46 +72,74 @@ LIBOBJS=$(DEST)/addicmp.o \ $(DEST)/optprint.o \ $(DEST)/optprintv6.o \ $(DEST)/optvalue.o \ + $(DEST)/parsefields.o \ + $(DEST)/parseipfexpr.o \ + $(DEST)/parsewhoisline.o \ + $(DEST)/poolio.o \ $(DEST)/portname.o \ $(DEST)/print_toif.o \ + $(DEST)/printactiveaddr.o \ $(DEST)/printactivenat.o \ + $(DEST)/printaddr.o \ $(DEST)/printaps.o \ $(DEST)/printbuf.o \ + $(DEST)/printdstlist.o \ + $(DEST)/printdstlistdata.o \ + $(DEST)/printdstlistnode.o \ + $(DEST)/printdstlistpolicy.o \ + $(DEST)/printdstl_live.o \ + $(DEST)/printfieldhdr.o \ + $(DEST)/printfr.o \ + $(DEST)/printfraginfo.o \ $(DEST)/printhash.o \ $(DEST)/printhashdata.o \ $(DEST)/printhashnode.o \ $(DEST)/printhash_live.o \ + $(DEST)/printhost.o \ + $(DEST)/printhostmap.o \ + $(DEST)/printhostmask.o \ + $(DEST)/printifname.o \ $(DEST)/printip.o \ + $(DEST)/printipfexpr.o \ + $(DEST)/printlog.o \ + $(DEST)/printlookup.o \ + $(DEST)/printmask.o \ + $(DEST)/printnat.o \ + $(DEST)/printnataddr.o \ + $(DEST)/printnatfield.o \ + $(DEST)/printnatside.o \ $(DEST)/printpool.o \ $(DEST)/printpooldata.o \ + $(DEST)/printpoolfield.o \ $(DEST)/printpoolnode.o \ $(DEST)/printpool_live.o \ $(DEST)/printproto.o \ - $(DEST)/printfr.o \ - $(DEST)/printfraginfo.o \ - $(DEST)/printhostmap.o \ - $(DEST)/printifname.o \ - $(DEST)/printhostmask.o \ - $(DEST)/printlog.o \ - $(DEST)/printmask.o \ - $(DEST)/printnat.o \ $(DEST)/printportcmp.o \ $(DEST)/printpacket.o \ $(DEST)/printpacket6.o \ $(DEST)/printsbuf.o \ $(DEST)/printstate.o \ + $(DEST)/printstatefields.o \ + $(DEST)/printtcpflags.o \ $(DEST)/printtqtable.o \ $(DEST)/printtunable.o \ + $(DEST)/printunit.o \ $(DEST)/remove_hash.o \ $(DEST)/remove_hashnode.o \ $(DEST)/remove_pool.o \ $(DEST)/remove_poolnode.o \ $(DEST)/resetlexer.o \ $(DEST)/rwlock_emul.o \ + $(DEST)/save_execute.o \ + $(DEST)/save_file.o \ + $(DEST)/save_nothing.o \ + $(DEST)/save_syslog.o \ + $(DEST)/save_v1trap.o \ + $(DEST)/save_v2trap.o \ $(DEST)/tcpflags.o \ - $(DEST)/tcp_flags.o \ $(DEST)/var.o \ $(DEST)/verbose.o \ + $(DEST)/vtof.o \ $(DEST)/v6ionames.o \ $(DEST)/v6optvalue.o @@ -115,12 +156,18 @@ $(DEST)/alist_free.o: $(LIBSRC)/alist_free.c $(INCDEP) $(CC) $(CCARGS) -c $(LIBSRC)/alist_free.c -o $@ $(DEST)/alist_new.o: $(LIBSRC)/alist_new.c $(INCDEP) $(CC) $(CCARGS) -c $(LIBSRC)/alist_new.c -o $@ +$(DEST)/allocmbt.o: $(LIBSRC)/allocmbt.c $(INCDEP) + $(CC) $(CCARGS) -c $(LIBSRC)/allocmbt.c -o $@ +$(DEST)/assigndefined.o: $(LIBSRC)/assigndefined.c $(INCDEP) + $(CC) $(CCARGS) -c $(LIBSRC)/assigndefined.c -o $@ $(DEST)/bcopywrap.o: $(LIBSRC)/bcopywrap.c $(INCDEP) $(CC) $(CCARGS) -c $(LIBSRC)/bcopywrap.c -o $@ $(DEST)/binprint.o: $(LIBSRC)/binprint.c $(INCDEP) $(CC) $(CCARGS) -c $(LIBSRC)/binprint.c -o $@ $(DEST)/buildopts.o: $(LIBSRC)/buildopts.c $(INCDEP) $(CC) $(CCARGS) -c $(LIBSRC)/buildopts.c -o $@ +$(DEST)/connecttcp.o: $(LIBSRC)/connecttcp.c $(INCDEP) + $(CC) $(CCARGS) -c $(LIBSRC)/connecttcp.c -o $@ $(DEST)/count6bits.o: $(LIBSRC)/count6bits.c $(INCDEP) $(CC) $(CCARGS) -c $(LIBSRC)/count6bits.c -o $@ $(DEST)/checkrev.o: $(LIBSRC)/checkrev.c $(INCDEP) $(TOP)/ipl.h @@ -129,17 +176,31 @@ $(DEST)/count4bits.o: $(LIBSRC)/count4bits.c $(INCDEP) $(CC) $(CCARGS) -c $(LIBSRC)/count4bits.c -o $@ $(DEST)/debug.o: $(LIBSRC)/debug.c $(INCDEP) $(CC) $(CCARGS) -c $(LIBSRC)/debug.c -o $@ +$(DEST)/dupmbt.o: $(LIBSRC)/dupmbt.c $(INCDEP) + $(CC) $(CCARGS) -c $(LIBSRC)/dupmbt.c -o $@ $(DEST)/facpri.o: $(LIBSRC)/facpri.c $(INCDEP) $(CC) $(CCARGS) -c $(LIBSRC)/facpri.c -o $@ +$(DEST)/familyname.o: $(LIBSRC)/familyname.c $(INCDEP) + $(CC) $(CCARGS) -c $(LIBSRC)/familyname.c -o $@ $(DEST)/fill6bits.o: $(LIBSRC)/fill6bits.c $(INCDEP) $(CC) $(CCARGS) -c $(LIBSRC)/fill6bits.c -o $@ +$(DEST)/findword.o: $(LIBSRC)/findword.c $(INCDEP) + $(CC) $(CCARGS) -c $(LIBSRC)/findword.c -o $@ $(DEST)/flags.o: $(LIBSRC)/flags.c $(INCDEP) $(CC) $(CCARGS) -c $(LIBSRC)/flags.c -o $@ +$(DEST)/freembt.o: $(LIBSRC)/freembt.c $(INCDEP) + $(CC) $(CCARGS) -c $(LIBSRC)/freembt.c -o $@ +$(DEST)/ftov.o: $(LIBSRC)/ftov.c $(INCDEP) + $(CC) $(CCARGS) -c $(LIBSRC)/ftov.c -o $@ +$(DEST)/genmask.o: $(LIBSRC)/genmask.c $(INCDEP) + $(CC) $(CCARGS) -c $(LIBSRC)/genmask.c -o $@ $(DEST)/gethost.o: $(LIBSRC)/gethost.c $(INCDEP) $(CC) $(CCARGS) -c $(LIBSRC)/gethost.c -o $@ +$(DEST)/geticmptype.o: $(LIBSRC)/geticmptype.c $(INCDEP) + $(CC) $(CCARGS) -c $(LIBSRC)/geticmptype.c -o $@ $(DEST)/getifname.o: $(LIBSRC)/getifname.c $(INCDEP) $(CC) $(CCARGS) -c $(LIBSRC)/getifname.c -o $@ -$(DEST)/getnattype.o: $(LIBSRC)/getnattype.c $(INCDEP) +$(DEST)/getnattype.o: $(LIBSRC)/getnattype.c $(INCDEP) $(TOP)/ip_nat.h $(CC) $(CCARGS) -c $(LIBSRC)/getnattype.c -o $@ $(DEST)/getport.o: $(LIBSRC)/getport.c $(INCDEP) $(CC) $(CCARGS) -c $(LIBSRC)/getport.c -o $@ @@ -153,26 +214,26 @@ $(DEST)/hostname.o: $(LIBSRC)/hostname.c $(INCDEP) $(CC) $(CCARGS) -c $(LIBSRC)/hostname.c -o $@ $(DEST)/icmpcode.o: $(LIBSRC)/icmpcode.c $(INCDEP) $(CC) $(CCARGS) -c $(LIBSRC)/icmpcode.c -o $@ +$(DEST)/icmptypename.o: $(LIBSRC)/icmptypename.c $(INCDEP) + $(CC) $(CCARGS) -c $(LIBSRC)/icmptypename.c -o $@ +$(DEST)/icmptypes.o: $(LIBSRC)/icmptypes.c $(INCDEP) + $(CC) $(CCARGS) -c $(LIBSRC)/icmptypes.c -o $@ +$(DEST)/interror.o: $(LIBSRC)/interror.c $(INCDEP) + $(CC) $(CCARGS) -c $(LIBSRC)/interror.c -o $@ $(DEST)/ipoptsec.o: $(LIBSRC)/ipoptsec.c $(INCDEP) $(CC) $(CCARGS) -c $(LIBSRC)/ipoptsec.c -o $@ -$(DEST)/inet_addr.o: $(LIBSRC)/inet_addr.c $(INCDEP) - $(CC) $(CCARGS) -c $(LIBSRC)/inet_addr.c -o $@ $(DEST)/initparse.o: $(LIBSRC)/initparse.c $(INCDEP) $(CC) $(CCARGS) -c $(LIBSRC)/initparse.c -o $@ $(DEST)/ionames.o: $(LIBSRC)/ionames.c $(INCDEP) $(CC) $(CCARGS) -c $(LIBSRC)/ionames.c -o $@ $(DEST)/ipf_dotuning.o: $(LIBSRC)/ipf_dotuning.c $(INCDEP) $(CC) $(CCARGS) -c $(LIBSRC)/ipf_dotuning.c -o $@ -$(DEST)/ipft_ef.o: $(LIBSRC)/ipft_ef.c $(INCDEP) - $(CC) $(CCARGS) -c $(LIBSRC)/ipft_ef.c -o $@ +$(DEST)/ipf_perror.o: $(LIBSRC)/ipf_perror.c $(INCDEP) + $(CC) $(CCARGS) -c $(LIBSRC)/ipf_perror.c -o $@ $(DEST)/ipft_hx.o: $(LIBSRC)/ipft_hx.c $(INCDEP) $(CC) $(CCARGS) -c $(LIBSRC)/ipft_hx.c -o $@ $(DEST)/ipft_pc.o: $(LIBSRC)/ipft_pc.c $(INCDEP) $(CC) $(CCARGS) -c $(LIBSRC)/ipft_pc.c -o $@ -$(DEST)/ipft_sn.o: $(LIBSRC)/ipft_sn.c $(TOP)/snoop.h - $(CC) $(CCARGS) -c $(LIBSRC)/ipft_sn.c -o $@ -$(DEST)/ipft_td.o: $(LIBSRC)/ipft_td.c $(INCDEP) - $(CC) $(CCARGS) -c $(LIBSRC)/ipft_td.c -o $@ $(DEST)/ipft_tx.o: $(LIBSRC)/ipft_tx.c $(INCDEP) $(CC) $(CCARGS) -c $(LIBSRC)/ipft_tx.c -o $@ $(DEST)/kmem.o: $(LIBSRC)/kmem.c $(INCDEP) @@ -183,6 +244,11 @@ $(DEST)/kvatoname.o: $(LIBSRC)/kvatoname.c $(INCDEP) $(CC) $(CCARGS) -c $(LIBSRC)/kvatoname.c -o $@ $(DEST)/load_file.o: $(LIBSRC)/load_file.c $(INCDEP) $(CC) $(CCARGS) -c $(LIBSRC)/load_file.c -o $@ +$(DEST)/load_dstlist.o: $(LIBSRC)/load_dstlist.c $(INCDEP) $(TOP)/ip_dstlist.h + $(CC) $(CCARGS) -c $(LIBSRC)/load_dstlist.c -o $@ +$(DEST)/load_dstlistnode.o: $(LIBSRC)/load_dstlistnode.c $(INCDEP) \ + $(TOP)/ip_dstlist.h + $(CC) $(CCARGS) -c $(LIBSRC)/load_dstlistnode.c -o $@ $(DEST)/load_hash.o: $(LIBSRC)/load_hash.c $(INCDEP) $(TOP)/ip_htable.h $(CC) $(CCARGS) -c $(LIBSRC)/load_hash.c -o $@ $(DEST)/load_hashnode.o: $(LIBSRC)/load_hashnode.c $(INCDEP) $(TOP)/ip_htable.h @@ -195,8 +261,8 @@ $(DEST)/load_poolnode.o: $(LIBSRC)/load_poolnode.c $(INCDEP) $(TOP)/ip_pool.h $(CC) $(CCARGS) -c $(LIBSRC)/load_poolnode.c -o $@ $(DEST)/load_url.o: $(LIBSRC)/load_url.c $(INCDEP) $(CC) $(CCARGS) -c $(LIBSRC)/load_url.c -o $@ -$(DEST)/make_range.o: $(LIBSRC)/make_range.c $(INCDEP) - $(CC) $(CCARGS) -c $(LIBSRC)/make_range.c -o $@ +$(DEST)/msgdsize.o: $(LIBSRC)/msgdsize.c $(INCDEP) + $(CC) $(CCARGS) -c $(LIBSRC)/msgdsize.c -o $@ $(DEST)/mutex_emul.o: $(LIBSRC)/mutex_emul.c $(INCDEP) $(CC) $(CCARGS) -c $(LIBSRC)/mutex_emul.c -o $@ $(DEST)/nametokva.o: $(LIBSRC)/nametokva.c $(INCDEP) @@ -214,35 +280,78 @@ $(DEST)/optprintv6.o: $(LIBSRC)/optprintv6.c $(INCDEP) $(CC) $(CCARGS) -c $(LIBSRC)/optprintv6.c -o $@ $(DEST)/optvalue.o: $(LIBSRC)/optvalue.c $(INCDEP) $(CC) $(CCARGS) -c $(LIBSRC)/optvalue.c -o $@ +$(DEST)/parsefields.o: $(LIBSRC)/parsefields.c $(INCDEP) + $(CC) $(CCARGS) -c $(LIBSRC)/parsefields.c -o $@ +$(DEST)/parseipfexpr.o: $(LIBSRC)/parseipfexpr.c $(INCDEP) + $(CC) $(CCARGS) -c $(LIBSRC)/parseipfexpr.c -o $@ +$(DEST)/parsewhoisline.o: $(LIBSRC)/parsewhoisline.c $(INCDEP) + $(CC) $(CCARGS) -c $(LIBSRC)/parsewhoisline.c -o $@ +$(DEST)/poolio.o: $(LIBSRC)/poolio.c $(INCDEP) + $(CC) $(CCARGS) -c $(LIBSRC)/poolio.c -o $@ $(DEST)/portname.o: $(LIBSRC)/portname.c $(INCDEP) $(CC) $(CCARGS) -c $(LIBSRC)/portname.c -o $@ $(DEST)/print_toif.o: $(LIBSRC)/print_toif.c $(INCDEP) $(CC) $(CCARGS) -c $(LIBSRC)/print_toif.c -o $@ -$(DEST)/printactivenat.o: $(LIBSRC)/printactivenat.c $(INCDEP) +$(DEST)/printactiveaddr.o: $(LIBSRC)/printactiveaddr.c $(INCDEP) $(TOP)/ip_nat.h + $(CC) $(CCARGS) -c $(LIBSRC)/printactiveaddr.c -o $@ +$(DEST)/printactivenat.o: $(LIBSRC)/printactivenat.c $(INCDEP) $(TOP)/ip_nat.h $(CC) $(CCARGS) -c $(LIBSRC)/printactivenat.c -o $@ +$(DEST)/printaddr.o: $(LIBSRC)/printaddr.c $(INCDEP) + $(CC) $(CCARGS) -c $(LIBSRC)/printaddr.c -o $@ $(DEST)/printaps.o: $(LIBSRC)/printaps.c $(INCDEP) $(CC) $(CCARGS) -c $(LIBSRC)/printaps.c -o $@ $(DEST)/printbuf.o: $(LIBSRC)/printbuf.c $(INCDEP) $(CC) $(CCARGS) -c $(LIBSRC)/printbuf.c -o $@ +$(DEST)/printdstlist.o: $(LIBSRC)/printdstlist.c $(INCDEP) $(TOP)/ip_dstlist.h + $(CC) $(CCARGS) -c $(LIBSRC)/printdstlist.c -o $@ +$(DEST)/printdstlistdata.o: $(LIBSRC)/printdstlistdata.c $(INCDEP) \ + $(TOP)/ip_dstlist.h + $(CC) $(CCARGS) -c $(LIBSRC)/printdstlistdata.c -o $@ +$(DEST)/printdstlistnode.o: $(LIBSRC)/printdstlistnode.c $(INCDEP) \ + $(TOP)/ip_dstlist.h + $(CC) $(CCARGS) -c $(LIBSRC)/printdstlistnode.c -o $@ +$(DEST)/printdstlistpolicy.o: $(LIBSRC)/printdstlistpolicy.c $(INCDEP) \ + $(TOP)/ip_dstlist.h + $(CC) $(CCARGS) -c $(LIBSRC)/printdstlistpolicy.c -o $@ +$(DEST)/printfieldhdr.o: $(LIBSRC)/printfieldhdr.c $(TOP)/ip_fil.h + $(CC) $(CCARGS) -c $(LIBSRC)/printfieldhdr.c -o $@ $(DEST)/printfr.o: $(LIBSRC)/printfr.c $(TOP)/ip_fil.h $(CC) $(CCARGS) -c $(LIBSRC)/printfr.c -o $@ -$(DEST)/printfraginfo.o: $(LIBSRC)/printfraginfo.c $(TOP)/ip_fil.h +$(DEST)/printfraginfo.o: $(LIBSRC)/printfraginfo.c $(TOP)/ip_fil.h \ + $(TOP)/ip_frag.h $(CC) $(CCARGS) -c $(LIBSRC)/printfraginfo.c -o $@ $(DEST)/printhash.o: $(LIBSRC)/printhash.c $(TOP)/ip_fil.h $(TOP)/ip_htable.h $(CC) $(CCARGS) -c $(LIBSRC)/printhash.c -o $@ -$(DEST)/printhashdata.o: $(LIBSRC)/printhash.c $(TOP)/ip_fil.h $(TOP)/ip_htable.h +$(DEST)/printhashdata.o: $(LIBSRC)/printhashdata.c $(TOP)/ip_fil.h \ + $(TOP)/ip_htable.h $(CC) $(CCARGS) -c $(LIBSRC)/printhashdata.c -o $@ $(DEST)/printhashnode.o: $(LIBSRC)/printhashnode.c $(TOP)/ip_fil.h \ $(TOP)/ip_htable.h $(TOP)/ip_lookup.h $(CC) $(CCARGS) -c $(LIBSRC)/printhashnode.c -o $@ -$(DEST)/printhash_live.o: $(LIBSRC)/printhash_live.c $(TOP)/ip_fil.h $(TOP)/ip_htable.h +$(DEST)/printhash_live.o: $(LIBSRC)/printhash_live.c $(TOP)/ip_fil.h \ + $(TOP)/ip_htable.h $(CC) $(CCARGS) -c $(LIBSRC)/printhash_live.c -o $@ +$(DEST)/printdstl_live.o: $(LIBSRC)/printdstl_live.c $(TOP)/ip_fil.h \ + $(TOP)/ip_dstlist.h + $(CC) $(CCARGS) -c $(LIBSRC)/printdstl_live.c -o $@ $(DEST)/printip.o: $(LIBSRC)/printip.c $(TOP)/ip_fil.h $(CC) $(CCARGS) -c $(LIBSRC)/printip.c -o $@ +$(DEST)/printipfexpr.o: $(LIBSRC)/printipfexpr.c $(TOP)/ip_fil.h + $(CC) $(CCARGS) -c $(LIBSRC)/printipfexpr.c -o $@ +$(DEST)/printlookup.o: $(LIBSRC)/printlookup.c $(INCDEP) + $(CC) $(CCARGS) -c $(LIBSRC)/printlookup.c -o $@ +$(DEST)/printnataddr.o: $(LIBSRC)/printnataddr.c $(INCDEP) $(TOP)/ip_nat.h + $(CC) $(CCARGS) -c $(LIBSRC)/printnataddr.c -o $@ +$(DEST)/printnatside.o: $(LIBSRC)/printnatside.c $(INCDEP) $(TOP)/ip_nat.h + $(CC) $(CCARGS) -c $(LIBSRC)/printnatside.c -o $@ $(DEST)/printpool.o: $(LIBSRC)/printpool.c $(TOP)/ip_fil.h $(TOP)/ip_pool.h $(CC) $(CCARGS) -c $(LIBSRC)/printpool.c -o $@ -$(DEST)/printpooldata.o: $(LIBSRC)/printpooldata.c $(TOP)/ip_fil.h $(TOP)/ip_pool.h +$(DEST)/printpooldata.o: $(LIBSRC)/printpooldata.c $(TOP)/ip_fil.h \ + $(TOP)/ip_pool.h $(TOP)/ip_lookup.h $(CC) $(CCARGS) -c $(LIBSRC)/printpooldata.c -o $@ +$(DEST)/printpoolfield.o: $(LIBSRC)/printpoolfield.c $(TOP)/ip_fil.h \ + $(TOP)/ip_pool.h $(TOP)/ip_lookup.h + $(CC) $(CCARGS) -c $(LIBSRC)/printpoolfield.c -o $@ $(DEST)/printpoolnode.o: $(LIBSRC)/printpoolnode.c $(TOP)/ip_fil.h \ $(TOP)/ip_pool.h $(TOP)/ip_lookup.h $(CC) $(CCARGS) -c $(LIBSRC)/printpoolnode.c -o $@ @@ -251,14 +360,18 @@ $(DEST)/printpool_live.o: $(LIBSRC)/printpool_live.c $(TOP)/ip_fil.h \ $(CC) $(CCARGS) -c $(LIBSRC)/printpool_live.c -o $@ $(DEST)/printproto.o: $(LIBSRC)/printproto.c $(TOP)/ip_fil.h $(CC) $(CCARGS) -c $(LIBSRC)/printproto.c -o $@ +$(DEST)/printhost.o: $(LIBSRC)/printhost.c $(TOP)/ip_fil.h + $(CC) $(CCARGS) -c $(LIBSRC)/printhost.c -o $@ $(DEST)/printhostmap.o: $(LIBSRC)/printhostmap.c $(TOP)/ip_fil.h $(CC) $(CCARGS) -c $(LIBSRC)/printhostmap.c -o $@ $(DEST)/printifname.o: $(LIBSRC)/printifname.c $(INCDEP) $(CC) $(CCARGS) -c $(LIBSRC)/printifname.c -o $@ $(DEST)/printmask.o: $(LIBSRC)/printmask.c $(INCDEP) $(CC) $(CCARGS) -c $(LIBSRC)/printmask.c -o $@ -$(DEST)/printnat.o: $(LIBSRC)/printnat.c $(INCDEP) +$(DEST)/printnat.o: $(LIBSRC)/printnat.c $(INCDEP) $(TOP)/ip_nat.h $(CC) $(CCARGS) -c $(LIBSRC)/printnat.c -o $@ +$(DEST)/printnatfield.o: $(LIBSRC)/printnatfield.c $(INCDEP) $(TOP)/ip_nat.h + $(CC) $(CCARGS) -c $(LIBSRC)/printnatfield.c -o $@ $(DEST)/printhostmask.o: $(LIBSRC)/printhostmask.c $(INCDEP) $(CC) $(CCARGS) -c $(LIBSRC)/printhostmask.c -o $@ $(DEST)/printlog.o: $(LIBSRC)/printlog.c $(INCDEP) @@ -273,10 +386,16 @@ $(DEST)/printsbuf.o: $(LIBSRC)/printsbuf.c $(INCDEP) $(CC) $(CCARGS) -c $(LIBSRC)/printsbuf.c -o $@ $(DEST)/printstate.o: $(LIBSRC)/printstate.c $(INCDEP) $(TOP)/ip_state.h $(CC) $(CCARGS) -c $(LIBSRC)/printstate.c -o $@ +$(DEST)/printstatefields.o: $(LIBSRC)/printstatefields.c $(INCDEP) $(TOP)/ip_state.h + $(CC) $(CCARGS) -c $(LIBSRC)/printstatefields.c -o $@ +$(DEST)/printtcpflags.o: $(LIBSRC)/printtcpflags.c $(INCDEP) + $(CC) $(CCARGS) -c $(LIBSRC)/printtcpflags.c -o $@ $(DEST)/printtqtable.o: $(LIBSRC)/printtqtable.c $(INCDEP) $(CC) $(CCARGS) -c $(LIBSRC)/printtqtable.c -o $@ $(DEST)/printtunable.o: $(LIBSRC)/printtunable.c $(INCDEP) $(CC) $(CCARGS) -c $(LIBSRC)/printtunable.c -o $@ +$(DEST)/printunit.o: $(LIBSRC)/printunit.c $(INCDEP) + $(CC) $(CCARGS) -c $(LIBSRC)/printunit.c -o $@ $(DEST)/remove_hash.o: $(LIBSRC)/remove_hash.c $(INCDEP) \ $(TOP)/ip_htable.h $(CC) $(CCARGS) -c $(LIBSRC)/remove_hash.c -o $@ @@ -301,6 +420,20 @@ $(DEST)/var.o: $(LIBSRC)/var.c $(INCDEP) $(CC) $(CCARGS) -c $(LIBSRC)/var.c -o $@ $(DEST)/verbose.o: $(LIBSRC)/verbose.c $(INCDEP) $(CC) $(CCARGS) -c $(LIBSRC)/verbose.c -o $@ +$(DEST)/save_execute.o: $(LIBSRC)/save_execute.c $(TOP)/ipl.h + $(CC) $(CCARGS) -c $(LIBSRC)/save_execute.c -o $@ +$(DEST)/save_file.o: $(LIBSRC)/save_file.c $(TOP)/ipl.h + $(CC) $(CCARGS) -c $(LIBSRC)/save_file.c -o $@ +$(DEST)/save_nothing.o: $(LIBSRC)/save_nothing.c $(TOP)/ipl.h + $(CC) $(CCARGS) -c $(LIBSRC)/save_nothing.c -o $@ +$(DEST)/save_syslog.o: $(LIBSRC)/save_syslog.c $(TOP)/ipl.h + $(CC) $(CCARGS) -c $(LIBSRC)/save_syslog.c -o $@ +$(DEST)/vtof.o: $(LIBSRC)/vtof.c $(INCDEP) + $(CC) $(CCARGS) -c $(LIBSRC)/vtof.c -o $@ +$(DEST)/save_v1trap.o: $(LIBSRC)/save_v1trap.c $(TOP)/ipl.h + $(CC) $(CCARGS) -c $(LIBSRC)/save_v1trap.c -o $@ +$(DEST)/save_v2trap.o: $(LIBSRC)/save_v2trap.c $(TOP)/ipl.h + $(CC) $(CCARGS) -c $(LIBSRC)/save_v2trap.c -o $@ $(DEST)/v6ionames.o: $(LIBSRC)/v6ionames.c $(INCDEP) $(CC) $(CCARGS) -c $(LIBSRC)/v6ionames.c -o $@ $(DEST)/v6optvalue.o: $(LIBSRC)/v6optvalue.c $(INCDEP) diff --git a/contrib/ipfilter/lib/addicmp.c b/contrib/ipfilter/lib/addicmp.c index ef9abfed3c9c..da52f1caacfe 100644 --- a/contrib/ipfilter/lib/addicmp.c +++ b/contrib/ipfilter/lib/addicmp.c @@ -1,11 +1,11 @@ /* $FreeBSD$ */ /* - * Copyright (C) 2000-2006 by Darren Reed. + * Copyright (C) 2012 by Darren Reed. * * See the IPFILTER.LICENCE file for details on licencing. * - * $Id: addicmp.c,v 1.10.2.5 2006/06/16 17:20:55 darrenr Exp $ + * $Id$ */ #include diff --git a/contrib/ipfilter/lib/addipopt.c b/contrib/ipfilter/lib/addipopt.c index 79155e7e4c57..26aff83f31b6 100644 --- a/contrib/ipfilter/lib/addipopt.c +++ b/contrib/ipfilter/lib/addipopt.c @@ -1,21 +1,21 @@ /* $FreeBSD$ */ /* - * Copyright (C) 2000-2002 by Darren Reed. + * Copyright (C) 2012 by Darren Reed. * * See the IPFILTER.LICENCE file for details on licencing. * - * $Id: addipopt.c,v 1.7.4.1 2006/06/16 17:20:56 darrenr Exp $ + * $Id$ */ #include "ipf.h" int addipopt(op, io, len, class) -char *op; -struct ipopt_names *io; -int len; -char *class; + char *op; + struct ipopt_names *io; + int len; + char *class; { int olen = len; struct in_addr ipadr; @@ -41,6 +41,10 @@ char *class; lvl = seclevel(class); *(op - 1) = lvl; break; + case IPOPT_RR : + case IPOPT_TS : + s[IPOPT_OLEN] = IPOPT_MINOFF - 1 + 4; + break; case IPOPT_LSRR : case IPOPT_SSRR : ipadr.s_addr = inet_addr(class); @@ -53,12 +57,6 @@ char *class; break; } } - - op += io->on_siz - 3; - if (len & 3) { - *op++ = IPOPT_NOP; - len++; - } } if (opts & OPT_DEBUG) fprintf(stderr, "bo: %s %d %#x: %d\n", diff --git a/contrib/ipfilter/lib/alist_free.c b/contrib/ipfilter/lib/alist_free.c index 3c1a51880430..44dea1330f81 100644 --- a/contrib/ipfilter/lib/alist_free.c +++ b/contrib/ipfilter/lib/alist_free.c @@ -1,15 +1,15 @@ /* - * Copyright (C) 2006 by Darren Reed. + * Copyright (C) 2012 by Darren Reed. * * See the IPFILTER.LICENCE file for details on licencing. * - * $Id: alist_free.c,v 1.1.2.1 2006/08/25 21:13:04 darrenr Exp $ + * $Id: alist_free.c,v 1.3.2.2 2012/07/22 08:04:24 darren_r Exp $ */ #include "ipf.h" void alist_free(hosts) -alist_t *hosts; + alist_t *hosts; { alist_t *a, *next; diff --git a/contrib/ipfilter/lib/alist_new.c b/contrib/ipfilter/lib/alist_new.c index 50a4275e7d54..73bc03073990 100644 --- a/contrib/ipfilter/lib/alist_new.c +++ b/contrib/ipfilter/lib/alist_new.c @@ -1,20 +1,30 @@ /* - * Copyright (C) 2006 by Darren Reed. + * Copyright (C) 2012 by Darren Reed. * * See the IPFILTER.LICENCE file for details on licencing. * - * $Id: alist_new.c,v 1.1.2.3 2007/06/06 08:05:33 darrenr Exp $ + * $Id: alist_new.c,v 1.5.2.2 2012/07/22 08:04:24 darren_r Exp $ */ #include "ipf.h" +#include -alist_t * -alist_new(int v, char *host) +alist_t * +alist_new(int family, char *host) { int a, b, c, d, bits; - char *slash; - alist_t *al; - u_int mask; + char *slash; + alist_t *al; + u_int mask; + + if (family == AF_UNSPEC) { + if (strchr(host, ':') != NULL) + family = AF_INET6; + else + family = AF_INET; + } + if (family != AF_INET && family != AF_INET6) + return NULL; al = calloc(1, sizeof(*al)); if (al == NULL) { @@ -22,45 +32,62 @@ alist_new(int v, char *host) return NULL; } - bits = -1; + while (ISSPACE(*host)) + host++; + + if (*host == '!') { + al->al_not = 1; + host++; + while (ISSPACE(*host)) + host++; + } + + bits = -1; slash = strchr(host, '/'); if (slash != NULL) { *slash = '\0'; bits = atoi(slash + 1); } - a = b = c = d = -1; - sscanf(host, "%d.%d.%d.%d", &a, &b, &c, &d); + if (family == AF_INET) { + if (bits > 32) + goto bad; - if (bits > 0 && bits < 33) { - mask = 0xffffffff << (32 - bits); - } else if (b == -1) { - mask = 0xff000000; - b = c = d = 0; - } else if (c == -1) { - mask = 0xffff0000; - c = d = 0; - } else if (d == -1) { - mask = 0xffffff00; - d = 0; + a = b = c = d = -1; + sscanf(host, "%d.%d.%d.%d", &a, &b, &c, &d); + + if (bits > 0 && bits < 33) { + mask = 0xffffffff << (32 - bits); + } else if (b == -1) { + mask = 0xff000000; + b = c = d = 0; + } else if (c == -1) { + mask = 0xffff0000; + c = d = 0; + } else if (d == -1) { + mask = 0xffffff00; + d = 0; + } else { + mask = 0xffffffff; + } + al->al_mask = htonl(mask); } else { - mask = 0xffffffff; + if (bits > 128) + goto bad; + fill6bits(bits, al->al_i6mask.i6); } - if (*host == '!') { - al->al_not = 1; - host++; - } - - if (gethost(host, &al->al_addr) == -1) { + if (gethost(family, host, &al->al_i6addr) == -1) { if (slash != NULL) *slash = '/'; fprintf(stderr, "Cannot parse hostname\n"); - free(al); - return NULL; + goto bad; } - al->al_mask = htonl(mask); + al->al_family = family; if (slash != NULL) *slash = '/'; return al; +bad: + free(al); + return NULL; } diff --git a/contrib/ipfilter/lib/allocmbt.c b/contrib/ipfilter/lib/allocmbt.c new file mode 100644 index 000000000000..df776842736c --- /dev/null +++ b/contrib/ipfilter/lib/allocmbt.c @@ -0,0 +1,22 @@ +/* + * Copyright (C) 2012 by Darren Reed. + * + * See the IPFILTER.LICENCE file for details on licencing. + * + * $Id: allocmbt.c,v 1.1.4.1 2012/07/22 08:04:24 darren_r Exp $ + */ + +#include "ipf.h" + +mb_t *allocmbt(size_t len) +{ + mb_t *m; + + m = (mb_t *)malloc(sizeof(mb_t)); + if (m == NULL) + return NULL; + m->mb_len = len; + m->mb_next = NULL; + m->mb_data = (char *)m->mb_buf; + return m; +} diff --git a/contrib/ipfilter/lib/assigndefined.c b/contrib/ipfilter/lib/assigndefined.c new file mode 100644 index 000000000000..34f8d9af3acc --- /dev/null +++ b/contrib/ipfilter/lib/assigndefined.c @@ -0,0 +1,27 @@ +/* + * Copyright (C) 2012 by Darren Reed. + * + * See the IPFILTER.LICENCE file for details on licencing. + * + * $Id: assigndefined.c,v 1.4.2.2 2012/07/22 08:04:24 darren_r Exp $ + */ + +#include "ipf.h" + +void assigndefined(env) + char *env; +{ + char *s, *t; + + if (env == NULL) + return; + + for (s = strtok(env, ";"); s != NULL; s = strtok(NULL, ";")) { + t = strchr(s, '='); + if (t == NULL) + continue; + *t++ = '\0'; + set_variable(s, t); + *--t = '='; + } +} diff --git a/contrib/ipfilter/lib/bcopywrap.c b/contrib/ipfilter/lib/bcopywrap.c index b2e8427a7b37..453c0464846f 100644 --- a/contrib/ipfilter/lib/bcopywrap.c +++ b/contrib/ipfilter/lib/bcopywrap.c @@ -1,18 +1,18 @@ /* $FreeBSD$ */ /* - * Copyright (C) 2002 by Darren Reed. + * Copyright (C) 2012 by Darren Reed. * * See the IPFILTER.LICENCE file for details on licencing. - * - * $Id: bcopywrap.c,v 1.1.4.1 2006/06/16 17:20:56 darrenr Exp $ - */ + * + * $Id$ + */ #include "ipf.h" int bcopywrap(from, to, size) -void *from, *to; -size_t size; + void *from, *to; + size_t size; { bcopy((caddr_t)from, (caddr_t)to, size); return 0; diff --git a/contrib/ipfilter/lib/binprint.c b/contrib/ipfilter/lib/binprint.c index fcb47ed37e5b..f826721e0d21 100644 --- a/contrib/ipfilter/lib/binprint.c +++ b/contrib/ipfilter/lib/binprint.c @@ -1,19 +1,19 @@ /* $FreeBSD$ */ /* - * Copyright (C) 2000-2002 by Darren Reed. + * Copyright (C) 2012 by Darren Reed. * * See the IPFILTER.LICENCE file for details on licencing. * - * $Id: binprint.c,v 1.8.4.1 2006/06/16 17:20:56 darrenr Exp $ + * $Id$ */ #include "ipf.h" void binprint(ptr, size) -void *ptr; -size_t size; + void *ptr; + size_t size; { u_char *s; int i, j; diff --git a/contrib/ipfilter/lib/buildopts.c b/contrib/ipfilter/lib/buildopts.c index bdd0538fdd14..1d1de8c36784 100644 --- a/contrib/ipfilter/lib/buildopts.c +++ b/contrib/ipfilter/lib/buildopts.c @@ -1,19 +1,19 @@ /* $FreeBSD$ */ /* - * Copyright (C) 2000-2002 by Darren Reed. + * Copyright (C) 2012 by Darren Reed. * * See the IPFILTER.LICENCE file for details on licencing. * - * $Id: buildopts.c,v 1.6.4.1 2006/06/16 17:20:56 darrenr Exp $ + * $Id$ */ #include "ipf.h" u_32_t buildopts(cp, op, len) -char *cp, *op; -int len; + char *cp, *op; + int len; { struct ipopt_names *io; u_32_t msk = 0; @@ -23,6 +23,8 @@ int len; for (s = strtok(cp, ","); s; s = strtok(NULL, ",")) { if ((t = strchr(s, '='))) *t++ = '\0'; + else + t = ""; for (io = ionames; io->on_name; io++) { if (strcasecmp(s, io->on_name) || (msk & io->on_bit)) continue; @@ -38,6 +40,10 @@ int len; return 0; } } + while ((len & 3) != 3) { + *op++ = IPOPT_NOP; + len++; + } *op++ = IPOPT_EOL; len++; return len; diff --git a/contrib/ipfilter/lib/checkrev.c b/contrib/ipfilter/lib/checkrev.c index 9e584cc48d89..b6f8eeec1fc2 100644 --- a/contrib/ipfilter/lib/checkrev.c +++ b/contrib/ipfilter/lib/checkrev.c @@ -1,11 +1,11 @@ /* $FreeBSD$ */ /* - * Copyright (C) 2000-2004 by Darren Reed. + * Copyright (C) 2012 by Darren Reed. * * See the IPFILTER.LICENCE file for details on licencing. * - * $Id: checkrev.c,v 1.12.2.2 2006/06/16 17:20:56 darrenr Exp $ + * $Id$ */ #include @@ -15,25 +15,25 @@ #include "netinet/ipl.h" int checkrev(ipfname) -char *ipfname; + char *ipfname; { static int vfd = -1; - struct friostat fio, *fiop = &fio; - ipfobj_t ipfo; + struct friostat fio; + ipfobj_t obj; - bzero((caddr_t)&ipfo, sizeof(ipfo)); - ipfo.ipfo_rev = IPFILTER_VERSION; - ipfo.ipfo_size = sizeof(*fiop); - ipfo.ipfo_ptr = (void *)fiop; - ipfo.ipfo_type = IPFOBJ_IPFSTAT; + bzero((caddr_t)&obj, sizeof(obj)); + obj.ipfo_rev = IPFILTER_VERSION; + obj.ipfo_size = sizeof(fio); + obj.ipfo_ptr = (void *)&fio; + obj.ipfo_type = IPFOBJ_IPFSTAT; if ((vfd == -1) && ((vfd = open(ipfname, O_RDONLY)) == -1)) { perror("open device"); return -1; } - if (ioctl(vfd, SIOCGETFS, &ipfo)) { - perror("ioctl(SIOCGETFS)"); + if (ioctl(vfd, SIOCGETFS, &obj)) { + ipferror(vfd, "ioctl(SIOCGETFS)"); close(vfd); vfd = -1; return -1; diff --git a/contrib/ipfilter/lib/connecttcp.c b/contrib/ipfilter/lib/connecttcp.c new file mode 100644 index 000000000000..2bab2afe0daa --- /dev/null +++ b/contrib/ipfilter/lib/connecttcp.c @@ -0,0 +1,48 @@ +/* + * Copyright (C) 2012 by Darren Reed. + * + * See the IPFILTER.LICENCE file for details on licencing. + * + * $Id: connecttcp.c,v 1.3.2.2 2012/07/22 08:04:24 darren_r Exp $ + */ + +#include "ipf.h" +#include + +/* + * Format expected is one addres per line, at the start of each line. + */ +int +connecttcp(char *server, int port) +{ + struct sockaddr_in sin; + struct hostent *host; + int fd; + + memset(&sin, 0, sizeof(sin)); + sin.sin_family = AF_INET; + sin.sin_port = htons(port & 65535); + + if (ISDIGIT(*server)) { + if (inet_aton(server, &sin.sin_addr) == -1) { + return -1; + } + } else { + host = gethostbyname(server); + if (host == NULL) + return -1; + memcpy(&sin.sin_addr, host->h_addr_list[0], + sizeof(sin.sin_addr)); + } + + fd = socket(AF_INET, SOCK_STREAM, 0); + if (fd == -1) + return -1; + + if (connect(fd, (struct sockaddr *)&sin, sizeof(sin)) == -1) { + close(fd); + return -1; + } + + return fd; +} diff --git a/contrib/ipfilter/lib/count4bits.c b/contrib/ipfilter/lib/count4bits.c index 38e574290c69..a847388fad8e 100644 --- a/contrib/ipfilter/lib/count4bits.c +++ b/contrib/ipfilter/lib/count4bits.c @@ -1,11 +1,11 @@ /* $FreeBSD$ */ /* - * Copyright (C) 2002 by Darren Reed. + * Copyright (C) 2012 by Darren Reed. * * See the IPFILTER.LICENCE file for details on licencing. * - * $Id: count4bits.c,v 1.1.4.1 2006/06/16 17:20:57 darrenr Exp $ + * $Id$ */ #include "ipf.h" @@ -17,7 +17,7 @@ * of bits. */ int count4bits(ip) -u_int ip; + u_int ip; { int cnt = 0, i, j; u_int ipn; diff --git a/contrib/ipfilter/lib/count6bits.c b/contrib/ipfilter/lib/count6bits.c index 15538c36c19c..b8f43206a8bd 100644 --- a/contrib/ipfilter/lib/count6bits.c +++ b/contrib/ipfilter/lib/count6bits.c @@ -1,18 +1,18 @@ /* $FreeBSD$ */ /* - * Copyright (C) 2000-2001 by Darren Reed. + * Copyright (C) 2012 by Darren Reed. * * See the IPFILTER.LICENCE file for details on licencing. * - * $Id: count6bits.c,v 1.4.4.1 2006/06/16 17:20:57 darrenr Exp $ + * $Id$ */ #include "ipf.h" int count6bits(msk) -u_32_t *msk; + u_32_t *msk; { int i = 0, k; u_32_t j; diff --git a/contrib/ipfilter/lib/debug.c b/contrib/ipfilter/lib/debug.c index 3181e78e1e10..02e5f5b48775 100644 --- a/contrib/ipfilter/lib/debug.c +++ b/contrib/ipfilter/lib/debug.c @@ -1,11 +1,11 @@ /* $FreeBSD$ */ /* - * Copyright (C) 2000-2001 by Darren Reed. + * Copyright (C) 2012 by Darren Reed. * * See the IPFILTER.LICENCE file for details on licencing. * - * $Id: debug.c,v 1.6.4.1 2006/06/16 17:20:57 darrenr Exp $ + * $Id$ */ #if defined(__STDC__) @@ -15,16 +15,37 @@ #endif #include -#include "ipt.h" +#include "ipf.h" #include "opts.h" +int debuglevel = 0; + #ifdef __STDC__ -void debug(char *fmt, ...) +void debug(int level, char *fmt, ...) #else -void debug(fmt, va_alist) -char *fmt; -va_dcl +void debug(level, fmt, va_alist) + int level; + char *fmt; + va_dcl +#endif +{ + va_list pvar; + + va_start(pvar, fmt); + + if ((debuglevel > 0) && (level <= debuglevel)) + vfprintf(stderr, fmt, pvar); + va_end(pvar); +} + + +#ifdef __STDC__ +void ipfkdebug(char *fmt, ...) +#else +void ipfkdebug(fmt, va_alist) + char *fmt; + va_dcl #endif { va_list pvar; @@ -32,6 +53,6 @@ va_dcl va_start(pvar, fmt); if (opts & OPT_DEBUG) - vprintf(fmt, pvar); + debug(0x1fffffff, fmt, pvar); va_end(pvar); } diff --git a/contrib/ipfilter/lib/dupmbt.c b/contrib/ipfilter/lib/dupmbt.c new file mode 100644 index 000000000000..0929eeb54229 --- /dev/null +++ b/contrib/ipfilter/lib/dupmbt.c @@ -0,0 +1,24 @@ +/* + * Copyright (C) 2012 by Darren Reed. + * + * See the IPFILTER.LICENCE file for details on licencing. + * + * $Id: dupmbt.c,v 1.3.2.2 2012/07/22 08:04:24 darren_r Exp $ + */ + +#include "ipf.h" + +mb_t *dupmbt(orig) + mb_t *orig; +{ + mb_t *m; + + m = (mb_t *)malloc(sizeof(mb_t)); + if (m == NULL) + return NULL; + m->mb_len = orig->mb_len; + m->mb_next = NULL; + m->mb_data = (char *)m->mb_buf + (orig->mb_data - (char *)orig->mb_buf); + bcopy(orig->mb_data, m->mb_data, m->mb_len); + return m; +} diff --git a/contrib/ipfilter/lib/facpri.c b/contrib/ipfilter/lib/facpri.c index b89e0f8e0127..c9b47746b3ac 100644 --- a/contrib/ipfilter/lib/facpri.c +++ b/contrib/ipfilter/lib/facpri.c @@ -1,11 +1,11 @@ /* $FreeBSD$ */ /* - * Copyright (C) 2000-2006 by Darren Reed. + * Copyright (C) 2012 by Darren Reed. * * See the IPFILTER.LICENCE file for details on licencing. * - * $Id: facpri.c,v 1.6.2.5 2006/06/16 17:20:58 darrenr Exp $ + * $Id$ */ #include @@ -22,7 +22,7 @@ #include "facpri.h" #if !defined(lint) -static const char rcsid[] = "@(#)$Id: facpri.c,v 1.6.2.5 2006/06/16 17:20:58 darrenr Exp $"; +static const char rcsid[] = "@(#)$Id$"; #endif @@ -96,7 +96,7 @@ fac_toname(facpri) /* * map a facility name to its number */ -int +int fac_findname(name) char *name; { @@ -118,6 +118,22 @@ table_t pris[] = { }; +/* + * map a facility name to its number + */ +int +pri_findname(name) + char *name; +{ + int i; + + for (i = 0; pris[i].name; i++) + if (!strcmp(pris[i].name, name)) + return pris[i].value; + return -1; +} + + /* * map a priority number to its name */ diff --git a/contrib/ipfilter/lib/facpri.h b/contrib/ipfilter/lib/facpri.h index ca53e051f90d..54ecabd6ce49 100644 --- a/contrib/ipfilter/lib/facpri.h +++ b/contrib/ipfilter/lib/facpri.h @@ -1,11 +1,11 @@ /* $FreeBSD$ */ /* - * Copyright (C) 2000-2001 by Darren Reed. + * Copyright (C) 2012 by Darren Reed. * * See the IPFILTER.LICENCE file for details on licencing. * - * $Id: facpri.h,v 1.3.4.1 2006/06/16 17:20:58 darrenr Exp $ + * $Id$ */ #ifndef __FACPRI_H__ diff --git a/contrib/ipfilter/lib/familyname.c b/contrib/ipfilter/lib/familyname.c new file mode 100644 index 000000000000..35bb975cc6b1 --- /dev/null +++ b/contrib/ipfilter/lib/familyname.c @@ -0,0 +1,12 @@ +#include "ipf.h" + +const char *familyname(int family) +{ + if (family == AF_INET) + return "inet"; +#ifdef AF_INET6 + if (family == AF_INET6) + return "inet6"; +#endif + return "unknown"; +} diff --git a/contrib/ipfilter/lib/fill6bits.c b/contrib/ipfilter/lib/fill6bits.c index c0faf6ae5f20..39ec735f8ee9 100644 --- a/contrib/ipfilter/lib/fill6bits.c +++ b/contrib/ipfilter/lib/fill6bits.c @@ -1,19 +1,19 @@ /* $FreeBSD$ */ /* - * Copyright (C) 2000-2002 by Darren Reed. + * Copyright (C) 2012 by Darren Reed. * * See the IPFILTER.LICENCE file for details on licencing. * - * $Id: fill6bits.c,v 1.5.4.1 2006/06/16 17:20:58 darrenr Exp $ + * $Id$ */ #include "ipf.h" void fill6bits(bits, msk) -int bits; -u_int *msk; + int bits; + u_int *msk; { if (bits == 0) { msk[0] = 0; diff --git a/contrib/ipfilter/lib/findword.c b/contrib/ipfilter/lib/findword.c new file mode 100644 index 000000000000..e06f213c0540 --- /dev/null +++ b/contrib/ipfilter/lib/findword.c @@ -0,0 +1,25 @@ +/* + * Copyright (C) 2012 by Darren Reed. + * + * See the IPFILTER.LICENCE file for details on licencing. + * + * $Id: findword.c,v 1.3.4.1 2012/07/22 08:04:24 darren_r Exp $ + */ + +#include "ipf.h" + + +wordtab_t *findword(words, name) + wordtab_t *words; + char *name; +{ + wordtab_t *w; + + for (w = words; w->w_word != NULL; w++) + if (!strcmp(name, w->w_word)) + break; + if (w->w_word == NULL) + return NULL; + + return w; +} diff --git a/contrib/ipfilter/lib/flags.c b/contrib/ipfilter/lib/flags.c index 200484c2231c..05fcc9874866 100644 --- a/contrib/ipfilter/lib/flags.c +++ b/contrib/ipfilter/lib/flags.c @@ -1,11 +1,11 @@ /* $FreeBSD$ */ /* - * Copyright (C) 2001-2002 by Darren Reed. + * Copyright (C) 2012 by Darren Reed. * * See the IPFILTER.LICENCE file for details on licencing. * - * $Id: flags.c,v 1.4.4.1 2006/06/16 17:20:58 darrenr Exp $ + * $Id$ */ #include "ipf.h" diff --git a/contrib/ipfilter/lib/freembt.c b/contrib/ipfilter/lib/freembt.c new file mode 100644 index 000000000000..0fc748decd65 --- /dev/null +++ b/contrib/ipfilter/lib/freembt.c @@ -0,0 +1,16 @@ +/* + * Copyright (C) 2012 by Darren Reed. + * + * See the IPFILTER.LICENCE file for details on licencing. + * + * $Id: freembt.c,v 1.3.2.2 2012/07/22 08:04:24 darren_r Exp $ + */ + +#include "ipf.h" + +void freembt(m) + mb_t *m; +{ + + free(m); +} diff --git a/contrib/ipfilter/lib/ftov.c b/contrib/ipfilter/lib/ftov.c new file mode 100644 index 000000000000..cb9715de450f --- /dev/null +++ b/contrib/ipfilter/lib/ftov.c @@ -0,0 +1,16 @@ +#include "ipf.h" + +int +ftov(version) + int version; +{ +#ifdef USE_INET6 + if (version == AF_INET6) + return 6; +#endif + if (version == AF_INET) + return 4; + if (version == AF_UNSPEC) + return 0; + return -1; +} diff --git a/contrib/ipfilter/lib/gethost.c b/contrib/ipfilter/lib/gethost.c index be536c1e755d..a11b09b2e49f 100644 --- a/contrib/ipfilter/lib/gethost.c +++ b/contrib/ipfilter/lib/gethost.c @@ -1,44 +1,75 @@ /* $FreeBSD$ */ /* - * Copyright (C) 2002-2004 by Darren Reed. - * - * See the IPFILTER.LICENCE file for details on licencing. - * - * $Id: gethost.c,v 1.3.2.2 2006/06/16 17:20:59 darrenr Exp $ - */ + * Copyright (C) 2012 by Darren Reed. + * + * See the IPFILTER.LICENCE file for details on licencing. + * + * $Id$ + */ #include "ipf.h" -int gethost(name, hostp) -char *name; -u_32_t *hostp; +int gethost(family, name, hostp) + int family; + char *name; + i6addr_t *hostp; { struct hostent *h; struct netent *n; u_32_t addr; if (!strcmp(name, "test.host.dots")) { - *hostp = htonl(0xfedcba98); + if (family == AF_INET) { + hostp->in4.s_addr = htonl(0xfedcba98); + } +#ifdef USE_INET6 + if (family == AF_INET6) { + hostp->i6[0] = 0xfe80aa55; + hostp->i6[1] = 0x12345678; + hostp->i6[2] = 0x5a5aa5a5; + hostp->i6[3] = 0xfedcba98; + } +#endif return 0; } if (!strcmp(name, "")) name = thishost; - h = gethostbyname(name); - if (h != NULL) { - if ((h->h_addr != NULL) && (h->h_length == sizeof(addr))) { - bcopy(h->h_addr, (char *)&addr, sizeof(addr)); - *hostp = addr; + if (family == AF_INET) { + h = gethostbyname(name); + if (h != NULL) { + if ((h->h_addr != NULL) && + (h->h_length == sizeof(addr))) { + bcopy(h->h_addr, (char *)&addr, sizeof(addr)); + hostp->in4.s_addr = addr; + return 0; + } + } + + n = getnetbyname(name); + if (n != NULL) { + hostp->in4.s_addr = htonl(n->n_net & 0xffffffff); return 0; } } +#ifdef USE_INET6 + if (family == AF_INET6) { + struct addrinfo hints, *res; + struct sockaddr_in6 *sin6; - n = getnetbyname(name); - if (n != NULL) { - *hostp = (u_32_t)htonl(n->n_net & 0xffffffff); - return 0; + bzero((char *)&hints, sizeof(hints)); + hints.ai_family = PF_INET6; + + getaddrinfo(name, NULL, &hints, &res); + if (res != NULL) { + sin6 = (struct sockaddr_in6 *)res->ai_addr; + hostp->in6 = sin6->sin6_addr; + freeaddrinfo(res); + return 0; + } } +#endif return -1; } diff --git a/contrib/ipfilter/lib/geticmptype.c b/contrib/ipfilter/lib/geticmptype.c new file mode 100644 index 000000000000..5c962e949526 --- /dev/null +++ b/contrib/ipfilter/lib/geticmptype.c @@ -0,0 +1,29 @@ +/* + * Copyright (C) 2012 by Darren Reed. + * + * See the IPFILTER.LICENCE file for details on licencing. + * + * $Id$ + */ +#include "ipf.h" + +int geticmptype(family, name) + int family; + char *name; +{ + icmptype_t *i; + + for (i = icmptypelist; i->it_name != NULL; i++) { + if (!strcmp(name, i->it_name)) { + if (family == AF_INET) + return i->it_v4; +#ifdef USE_INET6 + if (family == AF_INET6) + return i->it_v6; +#endif + return -1; + } + } + + return -1; +} diff --git a/contrib/ipfilter/lib/getifname.c b/contrib/ipfilter/lib/getifname.c index 7246fbb83714..88cad329f1e3 100644 --- a/contrib/ipfilter/lib/getifname.c +++ b/contrib/ipfilter/lib/getifname.c @@ -1,12 +1,12 @@ /* $FreeBSD$ */ /* - * Copyright (C) 2002-2004 by Darren Reed. - * - * See the IPFILTER.LICENCE file for details on licencing. - * - * $Id: getifname.c,v 1.5.2.3 2006/07/14 06:12:24 darrenr Exp $ - */ + * Copyright (C) 2012 by Darren Reed. + * + * See the IPFILTER.LICENCE file for details on licencing. + * + * $Id$ + */ #include "ipf.h" @@ -18,7 +18,7 @@ */ #if 0 char *getifname(ptr) -struct ifnet *ptr; + struct ifnet *ptr; { #if SOLARIS || defined(__hpux) # if SOLARIS @@ -50,7 +50,7 @@ struct ifnet *ptr; defined(__OpenBSD__) || \ (defined(__FreeBSD__) && (__FreeBSD_version >= 501113)) #else - char buf[32]; + char buf[LIFNAMSIZ]; int len; # endif struct ifnet netif; @@ -85,8 +85,11 @@ struct ifnet *ptr; } #else char *getifname(ptr) -struct ifnet *ptr; + struct ifnet *ptr; { +#if 0 + ptr = ptr; +#endif return "X"; } #endif diff --git a/contrib/ipfilter/lib/getnattype.c b/contrib/ipfilter/lib/getnattype.c index 2fb5d174e4a2..ef7ffd47a050 100644 --- a/contrib/ipfilter/lib/getnattype.c +++ b/contrib/ipfilter/lib/getnattype.c @@ -1,7 +1,7 @@ /* $FreeBSD$ */ /* - * Copyright (C) 2002-2004 by Darren Reed. + * Copyright (C) 2012 by Darren Reed. * * See the IPFILTER.LICENCE file for details on licencing. * @@ -11,34 +11,24 @@ #include "kmem.h" #if !defined(lint) -static const char rcsid[] = "@(#)$Id: getnattype.c,v 1.3.2.2 2006/07/14 06:12:24 darrenr Exp $"; +static const char rcsid[] = "@(#)$Id$"; #endif /* * Get a nat filter type given its kernel address. */ -char *getnattype(nat, alive) -nat_t *nat; -int alive; +char * +getnattype(nat) + nat_t *nat; { static char unknownbuf[20]; - ipnat_t *ipn, ipnat; char *which; - int type; if (!nat) return "???"; - if (alive) { - type = nat->nat_redir; - } else { - ipn = nat->nat_ptr; - if (kmemcpy((char *)&ipnat, (long)ipn, sizeof(ipnat))) - return "!!!"; - type = ipnat.in_redir; - } - switch (type) + switch (nat->nat_redir) { case NAT_MAP : which = "MAP"; @@ -49,11 +39,30 @@ int alive; case NAT_REDIRECT : which = "RDR"; break; + case NAT_MAP|NAT_REWRITE : + which = "RWR-MAP"; + break; + case NAT_REDIRECT|NAT_REWRITE : + which = "RWR-RDR"; + break; case NAT_BIMAP : which = "BIMAP"; break; + case NAT_REDIRECT|NAT_DIVERTUDP : + which = "DIV-RDR"; + break; + case NAT_MAP|NAT_DIVERTUDP : + which = "DIV-MAP"; + break; + case NAT_REDIRECT|NAT_ENCAP : + which = "ENC-RDR"; + break; + case NAT_MAP|NAT_ENCAP : + which = "ENC-MAP"; + break; default : - sprintf(unknownbuf, "unknown(%04x)", type & 0xffffffff); + sprintf(unknownbuf, "unknown(%04x)", + nat->nat_redir & 0xffffffff); which = unknownbuf; break; } diff --git a/contrib/ipfilter/lib/getport.c b/contrib/ipfilter/lib/getport.c index 69e897c660c3..0981ff172b96 100644 --- a/contrib/ipfilter/lib/getport.c +++ b/contrib/ipfilter/lib/getport.c @@ -1,30 +1,39 @@ /* $FreeBSD$ */ /* - * Copyright (C) 2002-2005 by Darren Reed. - * - * See the IPFILTER.LICENCE file for details on licencing. - * - * $Id: getport.c,v 1.1.4.6 2006/06/16 17:21:00 darrenr Exp $ - */ + * Copyright (C) 2012 by Darren Reed. + * + * See the IPFILTER.LICENCE file for details on licencing. + * + * $Id$ + */ #include "ipf.h" +#include -int getport(fr, name, port) -frentry_t *fr; -char *name; -u_short *port; +int getport(fr, name, port, proto) + frentry_t *fr; + char *name, *proto; + u_short *port; { struct protoent *p; struct servent *s; u_short p1; if (fr == NULL || fr->fr_type != FR_T_IPF) { - s = getservbyname(name, NULL); + s = getservbyname(name, proto); if (s != NULL) { *port = s->s_port; return 0; } + + if (ISDIGIT(*name)) { + int portval = atoi(name); + if (portval < 0 || portval > 65535) + return -1; + *port = htons((u_short)portval); + return 0; + } return -1; } diff --git a/contrib/ipfilter/lib/getportproto.c b/contrib/ipfilter/lib/getportproto.c index 23e5fb18a6a5..69fecff157fd 100644 --- a/contrib/ipfilter/lib/getportproto.c +++ b/contrib/ipfilter/lib/getportproto.c @@ -1,19 +1,19 @@ /* $FreeBSD$ */ /* - * Copyright (C) 2002-2005 by Darren Reed. - * - * See the IPFILTER.LICENCE file for details on licencing. - * - * $Id: getportproto.c,v 1.2.4.4 2006/06/16 17:21:00 darrenr Exp $ - */ + * Copyright (C) 2012 by Darren Reed. + * + * See the IPFILTER.LICENCE file for details on licencing. + * + * $Id$ + */ #include #include "ipf.h" int getportproto(name, proto) -char *name; -int proto; + char *name; + int proto; { struct servent *s; struct protoent *p; diff --git a/contrib/ipfilter/lib/getproto.c b/contrib/ipfilter/lib/getproto.c index 33f6f47ac1b9..6c52cd3b7677 100644 --- a/contrib/ipfilter/lib/getproto.c +++ b/contrib/ipfilter/lib/getproto.c @@ -1,17 +1,18 @@ /* $FreeBSD$ */ /* - * Copyright (C) 2002-2005 by Darren Reed. - * - * See the IPFILTER.LICENCE file for details on licencing. - * - * $Id: getproto.c,v 1.2.2.3 2006/06/16 17:21:00 darrenr Exp $ - */ + * Copyright (C) 2012 by Darren Reed. + * + * See the IPFILTER.LICENCE file for details on licencing. + * + * $Id$ + */ #include "ipf.h" +#include int getproto(name) -char *name; + char *name; { struct protoent *p; char *s; @@ -25,10 +26,13 @@ char *name; #ifdef _AIX51 /* * For some bogus reason, "ip" is 252 in /etc/protocols on AIX 5 + * The IANA has doubled up on the definition of 0 - it is now also + * used for IPv6 hop-opts, so we can no longer rely on /etc/protocols + * providing the correct name->number mapping */ +#endif if (!strcasecmp(name, "ip")) return 0; -#endif p = getprotobyname(name); if (p != NULL) diff --git a/contrib/ipfilter/lib/getsumd.c b/contrib/ipfilter/lib/getsumd.c index fdad461673e3..84acc7a282ed 100644 --- a/contrib/ipfilter/lib/getsumd.c +++ b/contrib/ipfilter/lib/getsumd.c @@ -1,17 +1,17 @@ /* $FreeBSD$ */ /* - * Copyright (C) 2002 by Darren Reed. - * - * See the IPFILTER.LICENCE file for details on licencing. - * - * $Id: getsumd.c,v 1.2.4.1 2006/06/16 17:21:01 darrenr Exp $ - */ + * Copyright (C) 2012 by Darren Reed. + * + * See the IPFILTER.LICENCE file for details on licencing. + * + * $Id$ + */ #include "ipf.h" char *getsumd(sum) -u_32_t sum; + u_32_t sum; { static char sumdbuf[17]; diff --git a/contrib/ipfilter/lib/hostname.c b/contrib/ipfilter/lib/hostname.c index e8fde98e5efa..28ead89a54f8 100644 --- a/contrib/ipfilter/lib/hostname.c +++ b/contrib/ipfilter/lib/hostname.c @@ -1,18 +1,18 @@ /* $FreeBSD$ */ /* - * Copyright (C) 2002-2003 by Darren Reed. - * - * See the IPFILTER.LICENCE file for details on licencing. - * - * $Id: hostname.c,v 1.6.2.2 2007/01/16 02:25:22 darrenr Exp $ - */ + * Copyright (C) 2012 by Darren Reed. + * + * See the IPFILTER.LICENCE file for details on licencing. + * + * $Id$ + */ #include "ipf.h" -char *hostname(v, ip) -int v; -void *ip; +char *hostname(family, ip) + int family; + void *ip; { static char hostbuf[MAXHOSTNAMELEN+1]; struct hostent *hp; @@ -21,14 +21,14 @@ void *ip; memset(&ipa, 0, sizeof(ipa)); /* XXX gcc */ - if (v == 4) { + if (family == AF_INET) { ipa.s_addr = *(u_32_t *)ip; if (ipa.s_addr == htonl(0xfedcba98)) return "test.host.dots"; } if ((opts & OPT_NORESOLVE) == 0) { - if (v == 4) { + if (family == AF_INET) { hp = gethostbyaddr(ip, 4, AF_INET); if (hp != NULL && hp->h_name != NULL && *hp->h_name != '\0') { @@ -47,7 +47,7 @@ void *ip; } } - if (v == 4) { + if (family == AF_INET) { return inet_ntoa(ipa); } #ifdef USE_INET6 diff --git a/contrib/ipfilter/lib/icmpcode.c b/contrib/ipfilter/lib/icmpcode.c index d558bebf7de6..e898ebfa39a5 100644 --- a/contrib/ipfilter/lib/icmpcode.c +++ b/contrib/ipfilter/lib/icmpcode.c @@ -1,11 +1,11 @@ /* $FreeBSD$ */ /* - * Copyright (C) 2000-2006 by Darren Reed. + * Copyright (C) 2012 by Darren Reed. * * See the IPFILTER.LICENCE file for details on licencing. * - * $Id: icmpcode.c,v 1.7.2.5 2006/06/16 17:21:02 darrenr Exp $ + * $Id$ */ #include diff --git a/contrib/ipfilter/lib/icmptypename.c b/contrib/ipfilter/lib/icmptypename.c new file mode 100644 index 000000000000..d7eb3bd3ab73 --- /dev/null +++ b/contrib/ipfilter/lib/icmptypename.c @@ -0,0 +1,28 @@ +/* + * Copyright (C) 2012 by Darren Reed. + * + * See the IPFILTER.LICENCE file for details on licencing. + * + * $Id$ + */ +#include "ipf.h" + +char *icmptypename(family, type) + int family, type; +{ + icmptype_t *i; + + if ((type < 0) || (type > 255)) + return NULL; + + for (i = icmptypelist; i->it_name != NULL; i++) { + if ((family == AF_INET) && (i->it_v4 == type)) + return i->it_name; +#ifdef USE_INET6 + if ((family == AF_INET6) && (i->it_v6 == type)) + return i->it_name; +#endif + } + + return NULL; +} diff --git a/contrib/ipfilter/lib/icmptypes.c b/contrib/ipfilter/lib/icmptypes.c new file mode 100644 index 000000000000..c1123ff5e04d --- /dev/null +++ b/contrib/ipfilter/lib/icmptypes.c @@ -0,0 +1,107 @@ +/* + * Copyright (C) 2012 by Darren Reed. + * + * See the IPFILTER.LICENCE file for details on licencing. + * + * $Id$ + */ +#include "ipf.h" + +#ifndef USE_INET6 +# undef ICMP6_ECHO_REQUEST +# define ICMP6_ECHO_REQUEST 0 +# undef ICMP6_ECHO_REPLY +# define ICMP6_ECHO_REPLY 0 +# undef ICMP6_NI_QUERY +# define ICMP6_NI_QUERY 0 +# undef ICMP6_NI_REPLY +# define ICMP6_NI_REPLY 0 +# undef ICMP6_PARAM_PROB +# define ICMP6_PARAM_PROB 0 +# undef ND_ROUTER_ADVERT +# define ND_ROUTER_ADVERT 0 +# undef ND_ROUTER_SOLICIT +# define ND_ROUTER_SOLICIT 0 +# undef ICMP6_TIME_EXCEEDED +# define ICMP6_TIME_EXCEEDED 0 +# undef ICMP6_DST_UNREACH +# define ICMP6_DST_UNREACH 0 +# undef ICMP6_PACKET_TOO_BIG +# define ICMP6_PACKET_TOO_BIG 0 +# undef MLD_LISTENER_QUERY +# define MLD_LISTENER_QUERY 0 +# undef MLD_LISTENER_REPORT +# define MLD_LISTENER_REPORT 0 +# undef MLD_LISTENER_DONE +# define MLD_LISTENER_DONE 0 +# undef ICMP6_MEMBERSHIP_QUERY +# define ICMP6_MEMBERSHIP_QUERY 0 +# undef ICMP6_MEMBERSHIP_REPORT +# define ICMP6_MEMBERSHIP_REPORT 0 +# undef ICMP6_MEMBERSHIP_REDUCTION +# define ICMP6_MEMBERSHIP_REDUCTION 0 +# undef ND_NEIGHBOR_ADVERT +# define ND_NEIGHBOR_ADVERT 0 +# undef ND_NEIGHBOR_SOLICIT +# define ND_NEIGHBOR_SOLICIT 0 +# undef ICMP6_ROUTER_RENUMBERING +# define ICMP6_ROUTER_RENUMBERING 0 +# undef ICMP6_WRUREQUEST +# define ICMP6_WRUREQUEST 0 +# undef ICMP6_WRUREPLY +# define ICMP6_WRUREPLY 0 +# undef ICMP6_FQDN_QUERY +# define ICMP6_FQDN_QUERY 0 +# undef ICMP6_FQDN_REPLY +# define ICMP6_FQDN_REPLY 0 +#else +# if !defined(MLD_LISTENER_QUERY) +# define MLD_LISTENER_QUERY 130 +# endif +# if !defined(MLD_LISTENER_REPORT) +# define MLD_LISTENER_REPORT 131 +# endif +# if !defined(MLD_LISTENER_DONE) +# define MLD_LISTENER_DONE 132 +# endif +# if defined(MLD_LISTENER_REDUCTION) && !defined(MLD_LISTENER_DONE) +# define MLD_LISTENER_DONE MLD_LISTENER_REDUCTION +# endif +#endif + +icmptype_t icmptypelist[] = { + { "echo", ICMP_ECHO, ICMP6_ECHO_REQUEST }, + { "echorep", ICMP_ECHOREPLY, ICMP6_ECHO_REPLY }, + { "fqdnquery", -1, ICMP6_FQDN_QUERY }, + { "fqdnreply", -1, ICMP6_FQDN_REPLY }, + { "infoqry", -1, ICMP6_NI_QUERY }, + { "inforeq", ICMP_IREQ, ICMP6_NI_QUERY }, + { "inforep", ICMP_IREQREPLY, ICMP6_NI_REPLY }, + { "listendone", -1, MLD_LISTENER_DONE }, + { "listenqry", -1, MLD_LISTENER_QUERY }, + { "listenrep", -1, MLD_LISTENER_REPORT }, + { "maskrep", ICMP_MASKREPLY, -1 }, + { "maskreq", ICMP_MASKREQ, -1 }, + { "memberqry", -1, ICMP6_MEMBERSHIP_QUERY }, + { "memberred", -1, ICMP6_MEMBERSHIP_REDUCTION }, + { "memberreply",-1, ICMP6_MEMBERSHIP_REPORT }, + { "neighadvert", -1, ND_NEIGHBOR_ADVERT }, + { "neighborsol", -1, ND_NEIGHBOR_SOLICIT }, + { "neighborsolicit", -1, ND_NEIGHBOR_SOLICIT }, + { "paramprob", ICMP_PARAMPROB, ICMP6_PARAM_PROB }, + { "redir", ICMP_REDIRECT, ND_REDIRECT }, + { "renumber", -1, ICMP6_ROUTER_RENUMBERING }, + { "routerad", ICMP_ROUTERADVERT, ND_ROUTER_ADVERT }, + { "routeradvert",ICMP_ROUTERADVERT, ND_ROUTER_ADVERT }, + { "routersol", ICMP_ROUTERSOLICIT, ND_ROUTER_SOLICIT }, + { "routersolcit",ICMP_ROUTERSOLICIT, ND_ROUTER_SOLICIT }, + { "squench", ICMP_SOURCEQUENCH, -1 }, + { "timest", ICMP_TSTAMP, -1 }, + { "timestrep", ICMP_TSTAMPREPLY, -1 }, + { "timex", ICMP_TIMXCEED, ICMP6_TIME_EXCEEDED }, + { "toobig", -1, ICMP6_PACKET_TOO_BIG }, + { "unreach", ICMP_UNREACH, ICMP6_DST_UNREACH }, + { "whorep", -1, ICMP6_WRUREPLY }, + { "whoreq", -1, ICMP6_WRUREQUEST }, + { NULL, -1, -1 } +}; diff --git a/contrib/ipfilter/lib/initparse.c b/contrib/ipfilter/lib/initparse.c index 6fdfc8a9a161..a16ac0f36bcd 100644 --- a/contrib/ipfilter/lib/initparse.c +++ b/contrib/ipfilter/lib/initparse.c @@ -1,11 +1,11 @@ /* $FreeBSD$ */ /* - * Copyright (C) 2000-2002 by Darren Reed. + * Copyright (C) 2012 by Darren Reed. * * See the IPFILTER.LICENCE file for details on licencing. * - * $Id: initparse.c,v 1.6.4.1 2006/06/16 17:21:02 darrenr Exp $ + * $Id$ */ #include "ipf.h" diff --git a/contrib/ipfilter/lib/interror.c b/contrib/ipfilter/lib/interror.c new file mode 100644 index 000000000000..c13f5f8618a8 --- /dev/null +++ b/contrib/ipfilter/lib/interror.c @@ -0,0 +1,582 @@ +/* + * Copyright (C) 2012 by Darren Reed. + * + * See the IPFILTER.LICENCE file for details on licencing. + * + * $Id: interror.c,v 1.9.2.12 2012/07/22 08:03:39 darren_r Exp $ + */ + +#include "ipf.h" +#include +#include + +typedef struct { + int iee_number; + char *iee_text; +} ipf_error_entry_t; + +static ipf_error_entry_t *find_error __P((int)); + +#define IPF_NUM_ERRORS 475 + +/* + * NO REUSE OF NUMBERS! + * + * IF YOU WANT TO ADD AN ERROR TO THIS TABLE, _ADD_ A NEW NUMBER. + * DO _NOT_ USE AN EMPTY NUMBER OR FILL IN A GAP. + */ +static ipf_error_entry_t ipf_errors[IPF_NUM_ERRORS] = { + { 1, "auth table locked/full" }, + { 2, "" }, + { 3, "copyinptr received bad address" }, + { 4, "copyoutptr received bad address" }, + { 5, "" }, + { 6, "cannot load a rule with FR_T_BUILTIN flag set" }, + { 7, "internal rule without FR_T_BUILDINT flag set" }, + { 8, "no data provided with filter rule" }, + { 9, "invalid ioctl for rule" }, + { 10, "rule protocol is not 4 or 6" }, + { 11, "cannot find rule function" }, + { 12, "cannot find rule group" }, + { 13, "group in/out does not match rule in/out" }, + { 14, "rule without in/out does not belong to a group" }, + { 15, "cannot determine where to append rule" }, + { 16, "malloc for rule data failed" }, + { 17, "copyin for rule data failed" }, + { 18, "" }, + { 19, "zero data size for BPF rule" }, + { 20, "BPF validation failed" }, + { 21, "incorrect data size for IPF rule" }, + { 22, "'keep state' rule included 'with oow'" }, + { 23, "bad interface index with dynamic source address" }, + { 24, "bad interface index with dynamic dest. address" }, + { 25, "match array verif failed for filter rule" }, + { 26, "bad filter rule type" }, + { 27, "rule not found for zero'stats" }, + { 28, "copyout failed for zero'ing stats" }, + { 29, "rule not found for removing" }, + { 30, "cannot remove internal rule" }, + { 31, "rule in use" }, + { 32, "rule already exists" }, + { 33, "no memory for another rule" }, + { 34, "could not find function" }, + { 35, "copyout failed for resolving function name -> addr" }, + { 36, "copyout failed for resolving function addr -> name" }, + { 37, "function name/addr resolving search failed" }, + { 38, "group map cannot find it's hash table" }, + { 39, "group map hash-table in/out do not match rule" }, + { 40, "bcopyout failed for SIOCIPFINTERROR" }, + { 41, "" }, + { 42, "ipfilter not enabled for NAT ioctl" }, + { 43, "ipfilter not enabled for state ioctl" }, + { 44, "ipfilter not enabled for auth ioctl" }, + { 45, "ipfilter not enbaled for sync ioctl" }, + { 46, "ipfilter not enabled for scan ioctl" }, + { 47, "ipfilter not enabled for lookup ioctl" }, + { 48, "unrecognised device minor number for ioctl" }, + { 49, "unrecognised object type for copying in ipfobj" }, + { 50, "mismatching object type for copying in ipfobj" }, + { 51, "object size too small for copying in ipfobj" }, + { 52, "object size mismatch for copying in ipfobj" }, + { 53, "compat object size too small for copying in ipfobj" }, + { 54, "compat object size mismatch for copying in ipfobj" }, + { 55, "error doing copyin of data for in ipfobj" }, + { 56, "unrecognised object type for size copy in ipfobj" }, + { 57, "object size too small for size copy in ipfobj" }, + { 58, "mismatching object type for size copy in ipfobj" }, + { 59, "object size mismatch for size copy in ipfobj" }, + { 60, "compat object size mismatch for size copy in ipfobj" }, + { 61, "error doing size copyin of data for in ipfobj" }, + { 62, "bad object type for size copy out ipfobj" }, + { 63, "mismatching object type for size copy out ipfobj" }, + { 64, "object size mismatch for size copy out ipfobj" }, + { 65, "compat object size wrong for size copy out ipfobj" }, + { 66, "error doing size copyout of data for out ipfobj" }, + { 67, "unrecognised object type for copying out ipfobj" }, + { 68, "mismatching object type for copying out ipfobj" }, + { 69, "object size too small for copying out ipfobj" }, + { 70, "object size mismatch for copying out ipfobj" }, + { 71, "compat object size too small for copying out ipfobj" }, + { 72, "compat object size mismatch for copying out ipfobj" }, + { 73, "error doing copyout of data for out ipfobj" }, + { 74, "attempt to add existing tunable name" }, + { 75, "cannot find tunable name to delete" }, + { 76, "internal data too big for next tunable" }, + { 77, "could not find tunable" }, + { 78, "tunable can only be changed when ipfilter disabled" }, + { 79, "new tunable value outside accepted range" }, + { 80, "ipftune called for unrecognised ioctl" }, + { 81, "" }, + { 82, "could not find token to delete" }, + { 83, "" }, + { 84, "attempt to get next rule when no more exist" }, + { 85, "value for iri_inout outside accepted range" }, + { 86, "value for iri_active outside accepted range" }, + { 87, "value for iri_nrules is 0" }, + { 88, "NULL pointer specified for where to copy rule to" }, + { 89, "copyout of rule failed" }, + { 90, "" }, + { 91, "could not get token for rule iteration" }, + { 92, "unrecognised generic iterator" }, + { 93, "could not find token for generic iterator" }, + { 94, "need write permissions to disable/enable ipfilter" }, + { 95, "error copying in enable/disable value" }, + { 96, "need write permissions to set ipf tunable" }, + { 97, "need write permissions to set ipf flags" }, + { 98, "error doing copyin of ipf flags" }, + { 99, "error doing copyout of ipf flags" }, + { 100, "need write permissions to add another rule" }, + { 101, "need write permissions to insert another rule" }, + { 102, "need write permissions to swap active rule set" }, + { 103, "error copying out current active rule set" }, + { 104, "need write permissions to zero ipf stats" }, + { 105, "need write permissions to flush ipf v4 rules" }, + { 106, "error copying out v4 flush results" }, + { 107, "error copying in v4 flush command" }, + { 108, "need write permissions to flush ipf v6 rules" }, + { 109, "error copying out v6 flush results" }, + { 110, "error copying in v6 flush command" }, + { 111, "error copying in new lock state for ipfilter" }, + { 112, "need write permissions to flush ipf logs" }, + { 113, "error copying out results of log flush" }, + { 114, "need write permissions to resync ipf" }, + { 115, "unrecognised ipf ioctl" }, + { 116, "error copying in match array" }, + { 117, "match array type is not IPFOBJ_IPFEXPR" }, + { 118, "bad size for match array" }, + { 119, "cannot allocate memory for match aray" }, + { 120, "error copying in match array" }, + { 121, "error verifying contents of match array" }, + { 122, "need write permissions to set ipf lock status" }, + { 123, "error copying in data for function resolution" }, + { 124, "error copying in ipfobj structure" }, + { 125, "error copying in ipfobj structure" }, + { 126, "error copying in ipfobj structure" }, + { 127, "error copying in ipfobj structure" }, + { 128, "no memory for filter rule comment" }, + { 129, "error copying in filter rule comment" }, + { 130, "error copying out filter rule comment" }, + { 131, "no memory for new rule alloc buffer" }, + { 132, "cannot find source lookup pool" }, + { 133, "unknown source address type" }, + { 134, "cannot find destination lookup pool" }, + { 135, "unknown destination address type" }, + { 136, "icmp head group name index incorrect" }, + { 137, "group head name index incorrect" }, + { 138, "group name index incorrect" }, + { 139, "to interface name index incorrect" }, + { 140, "dup-to interface name index incorrect" }, + { 141, "reply-to interface name index incorrect" }, + { 142, "could not initialise call now function" }, + { 143, "could not initialise call function" }, + { 144, "could not find destination list" }, + { 145, "auth rules cannot have dup/to/fastroute" }, + { 146, "incorrect size for object to copy out" }, + { 147, "object type out of bounds for kernel copyout" }, + { 148, "object size too small for kernel copyout" }, + { 149, "object size validation failed for kernel copyout" }, + { 150, "error copying data out for kernel copyout" }, + { 151, "version mismatch for kernel copyout" }, +/* -------------------------------------------------------------------------- */ + { 10001, "could not find token for auth iterator" }, + { 10002, "write permissions require to add/remove auth rule" }, + { 10003, "need write permissions to set auth lock" }, + { 10004, "error copying out results of auth flush" }, + { 10005, "unknown auth ioctl" }, + { 10006, "can only append or remove preauth rules" }, + { 10007, "NULL pointers passed in for preauth remove" }, + { 10008, "preauth rule not found to remove" }, + { 10009, "could not malloc memory for preauth entry" }, + { 10010, "unrecognised preauth rule ioctl command" }, + { 10011, "iterator data supplied with NULL pointer" }, + { 10012, "unknown auth iterator type" }, + { 10013, "iterator error copying out auth data" }, + { 10014, "sleep waiting for auth packet interrupted" }, + { 10015, "bad index supplied in auth reply" }, + { 10016, "error injecting outbound packet back into kernel" }, + { 10017, "error injecting inbound packet back into kernel" }, + { 10018, "could not attempt to inject packet back into kernel" }, + { 10019, "packet id does not match" }, +/* -------------------------------------------------------------------------- */ + { 20001, "invalid frag token data pointer supplied" }, + { 20002, "error copying out frag token data" }, + { 20003, "can only copy one fragment state entry at a time" }, +/* -------------------------------------------------------------------------- */ + { 30001, "incorrect object size to get hash table stats" }, + { 30002, "could not malloc memory for new hash table" }, + { 30003, "error coping in hash table structure" }, + { 30004, "hash table already exists" }, + { 30005, "mismach between new hash table and operation unit" }, + { 30006, "could not malloc memory for hash table base" }, + { 30007, "could not find hash table" }, + { 30008, "mismatch between hash table and operation unit" }, + { 30009, "could not find hash table for iterators next node" }, + { 30010, "unknown iterator tpe" }, + { 30011, "iterator error copying out hash table" }, + { 30012, "iterator error copying out hash table entry" }, + { 30013, "error copying out hash table statistics" }, + { 30014, "table node delete structure wrong size" }, + { 30015, "error copying in node to delete" }, + { 30016, "table to delete node from does not exist" }, + { 30017, "could not find table to remove node from" }, + { 30018, "table node add structure wrong size" }, + { 30019, "error copying in node to add" }, + { 30020, "could not find table to add node to" }, + { 30021, "node already exists in the table" }, + { 30022, "could not find node to delete in table" }, + { 30023, "uid mismatch on node to delete" }, + { 30024, "object size incorrect for hash table" }, + { 30025, "hash table size must be at least 1"}, + { 30026, "cannot allocate memory for hash table context" }, +/* -------------------------------------------------------------------------- */ + { 40001, "invalid minor device numebr for log read" }, + { 40002, "read size too small" }, + { 40003, "interrupted waiting for log data to read" }, + { 40004, "interrupted waiting for log data to read" }, + { 40005, "read size too large" }, + { 40006, "uiomove for read operation failed" }, +/* -------------------------------------------------------------------------- */ + { 50001, "unknown lookup ioctl" }, + { 50002, "error copying in object data for add node" }, + { 50003, "invalid unit for lookup add node" }, + { 50004, "incorrect size for adding a pool node" }, + { 50005, "error copying in pool node structure" }, + { 50006, "mismatch in pool node address/mask families" }, + { 50007, "could not find pool name" }, + { 50008, "node already exists in pool" }, + { 50009, "incorrect size for adding a hash node" }, + { 50010, "error copying in hash node structure" }, + { 50011, "could not find hash table name" }, + { 50012, "unrecognised object type for lookup add node" }, + { 50013, "invalid unit for lookup delete node" }, + { 50014, "incorrect size for deleting a pool node" }, + { 50015, "error copying in pool node structure" }, + { 50016, "could not find pool name" }, + { 50017, "could not find pool node" }, + { 50018, "incorrect size for removing a hash node" }, + { 50019, "error copying in hash node structure" }, + { 50020, "could not find hash table name" }, + { 50021, "unrecognised object type for lookup delete node" }, + { 50022, "error copying in add table data" }, + { 50023, "invalid unit for lookup add table" }, + { 50024, "pool name already exists" }, + { 50025, "hash table name already exists" }, + { 50026, "unrecognised object type for lookup add table" }, + { 50027, "error copying table data back out" }, + { 50028, "error copying in remove table data" }, + { 50029, "invalid unit for lookup remove table" }, + { 50030, "unrecognised object type for lookup remove table" }, + { 50031, "error copying in lookup stats structure" }, + { 50032, "invalid unit for lookup stats" }, + { 50033, "unrecognised object type for lookup stats" }, + { 50034, "error copying in flush lookup data" }, + { 50035, "invalid unit for lookup flush" }, + { 50036, "incorrect table type for lookup flush" }, + { 50037, "error copying out lookup flush results" }, + { 50038, "invalid unit for lookup iterator" }, + { 50039, "invalid unit for lookup iterator" }, + { 50040, "could not find token for lookup iterator" }, + { 50041, "unrecognised object type for lookup interator" }, + { 50042, "error copying in lookup delete node operation" }, +/* -------------------------------------------------------------------------- */ + { 60001, "insufficient privilege for NAT write operation" }, + { 60002, "need write permissions to flush NAT logs" }, + { 60003, "need write permissions to turn NAT logging on/off" }, + { 60004, "error copying out current NAT log setting" }, + { 60005, "error copying out bytes waiting to be read in NAT \ +log" }, + { 60006, "need write permissions to add NAT rule" }, + { 60007, "NAT rule already exists" }, + { 60008, "could not allocate memory for NAT rule" }, + { 60009, "need write permissions to remove NAT rule" }, + { 60010, "NAT rule could not be found" }, + { 60011, "could not find NAT entry for redirect lookup" }, + { 60012, "need write permissions to flush NAT table" }, + { 60013, "error copying in NAT flush command" }, + { 60014, "need write permissions to do matching NAT flush" }, + { 60015, "need write permissions to set NAT lock" }, + { 60016, "need write permissions to add entry to NAT table" }, + { 60017, "NAT not locked for size retrieval" }, + { 60018, "NAT not locked for fetching NAT table entry" }, + { 60019, "error copying in NAT token data for deletion" }, + { 60020, "unknown NAT ioctl" }, + { 60021, "" }, + { 60022, "resolving proxy name in NAT rule failed" }, + { 60023, "only reply age specified in NAT rule" }, + { 60024, "error doing copyin to determine NAT entry size" }, + { 60025, "error copying out NAT size of 0" }, + { 60026, "NAT entry not found" }, + { 60027, "error doing copyout of NAT entry size" }, + { 60028, "invalid data size for getting NAT entry" }, + { 60029, "could not malloc temporary space for NAT entry" }, + { 60030, "no NAT table entries present" }, + { 60031, "NAT entry to get next from not found" }, + { 60032, "not enough space for proxy structure" }, + { 60033, "not enough space for private proxy data" }, + { 60034, "NAT entry size is too large" }, + { 60035, "could not malloc memory for NAT entry sratch space" }, + { 60036, "" }, + { 60037, "could not malloc memory for NAT entry" }, + { 60038, "could not malloc memory for NAT entry rule" }, + { 60039, "could not resolve NAT entry rule's proxy" }, + { 60040, "cannot add outbound duplicate NAT entry" }, + { 60041, "cannot add inbound duplicate NAT entry" }, + { 60042, "cannot add NAT entry that is neither IN nor OUT" }, + { 60043, "could not malloc memory for NAT proxy data" }, + { 60044, "proxy data size too big" }, + { 60045, "could not malloc proxy private data for NAT entry" }, + { 60046, "could not malloc memory for new NAT filter rule" }, + { 60047, "could not find existing filter rule for NAT entry" }, + { 60048, "insertion into NAT table failed" }, + { 60049, "iterator error copying out hostmap data" }, + { 60050, "iterator error copying out NAT rule data" }, + { 60051, "iterator error copying out NAT entry data" }, + { 60052, "iterator data supplied with NULL pointer" }, + { 60053, "unknown NAT iterator type" }, + { 60054, "unknwon next address type" }, + { 60055, "iterator suppled with unknown type for get-next" }, + { 60056, "unknown lookup group for next address" }, + { 60057, "error copying out NAT log flush results" }, + { 60058, "bucket table type is incorrect" }, + { 60059, "error copying out NAT bucket table" }, + { 60060, "function not found for lookup" }, + { 60061, "address family not supported with SIOCSTPUT" }, + { 60062, "unknown timeout name" }, + { 60063, "cannot allocate new inbound NAT entry table" }, + { 60064, "cannot allocate new outbound NAT entry table" }, + { 60065, "cannot allocate new inbound NAT bucketlen table" }, + { 60066, "cannot allocate new outbound NAT bucketlen table" }, + { 60067, "cannot allocate new NAT rules table" }, + { 60068, "cannot allocate new NAT hostmap table" }, + { 60069, "new source lookup type is not dstlist" }, + { 60070, "cannot allocate NAT rule scratch space" }, + { 60071, "new destination lookup type is not dstlist" }, + { 60072, "function not found for lookup (ipv6)" }, + { 60073, "unknown lookup group for next address (ipv6)" }, + { 60074, "unknown next address type (ipv6)" }, + { 60075, "one object at a time must be copied" }, +/* -------------------------------------------------------------------------- */ + { 70001, "incorrect object size to get pool stats" }, + { 70002, "could not malloc memory for new pool node" }, + { 70003, "invalid addresss length for new pool node" }, + { 70004, "invalid mask length for new pool node" }, + { 70005, "error adding node to pool" }, + { 70006, "pool already exists" }, + { 70007, "could not malloc memory for new pool" }, + { 70008, "could not allocate radix tree for new pool" }, + { 70009, "could not find pool" }, + { 70010, "unknown pool name for iteration" }, + { 70011, "unknown pool iterator" }, + { 70012, "error copying out pool head" }, + { 70013, "error copying out pool node" }, + { 70014, "add node size incorrect" }, + { 70015, "error copying in pool node" }, + { 70016, "" }, + { 70017, "cannot find pool for node" }, + { 70018, "node entry already present in pool" }, + { 70019, "delete node size incorrect" }, + { 70020, "error copying in node to delete" }, + { 70021, "cannot find pool to delete node from" }, + { 70022, "cannot find node to delete in pool" }, + { 70023, "pool name already exists" }, + { 70024, "uid mismatch for node removal" }, + { 70025, "stats device unit is invalid" }, + { 70026, "error copying out statistics" }, + { 70027, "could not remove node from radix tree" }, + { 70028, "incorrect address length in pool node add" }, + { 70029, "incorrect mask length in pool node add" }, + { 70030, "incorrect address length in pool node remove" }, + { 70031, "incorrect mask length in pool node remove" }, + { 70032, "cannot allocate memory for pool context" }, + { 70033, "cannot allocate memory for radix tree context" }, + { 70034, "adding IPv6 node with incorrect address length" }, + { 70035, "IPv4 address not masked" }, + { 70036, "IPv6 address not masked" }, + { 70037, "removing IPv6 node with incorrect address length" }, +/* -------------------------------------------------------------------------- */ + { 80001, "could not find proxy" }, + { 80002, "proxy does not support control operations" }, + { 80003, "could not allocate data to hold proxy operation" }, + { 80004, "unknown proxy ioctl" }, + { 80005, "could not copyin proxy control structure" }, + { 80006, "DNS proxy could not find rule to delete" }, + { 80007, "DNS proxy found existing matching rule" }, + { 80008, "DNS proxy could not allocate memory for new rule" }, + { 80009, "DNS proxy unknown command request" }, +/* -------------------------------------------------------------------------- */ + { 90001, "could not malloc space for new scan structure" }, + { 90002, "scan tag already exists" }, + { 90003, "scan structure in use" }, + { 90004, "could not find matching scan tag for filter rule" }, + { 90005, "could not copyout scan statistics" }, +/* -------------------------------------------------------------------------- */ + { 100001, "cannot find matching state entry to remove" }, + { 100002, "error copying in v4 state flush command" }, + { 100003, "error copying out v4 state flush results" }, + { 100004, "error copying in v6 state flush command" }, + { 100005, "error copying out v6 state flush results" }, + { 100006, "" }, + { 100007, "" }, + { 100008, "need write permissions to flush state log" }, + { 100009, "erorr copyout results of flushing state log" }, + { 100010, "need write permissions to turn state logging on/off" }, + { 100011, "error copying in new state logging state" }, + { 100012, "error copying out current state logging state" }, + { 100013, "error copying out bytes waiting to be read in state \ +log" }, + { 100014, "need write permissions to set state lock" }, + { 100015, "need write permissions to add entry to state table" }, + { 100016, "state not locked for size retrieval" }, + { 100017, "error copying out hash table bucket lengths" }, + { 100018, "could not find token for state iterator" }, + { 100019, "error copying in state token data for deletion" }, + { 100020, "unknown state ioctl" }, + { 100021, "no state table entries present" }, + { 100022, "state entry to get next from not found" }, + { 100023, "could not malloc memory for state entry" }, + { 100024, "could not malloc memory for state entry rule" }, + { 100025, "could not copy back state entry to user space" }, + { 100026, "iterator data supplied with NULL pointer" }, + { 100027, "iterator supplied with 0 item count" }, + { 100028, "iterator type is incorrect" }, + { 100029, "invalid state token data pointer supplied" }, + { 100030, "error copying out next state entry" }, + { 100031, "unrecognised table request" }, + { 100032, "error copying out bucket length data" }, + { 100033, "could not find existing filter rule for state entry" }, + { 100034, "could not find timeout name" }, + { 100035, "could not allocate new state table" }, + { 100036, "could not allocate new state bucket length table" }, +/* -------------------------------------------------------------------------- */ + { 110001, "sync write header magic number is incorrect" }, + { 110002, "sync write header protocol is incorrect" }, + { 110003, "sync write header command is incorrect" }, + { 110004, "sync write header table number is incorrect" }, + { 110005, "data structure too small for sync write operation" }, + { 110006, "zero length data with sync write header" }, + { 110007, "insufficient data for sync write" }, + { 110008, "bad sync read size" }, + { 110009, "interrupted sync read (solaris)" }, + { 110010, "interrupted sync read (hpux)" }, + { 110011, "interrupted sync read (osf)" }, + { 110012, "interrupted sync read" }, + { 110013, "could not malloc memory for sync'd state" }, + { 110014, "could not malloc memory for sync-state list item" }, + { 110015, "sync update could not find state" }, + { 110016, "unrecognised sync state command" }, + { 110017, "could not malloc memory for new sync'd NAT entry" }, + { 110018, "could not malloc memory for sync-NAT list item" }, + { 110019, "sync update could not find NAT entry" }, + { 110020, "unrecognised sync NAT command" }, + { 110021, "ioctls are not handled with sync" }, +/* -------------------------------------------------------------------------- */ + { 120001, "null data pointer for iterator" }, + { 120002, "unit outside of acceptable range" }, + { 120003, "unknown iterator subtype" }, + { 120004, "cannot find dest. list for iteration" }, + { 120005, "error copying out destination iteration list" }, + { 120006, "error copying out destination iteration node" }, + { 120007, "wrong size for frdest_t structure" }, + { 120008, "cannot allocate memory for new destination node" }, + { 120009, "error copying in destination node to add" }, + { 120010, "could not find destination list to add node to" }, + { 120011, "error copying in destination node to remove" }, + { 120012, "could not find dest. list to remove node from" }, + { 120013, "destination list already exists" }, + { 120014, "could not allocate new destination table" }, + { 120015, "could not find destination list to remove" }, + { 120016, "destination list cannot be removed - it is busy" }, + { 120017, "error copying in names for destination" }, + { 120018, "destination name is too long/short" }, + { 120019, "unrecognised address family in destination" }, + { 120020, "" }, + { 120021, "error copying in new destination table" }, + { 120022, "cannot allocate memory for node table" }, + { 120023, "stats object size is incorrect for dest. lists" }, + { 120024, "stats device unit is invalid for dest. lists" }, + { 120025, "error copying out dest. list statistics" }, + { 120026, "cannot allocate memory for destination node" }, + { 120027, "error copying in destination node" }, + { 120028, "cannot allocate memory for destination context " }, +/* -------------------------------------------------------------------------- */ + { 130001, "ioctl denied by system security level" }, + { 130002, "ioctl operation on invalid minor device" }, + { 130003, "ioctl on device denied, ipfitler is disabled" }, + { 130004, "ioctl command not allowed when disabled" }, + { 130005, "ioctl denied due to insufficient authorisation" }, + { 130006, "cannot read while ipfilter is disabled" }, + { 130007, "read on minor device not supported" }, + { 130008, "cannot write while ipfilter is disabled" }, + { 130009, "write on minor device not supported" }, + { 130010, "poll on minor device is not supported" }, + { 130011, "error removing IPv4 filter hooks" }, + { 130012, "error removing IPv6 filter hooks" }, + { 130013, "attaching IPv4 hook failed" }, + { 130014, "attaching IPv6 hook failed" }, + { 130015, "ipf_init_all failed" }, + { 130016, "finding pfil head failed" }, + { 130017, "ipfilter is already initialised and running" }, +}; + + +static ipf_error_entry_t * +find_error(errnum) + int errnum; +{ + ipf_error_entry_t *ie; + + int l = -1, r = IPF_NUM_ERRORS + 1, step; + step = (r - l) / 2;; + + while (step != 0) { + ie = ipf_errors + l + step; + if (ie->iee_number == errnum) + return ie; + step = l + step; + if (ie->iee_number > errnum) + r = step; + else + l = step; + step = (r - l) / 2;; + } + + return NULL; +} + +char * +ipf_geterror(fd, func) + int fd; + ioctlfunc_t *func; +{ + static char text[80]; + ipf_error_entry_t *ie; + int errnum; + + if ((*func)(fd, SIOCIPFINTERROR, &errnum) == 0) { + + ie = find_error(errnum); + if (ie != NULL) + return ie->iee_text; + sprintf(text, "unknown error %d", errnum); + } else { + sprintf(text, "retrieving error number failed (%d)", errno); + } + return text; +} + + +char * +ipf_strerror(errnum) + int errnum; +{ + static char text[80]; + ipf_error_entry_t *ie; + + + ie = find_error(errnum); + if (ie != NULL) + return ie->iee_text; + + sprintf(text, "unknown error %d", errnum); + return text; +} diff --git a/contrib/ipfilter/lib/ionames.c b/contrib/ipfilter/lib/ionames.c index d2fc97775452..9b586422a392 100644 --- a/contrib/ipfilter/lib/ionames.c +++ b/contrib/ipfilter/lib/ionames.c @@ -1,40 +1,41 @@ /* $FreeBSD$ */ /* - * Copyright (C) 2000-2005 by Darren Reed. + * Copyright (C) 2012 by Darren Reed. * * See the IPFILTER.LICENCE file for details on licencing. * - * $Id: ionames.c,v 1.7.4.1 2006/06/16 17:21:02 darrenr Exp $ + * $Id$ */ #include "ipf.h" struct ipopt_names ionames[] ={ { IPOPT_NOP, 0x000001, 1, "nop" }, /* RFC791 */ - { IPOPT_RR, 0x000002, 7, "rr" }, /* 1 route */ - { IPOPT_ZSU, 0x000004, 3, "zsu" }, /* size ?? */ - { IPOPT_MTUP, 0x000008, 3, "mtup" }, /* RFC1191 */ - { IPOPT_MTUR, 0x000010, 3, "mtur" }, /* RFC1191 */ - { IPOPT_ENCODE, 0x000020, 3, "encode" }, /* size ?? */ + { IPOPT_RR, 0x000002, 8, "rr" }, /* 1 route */ + { IPOPT_ZSU, 0x000004, 4, "zsu" }, /* size ?? */ + { IPOPT_MTUP, 0x000008, 4, "mtup" }, /* RFC1191 */ + { IPOPT_MTUR, 0x000010, 4, "mtur" }, /* RFC1191 */ + { IPOPT_ENCODE, 0x000020, 4, "encode" }, /* size ?? */ { IPOPT_TS, 0x000040, 8, "ts" }, /* 1 TS */ - { IPOPT_TR, 0x000080, 3, "tr" }, /* RFC1393 */ - { IPOPT_SECURITY,0x000100, 11, "sec" }, /* RFC1108 */ - { IPOPT_SECURITY,0x000100, 11, "sec-class" }, /* RFC1108 */ - { IPOPT_LSRR, 0x000200, 7, "lsrr" }, /* 1 route */ - { IPOPT_E_SEC, 0x000400, 3, "e-sec" }, /* RFC1108 */ - { IPOPT_CIPSO, 0x000800, 3, "cipso" }, /* size ?? */ + { IPOPT_TR, 0x000080, 4, "tr" }, /* RFC1393 */ + { IPOPT_SECURITY,0x000100, 12, "sec" }, /* RFC1108 */ + { IPOPT_SECURITY,0x000100, 12, "sec-class" }, /* RFC1108 */ + { IPOPT_LSRR, 0x000200, 8, "lsrr" }, /* 1 route */ + { IPOPT_E_SEC, 0x000400, 8, "e-sec" }, /* RFC1108 */ + { IPOPT_CIPSO, 0x000800, 8, "cipso" }, /* size ?? */ { IPOPT_SATID, 0x001000, 4, "satid" }, /* RFC791 */ - { IPOPT_SSRR, 0x002000, 7, "ssrr" }, /* 1 route */ - { IPOPT_ADDEXT, 0x004000, 3, "addext" }, /* IPv7 ?? */ - { IPOPT_VISA, 0x008000, 3, "visa" }, /* size ?? */ - { IPOPT_IMITD, 0x010000, 3, "imitd" }, /* size ?? */ - { IPOPT_EIP, 0x020000, 3, "eip" }, /* RFC1385 */ - { IPOPT_FINN, 0x040000, 3, "finn" }, /* size ?? */ - { IPOPT_DPS, 0x080000, 3, "dps" }, /* size ?? */ - { IPOPT_SDB, 0x100000, 3, "sdb" }, /* size ?? */ - { IPOPT_NSAPA, 0x200000, 3, "nsapa" }, /* size ?? */ - { IPOPT_RTRALRT,0x400000, 3, "rtralrt" }, /* RFC2113 */ - { IPOPT_UMP, 0x800000, 3, "ump" }, /* size ?? */ + { IPOPT_SSRR, 0x002000, 8, "ssrr" }, /* 1 route */ + { IPOPT_ADDEXT, 0x004000, 4, "addext" }, /* IPv7 ?? */ + { IPOPT_VISA, 0x008000, 4, "visa" }, /* size ?? */ + { IPOPT_IMITD, 0x010000, 4, "imitd" }, /* size ?? */ + { IPOPT_EIP, 0x020000, 4, "eip" }, /* RFC1385 */ + { IPOPT_FINN, 0x040000, 4, "finn" }, /* size ?? */ + { IPOPT_DPS, 0x080000, 4, "dps" }, /* size ?? */ + { IPOPT_SDB, 0x100000, 4, "sdb" }, /* size ?? */ + { IPOPT_NSAPA, 0x200000, 4, "nsapa" }, /* size ?? */ + { IPOPT_RTRALRT,0x400000, 4, "rtralrt" }, /* RFC2113 */ + { IPOPT_UMP, 0x800000, 4, "ump" }, /* size ?? */ + { IPOPT_AH, 0x1000000, 0, "ah" }, /* IPPROTO_AH */ { 0, 0, 0, (char *)NULL } /* must be last */ }; diff --git a/contrib/ipfilter/lib/ipf_dotuning.c b/contrib/ipfilter/lib/ipf_dotuning.c index 6508a266271c..b0ac8b42a2f8 100644 --- a/contrib/ipfilter/lib/ipf_dotuning.c +++ b/contrib/ipfilter/lib/ipf_dotuning.c @@ -1,21 +1,21 @@ /* $FreeBSD$ */ /* - * Copyright (C) 2003-2005 by Darren Reed. - * - * See the IPFILTER.LICENCE file for details on licencing. - * - * $Id: ipf_dotuning.c,v 1.2.4.3 2006/06/16 17:21:02 darrenr Exp $ - */ + * Copyright (C) 2012 by Darren Reed. + * + * See the IPFILTER.LICENCE file for details on licencing. + * + * $Id$ + */ #include "ipf.h" #include "netinet/ipl.h" #include void ipf_dotuning(fd, tuneargs, iocfn) -int fd; -char *tuneargs; -ioctlfunc_t iocfn; + int fd; + char *tuneargs; + ioctlfunc_t iocfn; { ipfobj_t obj; ipftune_t tu; @@ -31,7 +31,8 @@ ioctlfunc_t iocfn; if (!strcmp(s, "list")) { while (1) { if ((*iocfn)(fd, SIOCIPFGETNEXT, &obj) == -1) { - perror("ioctl(SIOCIPFGETNEXT)"); + ipf_perror_fd(fd, iocfn, + "ioctl(SIOCIPFGETNEXT)"); break; } if (tu.ipft_cookie == NULL) @@ -46,7 +47,8 @@ ioctlfunc_t iocfn; strncpy(tu.ipft_name, s, sizeof(tu.ipft_name)); if (sscanf(t, "%lu", &tu.ipft_vlong) == 1) { if ((*iocfn)(fd, SIOCIPFSET, &obj) == -1) { - perror("ioctl(SIOCIPFSET)"); + ipf_perror_fd(fd, iocfn, + "ioctl(SIOCIPFSET)"); return; } } else { @@ -57,7 +59,7 @@ ioctlfunc_t iocfn; tu.ipft_cookie = NULL; strncpy(tu.ipft_name, s, sizeof(tu.ipft_name)); if ((*iocfn)(fd, SIOCIPFGET, &obj) == -1) { - perror("ioctl(SIOCIPFGET)"); + ipf_perror_fd(fd, iocfn, "ioctl(SIOCIPFGET)"); return; } if (tu.ipft_cookie == NULL) { diff --git a/contrib/ipfilter/lib/ipf_perror.c b/contrib/ipfilter/lib/ipf_perror.c new file mode 100644 index 000000000000..85a1b1d66e2e --- /dev/null +++ b/contrib/ipfilter/lib/ipf_perror.c @@ -0,0 +1,47 @@ +#include +#include +#include "ipf.h" + +void +ipf_perror(err, string) + int err; + char *string; +{ + if (err == 0) + fprintf(stderr, "%s\n", string); + else + fprintf(stderr, "%s %s\n", string, ipf_strerror(err)); +} + +int +ipf_perror_fd(fd, iocfunc, string) + int fd; + ioctlfunc_t iocfunc; + char *string; +{ + int save; + int realerr; + + save = errno; + if ((*iocfunc)(fd, SIOCIPFINTERROR, &realerr) == -1) + realerr = 0; + + errno = save; + fprintf(stderr, "%d:", realerr); + ipf_perror(realerr, string); + return realerr ? realerr : save; + +} + +void +ipferror(fd, msg) + int fd; + char *msg; +{ + if (fd >= 0) { + ipf_perror_fd(fd, ioctl, msg); + } else { + fprintf(stderr, "0:"); + perror(msg); + } +} diff --git a/contrib/ipfilter/lib/ipft_ef.c b/contrib/ipfilter/lib/ipft_ef.c deleted file mode 100644 index 2d50f076bfbe..000000000000 --- a/contrib/ipfilter/lib/ipft_ef.c +++ /dev/null @@ -1,135 +0,0 @@ -/* $FreeBSD$ */ - -/* - * Copyright (C) 2000-2006 by Darren Reed. - * - * See the IPFILTER.LICENCE file for details on licencing. - * - * $Id: ipft_ef.c,v 1.14.2.2 2006/06/16 17:21:02 darrenr Exp $ - */ - -/* - icmp type - lnth proto source destination src port dst port - -etherfind -n - - 60 tcp 128.250.20.20 128.250.133.13 2419 telnet - -etherfind -n -t - - 0.32 91 04 131.170.1.10 128.250.133.13 - 0.33 566 udp 128.250.37.155 128.250.133.3 901 901 -*/ - -#include "ipf.h" -#include "ipt.h" - -#ifndef linux -#include -#endif -#include - - -#if !defined(lint) -static const char sccsid[] = "@(#)ipft_ef.c 1.6 2/4/96 (C)1995 Darren Reed"; -static const char rcsid[] = "@(#)$Id: ipft_ef.c,v 1.14.2.2 2006/06/16 17:21:02 darrenr Exp $"; -#endif - -static int etherf_open __P((char *)); -static int etherf_close __P((void)); -static int etherf_readip __P((char *, int, char **, int *)); - -struct ipread etherf = { etherf_open, etherf_close, etherf_readip, 0 }; - -static FILE *efp = NULL; -static int efd = -1; - - -static int etherf_open(fname) -char *fname; -{ - if (efd != -1) - return efd; - - if (!strcmp(fname, "-")) { - efd = 0; - efp = stdin; - } else { - efd = open(fname, O_RDONLY); - efp = fdopen(efd, "r"); - } - return efd; -} - - -static int etherf_close() -{ - return close(efd); -} - - -static int etherf_readip(buf, cnt, ifn, dir) -char *buf, **ifn; -int cnt, *dir; -{ - struct tcpiphdr pkt; - ip_t *ip = (ip_t *)&pkt; - char src[16], dst[16], sprt[16], dprt[16]; - char lbuf[128], len[8], prot[8], time[8], *s; - int slen, extra = 0, i; - - if (!fgets(lbuf, sizeof(lbuf) - 1, efp)) - return 0; - - if ((s = strchr(lbuf, '\n'))) - *s = '\0'; - lbuf[sizeof(lbuf)-1] = '\0'; - - bzero(&pkt, sizeof(pkt)); - - if (sscanf(lbuf, "%7s %7s %15s %15s %15s %15s", len, prot, src, dst, - sprt, dprt) != 6) - if (sscanf(lbuf, "%7s %7s %7s %15s %15s %15s %15s", time, - len, prot, src, dst, sprt, dprt) != 7) - return -1; - - ip->ip_p = getproto(prot); - - switch (ip->ip_p) { - case IPPROTO_TCP : - if (isdigit(*sprt)) - pkt.ti_sport = htons(atoi(sprt) & 65535); - if (isdigit(*dprt)) - pkt.ti_dport = htons(atoi(dprt) & 65535); - extra = sizeof(struct tcphdr); - break; - case IPPROTO_UDP : - if (isdigit(*sprt)) - pkt.ti_sport = htons(atoi(sprt) & 65535); - if (isdigit(*dprt)) - pkt.ti_dport = htons(atoi(dprt) & 65535); - extra = sizeof(struct udphdr); - break; -#ifdef IGMP - case IPPROTO_IGMP : - extra = sizeof(struct igmp); - break; -#endif - case IPPROTO_ICMP : - extra = sizeof(struct icmp); - break; - default : - break; - } - - (void) inet_aton(src, &ip->ip_src); - (void) inet_aton(dst, &ip->ip_dst); - ip->ip_len = atoi(len); - IP_HL_A(ip, sizeof(ip_t)); - - slen = IP_HL(ip) + extra; - i = MIN(cnt, slen); - bcopy((char *)&pkt, buf, i); - return i; -} diff --git a/contrib/ipfilter/lib/ipft_hx.c b/contrib/ipfilter/lib/ipft_hx.c index d295c21a7d9f..15002eac788d 100644 --- a/contrib/ipfilter/lib/ipft_hx.c +++ b/contrib/ipfilter/lib/ipft_hx.c @@ -1,13 +1,13 @@ /* $FreeBSD$ */ /* - * Copyright (C) 2000-2005 by Darren Reed. + * Copyright (C) 2012 by Darren Reed. * * See the IPFILTER.LICENCE file for details on licencing. */ #if !defined(lint) static const char sccsid[] = "@(#)ipft_hx.c 1.1 3/9/96 (C) 1996 Darren Reed"; -static const char rcsid[] = "@(#)$Id: ipft_hx.c,v 1.11.4.4 2006/06/16 17:21:03 darrenr Exp $"; +static const char rcsid[] = "@(#)$Id$"; #endif #include @@ -20,7 +20,7 @@ extern int opts; static int hex_open __P((char *)); static int hex_close __P((void)); -static int hex_readip __P((char *, int, char **, int *)); +static int hex_readip __P((mb_t *, char **, int *)); static char *readhex __P((char *, char *)); struct ipread iphex = { hex_open, hex_close, hex_readip, 0 }; @@ -28,7 +28,7 @@ static FILE *tfp = NULL; static int tfd = -1; static int hex_open(fname) -char *fname; + char *fname; { if (tfp && tfd != -1) { rewind(tfp); @@ -56,14 +56,19 @@ static int hex_close() } -static int hex_readip(buf, cnt, ifn, dir) -char *buf, **ifn; -int cnt, *dir; +static int hex_readip(mb, ifn, dir) + mb_t *mb; + char **ifn; + int *dir; { register char *s, *t, *u; char line[513]; ip_t *ip; + char *buf; + int cnt; + buf = (char *)mb->mb_buf; + cnt = sizeof(mb->mb_buf); /* * interpret start of line as possibly "[ifname]" or * "[in/out,ifname]". @@ -75,8 +80,10 @@ int cnt, *dir; ip = (ip_t *)buf; while (fgets(line, sizeof(line)-1, tfp)) { if ((s = strchr(line, '\n'))) { - if (s == line) - return (char *)ip - buf; + if (s == line) { + mb->mb_len = (char *)ip - buf; + return mb->mb_len; + } *s = '\0'; } if ((s = strchr(line, '#'))) @@ -104,17 +111,35 @@ int cnt, *dir; } else if (ifn) *ifn = t; } + + while (*s++ == '+') { + if (!strncasecmp(s, "mcast", 5)) { + mb->mb_flags |= M_MCAST; + s += 5; + } + if (!strncasecmp(s, "bcast", 5)) { + mb->mb_flags |= M_BCAST; + s += 5; + } + if (!strncasecmp(s, "mbcast", 6)) { + mb->mb_flags |= M_MBCAST; + s += 6; + } + } + while (ISSPACE(*s)) + s++; } else s = line; t = (char *)ip; ip = (ip_t *)readhex(s, (char *)ip); if ((opts & OPT_DEBUG) != 0) { if (opts & OPT_ASCII) { + int c = *t; if (t < (char *)ip) putchar('\t'); while (t < (char *)ip) { - if (ISPRINT(*t) && ISASCII(*t)) - putchar(*t); + if (isprint(c) && isascii(c)) + putchar(c); else putchar('.'); t++; diff --git a/contrib/ipfilter/lib/ipft_pc.c b/contrib/ipfilter/lib/ipft_pc.c index 0f31a10efd3b..3a264bd66ffe 100644 --- a/contrib/ipfilter/lib/ipft_pc.c +++ b/contrib/ipfilter/lib/ipft_pc.c @@ -1,19 +1,17 @@ /* $FreeBSD$ */ /* - * Copyright (C) 2000-2005 by Darren Reed. + * Copyright (C) 2012 by Darren Reed. * * See the IPFILTER.LICENCE file for details on licencing. * - * $Id: ipft_pc.c,v 1.10.2.2 2006/06/16 17:21:03 darrenr Exp $ + * $Id$ */ #include "ipf.h" -#include "pcap-ipf.h" -#include "bpf-ipf.h" #include "ipt.h" #if !defined(lint) -static const char rcsid[] = "@(#)$Id: ipft_pc.c,v 1.10.2.2 2006/06/16 17:21:03 darrenr Exp $"; +static const char rcsid[] = "@(#)$Id$"; #endif struct llc { @@ -29,79 +27,61 @@ struct llc { */ static struct llc llcs[] = { - { DLT_NULL, 0, 0, 0 }, - { DLT_EN10MB, 14, 12, 2 }, - { DLT_EN3MB, 0, 0, 0 }, - { DLT_AX25, 0, 0, 0 }, - { DLT_PRONET, 0, 0, 0 }, - { DLT_CHAOS, 0, 0, 0 }, - { DLT_IEEE802, 0, 0, 0 }, - { DLT_ARCNET, 0, 0, 0 }, - { DLT_SLIP, 0, 0, 0 }, - { DLT_PPP, 0, 0, 0 }, - { DLT_FDDI, 0, 0, 0 }, -#ifdef DLT_ATMRFC1483 - { DLT_ATMRFC1483, 0, 0, 0 }, -#endif - { DLT_RAW, 0, 0, 0 }, -#ifdef DLT_ENC - { DLT_ENC, 0, 0, 0 }, -#endif -#ifdef DLT_SLIP_BSDOS - { DLT_SLIP_BSDOS, 0, 0, 0 }, -#endif -#ifdef DLT_PPP_BSDOS - { DLT_PPP_BSDOS, 0, 0, 0 }, -#endif -#ifdef DLT_HIPPI - { DLT_HIPPI, 0, 0, 0 }, -#endif -#ifdef DLT_HDLC - { DLT_HDLC, 0, 0, 0 }, -#endif -#ifdef DLT_PPP_SERIAL - { DLT_PPP_SERIAL, 4, 4, 0 }, -#endif -#ifdef DLT_PPP_ETHER - { DLT_PPP_ETHER, 8, 8, 0 }, -#endif -#ifdef DLT_ECONET - { DLT_ECONET, 0, 0, 0 }, -#endif + { 0, 0, 0, 0 }, /* DLT_NULL */ + { 1, 14, 12, 2 }, /* DLT_Ethernet */ + { 10, 0, 0, 0 }, /* DLT_FDDI */ + { 12, 0, 0, 0 }, /* DLT_RAW */ { -1, -1, -1, -1 } }; -static int pcap_open __P((char *)); -static int pcap_close __P((void)); -static int pcap_readip __P((char *, int, char **, int *)); -static void swap_hdr __P((pcaphdr_t *)); -static int pcap_read_rec __P((struct pcap_pkthdr *)); +typedef struct { + u_int id; + u_short major; + u_short minor; + u_int timezone; + u_int sigfigs; + u_int snaplen; + u_int type; +} fileheader_t; + +typedef struct { + u_32_t seconds; + u_32_t microseconds; + u_32_t caplen; + u_32_t wirelen; +} packetheader_t; + +static int ipcap_open __P((char *)); +static int ipcap_close __P((void)); +static int ipcap_readip __P((mb_t *, char **, int *)); +static int ipcap_read_rec __P((packetheader_t *)); +static void iswap_hdr __P((fileheader_t *)); static int pfd = -1, swapped = 0; static struct llc *llcp = NULL; -struct ipread pcap = { pcap_open, pcap_close, pcap_readip, 0 }; +struct ipread pcap = { ipcap_open, ipcap_close, ipcap_readip, 0 }; #define SWAPLONG(y) \ ((((y)&0xff)<<24) | (((y)&0xff00)<<8) | (((y)&0xff0000)>>8) | (((y)>>24)&0xff)) #define SWAPSHORT(y) \ ( (((y)&0xff)<<8) | (((y)&0xff00)>>8) ) -static void swap_hdr(p) -pcaphdr_t *p; +static void iswap_hdr(p) + fileheader_t *p; { - p->pc_v_maj = SWAPSHORT(p->pc_v_maj); - p->pc_v_min = SWAPSHORT(p->pc_v_min); - p->pc_zone = SWAPLONG(p->pc_zone); - p->pc_sigfigs = SWAPLONG(p->pc_sigfigs); - p->pc_slen = SWAPLONG(p->pc_slen); - p->pc_type = SWAPLONG(p->pc_type); + p->major = SWAPSHORT(p->major); + p->minor = SWAPSHORT(p->minor); + p->timezone = SWAPLONG(p->timezone); + p->sigfigs = SWAPLONG(p->sigfigs); + p->snaplen = SWAPLONG(p->snaplen); + p->type = SWAPLONG(p->type); } -static int pcap_open(fname) -char *fname; +static int ipcap_open(fname) + char *fname; { - pcaphdr_t ph; + fileheader_t ph; int fd, i; if (pfd != -1) @@ -115,22 +95,17 @@ char *fname; if (read(fd, (char *)&ph, sizeof(ph)) != sizeof(ph)) return -2; - if (ph.pc_id != TCPDUMP_MAGIC) { - if (SWAPLONG(ph.pc_id) != TCPDUMP_MAGIC) { + if (ph.id != 0xa1b2c3d4) { + if (SWAPLONG(ph.id) != 0xa1b2c3d4) { (void) close(fd); return -2; } swapped = 1; - swap_hdr(&ph); - } - - if (ph.pc_v_maj != PCAP_VERSION_MAJ) { - (void) close(fd); - return -2; + iswap_hdr(&ph); } for (i = 0; llcs[i].lc_type != -1; i++) - if (llcs[i].lc_type == ph.pc_type) { + if (llcs[i].lc_type == ph.type) { llcp = llcs + i; break; } @@ -143,13 +118,13 @@ char *fname; pfd = fd; printf("opened pcap file %s:\n", fname); printf("\tid: %08x version: %d.%d type: %d snap %d\n", - ph.pc_id, ph.pc_v_maj, ph.pc_v_min, ph.pc_type, ph.pc_slen); + ph.id, ph.major, ph.minor, ph.type, ph.snaplen); return fd; } -static int pcap_close() +static int ipcap_close() { return close(pfd); } @@ -159,8 +134,8 @@ static int pcap_close() * read in the header (and validate) which should be the first record * in a pcap file. */ -static int pcap_read_rec(rec) -struct pcap_pkthdr *rec; +static int ipcap_read_rec(rec) + packetheader_t *rec; { int n, p, i; char *s; @@ -177,13 +152,13 @@ struct pcap_pkthdr *rec; } if (swapped) { - rec->ph_clen = SWAPLONG(rec->ph_clen); - rec->ph_len = SWAPLONG(rec->ph_len); - rec->ph_ts.tv_sec = SWAPLONG(rec->ph_ts.tv_sec); - rec->ph_ts.tv_usec = SWAPLONG(rec->ph_ts.tv_usec); + rec->caplen = SWAPLONG(rec->caplen); + rec->wirelen = SWAPLONG(rec->wirelen); + rec->seconds = SWAPLONG(rec->seconds); + rec->microseconds = SWAPLONG(rec->microseconds); } - p = rec->ph_clen; - n = MIN(p, rec->ph_len); + p = rec->caplen; + n = MIN(p, rec->wirelen); if (!n || n < 0) return -3; @@ -198,15 +173,15 @@ struct pcap_pkthdr *rec; * read an entire pcap packet record. only the data part is copied into * the available buffer, with the number of bytes copied returned. */ -static int pcap_read(buf, cnt) -char *buf; -int cnt; +static int ipcap_read(buf, cnt) + char *buf; + int cnt; { - struct pcap_pkthdr rec; + packetheader_t rec; static char *bufp = NULL; int i, n; - if ((i = pcap_read_rec(&rec)) <= 0) + if ((i = ipcap_read_rec(&rec)) <= 0) return i; if (!bufp) @@ -227,20 +202,29 @@ int cnt; /* * return only an IP packet read into buf */ -static int pcap_readip(buf, cnt, ifn, dir) -char *buf, **ifn; -int cnt, *dir; +static int ipcap_readip(mb, ifn, dir) + mb_t *mb; + char **ifn; + int *dir; { static char *bufp = NULL; - struct pcap_pkthdr rec; + packetheader_t rec; struct llc *l; char *s, ty[4]; int i, j, n; + char *buf; + int cnt; +#if 0 + ifn = ifn; /* gcc -Wextra */ + dir = dir; /* gcc -Wextra */ +#endif + buf = (char *)mb->mb_buf; + cnt = sizeof(mb->mb_buf); l = llcp; /* do { */ - if ((i = pcap_read_rec(&rec)) <= 0) + if ((i = ipcap_read_rec(&rec)) <= 0) return i; if (!bufp) @@ -265,5 +249,6 @@ int cnt, *dir; /* } while (ty[0] != 0x8 && ty[1] != 0); */ n = MIN(i, cnt); bcopy(s, buf, n); + mb->mb_len = n; return n; } diff --git a/contrib/ipfilter/lib/ipft_sn.c b/contrib/ipfilter/lib/ipft_sn.c deleted file mode 100644 index 2beb6eed704f..000000000000 --- a/contrib/ipfilter/lib/ipft_sn.c +++ /dev/null @@ -1,197 +0,0 @@ -/* $FreeBSD$ */ - -/* - * Copyright (C) 2000-2003 by Darren Reed. - * - * See the IPFILTER.LICENCE file for details on licencing. - * - * $Id: ipft_sn.c,v 1.7.4.1 2006/06/16 17:21:03 darrenr Exp $ - */ - -/* - * Written to comply with the recent RFC 1761 from Sun. - */ -#include "ipf.h" -#include "snoop.h" -#include "ipt.h" - -#if !defined(lint) -static const char rcsid[] = "@(#)$Id: ipft_sn.c,v 1.7.4.1 2006/06/16 17:21:03 darrenr Exp $"; -#endif - -struct llc { - int lc_sz; /* LLC header length */ - int lc_to; /* LLC Type offset */ - int lc_tl; /* LLC Type length */ -}; - -/* - * While many of these maybe the same, some do have different header formats - * which make this useful. - */ -static struct llc llcs[SDL_MAX+1] = { - { 0, 0, 0 }, /* SDL_8023 */ - { 0, 0, 0 }, /* SDL_8024 */ - { 0, 0, 0 }, /* SDL_8025 */ - { 0, 0, 0 }, /* SDL_8026 */ - { 14, 12, 2 }, /* SDL_ETHER */ - { 0, 0, 0 }, /* SDL_HDLC */ - { 0, 0, 0 }, /* SDL_CHSYNC */ - { 0, 0, 0 }, /* SDL_IBMCC */ - { 0, 0, 0 }, /* SDL_FDDI */ - { 0, 0, 0 }, /* SDL_OTHER */ -}; - -static int snoop_open __P((char *)); -static int snoop_close __P((void)); -static int snoop_readip __P((char *, int, char **, int *)); - -static int sfd = -1, s_type = -1; -static int snoop_read_rec __P((struct snooppkt *)); - -struct ipread snoop = { snoop_open, snoop_close, snoop_readip, 0 }; - - -static int snoop_open(fname) -char *fname; -{ - struct snoophdr sh; - int fd; - int s_v; - - if (sfd != -1) - return sfd; - - if (!strcmp(fname, "-")) - fd = 0; - else if ((fd = open(fname, O_RDONLY)) == -1) - return -1; - - if (read(fd, (char *)&sh, sizeof(sh)) != sizeof(sh)) - return -2; - - s_v = (int)ntohl(sh.s_v); - s_type = (int)ntohl(sh.s_type); - - if (s_v != SNOOP_VERSION || - s_type < 0 || s_type > SDL_MAX) { - (void) close(fd); - return -2; - } - - sfd = fd; - printf("opened snoop file %s:\n", fname); - printf("\tid: %8.8s version: %d type: %d\n", sh.s_id, s_v, s_type); - - return fd; -} - - -static int snoop_close() -{ - return close(sfd); -} - - -/* - * read in the header (and validate) which should be the first record - * in a snoop file. - */ -static int snoop_read_rec(rec) -struct snooppkt *rec; -{ - int n, plen, ilen; - - if (read(sfd, (char *)rec, sizeof(*rec)) != sizeof(*rec)) - return -2; - - ilen = (int)ntohl(rec->sp_ilen); - plen = (int)ntohl(rec->sp_plen); - if (ilen > plen || plen < sizeof(*rec)) - return -2; - - plen -= sizeof(*rec); - n = MIN(plen, ilen); - if (!n || n < 0) - return -3; - - return plen; -} - - -#ifdef notyet -/* - * read an entire snoop packet record. only the data part is copied into - * the available buffer, with the number of bytes copied returned. - */ -static int snoop_read(buf, cnt) -char *buf; -int cnt; -{ - struct snooppkt rec; - static char *bufp = NULL; - int i, n; - - if ((i = snoop_read_rec(&rec)) <= 0) - return i; - - if (!bufp) - bufp = malloc(i); - else - bufp = realloc(bufp, i); - - if (read(sfd, bufp, i) != i) - return -2; - - n = MIN(i, cnt); - bcopy(bufp, buf, n); - return n; -} -#endif - - -/* - * return only an IP packet read into buf - */ -static int snoop_readip(buf, cnt, ifn, dir) -char *buf, **ifn; -int cnt, *dir; -{ - static char *bufp = NULL; - struct snooppkt rec; - struct llc *l; - char ty[4], *s; - int i, n; - - do { - if ((i = snoop_read_rec(&rec)) <= 0) - return i; - - if (!bufp) - bufp = malloc(i); - else - bufp = realloc(bufp, i); - s = bufp; - - if (read(sfd, s, i) != i) - return -2; - - l = &llcs[s_type]; - i -= l->lc_to; - s += l->lc_to; - /* - * XXX - bogus assumption here on the part of the time field - * that it won't be greater than 4 bytes and the 1st two will - * have the values 8 and 0 for IP. Should be a table of - * these too somewhere. Really only works for SDL_ETHER. - */ - bcopy(s, ty, l->lc_tl); - } while (ty[0] != 0x8 && ty[1] != 0); - - i -= l->lc_tl; - s += l->lc_tl; - n = MIN(i, cnt); - bcopy(s, buf, n); - - return n; -} diff --git a/contrib/ipfilter/lib/ipft_td.c b/contrib/ipfilter/lib/ipft_td.c deleted file mode 100644 index d571ada7b56e..000000000000 --- a/contrib/ipfilter/lib/ipft_td.c +++ /dev/null @@ -1,178 +0,0 @@ -/* $FreeBSD$ */ - -/* - * Copyright (C) 2000-2006 by Darren Reed. - * - * See the IPFILTER.LICENCE file for details on licencing. - * - * $Id: ipft_td.c,v 1.15.2.2 2006/06/16 17:21:03 darrenr Exp $ - */ - -/* -tcpdump -n - -00:05:47.816843 128.231.76.76.3291 > 224.2.252.231.36573: udp 36 (encap) - -tcpdump -nq - -00:33:48.410771 192.73.213.11.1463 > 224.2.248.153.59360: udp 31 (encap) - -tcpdump -nqt - -128.250.133.13.23 > 128.250.20.20.2419: tcp 27 - -tcpdump -nqtt - -123456789.1234567 128.250.133.13.23 > 128.250.20.20.2419: tcp 27 - -tcpdump -nqte - -8:0:20:f:65:f7 0:0:c:1:8a:c5 81: 128.250.133.13.23 > 128.250.20.20.2419: tcp 27 - -*/ - -#include "ipf.h" -#include "ipt.h" - -#ifndef linux -#include -#endif -#include - - -#if !defined(lint) -static const char sccsid[] = "@(#)ipft_td.c 1.8 2/4/96 (C)1995 Darren Reed"; -static const char rcsid[] = "@(#)$Id: ipft_td.c,v 1.15.2.2 2006/06/16 17:21:03 darrenr Exp $"; -#endif - -static int tcpd_open __P((char *)); -static int tcpd_close __P((void)); -static int tcpd_readip __P((char *, int, char **, int *)); -static int count_dots __P((char *)); - -struct ipread tcpd = { tcpd_open, tcpd_close, tcpd_readip, 0 }; - -static FILE *tfp = NULL; -static int tfd = -1; - - -static int tcpd_open(fname) -char *fname; -{ - if (tfd != -1) - return tfd; - - if (!strcmp(fname, "-")) { - tfd = 0; - tfp = stdin; - } else { - tfd = open(fname, O_RDONLY); - tfp = fdopen(tfd, "r"); - } - return tfd; -} - - -static int tcpd_close() -{ - (void) fclose(tfp); - return close(tfd); -} - - -static int count_dots(str) -char *str; -{ - int i = 0; - - while (*str) - if (*str++ == '.') - i++; - return i; -} - - -static int tcpd_readip(buf, cnt, ifn, dir) -char *buf, **ifn; -int cnt, *dir; -{ - struct tcpiphdr pkt; - ip_t *ip = (ip_t *)&pkt; - char src[32], dst[32], misc[256], time[32], link1[32], link2[32]; - char lbuf[160], *s; - int n, slen, extra = 0; - - if (!fgets(lbuf, sizeof(lbuf) - 1, tfp)) - return 0; - - if ((s = strchr(lbuf, '\n'))) - *s = '\0'; - lbuf[sizeof(lbuf)-1] = '\0'; - - bzero(&pkt, sizeof(pkt)); - - if ((n = sscanf(lbuf, "%31s > %31s: %255s", src, dst, misc)) != 3) - if ((n = sscanf(lbuf, "%31s %31s > %31s: %255s", - time, src, dst, misc)) != 4) - if ((n = sscanf(lbuf, "%31s %31s: %31s > %31s: %255s", - link1, link2, src, dst, misc)) != 5) { - n = sscanf(lbuf, - "%31s %31s %31s: %31s > %31s: %255s", - time, link1, link2, src, dst, misc); - if (n != 6) - return -1; - } - - if (count_dots(dst) == 4) { - s = strrchr(src, '.'); - *s++ = '\0'; - (void) inet_aton(src, &ip->ip_src); - pkt.ti_sport = htons(atoi(s)); - *--s = '.'; - s = strrchr(dst, '.'); - - *s++ = '\0'; - (void) inet_aton(src, &ip->ip_dst); - pkt.ti_dport = htons(atoi(s)); - *--s = '.'; - - } else { - (void) inet_aton(src, &ip->ip_src); - (void) inet_aton(src, &ip->ip_dst); - } - ip->ip_len = sizeof(ip_t); - IP_HL_A(ip, sizeof(ip_t)); - - s = strtok(misc, " :"); - if (s == NULL) - return 0; - ip->ip_p = getproto(s); - - switch (ip->ip_p) - { - case IPPROTO_TCP : - case IPPROTO_UDP : - s = strtok(NULL, " :"); - if (s == NULL) - return 0; - ip->ip_len += atoi(s); - if (ip->ip_p == IPPROTO_TCP) - extra = sizeof(struct tcphdr); - else if (ip->ip_p == IPPROTO_UDP) - extra = sizeof(struct udphdr); - break; -#ifdef IGMP - case IPPROTO_IGMP : - extra = sizeof(struct igmp); - break; -#endif - case IPPROTO_ICMP : - extra = sizeof(struct icmp); - break; - default : - break; - } - - slen = IP_HL(ip) + extra + ip->ip_len; - return slen; -} diff --git a/contrib/ipfilter/lib/ipft_tx.c b/contrib/ipfilter/lib/ipft_tx.c index f4475e3c8426..a996c5b9612a 100644 --- a/contrib/ipfilter/lib/ipft_tx.c +++ b/contrib/ipfilter/lib/ipft_tx.c @@ -1,15 +1,15 @@ /* $FreeBSD$ */ /* - * Copyright (C) 2000-2006 by Darren Reed. + * Copyright (C) 2012 by Darren Reed. * * See the IPFILTER.LICENCE file for details on licencing. * - * $Id: ipft_tx.c,v 1.15.2.10 2007/09/03 21:54:44 darrenr Exp $ + * $Id$ */ #if !defined(lint) static const char sccsid[] = "@(#)ipft_tx.c 1.7 6/5/96 (C) 1993 Darren Reed"; -static const char rcsid[] = "@(#)$Id: ipft_tx.c,v 1.15.2.10 2007/09/03 21:54:44 darrenr Exp $"; +static const char rcsid[] = "@(#)$Id$"; #endif #include @@ -17,18 +17,12 @@ static const char rcsid[] = "@(#)$Id: ipft_tx.c,v 1.15.2.10 2007/09/03 21:54:44 #include "ipf.h" #include "ipt.h" -#ifndef linux -#include -#endif -#include - - extern int opts; static char *tx_proto = ""; static int text_open __P((char *)), text_close __P((void)); -static int text_readip __P((char *, int, char **, int *)); +static int text_readip __P((mb_t *, char **, int *)); static int parseline __P((char *, ip_t *, char **, int *)); static char myflagset[] = "FSRPAUEC"; @@ -42,16 +36,19 @@ static int tfd = -1; static u_32_t tx_hostnum __P((char *, int *)); static u_short tx_portnum __P((char *)); +#ifdef USE_INET6 +int parseipv6 __P((char **, ip6_t *, char **, int *)); +#endif /* * returns an ip address as a long var as a result of either a DNS lookup or * straight inet_addr() call */ static u_32_t tx_hostnum(host, resolved) -char *host; -int *resolved; + char *host; + int *resolved; { - u_32_t ipa; + i6addr_t ipa; *resolved = 0; if (!strcasecmp("any", host)) @@ -59,12 +56,12 @@ int *resolved; if (ISDIGIT(*host)) return inet_addr(host); - if (gethost(host, &ipa) == -1) { + if (gethost(AF_INET, host, &ipa) == -1) { *resolved = -1; fprintf(stderr, "can't resolve hostname: %s\n", host); return 0; } - return ipa; + return ipa.in4.s_addr; } @@ -73,7 +70,7 @@ int *resolved; * straight atoi() */ static u_short tx_portnum(name) -char *name; + char *name; { struct servent *sp; @@ -87,15 +84,8 @@ char *name; } -char *tx_icmptypes[] = { - "echorep", (char *)NULL, (char *)NULL, "unreach", "squench", - "redir", (char *)NULL, (char *)NULL, "echo", "routerad", - "routersol", "timex", "paramprob", "timest", "timestrep", - "inforeq", "inforep", "maskreq", "maskrep", "END" -}; - static int text_open(fname) -char *fname; + char *fname; { if (tfp && tfd != -1) { rewind(tfp); @@ -123,13 +113,19 @@ static int text_close() } -static int text_readip(buf, cnt, ifn, dir) -char *buf, **ifn; -int cnt, *dir; +static int text_readip(mb, ifn, dir) + mb_t *mb; + char **ifn; + int *dir; { register char *s; char line[513]; ip_t *ip; + char *buf; + int cnt; + + buf = (char *)mb->mb_buf; + cnt = sizeof(mb->mb_buf); *ifn = NULL; while (fgets(line, sizeof(line)-1, tfp)) { @@ -147,7 +143,17 @@ int cnt, *dir; *dir = 0; if (!parseline(line, (ip_t *)buf, ifn, dir)) { ip = (ip_t *)buf; - return ntohs(ip->ip_len); + if (IP_V(ip) == 6) { +#ifdef USE_INET6 + mb->mb_len = ntohs(((ip6_t *)ip)->ip6_plen) + + sizeof(ip6_t); +#else + mb->mb_len = 0; +#endif + } else { + mb->mb_len = ntohs(ip->ip_len); + } + return mb->mb_len; } } if (feof(tfp)) @@ -156,10 +162,10 @@ int cnt, *dir; } static int parseline(line, ip, ifn, out) -char *line; -ip_t *ip; -char **ifn; -int *out; + char *line; + ip_t *ip; + char **ifn; + int *out; { tcphdr_t th, *tcp = &th; struct icmp icmp, *ic = &icmp; @@ -174,6 +180,7 @@ int *out; bzero(ipopts, sizeof(ipopts)); IP_HL_A(ip, sizeof(*ip) >> 2); IP_V_A(ip, IPVERSION); + ip->ip_ttl = 63; for (i = 0, cps[0] = strtok(line, " \b\t\r\n"); cps[i] && i < 19; ) cps[++i] = strtok(NULL, " \b\t\r\n"); @@ -186,6 +193,13 @@ int *out; fprintf(stderr, "bad direction \"%s\"\n", *cpp); return 1; } + +#ifdef USE_INET6 + if (!strcasecmp(*cpp, "out6") || !strcasecmp(*cpp, "in6")) { + return parseipv6(cpp, (ip6_t *)ip, ifn, out); + } +#endif + *out = (TOLOWER(c) == 'o') ? 1 : 0; cpp++; if (!*cpp) @@ -284,24 +298,20 @@ int *out; cpp++; } } else if (*cpp && ip->ip_p == IPPROTO_ICMP) { - extern char *tx_icmptypes[]; - char **s, *t; - int i; + char *t; t = strchr(*cpp, ','); if (t != NULL) *t = '\0'; - for (s = tx_icmptypes, i = 0; !*s || strcmp(*s, "END"); - s++, i++) { - if (*s && !strcasecmp(*cpp, *s)) { - ic->icmp_type = i; - if (t != NULL) - ic->icmp_code = atoi(t + 1); - cpp++; - break; - } - } + ic->icmp_type = geticmptype(AF_INET, *cpp); + if (t != NULL) + ic->icmp_code = atoi(t + 1); + cpp++; + + if (ic->icmp_type == ICMP_ECHO || + ic->icmp_type == ICMP_ECHOREPLY) + ic->icmp_id = htons(getpid()); if (t != NULL) *t = ','; } @@ -314,6 +324,7 @@ int *out; if (olen) { bcopy(ipopts, (char *)(ip + 1), olen); IP_HL_A(ip, IP_HL(ip) + (olen >> 2)); + ip->ip_len += olen; } } if (ip->ip_p == IPPROTO_TCP || ip->ip_p == IPPROTO_UDP) @@ -325,3 +336,175 @@ int *out; ip->ip_len = htons(ip->ip_len); return 0; } + + +#ifdef USE_INET6 +int parseipv6(cpp, ip6, ifn, out) + char **cpp; + ip6_t *ip6; + char **ifn; + int *out; +{ + tcphdr_t th, *tcp = &th; + struct icmp6_hdr icmp, *ic6 = &icmp; + + bzero((char *)ip6, MAX(sizeof(*tcp), sizeof(*ic6)) + sizeof(*ip6)); + bzero((char *)tcp, sizeof(*tcp)); + bzero((char *)ic6, sizeof(*ic6)); + ip6->ip6_vfc = 0x60; + + *out = (**cpp == 'o') ? 1 : 0; + cpp++; + if (!*cpp) + return 1; + + if (!strcasecmp(*cpp, "on")) { + cpp++; + if (!*cpp) + return 1; + *ifn = strdup(*cpp++); + if (!*cpp) + return 1; + } + + if (!strcasecmp(*cpp, "tcp")) { + ip6->ip6_nxt = IPPROTO_TCP; + tx_proto = "tcp"; + cpp++; + } else if (!strcasecmp(*cpp, "udp")) { + ip6->ip6_nxt = IPPROTO_UDP; + tx_proto = "udp"; + cpp++; + } else if (!strcasecmp(*cpp, "icmpv6")) { + ip6->ip6_nxt = IPPROTO_ICMPV6; + tx_proto = "icmpv6"; + cpp++; + } else if (ISDIGIT(**cpp) && !index(*cpp, ':')) { + ip6->ip6_nxt = atoi(*cpp); + cpp++; + } else + ip6->ip6_nxt = IPPROTO_IPV6; + + if (!*cpp) + return 1; + + switch (ip6->ip6_nxt) + { + case IPPROTO_TCP : + ip6->ip6_plen = sizeof(struct tcphdr); + break; + case IPPROTO_UDP : + ip6->ip6_plen = sizeof(struct udphdr); + break; + case IPPROTO_ICMPV6 : + ip6->ip6_plen = ICMP6ERR_IPICMPHLEN; + break; + default : + break; + } + + if (ip6->ip6_nxt == IPPROTO_TCP || ip6->ip6_nxt == IPPROTO_UDP) { + char *last; + + last = strchr(*cpp, ','); + if (!last) { + fprintf(stderr, "tcp/udp with no source port\n"); + return 1; + } + *last++ = '\0'; + tcp->th_sport = htons(tx_portnum(last)); + if (ip6->ip6_nxt == IPPROTO_TCP) { + tcp->th_win = htons(4096); + TCP_OFF_A(tcp, sizeof(*tcp) >> 2); + } + } + + if (inet_pton(AF_INET6, *cpp, &ip6->ip6_src) != 1) { + fprintf(stderr, "cannot parse source address '%s'\n", *cpp); + return 1; + } + + cpp++; + if (!*cpp) + return 1; + + if (ip6->ip6_nxt == IPPROTO_TCP || ip6->ip6_nxt == IPPROTO_UDP) { + char *last; + + last = strchr(*cpp, ','); + if (!last) { + fprintf(stderr, "tcp/udp with no destination port\n"); + return 1; + } + *last++ = '\0'; + tcp->th_dport = htons(tx_portnum(last)); + } + + if (inet_pton(AF_INET6, *cpp, &ip6->ip6_dst) != 1) { + fprintf(stderr, "cannot parse destination address '%s'\n", + *cpp); + return 1; + } + + cpp++; + if (ip6->ip6_nxt == IPPROTO_TCP) { + if (*cpp != NULL) { + char *s, *t; + + tcp->th_flags = 0; + for (s = *cpp; *s; s++) + if ((t = strchr(myflagset, *s))) + tcp->th_flags |= myflags[t-myflagset]; + if (tcp->th_flags) + cpp++; + } + + if (tcp->th_flags & TH_URG) + tcp->th_urp = htons(1); + + if (*cpp && !strncasecmp(*cpp, "seq=", 4)) { + tcp->th_seq = htonl(atoi(*cpp + 4)); + cpp++; + } + + if (*cpp && !strncasecmp(*cpp, "ack=", 4)) { + tcp->th_ack = htonl(atoi(*cpp + 4)); + cpp++; + } + } else if (*cpp && ip6->ip6_nxt == IPPROTO_ICMPV6) { + char *t; + + t = strchr(*cpp, ','); + if (t != NULL) + *t = '\0'; + + ic6->icmp6_type = geticmptype(AF_INET6, *cpp); + if (t != NULL) + ic6->icmp6_code = atoi(t + 1); + + if (ic6->icmp6_type == ICMP6_ECHO_REQUEST || + ic6->icmp6_type == ICMP6_ECHO_REPLY) + ic6->icmp6_id = htons(getpid()); + + if (t != NULL) + *t = ','; + } + + if (ip6->ip6_nxt == IPPROTO_TCP || ip6->ip6_nxt == IPPROTO_UDP) { + bcopy((char *)tcp, (char *)ip6 + sizeof(*ip6), + sizeof(*tcp)); + } else if (ip6->ip6_nxt == IPPROTO_ICMPV6) { + bcopy((char *)ic6, (char *)ip6 + sizeof(*ip6), + sizeof(*ic6)); + } + + /* + * Because a length of 0 == jumbo gram... + */ + if (ip6->ip6_plen == 0) { + ip6->ip6_plen++; + } + ip6->ip6_plen = htons(ip6->ip6_plen); + return 0; +} +#endif diff --git a/contrib/ipfilter/lib/ipoptsec.c b/contrib/ipfilter/lib/ipoptsec.c index 66a55c80dbb7..5e585ba57ef8 100644 --- a/contrib/ipfilter/lib/ipoptsec.c +++ b/contrib/ipfilter/lib/ipoptsec.c @@ -1,11 +1,11 @@ /* $FreeBSD$ */ /* - * Copyright (C) 2001-2002 by Darren Reed. + * Copyright (C) 2012 by Darren Reed. * * See the IPFILTER.LICENCE file for details on licencing. * - * $Id: ipoptsec.c,v 1.2.4.1 2006/06/16 17:21:04 darrenr Exp $ + * $Id$ */ #include "ipf.h" @@ -25,16 +25,19 @@ struct ipopt_names secclass[] = { u_char seclevel(slevel) -char *slevel; + char *slevel; { struct ipopt_names *so; + if (slevel == NULL || *slevel == '\0') + return 0; + for (so = secclass; so->on_name; so++) if (!strcasecmp(slevel, so->on_name)) break; if (!so->on_name) { - fprintf(stderr, "no such security level: %s\n", slevel); + fprintf(stderr, "no such security level: '%s'\n", slevel); return 0; } return (u_char)so->on_value; @@ -42,7 +45,7 @@ char *slevel; u_char secbit(class) -int class; + int class; { struct ipopt_names *so; @@ -51,7 +54,7 @@ int class; break; if (!so->on_name) { - fprintf(stderr, "no such security class: %d\n", class); + fprintf(stderr, "no such security class: %d.\n", class); return 0; } return (u_char)so->on_bit; diff --git a/contrib/ipfilter/lib/kmem.c b/contrib/ipfilter/lib/kmem.c index 26da2d0139f7..382a51c88c18 100644 --- a/contrib/ipfilter/lib/kmem.c +++ b/contrib/ipfilter/lib/kmem.c @@ -1,7 +1,7 @@ /* $FreeBSD$ */ /* - * Copyright (C) 2000-2005 by Darren Reed. + * Copyright (C) 2012 by Darren Reed. * * See the IPFILTER.LICENCE file for details on licencing. */ @@ -44,7 +44,7 @@ #if !defined(lint) static const char sccsid[] = "@(#)kmem.c 1.4 1/12/96 (C) 1992 Darren Reed"; -static const char rcsid[] = "@(#)$Id: kmem.c,v 1.16.2.3 2006/06/16 17:21:04 darrenr Exp $"; +static const char rcsid[] = "@(#)$Id$"; #endif @@ -70,9 +70,9 @@ kvm_t kvm_open __P((char *, char *, char *, int, char *)); int kvm_read __P((kvm_t, u_long, char *, size_t)); kvm_t kvm_open(kernel, core, swap, mode, errstr) -char *kernel, *core, *swap; -int mode; -char *errstr; + char *kernel, *core, *swap; + int mode; + char *errstr; { kvm_t k; int fd; @@ -93,10 +93,10 @@ char *errstr; } int kvm_read(kvm, pos, buffer, size) -kvm_t kvm; -u_long pos; -char *buffer; -size_t size; + kvm_t kvm; + u_long pos; + char *buffer; + size_t size; { int r = 0, left; char *bufp; @@ -127,7 +127,7 @@ size_t size; #endif /* !defined(__sgi) && !defined(__hpux) && !defined(__osf__) */ int openkmem(kern, core) -char *kern, *core; + char *kern, *core; { kvm_f = kvm_open(kern, core, NULL, O_RDONLY, NULL); if (kvm_f == NULL) @@ -139,9 +139,9 @@ char *kern, *core; } int kmemcpy(buf, pos, n) -register char *buf; -long pos; -register int n; + register char *buf; + long pos; + register int n; { register int r; @@ -169,9 +169,9 @@ register int n; } int kstrncpy(buf, pos, n) -register char *buf; -long pos; -register int n; + register char *buf; + long pos; + register int n; { register int r; diff --git a/contrib/ipfilter/lib/kmem.h b/contrib/ipfilter/lib/kmem.h index bcfde06d045d..ce6ad56f52d9 100644 --- a/contrib/ipfilter/lib/kmem.h +++ b/contrib/ipfilter/lib/kmem.h @@ -1,10 +1,10 @@ /* $FreeBSD$ */ /* - * Copyright (C) 2002 by Darren Reed. + * Copyright (C) 2012 by Darren Reed. * * See the IPFILTER.LICENCE file for details on licencing. - * $Id: kmem.h,v 1.2.4.1 2006/06/16 17:21:04 darrenr Exp $ + * $Id$ */ #ifndef __KMEM_H__ diff --git a/contrib/ipfilter/lib/kmemcpywrap.c b/contrib/ipfilter/lib/kmemcpywrap.c index 87474915334e..6c398d6d39f3 100644 --- a/contrib/ipfilter/lib/kmemcpywrap.c +++ b/contrib/ipfilter/lib/kmemcpywrap.c @@ -1,19 +1,19 @@ /* $FreeBSD$ */ /* - * Copyright (C) 2002 by Darren Reed. - * - * See the IPFILTER.LICENCE file for details on licencing. - * - * $Id: kmemcpywrap.c,v 1.1.4.1 2006/06/16 17:21:05 darrenr Exp $ - */ + * Copyright (C) 2012 by Darren Reed. + * + * See the IPFILTER.LICENCE file for details on licencing. + * + * $Id$ + */ #include "ipf.h" #include "kmem.h" int kmemcpywrap(from, to, size) -void *from, *to; -size_t size; + void *from, *to; + size_t size; { int ret; diff --git a/contrib/ipfilter/lib/kvatoname.c b/contrib/ipfilter/lib/kvatoname.c index c8c0d8fff621..65b524082df4 100644 --- a/contrib/ipfilter/lib/kvatoname.c +++ b/contrib/ipfilter/lib/kvatoname.c @@ -1,12 +1,12 @@ /* $FreeBSD$ */ /* - * Copyright (C) 2002 by Darren Reed. - * - * See the IPFILTER.LICENCE file for details on licencing. - * - * $Id: kvatoname.c,v 1.1.4.1 2006/06/16 17:21:05 darrenr Exp $ - */ + * Copyright (C) 2012 by Darren Reed. + * + * See the IPFILTER.LICENCE file for details on licencing. + * + * $Id$ + */ #include "ipf.h" @@ -14,8 +14,8 @@ #include char *kvatoname(func, iocfunc) -ipfunc_t func; -ioctlfunc_t iocfunc; + ipfunc_t func; + ioctlfunc_t iocfunc; { static char funcname[40]; ipfunc_resolve_t res; @@ -25,7 +25,7 @@ ioctlfunc_t iocfunc; res.ipfu_name[0] = '\0'; fd = -1; - if ((opts & OPT_DONOTHING) == 0) { + if ((opts & OPT_DONTOPEN) == 0) { fd = open(IPL_NAME, O_RDONLY); if (fd == -1) return NULL; diff --git a/contrib/ipfilter/lib/load_dstlist.c b/contrib/ipfilter/lib/load_dstlist.c new file mode 100644 index 000000000000..760699dafeae --- /dev/null +++ b/contrib/ipfilter/lib/load_dstlist.c @@ -0,0 +1,69 @@ +/* + * Copyright (C) 2012 by Darren Reed. + * + * See the IPFILTER.LICENCE file for details on licencing. + * + * $Id: load_dstlist.c,v 1.1.2.5 2012/07/22 08:04:24 darren_r Exp $ + */ + +#include +#include +#include "ipf.h" +#include "netinet/ip_lookup.h" +#include "netinet/ip_dstlist.h" + + +int +load_dstlist(dst, iocfunc, nodes) + ippool_dst_t *dst; + ioctlfunc_t iocfunc; + ipf_dstnode_t *nodes; +{ + iplookupop_t op; + ipf_dstnode_t *a; + ippool_dst_t dest; + + if (dst->ipld_name[0] == '\0') + return -1; + + if (pool_open() == -1) + return -1; + + op.iplo_unit = dst->ipld_unit; + op.iplo_type = IPLT_DSTLIST; + op.iplo_arg = 0; + strncpy(op.iplo_name, dst->ipld_name, sizeof(op.iplo_name)); + op.iplo_size = sizeof(dest); + op.iplo_struct = &dest; + bzero((char *)&dest, sizeof(dest)); + dest.ipld_unit = dst->ipld_unit; + dest.ipld_policy = dst->ipld_policy; + dest.ipld_flags = dst->ipld_flags; + strncpy(dest.ipld_name, dst->ipld_name, sizeof(dest.ipld_name)); + + if ((opts & OPT_REMOVE) == 0) { + if (pool_ioctl(iocfunc, SIOCLOOKUPADDTABLE, &op)) + if ((opts & OPT_DONOTHING) == 0) { + return ipf_perror_fd(pool_fd(), iocfunc, + "add destination list table"); + } + } + + if ((opts & OPT_VERBOSE) != 0) { + dest.ipld_dests = dst->ipld_dests; + printdstlist(&dest, bcopywrap, dest.ipld_name, opts, nodes, NULL); + dest.ipld_dests = NULL; + } + + for (a = nodes; a != NULL; a = a->ipfd_next) + load_dstlistnode(dst->ipld_unit, dest.ipld_name, a, iocfunc); + + if ((opts & OPT_REMOVE) != 0) { + if (pool_ioctl(iocfunc, SIOCLOOKUPDELTABLE, &op)) + if ((opts & OPT_DONOTHING) == 0) { + return ipf_perror_fd(pool_fd(), iocfunc, + "delete destination list table"); + } + } + return 0; +} diff --git a/contrib/ipfilter/lib/load_dstlistnode.c b/contrib/ipfilter/lib/load_dstlistnode.c new file mode 100644 index 000000000000..e1ec0013fae7 --- /dev/null +++ b/contrib/ipfilter/lib/load_dstlistnode.c @@ -0,0 +1,70 @@ +/* + * Copyright (C) 2012 by Darren Reed. + * + * See the IPFILTER.LICENCE file for details on licencing. + * + * $Id: load_dstlistnode.c,v 1.1.2.5 2012/07/22 08:04:24 darren_r Exp $ + */ + +#include +#include +#include "ipf.h" +#include "netinet/ip_lookup.h" +#include "netinet/ip_pool.h" + + +int +load_dstlistnode(role, name, node, iocfunc) + int role; + char *name; + ipf_dstnode_t *node; + ioctlfunc_t iocfunc; +{ + iplookupop_t op; + frdest_t *dst; + char *what; + int err; + + if (pool_open() == -1) + return -1; + + dst = calloc(1, sizeof(*dst) + node->ipfd_dest.fd_name); + if (dst == NULL) + return -1; + + op.iplo_unit = role; + op.iplo_type = IPLT_DSTLIST; + op.iplo_arg = 0; + op.iplo_struct = dst; + op.iplo_size = sizeof(*dst); + if (node->ipfd_dest.fd_name >= 0) + op.iplo_size += node->ipfd_dest.fd_name; + (void) strncpy(op.iplo_name, name, sizeof(op.iplo_name)); + + dst->fd_addr = node->ipfd_dest.fd_addr; + dst->fd_type = node->ipfd_dest.fd_type; + dst->fd_name = node->ipfd_dest.fd_name; + if (node->ipfd_dest.fd_name >= 0) + bcopy(node->ipfd_names, (char *)dst + sizeof(*dst), + node->ipfd_dest.fd_name); + + if ((opts & OPT_REMOVE) == 0) { + what = "add"; + err = pool_ioctl(iocfunc, SIOCLOOKUPADDNODE, &op); + } else { + what = "delete"; + err = pool_ioctl(iocfunc, SIOCLOOKUPDELNODE, &op); + } + free(dst); + + if (err != 0) { + if ((opts & OPT_DONOTHING) == 0) { + char msg[80]; + + (void) sprintf(msg, "%s lookup node", what); + return ipf_perror_fd(pool_fd(), iocfunc, msg); + } + } + + return 0; +} diff --git a/contrib/ipfilter/lib/load_file.c b/contrib/ipfilter/lib/load_file.c index 9bb3899aebf5..a1d1f70b5c33 100644 --- a/contrib/ipfilter/lib/load_file.c +++ b/contrib/ipfilter/lib/load_file.c @@ -1,12 +1,13 @@ /* - * Copyright (C) 2006 by Darren Reed. + * Copyright (C) 2012 by Darren Reed. * * See the IPFILTER.LICENCE file for details on licencing. * - * $Id: load_file.c,v 1.1.2.1 2006/08/25 21:13:04 darrenr Exp $ + * $Id: load_file.c,v 1.6.2.2 2012/07/22 08:04:24 darren_r Exp $ */ #include "ipf.h" +#include alist_t * load_file(char *filename) @@ -20,13 +21,13 @@ load_file(char *filename) if (fp == NULL) { fprintf(stderr, "load_file cannot open '%s'\n", filename); return NULL; - } + } a = NULL; rtop = NULL; rbot = NULL; - linenum = 0; - + linenum = 0; + while (fgets(line, sizeof(line) - 1, fp)) { line[sizeof(line) - 1] = '\0'; linenum++; @@ -35,17 +36,23 @@ load_file(char *filename) */ s = strchr(line, '\n'); if (s == NULL) { - fprintf(stderr, "%d:%s: line too long\n", linenum, filename); + fprintf(stderr, "%d:%s: line too long\n", + linenum, filename); fclose(fp); alist_free(rtop); return NULL; } - *s = '\0'; + /* + * Remove trailing spaces + */ + for (; ISSPACE(*s); s--) + *s = '\0'; + s = strchr(line, '\r'); if (s != NULL) *s = '\0'; - for (t = line; isspace(*t); t++) + for (t = line; ISSPACE(*t); t++) ; if (*t == '!') { not = 1; @@ -56,21 +63,22 @@ load_file(char *filename) /* * Remove comment markers */ - for (s = t; *s; s++) { - if (*s == '#') - *s = '\0'; + s = strchr(t, '#'); + if (s != NULL) { + *s = '\0'; + if (s == t) + continue; } - if (!*t) - continue; + /* * Trim off tailing white spaces */ s = strlen(t) + t - 1; - while (isspace(*s)) + while (ISSPACE(*s)) *s-- = '\0'; - if (isdigit(*t)) { - a = alist_new(4, t); + a = alist_new(AF_UNSPEC, t); + if (a != NULL) { a->al_not = not; if (rbot != NULL) rbot->al_next = a; @@ -78,8 +86,8 @@ load_file(char *filename) rtop = a; rbot = a; } else { - fprintf(stderr, "%s: unrecognised content line %d\n", - filename, linenum); + fprintf(stderr, "%s:%d unrecognised content :%s\n", + filename, linenum, t); } } fclose(fp); diff --git a/contrib/ipfilter/lib/load_hash.c b/contrib/ipfilter/lib/load_hash.c index 7683470b47e8..7ec79a91258f 100644 --- a/contrib/ipfilter/lib/load_hash.c +++ b/contrib/ipfilter/lib/load_hash.c @@ -1,11 +1,11 @@ /* $FreeBSD$ */ /* - * Copyright (C) 2002-2005 by Darren Reed. + * Copyright (C) 2012 by Darren Reed. * * See the IPFILTER.LICENCE file for details on licencing. * - * $Id: load_hash.c,v 1.11.2.5 2006/07/14 06:12:25 darrenr Exp $ + * $Id$ */ #include @@ -14,13 +14,12 @@ #include "netinet/ip_lookup.h" #include "netinet/ip_htable.h" -static int hashfd = -1; - -int load_hash(iphp, list, iocfunc) -iphtable_t *iphp; -iphtent_t *list; -ioctlfunc_t iocfunc; +int +load_hash(iphp, list, iocfunc) + iphtable_t *iphp; + iphtent_t *list; + ioctlfunc_t iocfunc; { iplookupop_t op; iphtable_t iph; @@ -28,14 +27,13 @@ ioctlfunc_t iocfunc; size_t size; int n; - if ((hashfd == -1) && ((opts & OPT_DONOTHING) == 0)) - hashfd = open(IPLOOKUP_NAME, O_RDWR); - if ((hashfd == -1) && ((opts & OPT_DONOTHING) == 0)) + if (pool_open() == -1) return -1; for (n = 0, a = list; a != NULL; a = a->ipe_next) n++; + bzero((char *)&iph, sizeof(iph)); op.iplo_arg = 0; op.iplo_type = IPLT_HASH; op.iplo_unit = iphp->iph_unit; @@ -44,10 +42,7 @@ ioctlfunc_t iocfunc; op.iplo_arg = IPHASH_ANON; op.iplo_size = sizeof(iph); op.iplo_struct = &iph; - iph.iph_unit = iphp->iph_unit; - iph.iph_type = iphp->iph_type; - strncpy(iph.iph_name, iphp->iph_name, sizeof(iph.iph_name)); - iph.iph_flags = iphp->iph_flags; + iph = *iphp; if (n <= 0) n = 1; if (iphp->iph_size == 0) @@ -60,16 +55,15 @@ ioctlfunc_t iocfunc; iphp->iph_name, "size to match expected use"); } iph.iph_size = size; - iph.iph_seed = iphp->iph_seed; iph.iph_table = NULL; iph.iph_list = NULL; iph.iph_ref = 0; if ((opts & OPT_REMOVE) == 0) { - if ((*iocfunc)(hashfd, SIOCLOOKUPADDTABLE, &op)) + if (pool_ioctl(iocfunc, SIOCLOOKUPADDTABLE, &op)) if ((opts & OPT_DONOTHING) == 0) { - perror("load_hash:SIOCLOOKUPADDTABLE"); - return -1; + return ipf_perror_fd(pool_fd(), iocfunc, + "add lookup hash table"); } } @@ -77,19 +71,14 @@ ioctlfunc_t iocfunc; strncpy(iphp->iph_name, op.iplo_name, sizeof(op.iplo_name)); if (opts & OPT_VERBOSE) { - for (a = list; a != NULL; a = a->ipe_next) { - a->ipe_addr.in4_addr = ntohl(a->ipe_addr.in4_addr); - a->ipe_mask.in4_addr = ntohl(a->ipe_mask.in4_addr); - } iph.iph_table = calloc(size, sizeof(*iph.iph_table)); if (iph.iph_table == NULL) { perror("calloc(size, sizeof(*iph.iph_table))"); return -1; } iph.iph_list = list; - printhash(&iph, bcopywrap, iph.iph_name, opts); + printhash(&iph, bcopywrap, iph.iph_name, opts, NULL); free(iph.iph_table); - iph.iph_list = NULL; for (a = list; a != NULL; a = a->ipe_next) { a->ipe_addr.in4_addr = htonl(a->ipe_addr.in4_addr); @@ -101,13 +90,13 @@ ioctlfunc_t iocfunc; printf("Hash %s:\n", iph.iph_name); for (a = list; a != NULL; a = a->ipe_next) - load_hashnode(iphp->iph_unit, iph.iph_name, a, iocfunc); + load_hashnode(iphp->iph_unit, iph.iph_name, a, 0, iocfunc); if ((opts & OPT_REMOVE) != 0) { - if ((*iocfunc)(hashfd, SIOCLOOKUPDELTABLE, &op)) + if (pool_ioctl(iocfunc, SIOCLOOKUPDELTABLE, &op)) if ((opts & OPT_DONOTHING) == 0) { - perror("load_hash:SIOCLOOKUPDELTABLE"); - return -1; + return ipf_perror_fd(pool_fd(), iocfunc, + "delete lookup hash table"); } } return 0; diff --git a/contrib/ipfilter/lib/load_hashnode.c b/contrib/ipfilter/lib/load_hashnode.c index 3c3416d95a14..2aac4331b41f 100644 --- a/contrib/ipfilter/lib/load_hashnode.c +++ b/contrib/ipfilter/lib/load_hashnode.c @@ -1,11 +1,11 @@ /* $FreeBSD$ */ /* - * Copyright (C) 2003-2005 by Darren Reed. + * Copyright (C) 2012 by Darren Reed. * * See the IPFILTER.LICENCE file for details on licencing. * - * $Id: load_hashnode.c,v 1.2.4.2 2006/06/16 17:21:05 darrenr Exp $ + * $Id$ */ #include @@ -14,22 +14,21 @@ #include "netinet/ip_lookup.h" #include "netinet/ip_htable.h" -static int hashfd = -1; - -int load_hashnode(unit, name, node, iocfunc) -int unit; -char *name; -iphtent_t *node; -ioctlfunc_t iocfunc; +int +load_hashnode(unit, name, node, ttl, iocfunc) + int unit; + char *name; + iphtent_t *node; + int ttl; + ioctlfunc_t iocfunc; { iplookupop_t op; iphtent_t ipe; + char *what; int err; - if ((hashfd == -1) && ((opts & OPT_DONOTHING) == 0)) - hashfd = open(IPLOOKUP_NAME, O_RDWR); - if ((hashfd == -1) && ((opts & OPT_DONOTHING) == 0)) + if (pool_open() == -1) return -1; op.iplo_type = IPLT_HASH; @@ -40,6 +39,8 @@ ioctlfunc_t iocfunc; strncpy(op.iplo_name, name, sizeof(op.iplo_name)); bzero((char *)&ipe, sizeof(ipe)); + ipe.ipe_family = node->ipe_family; + ipe.ipe_die = ttl; bcopy((char *)&node->ipe_addr, (char *)&ipe.ipe_addr, sizeof(ipe.ipe_addr)); bcopy((char *)&node->ipe_mask, (char *)&ipe.ipe_mask, @@ -47,15 +48,20 @@ ioctlfunc_t iocfunc; bcopy((char *)&node->ipe_group, (char *)&ipe.ipe_group, sizeof(ipe.ipe_group)); - if ((opts & OPT_REMOVE) == 0) - err = (*iocfunc)(hashfd, SIOCLOOKUPADDNODE, &op); - else - err = (*iocfunc)(hashfd, SIOCLOOKUPDELNODE, &op); + if ((opts & OPT_REMOVE) == 0) { + what = "add"; + err = pool_ioctl(iocfunc, SIOCLOOKUPADDNODE, &op); + } else { + what = "delete"; + err = pool_ioctl(iocfunc, SIOCLOOKUPDELNODE, &op); + } if (err != 0) if (!(opts & OPT_DONOTHING)) { - perror("load_hash:SIOCLOOKUP*NODE"); - return -1; + char msg[80]; + + sprintf(msg, "%s node from lookup hash table", what); + return ipf_perror_fd(pool_fd(), iocfunc, msg); } return 0; } diff --git a/contrib/ipfilter/lib/load_http.c b/contrib/ipfilter/lib/load_http.c index 38d0b67d26d7..88fc1e37cb53 100644 --- a/contrib/ipfilter/lib/load_http.c +++ b/contrib/ipfilter/lib/load_http.c @@ -1,12 +1,28 @@ +/* $FreeBSD$ */ + /* - * Copyright (C) 2006 by Darren Reed. + * Copyright (C) 2012 by Darren Reed. * * See the IPFILTER.LICENCE file for details on licencing. * - * $Id: load_http.c,v 1.1.2.1 2006/08/25 21:13:04 darrenr Exp $ + * $Id: load_http.c,v 1.5.2.5 2012/07/22 08:04:24 darren_r Exp $ */ #include "ipf.h" +#include + +/* + * Because the URL can be included twice into the buffer, once as the + * full path for the "GET" and once as the "Host:", the buffer it is + * put in needs to be larger than 512*2 to make room for the supporting + * text. Why not just use snprintf and truncate? The warning about the + * URL being too long tells you something is wrong and does not fetch + * any data - just truncating the URL (with snprintf, etc) and sending + * that to the server is allowing an unknown and unintentioned action + * to happen. + */ +#define MAX_URL_LEN 512 +#define LOAD_BUFSIZE (MAX_URL_LEN * 2 + 128) /* * Format expected is one addres per line, at the start of each line. @@ -14,19 +30,18 @@ alist_t * load_http(char *url) { - char *s, *t, *u, buffer[1044], *myurl; + int fd, len, left, port, endhdr, removed, linenum = 0; + char *s, *t, *u, buffer[LOAD_BUFSIZE], *myurl; alist_t *a, *rtop, *rbot; - struct sockaddr_in sin; - struct hostent *host; size_t avail; - int fd, len, left, port, endhdr, removed; int error; /* * More than this would just be absurd. */ - if (strlen(url) > 512) { - fprintf(stderr, "load_http has a URL > 512 bytes?!\n"); + if (strlen(url) > MAX_URL_LEN) { + fprintf(stderr, "load_http has a URL > %d bytes?!\n", + MAX_URL_LEN); return NULL; } @@ -56,6 +71,15 @@ load_http(char *url) } *t++ = '\0'; + /* + * 10 is the length of 'Host: \r\n\r\n' below. + */ + if (strlen(s) + strlen(buffer) + 10 > sizeof(buffer)) { + fprintf(stderr, "load_http has a malformed URL '%s'\n", url); + free(myurl); + return NULL; + } + u = strchr(s, '@'); if (u != NULL) s = u + 1; /* AUTH */ @@ -76,28 +100,11 @@ load_http(char *url) port = 80; } - memset(&sin, 0, sizeof(sin)); - sin.sin_family = AF_INET; - sin.sin_port = htons(port); - if (isdigit(*s)) { - if (inet_aton(s, &sin.sin_addr) == -1) { - goto done; - } - } else { - host = gethostbyname(s); - if (host == NULL) - goto done; - memcpy(&sin.sin_addr, host->h_addr_list[0], - sizeof(sin.sin_addr)); - } - - fd = socket(AF_INET, SOCK_STREAM, 0); + fd = connecttcp(s, port); if (fd == -1) goto done; - if (connect(fd, (struct sockaddr *)&sin, sizeof(sin)) == -1) - goto done; len = strlen(buffer); if (write(fd, buffer, len) != len) @@ -150,30 +157,40 @@ load_http(char *url) if (t == NULL) break; - *t++ = '\0'; - for (u = buffer; isdigit(*u) || (*u == '.'); u++) - ; - if (*u == '/') { - char *slash; + linenum++; + *t = '\0'; - slash = u; - u++; - while (isdigit(*u)) - u++; - if (!isspace(*u) && *u) - u = slash; + /* + * Remove comment and continue to the next line if + * the comment is at the start of the line. + */ + u = strchr(buffer, '#'); + if (u != NULL) { + *u = '\0'; + if (u == buffer) + continue; } - *u = '\0'; - a = alist_new(4, buffer); + /* + * Trim off tailing white spaces, will include \r + */ + for (u = t - 1; (u >= buffer) && ISSPACE(*u); u--) + *u = '\0'; + + a = alist_new(AF_UNSPEC, buffer); if (a != NULL) { if (rbot != NULL) rbot->al_next = a; else rtop = a; rbot = a; + } else { + fprintf(stderr, + "%s:%d unrecognised content:%s\n", + url, linenum, buffer); } + t++; removed = t - buffer; memmove(buffer, t, sizeof(buffer) - left - removed); s -= removed; diff --git a/contrib/ipfilter/lib/load_pool.c b/contrib/ipfilter/lib/load_pool.c index 08baae767db9..190a2dff2520 100644 --- a/contrib/ipfilter/lib/load_pool.c +++ b/contrib/ipfilter/lib/load_pool.c @@ -1,11 +1,11 @@ /* $FreeBSD$ */ /* - * Copyright (C) 2002-2005 by Darren Reed. + * Copyright (C) 2012 by Darren Reed. * * See the IPFILTER.LICENCE file for details on licencing. * - * $Id: load_pool.c,v 1.14.2.4 2006/06/16 17:21:06 darrenr Exp $ + * $Id$ */ #include @@ -14,20 +14,17 @@ #include "netinet/ip_lookup.h" #include "netinet/ip_pool.h" -static int poolfd = -1; - -int load_pool(plp, iocfunc) -ip_pool_t *plp; -ioctlfunc_t iocfunc; +int +load_pool(plp, iocfunc) + ip_pool_t *plp; + ioctlfunc_t iocfunc; { iplookupop_t op; ip_pool_node_t *a; ip_pool_t pool; - if ((poolfd == -1) && ((opts & OPT_DONOTHING) == 0)) - poolfd = open(IPLOOKUP_NAME, O_RDWR); - if ((poolfd == -1) && ((opts & OPT_DONOTHING) == 0)) + if (pool_open() == -1) return -1; op.iplo_unit = plp->ipo_unit; @@ -37,16 +34,18 @@ ioctlfunc_t iocfunc; op.iplo_size = sizeof(pool); op.iplo_struct = &pool; bzero((char *)&pool, sizeof(pool)); + pool.ipo_unit = plp->ipo_unit; strncpy(pool.ipo_name, plp->ipo_name, sizeof(pool.ipo_name)); if (plp->ipo_name[0] == '\0') op.iplo_arg |= IPOOL_ANON; if ((opts & OPT_REMOVE) == 0) { - if ((*iocfunc)(poolfd, SIOCLOOKUPADDTABLE, &op)) + if (pool_ioctl(iocfunc, SIOCLOOKUPADDTABLE, &op)) { if ((opts & OPT_DONOTHING) == 0) { - perror("load_pool:SIOCLOOKUPADDTABLE"); - return -1; + return ipf_perror_fd(pool_fd(), iocfunc, + "add lookup table"); } + } } if (op.iplo_arg & IPOOL_ANON) @@ -54,18 +53,19 @@ ioctlfunc_t iocfunc; if ((opts & OPT_VERBOSE) != 0) { pool.ipo_list = plp->ipo_list; - printpool(&pool, bcopywrap, pool.ipo_name, opts); + (void) printpool(&pool, bcopywrap, pool.ipo_name, opts, NULL); pool.ipo_list = NULL; } for (a = plp->ipo_list; a != NULL; a = a->ipn_next) - load_poolnode(plp->ipo_unit, pool.ipo_name, a, iocfunc); + load_poolnode(plp->ipo_unit, pool.ipo_name, + a, 0, iocfunc); if ((opts & OPT_REMOVE) != 0) { - if ((*iocfunc)(poolfd, SIOCLOOKUPDELTABLE, &op)) + if (pool_ioctl(iocfunc, SIOCLOOKUPDELTABLE, &op)) if ((opts & OPT_DONOTHING) == 0) { - perror("load_pool:SIOCLOOKUPDELTABLE"); - return -1; + return ipf_perror_fd(pool_fd(), iocfunc, + "delete lookup table"); } } return 0; diff --git a/contrib/ipfilter/lib/load_poolnode.c b/contrib/ipfilter/lib/load_poolnode.c index 110a8b9c3e5b..5afca8412b08 100644 --- a/contrib/ipfilter/lib/load_poolnode.c +++ b/contrib/ipfilter/lib/load_poolnode.c @@ -1,11 +1,11 @@ /* $FreeBSD$ */ /* - * Copyright (C) 2003-2004 by Darren Reed. + * Copyright (C) 2012 by Darren Reed. * * See the IPFILTER.LICENCE file for details on licencing. * - * $Id: load_poolnode.c,v 1.3.2.3 2006/06/16 17:21:06 darrenr Exp $ + * $Id$ */ #include @@ -14,22 +14,21 @@ #include "netinet/ip_lookup.h" #include "netinet/ip_pool.h" -static int poolfd = -1; - -int load_poolnode(role, name, node, iocfunc) -int role; -char *name; -ip_pool_node_t *node; -ioctlfunc_t iocfunc; +int +load_poolnode(role, name, node, ttl, iocfunc) + int role; + char *name; + ip_pool_node_t *node; + int ttl; + ioctlfunc_t iocfunc; { ip_pool_node_t pn; iplookupop_t op; + char *what; int err; - if ((poolfd == -1) && ((opts & OPT_DONOTHING) == 0)) - poolfd = open(IPLOOKUP_NAME, O_RDWR); - if ((poolfd == -1) && ((opts & OPT_DONOTHING) == 0)) + if (pool_open() == -1) return -1; op.iplo_unit = role; @@ -45,17 +44,25 @@ ioctlfunc_t iocfunc; bcopy((char *)&node->ipn_mask, (char *)&pn.ipn_mask, sizeof(pn.ipn_mask)); pn.ipn_info = node->ipn_info; + pn.ipn_die = ttl; strncpy(pn.ipn_name, node->ipn_name, sizeof(pn.ipn_name)); - if ((opts & OPT_REMOVE) == 0) - err = (*iocfunc)(poolfd, SIOCLOOKUPADDNODE, &op); - else - err = (*iocfunc)(poolfd, SIOCLOOKUPDELNODE, &op); + if ((opts & OPT_REMOVE) == 0) { + what = "add"; + err = pool_ioctl(iocfunc, SIOCLOOKUPADDNODE, &op); + } else { + what = "delete"; + err = pool_ioctl(iocfunc, SIOCLOOKUPDELNODE, &op); + } if (err != 0) { if ((opts & OPT_DONOTHING) == 0) { - perror("load_poolnode:SIOCLOOKUP*NODE"); - return -1; + char msg[80]; + + sprintf(msg, "%s pool node(%s/", what, + inet_ntoa(pn.ipn_addr.adf_addr.in4)); + strcat(msg, inet_ntoa(pn.ipn_mask.adf_addr.in4)); + return ipf_perror_fd(pool_fd(), iocfunc, msg); } } diff --git a/contrib/ipfilter/lib/load_url.c b/contrib/ipfilter/lib/load_url.c index 77091534b0c2..dcda4c07fdf8 100644 --- a/contrib/ipfilter/lib/load_url.c +++ b/contrib/ipfilter/lib/load_url.c @@ -1,9 +1,9 @@ /* - * Copyright (C) 2006 by Darren Reed. + * Copyright (C) 2012 by Darren Reed. * * See the IPFILTER.LICENCE file for details on licencing. * - * $Id: load_url.c,v 1.1.2.1 2006/08/25 21:13:04 darrenr Exp $ + * $Id: load_url.c,v 1.3.2.2 2012/07/22 08:04:24 darren_r Exp $ */ #include "ipf.h" @@ -13,11 +13,11 @@ load_url(char *url) { alist_t *hosts = NULL; - if (strncmp(url, "file://", 7) == 0) { - /* + if (strncmp(url, "file://", 7) == 0) { + /* * file:///etc/passwd * ^------------s - */ + */ hosts = load_file(url); } else if (*url == '/' || *url == '.') { @@ -27,5 +27,5 @@ load_url(char *url) hosts = load_http(url); } - return hosts; + return hosts; } diff --git a/contrib/ipfilter/lib/mb_hexdump.c b/contrib/ipfilter/lib/mb_hexdump.c new file mode 100644 index 000000000000..6da65633191c --- /dev/null +++ b/contrib/ipfilter/lib/mb_hexdump.c @@ -0,0 +1,32 @@ +/* + * Copyright (C) 2012 by Darren Reed. + * + * See the IPFILTER.LICENCE file for details on licencing. + * + * $Id: mb_hexdump.c,v 1.1.2.3 2012/07/22 08:04:24 darren_r Exp $ + */ + +#include "ipf.h" + +void +mb_hexdump(m, fp) + mb_t *m; + FILE *fp; +{ + u_char *s; + int len; + int i; + + for (; m != NULL; m = m->mb_next) { + len = m->mb_len; + for (s = (u_char *)m->mb_data, i = 0; i < len; i++) { + fprintf(fp, "%02x", *s++ & 0xff); + if (len - i > 1) { + i++; + fprintf(fp, "%02x", *s++ & 0xff); + } + fputc(' ', fp); + } + } + fputc('\n', fp); +} diff --git a/contrib/ipfilter/lib/msgdsize.c b/contrib/ipfilter/lib/msgdsize.c new file mode 100644 index 000000000000..9bdc584bc008 --- /dev/null +++ b/contrib/ipfilter/lib/msgdsize.c @@ -0,0 +1,20 @@ +/* + * Copyright (C) 2012 by Darren Reed. + * + * See the IPFILTER.LICENCE file for details on licencing. + * + * $Id: msgdsize.c,v 1.2.4.3 2012/07/22 08:04:24 darren_r Exp $ + */ + +#include "ipf.h" + +size_t msgdsize(orig) + mb_t *orig; +{ + size_t sz = 0; + mb_t *m; + + for (m = orig; m != NULL; m = m->mb_next) + sz += m->mb_len; + return sz; +} diff --git a/contrib/ipfilter/lib/mutex_emul.c b/contrib/ipfilter/lib/mutex_emul.c index 3983f04c6257..1846701fa40a 100644 --- a/contrib/ipfilter/lib/mutex_emul.c +++ b/contrib/ipfilter/lib/mutex_emul.c @@ -1,22 +1,30 @@ /* $FreeBSD$ */ /* - * Copyright (C) 2003 by Darren Reed. - * - * See the IPFILTER.LICENCE file for details on licencing. - * - * $Id: mutex_emul.c,v 1.2.4.1 2006/06/16 17:21:06 darrenr Exp $ - */ + * Copyright (C) 2012 by Darren Reed. + * + * See the IPFILTER.LICENCE file for details on licencing. + * + * $Id$ + */ #include "ipf.h" #define EMM_MAGIC 0x9d7adba3 -void eMmutex_enter(mtx, file, line) -eMmutex_t *mtx; -char *file; -int line; +static int mutex_debug = 0; +static FILE *mutex_file = NULL; +static int initcount = 0; + +void +eMmutex_enter(mtx, file, line) + eMmutex_t *mtx; + char *file; + int line; { + if (mutex_debug & 2) + fprintf(mutex_file, "%s:%d:eMmutex_enter(%s)\n", file, line, + mtx->eMm_owner); if (mtx->eMm_magic != EMM_MAGIC) { fprintf(stderr, "%s:eMmutex_enter(%p): bad magic: %#x\n", mtx->eMm_owner, mtx, mtx->eMm_magic); @@ -33,9 +41,15 @@ int line; } -void eMmutex_exit(mtx) -eMmutex_t *mtx; +void +eMmutex_exit(mtx, file, line) + eMmutex_t *mtx; + char *file; + int line; { + if (mutex_debug & 2) + fprintf(mutex_file, "%s:%d:eMmutex_exit(%s)\n", file, line, + mtx->eMm_owner); if (mtx->eMm_magic != EMM_MAGIC) { fprintf(stderr, "%s:eMmutex_exit(%p): bad magic: %#x\n", mtx->eMm_owner, mtx, mtx->eMm_magic); @@ -52,10 +66,18 @@ eMmutex_t *mtx; } -void eMmutex_init(mtx, who) -eMmutex_t *mtx; -char *who; +void +eMmutex_init(mtx, who, file, line) + eMmutex_t *mtx; + char *who; + char *file; + int line; { + if (mutex_file == NULL && mutex_debug) + mutex_file = fopen("ipf_mutex_log", "w"); + if (mutex_debug & 1) + fprintf(mutex_file, "%s:%d:eMmutex_init(%p,%s)\n", + file, line, mtx, who); if (mtx->eMm_magic == EMM_MAGIC) { /* safe bet ? */ fprintf(stderr, "%s:eMmutex_init(%p): already initialised?: %#x\n", @@ -68,21 +90,44 @@ char *who; mtx->eMm_owner = strdup(who); else mtx->eMm_owner = NULL; + initcount++; } -void eMmutex_destroy(mtx) -eMmutex_t *mtx; +void +eMmutex_destroy(mtx, file, line) + eMmutex_t *mtx; + char *file; + int line; { + if (mutex_debug & 1) + fprintf(mutex_file, + "%s:%d:eMmutex_destroy(%p,%s)\n", file, line, + mtx, mtx->eMm_owner); if (mtx->eMm_magic != EMM_MAGIC) { fprintf(stderr, "%s:eMmutex_destroy(%p): bad magic: %#x\n", mtx->eMm_owner, mtx, mtx->eMm_magic); abort(); } if (mtx->eMm_held != 0) { - fprintf(stderr, "%s:eMmutex_enter(%p): still locked: %d\n", + fprintf(stderr, + "%s:eMmutex_enter(%p): still locked: %d\n", mtx->eMm_owner, mtx, mtx->eMm_held); abort(); } + if (mtx->eMm_owner != NULL) + free(mtx->eMm_owner); memset(mtx, 0xa5, sizeof(*mtx)); + initcount--; +} + + +void +ipf_mutex_clean() +{ + if (initcount != 0) { + if (mutex_file) + fprintf(mutex_file, "initcount %d\n", initcount); + abort(); + } } diff --git a/contrib/ipfilter/lib/nametokva.c b/contrib/ipfilter/lib/nametokva.c index deee4399b946..8e7af944d508 100644 --- a/contrib/ipfilter/lib/nametokva.c +++ b/contrib/ipfilter/lib/nametokva.c @@ -1,12 +1,12 @@ /* $FreeBSD$ */ /* - * Copyright (C) 2002 by Darren Reed. - * - * See the IPFILTER.LICENCE file for details on licencing. - * - * $Id: nametokva.c,v 1.1.4.1 2006/06/16 17:21:07 darrenr Exp $ - */ + * Copyright (C) 2012 by Darren Reed. + * + * See the IPFILTER.LICENCE file for details on licencing. + * + * $Id$ + */ #include "ipf.h" @@ -14,8 +14,8 @@ #include ipfunc_t nametokva(name, iocfunc) -char *name; -ioctlfunc_t iocfunc; + char *name; + ioctlfunc_t iocfunc; { ipfunc_resolve_t res; int fd; @@ -24,7 +24,7 @@ ioctlfunc_t iocfunc; res.ipfu_addr = NULL; fd = -1; - if ((opts & OPT_DONOTHING) == 0) { + if ((opts & OPT_DONTOPEN) == 0) { fd = open(IPL_NAME, O_RDONLY); if (fd == -1) return NULL; diff --git a/contrib/ipfilter/lib/nat_setgroupmap.c b/contrib/ipfilter/lib/nat_setgroupmap.c index 08b1a0a4475b..15c21f6ced12 100644 --- a/contrib/ipfilter/lib/nat_setgroupmap.c +++ b/contrib/ipfilter/lib/nat_setgroupmap.c @@ -1,33 +1,33 @@ /* $FreeBSD$ */ /* - * Copyright (C) 2003 by Darren Reed. + * Copyright (C) 2012 by Darren Reed. * * See the IPFILTER.LICENCE file for details on licencing. */ #if !defined(lint) -static const char rcsid[] = "@(#)$Id: nat_setgroupmap.c,v 1.1.4.1 2006/06/16 17:21:07 darrenr Exp $"; +static const char rcsid[] = "@(#)$Id$"; #endif #include "ipf.h" void nat_setgroupmap(n) -ipnat_t *n; + ipnat_t *n; { - if (n->in_outmsk == n->in_inmsk) + if (n->in_nsrcmsk == n->in_osrcmsk) n->in_ippip = 1; else if (n->in_flags & IPN_AUTOPORTMAP) { - n->in_ippip = ~ntohl(n->in_inmsk); - if (n->in_outmsk != 0xffffffff) - n->in_ippip /= (~ntohl(n->in_outmsk) + 1); + n->in_ippip = ~ntohl(n->in_osrcmsk); + if (n->in_nsrcmsk != 0xffffffff) + n->in_ippip /= (~ntohl(n->in_nsrcmsk) + 1); n->in_ippip++; if (n->in_ippip == 0) n->in_ippip = 1; n->in_ppip = USABLE_PORTS / n->in_ippip; } else { - n->in_space = USABLE_PORTS * ~ntohl(n->in_outmsk); - n->in_nip = 0; - if (!(n->in_ppip = n->in_pmin)) + n->in_space = USABLE_PORTS * ~ntohl(n->in_nsrcmsk); + n->in_snip = 0; + if (!(n->in_ppip = n->in_spmin)) n->in_ppip = 1; n->in_ippip = USABLE_PORTS / n->in_ppip; } diff --git a/contrib/ipfilter/lib/ntomask.c b/contrib/ipfilter/lib/ntomask.c index ba91a65b526c..98e3b26119b0 100644 --- a/contrib/ipfilter/lib/ntomask.c +++ b/contrib/ipfilter/lib/ntomask.c @@ -1,28 +1,28 @@ /* $FreeBSD$ */ /* - * Copyright (C) 2002-2005 by Darren Reed. - * - * See the IPFILTER.LICENCE file for details on licencing. - * - * $Id: ntomask.c,v 1.6.2.1 2006/06/16 17:21:07 darrenr Exp $ - */ + * Copyright (C) 2012 by Darren Reed. + * + * See the IPFILTER.LICENCE file for details on licencing. + * + * $Id$ + */ #include "ipf.h" -int ntomask(v, nbits, ap) -int v, nbits; -u_32_t *ap; +int ntomask(family, nbits, ap) + int family, nbits; + u_32_t *ap; { u_32_t mask; if (nbits < 0) return -1; - switch (v) + switch (family) { - case 4 : - if (nbits > 32 || use_inet6 != 0) + case AF_INET : + if (nbits > 32 || use_inet6 == 1) return -1; if (nbits == 0) { mask = 0; @@ -33,8 +33,9 @@ u_32_t *ap; *ap = htonl(mask); break; - case 6 : - if ((nbits > 128) || (use_inet6 == 0)) + case 0 : + case AF_INET6 : + if ((nbits > 128) || (use_inet6 == -1)) return -1; fill6bits(nbits, ap); break; diff --git a/contrib/ipfilter/lib/optname.c b/contrib/ipfilter/lib/optname.c index f41cab11ea17..2bc811b8dbe5 100644 --- a/contrib/ipfilter/lib/optname.c +++ b/contrib/ipfilter/lib/optname.c @@ -1,20 +1,20 @@ /* $FreeBSD$ */ /* - * Copyright (C) 2000-2001 by Darren Reed. + * Copyright (C) 2012 by Darren Reed. * * See the IPFILTER.LICENCE file for details on licencing. * - * $Id: optname.c,v 1.3.4.1 2006/06/16 17:21:07 darrenr Exp $ + * $Id$ */ #include "ipf.h" u_32_t optname(cp, sp, linenum) -char ***cp; -u_short *sp; -int linenum; + char ***cp; + u_short *sp; + int linenum; { struct ipopt_names *io, *so; u_long msk = 0; diff --git a/contrib/ipfilter/lib/optprint.c b/contrib/ipfilter/lib/optprint.c index 81a3287cf672..8b1f5cd9d042 100644 --- a/contrib/ipfilter/lib/optprint.c +++ b/contrib/ipfilter/lib/optprint.c @@ -1,18 +1,18 @@ /* $FreeBSD$ */ /* - * Copyright (C) 2000-2005 by Darren Reed. + * Copyright (C) 2012 by Darren Reed. * * See the IPFILTER.LICENCE file for details on licencing. * - * $Id: optprint.c,v 1.6.4.2 2006/06/16 17:21:08 darrenr Exp $ + * $Id$ */ #include "ipf.h" void optprint(sec, optmsk, optbits) -u_short *sec; -u_long optmsk, optbits; + u_short *sec; + u_long optmsk, optbits; { u_short secmsk = sec[0], secbits = sec[1]; struct ipopt_names *io, *so; diff --git a/contrib/ipfilter/lib/optprintv6.c b/contrib/ipfilter/lib/optprintv6.c index f6ea6eca905e..752d1b353485 100644 --- a/contrib/ipfilter/lib/optprintv6.c +++ b/contrib/ipfilter/lib/optprintv6.c @@ -1,11 +1,11 @@ /* $FreeBSD$ */ /* - * Copyright (C) 2003 by Darren Reed. + * Copyright (C) 2012 by Darren Reed. * * See the IPFILTER.LICENCE file for details on licencing. * - * $Id: optprintv6.c,v 1.2.4.1 2006/06/16 17:21:08 darrenr Exp $ + * $Id$ */ #include "ipf.h" @@ -13,14 +13,14 @@ #ifdef USE_INET6 void optprintv6(sec, optmsk, optbits) -u_short *sec; -u_long optmsk, optbits; + u_short *sec; + u_long optmsk, optbits; { u_short secmsk = sec[0], secbits = sec[1]; struct ipopt_names *io; char *s; - s = " v6hdrs "; + s = " v6hdr "; for (io = v6ionames; io->on_name; io++) if ((io->on_bit & optmsk) && ((io->on_bit & optmsk) == (io->on_bit & optbits))) { diff --git a/contrib/ipfilter/lib/optvalue.c b/contrib/ipfilter/lib/optvalue.c index aa1ef2e7648f..5bc1f4298a25 100644 --- a/contrib/ipfilter/lib/optvalue.c +++ b/contrib/ipfilter/lib/optvalue.c @@ -1,17 +1,17 @@ /* $FreeBSD$ */ /* - * Copyright (C) 2001-2002 by Darren Reed. + * Copyright (C) 2012 by Darren Reed. * * See the IPFILTER.LICENCE file for details on licencing. * - * $Id: optvalue.c,v 1.2.4.1 2006/06/16 17:21:08 darrenr Exp $ + * $Id$ */ #include "ipf.h" u_32_t getoptbyname(optname) -char *optname; + char *optname; { struct ipopt_names *io; @@ -23,7 +23,7 @@ char *optname; u_32_t getoptbyvalue(optval) -int optval; + int optval; { struct ipopt_names *io; diff --git a/contrib/ipfilter/lib/parsefields.c b/contrib/ipfilter/lib/parsefields.c new file mode 100644 index 000000000000..241496c96da9 --- /dev/null +++ b/contrib/ipfilter/lib/parsefields.c @@ -0,0 +1,48 @@ +#include "ipf.h" + +extern int nohdrfields; + +wordtab_t *parsefields(table, arg) + wordtab_t *table; + char *arg; +{ + wordtab_t *f, *fields; + char *s, *t; + int num; + + fields = NULL; + num = 0; + + for (s = strtok(arg, ","); s != NULL; s = strtok(NULL, ",")) { + t = strchr(s, '='); + if (t != NULL) { + *t++ = '\0'; + if (*t == '\0') + nohdrfields = 1; + } + + f = findword(table, s); + if (f == NULL) { + fprintf(stderr, "Unknown field '%s'\n", s); + exit(1); + } + + num++; + if (fields == NULL) { + fields = malloc(2 * sizeof(*fields)); + } else { + fields = realloc(fields, (num + 1) * sizeof(*fields)); + } + + if (t == NULL) { + fields[num - 1].w_word = f->w_word; + } else { + fields[num - 1].w_word = t; + } + fields[num - 1].w_value = f->w_value; + fields[num].w_word = NULL; + fields[num].w_value = 0; + } + + return fields; +} diff --git a/contrib/ipfilter/lib/parseipfexpr.c b/contrib/ipfilter/lib/parseipfexpr.c new file mode 100644 index 000000000000..9a2a2071e9db --- /dev/null +++ b/contrib/ipfilter/lib/parseipfexpr.c @@ -0,0 +1,283 @@ +#include "ipf.h" +#include + + +typedef struct ipfopentry { + int ipoe_cmd; + int ipoe_nbasearg; + int ipoe_maxarg; + int ipoe_argsize; + char *ipoe_word; +} ipfopentry_t; + +static ipfopentry_t opwords[17] = { + { IPF_EXP_IP_ADDR, 2, 0, 1, "ip.addr" }, + { IPF_EXP_IP6_ADDR, 2, 0, 4, "ip6.addr" }, + { IPF_EXP_IP_PR, 1, 0, 1, "ip.p" }, + { IPF_EXP_IP_SRCADDR, 2, 0, 1, "ip.src" }, + { IPF_EXP_IP_DSTADDR, 2, 0, 1, "ip.dst" }, + { IPF_EXP_IP6_SRCADDR, 2, 0, 4, "ip6.src" }, + { IPF_EXP_IP6_DSTADDR, 2, 0, 4, "ip6.dst" }, + { IPF_EXP_TCP_PORT, 1, 0, 1, "tcp.port" }, + { IPF_EXP_TCP_DPORT, 1, 0, 1, "tcp.dport" }, + { IPF_EXP_TCP_SPORT, 1, 0, 1, "tcp.sport" }, + { IPF_EXP_TCP_FLAGS, 2, 0, 1, "tcp.flags" }, + { IPF_EXP_UDP_PORT, 1, 0, 1, "udp.port" }, + { IPF_EXP_UDP_DPORT, 1, 0, 1, "udp.dport" }, + { IPF_EXP_UDP_SPORT, 1, 0, 1, "udp.sport" }, + { IPF_EXP_TCP_STATE, 1, 0, 1, "tcp.state" }, + { IPF_EXP_IDLE_GT, 1, 1, 1, "idle-gt" }, + { -1, 0, 0, 0, NULL } +}; + + +int * +parseipfexpr(line, errorptr) + char *line; + char **errorptr; +{ + int not, items, asize, *oplist, osize, i; + char *temp, *arg, *s, *t, *ops, *error; + ipfopentry_t *e; + ipfexp_t *ipfe; + + asize = 0; + error = NULL; + oplist = NULL; + + temp = strdup(line); + if (temp == NULL) { + error = "strdup failed"; + goto parseerror; + } + + /* + * Eliminate any white spaces to make parsing easier. + */ + for (s = temp; *s != '\0'; ) { + if (ISSPACE(*s)) + strcpy(s, s + 1); + else + s++; + } + + /* + * Parse the string. + * It should be sets of "ip.dst=1.2.3.4/32;" things. + * There must be a "=" or "!=" and it must end in ";". + */ + if (temp[strlen(temp) - 1] != ';') { + error = "last character not ';'"; + goto parseerror; + } + + /* + * Work through the list of complete operands present. + */ + for (ops = strtok(temp, ";"); ops != NULL; ops = strtok(NULL, ";")) { + arg = strchr(ops, '='); + if ((arg < ops + 2) || (arg == NULL)) { + error = "bad 'arg' vlaue"; + goto parseerror; + } + + if (*(arg - 1) == '!') { + *(arg - 1) = '\0'; + not = 1; + } else { + not = 0; + } + *arg++ = '\0'; + + + for (e = opwords; e->ipoe_word; e++) { + if (strcmp(ops, e->ipoe_word) == 0) + break; + } + if (e->ipoe_word == NULL) { + error = malloc(32); + if (error != NULL) { + sprintf(error, "keyword (%.10s) not found", + ops); + } + goto parseerror; + } + + /* + * Count the number of commas so we know how big to + * build the array + */ + for (s = arg, items = 1; *s != '\0'; s++) + if (*s == ',') + items++; + + if ((e->ipoe_maxarg != 0) && (items > e->ipoe_maxarg)) { + error = "too many items"; + goto parseerror; + } + + /* + * osize will mark the end of where we have filled up to + * and is thus where we start putting new data. + */ + osize = asize; + asize += 4 + (items * e->ipoe_nbasearg * e->ipoe_argsize); + if (oplist == NULL) + oplist = calloc(1, sizeof(int) * (asize + 2)); + else + oplist = realloc(oplist, sizeof(int) * (asize + 2)); + if (oplist == NULL) { + error = "oplist alloc failed"; + goto parseerror; + } + ipfe = (ipfexp_t *)(oplist + osize); + osize += 4; + ipfe->ipfe_cmd = e->ipoe_cmd; + ipfe->ipfe_not = not; + ipfe->ipfe_narg = items * e->ipoe_nbasearg; + ipfe->ipfe_size = items * e->ipoe_nbasearg * e->ipoe_argsize; + ipfe->ipfe_size += 4; + + for (s = arg; (*s != '\0') && (osize < asize); s = t) { + /* + * Look for the end of this arg or the ',' to say + * there is another following. + */ + for (t = s; (*t != '\0') && (*t != ','); t++) + ; + if (*t == ',') + *t++ = '\0'; + + if (!strcasecmp(ops, "ip.addr") || + !strcasecmp(ops, "ip.src") || + !strcasecmp(ops, "ip.dst")) { + i6addr_t mask, addr; + char *delim; + + delim = strchr(s, '/'); + if (delim != NULL) { + *delim++ = '\0'; + if (genmask(AF_INET, delim, + &mask) == -1) { + error = "genmask failed"; + goto parseerror; + } + } else { + mask.in4.s_addr = 0xffffffff; + } + if (gethost(AF_INET, s, &addr) == -1) { + error = "gethost failed"; + goto parseerror; + } + + oplist[osize++] = addr.in4.s_addr; + oplist[osize++] = mask.in4.s_addr; + +#ifdef USE_INET6 + } else if (!strcasecmp(ops, "ip6.addr") || + !strcasecmp(ops, "ip6.src") || + !strcasecmp(ops, "ip6.dst")) { + i6addr_t mask, addr; + char *delim; + + delim = strchr(s, '/'); + if (delim != NULL) { + *delim++ = '\0'; + if (genmask(AF_INET6, delim, + &mask) == -1) { + error = "genmask failed"; + goto parseerror; + } + } else { + mask.i6[0] = 0xffffffff; + mask.i6[1] = 0xffffffff; + mask.i6[2] = 0xffffffff; + mask.i6[3] = 0xffffffff; + } + if (gethost(AF_INET6, s, &addr) == -1) { + error = "gethost failed"; + goto parseerror; + } + + oplist[osize++] = addr.i6[0]; + oplist[osize++] = addr.i6[1]; + oplist[osize++] = addr.i6[2]; + oplist[osize++] = addr.i6[3]; + oplist[osize++] = mask.i6[0]; + oplist[osize++] = mask.i6[1]; + oplist[osize++] = mask.i6[2]; + oplist[osize++] = mask.i6[3]; +#endif + + } else if (!strcasecmp(ops, "ip.p")) { + int p; + + p = getproto(s); + if (p == -1) + goto parseerror; + oplist[osize++] = p; + + } else if (!strcasecmp(ops, "tcp.flags")) { + u_32_t mask, flags; + char *delim; + + delim = strchr(s, '/'); + if (delim != NULL) { + *delim++ = '\0'; + mask = tcpflags(delim); + } else { + mask = 0xff; + } + flags = tcpflags(s); + + oplist[osize++] = flags; + oplist[osize++] = mask; + + + } else if (!strcasecmp(ops, "tcp.port") || + !strcasecmp(ops, "tcp.sport") || + !strcasecmp(ops, "tcp.dport") || + !strcasecmp(ops, "udp.port") || + !strcasecmp(ops, "udp.sport") || + !strcasecmp(ops, "udp.dport")) { + char proto[4]; + u_short port; + + strncpy(proto, ops, 3); + proto[3] = '\0'; + if (getport(NULL, s, &port, proto) == -1) + goto parseerror; + oplist[osize++] = port; + + } else if (!strcasecmp(ops, "tcp.state")) { + oplist[osize++] = atoi(s); + + } else { + error = "unknown word"; + goto parseerror; + } + } + } + + free(temp); + + if (errorptr != NULL) + *errorptr = NULL; + + for (i = asize; i > 0; i--) + oplist[i] = oplist[i - 1]; + + oplist[0] = asize + 2; + oplist[asize + 1] = IPF_EXP_END; + + return oplist; + +parseerror: + if (errorptr != NULL) + *errorptr = error; + if (oplist != NULL) + free(oplist); + if (temp != NULL) + free(temp); + return NULL; +} diff --git a/contrib/ipfilter/lib/parsewhoisline.c b/contrib/ipfilter/lib/parsewhoisline.c new file mode 100644 index 000000000000..526935ca23a5 --- /dev/null +++ b/contrib/ipfilter/lib/parsewhoisline.c @@ -0,0 +1,132 @@ +/* + * Copyright (C) 2012 by Darren Reed. + * + * See the IPFILTER.LICENCE file for details on licencing. + * + * $Id: parsewhoisline.c,v 1.2.2.5 2012/07/22 08:04:24 darren_r Exp $ + */ +#include "ipf.h" + +/* +Microsoft Corp MICROSOFT19 (NET-198-136-97-0-1) 198.137.97.0 - 198.137.97.255 +Microsoft Corp SAVV-S233053-6 (NET-206-79-74-32-1) 206.79.74.32 - 206.79.74.47 + */ +int +parsewhoisline(line, addrp, maskp) + char *line; + addrfamily_t *addrp; + addrfamily_t *maskp; +{ + struct in_addr a1, a2; + char *src = line; + char *s = NULL; + + if (line == NULL) + return -1; + + while (*src != '\0') { + s = strchr(src, '('); + if (s == NULL) + break; + + if (strncmp(s, "(NET", 4)) { + src = s + 1; + } + break; + } + + if (s == NULL) + return -1; + + memset(addrp, 0x00, sizeof(*maskp)); + memset(maskp, 0x00, sizeof(*maskp)); + + if (*(s + 4) == '6') { +#ifdef USE_INET6 + i6addr_t a61, a62; + + s = strchr(s, ')'); + if (s == NULL || *++s != ' ') + return -1; + /* + * Parse the IPv6 + */ + if (inet_pton(AF_INET6, s, &a61.in6) != 1) + return -1; + + s = strchr(s, ' '); + if (s == NULL || strncmp(s, " - ", 3)) + return -1; + + s += 3; + if (inet_pton(AF_INET6, s, &a62) != 1) + return -1; + + addrp->adf_addr = a61; + addrp->adf_family = AF_INET6; + addrp->adf_len = offsetof(addrfamily_t, adf_addr) + + sizeof(struct in6_addr); + + maskp->adf_addr.i6[0] = ~(a62.i6[0] ^ a61.i6[0]); + maskp->adf_addr.i6[1] = ~(a62.i6[1] ^ a61.i6[1]); + maskp->adf_addr.i6[2] = ~(a62.i6[2] ^ a61.i6[2]); + maskp->adf_addr.i6[3] = ~(a62.i6[3] ^ a61.i6[3]); + + /* + * If the mask that's been generated isn't a consecutive mask + * then we can't add it into a pool. + */ + if (count6bits(maskp->adf_addr.i6) == -1) + return -1; + + maskp->adf_family = AF_INET6; + maskp->adf_len = addrp->adf_len; + + if (IP6_MASKNEQ(&addrp->adf_addr.in6, &maskp->adf_addr.in6, + &addrp->adf_addr.in6)) { + return -1; + } + return 0; +#else + return -1; +#endif + } + + s = strchr(s, ')'); + if (s == NULL || *++s != ' ') + return -1; + + s++; + + if (inet_aton(s, &a1) != 1) + return -1; + + s = strchr(s, ' '); + if (s == NULL || strncmp(s, " - ", 3)) + return -1; + + s += 3; + if (inet_aton(s, &a2) != 1) + return -1; + + addrp->adf_addr.in4 = a1; + addrp->adf_family = AF_INET; + addrp->adf_len = offsetof(addrfamily_t, adf_addr) + + sizeof(struct in_addr); + maskp->adf_addr.in4.s_addr = ~(a2.s_addr ^ a1.s_addr); + + /* + * If the mask that's been generated isn't a consecutive mask then + * we can't add it into a pool. + */ + if (count4bits(maskp->adf_addr.in4.s_addr) == -1) + return -1; + + maskp->adf_family = AF_INET; + maskp->adf_len = addrp->adf_len; + bzero((char *)maskp + maskp->adf_len, sizeof(*maskp) - maskp->adf_len); + if ((addrp->adf_addr.in4.s_addr & maskp->adf_addr.in4.s_addr) != + addrp->adf_addr.in4.s_addr) + return -1; + return 0; +} diff --git a/contrib/ipfilter/lib/poolio.c b/contrib/ipfilter/lib/poolio.c new file mode 100644 index 000000000000..18cf698222a8 --- /dev/null +++ b/contrib/ipfilter/lib/poolio.c @@ -0,0 +1,53 @@ +/* + * Copyright (C) 2012 by Darren Reed. + * + * See the IPFILTER.LICENCE file for details on licencing. + * + * $Id: poolio.c,v 1.1.2.3 2012/07/22 08:04:24 darren_r Exp $ + */ + +#include +#include +#include "ipf.h" +#include "netinet/ip_lookup.h" +#include "netinet/ip_pool.h" + +static int poolfd = -1; + + +int +pool_open() +{ + + if ((opts & OPT_DONTOPEN) != 0) + return 0; + + if (poolfd == -1) + poolfd = open(IPLOOKUP_NAME, O_RDWR); + return poolfd; +} + +int +pool_ioctl(iocfunc, cmd, ptr) + ioctlfunc_t iocfunc; + ioctlcmd_t cmd; + void *ptr; +{ + return (*iocfunc)(poolfd, cmd, ptr); +} + + +void +pool_close() +{ + if (poolfd != -1) { + close(poolfd); + poolfd = -1; + } +} + +int +pool_fd() +{ + return poolfd; +} diff --git a/contrib/ipfilter/lib/portname.c b/contrib/ipfilter/lib/portname.c index f0c8625e6a77..59345f4b2f57 100644 --- a/contrib/ipfilter/lib/portname.c +++ b/contrib/ipfilter/lib/portname.c @@ -1,21 +1,22 @@ /* $FreeBSD$ */ /* - * Copyright (C) 2000-2003 by Darren Reed. + * Copyright (C) 2012 by Darren Reed. * * See the IPFILTER.LICENCE file for details on licencing. * - * $Id: portname.c,v 1.7.2.1 2006/06/16 17:21:09 darrenr Exp $ + * $Id$ */ #include "ipf.h" -char *portname(pr, port) -int pr, port; +char *portname(pr, port) + int pr, port; { - static char buf[32]; - struct protoent *p = NULL; - struct servent *sv = NULL, *sv1 = NULL; + static char buf[32]; + struct protoent *p = NULL; + struct servent *sv = NULL; + struct servent *sv1 = NULL; if ((opts & OPT_NORESOLVE) == 0) { if (pr == -1) { diff --git a/contrib/ipfilter/lib/prependmbt.c b/contrib/ipfilter/lib/prependmbt.c new file mode 100644 index 000000000000..4f7220ba236a --- /dev/null +++ b/contrib/ipfilter/lib/prependmbt.c @@ -0,0 +1,18 @@ +/* + * Copyright (C) 2012 by Darren Reed. + * + * See the IPFILTER.LICENCE file for details on licencing. + * + * $Id: prependmbt.c,v 1.3.2.3 2012/07/22 08:04:24 darren_r Exp $ + */ + +#include "ipf.h" + +int prependmbt(fin, m) + fr_info_t *fin; + mb_t *m; +{ + m->mb_next = *fin->fin_mp; + *fin->fin_mp = m; + return 0; +} diff --git a/contrib/ipfilter/lib/print_toif.c b/contrib/ipfilter/lib/print_toif.c index 94a4618dbae2..fb4a266318b4 100644 --- a/contrib/ipfilter/lib/print_toif.c +++ b/contrib/ipfilter/lib/print_toif.c @@ -1,32 +1,50 @@ /* $FreeBSD$ */ /* - * Copyright (C) 2000-2002 by Darren Reed. + * Copyright (C) 2012 by Darren Reed. * * See the IPFILTER.LICENCE file for details on licencing. * - * $Id: print_toif.c,v 1.8.4.1 2006/06/16 17:21:09 darrenr Exp $ + * $Id$ */ #include "ipf.h" -void print_toif(tag, fdp) -char *tag; -frdest_t *fdp; +void +print_toif(family, tag, base, fdp) + int family; + char *tag; + char *base; + frdest_t *fdp; { - printf("%s %s%s", tag, fdp->fd_ifname, - (fdp->fd_ifp || (long)fdp->fd_ifp == -1) ? "" : "(!)"); + switch (fdp->fd_type) + { + case FRD_NORMAL : + PRINTF("%s %s%s", tag, base + fdp->fd_name, + (fdp->fd_ptr || (long)fdp->fd_ptr == -1) ? "" : "(!)"); #ifdef USE_INET6 - if (use_inet6 && IP6_NOTZERO(&fdp->fd_ip6.in6)) { - char ipv6addr[80]; + if (family == AF_INET6) { + if (IP6_NOTZERO(&fdp->fd_ip6)) { + char ipv6addr[80]; - inet_ntop(AF_INET6, &fdp->fd_ip6, ipv6addr, - sizeof(fdp->fd_ip6)); - printf(":%s", ipv6addr); - } else + inet_ntop(AF_INET6, &fdp->fd_ip6, ipv6addr, + sizeof(fdp->fd_ip6)); + PRINTF(":%s", ipv6addr); + } + } else #endif - if (fdp->fd_ip.s_addr) - printf(":%s", inet_ntoa(fdp->fd_ip)); - putchar(' '); + if (fdp->fd_ip.s_addr) + PRINTF(":%s", inet_ntoa(fdp->fd_ip)); + putchar(' '); + break; + + case FRD_DSTLIST : + PRINTF("%s dstlist/%s ", tag, base + fdp->fd_name); + break; + + default : + PRINTF("%s <%d>", tag, fdp->fd_type); + break; + } } diff --git a/contrib/ipfilter/lib/printactiveaddr.c b/contrib/ipfilter/lib/printactiveaddr.c new file mode 100644 index 000000000000..531cdc1fc782 --- /dev/null +++ b/contrib/ipfilter/lib/printactiveaddr.c @@ -0,0 +1,37 @@ +/* + * Copyright (C) 2012 by Darren Reed. + * + * See the IPFILTER.LICENCE file for details on licencing. + * + * Added redirect stuff and a variety of bug fixes. (mcn@EnGarde.com) + */ + +#include "ipf.h" + + +#if !defined(lint) +static const char rcsid[] = "@(#)$Id: printactiveaddr.c,v 1.3.2.2 2012/07/22 08:04:24 darren_r Exp $"; +#endif + + +void +printactiveaddress(v, fmt, addr, ifname) + int v; + char *fmt, *ifname; + i6addr_t *addr; +{ + switch (v) + { + case 4 : + PRINTF(fmt, inet_ntoa(addr->in4)); + break; +#ifdef USE_INET6 + case 6 : + printaddr(AF_INET6, FRI_NORMAL, ifname, 0, + (u_32_t *)&addr->in6, NULL); + break; +#endif + default : + break; + } +} diff --git a/contrib/ipfilter/lib/printactivenat.c b/contrib/ipfilter/lib/printactivenat.c index a2e292406614..c696c0b2cacd 100644 --- a/contrib/ipfilter/lib/printactivenat.c +++ b/contrib/ipfilter/lib/printactivenat.c @@ -1,7 +1,7 @@ /* $FreeBSD$ */ /* - * Copyright (C) 2002-2004 by Darren Reed. + * Copyright (C) 2012 by Darren Reed. * * See the IPFILTER.LICENCE file for details on licencing. * @@ -12,73 +12,135 @@ #if !defined(lint) -static const char rcsid[] = "@(#)$Id: printactivenat.c,v 1.3.2.7 2006/12/12 16:13:00 darrenr Exp $"; +static const char rcsid[] = "@(#)$Id$"; #endif -void printactivenat(nat, opts, alive, now) -nat_t *nat; -int opts, alive; -u_long now; +void +printactivenat(nat, opts, ticks) + nat_t *nat; + int opts; + u_long ticks; { - printf("%s", getnattype(nat, alive)); + PRINTF("%s", getnattype(nat)); if (nat->nat_flags & SI_CLONE) - printf(" CLONE"); + PRINTF(" CLONE"); + if (nat->nat_phnext[0] == NULL && nat->nat_phnext[1] == NULL) + PRINTF(" ORPHAN"); - printf(" %-15s", inet_ntoa(nat->nat_inip)); + putchar(' '); + if (nat->nat_redir & NAT_REWRITE) { + printactiveaddress(nat->nat_v[0], "%-15s", &nat->nat_osrc6, + nat->nat_ifnames[0]); - if ((nat->nat_flags & IPN_TCPUDP) != 0) - printf(" %-5hu", ntohs(nat->nat_inport)); + if ((nat->nat_flags & IPN_TCPUDP) != 0) + PRINTF(" %-5hu", ntohs(nat->nat_osport)); - printf(" <- -> %-15s",inet_ntoa(nat->nat_outip)); + putchar(' '); + printactiveaddress(nat->nat_v[0], "%-15s", &nat->nat_odst6, + nat->nat_ifnames[0]); - if ((nat->nat_flags & IPN_TCPUDP) != 0) - printf(" %-5hu", ntohs(nat->nat_outport)); + if ((nat->nat_flags & IPN_TCPUDP) != 0) + PRINTF(" %-5hu", ntohs(nat->nat_odport)); - printf(" [%s", inet_ntoa(nat->nat_oip)); - if ((nat->nat_flags & IPN_TCPUDP) != 0) - printf(" %hu", ntohs(nat->nat_oport)); - printf("]"); + PRINTF("<- -> "); + printactiveaddress(nat->nat_v[1], "%-15s", &nat->nat_nsrc6, + nat->nat_ifnames[0]); + + if ((nat->nat_flags & IPN_TCPUDP) != 0) + PRINTF(" %-5hu", ntohs(nat->nat_nsport)); + + putchar(' '); + printactiveaddress(nat->nat_v[1], "%-15s", &nat->nat_ndst6, + nat->nat_ifnames[0]); + if ((nat->nat_flags & IPN_TCPUDP) != 0) + PRINTF(" %-5hu", ntohs(nat->nat_ndport)); + + } else if (nat->nat_dir == NAT_OUTBOUND) { + printactiveaddress(nat->nat_v[0], "%-15s", &nat->nat_osrc6, + nat->nat_ifnames[0]); + + if ((nat->nat_flags & IPN_TCPUDP) != 0) + PRINTF(" %-5hu", ntohs(nat->nat_osport)); + + PRINTF(" <- -> "); + printactiveaddress(nat->nat_v[1], "%-15s", &nat->nat_nsrc6, + nat->nat_ifnames[0]); + + if ((nat->nat_flags & IPN_TCPUDP) != 0) + PRINTF(" %-5hu", ntohs(nat->nat_nsport)); + + PRINTF(" ["); + printactiveaddress(nat->nat_v[0], "%s", &nat->nat_odst6, + nat->nat_ifnames[0]); + + if ((nat->nat_flags & IPN_TCPUDP) != 0) + PRINTF(" %hu", ntohs(nat->nat_odport)); + PRINTF("]"); + } else { + printactiveaddress(nat->nat_v[1], "%-15s", &nat->nat_ndst6, + nat->nat_ifnames[0]); + + if ((nat->nat_flags & IPN_TCPUDP) != 0) + PRINTF(" %-5hu", ntohs(nat->nat_ndport)); + + PRINTF(" <- -> "); + printactiveaddress(nat->nat_v[0], "%-15s", &nat->nat_odst6, + nat->nat_ifnames[0]); + + if ((nat->nat_flags & IPN_TCPUDP) != 0) + PRINTF(" %-5hu", ntohs(nat->nat_odport)); + + PRINTF(" ["); + printactiveaddress(nat->nat_v[0], "%s", &nat->nat_osrc6, + nat->nat_ifnames[0]); + + if ((nat->nat_flags & IPN_TCPUDP) != 0) + PRINTF(" %hu", ntohs(nat->nat_osport)); + PRINTF("]"); + } if (opts & OPT_VERBOSE) { - printf("\n\tttl %lu use %hu sumd %s/", - nat->nat_age - now, nat->nat_use, + PRINTF("\n\tttl %lu use %hu sumd %s/", + nat->nat_age - ticks, nat->nat_use, getsumd(nat->nat_sumd[0])); - printf("%s pr %u bkt %d/%d flags %x\n", - getsumd(nat->nat_sumd[1]), nat->nat_p, + PRINTF("%s pr %u/%u hash %u/%u flags %x\n", + getsumd(nat->nat_sumd[1]), + nat->nat_pr[0], nat->nat_pr[1], nat->nat_hv[0], nat->nat_hv[1], nat->nat_flags); - printf("\tifp %s", getifname(nat->nat_ifps[0])); - printf(",%s ", getifname(nat->nat_ifps[1])); + PRINTF("\tifp %s", getifname(nat->nat_ifps[0])); + PRINTF(",%s ", getifname(nat->nat_ifps[1])); #ifdef USE_QUAD_T - printf("bytes %qu/%qu pkts %qu/%qu", + PRINTF("bytes %"PRIu64"/%"PRIu64" pkts %"PRIu64"/%"PRIu64"", (unsigned long long)nat->nat_bytes[0], (unsigned long long)nat->nat_bytes[1], (unsigned long long)nat->nat_pkts[0], (unsigned long long)nat->nat_pkts[1]); #else - printf("bytes %lu/%lu pkts %lu/%lu", nat->nat_bytes[0], + PRINTF("bytes %lu/%lu pkts %lu/%lu", nat->nat_bytes[0], nat->nat_bytes[1], nat->nat_pkts[0], nat->nat_pkts[1]); #endif - printf(" ipsumd %x", nat->nat_ipsumd); + PRINTF(" ipsumd %x", nat->nat_ipsumd); } if (opts & OPT_DEBUG) { - printf("\n\tnat_next %p _pnext %p _hm %p\n", + PRINTF("\n\tnat_next %p _pnext %p _hm %p\n", nat->nat_next, nat->nat_pnext, nat->nat_hm); - printf("\t_hnext %p/%p _phnext %p/%p\n", + PRINTF("\t_hnext %p/%p _phnext %p/%p\n", nat->nat_hnext[0], nat->nat_hnext[1], nat->nat_phnext[0], nat->nat_phnext[1]); - printf("\t_data %p _me %p _state %p _aps %p\n", - nat->nat_data, nat->nat_me, nat->nat_state, nat->nat_aps); - printf("\tfr %p ptr %p ifps %p/%p sync %p\n", + PRINTF("\t_data %p _me %p _state %p _aps %p\n", + nat->nat_data, nat->nat_me, nat->nat_state, + nat->nat_aps); + PRINTF("\tfr %p ptr %p ifps %p/%p sync %p\n", nat->nat_fr, nat->nat_ptr, nat->nat_ifps[0], nat->nat_ifps[1], nat->nat_sync); - printf("\ttqe:pnext %p next %p ifq %p parent %p/%p\n", + PRINTF("\ttqe:pnext %p next %p ifq %p parent %p/%p\n", nat->nat_tqe.tqe_pnext, nat->nat_tqe.tqe_next, nat->nat_tqe.tqe_ifq, nat->nat_tqe.tqe_parent, nat); - printf("\ttqe:die %ld touched %ld flags %x state %d/%d\n", + PRINTF("\ttqe:die %d touched %d flags %x state %d/%d\n", nat->nat_tqe.tqe_die, nat->nat_tqe.tqe_touched, nat->nat_tqe.tqe_flags, nat->nat_tqe.tqe_state[0], nat->nat_tqe.tqe_state[1]); diff --git a/contrib/ipfilter/lib/printaddr.c b/contrib/ipfilter/lib/printaddr.c new file mode 100644 index 000000000000..03fbacbcce74 --- /dev/null +++ b/contrib/ipfilter/lib/printaddr.c @@ -0,0 +1,75 @@ +/* + * Copyright (C) 2012 by Darren Reed. + * + * See the IPFILTER.LICENCE file for details on licencing. + * + * $Id$ + */ + +#include "ipf.h" + +void +printaddr(family, type, base, ifidx, addr, mask) + int family, type, ifidx; + char *base; + u_32_t *addr, *mask; +{ + char *suffix; + + switch (type) + { + case FRI_BROADCAST : + suffix = "bcast"; + break; + + case FRI_DYNAMIC : + PRINTF("%s", base + ifidx); + printmask(family, mask); + suffix = NULL; + break; + + case FRI_NETWORK : + suffix = "net"; + break; + + case FRI_NETMASKED : + suffix = "netmasked"; + break; + + case FRI_PEERADDR : + suffix = "peer"; + break; + + case FRI_LOOKUP : + suffix = NULL; + printlookup(base, (i6addr_t *)addr, (i6addr_t *)mask); + break; + + case FRI_NONE : + case FRI_NORMAL : + printhostmask(family, addr, mask); + suffix = NULL; + break; + case FRI_RANGE : + printhost(family, addr); + putchar('-'); + printhost(family, mask); + suffix = NULL; + break; + case FRI_SPLIT : + printhost(family, addr); + putchar(','); + printhost(family, mask); + suffix = NULL; + break; + default : + PRINTF("<%d>", type); + printmask(family, mask); + suffix = NULL; + break; + } + + if (suffix != NULL) { + PRINTF("%s/%s", base + ifidx, suffix); + } +} diff --git a/contrib/ipfilter/lib/printaps.c b/contrib/ipfilter/lib/printaps.c index 87a12cd494fc..0304f34c6010 100644 --- a/contrib/ipfilter/lib/printaps.c +++ b/contrib/ipfilter/lib/printaps.c @@ -1,7 +1,7 @@ /* $FreeBSD$ */ /* - * Copyright (C) 2002-2004 by Darren Reed. + * Copyright (C) 2012 by Darren Reed. * * See the IPFILTER.LICENCE file for details on licencing. * @@ -13,13 +13,14 @@ #if !defined(lint) -static const char rcsid[] = "@(#)$Id: printaps.c,v 1.4.2.1 2006/06/16 17:21:10 darrenr Exp $"; +static const char rcsid[] = "@(#)$Id$"; #endif -void printaps(aps, opts) -ap_session_t *aps; -int opts; +void +printaps(aps, opts, proto) + ap_session_t *aps; + int opts, proto; { ipsec_pxy_t ipsec; ap_session_t ap; @@ -31,33 +32,33 @@ int opts; return; if (kmemcpy((char *)&apr, (long)ap.aps_apr, sizeof(apr))) return; - printf("\tproxy %s/%d use %d flags %x\n", apr.apr_label, + PRINTF("\tproxy %s/%d use %d flags %x\n", apr.apr_label, 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", (unsigned long long)ap.aps_bytes, + PRINTF("\tbytes %"PRIu64" pkts %"PRIu64"", + (unsigned long long)ap.aps_bytes, (unsigned long long)ap.aps_pkts); #else - printf("%lu pkts %lu", ap.aps_bytes, ap.aps_pkts); + PRINTF("\tbytes %lu pkts %lu", ap.aps_bytes, ap.aps_pkts); #endif - printf(" data %s size %d\n", ap.aps_data ? "YES" : "NO", ap.aps_psiz); - if ((ap.aps_p == IPPROTO_TCP) && (opts & OPT_VERBOSE)) { - printf("\t\tstate[%u,%u], sel[%d,%d]\n", + PRINTF(" data %s\n", ap.aps_data ? "YES" : "NO"); + if ((proto == IPPROTO_TCP) && (opts & OPT_VERBOSE)) { + PRINTF("\t\tstate[%u,%u], sel[%d,%d]\n", ap.aps_state[0], ap.aps_state[1], ap.aps_sel[0], ap.aps_sel[1]); #if (defined(NetBSD) && (NetBSD >= 199905) && (NetBSD < 1991011)) || \ (__FreeBSD_version >= 300000) || defined(OpenBSD) - printf("\t\tseq: off %hd/%hd min %x/%x\n", + PRINTF("\t\tseq: off %hd/%hd min %x/%x\n", ap.aps_seqoff[0], ap.aps_seqoff[1], ap.aps_seqmin[0], ap.aps_seqmin[1]); - printf("\t\tack: off %hd/%hd min %x/%x\n", + PRINTF("\t\tack: off %hd/%hd min %x/%x\n", ap.aps_ackoff[0], ap.aps_ackoff[1], ap.aps_ackmin[0], ap.aps_ackmin[1]); #else - printf("\t\tseq: off %hd/%hd min %lx/%lx\n", + PRINTF("\t\tseq: off %hd/%hd min %lx/%lx\n", ap.aps_seqoff[0], ap.aps_seqoff[1], ap.aps_seqmin[0], ap.aps_seqmin[1]); - printf("\t\tack: off %hd/%hd min %lx/%lx\n", + PRINTF("\t\tack: off %hd/%hd min %lx/%lx\n", ap.aps_ackoff[0], ap.aps_ackoff[1], ap.aps_ackmin[0], ap.aps_ackmin[1]); #endif @@ -66,43 +67,43 @@ int opts; if (!strcmp(apr.apr_label, "raudio") && ap.aps_psiz == sizeof(ra)) { if (kmemcpy((char *)&ra, (long)ap.aps_data, sizeof(ra))) return; - printf("\tReal Audio Proxy:\n"); - printf("\t\tSeen PNA: %d\tVersion: %d\tEOS: %d\n", + PRINTF("\tReal Audio Proxy:\n"); + PRINTF("\t\tSeen PNA: %d\tVersion: %d\tEOS: %d\n", ra.rap_seenpna, ra.rap_version, ra.rap_eos); - printf("\t\tMode: %#x\tSBF: %#x\n", ra.rap_mode, ra.rap_sbf); - printf("\t\tPorts:pl %hu, pr %hu, sr %hu\n", + 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); + 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\tseq %x (ack %x) len %d junk %d cmds %d\n", + PRINTF("\tClient:\n"); + PRINTF("\t\tseq %x (ack %x) len %d junk %d cmds %d\n", ftp.ftp_side[0].ftps_seq[0], ftp.ftp_side[0].ftps_seq[1], ftp.ftp_side[0].ftps_len, ftp.ftp_side[0].ftps_junk, ftp.ftp_side[0].ftps_cmds); - printf("\t\tbuf ["); + PRINTF("\t\tbuf ["); printbuf(ftp.ftp_side[0].ftps_buf, FTP_BUFSZ, 1); - printf("]\n\tServer:\n"); - printf("\t\tseq %x (ack %x) len %d junk %d cmds %d\n", + PRINTF("]\n\tServer:\n"); + PRINTF("\t\tseq %x (ack %x) len %d junk %d cmds %d\n", ftp.ftp_side[1].ftps_seq[0], ftp.ftp_side[1].ftps_seq[1], ftp.ftp_side[1].ftps_len, ftp.ftp_side[1].ftps_junk, ftp.ftp_side[1].ftps_cmds); - printf("\t\tbuf ["); + PRINTF("\t\tbuf ["); printbuf(ftp.ftp_side[1].ftps_buf, FTP_BUFSZ, 1); - printf("]\n"); + PRINTF("]\n"); } else if (!strcmp(apr.apr_label, "ipsec") && (ap.aps_psiz == sizeof(ipsec))) { if (kmemcpy((char *)&ipsec, (long)ap.aps_data, sizeof(ipsec))) return; - printf("\tIPSec Proxy:\n"); - printf("\t\tICookie %08x%08x RCookie %08x%08x %s\n", + PRINTF("\tIPSec Proxy:\n"); + PRINTF("\t\tICookie %08x%08x RCookie %08x%08x %s\n", (u_int)ntohl(ipsec.ipsc_icookie[0]), (u_int)ntohl(ipsec.ipsc_icookie[1]), (u_int)ntohl(ipsec.ipsc_rcookie[0]), diff --git a/contrib/ipfilter/lib/printbuf.c b/contrib/ipfilter/lib/printbuf.c index b2e209a01325..4e9236f0d02d 100644 --- a/contrib/ipfilter/lib/printbuf.c +++ b/contrib/ipfilter/lib/printbuf.c @@ -1,11 +1,11 @@ /* $FreeBSD$ */ /* - * Copyright (C) 2000-2004 by Darren Reed. + * Copyright (C) 2012 by Darren Reed. * * See the IPFILTER.LICENCE file for details on licencing. * - * $Id: printbuf.c,v 1.5.4.2 2006/06/16 17:21:10 darrenr Exp $ + * $Id$ */ #include @@ -13,19 +13,21 @@ #include "ipf.h" -void printbuf(buf, len, zend) -char *buf; -int len, zend; +void +printbuf(buf, len, zend) + char *buf; + int len, zend; { - char *s, c; + char *s; + int c; int i; for (s = buf, i = len; i; i--) { c = *s++; - if (ISPRINT(c)) + if (isprint(c)) putchar(c); else - printf("\\%03o", c); + PRINTF("\\%03o", c); if ((c == '\0') && zend) break; } diff --git a/contrib/ipfilter/lib/printdstl_live.c b/contrib/ipfilter/lib/printdstl_live.c new file mode 100644 index 000000000000..c8741ed4005a --- /dev/null +++ b/contrib/ipfilter/lib/printdstl_live.c @@ -0,0 +1,84 @@ +/* + * Copyright (C) 2012 by Darren Reed. + * + * See the IPFILTER.LICENCE file for details on licencing. + */ + +#include +#include "ipf.h" +#include "netinet/ipl.h" + + +/* + * Because the ipf_dstnode_t can vary in size because of the interface name, + * the size may be larger than just sizeof(). + */ +ippool_dst_t * +printdstl_live(d, fd, name, opts, fields) + ippool_dst_t *d; + int fd; + char *name; + int opts; + wordtab_t *fields; +{ + ipf_dstnode_t *entry, *zero; + ipflookupiter_t iter; + int printed, last; + ipfobj_t obj; + + if ((name != NULL) && strncmp(name, d->ipld_name, FR_GROUPLEN)) + return d->ipld_next; + + entry = calloc(1, sizeof(*entry) + 64); + if (entry == NULL) + return d->ipld_next; + zero = calloc(1, sizeof(*zero) + 64); + if (zero == NULL) { + free(entry); + return d->ipld_next; + } + + if (fields == NULL) + printdstlistdata(d, opts); + + if ((d->ipld_flags & IPHASH_DELETE) != 0) + PRINTF("# "); + + if ((opts & OPT_DEBUG) == 0) + PRINTF("\t{"); + + obj.ipfo_rev = IPFILTER_VERSION; + obj.ipfo_type = IPFOBJ_LOOKUPITER; + obj.ipfo_ptr = &iter; + obj.ipfo_size = sizeof(iter); + + iter.ili_data = entry; + iter.ili_type = IPLT_DSTLIST; + iter.ili_otype = IPFLOOKUPITER_NODE; + iter.ili_ival = IPFGENITER_LOOKUP; + iter.ili_unit = d->ipld_unit; + strncpy(iter.ili_name, d->ipld_name, FR_GROUPLEN); + + last = 0; + printed = 0; + + while (!last && (ioctl(fd, SIOCLOOKUPITER, &obj) == 0)) { + if (entry->ipfd_next == NULL) + last = 1; + if (bcmp((char *)zero, (char *)entry, sizeof(*zero)) == 0) + break; + (void) printdstlistnode(entry, bcopywrap, opts, fields); + printed++; + } + + (void) ioctl(fd, SIOCIPFDELTOK, &iter.ili_key); + free(entry); + free(zero); + + if (printed == 0) + putchar(';'); + + if ((opts & OPT_DEBUG) == 0) + PRINTF(" };\n"); + return d->ipld_next; +} diff --git a/contrib/ipfilter/lib/printdstlist.c b/contrib/ipfilter/lib/printdstlist.c new file mode 100644 index 000000000000..829a1d2e69ce --- /dev/null +++ b/contrib/ipfilter/lib/printdstlist.c @@ -0,0 +1,60 @@ +/* + * Copyright (C) 2012 by Darren Reed. + * + * See the IPFILTER.LICENCE file for details on licencing. + */ + +#include "ipf.h" + + +ippool_dst_t * +printdstlist(pp, copyfunc, name, opts, nodes, fields) + ippool_dst_t *pp; + copyfunc_t copyfunc; + char *name; + int opts; + ipf_dstnode_t *nodes; + wordtab_t *fields; +{ + ipf_dstnode_t *node; + ippool_dst_t dst; + + if ((*copyfunc)(pp, &dst, sizeof(dst))) + return NULL; + + if ((name != NULL) && strncmp(name, dst.ipld_name, FR_GROUPLEN)) + return dst.ipld_next; + + if (fields == NULL) + printdstlistdata(&dst, opts); + + if ((dst.ipld_flags & IPDST_DELETE) != 0) + PRINTF("# "); + if ((opts & OPT_DEBUG) == 0) + PRINTF("\t{"); + + if (nodes == NULL) { + putchar(';'); + } else { + for (node = nodes; node != NULL; ) { + ipf_dstnode_t *n; + + n = calloc(1, node->ipfd_size); + if (n == NULL) + break; + if ((*copyfunc)(node, n, node->ipfd_size)) { + free(n); + return NULL; + } + + node = printdstlistnode(n, bcopywrap, opts, fields); + + free(n); + } + } + + if ((opts & OPT_DEBUG) == 0) + PRINTF(" };\n"); + + return dst.ipld_next; +} diff --git a/contrib/ipfilter/lib/printdstlistdata.c b/contrib/ipfilter/lib/printdstlistdata.c new file mode 100644 index 000000000000..8b55afdb57c7 --- /dev/null +++ b/contrib/ipfilter/lib/printdstlistdata.c @@ -0,0 +1,47 @@ +/* + * Copyright (C) 2012 by Darren Reed. + * + * See the IPFILTER.LICENCE file for details on licencing. + */ + +#include "ipf.h" +#include + + +void +printdstlistdata(pool, opts) + ippool_dst_t *pool; + int opts; +{ + + if ((opts & OPT_DEBUG) == 0) { + if ((pool->ipld_flags & IPDST_DELETE) != 0) + PRINTF("# "); + PRINTF("pool "); + } else { + if ((pool->ipld_flags & IPDST_DELETE) != 0) + PRINTF("# "); + PRINTF("Name: %s\tRole: ", pool->ipld_name); + } + + printunit(pool->ipld_unit); + + if ((opts & OPT_DEBUG) == 0) { + PRINTF("/dstlist (name %s;", pool->ipld_name); + if (pool->ipld_policy != IPLDP_NONE) { + PRINTF(" policy "); + printdstlistpolicy(pool->ipld_policy); + putchar(';'); + } + PRINTF(")\n"); + } else { + putchar(' '); + + PRINTF("\tReferences: %d\n", pool->ipld_ref); + if ((pool->ipld_flags & IPDST_DELETE) != 0) + PRINTF("# "); + PRINTF("Policy: \n"); + printdstlistpolicy(pool->ipld_policy); + PRINTF("\n\tNodes Starting at %p\n", pool->ipld_dests); + } +} diff --git a/contrib/ipfilter/lib/printdstlistnode.c b/contrib/ipfilter/lib/printdstlistnode.c new file mode 100644 index 000000000000..898986d1c066 --- /dev/null +++ b/contrib/ipfilter/lib/printdstlistnode.c @@ -0,0 +1,78 @@ +/* + * Copyright (C) 2012 by Darren Reed. + * + * See the IPFILTER.LICENCE file for details on licencing. + */ + +#include "ipf.h" + + +ipf_dstnode_t * +printdstlistnode(inp, copyfunc, opts, fields) + ipf_dstnode_t *inp; + copyfunc_t copyfunc; + int opts; + wordtab_t *fields; +{ + ipf_dstnode_t node, *np; + int i; +#ifdef USE_INET6 + char buf[INET6_ADDRSTRLEN+1]; + const char *str; +#endif + + if ((*copyfunc)(inp, &node, sizeof(node))) + return NULL; + + np = calloc(1, node.ipfd_size); + if (np == NULL) + return node.ipfd_next; + if ((*copyfunc)(inp, np, node.ipfd_size)) + return NULL; + + if (fields != NULL) { + for (i = 0; fields[i].w_value != 0; i++) { + printpoolfield(np, IPLT_DSTLIST, i); + if (fields[i + 1].w_value != 0) + printf("\t"); + } + printf("\n"); + } else if ((opts & OPT_DEBUG) == 0) { + putchar(' '); + if (np->ipfd_dest.fd_name >= 0) + PRINTF("%s:", np->ipfd_names); + if (np->ipfd_dest.fd_addr.adf_family == AF_INET) { + printip(AF_INET, (u_32_t *)&np->ipfd_dest.fd_ip); + } else { +#ifdef USE_INET6 + str = inet_ntop(AF_INET6, &np->ipfd_dest.fd_ip6, + buf, sizeof(buf) - 1); + if (str != NULL) + PRINTF("%s", str); +#endif + } + putchar(';'); + } else { + PRINTF("Interface: [%s]/%d\n", np->ipfd_names, + np->ipfd_dest.fd_name); +#ifdef USE_INET6 + str = inet_ntop(np->ipfd_dest.fd_addr.adf_family, + &np->ipfd_dest.fd_ip6, buf, sizeof(buf) - 1); + if (str != NULL) { + PRINTF("\tAddress: %s\n", str); + } +#else + PRINTF("\tAddress: %s\n", inet_ntoa(np->ipfd_dest.fd_ip)); +#endif + PRINTF( +#ifdef USE_QUAD_T + "\t\tStates %d\tRef %d\tName [%s]\tUid %d\n", +#else + "\t\tStates %d\tRef %d\tName [%s]\tUid %d\n", +#endif + np->ipfd_states, np->ipfd_ref, + np->ipfd_names, np->ipfd_uid); + } + free(np); + return node.ipfd_next; +} diff --git a/contrib/ipfilter/lib/printdstlistpolicy.c b/contrib/ipfilter/lib/printdstlistpolicy.c new file mode 100644 index 000000000000..4873b95e207f --- /dev/null +++ b/contrib/ipfilter/lib/printdstlistpolicy.c @@ -0,0 +1,31 @@ +/* + * Copyright (C) 2012 by Darren Reed. + * + * See the IPFILTER.LICENCE file for details on licencing. + */ + +#include "ipf.h" + + +void +printdstlistpolicy(policy) + ippool_policy_t policy; +{ + switch (policy) + { + case IPLDP_NONE : + PRINTF("none"); + break; + case IPLDP_ROUNDROBIN : + PRINTF("round-robin"); + break; + case IPLDP_CONNECTION : + PRINTF("weighting connection"); + break; + case IPLDP_RANDOM : + PRINTF("random"); + break; + default : + break; + } +} diff --git a/contrib/ipfilter/lib/printfieldhdr.c b/contrib/ipfilter/lib/printfieldhdr.c new file mode 100644 index 000000000000..3cc22a655a63 --- /dev/null +++ b/contrib/ipfilter/lib/printfieldhdr.c @@ -0,0 +1,55 @@ +/* + * Copyright (C) 2012 by Darren Reed. + * + * See the IPFILTER.LICENCE file for details on licencing. + * + * $Id: printfieldhdr.c,v 1.5.2.3 2012/07/22 08:04:24 darren_r Exp $ + */ + +#include "ipf.h" +#include + + +void +printfieldhdr(words, field) + wordtab_t *words, *field; +{ + wordtab_t *w; + char *s, *t; + int i; + + if (field->w_value == -2) { + for (i = 0, w = words; w->w_word != NULL; ) { + if (w->w_value > 0) { + printfieldhdr(words, w); + w++; + if (w->w_value > 0) + putchar('\t'); + } else { + w++; + } + } + return; + } + + for (w = words; w->w_word != NULL; w++) { + if (w->w_value == field->w_value) { + if (w->w_word == field->w_word) { + s = strdup(w->w_word); + } else { + s = NULL; + } + + if ((w->w_word != field->w_word) || (s == NULL)) { + PRINTF("%s", field->w_word); + } else { + for (t = s; *t != '\0'; t++) { + if (ISALPHA(*t) && ISLOWER(*t)) + *t = TOUPPER(*t); + } + PRINTF("%s", s); + free(s); + } + } + } +} diff --git a/contrib/ipfilter/lib/printfr.c b/contrib/ipfilter/lib/printfr.c index 587d8cb01a48..9883df48f8f4 100644 --- a/contrib/ipfilter/lib/printfr.c +++ b/contrib/ipfilter/lib/printfr.c @@ -1,161 +1,88 @@ /* $FreeBSD$ */ /* - * Copyright (C) 2000-2006 by Darren Reed. + * Copyright (C) 2012 by Darren Reed. * * See the IPFILTER.LICENCE file for details on licencing. * - * $Id: printfr.c,v 1.43.2.18 2007/05/07 06:55:38 darrenr Exp $ + * $Id$ */ #include "ipf.h" -static void printaddr(int, int, char *, u_32_t *, u_32_t *); - -static void printaddr(v, type, ifname, addr, mask) -int v, type; -char *ifname; -u_32_t *addr, *mask; -{ - char *suffix; - - switch (type) - { - case FRI_BROADCAST : - suffix = "bcast"; - break; - - case FRI_DYNAMIC : - printf("%s", ifname); - printmask(mask); - suffix = NULL; - break; - - case FRI_NETWORK : - suffix = "net"; - break; - - case FRI_NETMASKED : - suffix = "netmasked"; - break; - - case FRI_PEERADDR : - suffix = "peer"; - break; - - case FRI_LOOKUP : - suffix = NULL; - printlookup((i6addr_t *)addr, (i6addr_t *)mask); - break; - - case FRI_NORMAL : - printhostmask(v, addr, mask); - suffix = NULL; - break; - default : - printf("<%d>", type); - printmask(mask); - suffix = NULL; - break; - } - - if (suffix != NULL) { - printf("%s/%s", ifname, suffix); - } -} - - -void printlookup(addr, mask) -i6addr_t *addr, *mask; -{ - switch (addr->iplookuptype) - { - case IPLT_POOL : - printf("pool/"); - break; - case IPLT_HASH : - printf("hash/"); - break; - default : - printf("lookup(%x)=", addr->iplookuptype); - break; - } - - printf("%u", addr->iplookupnum); - if (mask->iplookupptr == NULL) - printf("(!)"); -} - /* * print the filter structure in a useful way */ -void printfr(fp, iocfunc) -struct frentry *fp; -ioctlfunc_t iocfunc; +void +printfr(fp, iocfunc) + struct frentry *fp; + ioctlfunc_t iocfunc; { struct protoent *p; u_short sec[2]; u_32_t type; - u_char *t; + int pr, af; char *s; - int pr; + int hash; pr = -2; type = fp->fr_type & ~FR_T_BUILTIN; if ((fp->fr_type & FR_T_BUILTIN) != 0) - printf("# Builtin: "); + PRINTF("# Builtin: "); if (fp->fr_collect != 0) - printf("%u ", fp->fr_collect); + PRINTF("%u ", fp->fr_collect); if (fp->fr_type == FR_T_CALLFUNC) { ; } else if (fp->fr_func != NULL) { - printf("call"); + PRINTF("call"); if ((fp->fr_flags & FR_CALLNOW) != 0) - printf(" now"); + PRINTF(" now"); s = kvatoname(fp->fr_func, iocfunc); - printf(" %s/%u", s ? s : "?", fp->fr_arg); + PRINTF(" %s/%u", s ? s : "?", fp->fr_arg); } else if (FR_ISPASS(fp->fr_flags)) - printf("pass"); + PRINTF("pass"); else if (FR_ISBLOCK(fp->fr_flags)) { - printf("block"); + PRINTF("block"); } else if ((fp->fr_flags & FR_LOGMASK) == FR_LOG) { printlog(fp); } else if (FR_ISACCOUNT(fp->fr_flags)) - printf("count"); + PRINTF("count"); else if (FR_ISAUTH(fp->fr_flags)) - printf("auth"); + PRINTF("auth"); else if (FR_ISPREAUTH(fp->fr_flags)) - printf("preauth"); + PRINTF("preauth"); else if (FR_ISNOMATCH(fp->fr_flags)) - printf("nomatch"); + PRINTF("nomatch"); + else if (FR_ISDECAPS(fp->fr_flags)) + PRINTF("decapsulate"); else if (FR_ISSKIP(fp->fr_flags)) - printf("skip %u", fp->fr_arg); + PRINTF("skip %u", fp->fr_arg); else { - printf("%x", fp->fr_flags); + PRINTF("%x", fp->fr_flags); } if (fp->fr_flags & FR_RETICMP) { if ((fp->fr_flags & FR_RETMASK) == FR_FAKEICMP) - printf(" return-icmp-as-dest"); + PRINTF(" return-icmp-as-dest"); else if ((fp->fr_flags & FR_RETMASK) == FR_RETICMP) - printf(" return-icmp"); + PRINTF(" return-icmp"); if (fp->fr_icode) { if (fp->fr_icode <= MAX_ICMPCODE) - printf("(%s)", + PRINTF("(%s)", icmpcodes[(int)fp->fr_icode]); else - printf("(%d)", fp->fr_icode); + PRINTF("(%d)", fp->fr_icode); } } else if ((fp->fr_flags & FR_RETMASK) == FR_RETRST) - printf(" return-rst"); + PRINTF(" return-rst"); if (fp->fr_flags & FR_OUTQUE) - printf(" out "); - else - printf(" in "); + PRINTF(" out "); + else if (fp->fr_flags & FR_INQUE) + PRINTF(" in "); if (((fp->fr_flags & FR_LOGB) == FR_LOGB) || ((fp->fr_flags & FR_LOGP) == FR_LOGP)) { @@ -164,126 +91,153 @@ ioctlfunc_t iocfunc; } if (fp->fr_flags & FR_QUICK) - printf("quick "); + PRINTF("quick "); - if (*fp->fr_ifname) { - printifname("on ", fp->fr_ifname, fp->fr_ifa); - if (*fp->fr_ifnames[1] && strcmp(fp->fr_ifnames[1], "*")) - printifname(",", fp->fr_ifnames[1], fp->fr_ifas[1]); + if (fp->fr_ifnames[0] != -1) { + printifname("on ", fp->fr_names + fp->fr_ifnames[0], + fp->fr_ifa); + if (fp->fr_ifnames[1] != -1 && + strcmp(fp->fr_names + fp->fr_ifnames[1], "*")) + printifname(",", fp->fr_names + fp->fr_ifnames[1], + fp->fr_ifas[1]); putchar(' '); } - if (*fp->fr_dif.fd_ifname || (fp->fr_flags & FR_DUP)) - print_toif("dup-to", &fp->fr_dif); - if (*fp->fr_tif.fd_ifname) - print_toif("to", &fp->fr_tif); - if (*fp->fr_rif.fd_ifname) - print_toif("reply-to", &fp->fr_rif); + if (fp->fr_tif.fd_name != -1) + print_toif(fp->fr_family, "to", fp->fr_names, &fp->fr_tif); + if (fp->fr_dif.fd_name != -1) + print_toif(fp->fr_family, "dup-to", fp->fr_names, + &fp->fr_dif); + if (fp->fr_rif.fd_name != -1) + print_toif(fp->fr_family, "reply-to", fp->fr_names, + &fp->fr_rif); if (fp->fr_flags & FR_FASTROUTE) - printf("fastroute "); + PRINTF("fastroute "); - if ((*fp->fr_ifnames[2] && strcmp(fp->fr_ifnames[2], "*")) || - (*fp->fr_ifnames[3] && strcmp(fp->fr_ifnames[3], "*"))) { + if ((fp->fr_ifnames[2] != -1 && + strcmp(fp->fr_names + fp->fr_ifnames[2], "*")) || + (fp->fr_ifnames[3] != -1 && + strcmp(fp->fr_names + fp->fr_ifnames[3], "*"))) { if (fp->fr_flags & FR_OUTQUE) - printf("in-via "); + PRINTF("in-via "); else - printf("out-via "); + PRINTF("out-via "); - if (*fp->fr_ifnames[2]) { - printifname("", fp->fr_ifnames[2], + if (fp->fr_ifnames[2] != -1) { + printifname("", fp->fr_names + fp->fr_ifnames[2], fp->fr_ifas[2]); - if (*fp->fr_ifnames[3]) { - printifname(",", fp->fr_ifnames[3], + if (fp->fr_ifnames[3] != -1) { + printifname(",", + fp->fr_names + fp->fr_ifnames[3], fp->fr_ifas[3]); } putchar(' '); } } + if (fp->fr_family == AF_INET) { + PRINTF("inet "); + af = AF_INET; +#ifdef USE_INET6 + } else if (fp->fr_family == AF_INET6) { + PRINTF("inet6 "); + af = AF_INET6; +#endif + } else { + af = -1; + } + if (type == FR_T_IPF) { if (fp->fr_mip.fi_tos) - printf("tos %#x ", fp->fr_tos); + PRINTF("tos %#x ", fp->fr_tos); if (fp->fr_mip.fi_ttl) - printf("ttl %d ", fp->fr_ttl); + PRINTF("ttl %d ", fp->fr_ttl); if (fp->fr_flx & FI_TCPUDP) { - printf("proto tcp/udp "); + PRINTF("proto tcp/udp "); pr = -1; } else if (fp->fr_mip.fi_p) { pr = fp->fr_ip.fi_p; p = getprotobynumber(pr); - printf("proto "); + PRINTF("proto "); printproto(p, pr, NULL); putchar(' '); } } - if (type == FR_T_NONE) { - printf("all"); - } else if (type == FR_T_IPF) { - printf("from %s", fp->fr_flags & FR_NOTSRCIP ? "!" : ""); - printaddr(fp->fr_v, fp->fr_satype, fp->fr_ifname, + switch (type) + { + case FR_T_NONE : + PRINTF("all"); + break; + + case FR_T_IPF : + PRINTF("from %s", fp->fr_flags & FR_NOTSRCIP ? "!" : ""); + printaddr(af, fp->fr_satype, fp->fr_names, fp->fr_ifnames[0], &fp->fr_src.s_addr, &fp->fr_smsk.s_addr); if (fp->fr_scmp) printportcmp(pr, &fp->fr_tuc.ftu_src); - printf(" to %s", fp->fr_flags & FR_NOTDSTIP ? "!" : ""); - printaddr(fp->fr_v, fp->fr_datype, fp->fr_ifname, + PRINTF(" to %s", fp->fr_flags & FR_NOTDSTIP ? "!" : ""); + printaddr(af, fp->fr_datype, fp->fr_names, fp->fr_ifnames[0], &fp->fr_dst.s_addr, &fp->fr_dmsk.s_addr); if (fp->fr_dcmp) printportcmp(pr, &fp->fr_tuc.ftu_dst); - if (fp->fr_proto == IPPROTO_ICMP && fp->fr_icmpm) { + if (((fp->fr_proto == IPPROTO_ICMP) || + (fp->fr_proto == IPPROTO_ICMPV6)) && fp->fr_icmpm) { int type = fp->fr_icmp, code; + char *name; type = ntohs(fp->fr_icmp); code = type & 0xff; type /= 256; - if (type < (sizeof(icmptypes) / sizeof(char *) - 1) && - icmptypes[type]) - printf(" icmp-type %s", icmptypes[type]); + name = icmptypename(fp->fr_family, type); + if (name == NULL) + PRINTF(" icmp-type %d", type); else - printf(" icmp-type %d", type); + PRINTF(" icmp-type %s", name); if (ntohs(fp->fr_icmpm) & 0xff) - printf(" code %d", code); + PRINTF(" code %d", code); } if ((fp->fr_proto == IPPROTO_TCP) && (fp->fr_tcpf || fp->fr_tcpfm)) { - printf(" flags "); - if (fp->fr_tcpf & ~TCPF_ALL) - printf("0x%x", fp->fr_tcpf); - else - 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_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); - } + PRINTF(" flags "); + printtcpflags(fp->fr_tcpf, fp->fr_tcpfm); } - } else if (type == FR_T_BPFOPC) { + break; + + case FR_T_BPFOPC : + { fakebpf_t *fb; int i; - printf("bpf-v%d { \"", fp->fr_v); + PRINTF("bpf-v%d { \"", fp->fr_family); i = fp->fr_dsize / sizeof(*fb); for (fb = fp->fr_data, s = ""; i; i--, fb++, s = " ") - printf("%s%#x %#x %#x %#x", s, fb->fb_c, fb->fb_t, + PRINTF("%s%#x %#x %#x %#x", s, fb->fb_c, fb->fb_t, fb->fb_f, fb->fb_k); - printf("\" }"); - } else if (type == FR_T_COMPIPF) { - ; - } else if (type == FR_T_CALLFUNC) { - printf("call function at %p", fp->fr_data); - } else { - printf("[unknown filter type %#x]", fp->fr_type); + PRINTF("\" }"); + break; + } + + case FR_T_COMPIPF : + break; + + case FR_T_CALLFUNC : + PRINTF("call function at %p", fp->fr_data); + break; + + case FR_T_IPFEXPR : + PRINTF("exp { \""); + printipfexpr(fp->fr_data); + PRINTF("\" } "); + break; + + default : + PRINTF("[unknown filter type %#x]", fp->fr_type); + break; } if ((type == FR_T_IPF) && @@ -292,12 +246,12 @@ ioctlfunc_t iocfunc; fp->fr_secbits || fp->fr_secmask)) { char *comma = " "; - printf(" with"); + PRINTF(" with"); if (fp->fr_optbits || fp->fr_optmask || fp->fr_secbits || fp->fr_secmask) { sec[0] = fp->fr_secmask; sec[1] = fp->fr_secbits; - if (fp->fr_v == 4) + if (fp->fr_family == AF_INET) optprint(sec, fp->fr_optmask, fp->fr_optbits); #ifdef USE_INET6 else @@ -307,175 +261,213 @@ ioctlfunc_t iocfunc; } else if (fp->fr_mflx & FI_OPTIONS) { fputs(comma, stdout); if (!(fp->fr_flx & FI_OPTIONS)) - printf("not "); - printf("ipopts"); + PRINTF("not "); + PRINTF("ipopts"); comma = ","; } if (fp->fr_mflx & FI_SHORT) { fputs(comma, stdout); if (!(fp->fr_flx & FI_SHORT)) - printf("not "); - printf("short"); + PRINTF("not "); + PRINTF("short"); comma = ","; } if (fp->fr_mflx & FI_FRAG) { fputs(comma, stdout); if (!(fp->fr_flx & FI_FRAG)) - printf("not "); - printf("frag"); + PRINTF("not "); + PRINTF("frag"); comma = ","; } if (fp->fr_mflx & FI_FRAGBODY) { fputs(comma, stdout); if (!(fp->fr_flx & FI_FRAGBODY)) - printf("not "); - printf("frag-body"); + PRINTF("not "); + PRINTF("frag-body"); comma = ","; } if (fp->fr_mflx & FI_NATED) { fputs(comma, stdout); if (!(fp->fr_flx & FI_NATED)) - printf("not "); - printf("nat"); + PRINTF("not "); + PRINTF("nat"); comma = ","; } if (fp->fr_mflx & FI_LOWTTL) { fputs(comma, stdout); if (!(fp->fr_flx & FI_LOWTTL)) - printf("not "); - printf("lowttl"); + PRINTF("not "); + PRINTF("lowttl"); comma = ","; } if (fp->fr_mflx & FI_BAD) { fputs(comma, stdout); if (!(fp->fr_flx & FI_BAD)) - printf("not "); - printf("bad"); + PRINTF("not "); + PRINTF("bad"); comma = ","; } if (fp->fr_mflx & FI_BADSRC) { fputs(comma, stdout); if (!(fp->fr_flx & FI_BADSRC)) - printf("not "); - printf("bad-src"); + PRINTF("not "); + PRINTF("bad-src"); comma = ","; } if (fp->fr_mflx & FI_BADNAT) { fputs(comma, stdout); if (!(fp->fr_flx & FI_BADNAT)) - printf("not "); - printf("bad-nat"); + PRINTF("not "); + PRINTF("bad-nat"); comma = ","; } if (fp->fr_mflx & FI_OOW) { fputs(comma, stdout); if (!(fp->fr_flx & FI_OOW)) - printf("not "); - printf("oow"); + PRINTF("not "); + PRINTF("oow"); comma = ","; } if (fp->fr_mflx & FI_MBCAST) { fputs(comma, stdout); if (!(fp->fr_flx & FI_MBCAST)) - printf("not "); - printf("mbcast"); + PRINTF("not "); + PRINTF("mbcast"); comma = ","; } if (fp->fr_mflx & FI_BROADCAST) { fputs(comma, stdout); if (!(fp->fr_flx & FI_BROADCAST)) - printf("not "); - printf("bcast"); + PRINTF("not "); + PRINTF("bcast"); comma = ","; } if (fp->fr_mflx & FI_MULTICAST) { fputs(comma, stdout); if (!(fp->fr_flx & FI_MULTICAST)) - printf("not "); - printf("mcast"); + PRINTF("not "); + PRINTF("mcast"); comma = ","; } if (fp->fr_mflx & FI_STATE) { fputs(comma, stdout); if (!(fp->fr_flx & FI_STATE)) - printf("not "); - printf("state"); + PRINTF("not "); + PRINTF("state"); + comma = ","; + } + if (fp->fr_mflx & FI_V6EXTHDR) { + fputs(comma, stdout); + if (!(fp->fr_flx & FI_V6EXTHDR)) + PRINTF("not "); + PRINTF("v6hdrs"); comma = ","; } } if (fp->fr_flags & FR_KEEPSTATE) { - printf(" keep state"); - if ((fp->fr_flags & (FR_STSTRICT|FR_NEWISN|FR_NOICMPERR|FR_STATESYNC)) || - (fp->fr_statemax != 0) || (fp->fr_age[0] != 0)) { + host_track_t *src = &fp->fr_srctrack; + PRINTF(" keep state"); + if ((fp->fr_flags & (FR_STSTRICT|FR_NEWISN| + FR_NOICMPERR|FR_STATESYNC)) || + (fp->fr_statemax != 0) || (fp->fr_age[0] != 0) || + (src->ht_max_nodes != 0)) { char *comma = ""; - printf(" ("); + PRINTF(" ("); if (fp->fr_statemax != 0) { - printf("limit %u", fp->fr_statemax); + PRINTF("limit %u", fp->fr_statemax); + comma = ","; + } + if (src->ht_max_nodes != 0) { + PRINTF("%smax-nodes %d", comma, + src->ht_max_nodes); + if (src->ht_max_per_node) + PRINTF(", max-per-src %d/%d", + src->ht_max_per_node, + src->ht_netmask); comma = ","; } if (fp->fr_flags & FR_STSTRICT) { - printf("%sstrict", comma); + PRINTF("%sstrict", comma); + comma = ","; + } + if (fp->fr_flags & FR_STLOOSE) { + PRINTF("%sloose", comma); comma = ","; } if (fp->fr_flags & FR_NEWISN) { - printf("%snewisn", comma); + PRINTF("%snewisn", comma); comma = ","; } if (fp->fr_flags & FR_NOICMPERR) { - printf("%sno-icmp-err", comma); + PRINTF("%sno-icmp-err", comma); comma = ","; } if (fp->fr_flags & FR_STATESYNC) { - printf("%ssync", comma); + PRINTF("%ssync", comma); comma = ","; } if (fp->fr_age[0] || fp->fr_age[1]) - printf("%sage %d/%d", comma, fp->fr_age[0], + PRINTF("%sage %d/%d", comma, fp->fr_age[0], fp->fr_age[1]); - printf(")"); + PRINTF(")"); } } if (fp->fr_flags & FR_KEEPFRAG) { - printf(" keep frags"); + PRINTF(" keep frags"); if (fp->fr_flags & (FR_FRSTRICT)) { - printf(" ("); + PRINTF(" ("); if (fp->fr_flags & FR_FRSTRICT) - printf("strict"); - printf(")"); - + PRINTF("strict"); + PRINTF(")"); + } } if (fp->fr_isc != (struct ipscan *)-1) { - if (fp->fr_isctag[0]) - printf(" scan %s", fp->fr_isctag); + if (fp->fr_isctag != -1) + PRINTF(" scan %s", fp->fr_isctag + fp->fr_names); else - printf(" scan *"); + PRINTF(" scan *"); } - if (*fp->fr_grhead != '\0') - printf(" head %s", fp->fr_grhead); - if (*fp->fr_group != '\0') - printf(" group %s", fp->fr_group); + if (fp->fr_grhead != -1) + PRINTF(" head %s", fp->fr_names + fp->fr_grhead); + if (fp->fr_group != -1) + PRINTF(" group %s", fp->fr_names + fp->fr_group); if (fp->fr_logtag != FR_NOLOGTAG || *fp->fr_nattag.ipt_tag) { char *s = ""; - printf(" set-tag("); + PRINTF(" set-tag("); if (fp->fr_logtag != FR_NOLOGTAG) { - printf("log=%u", fp->fr_logtag); + PRINTF("log=%u", fp->fr_logtag); s = ", "; } if (*fp->fr_nattag.ipt_tag) { - printf("%snat=%-.*s", s, IPFTAG_LEN, + PRINTF("%snat=%-.*s", s, IPFTAG_LEN, fp->fr_nattag.ipt_tag); } - printf(")"); + PRINTF(")"); } if (fp->fr_pps) - printf(" pps %d", fp->fr_pps); + PRINTF(" pps %d", fp->fr_pps); + if (fp->fr_comment != -1) + PRINTF(" comment \"%s\"", fp->fr_names + fp->fr_comment); + + hash = 0; if ((fp->fr_flags & FR_KEEPSTATE) && (opts & OPT_VERBOSE)) { - printf(" # count %d", fp->fr_statecnt); + PRINTF(" # count %d", fp->fr_statecnt); + if (fp->fr_die != 0) + PRINTF(" rule-ttl %u", fp->fr_die); + hash = 1; + } else if (fp->fr_die != 0) { + PRINTF(" # rule-ttl %u", fp->fr_die); + hash = 1; + } + if (opts & OPT_DEBUG) { + if (hash == 0) + putchar('#'); + PRINTF(" ref %d", fp->fr_ref); } (void)putchar('\n'); } diff --git a/contrib/ipfilter/lib/printfraginfo.c b/contrib/ipfilter/lib/printfraginfo.c index d9317e87480d..dd2966fc05b5 100644 --- a/contrib/ipfilter/lib/printfraginfo.c +++ b/contrib/ipfilter/lib/printfraginfo.c @@ -1,30 +1,42 @@ /* $FreeBSD$ */ /* - * Copyright (C) 2004-2005 by Darren Reed. + * Copyright (C) 2012 by Darren Reed. * * See the IPFILTER.LICENCE file for details on licencing. * - * $Id: printfraginfo.c,v 1.1.2.5 2006/12/25 15:10:37 darrenr Exp $ + * $Id$ */ #include "ipf.h" #include "kmem.h" -void printfraginfo(prefix, ifr) -char *prefix; -struct ipfr *ifr; + +void +printfraginfo(prefix, ifr) + char *prefix; + struct ipfr *ifr; { frentry_t fr; + int family; + PRINTF("%s", prefix); + if (ifr->ipfr_v == 6) { + PRINTF("inet6"); + family = AF_INET6; + } else { + PRINTF("inet"); + family = AF_INET; + } fr.fr_flags = 0xffffffff; - printf("%s%s -> ", prefix, hostname(4, &ifr->ipfr_src)); + PRINTF(" %s -> ", hostname(family, &ifr->ipfr_src)); /* if (kmemcpy((char *)&fr, (u_long)ifr->ipfr_rule, sizeof(fr)) == -1) return; -*/ - printf("%s id %d ttl %ld pr %d seen0 %d ref %d tos %#02x\n", - hostname(4, &ifr->ipfr_dst), ifr->ipfr_id, ifr->ipfr_ttl, - ifr->ipfr_p, ifr->ipfr_seen0, ifr->ipfr_ref, ifr->ipfr_tos); + */ + PRINTF("%s id %x ttl %lu pr %d pkts %u bytes %u seen0 %d ref %d\n", + hostname(family, &ifr->ipfr_dst), ifr->ipfr_id, + ifr->ipfr_ttl, ifr->ipfr_p, ifr->ipfr_pkts, ifr->ipfr_bytes, + ifr->ipfr_seen0, ifr->ipfr_ref); } diff --git a/contrib/ipfilter/lib/printhash.c b/contrib/ipfilter/lib/printhash.c index 975b60eabcd5..37796620fc1d 100644 --- a/contrib/ipfilter/lib/printhash.c +++ b/contrib/ipfilter/lib/printhash.c @@ -1,22 +1,21 @@ /* $FreeBSD$ */ /* - * Copyright (C) 2002-2005 by Darren Reed. + * Copyright (C) 2012 by Darren Reed. * * See the IPFILTER.LICENCE file for details on licencing. */ #include "ipf.h" -#define PRINTF (void)printf -#define FPRINTF (void)fprintf - -iphtable_t *printhash(hp, copyfunc, name, opts) -iphtable_t *hp; -copyfunc_t copyfunc; -char *name; -int opts; +iphtable_t * +printhash(hp, copyfunc, name, opts, fields) + iphtable_t *hp; + copyfunc_t copyfunc; + char *name; + int opts; + wordtab_t *fields; { iphtent_t *ipep, **table; iphtable_t iph; @@ -29,7 +28,8 @@ int opts; if ((name != NULL) && strncmp(name, iph.iph_name, FR_GROUPLEN)) return iph.iph_next; - printhashdata(hp, opts); + if (fields == NULL) + printhashdata(hp, opts); if ((hp->iph_flags & IPHASH_DELETE) != 0) PRINTF("# "); @@ -43,7 +43,7 @@ int opts; return NULL; for (printed = 0, ipep = iph.iph_list; ipep != NULL; ) { - ipep = printhashnode(&iph, ipep, copyfunc, opts); + ipep = printhashnode(&iph, ipep, copyfunc, opts, fields); printed++; } if (printed == 0) diff --git a/contrib/ipfilter/lib/printhash_live.c b/contrib/ipfilter/lib/printhash_live.c index 1afe63228e48..53159b133023 100644 --- a/contrib/ipfilter/lib/printhash_live.c +++ b/contrib/ipfilter/lib/printhash_live.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002 by Darren Reed. + * Copyright (C) 2012 by Darren Reed. * * See the IPFILTER.LICENCE file for details on licencing. */ @@ -8,25 +8,25 @@ #include "ipf.h" #include "netinet/ipl.h" -#define PRINTF (void)printf -#define FPRINTF (void)fprintf - -iphtable_t *printhash_live(hp, fd, name, opts) -iphtable_t *hp; -int fd; -char *name; -int opts; +iphtable_t * +printhash_live(hp, fd, name, opts, fields) + iphtable_t *hp; + int fd; + char *name; + int opts; + wordtab_t *fields; { - iphtent_t entry, *top, *node; + iphtent_t entry, zero; ipflookupiter_t iter; - int printed, last; + int last, printed; ipfobj_t obj; if ((name != NULL) && strncmp(name, hp->iph_name, FR_GROUPLEN)) return hp->iph_next; - printhashdata(hp, opts); + if (fields == NULL) + printhashdata(hp, opts); if ((hp->iph_flags & IPHASH_DELETE) != 0) PRINTF("# "); @@ -47,26 +47,19 @@ int opts; strncpy(iter.ili_name, hp->iph_name, FR_GROUPLEN); last = 0; - top = NULL; printed = 0; + bzero((char *)&zero, sizeof(zero)); while (!last && (ioctl(fd, SIOCLOOKUPITER, &obj) == 0)) { if (entry.ipe_next == NULL) last = 1; - entry.ipe_next = top; - top = malloc(sizeof(*top)); - if (top == NULL) + if (bcmp(&zero, &entry, sizeof(zero)) == 0) break; - bcopy(&entry, top, sizeof(entry)); - } - - while (top != NULL) { - node = top; - (void) printhashnode(hp, node, bcopywrap, opts); - top = node->ipe_next; - free(node); + (void) printhashnode(hp, &entry, bcopywrap, opts, fields); printed++; } + if (last == 0) + ipferror(fd, "walking hash nodes:"); if (printed == 0) putchar(';'); diff --git a/contrib/ipfilter/lib/printhashdata.c b/contrib/ipfilter/lib/printhashdata.c index d278c365a69f..ea2d41636e46 100644 --- a/contrib/ipfilter/lib/printhashdata.c +++ b/contrib/ipfilter/lib/printhashdata.c @@ -1,23 +1,22 @@ /* - * Copyright (C) 2002 by Darren Reed. + * Copyright (C) 2012 by Darren Reed. * * See the IPFILTER.LICENCE file for details on licencing. */ #include "ipf.h" - -#define PRINTF (void)printf -#define FPRINTF (void)fprintf +#include -void printhashdata(hp, opts) -iphtable_t *hp; -int opts; +void +printhashdata(hp, opts) + iphtable_t *hp; + int opts; { if ((opts & OPT_DEBUG) == 0) { if ((hp->iph_type & IPHASH_ANON) == IPHASH_ANON) - PRINTF("# 'anonymous' table\n"); + PRINTF("# 'anonymous' table refs %d\n", hp->iph_ref); if ((hp->iph_flags & IPHASH_DELETE) == IPHASH_DELETE) PRINTF("# "); switch (hp->iph_type & ~IPHASH_ANON) @@ -38,10 +37,10 @@ int opts; PRINTF("%#x", hp->iph_type); break; } - PRINTF(" role = "); + PRINTF(" role="); } else { PRINTF("Hash Table %s: %s", - isdigit(*hp->iph_name) ? "Number" : "Name", + ISDIGIT(*hp->iph_name) ? "Number" : "Name", hp->iph_name); if ((hp->iph_type & IPHASH_ANON) == IPHASH_ANON) PRINTF("(anon)"); @@ -49,33 +48,16 @@ int opts; PRINTF("Role: "); } - switch (hp->iph_unit) - { - case IPL_LOGNAT : - PRINTF("nat"); - break; - case IPL_LOGIPF : - PRINTF("ipf"); - break; - case IPL_LOGAUTH : - PRINTF("auth"); - break; - case IPL_LOGCOUNT : - PRINTF("count"); - break; - default : - PRINTF("#%d", hp->iph_unit); - break; - } + printunit(hp->iph_unit); if ((opts & OPT_DEBUG) == 0) { if ((hp->iph_type & ~IPHASH_ANON) == IPHASH_LOOKUP) - PRINTF(" type = hash"); - PRINTF(" %s = %s size = %lu", - isdigit(*hp->iph_name) ? "number" : "name", + PRINTF(" type=hash"); + PRINTF(" %s=%s size=%lu", + ISDIGIT(*hp->iph_name) ? "number" : "name", hp->iph_name, (u_long)hp->iph_size); if (hp->iph_seed != 0) - PRINTF(" seed = %lu", hp->iph_seed); + PRINTF(" seed=%lu", hp->iph_seed); putchar('\n'); } else { PRINTF(" Type: "); @@ -95,7 +77,7 @@ int opts; PRINTF("\t\tSize: %lu\tSeed: %lu", (u_long)hp->iph_size, hp->iph_seed); PRINTF("\tRef. Count: %d\tMasks: %#x\n", hp->iph_ref, - hp->iph_masks); + hp->iph_maskset[0]); } if ((opts & OPT_DEBUG) != 0) { @@ -103,8 +85,8 @@ int opts; int i; for (i = 0; i < 32; i++) { - if ((1 << i) & hp->iph_masks) { - ntomask(4, i, &m.s_addr); + if ((1 << i) & hp->iph_maskset[0]) { + ntomask(AF_INET, i, &m.s_addr); PRINTF("\t\tMask: %s\n", inet_ntoa(m)); } } diff --git a/contrib/ipfilter/lib/printhashnode.c b/contrib/ipfilter/lib/printhashnode.c index ed83c397b4c5..e245535cb1c4 100644 --- a/contrib/ipfilter/lib/printhashnode.c +++ b/contrib/ipfilter/lib/printhashnode.c @@ -1,47 +1,63 @@ /* $FreeBSD$ */ /* - * Copyright (C) 2002-2005 by Darren Reed. + * Copyright (C) 2012 by Darren Reed. * * See the IPFILTER.LICENCE file for details on licencing. */ #include "ipf.h" -#define PRINTF (void)printf -#define FPRINTF (void)fprintf -iphtent_t *printhashnode(iph, ipep, copyfunc, opts) -iphtable_t *iph; -iphtent_t *ipep; -copyfunc_t copyfunc; -int opts; +iphtent_t * +printhashnode(iph, ipep, copyfunc, opts, fields) + iphtable_t *iph; + iphtent_t *ipep; + copyfunc_t copyfunc; + int opts; + wordtab_t *fields; { iphtent_t ipe; + u_int hv; + int i; if ((*copyfunc)(ipep, &ipe, sizeof(ipe))) return NULL; - ipe.ipe_addr.in4_addr = htonl(ipe.ipe_addr.in4_addr); - ipe.ipe_mask.in4_addr = htonl(ipe.ipe_mask.in4_addr); + hv = IPE_V4_HASH_FN(ipe.ipe_addr.i6[0], ipe.ipe_mask.i6[0], + iph->iph_size); - if ((opts & OPT_DEBUG) != 0) { - PRINTF("\tAddress: %s", + if (fields != NULL) { + for (i = 0; fields[i].w_value != 0; i++) { + printpoolfield(&ipe, IPLT_HASH, i); + if (fields[i + 1].w_value != 0) + printf("\t"); + } + printf("\n"); + } else if ((opts & OPT_DEBUG) != 0) { + PRINTF("\t%d\tAddress: %s", hv, inet_ntoa(ipe.ipe_addr.in4)); - printmask((u_32_t *)&ipe.ipe_mask.in4_addr); + printmask(ipe.ipe_family, (u_32_t *)&ipe.ipe_mask.in4_addr); PRINTF("\tRef. Count: %d\tGroup: %s\n", ipe.ipe_ref, ipe.ipe_group); +#ifdef USE_QUAD_T + PRINTF("\tHits: %"PRIu64"\tBytes: %"PRIu64"\n", + ipe.ipe_hits, ipe.ipe_bytes); +#else + PRINTF("\tHits: %lu\tBytes: %lu\n", + ipe.ipe_hits, ipe.ipe_bytes); +#endif } else { putchar(' '); - printip((u_32_t *)&ipe.ipe_addr.in4_addr); - printmask((u_32_t *)&ipe.ipe_mask.in4_addr); + printip(ipe.ipe_family, (u_32_t *)&ipe.ipe_addr.in4_addr); + printmask(ipe.ipe_family, (u_32_t *)&ipe.ipe_mask.in4_addr); if (ipe.ipe_value != 0) { switch (iph->iph_type & ~IPHASH_ANON) { case IPHASH_GROUPMAP : if (strncmp(ipe.ipe_group, iph->iph_name, FR_GROUPLEN)) - PRINTF(", group = %s", ipe.ipe_group); + PRINTF(", group=%s", ipe.ipe_group); break; } } diff --git a/contrib/ipfilter/lib/printhost.c b/contrib/ipfilter/lib/printhost.c new file mode 100644 index 000000000000..eaf3fda45844 --- /dev/null +++ b/contrib/ipfilter/lib/printhost.c @@ -0,0 +1,35 @@ +/* + * Copyright (C) 2012 by Darren Reed. + * + * See the IPFILTER.LICENCE file for details on licencing. + * + * $Id: printhost.c,v 1.3.2.2 2012/07/22 08:04:24 darren_r Exp $ + */ + +#include "ipf.h" + + +void +printhost(family, addr) + int family; + u_32_t *addr; +{ +#ifdef USE_INET6 + char ipbuf[64]; +#else + struct in_addr ipa; +#endif + + if ((family == -1) || !*addr) + PRINTF("any"); + else { + void *ptr = addr; + +#ifdef USE_INET6 + PRINTF("%s", inet_ntop(family, ptr, ipbuf, sizeof(ipbuf))); +#else + ipa.s_addr = *addr; + PRINTF("%s", inet_ntoa(ipa)); +#endif + } +} diff --git a/contrib/ipfilter/lib/printhostmap.c b/contrib/ipfilter/lib/printhostmap.c index 0c9242f91eef..714bc416932b 100644 --- a/contrib/ipfilter/lib/printhostmap.c +++ b/contrib/ipfilter/lib/printhostmap.c @@ -1,22 +1,31 @@ /* $FreeBSD$ */ /* - * Copyright (C) 2002-2005 by Darren Reed. - * - * See the IPFILTER.LICENCE file for details on licencing. - * - * $Id: printhostmap.c,v 1.3.2.3 2006/09/30 21:42:07 darrenr Exp $ - */ + * Copyright (C) 2012 by Darren Reed. + * + * See the IPFILTER.LICENCE file for details on licencing. + * + * $Id$ + */ #include "ipf.h" -void printhostmap(hmp, hv) -hostmap_t *hmp; -u_int hv; +void +printhostmap(hmp, hv) + hostmap_t *hmp; + u_int hv; { - printf("%s,", inet_ntoa(hmp->hm_srcip)); - printf("%s -> ", inet_ntoa(hmp->hm_dstip)); - printf("%s ", inet_ntoa(hmp->hm_mapip)); - printf("(use = %d hv = %u)\n", hmp->hm_ref, hv); + printactiveaddress(hmp->hm_v, "%s", &hmp->hm_osrcip6, NULL); + putchar(','); + printactiveaddress(hmp->hm_v, "%s", &hmp->hm_odstip6, NULL); + PRINTF(" -> "); + printactiveaddress(hmp->hm_v, "%s", &hmp->hm_nsrcip6, NULL); + putchar(','); + printactiveaddress(hmp->hm_v, "%s", &hmp->hm_ndstip6, NULL); + putchar(' '); + PRINTF("(use = %d", hmp->hm_ref); + if (opts & OPT_VERBOSE) + PRINTF(" hv = %u", hv); + printf(")\n"); } diff --git a/contrib/ipfilter/lib/printhostmask.c b/contrib/ipfilter/lib/printhostmask.c index 44703c4c4636..10d90b2df96e 100644 --- a/contrib/ipfilter/lib/printhostmask.c +++ b/contrib/ipfilter/lib/printhostmask.c @@ -1,19 +1,20 @@ /* $FreeBSD$ */ /* - * Copyright (C) 2000-2005 by Darren Reed. + * Copyright (C) 2012 by Darren Reed. * * See the IPFILTER.LICENCE file for details on licencing. * - * $Id: printhostmask.c,v 1.8.4.1 2006/06/16 17:21:12 darrenr Exp $ + * $Id$ */ #include "ipf.h" -void printhostmask(v, addr, mask) -int v; -u_32_t *addr, *mask; +void +printhostmask(family, addr, mask) + int family; + u_32_t *addr, *mask; { #ifdef USE_INET6 char ipbuf[64]; @@ -21,26 +22,18 @@ u_32_t *addr, *mask; struct in_addr ipa; #endif - if (!*addr && !*mask) - printf("any"); + if ((family == -1) || ((!addr || !*addr) && (!mask || !*mask))) + PRINTF("any"); else { -#ifdef USE_INET6 void *ptr = addr; - int af; - if (v == 4) { - ptr = addr; - af = AF_INET; - } else if (v == 6) { - ptr = addr; - af = AF_INET6; - } else - af = 0; - printf("%s", inet_ntop(af, ptr, ipbuf, sizeof(ipbuf))); +#ifdef USE_INET6 + PRINTF("%s", inet_ntop(family, ptr, ipbuf, sizeof(ipbuf))); #else ipa.s_addr = *addr; - printf("%s", inet_ntoa(ipa)); + PRINTF("%s", inet_ntoa(ipa)); #endif - printmask(mask); + if (mask != NULL) + printmask(family, mask); } } diff --git a/contrib/ipfilter/lib/printifname.c b/contrib/ipfilter/lib/printifname.c index 2f7d912cf3e0..2e554d950aed 100644 --- a/contrib/ipfilter/lib/printifname.c +++ b/contrib/ipfilter/lib/printifname.c @@ -1,20 +1,22 @@ /* $FreeBSD$ */ /* - * Copyright (C) 2002 by Darren Reed. + * Copyright (C) 2012 by Darren Reed. * * See the IPFILTER.LICENCE file for details on licencing. * - * $Id: printifname.c,v 1.2.4.1 2006/06/16 17:21:12 darrenr Exp $ + * $Id$ */ #include "ipf.h" -void printifname(format, name, ifp) -char *format, *name; -void *ifp; + +void +printifname(format, name, ifp) + char *format, *name; + void *ifp; { - printf("%s%s", format, name); + PRINTF("%s%s", format, name); if ((ifp == NULL) && strcmp(name, "-") && strcmp(name, "*")) - printf("(!)"); + PRINTF("(!)"); } diff --git a/contrib/ipfilter/lib/printip.c b/contrib/ipfilter/lib/printip.c index 8c008afa9d24..6d414fe3fa41 100644 --- a/contrib/ipfilter/lib/printip.c +++ b/contrib/ipfilter/lib/printip.c @@ -1,24 +1,43 @@ /* $FreeBSD$ */ /* - * Copyright (C) 2002-2005 by Darren Reed. + * Copyright (C) 2012 by Darren Reed. * * See the IPFILTER.LICENCE file for details on licencing. * - * $Id: printip.c,v 1.3.4.1 2006/06/16 17:21:12 darrenr Exp $ + * $Id$ */ #include "ipf.h" -void printip(addr) -u_32_t *addr; +void +printip(family, addr) + int family; + u_32_t *addr; { struct in_addr ipa; - ipa.s_addr = *addr; - if (ntohl(ipa.s_addr) < 256) - printf("%lu", (u_long)ntohl(ipa.s_addr)); + if (family == AF_INET) { + ipa.s_addr = *addr; + if (ntohl(ipa.s_addr) < 256) + PRINTF("%lu", (u_long)ntohl(ipa.s_addr)); + else + PRINTF("%s", inet_ntoa(ipa)); + } +#ifdef AF_INET6 + else if (family == AF_INET6) { + char buf[INET6_ADDRSTRLEN + 1]; + const char *str; + + buf[0] = '\0'; + str = inet_ntop(AF_INET6, addr, buf, sizeof(buf) - 1); + if (str != NULL) + PRINTF("%s", str); + else + PRINTF("???"); + } +#endif else - printf("%s", inet_ntoa(ipa)); + PRINTF("?(%d)?", family); } diff --git a/contrib/ipfilter/lib/printipfexpr.c b/contrib/ipfilter/lib/printipfexpr.c new file mode 100644 index 000000000000..64c2f1c1a7e8 --- /dev/null +++ b/contrib/ipfilter/lib/printipfexpr.c @@ -0,0 +1,197 @@ +#include "ipf.h" + +static void printport __P((int *)); +static void printhosts __P((int *)); +static void printsingle __P((int *)); +static void printhostsv6 __P((int *)); + +void +printipfexpr(array) + int *array; +{ + int i, nelems, j, not; + ipfexp_t *ipfe; + + nelems = array[0]; + + for (i = 1; i < nelems; ) { + ipfe = (ipfexp_t *)(array + i); + if (ipfe->ipfe_cmd == IPF_EXP_END) + break; + + not = ipfe->ipfe_not; + + switch (ipfe->ipfe_cmd) + { + case IPF_EXP_IP_ADDR : + PRINTF("ip.addr %s= ", not ? "!" : ""); + printhosts(array + i); + break; + + case IPF_EXP_IP_PR : + PRINTF("ip.p %s= ", not ? "!" : ""); + printsingle(array + i); + break; + + case IPF_EXP_IP_SRCADDR : + PRINTF("ip.src %s= ", not ? "!" : ""); + printhosts(array + i); + break; + + case IPF_EXP_IP_DSTADDR : + PRINTF("ip.dst %s= ", not ? "!" : ""); + printhosts(array + i); + break; + + case IPF_EXP_TCP_PORT : + PRINTF("tcp.port %s= ", not ? "!" : ""); + printport(array + i); + break; + + case IPF_EXP_TCP_DPORT : + PRINTF("tcp.dport %s= ", not ? "!" : ""); + printport(array + i); + break; + + case IPF_EXP_TCP_SPORT : + PRINTF("tcp.sport %s= ", not ? "!" : ""); + printport(array + i); + break; + + case IPF_EXP_TCP_FLAGS : + PRINTF("tcp.flags %s= ", not ? "!" : ""); + + for (j = 0; j < ipfe->ipfe_narg; ) { + printtcpflags(array[i + 4], array[i + 5]); + j += 2; + if (j < array[4]) + putchar(','); + } + break; + + case IPF_EXP_UDP_PORT : + PRINTF("udp.port %s= ", not ? "!" : ""); + printport(array + i); + break; + + case IPF_EXP_UDP_DPORT : + PRINTF("udp.dport %s= ", not ? "!" : ""); + printport(array + i); + break; + + case IPF_EXP_UDP_SPORT : + PRINTF("udp.sport %s= ", not ? "!" : ""); + printport(array + i); + break; + + case IPF_EXP_IDLE_GT : + PRINTF("idle-gt %s= ", not ? "!" : ""); + printsingle(array + i); + break; + + case IPF_EXP_TCP_STATE : + PRINTF("tcp-state %s= ", not ? "!" : ""); + printsingle(array + i); + break; + +#ifdef USE_INET6 + case IPF_EXP_IP6_ADDR : + PRINTF("ip6.addr %s= ", not ? "!" : ""); + printhostsv6(array + i); + break; + + case IPF_EXP_IP6_SRCADDR : + PRINTF("ip6.src %s= ", not ? "!" : ""); + printhostsv6(array + i); + break; + + case IPF_EXP_IP6_DSTADDR : + PRINTF("ip6.dst %s= ", not ? "!" : ""); + printhostsv6(array + i); + break; +#endif + + case IPF_EXP_END : + break; + + default : + PRINTF("#%#x,len=%d;", + ipfe->ipfe_cmd, ipfe->ipfe_narg); + } + + if (array[i] != IPF_EXP_END) + putchar(';'); + + i += ipfe->ipfe_size; + if (array[i] != IPF_EXP_END) + putchar(' '); + } +} + + +static void +printsingle(array) + int *array; +{ + ipfexp_t *ipfe = (ipfexp_t *)array; + int i; + + for (i = 0; i < ipfe->ipfe_narg; ) { + PRINTF("%d", array[i + 4]); + i++; + if (i < ipfe->ipfe_narg) + putchar(','); + } +} + + +static void +printport(array) + int *array; +{ + ipfexp_t *ipfe = (ipfexp_t *)array; + int i; + + for (i = 0; i < ipfe->ipfe_narg; ) { + PRINTF("%d", ntohs(array[i + 4])); + i++; + if (i < ipfe->ipfe_narg) + putchar(','); + } +} + + +static void +printhosts(array) + int *array; +{ + ipfexp_t *ipfe = (ipfexp_t *)array; + int i, j; + + for (i = 0, j = 0; i < ipfe->ipfe_narg; j++) { + printhostmask(AF_INET, (u_32_t *)ipfe->ipfe_arg0 + j * 2, + (u_32_t *)ipfe->ipfe_arg0 + j * 2 + 1); + i += 2; + if (i < ipfe->ipfe_narg) + putchar(','); + } +} + + +#ifdef USE_INET6 +static void +printhostsv6(array) + int *array; +{ + ipfexp_t *ipfe = (ipfexp_t *)array; + int i, j; + + for (i = 4, j= 0; i < ipfe->ipfe_size; j++) { + printhostmask(AF_INET6, (u_32_t *)ipfe->ipfe_arg0 + j * 8, + (u_32_t *)ipfe->ipfe_arg0 + j * 8 + 4); + i += 8; + if (i < ipfe->ipfe_size) + putchar(','); + } +} +#endif diff --git a/contrib/ipfilter/lib/printiphdr.c b/contrib/ipfilter/lib/printiphdr.c new file mode 100644 index 000000000000..fdf0f75f9079 --- /dev/null +++ b/contrib/ipfilter/lib/printiphdr.c @@ -0,0 +1,20 @@ +/* + * Copyright (C) by Darren Reed. + * + * See the IPFILTER.LICENCE file for details on licencing. + * + * $Id: printiphdr.c,v 1.1 2009/03/01 12:48:32 darren_r Exp $ + */ + +#include "ipf.h" + + +void +printiphdr(ip) + ip_t *ip; +{ + PRINTF("ip(v=%d,hl=%d,len=%d,tos=%#x,off=%#x,sum=%#x,src=%#x,dst=%#x", + ip->ip_v, ip->ip_hl, ntohs(ip->ip_len), ip->ip_tos, + ntohs(ip->ip_off), ntohs(ip->ip_sum), ntohl(ip->ip_src.s_addr), + ntohl(ip->ip_dst.s_addr)); +} diff --git a/contrib/ipfilter/lib/printlog.c b/contrib/ipfilter/lib/printlog.c index 82c0400759eb..c5278cdfdd6a 100644 --- a/contrib/ipfilter/lib/printlog.c +++ b/contrib/ipfilter/lib/printlog.c @@ -1,11 +1,11 @@ /* $FreeBSD$ */ /* - * Copyright (C) 2000-2005 by Darren Reed. + * Copyright (C) 2012 by Darren Reed. * * See the IPFILTER.LICENCE file for details on licencing. * - * $Id: printlog.c,v 1.6.4.3 2006/06/16 17:21:12 darrenr Exp $ + * $Id$ */ #include "ipf.h" @@ -13,26 +13,27 @@ #include -void printlog(fp) -frentry_t *fp; +void +printlog(fp) + frentry_t *fp; { char *s, *u; - printf("log"); + PRINTF("log"); if (fp->fr_flags & FR_LOGBODY) - printf(" body"); + PRINTF(" body"); if (fp->fr_flags & FR_LOGFIRST) - printf(" first"); + PRINTF(" first"); if (fp->fr_flags & FR_LOGORBLOCK) - printf(" or-block"); + PRINTF(" or-block"); if (fp->fr_loglevel != 0xffff) { - printf(" level "); + PRINTF(" level "); s = fac_toname(fp->fr_loglevel); if (s == NULL || *s == '\0') s = "!!!"; u = pri_toname(fp->fr_loglevel); if (u == NULL || *u == '\0') u = "!!!"; - printf("%s.%s", s, u); + PRINTF("%s.%s", s, u); } } diff --git a/contrib/ipfilter/lib/printlookup.c b/contrib/ipfilter/lib/printlookup.c new file mode 100644 index 000000000000..51f8d6e3b2df --- /dev/null +++ b/contrib/ipfilter/lib/printlookup.c @@ -0,0 +1,42 @@ +/* + * Copyright (C) 2012 by Darren Reed. + * + * See the IPFILTER.LICENCE file for details on licencing. + * + * $Id$ + */ + +#include "ipf.h" + + +void +printlookup(base, addr, mask) + char *base; + i6addr_t *addr, *mask; +{ + char name[32]; + + switch (addr->iplookuptype) + { + case IPLT_POOL : + PRINTF("pool/"); + break; + case IPLT_HASH : + PRINTF("hash/"); + break; + case IPLT_DSTLIST : + PRINTF("dstlist/"); + break; + default : + PRINTF("lookup(%x)=", addr->iplookuptype); + break; + } + + if (addr->iplookupsubtype == 0) + PRINTF("%u", addr->iplookupnum); + else if (addr->iplookupsubtype == 1) { + strncpy(name, base + addr->iplookupname, sizeof(name)); + name[sizeof(name) - 1] = '\0'; + PRINTF("%s", name); + } +} diff --git a/contrib/ipfilter/lib/printmask.c b/contrib/ipfilter/lib/printmask.c index 9230dc0026a5..365d7ffeba14 100644 --- a/contrib/ipfilter/lib/printmask.c +++ b/contrib/ipfilter/lib/printmask.c @@ -1,30 +1,30 @@ /* $FreeBSD$ */ /* - * Copyright (C) 2000-2005 by Darren Reed. + * Copyright (C) 2012 by Darren Reed. * * See the IPFILTER.LICENCE file for details on licencing. * - * $Id: printmask.c,v 1.5.4.1 2006/06/16 17:21:13 darrenr Exp $ + * $Id$ */ #include "ipf.h" -void printmask(mask) -u_32_t *mask; +void +printmask(family, mask) + int family; + u_32_t *mask; { struct in_addr ipa; int ones; -#ifdef USE_INET6 - if (use_inet6) - printf("/%d", count6bits(mask)); - else -#endif - if ((ones = count4bits(*mask)) == -1) { + if (family == AF_INET6) { + PRINTF("/%d", count6bits(mask)); + } else if ((ones = count4bits(*mask)) == -1) { ipa.s_addr = *mask; - printf("/%s", inet_ntoa(ipa)); - } else - printf("/%d", ones); + PRINTF("/%s", inet_ntoa(ipa)); + } else { + PRINTF("/%d", ones); + } } diff --git a/contrib/ipfilter/lib/printnat.c b/contrib/ipfilter/lib/printnat.c index 39c43cafdce1..37a7e12d527e 100644 --- a/contrib/ipfilter/lib/printnat.c +++ b/contrib/ipfilter/lib/printnat.c @@ -1,7 +1,7 @@ /* $FreeBSD$ */ /* - * Copyright (C) 2002-2005 by Darren Reed. + * Copyright (C) 2012 by Darren Reed. * * See the IPFILTER.LICENCE file for details on licencing. * @@ -13,230 +13,339 @@ #if !defined(lint) -static const char rcsid[] = "@(#)$Id: printnat.c,v 1.22.2.14 2007/09/06 16:40:11 darrenr Exp $"; +static const char rcsid[] = "@(#)$Id$"; #endif + /* * Print out a NAT rule */ -void printnat(np, opts) -ipnat_t *np; -int opts; +void +printnat(np, opts) + ipnat_t *np; + int opts; { - struct protoent *pr; - int bits; + struct protoent *pr; + char *base; + int family; + int proto; - pr = getprotobynumber(np->in_p); + if (np->in_v[0] == 4) + family = AF_INET; +#ifdef USE_INET6 + else if (np->in_v[0] == 6) + family = AF_INET6; +#endif + else + family = AF_UNSPEC; + + if (np->in_flags & IPN_NO) + PRINTF("no "); switch (np->in_redir) { + case NAT_REDIRECT|NAT_ENCAP : + PRINTF("encap in on"); + proto = np->in_pr[0]; + break; + case NAT_MAP|NAT_ENCAP : + PRINTF("encap out on"); + proto = np->in_pr[1]; + break; + case NAT_REDIRECT|NAT_DIVERTUDP : + PRINTF("divert in on"); + proto = np->in_pr[0]; + break; + case NAT_MAP|NAT_DIVERTUDP : + PRINTF("divert out on"); + proto = np->in_pr[1]; + break; + case NAT_REDIRECT|NAT_REWRITE : + PRINTF("rewrite in on"); + proto = np->in_pr[0]; + break; + case NAT_MAP|NAT_REWRITE : + PRINTF("rewrite out on"); + proto = np->in_pr[1]; + break; case NAT_REDIRECT : - printf("rdr"); + PRINTF("rdr"); + proto = np->in_pr[0]; break; case NAT_MAP : - printf("map"); + PRINTF("map"); + proto = np->in_pr[1]; break; case NAT_MAPBLK : - printf("map-block"); + PRINTF("map-block"); + proto = np->in_pr[1]; break; case NAT_BIMAP : - printf("bimap"); + PRINTF("bimap"); + proto = np->in_pr[0]; break; default : - fprintf(stderr, "unknown value for in_redir: %#x\n", + FPRINTF(stderr, "unknown value for in_redir: %#x\n", np->in_redir); + proto = np->in_pr[0]; break; } - if (!strcmp(np->in_ifnames[0], "-")) - printf(" \"%s\"", np->in_ifnames[0]); + pr = getprotobynumber(proto); + + base = np->in_names; + if (!strcmp(base + np->in_ifnames[0], "-")) + PRINTF(" \"%s\"", base + np->in_ifnames[0]); else - printf(" %s", np->in_ifnames[0]); - if ((np->in_ifnames[1][0] != '\0') && - (strncmp(np->in_ifnames[0], np->in_ifnames[1], LIFNAMSIZ) != 0)) { - if (!strcmp(np->in_ifnames[1], "-")) - printf(",\"%s\"", np->in_ifnames[1]); + PRINTF(" %s", base + np->in_ifnames[0]); + if ((np->in_ifnames[1] != -1) && + (strcmp(base + np->in_ifnames[0], base + np->in_ifnames[1]) != 0)) { + if (!strcmp(base + np->in_ifnames[1], "-")) + PRINTF(",\"%s\"", base + np->in_ifnames[1]); else - printf(",%s", np->in_ifnames[1]); + PRINTF(",%s", base + np->in_ifnames[1]); } putchar(' '); - 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); - } else { - printhostmask(4, (u_32_t *)&np->in_inip, - (u_32_t *)&np->in_inmsk); - } - if (np->in_scmp) - printportcmp(np->in_p, &np->in_tuc.ftu_src); + if (family == AF_INET6) + PRINTF("inet6 "); - 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); - } else { - printhostmask(4, (u_32_t *)&np->in_srcip, - (u_32_t *)&np->in_srcmsk); + if (np->in_redir & (NAT_REWRITE|NAT_ENCAP|NAT_DIVERTUDP)) { + if ((proto != 0) || (np->in_flags & IPN_TCPUDP)) { + PRINTF("proto "); + printproto(pr, proto, np); + putchar(' '); } - if (np->in_dcmp) - printportcmp(np->in_p, &np->in_tuc.ftu_dst); } - if (np->in_redir == NAT_REDIRECT) { - if (!(np->in_flags & IPN_FILTER)) { - printf("%s", inet_ntoa(np->in_out[0].in4)); - bits = count4bits(np->in_outmsk); - if (bits != -1) - printf("/%d", bits); + if (np->in_flags & IPN_FILTER) { + if (np->in_flags & IPN_NOTSRC) + PRINTF("! "); + PRINTF("from "); + printnataddr(np->in_v[0], np->in_names, &np->in_osrc, + np->in_ifnames[0]); + if (np->in_scmp) + printportcmp(proto, &np->in_tuc.ftu_src); + + if (np->in_flags & IPN_NOTDST) + PRINTF(" !"); + PRINTF(" to "); + printnataddr(np->in_v[0], np->in_names, &np->in_odst, + np->in_ifnames[0]); + if (np->in_dcmp) + printportcmp(proto, &np->in_tuc.ftu_dst); + } + + if (np->in_redir & (NAT_ENCAP|NAT_DIVERTUDP)) { + PRINTF(" -> src "); + printnataddr(np->in_v[1], np->in_names, &np->in_nsrc, + np->in_ifnames[0]); + if ((np->in_redir & NAT_DIVERTUDP) != 0) + PRINTF(",%u", np->in_spmin); + PRINTF(" dst "); + printnataddr(np->in_v[1], np->in_names, &np->in_ndst, + np->in_ifnames[0]); + if ((np->in_redir & NAT_DIVERTUDP) != 0) + PRINTF(",%u udp", np->in_dpmin); + if ((np->in_flags & IPN_PURGE) != 0) + PRINTF(" purge"); + PRINTF(";\n"); + + } else if (np->in_redir & NAT_REWRITE) { + PRINTF(" -> src "); + if (np->in_nsrc.na_type == IPLT_DSTLIST) { + PRINTF("dstlist/"); + if (np->in_nsrc.na_subtype == 0) + PRINTF("%d", np->in_nsrc.na_num); else - printf("/%s", inet_ntoa(np->in_out[1].in4)); - if (np->in_flags & IPN_TCPUDP) { - printf(" port %d", ntohs(np->in_pmin)); - if (np->in_pmax != np->in_pmin) - printf("-%d", ntohs(np->in_pmax)); + PRINTF("%s", base + np->in_nsrc.na_num); + } else { + printnataddr(np->in_v[1], np->in_names, &np->in_nsrc, + np->in_ifnames[0]); + } + if ((((np->in_flags & IPN_TCPUDP) != 0)) && + (np->in_spmin != 0)) { + if ((np->in_flags & IPN_FIXEDSPORT) != 0) { + PRINTF(",port = %u", np->in_spmin); + } else { + PRINTF(",%u", np->in_spmin); + if (np->in_spmax != np->in_spmin) + PRINTF("-%u", np->in_spmax); } } - printf(" -> %s", inet_ntoa(np->in_in[0].in4)); - if (np->in_flags & IPN_SPLIT) - printf(",%s", inet_ntoa(np->in_in[1].in4)); - else if (np->in_inmsk == 0 && np->in_inip == 0) - printf("/0"); + PRINTF(" dst "); + if (np->in_ndst.na_type == IPLT_DSTLIST) { + PRINTF("dstlist/"); + if (np->in_ndst.na_subtype == 0) + PRINTF("%d", np->in_nsrc.na_num); + else + PRINTF("%s", base + np->in_ndst.na_num); + } else { + printnataddr(np->in_v[1], np->in_names, &np->in_ndst, + np->in_ifnames[0]); + } + if ((((np->in_flags & IPN_TCPUDP) != 0)) && + (np->in_dpmin != 0)) { + if ((np->in_flags & IPN_FIXEDDPORT) != 0) { + PRINTF(",port = %u", np->in_dpmin); + } else { + PRINTF(",%u", np->in_dpmin); + if (np->in_dpmax != np->in_dpmin) + PRINTF("-%u", np->in_dpmax); + } + } + if ((np->in_flags & IPN_PURGE) != 0) + PRINTF(" purge"); + PRINTF(";\n"); + + } else if (np->in_redir == NAT_REDIRECT) { + if (!(np->in_flags & IPN_FILTER)) { + printnataddr(np->in_v[0], np->in_names, &np->in_odst, + np->in_ifnames[0]); + if (np->in_flags & IPN_TCPUDP) { + PRINTF(" port %d", np->in_odport); + if (np->in_odport != np->in_dtop) + PRINTF("-%d", np->in_dtop); + } + } + if (np->in_flags & IPN_NO) { + putchar(' '); + printproto(pr, proto, np); + PRINTF(";\n"); + return; + } + PRINTF(" -> "); + printnataddr(np->in_v[1], np->in_names, &np->in_ndst, + np->in_ifnames[0]); if (np->in_flags & IPN_TCPUDP) { if ((np->in_flags & IPN_FIXEDDPORT) != 0) - printf(" port = %d", ntohs(np->in_pnext)); - else - printf(" port %d", ntohs(np->in_pnext)); + PRINTF(" port = %d", np->in_dpmin); + else { + PRINTF(" port %d", np->in_dpmin); + if (np->in_dpmin != np->in_dpmax) + PRINTF("-%d", np->in_dpmax); + } } putchar(' '); - printproto(pr, np->in_p, np); + printproto(pr, proto, np); if (np->in_flags & IPN_ROUNDR) - printf(" round-robin"); + PRINTF(" round-robin"); if (np->in_flags & IPN_FRAG) - printf(" frag"); + PRINTF(" frag"); if (np->in_age[0] != 0 || np->in_age[1] != 0) { - printf(" age %d/%d", np->in_age[0], np->in_age[1]); + PRINTF(" age %d/%d", np->in_age[0], np->in_age[1]); } if (np->in_flags & IPN_STICKY) - printf(" sticky"); + PRINTF(" sticky"); if (np->in_mssclamp != 0) - printf(" mssclamp %d", np->in_mssclamp); - if (*np->in_plabel != '\0') - printf(" proxy %.*s", (int)sizeof(np->in_plabel), - np->in_plabel); + PRINTF(" mssclamp %d", np->in_mssclamp); + if (np->in_plabel != -1) + PRINTF(" proxy %s", np->in_names + np->in_plabel); if (np->in_tag.ipt_tag[0] != '\0') - printf(" tag %-.*s", IPFTAG_LEN, np->in_tag.ipt_tag); - printf("\n"); + PRINTF(" tag %-.*s", IPFTAG_LEN, np->in_tag.ipt_tag); + if ((np->in_flags & IPN_PURGE) != 0) + PRINTF(" purge"); + PRINTF("\n"); if (opts & OPT_DEBUG) - printf("\tpmax %u\n", np->in_pmax); + PRINTF("\tpmax %u\n", np->in_dpmax); + } else { int protoprinted = 0; if (!(np->in_flags & IPN_FILTER)) { - printf("%s/", inet_ntoa(np->in_in[0].in4)); - bits = count4bits(np->in_inmsk); - if (bits != -1) - printf("%d", bits); - else - printf("%s", inet_ntoa(np->in_in[1].in4)); + printnataddr(np->in_v[0], np->in_names, &np->in_osrc, + np->in_ifnames[0]); } - printf(" -> "); - if (np->in_flags & IPN_IPRANGE) { - printf("range %s-", inet_ntoa(np->in_out[0].in4)); - printf("%s", inet_ntoa(np->in_out[1].in4)); + if (np->in_flags & IPN_NO) { + putchar(' '); + printproto(pr, proto, np); + PRINTF(";\n"); + return; + } + PRINTF(" -> "); + if (np->in_flags & IPN_SIPRANGE) { + PRINTF("range "); + printnataddr(np->in_v[1], np->in_names, &np->in_nsrc, + np->in_ifnames[0]); } else { - printf("%s/", inet_ntoa(np->in_out[0].in4)); - bits = count4bits(np->in_outmsk); - if (bits != -1) - printf("%d", bits); - else - printf("%s", inet_ntoa(np->in_out[1].in4)); + printnataddr(np->in_v[1], np->in_names, &np->in_nsrc, + np->in_ifnames[0]); } - if (*np->in_plabel != '\0') { - printf(" proxy port "); - if (np->in_dcmp != 0) - np->in_dport = htons(np->in_dport); - if (np->in_dport != 0) { + if (np->in_plabel != -1) { + PRINTF(" proxy port "); + if (np->in_odport != 0) { char *s; - s = portname(np->in_p, ntohs(np->in_dport)); + s = portname(proto, np->in_odport); if (s != NULL) fputs(s, stdout); else fputs("???", stdout); } - printf(" %.*s/", (int)sizeof(np->in_plabel), - np->in_plabel); - printproto(pr, np->in_p, NULL); + PRINTF(" %s/", np->in_names + np->in_plabel); + printproto(pr, proto, NULL); protoprinted = 1; } else if (np->in_redir == NAT_MAPBLK) { - if ((np->in_pmin == 0) && + if ((np->in_spmin == 0) && (np->in_flags & IPN_AUTOPORTMAP)) - printf(" ports auto"); + PRINTF(" ports auto"); else - printf(" ports %d", np->in_pmin); + PRINTF(" ports %d", np->in_spmin); if (opts & OPT_DEBUG) - printf("\n\tip modulous %d", np->in_pmax); - } else if (np->in_pmin || np->in_pmax) { + PRINTF("\n\tip modulous %d", np->in_spmax); + + } else if (np->in_spmin || np->in_spmax) { if (np->in_flags & IPN_ICMPQUERY) { - printf(" icmpidmap "); + PRINTF(" icmpidmap "); } else { - printf(" portmap "); + PRINTF(" portmap "); } - printproto(pr, np->in_p, np); + printproto(pr, proto, np); protoprinted = 1; if (np->in_flags & IPN_AUTOPORTMAP) { - printf(" auto"); + PRINTF(" auto"); if (opts & OPT_DEBUG) - printf(" [%d:%d %d %d]", - ntohs(np->in_pmin), - ntohs(np->in_pmax), + PRINTF(" [%d:%d %d %d]", + np->in_spmin, np->in_spmax, np->in_ippip, np->in_ppip); } else { - printf(" %d:%d", ntohs(np->in_pmin), - ntohs(np->in_pmax)); + PRINTF(" %d:%d", np->in_spmin, np->in_spmax); } + if (np->in_flags & IPN_SEQUENTIAL) + PRINTF(" sequential"); } if (np->in_flags & IPN_FRAG) - printf(" frag"); + PRINTF(" frag"); if (np->in_age[0] != 0 || np->in_age[1] != 0) { - printf(" age %d/%d", np->in_age[0], np->in_age[1]); + PRINTF(" age %d/%d", np->in_age[0], np->in_age[1]); } if (np->in_mssclamp != 0) - printf(" mssclamp %d", np->in_mssclamp); + PRINTF(" mssclamp %d", np->in_mssclamp); if (np->in_tag.ipt_tag[0] != '\0') - printf(" tag %s", np->in_tag.ipt_tag); - if (!protoprinted && (np->in_flags & IPN_TCPUDP || np->in_p)) { + PRINTF(" tag %s", np->in_tag.ipt_tag); + if (!protoprinted && (np->in_flags & IPN_TCPUDP || proto)) { putchar(' '); - printproto(pr, np->in_p, np); + printproto(pr, proto, np); } - if (np->in_flags & IPN_SEQUENTIAL) - printf(" sequential"); - printf("\n"); + if ((np->in_flags & IPN_PURGE) != 0) + PRINTF(" purge"); + PRINTF("\n"); if (opts & OPT_DEBUG) { - struct in_addr nip; - - nip.s_addr = htonl(np->in_nextip.s_addr); - - printf("\tnextip %s pnext %d\n", - inet_ntoa(nip), np->in_pnext); + PRINTF("\tnextip "); + printip(family, &np->in_snip); + PRINTF(" pnext %d\n", np->in_spnext); } } if (opts & OPT_DEBUG) { - printf("\tspace %lu use %u hits %lu flags %#x proto %d hv %d\n", + PRINTF("\tspace %lu use %u hits %lu flags %#x proto %d/%d", np->in_space, np->in_use, np->in_hits, - np->in_flags, np->in_p, np->in_hv); - printf("\tifp[0] %p ifp[1] %p apr %p\n", + np->in_flags, np->in_pr[0], np->in_pr[1]); + PRINTF(" hv %u/%u\n", np->in_hv[0], np->in_hv[1]); + PRINTF("\tifp[0] %p ifp[1] %p apr %p\n", np->in_ifps[0], np->in_ifps[1], np->in_apr); - printf("\ttqehead %p/%p comment %p\n", + PRINTF("\ttqehead %p/%p comment %p\n", np->in_tqehead[0], np->in_tqehead[1], np->in_comment); } } diff --git a/contrib/ipfilter/lib/printnataddr.c b/contrib/ipfilter/lib/printnataddr.c new file mode 100644 index 000000000000..89faa624193c --- /dev/null +++ b/contrib/ipfilter/lib/printnataddr.c @@ -0,0 +1,48 @@ +/* + * Copyright (C) 2012 by Darren Reed. + * + * See the IPFILTER.LICENCE file for details on licencing. + * + * Added redirect stuff and a variety of bug fixes. (mcn@EnGarde.com) + */ + +#include "ipf.h" +#include "kmem.h" + + +#if !defined(lint) +static const char rcsid[] = "@(#)$Id: printnataddr.c,v 1.4.2.2 2012/07/22 08:04:24 darren_r Exp $"; +#endif + + +void +printnataddr(v, base, addr, ifidx) + int v; + char *base; + nat_addr_t *addr; + int ifidx; +{ + switch (v) + { + case 4 : + if (addr->na_atype == FRI_NORMAL && + addr->na_addr[0].in4.s_addr == 0) { + PRINTF("0/%d", count4bits(addr->na_addr[1].in4.s_addr)); + } else { + printaddr(AF_INET, addr->na_atype, base, ifidx, + (u_32_t *)&addr->na_addr[0].in4.s_addr, + (u_32_t *)&addr->na_addr[1].in4.s_addr); + } + break; +#ifdef USE_INET6 + case 6 : + printaddr(AF_INET6, addr->na_atype, base, ifidx, + (u_32_t *)&addr->na_addr[0].in6, + (u_32_t *)&addr->na_addr[1].in6); + break; +#endif + default : + printf("{v=%d}", v); + break; + } +} diff --git a/contrib/ipfilter/lib/printnatfield.c b/contrib/ipfilter/lib/printnatfield.c new file mode 100644 index 000000000000..49596f607170 --- /dev/null +++ b/contrib/ipfilter/lib/printnatfield.c @@ -0,0 +1,220 @@ +/* + * Copyright (C) 2012 by Darren Reed. + * + * See the IPFILTER.LICENCE file for details on licencing. + * + * $Id: printnatfield.c,v 1.6.2.2 2012/01/26 05:44:26 darren_r Exp $ + */ + +#include "ipf.h" + +wordtab_t natfields[] = { + { "all", -2 }, + { "ifp0", 1 }, + { "ifp1", 2 }, + { "mtu0", 3 }, + { "mtu1", 4 }, + { "ifname0", 5 }, + { "ifname1", 6 }, + { "sumd0", 7 }, + { "sumd1", 8 }, + { "pkts0", 9 }, + { "pkts1", 10 }, + { "bytes0", 11 }, + { "bytes1", 12 }, + { "proto0", 13 }, + { "proto1", 14 }, + { "hash0", 15 }, + { "hash1", 16 }, + { "ref", 17 }, + { "rev", 18 }, + { "v0", 19 }, + { "redir", 20 }, + { "use", 21 }, + { "ipsumd", 22 }, + { "dir", 23 }, + { "olddstip", 24 }, + { "oldsrcip", 25 }, + { "newdstip", 26 }, + { "newsrcip", 27 }, + { "olddport", 28 }, + { "oldsport", 29 }, + { "newdport", 30 }, + { "newsport", 31 }, + { "age", 32 }, + { "v1", 33 }, + { NULL, 0 } +}; + + +void +printnatfield(n, fieldnum) + nat_t *n; + int fieldnum; +{ + int i; + + switch (fieldnum) + { + case -2 : + for (i = 1; natfields[i].w_word != NULL; i++) { + if (natfields[i].w_value > 0) { + printnatfield(n, i); + if (natfields[i + 1].w_value > 0) + putchar('\t'); + } + } + break; + + case 1: + PRINTF("%#lx", (u_long)n->nat_ifps[0]); + break; + + case 2: + PRINTF("%#lx", (u_long)n->nat_ifps[1]); + break; + + case 3: + PRINTF("%d", n->nat_mtu[0]); + break; + + case 4: + PRINTF("%d", n->nat_mtu[1]); + break; + + case 5: + PRINTF("%s", n->nat_ifnames[0]); + break; + + case 6: + PRINTF("%s", n->nat_ifnames[1]); + break; + + case 7: + PRINTF("%d", n->nat_sumd[0]); + break; + + case 8: + PRINTF("%d", n->nat_sumd[1]); + break; + + case 9: +#ifdef USE_QUAD_T + PRINTF("%"PRIu64"", n->nat_pkts[0]); +#else + PRINTF("%lu", n->nat_pkts[0]); +#endif + break; + + case 10: +#ifdef USE_QUAD_T + PRINTF("%"PRIu64"", n->nat_pkts[1]); +#else + PRINTF("%lu", n->nat_pkts[1]); +#endif + break; + + case 11: +#ifdef USE_QUAD_T + PRINTF("%"PRIu64"", n->nat_bytes[0]); +#else + PRINTF("%lu", n->nat_bytes[0]); +#endif + break; + + case 12: +#ifdef USE_QUAD_T + PRINTF("%"PRIu64"", n->nat_bytes[1]); +#else + PRINTF("%lu", n->nat_bytes[1]); +#endif + break; + + case 13: + PRINTF("%d", n->nat_pr[0]); + break; + + case 14: + PRINTF("%d", n->nat_pr[1]); + break; + + case 15: + PRINTF("%u", n->nat_hv[0]); + break; + + case 16: + PRINTF("%u", n->nat_hv[1]); + break; + + case 17: + PRINTF("%d", n->nat_ref); + break; + + case 18: + PRINTF("%d", n->nat_rev); + break; + + case 19: + PRINTF("%d", n->nat_v[0]); + break; + + case 33: + PRINTF("%d", n->nat_v[0]); + break; + + case 20: + PRINTF("%d", n->nat_redir); + break; + + case 21: + PRINTF("%d", n->nat_use); + break; + + case 22: + PRINTF("%u", n->nat_ipsumd); + break; + + case 23: + PRINTF("%d", n->nat_dir); + break; + + case 24: + PRINTF("%s", hostname(n->nat_v[0], &n->nat_odstip)); + break; + + case 25: + PRINTF("%s", hostname(n->nat_v[0], &n->nat_osrcip)); + break; + + case 26: + PRINTF("%s", hostname(n->nat_v[1], &n->nat_ndstip)); + break; + + case 27: + PRINTF("%s", hostname(n->nat_v[1], &n->nat_nsrcip)); + break; + + case 28: + PRINTF("%hu", ntohs(n->nat_odport)); + break; + + case 29: + PRINTF("%hu", ntohs(n->nat_osport)); + break; + + case 30: + PRINTF("%hu", ntohs(n->nat_ndport)); + break; + + case 31: + PRINTF("%hu", ntohs(n->nat_nsport)); + break; + + case 32: + PRINTF("%u", n->nat_age); + break; + + default: + break; + } +} diff --git a/contrib/ipfilter/lib/printnatside.c b/contrib/ipfilter/lib/printnatside.c new file mode 100644 index 000000000000..37e1cb8d1e3a --- /dev/null +++ b/contrib/ipfilter/lib/printnatside.c @@ -0,0 +1,55 @@ +/* + * Copyright (C) 2012 by Darren Reed. + * + * See the IPFILTER.LICENCE file for details on licencing. + * + * $Id: printnatside.c,v 1.2.2.6 2012/07/22 08:04:24 darren_r Exp $ + */ +#include "ipf.h" + +void +printnatside(side, ns) + char *side; + nat_stat_side_t *ns; +{ + PRINTF("%lu\tproxy create fail %s\n", ns->ns_appr_fail, side); + PRINTF("%lu\tproxy fail %s\n", ns->ns_ipf_proxy_fail, side); + PRINTF("%lu\tbad nat %s\n", ns->ns_badnat, side); + PRINTF("%lu\tbad nat new %s\n", ns->ns_badnatnew, side); + PRINTF("%lu\tbad next addr %s\n", ns->ns_badnextaddr, side); + PRINTF("%lu\tbucket max %s\n", ns->ns_bucket_max, side); + PRINTF("%lu\tclone nomem %s\n", ns->ns_clone_nomem, side); + PRINTF("%lu\tdecap bad %s\n", ns->ns_decap_bad, side); + PRINTF("%lu\tdecap fail %s\n", ns->ns_decap_fail, side); + PRINTF("%lu\tdecap pullup %s\n", ns->ns_decap_pullup, side); + PRINTF("%lu\tdivert dup %s\n", ns->ns_divert_dup, side); + PRINTF("%lu\tdivert exist %s\n", ns->ns_divert_exist, side); + PRINTF("%lu\tdrop %s\n", ns->ns_drop, side); + PRINTF("%lu\texhausted %s\n", ns->ns_exhausted, side); + PRINTF("%lu\ticmp address %s\n", ns->ns_icmp_address, side); + PRINTF("%lu\ticmp basic %s\n", ns->ns_icmp_basic, side); + PRINTF("%lu\tinuse %s\n", ns->ns_inuse, side); + PRINTF("%lu\ticmp mbuf wrong size %s\n", ns->ns_icmp_mbuf, side); + PRINTF("%lu\ticmp header unmatched %s\n", ns->ns_icmp_notfound, side); + PRINTF("%lu\ticmp rebuild failures %s\n", ns->ns_icmp_rebuild, side); + PRINTF("%lu\ticmp short %s\n", ns->ns_icmp_short, side); + PRINTF("%lu\ticmp packet size wrong %s\n", ns->ns_icmp_size, side); + PRINTF("%lu\tIFP address fetch failures %s\n", + ns->ns_ifpaddrfail, side); + PRINTF("%lu\tpackets untranslated %s\n", ns->ns_ignored, side); + PRINTF("%lu\tNAT insert failures %s\n", ns->ns_insert_fail, side); + PRINTF("%lu\tNAT lookup misses %s\n", ns->ns_lookup_miss, side); + PRINTF("%lu\tNAT lookup nowild %s\n", ns->ns_lookup_nowild, side); + PRINTF("%lu\tnew ifpaddr failed %s\n", ns->ns_new_ifpaddr, side); + PRINTF("%lu\tmemory requests failed %s\n", ns->ns_memfail, side); + PRINTF("%lu\ttable max reached %s\n", ns->ns_table_max, side); + PRINTF("%lu\tpackets translated %s\n", ns->ns_translated, side); + PRINTF("%lu\tfinalised failed %s\n", ns->ns_unfinalised, side); + PRINTF("%lu\tsearch wraps %s\n", ns->ns_wrap, side); + PRINTF("%lu\tnull translations %s\n", ns->ns_xlate_null, side); + PRINTF("%lu\ttranslation exists %s\n", ns->ns_xlate_exists, side); + PRINTF("%lu\tno memory %s\n", ns->ns_memfail, side); + + if (opts & OPT_VERBOSE) + PRINTF("%p table %s\n", ns->ns_table, side); +} diff --git a/contrib/ipfilter/lib/printpacket.c b/contrib/ipfilter/lib/printpacket.c index 25a4d5a8f7da..5c4a74975cb6 100644 --- a/contrib/ipfilter/lib/printpacket.c +++ b/contrib/ipfilter/lib/printpacket.c @@ -1,11 +1,11 @@ /* $FreeBSD$ */ /* - * Copyright (C) 2000-2005 by Darren Reed. + * Copyright (C) 2012 by Darren Reed. * * See the IPFILTER.LICENCE file for details on licencing. * - * $Id: printpacket.c,v 1.12.4.5 2007/09/09 22:15:30 darrenr Exp $ + * $Id$ */ #include "ipf.h" @@ -15,32 +15,43 @@ #endif -void printpacket(ip) -struct ip *ip; +void +printpacket(dir, m) + int dir; + mb_t *m; { - struct tcphdr *tcp; - u_short len; - u_short off; + u_short len, off; + tcphdr_t *tcp; + ip_t *ip; + + ip = MTOD(m, ip_t *); if (IP_V(ip) == 6) { - off = 0; - len = ntohs(((u_short *)ip)[2]) + 40; +#ifdef USE_INET6 + len = ntohs(((ip6_t *)ip)->ip6_plen); +#else + len = ntohs(((u_short *)ip)[2]); +#endif + len += 40; } else { - off = ntohs(ip->ip_off); len = ntohs(ip->ip_len); } + ASSERT(len == msgdsize(m)); if ((opts & OPT_HEX) == OPT_HEX) { u_char *s; int i; - for (s = (u_char *)ip, i = 0; i < len; i++) { - printf("%02x", *s++ & 0xff); - if (len - i > 1) { - i++; - printf("%02x", *s++ & 0xff); + for (; m != NULL; m = m->mb_next) { + len = m->mb_len; + for (s = (u_char *)m->mb_data, i = 0; i < len; i++) { + PRINTF("%02x", *s++ & 0xff); + if (len - i > 1) { + i++; + PRINTF("%02x", *s++ & 0xff); + } + putchar(' '); } - putchar(' '); } putchar('\n'); putchar('\n'); @@ -48,24 +59,32 @@ struct ip *ip; } if (IP_V(ip) == 6) { - printpacket6(ip); + printpacket6(dir, m); return; } + if (dir) + PRINTF("> "); + else + PRINTF("< "); + + PRINTF("%s ", IFNAME(m->mb_ifp)); + + off = ntohs(ip->ip_off); tcp = (struct tcphdr *)((char *)ip + (IP_HL(ip) << 2)); - printf("ip #%d %d(%d) %d", ntohs(ip->ip_id), ntohs(ip->ip_len), + PRINTF("ip #%d %d(%d) %d", ntohs(ip->ip_id), ntohs(ip->ip_len), IP_HL(ip) << 2, ip->ip_p); if (off & IP_OFFMASK) - printf(" @%d", (off & IP_OFFMASK) << 3); - printf(" %s", inet_ntoa(ip->ip_src)); + PRINTF(" @%d", off << 3); + PRINTF(" %s", inet_ntoa(ip->ip_src)); if (!(off & IP_OFFMASK)) if (ip->ip_p == IPPROTO_TCP || ip->ip_p == IPPROTO_UDP) - printf(",%d", ntohs(tcp->th_sport)); - printf(" > "); - printf("%s", inet_ntoa(ip->ip_dst)); + PRINTF(",%d", ntohs(tcp->th_sport)); + PRINTF(" > "); + PRINTF("%s", inet_ntoa(ip->ip_dst)); if (!(off & IP_OFFMASK)) { if (ip->ip_p == IPPROTO_TCP || ip->ip_p == IPPROTO_UDP) - printf(",%d", ntohs(tcp->th_dport)); + PRINTF(",%d", ntohs(tcp->th_dport)); if ((ip->ip_p == IPPROTO_TCP) && (tcp->th_flags != 0)) { putchar(' '); if (tcp->th_flags & TH_FIN) diff --git a/contrib/ipfilter/lib/printpacket6.c b/contrib/ipfilter/lib/printpacket6.c index ca3b42133a3e..6363e55fc76d 100644 --- a/contrib/ipfilter/lib/printpacket6.c +++ b/contrib/ipfilter/lib/printpacket6.c @@ -1,12 +1,12 @@ /* $FreeBSD$ */ /* - * Copyright (C) 2002 by Darren Reed. - * - * See the IPFILTER.LICENCE file for details on licencing. - * - * $Id: printpacket6.c,v 1.3.4.1 2006/06/16 17:21:13 darrenr Exp $ - */ + * Copyright (C) 2012 by Darren Reed. + * + * See the IPFILTER.LICENCE file for details on licencing. + * + * $Id$ + */ #include "ipf.h" @@ -14,15 +14,17 @@ * This is meant to work without the IPv6 header files being present or * the inet_ntop() library. */ -void printpacket6(ip) -struct ip *ip; +void +printpacket6(dir, m) + int dir; + mb_t *m; { u_char *buf, p; u_short plen, *addrs; tcphdr_t *tcp; u_32_t flow; - buf = (u_char *)ip; + buf = (u_char *)m->mb_data; tcp = (tcphdr_t *)(buf + 40); p = buf[6]; flow = ntohl(*(u_32_t *)buf); @@ -30,22 +32,29 @@ struct ip *ip; plen = ntohs(*((u_short *)buf +2)); addrs = (u_short *)buf + 4; - printf("ip6/%d %d %#x %d", buf[0] & 0xf, plen, flow, p); - printf(" %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x", + if (dir) + PRINTF("> "); + else + PRINTF("< "); + + PRINTF("%s ", IFNAME(m->mb_ifp)); + + PRINTF("ip6/%d %d %#x %d", buf[0] & 0xf, plen, flow, p); + PRINTF(" %x:%x:%x:%x:%x:%x:%x:%x", ntohs(addrs[0]), ntohs(addrs[1]), ntohs(addrs[2]), ntohs(addrs[3]), ntohs(addrs[4]), ntohs(addrs[5]), ntohs(addrs[6]), ntohs(addrs[7])); if (plen >= 4) if (p == IPPROTO_TCP || p == IPPROTO_UDP) - (void)printf(",%d", ntohs(tcp->th_sport)); - printf(" >"); + (void)PRINTF(",%d", ntohs(tcp->th_sport)); + PRINTF(" >"); addrs += 8; - printf(" %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x", + PRINTF(" %x:%x:%x:%x:%x:%x:%x:%x", ntohs(addrs[0]), ntohs(addrs[1]), ntohs(addrs[2]), ntohs(addrs[3]), ntohs(addrs[4]), ntohs(addrs[5]), ntohs(addrs[6]), ntohs(addrs[7])); if (plen >= 4) if (p == IPPROTO_TCP || p == IPPROTO_UDP) - (void)printf(",%d", ntohs(tcp->th_dport)); + PRINTF(",%d", ntohs(tcp->th_dport)); putchar('\n'); } diff --git a/contrib/ipfilter/lib/printpool.c b/contrib/ipfilter/lib/printpool.c index 4ab85fac8c35..8d8cdccea59f 100644 --- a/contrib/ipfilter/lib/printpool.c +++ b/contrib/ipfilter/lib/printpool.c @@ -1,23 +1,23 @@ /* $FreeBSD$ */ /* - * Copyright (C) 2002-2005 by Darren Reed. + * Copyright (C) 2012 by Darren Reed. * * See the IPFILTER.LICENCE file for details on licencing. */ #include "ipf.h" -#define PRINTF (void)printf -#define FPRINTF (void)fprintf -ip_pool_t *printpool(pp, copyfunc, name, opts) -ip_pool_t *pp; -copyfunc_t copyfunc; -char *name; -int opts; +ip_pool_t * +printpool(pp, copyfunc, name, opts, fields) + ip_pool_t *pp; + copyfunc_t copyfunc; + char *name; + int opts; + wordtab_t *fields; { - ip_pool_node_t *ipnp, *ipnpn, ipn; + ip_pool_node_t *ipnp, *ipnpn, ipn, **pnext; ip_pool_t ipp; if ((*copyfunc)(pp, &ipp, sizeof(ipp))) @@ -35,19 +35,22 @@ int opts; ipnpn = ipp.ipo_list; ipp.ipo_list = NULL; + pnext = &ipp.ipo_list; while (ipnpn != NULL) { ipnp = (ip_pool_node_t *)malloc(sizeof(*ipnp)); (*copyfunc)(ipnpn, ipnp, sizeof(ipn)); ipnpn = ipnp->ipn_next; - ipnp->ipn_next = ipp.ipo_list; - ipp.ipo_list = ipnp; + *pnext = ipnp; + pnext = &ipnp->ipn_next; + ipnp->ipn_next = NULL; } if (ipp.ipo_list == NULL) { putchar(';'); } else { - for (ipnp = ipp.ipo_list; ipnp != NULL; ) { - ipnp = printpoolnode(ipnp, opts); + for (ipnp = ipp.ipo_list; ipnp != NULL; ipnp = ipnpn) { + ipnpn = printpoolnode(ipnp, opts, fields); + free(ipnp); if ((opts & OPT_DEBUG) == 0) { putchar(';'); diff --git a/contrib/ipfilter/lib/printpool_live.c b/contrib/ipfilter/lib/printpool_live.c index e228a3965adb..2aabf32bc14a 100644 --- a/contrib/ipfilter/lib/printpool_live.c +++ b/contrib/ipfilter/lib/printpool_live.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002 by Darren Reed. + * Copyright (C) 2012 by Darren Reed. * * See the IPFILTER.LICENCE file for details on licencing. */ @@ -8,17 +8,16 @@ #include "ipf.h" #include "netinet/ipl.h" -#define PRINTF (void)printf -#define FPRINTF (void)fprintf - -ip_pool_t *printpool_live(pool, fd, name, opts) -ip_pool_t *pool; -int fd; -char *name; -int opts; +ip_pool_t * +printpool_live(pool, fd, name, opts, fields) + ip_pool_t *pool; + int fd; + char *name; + int opts; + wordtab_t *fields; { - ip_pool_node_t entry, *top, *node; + ip_pool_node_t entry; ipflookupiter_t iter; int printed, last; ipfobj_t obj; @@ -26,7 +25,8 @@ int opts; if ((name != NULL) && strncmp(name, pool->ipo_name, FR_GROUPLEN)) return pool->ipo_next; - printpooldata(pool, opts); + if (fields == NULL) + printpooldata(pool, opts); if ((pool->ipo_flags & IPOOL_DELETE) != 0) PRINTF("# "); @@ -46,28 +46,17 @@ int opts; strncpy(iter.ili_name, pool->ipo_name, FR_GROUPLEN); last = 0; - top = NULL; printed = 0; - while (!last && (ioctl(fd, SIOCLOOKUPITER, &obj) == 0)) { - if (entry.ipn_next == NULL) - last = 1; - node = malloc(sizeof(*top)); - if (node == NULL) - break; - bcopy(&entry, node, sizeof(entry)); - node->ipn_next = top; - top = node; - } - - while (top != NULL) { - node = top; - (void) printpoolnode(node, opts); - if ((opts & OPT_DEBUG) == 0) - putchar(';'); - top = node->ipn_next; - free(node); - printed++; + if (pool->ipo_list != NULL) { + while (!last && (ioctl(fd, SIOCLOOKUPITER, &obj) == 0)) { + if (entry.ipn_next == NULL) + last = 1; + (void) printpoolnode(&entry, opts, fields); + if ((opts & OPT_DEBUG) == 0) + putchar(';'); + printed++; + } } if (printed == 0) @@ -76,8 +65,7 @@ int opts; if ((opts & OPT_DEBUG) == 0) PRINTF(" };\n"); - if (ioctl(fd, SIOCIPFDELTOK, &iter.ili_key) != 0) - perror("SIOCIPFDELTOK"); + (void) ioctl(fd,SIOCIPFDELTOK, &iter.ili_key); return pool->ipo_next; } diff --git a/contrib/ipfilter/lib/printpooldata.c b/contrib/ipfilter/lib/printpooldata.c index 8d8e962cbbde..a1591774b4df 100644 --- a/contrib/ipfilter/lib/printpooldata.c +++ b/contrib/ipfilter/lib/printpooldata.c @@ -1,17 +1,17 @@ /* - * Copyright (C) 2002 by Darren Reed. + * Copyright (C) 2012 by Darren Reed. * * See the IPFILTER.LICENCE file for details on licencing. */ #include "ipf.h" +#include -#define PRINTF (void)printf -#define FPRINTF (void)fprintf -void printpooldata(pool, opts) -ip_pool_t *pool; -int opts; +void +printpooldata(pool, opts) + ip_pool_t *pool; + int opts; { if ((opts & OPT_DEBUG) == 0) { @@ -19,12 +19,12 @@ int opts; PRINTF("# 'anonymous' tree %s\n", pool->ipo_name); if ((pool->ipo_flags & IPOOL_DELETE) != 0) PRINTF("# "); - PRINTF("table role = "); + PRINTF("table role="); } else { if ((pool->ipo_flags & IPOOL_DELETE) != 0) PRINTF("# "); PRINTF("%s: %s", - isdigit(*pool->ipo_name) ? "Number" : "Name", + ISDIGIT(*pool->ipo_name) ? "Number" : "Name", pool->ipo_name); if ((pool->ipo_flags & IPOOL_ANON) == IPOOL_ANON) PRINTF("(anon)"); @@ -32,40 +32,12 @@ int opts; PRINTF("Role: "); } - switch (pool->ipo_unit) - { - case IPL_LOGIPF : - printf("ipf"); - break; - case IPL_LOGNAT : - printf("nat"); - break; - case IPL_LOGSTATE : - printf("state"); - break; - case IPL_LOGAUTH : - printf("auth"); - break; - case IPL_LOGSYNC : - printf("sync"); - break; - case IPL_LOGSCAN : - printf("scan"); - break; - case IPL_LOGLOOKUP : - printf("lookup"); - break; - case IPL_LOGCOUNT : - printf("count"); - break; - default : - printf("unknown(%d)", pool->ipo_unit); - } + printunit(pool->ipo_unit); if ((opts & OPT_DEBUG) == 0) { - PRINTF(" type = tree %s = %s\n", - isdigit(*pool->ipo_name) ? "number" : "name", - pool->ipo_name); + PRINTF(" type=tree %s=%s\n", + (!*pool->ipo_name || ISDIGIT(*pool->ipo_name)) ? \ + "number" : "name", pool->ipo_name); } else { putchar(' '); diff --git a/contrib/ipfilter/lib/printpoolfield.c b/contrib/ipfilter/lib/printpoolfield.c new file mode 100644 index 000000000000..9254ab844615 --- /dev/null +++ b/contrib/ipfilter/lib/printpoolfield.c @@ -0,0 +1,168 @@ +/* + * Copyright (C) 2012 by Darren Reed. + * + * See the IPFILTER.LICENCE file for details on licencing. + * + * $Id: printpoolfield.c,v 1.1.2.4 2012/01/26 05:44:26 darren_r Exp $ + */ + +#include "ipf.h" + +wordtab_t poolfields[] = { + { "all", -2 }, + { "address", 1 }, + { "mask", 2 }, + { "ifname", 3 }, + { "pkts", 4 }, + { "bytes", 5 }, + { "family", 6 }, + { NULL, 0 } +}; + + +void +printpoolfield(p, ptype, fieldnum) + void *p; + int ptype; + int fieldnum; +{ + addrfamily_t *a; + char abuf[80]; + int i; + + switch (fieldnum) + { + case -2 : + for (i = 1; poolfields[i].w_word != NULL; i++) { + if (poolfields[i].w_value > 0) { + printpoolfield(p, ptype, i); + if (poolfields[i + 1].w_value > 0) + putchar('\t'); + } + } + break; + + case 1: + if (ptype == IPLT_POOL) { + ip_pool_node_t *node = (ip_pool_node_t *)p; + + if (node->ipn_info) + PRINTF("!"); + a = &node->ipn_addr; + PRINTF("%s", inet_ntop(a->adf_family, &a->adf_addr, + abuf, sizeof(abuf))); + } else if (ptype == IPLT_HASH) { + iphtent_t *node = (iphtent_t *)p; + + PRINTF("%s", inet_ntop(node->ipe_family, + &node->ipe_addr, + abuf, sizeof(abuf))); + } else if (ptype == IPLT_DSTLIST) { + ipf_dstnode_t *node = (ipf_dstnode_t *)p; + + a = &node->ipfd_dest.fd_addr; + PRINTF("%s", inet_ntop(a->adf_family, &a->adf_addr, + abuf, sizeof(abuf))); + } + break; + + case 2: + if (ptype == IPLT_POOL) { + ip_pool_node_t *node = (ip_pool_node_t *)p; + + a = &node->ipn_mask; + PRINTF("%s", inet_ntop(a->adf_family, &a->adf_addr, + abuf, sizeof(abuf))); + } else if (ptype == IPLT_HASH) { + iphtent_t *node = (iphtent_t *)p; + + PRINTF("%s", inet_ntop(node->ipe_family, + &node->ipe_mask, + abuf, sizeof(abuf))); + } else if (ptype == IPLT_DSTLIST) { + PRINTF("%s", ""); + } + break; + + case 3: + if (ptype == IPLT_POOL) { + PRINTF("%s", ""); + } else if (ptype == IPLT_HASH) { + PRINTF("%s", ""); + } else if (ptype == IPLT_DSTLIST) { + ipf_dstnode_t *node = (ipf_dstnode_t *)p; + + if (node->ipfd_dest.fd_name == -1) { + PRINTF("%s", ""); + } else { + PRINTF("%s", node->ipfd_names + + node->ipfd_dest.fd_name); + } + } + break; + + case 4: + if (ptype == IPLT_POOL) { + ip_pool_node_t *node = (ip_pool_node_t *)p; + +#ifdef USE_QUAD_T + PRINTF("%"PRIu64"", node->ipn_hits); +#else + PRINTF("%lu", node->ipn_hits); +#endif + } else if (ptype == IPLT_HASH) { + iphtent_t *node = (iphtent_t *)p; + +#ifdef USE_QUAD_T + PRINTF("%"PRIu64"", node->ipe_hits); +#else + PRINTF("%lu", node->ipe_hits); +#endif + } else if (ptype == IPLT_DSTLIST) { + printf("0"); + } + break; + + case 5: + if (ptype == IPLT_POOL) { + ip_pool_node_t *node = (ip_pool_node_t *)p; + +#ifdef USE_QUAD_T + PRINTF("%"PRIu64"", node->ipn_bytes); +#else + PRINTF("%lu", node->ipn_bytes); +#endif + } else if (ptype == IPLT_HASH) { + iphtent_t *node = (iphtent_t *)p; + +#ifdef USE_QUAD_T + PRINTF("%"PRIu64"", node->ipe_bytes); +#else + PRINTF("%lu", node->ipe_bytes); +#endif + } else if (ptype == IPLT_DSTLIST) { + printf("0"); + } + break; + + case 6: + if (ptype == IPLT_POOL) { + ip_pool_node_t *node = (ip_pool_node_t *)p; + + PRINTF("%s", familyname(node->ipn_addr.adf_family)); + } else if (ptype == IPLT_HASH) { + iphtent_t *node = (iphtent_t *)p; + + PRINTF("%s", familyname(node->ipe_family)); + } else if (ptype == IPLT_DSTLIST) { + ipf_dstnode_t *node = (ipf_dstnode_t *)p; + + a = &node->ipfd_dest.fd_addr; + PRINTF("%s", familyname(a->adf_family)); + } + break; + + default : + break; + } +} diff --git a/contrib/ipfilter/lib/printpoolnode.c b/contrib/ipfilter/lib/printpoolnode.c index 3327b8a5a43a..aa2aed96cad3 100644 --- a/contrib/ipfilter/lib/printpoolnode.c +++ b/contrib/ipfilter/lib/printpoolnode.c @@ -1,33 +1,51 @@ /* $FreeBSD$ */ /* - * Copyright (C) 2002-2005 by Darren Reed. + * Copyright (C) 2012 by Darren Reed. * * See the IPFILTER.LICENCE file for details on licencing. */ #include "ipf.h" -#define PRINTF (void)printf -#define FPRINTF (void)fprintf -ip_pool_node_t *printpoolnode(np, opts) -ip_pool_node_t *np; -int opts; +ip_pool_node_t * +printpoolnode(np, opts, fields) + ip_pool_node_t *np; + int opts; + wordtab_t *fields; { + int i; - if ((opts & OPT_DEBUG) == 0) { + if (fields != NULL) { + for (i = 0; fields[i].w_value != 0; i++) { + printpoolfield(np, IPLT_POOL, i); + if (fields[i + 1].w_value != 0) + printf("\t"); + } + printf("\n"); + } else if ((opts & OPT_DEBUG) == 0) { putchar(' '); if (np->ipn_info == 1) PRINTF("! "); - printip((u_32_t *)&np->ipn_addr.adf_addr.in4); - printmask((u_32_t *)&np->ipn_mask.adf_addr); + printip(np->ipn_addr.adf_family, + (u_32_t *)&np->ipn_addr.adf_addr.in4); + printmask(np->ipn_addr.adf_family, + (u_32_t *)&np->ipn_mask.adf_addr); } else { PRINTF("\tAddress: %s%s", np->ipn_info ? "! " : "", inet_ntoa(np->ipn_addr.adf_addr.in4)); - printmask((u_32_t *)&np->ipn_mask.adf_addr); - PRINTF("\t\tHits %lu\tName %s\tRef %d\n", - np->ipn_hits, np->ipn_name, np->ipn_ref); + printmask(np->ipn_addr.adf_family, + (u_32_t *)&np->ipn_mask.adf_addr); +#ifdef USE_QUAD_T + PRINTF("\n\t\tHits %"PRIu64"\tBytes %"PRIu64"\tName %s\tRef %d\n", + np->ipn_hits, np->ipn_bytes, + np->ipn_name, np->ipn_ref); +#else + PRINTF("\n\t\tHits %lu\tBytes %lu\tName %s\tRef %d\n", + np->ipn_hits, np->ipn_bytes, + np->ipn_name, np->ipn_ref); +#endif } return np->ipn_next; } diff --git a/contrib/ipfilter/lib/printportcmp.c b/contrib/ipfilter/lib/printportcmp.c index 6a1a461b6206..2a5bd0229201 100644 --- a/contrib/ipfilter/lib/printportcmp.c +++ b/contrib/ipfilter/lib/printportcmp.c @@ -1,29 +1,30 @@ /* $FreeBSD$ */ /* - * Copyright (C) 2000-2003 by Darren Reed. + * Copyright (C) 2012 by Darren Reed. * * See the IPFILTER.LICENCE file for details on licencing. * - * $Id: printportcmp.c,v 1.7.4.1 2006/06/16 17:21:14 darrenr Exp $ + * $Id$ */ #include "ipf.h" -void printportcmp(pr, frp) -int pr; -frpcmp_t *frp; +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, + PRINTF(" port %d %s %d", frp->frp_port, pcmp1[frp->frp_cmp], frp->frp_top); else if (frp->frp_cmp == FR_INCRANGE) - printf(" port %d:%d", frp->frp_port, frp->frp_top); + PRINTF(" port %d:%d", frp->frp_port, frp->frp_top); else - printf(" port %s %s", pcmp1[frp->frp_cmp], + PRINTF(" port %s %s", pcmp1[frp->frp_cmp], portname(pr, frp->frp_port)); } diff --git a/contrib/ipfilter/lib/printproto.c b/contrib/ipfilter/lib/printproto.c index e65ec1160826..d411bfa00421 100644 --- a/contrib/ipfilter/lib/printproto.c +++ b/contrib/ipfilter/lib/printproto.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2005 by Darren Reed. + * Copyright (C) 2012 by Darren Reed. * * See the IPFILTER.LICENCE file for details on licencing. */ @@ -8,44 +8,48 @@ #if !defined(lint) -static const char rcsid[] = "@(#)$Id: printproto.c,v 1.1.2.2 2006/06/16 17:21:14 darrenr Exp $"; +static const char rcsid[] = "@(#)$Id$"; #endif -void printproto(pr, p, np) -struct protoent *pr; -int p; -ipnat_t *np; +void +printproto(pr, p, np) + struct protoent *pr; + int p; + ipnat_t *np; { if (np != NULL) { if ((np->in_flags & IPN_TCPUDP) == IPN_TCPUDP) - printf("tcp/udp"); + PRINTF("tcp/udp"); else if (np->in_flags & IPN_TCP) - printf("tcp"); + PRINTF("tcp"); else if (np->in_flags & IPN_UDP) - printf("udp"); + PRINTF("udp"); else if (np->in_flags & IPN_ICMPQUERY) - printf("icmp"); + PRINTF("icmp"); #ifdef _AIX51 /* * To make up for "ip = 252" and "hopopt = 0" in /etc/protocols + * The IANA has doubled up on the definition of 0 - it is now + * also used for IPv6 hop-opts, so we can no longer rely on + * /etc/protocols providing the correct name->number mapping. */ - else if (np->in_p == 0) - printf("ip"); #endif + else if (np->in_pr[0] == 0) + PRINTF("ip"); else if (pr != NULL) - printf("%s", pr->p_name); + PRINTF("%s", pr->p_name); else - printf("%d", np->in_p); + PRINTF("%d", np->in_pr[0]); } else { #ifdef _AIX51 if (p == 0) - printf("ip"); + PRINTF("ip"); else #endif if (pr != NULL) - printf("%s", pr->p_name); + PRINTF("%s", pr->p_name); else - printf("%d", p); + PRINTF("%d", p); } } diff --git a/contrib/ipfilter/lib/printsbuf.c b/contrib/ipfilter/lib/printsbuf.c index f6c633c13fd6..efda99e856b8 100644 --- a/contrib/ipfilter/lib/printsbuf.c +++ b/contrib/ipfilter/lib/printsbuf.c @@ -1,12 +1,12 @@ /* $FreeBSD$ */ /* - * Copyright (C) 2002-2004 by Darren Reed. - * - * See the IPFILTER.LICENCE file for details on licencing. - * - * $Id: printsbuf.c,v 1.2.4.2 2006/06/16 17:21:14 darrenr Exp $ - */ + * Copyright (C) 2012 by Darren Reed. + * + * See the IPFILTER.LICENCE file for details on licencing. + * + * $Id$ + */ #ifdef IPFILTER_SCAN @@ -15,8 +15,9 @@ #include "ipf.h" #include "netinet/ip_scan.h" -void printsbuf(buf) -char *buf; +void +printsbuf(buf) + char *buf; { u_char *s; int i; @@ -25,8 +26,17 @@ char *buf; if (ISPRINT(*s)) putchar(*s); else - printf("\\%o", *s); + PRINTF("\\%o", *s); } } +#else +void printsbuf(char *buf); +void printsbuf(buf) + char *buf; +{ +#if 0 + buf = buf; /* gcc -Wextra */ +#endif +} #endif diff --git a/contrib/ipfilter/lib/printstate.c b/contrib/ipfilter/lib/printstate.c index a8777b2b59f2..fc85a70dcbe2 100644 --- a/contrib/ipfilter/lib/printstate.c +++ b/contrib/ipfilter/lib/printstate.c @@ -1,7 +1,7 @@ /* $FreeBSD$ */ /* - * Copyright (C) 2002-2005 by Darren Reed. + * Copyright (C) 2012 by Darren Reed. * * See the IPFILTER.LICENCE file for details on licencing. */ @@ -9,75 +9,102 @@ #include "ipf.h" #include "kmem.h" -#define PRINTF (void)printf -#define FPRINTF (void)fprintf -ipstate_t *printstate(sp, opts, now) -ipstate_t *sp; -int opts; -u_long now; +ipstate_t * +printstate(sp, opts, now) + ipstate_t *sp; + int opts; + u_long now; { + struct protoent *pr; synclist_t ipsync; - if (sp->is_phnext == NULL) - PRINTF("ORPHAN "); - PRINTF("%s -> ", hostname(sp->is_v, &sp->is_src.in4)); - PRINTF("%s pass %#x pr %d state %d/%d", - hostname(sp->is_v, &sp->is_dst.in4), sp->is_pass, sp->is_p, - sp->is_state[0], sp->is_state[1]); - if (opts & OPT_DEBUG) - PRINTF(" bkt %d ref %d", sp->is_hv, sp->is_ref); - PRINTF("\n\ttag %u ttl %lu", sp->is_tag, sp->is_die - now); + if ((opts & OPT_NORESOLVE) == 0) + pr = getprotobynumber(sp->is_p); + else + pr = NULL; + + PRINTF("%d:", sp->is_v); + if (pr != NULL) + PRINTF("%s", pr->p_name); + else + PRINTF("%d", sp->is_p); + + PRINTF(" src:%s", hostname(sp->is_family, &sp->is_src.in4)); + if (sp->is_p == IPPROTO_UDP || sp->is_p == IPPROTO_TCP) { + if (sp->is_flags & IS_WSPORT) + PRINTF(",*"); + else + PRINTF(",%d", ntohs(sp->is_sport)); + } + + PRINTF(" dst:%s", hostname(sp->is_family, &sp->is_dst.in4)); + if (sp->is_p == IPPROTO_UDP || sp->is_p == IPPROTO_TCP) { + if (sp->is_flags & IS_WDPORT) + PRINTF(",*"); + else + PRINTF(",%d", ntohs(sp->is_dport)); + } if (sp->is_p == IPPROTO_TCP) { - PRINTF("\n\t%hu -> %hu %x:%x %hu<<%d:%hu<<%d\n", - ntohs(sp->is_sport), ntohs(sp->is_dport), + PRINTF(" state:%d/%d", sp->is_state[0], sp->is_state[1]); + } + + PRINTF(" %ld", sp->is_die - now); + if (sp->is_phnext == NULL) + PRINTF(" ORPHAN"); + if (sp->is_flags & IS_CLONE) + PRINTF(" CLONE"); + putchar('\n'); + + if (sp->is_p == IPPROTO_TCP) { + PRINTF("\t%x:%x %hu<<%d:%hu<<%d\n", sp->is_send, sp->is_dend, sp->is_maxswin, sp->is_swinscale, sp->is_maxdwin, sp->is_dwinscale); - PRINTF("\tcmsk %04x smsk %04x s0 %08x/%08x\n", - sp->is_smsk[0], sp->is_smsk[1], - sp->is_s0[0], sp->is_s0[1]); - PRINTF("\tFWD:ISN inc %x sumd %x\n", - sp->is_isninc[0], sp->is_sumd[0]); - PRINTF("\tREV:ISN inc %x sumd %x\n", - sp->is_isninc[1], sp->is_sumd[1]); + if ((opts & OPT_VERBOSE) != 0) { + PRINTF("\tcmsk %04x smsk %04x isc %p s0 %08x/%08x\n", + sp->is_smsk[0], sp->is_smsk[1], sp->is_isc, + sp->is_s0[0], sp->is_s0[1]); + PRINTF("\tFWD: ISN inc %x sumd %x\n", + sp->is_isninc[0], sp->is_sumd[0]); + PRINTF("\tREV: ISN inc %x sumd %x\n", + sp->is_isninc[1], sp->is_sumd[1]); #ifdef IPFILTER_SCAN - PRINTF("\tsbuf[0] ["); - printsbuf(sp->is_sbuf[0]); - PRINTF("] sbuf[1] ["); - printsbuf(sp->is_sbuf[1]); - PRINTF("]\n"); + PRINTF("\tsbuf[0] ["); + printsbuf(sp->is_sbuf[0]); + PRINTF("] sbuf[1] ["); + printsbuf(sp->is_sbuf[1]); + PRINTF("]\n"); #endif - } else if (sp->is_p == IPPROTO_UDP) { - PRINTF(" %hu -> %hu\n", ntohs(sp->is_sport), - ntohs(sp->is_dport)); + } } else if (sp->is_p == IPPROTO_GRE) { - PRINTF(" call %hx/%hx\n", ntohs(sp->is_gre.gs_call[0]), + PRINTF("\tcall %hx/%hx\n", ntohs(sp->is_gre.gs_call[0]), ntohs(sp->is_gre.gs_call[1])); } else if (sp->is_p == IPPROTO_ICMP #ifdef USE_INET6 || sp->is_p == IPPROTO_ICMPV6 #endif - ) - PRINTF(" id %hu seq %hu type %d\n", sp->is_icmp.ici_id, + ) { + PRINTF("\tid %hu seq %hu type %d\n", sp->is_icmp.ici_id, sp->is_icmp.ici_seq, sp->is_icmp.ici_type); + } #ifdef USE_QUAD_T - PRINTF("\tforward: pkts in %lld bytes in %lld pkts out %lld bytes out %lld\n\tbackward: pkts in %lld bytes in %lld pkts out %lld bytes out %lld\n", + PRINTF("\tFWD: IN pkts %"PRIu64" bytes %"PRIu64" OUT pkts %"PRIu64" bytes %"PRIu64"\n\tREV: IN pkts %"PRIu64" bytes %"PRIu64" OUT pkts %"PRIu64" bytes %"PRIu64"\n", sp->is_pkts[0], sp->is_bytes[0], sp->is_pkts[1], sp->is_bytes[1], sp->is_pkts[2], sp->is_bytes[2], sp->is_pkts[3], sp->is_bytes[3]); #else - PRINTF("\tforward: pkts in %ld bytes in %ld pkts out %ld bytes out %ld\n\tbackward: pkts in %ld bytes in %ld pkts out %ld bytes out %ld\n", + PRINTF("\tFWD: IN pkts %lu bytes %lu OUT pkts %lu bytes %lu\n\tREV: IN pkts %lu bytes %lu OUT pkts %lu bytes %lu\n", sp->is_pkts[0], sp->is_bytes[0], sp->is_pkts[1], sp->is_bytes[1], sp->is_pkts[2], sp->is_bytes[2], sp->is_pkts[3], sp->is_bytes[3]); #endif - PRINTF("\t"); + PRINTF("\ttag %u pass %#x = ", sp->is_tag, sp->is_pass); /* * Print out bits set in the result code for the state being @@ -135,22 +162,31 @@ u_long now; /* a given; no? */ if (sp->is_pass & FR_KEEPSTATE) { PRINTF(" keep state"); - if (sp->is_pass & FR_STATESYNC) - PRINTF(" ( sync )"); + if (sp->is_pass & (FR_STATESYNC|FR_STSTRICT|FR_STLOOSE)) { + PRINTF(" ("); + if (sp->is_pass & FR_STATESYNC) + PRINTF(" sync"); + if (sp->is_pass & FR_STSTRICT) + PRINTF(" strict"); + if (sp->is_pass & FR_STLOOSE) + PRINTF(" loose"); + PRINTF(" )"); + } } - PRINTF("\tIPv%d", sp->is_v); PRINTF("\n"); - PRINTF("\tpkt_flags & %x(%x) = %x,\t", - sp->is_flags & 0xf, sp->is_flags, - sp->is_flags >> 4); - PRINTF("\tpkt_options & %x = %x, %x = %x \n", sp->is_optmsk[0], - sp->is_opt[0], sp->is_optmsk[1], sp->is_opt[1]); - PRINTF("\tpkt_security & %x = %x, pkt_auth & %x = %x\n", - sp->is_secmsk, sp->is_sec, sp->is_authmsk, - sp->is_auth); - PRINTF("\tis_flx %#x %#x %#x %#x\n", sp->is_flx[0][0], sp->is_flx[0][1], - sp->is_flx[1][0], sp->is_flx[1][1]); + if ((opts & OPT_VERBOSE) != 0) { + PRINTF("\tref %d", sp->is_ref); + PRINTF(" pkt_flags & %x(%x) = %x\n", + sp->is_flags & 0xf, sp->is_flags, sp->is_flags >> 4); + PRINTF("\tpkt_options & %x = %x, %x = %x \n", sp->is_optmsk[0], + sp->is_opt[0], sp->is_optmsk[1], sp->is_opt[1]); + PRINTF("\tpkt_security & %x = %x, pkt_auth & %x = %x\n", + sp->is_secmsk, sp->is_sec, sp->is_authmsk, + sp->is_auth); + PRINTF("\tis_flx %#x %#x %#x %#x\n", sp->is_flx[0][0], + sp->is_flx[0][1], sp->is_flx[1][0], sp->is_flx[1][1]); + } PRINTF("\tinterfaces: in %s[%s", getifname(sp->is_ifp[0]), sp->is_ifname[0]); if (opts & OPT_DEBUG) @@ -169,20 +205,19 @@ u_long now; PRINTF("/%p", sp->is_ifp[3]); PRINTF("]\n"); + PRINTF("\tSync status: "); if (sp->is_sync != NULL) { - - if (kmemcpy((char *)&ipsync, (u_long)sp->is_sync, sizeof(ipsync))) { - - PRINTF("\tSync status: status could not be retrieved\n"); + if (kmemcpy((char *)&ipsync, (u_long)sp->is_sync, + sizeof(ipsync))) { + PRINTF("status could not be retrieved\n"); return NULL; } - PRINTF("\tSync status: idx %d num %d v %d pr %d rev %d\n", + PRINTF("idx %d num %d v %d pr %d rev %d\n", ipsync.sl_idx, ipsync.sl_num, ipsync.sl_v, ipsync.sl_p, ipsync.sl_rev); - } else { - PRINTF("\tSync status: not synchronized\n"); + PRINTF("not synchronized\n"); } return sp->is_next; diff --git a/contrib/ipfilter/lib/printstatefields.c b/contrib/ipfilter/lib/printstatefields.c new file mode 100644 index 000000000000..5632d8416c47 --- /dev/null +++ b/contrib/ipfilter/lib/printstatefields.c @@ -0,0 +1,358 @@ +/* + * Copyright (C) 2012 by Darren Reed. + * + * See the IPFILTER.LICENCE file for details on licencing. + * + * $Id: printstatefields.c,v 1.4.2.2 2012/01/26 05:44:26 darren_r Exp $ + */ + +#include "ipf.h" + +wordtab_t statefields[] = { + { "all", -2 }, + { "ifp0", 1 }, + { "ifp1", 2 }, + { "ifp2", 3 }, + { "ifp3", 4 }, + { "ifname0", 5 }, + { "ifname1", 6 }, + { "ifname2", 7 }, + { "ifname3", 8 }, + { "pkts0", 9 }, + { "pkts1", 10 }, + { "pkts2", 11 }, + { "pkts3", 12 }, + { "bytes0", 13 }, + { "bytes1", 14 }, + { "bytes2", 15 }, + { "bytes3", 16 }, + { "state0", 17 }, + { "state1", 18 }, + { "age0", 19 }, + { "age1", 20 }, + { "ref", 21 }, + { "isn0", 22 }, + { "isn1", 23 }, + { "sumd0", 24 }, + { "sumd1", 25 }, + { "src", 26 }, + { "dst", 27 }, + { "sport", 28 }, + { "dport", 29 }, + { "icmptype", 30 }, + { "-", 31 }, + { "pass", 32 }, + { "proto", 33 }, + { "version", 34 }, + { "hash", 35 }, + { "tag", 36 }, + { "flags", 37 }, + { "rulen", 38 }, + { "group", 39 }, + { "flx0", 40 }, + { "flx1", 41 }, + { "flx2", 42 }, + { "flx3", 43 }, + { "opt0", 44 }, + { "opt1", 45 }, + { "optmsk0", 46 }, + { "optmsk1", 47 }, + { "sec", 48 }, + { "secmsk", 49 }, + { "auth", 50 }, + { "authmsk", 51 }, + { "icmppkts0", 52 }, + { "icmppkts1", 53 }, + { "icmppkts2", 54 }, + { "icmppkts3", 55 }, + { NULL, 0 } +}; + + +void +printstatefield(sp, fieldnum) + ipstate_t *sp; + int fieldnum; +{ + int i; + + switch (fieldnum) + { + case -2 : + for (i = 1; statefields[i].w_word != NULL; i++) { + if (statefields[i].w_value > 0) { + printstatefield(sp, i); + if (statefields[i + 1].w_value > 0) + putchar('\t'); + } + } + break; + + case 1: + PRINTF("%#lx", (u_long)sp->is_ifp[0]); + break; + + case 2: + PRINTF("%#lx", (u_long)sp->is_ifp[1]); + break; + + case 3: + PRINTF("%#lx", (u_long)sp->is_ifp[2]); + break; + + case 4: + PRINTF("%#lx", (u_long)sp->is_ifp[3]); + break; + + case 5: + PRINTF("%s", sp->is_ifname[0]); + break; + + case 6: + PRINTF("%s", sp->is_ifname[1]); + break; + + case 7: + PRINTF("%s", sp->is_ifname[2]); + break; + + case 8: + PRINTF("%s", sp->is_ifname[3]); + break; + + case 9: +#ifdef USE_QUAD_T + PRINTF("%"PRIu64"", sp->is_pkts[0]); +#else + PRINTF("%lu", sp->is_pkts[0]); +#endif + break; + + case 10: +#ifdef USE_QUAD_T + PRINTF("%"PRIu64"", sp->is_pkts[1]); +#else + PRINTF("%lu", sp->is_pkts[1]); +#endif + break; + + case 11: +#ifdef USE_QUAD_T + PRINTF("%"PRIu64"", sp->is_pkts[2]); +#else + PRINTF("%lu", sp->is_pkts[2]); +#endif + break; + + case 12: +#ifdef USE_QUAD_T + PRINTF("%"PRIu64"", sp->is_pkts[3]); +#else + PRINTF("%lu", sp->is_pkts[3]); +#endif + break; + + case 13: +#ifdef USE_QUAD_T + PRINTF("%"PRIu64"", sp->is_bytes[0]); +#else + PRINTF("%lu", sp->is_bytes[0]); +#endif + break; + + case 14: +#ifdef USE_QUAD_T + PRINTF("%"PRIu64"", sp->is_bytes[1]); +#else + PRINTF("%lu", sp->is_bytes[1]); +#endif + break; + + case 15: +#ifdef USE_QUAD_T + PRINTF("%"PRIu64"", sp->is_bytes[2]); +#else + PRINTF("%lu", sp->is_bytes[2]); +#endif + break; + + case 16: +#ifdef USE_QUAD_T + PRINTF("%"PRIu64"", sp->is_bytes[3]); +#else + PRINTF("%lu", sp->is_bytes[3]); +#endif + break; + + case 17: + PRINTF("%d", sp->is_state[0]); + break; + + case 18: + PRINTF("%d", sp->is_state[1]); + break; + + case 19: + PRINTF("%d", sp->is_frage[0]); + break; + + case 20: + PRINTF("%d", sp->is_frage[1]); + break; + + case 21: + PRINTF("%d", sp->is_ref); + break; + + case 22: + PRINTF("%d", sp->is_isninc[0]); + break; + + case 23: + PRINTF("%d", sp->is_isninc[1]); + break; + + case 24: + PRINTF("%hd", sp->is_sumd[0]); + break; + + case 25: + PRINTF("%hd", sp->is_sumd[1]); + break; + + case 26: + PRINTF("%s", hostname(sp->is_v, &sp->is_src.in4)); + break; + + case 27: + PRINTF("%s", hostname(sp->is_v, &sp->is_dst.in4)); + break; + + case 28: + PRINTF("%hu", ntohs(sp->is_sport)); + break; + + case 29: + PRINTF("%hu", ntohs(sp->is_dport)); + break; + + case 30: + PRINTF("%d", sp->is_type); + break; + + case 32: + PRINTF("%#x", sp->is_pass); + break; + + case 33: + PRINTF("%d", sp->is_p); + break; + + case 34: + PRINTF("%d", sp->is_v); + break; + + case 35: + PRINTF("%d", sp->is_hv); + break; + + case 36: + PRINTF("%d", sp->is_tag); + break; + + case 37: + PRINTF("%#x", sp->is_flags); + break; + + case 38: + PRINTF("%d", sp->is_rulen); + break; + + case 39: + PRINTF("%s", sp->is_group); + break; + + case 40: + PRINTF("%#x", sp->is_flx[0][0]); + break; + + case 41: + PRINTF("%#x", sp->is_flx[0][1]); + break; + + case 42: + PRINTF("%#x", sp->is_flx[1][0]); + break; + + case 43: + PRINTF("%#x", sp->is_flx[1][1]); + break; + + case 44: + PRINTF("%#x", sp->is_opt[0]); + break; + + case 45: + PRINTF("%#x", sp->is_opt[1]); + break; + + case 46: + PRINTF("%#x", sp->is_optmsk[0]); + break; + + case 47: + PRINTF("%#x", sp->is_optmsk[1]); + break; + + case 48: + PRINTF("%#x", sp->is_sec); + break; + + case 49: + PRINTF("%#x", sp->is_secmsk); + break; + + case 50: + PRINTF("%#x", sp->is_auth); + break; + + case 51: + PRINTF("%#x", sp->is_authmsk); + break; + + case 52: +#ifdef USE_QUAD_T + PRINTF("%"PRIu64"", sp->is_icmppkts[0]); +#else + PRINTF("%lu", sp->is_icmppkts[0]); +#endif + break; + + case 53: +#ifdef USE_QUAD_T + PRINTF("%"PRIu64"", sp->is_icmppkts[1]); +#else + PRINTF("%lu", sp->is_icmppkts[1]); +#endif + break; + + case 54: +#ifdef USE_QUAD_T + PRINTF("%"PRIu64"", sp->is_icmppkts[2]); +#else + PRINTF("%lu", sp->is_icmppkts[2]); +#endif + break; + + case 55: +#ifdef USE_QUAD_T + PRINTF("%"PRIu64"", sp->is_icmppkts[3]); +#else + PRINTF("%lu", sp->is_icmppkts[3]); +#endif + break; + + default: + break; + } +} diff --git a/contrib/ipfilter/lib/printtcpflags.c b/contrib/ipfilter/lib/printtcpflags.c new file mode 100644 index 000000000000..9860780307a8 --- /dev/null +++ b/contrib/ipfilter/lib/printtcpflags.c @@ -0,0 +1,30 @@ +#include "ipf.h" + + +void +printtcpflags(tcpf, tcpfm) + u_32_t tcpf, tcpfm; +{ + u_char *t; + char *s; + + if (tcpf & ~TCPF_ALL) { + PRINTF("0x%x", tcpf); + } else { + for (s = flagset, t = flags; *s; s++, t++) { + if (tcpf & *t) + (void)putchar(*s); + } + } + + if (tcpfm) { + (void)putchar('/'); + if (tcpfm & ~TCPF_ALL) { + PRINTF("0x%x", tcpfm); + } else { + for (s = flagset, t = flags; *s; s++, t++) + if (tcpfm & *t) + (void)putchar(*s); + } + } +} diff --git a/contrib/ipfilter/lib/printtqtable.c b/contrib/ipfilter/lib/printtqtable.c index 67adb53b1c34..ffb512dac42e 100644 --- a/contrib/ipfilter/lib/printtqtable.c +++ b/contrib/ipfilter/lib/printtqtable.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2007 by Darren Reed. + * Copyright (C) 2012 by Darren Reed. * * See the IPFILTER.LICENCE file for details on licencing. */ @@ -9,17 +9,18 @@ #include "ipf.h" -void printtqtable(table) -ipftq_t *table; +void +printtqtable(table) + ipftq_t *table; { int i; - printf("TCP Entries per state\n"); + PRINTF("TCP Entries per state\n"); for (i = 0; i < IPF_TCP_NSTATES; i++) - printf(" %5d", i); - printf("\n"); + PRINTF(" %5d", i); + PRINTF("\n"); for (i = 0; i < IPF_TCP_NSTATES; i++) - printf(" %5d", table[i].ifq_ref - 1); - printf("\n"); + PRINTF(" %5d", table[i].ifq_ref - 1); + PRINTF("\n"); } diff --git a/contrib/ipfilter/lib/printtunable.c b/contrib/ipfilter/lib/printtunable.c index aa7ae5d0e578..aa82841b2fe1 100644 --- a/contrib/ipfilter/lib/printtunable.c +++ b/contrib/ipfilter/lib/printtunable.c @@ -1,29 +1,30 @@ /* $FreeBSD$ */ /* - * Copyright (C) 2003 by Darren Reed. - * - * See the IPFILTER.LICENCE file for details on licencing. - * - * $Id: printtunable.c,v 1.1.4.1 2006/06/16 17:21:15 darrenr Exp $ - */ + * Copyright (C) 2012 by Darren Reed. + * + * See the IPFILTER.LICENCE file for details on licencing. + * + * $Id$ + */ #include "ipf.h" -void printtunable(tup) -ipftune_t *tup; +void +printtunable(tup) + ipftune_t *tup; { - printf("%s\tmin %#lx\tmax %#lx\tcurrent ", + PRINTF("%s\tmin %lu\tmax %lu\tcurrent ", tup->ipft_name, tup->ipft_min, tup->ipft_max); if (tup->ipft_sz == sizeof(u_long)) - printf("%lu\n", tup->ipft_vlong); + PRINTF("%lu\n", tup->ipft_vlong); else if (tup->ipft_sz == sizeof(u_int)) - printf("%u\n", tup->ipft_vint); + PRINTF("%u\n", tup->ipft_vint); else if (tup->ipft_sz == sizeof(u_short)) - printf("%hu\n", tup->ipft_vshort); + PRINTF("%hu\n", tup->ipft_vshort); else if (tup->ipft_sz == sizeof(u_char)) - printf("%u\n", (u_int)tup->ipft_vchar); + PRINTF("%u\n", (u_int)tup->ipft_vchar); else { - printf("sz = %d\n", tup->ipft_sz); + PRINTF("sz = %d\n", tup->ipft_sz); } } diff --git a/contrib/ipfilter/lib/printunit.c b/contrib/ipfilter/lib/printunit.c new file mode 100644 index 000000000000..bac3d45d34c5 --- /dev/null +++ b/contrib/ipfilter/lib/printunit.c @@ -0,0 +1,47 @@ +/* + * Copyright (C) 2012 by Darren Reed. + * + * See the IPFILTER.LICENCE file for details on licencing. + */ + +#include "ipf.h" + + +void +printunit(unit) + int unit; +{ + + switch (unit) + { + case IPL_LOGIPF : + PRINTF("ipf"); + break; + case IPL_LOGNAT : + PRINTF("nat"); + break; + case IPL_LOGSTATE : + PRINTF("state"); + break; + case IPL_LOGAUTH : + PRINTF("auth"); + break; + case IPL_LOGSYNC : + PRINTF("sync"); + break; + case IPL_LOGSCAN : + PRINTF("scan"); + break; + case IPL_LOGLOOKUP : + PRINTF("lookup"); + break; + case IPL_LOGCOUNT : + PRINTF("count"); + break; + case IPL_LOGALL : + PRINTF("all"); + break; + default : + PRINTF("unknown(%d)", unit); + } +} diff --git a/contrib/ipfilter/lib/remove_hash.c b/contrib/ipfilter/lib/remove_hash.c index 297db4827d73..a60c1fddc7e9 100644 --- a/contrib/ipfilter/lib/remove_hash.c +++ b/contrib/ipfilter/lib/remove_hash.c @@ -1,11 +1,11 @@ /* $FreeBSD$ */ /* - * Copyright (C) 2003 by Darren Reed. + * Copyright (C) 2012 by Darren Reed. * * See the IPFILTER.LICENCE file for details on licencing. * - * $Id: remove_hash.c,v 1.1.4.1 2006/06/16 17:21:16 darrenr Exp $ + * $Id$ */ #include @@ -14,19 +14,16 @@ #include "netinet/ip_lookup.h" #include "netinet/ip_htable.h" -static int hashfd = -1; - -int remove_hash(iphp, iocfunc) -iphtable_t *iphp; -ioctlfunc_t iocfunc; +int +remove_hash(iphp, iocfunc) + iphtable_t *iphp; + ioctlfunc_t iocfunc; { iplookupop_t op; iphtable_t iph; - if ((hashfd == -1) && ((opts & OPT_DONOTHING) == 0)) - hashfd = open(IPLOOKUP_NAME, O_RDWR); - if ((hashfd == -1) && ((opts & OPT_DONOTHING) == 0)) + if (pool_open() == -1) return -1; op.iplo_type = IPLT_HASH; @@ -43,11 +40,11 @@ ioctlfunc_t iocfunc; strncpy(iph.iph_name, iphp->iph_name, sizeof(iph.iph_name)); iph.iph_flags = iphp->iph_flags; - if ((*iocfunc)(hashfd, SIOCLOOKUPDELTABLE, &op)) + if (pool_ioctl(iocfunc, SIOCLOOKUPDELTABLE, &op)) { if ((opts & OPT_DONOTHING) == 0) { - perror("remove_hash:SIOCLOOKUPDELTABLE"); - return -1; + return ipf_perror_fd(pool_fd(), iocfunc, + "remove lookup hash table"); } - + } return 0; } diff --git a/contrib/ipfilter/lib/remove_hashnode.c b/contrib/ipfilter/lib/remove_hashnode.c index 47a19dcaa62f..58e9125015b6 100644 --- a/contrib/ipfilter/lib/remove_hashnode.c +++ b/contrib/ipfilter/lib/remove_hashnode.c @@ -1,11 +1,11 @@ /* $FreeBSD$ */ /* - * Copyright (C) 2003 by Darren Reed. + * Copyright (C) 2012 by Darren Reed. * * See the IPFILTER.LICENCE file for details on licencing. * - * $Id: remove_hashnode.c,v 1.1.4.1 2006/06/16 17:21:16 darrenr Exp $ + * $Id$ */ #include @@ -14,21 +14,18 @@ #include "netinet/ip_lookup.h" #include "netinet/ip_htable.h" -static int hashfd = -1; - -int remove_hashnode(unit, name, node, iocfunc) -int unit; -char *name; -iphtent_t *node; -ioctlfunc_t iocfunc; +int +remove_hashnode(unit, name, node, iocfunc) + int unit; + char *name; + iphtent_t *node; + ioctlfunc_t iocfunc; { iplookupop_t op; iphtent_t ipe; - if ((hashfd == -1) && ((opts & OPT_DONOTHING) == 0)) - hashfd = open(IPLOOKUP_NAME, O_RDWR); - if ((hashfd == -1) && ((opts & OPT_DONOTHING) == 0)) + if (pool_open() == -1) return -1; op.iplo_type = IPLT_HASH; @@ -49,10 +46,11 @@ ioctlfunc_t iocfunc; printf("%s\n", inet_ntoa(ipe.ipe_mask.in4)); } - if ((*iocfunc)(hashfd, SIOCLOOKUPDELNODE, &op)) + if (pool_ioctl(iocfunc, SIOCLOOKUPDELNODE, &op)) { if (!(opts & OPT_DONOTHING)) { - perror("remove_hash:SIOCLOOKUPDELNODE"); - return -1; + return ipf_perror_fd(pool_fd(), iocfunc, + "remove lookup hash node"); } + } return 0; } diff --git a/contrib/ipfilter/lib/remove_pool.c b/contrib/ipfilter/lib/remove_pool.c index 1e7fe5f16cdf..8e7554963afd 100644 --- a/contrib/ipfilter/lib/remove_pool.c +++ b/contrib/ipfilter/lib/remove_pool.c @@ -1,11 +1,11 @@ /* $FreeBSD$ */ /* - * Copyright (C) 2003 by Darren Reed. + * Copyright (C) 2012 by Darren Reed. * * See the IPFILTER.LICENCE file for details on licencing. * - * $Id: remove_pool.c,v 1.1.4.1 2006/06/16 17:21:16 darrenr Exp $ + * $Id$ */ #include @@ -14,19 +14,16 @@ #include "netinet/ip_lookup.h" #include "netinet/ip_htable.h" -static int poolfd = -1; - -int remove_pool(poolp, iocfunc) -ip_pool_t *poolp; -ioctlfunc_t iocfunc; +int +remove_pool(poolp, iocfunc) + ip_pool_t *poolp; + ioctlfunc_t iocfunc; { iplookupop_t op; ip_pool_t pool; - if ((poolfd == -1) && ((opts & OPT_DONOTHING) == 0)) - poolfd = open(IPLOOKUP_NAME, O_RDWR); - if ((poolfd == -1) && ((opts & OPT_DONOTHING) == 0)) + if (pool_open() == -1) return -1; op.iplo_type = IPLT_POOL; @@ -40,11 +37,11 @@ ioctlfunc_t iocfunc; strncpy(pool.ipo_name, poolp->ipo_name, sizeof(pool.ipo_name)); pool.ipo_flags = poolp->ipo_flags; - if ((*iocfunc)(poolfd, SIOCLOOKUPDELTABLE, &op)) + if (pool_ioctl(iocfunc, SIOCLOOKUPDELTABLE, &op)) { if ((opts & OPT_DONOTHING) == 0) { - perror("remove_pool:SIOCLOOKUPDELTABLE"); - return -1; + return ipf_perror_fd(pool_fd(), iocfunc, + "delete lookup pool"); } - + } return 0; } diff --git a/contrib/ipfilter/lib/remove_poolnode.c b/contrib/ipfilter/lib/remove_poolnode.c index c80ff7093c67..0b78118ec582 100644 --- a/contrib/ipfilter/lib/remove_poolnode.c +++ b/contrib/ipfilter/lib/remove_poolnode.c @@ -1,11 +1,11 @@ /* $FreeBSD$ */ /* - * Copyright (C) 2003 by Darren Reed. + * Copyright (C) 2012 by Darren Reed. * * See the IPFILTER.LICENCE file for details on licencing. * - * $Id: remove_poolnode.c,v 1.3.2.1 2006/06/16 17:21:16 darrenr Exp $ + * $Id$ */ #include @@ -14,21 +14,18 @@ #include "netinet/ip_lookup.h" #include "netinet/ip_pool.h" -static int poolfd = -1; - -int remove_poolnode(unit, name, node, iocfunc) -int unit; -char *name; -ip_pool_node_t *node; -ioctlfunc_t iocfunc; +int +remove_poolnode(unit, name, node, iocfunc) + int unit; + char *name; + ip_pool_node_t *node; + ioctlfunc_t iocfunc; { ip_pool_node_t pn; iplookupop_t op; - if ((poolfd == -1) && ((opts & OPT_DONOTHING) == 0)) - poolfd = open(IPLOOKUP_NAME, O_RDWR); - if ((poolfd == -1) && ((opts & OPT_DONOTHING) == 0)) + if (pool_open() == -1) return -1; op.iplo_unit = unit; @@ -46,10 +43,10 @@ ioctlfunc_t iocfunc; pn.ipn_info = node->ipn_info; strncpy(pn.ipn_name, node->ipn_name, sizeof(pn.ipn_name)); - if ((*iocfunc)(poolfd, SIOCLOOKUPDELNODE, &op)) { + if (pool_ioctl(iocfunc, SIOCLOOKUPDELNODE, &op)) { if ((opts & OPT_DONOTHING) == 0) { - perror("remove_pool:SIOCLOOKUPDELNODE"); - return -1; + return ipf_perror_fd(pool_fd(), iocfunc, + "remove lookup pool node"); } } diff --git a/contrib/ipfilter/lib/resetlexer.c b/contrib/ipfilter/lib/resetlexer.c index 8ea83f101a23..558db98603ed 100644 --- a/contrib/ipfilter/lib/resetlexer.c +++ b/contrib/ipfilter/lib/resetlexer.c @@ -1,12 +1,12 @@ /* $FreeBSD$ */ /* - * Copyright (C) 2002 by Darren Reed. - * - * See the IPFILTER.LICENCE file for details on licencing. - * - * $Id: resetlexer.c,v 1.1.4.1 2006/06/16 17:21:16 darrenr Exp $ - */ + * Copyright (C) 2012 by Darren Reed. + * + * See the IPFILTER.LICENCE file for details on licencing. + * + * $Id$ + */ #include "ipf.h" diff --git a/contrib/ipfilter/lib/rwlock_emul.c b/contrib/ipfilter/lib/rwlock_emul.c index 1ee247570082..24d00a5772f5 100644 --- a/contrib/ipfilter/lib/rwlock_emul.c +++ b/contrib/ipfilter/lib/rwlock_emul.c @@ -1,21 +1,21 @@ /* $FreeBSD$ */ /* - * Copyright (C) 2003 by Darren Reed. - * - * See the IPFILTER.LICENCE file for details on licencing. - * - * $Id: rwlock_emul.c,v 1.1.4.1 2006/06/16 17:21:17 darrenr Exp $ - */ + * Copyright (C) 2012 by Darren Reed. + * + * See the IPFILTER.LICENCE file for details on licencing. + * + * $Id$ + */ #include "ipf.h" #define EMM_MAGIC 0x97dd8b3a void eMrwlock_read_enter(rw, file, line) -eMrwlock_t *rw; -char *file; -int line; + eMrwlock_t *rw; + char *file; + int line; { if (rw->eMrw_magic != EMM_MAGIC) { fprintf(stderr, "%s:eMrwlock_read_enter(%p): bad magic: %#x\n", @@ -35,9 +35,9 @@ int line; void eMrwlock_write_enter(rw, file, line) -eMrwlock_t *rw; -char *file; -int line; + eMrwlock_t *rw; + char *file; + int line; { if (rw->eMrw_magic != EMM_MAGIC) { fprintf(stderr, "%s:eMrwlock_write_enter(%p): bad magic: %#x\n", @@ -57,9 +57,9 @@ int line; void eMrwlock_downgrade(rw, file, line) -eMrwlock_t *rw; -char *file; -int line; + eMrwlock_t *rw; + char *file; + int line; { if (rw->eMrw_magic != EMM_MAGIC) { fprintf(stderr, "%s:eMrwlock_write_enter(%p): bad magic: %#x\n", @@ -80,7 +80,7 @@ int line; void eMrwlock_exit(rw) -eMrwlock_t *rw; + eMrwlock_t *rw; { if (rw->eMrw_magic != EMM_MAGIC) { fprintf(stderr, "%s:eMrwlock_exit(%p): bad magic: %#x\n", @@ -101,9 +101,11 @@ eMrwlock_t *rw; } +static int initcount = 0; + void eMrwlock_init(rw, who) -eMrwlock_t *rw; -char *who; + eMrwlock_t *rw; + char *who; { if (rw->eMrw_magic == EMM_MAGIC) { /* safe bet ? */ fprintf(stderr, @@ -118,16 +120,26 @@ char *who; rw->eMrw_owner = strdup(who); else rw->eMrw_owner = NULL; + initcount++; } void eMrwlock_destroy(rw) -eMrwlock_t *rw; + eMrwlock_t *rw; { if (rw->eMrw_magic != EMM_MAGIC) { fprintf(stderr, "%s:eMrwlock_destroy(%p): bad magic: %#x\n", rw->eMrw_owner, rw, rw->eMrw_magic); abort(); } + if (rw->eMrw_owner != NULL) + free(rw->eMrw_owner); memset(rw, 0xa5, sizeof(*rw)); + initcount--; +} + +void ipf_rwlock_clean() +{ + if (initcount != 0) + abort(); } diff --git a/contrib/ipfilter/lib/save_execute.c b/contrib/ipfilter/lib/save_execute.c new file mode 100644 index 000000000000..65caca46bc76 --- /dev/null +++ b/contrib/ipfilter/lib/save_execute.c @@ -0,0 +1,80 @@ +#include "ipf.h" +#include "ipmon.h" + +static void *execute_parse __P((char **)); +static void execute_destroy __P((void *)); +static int execute_send __P((void *, ipmon_msg_t *)); +static void execute_print __P((void *)); + +typedef struct execute_opts_s { + char *path; +} execute_opts_t; + +ipmon_saver_t executesaver = { + "execute", + execute_destroy, + NULL, /* dup */ + NULL, /* match */ + execute_parse, + execute_print, + execute_send +}; + + +static void * +execute_parse(char **strings) +{ + execute_opts_t *ctx; + + ctx = calloc(1, sizeof(*ctx)); + + if (ctx != NULL && strings[0] != NULL && strings[0][0] != '\0') { + ctx->path = strdup(strings[0]); + + } else { + free(ctx); + return NULL; + } + + return ctx; +} + + +static void +execute_print(ctx) + void *ctx; +{ + execute_opts_t *exe = ctx; + + printf("%s", exe->path); +} + + +static void +execute_destroy(ctx) + void *ctx; +{ + execute_opts_t *exe = ctx; + + if (exe != NULL) + free(exe->path); + free(exe); +} + + +static int +execute_send(ctx, msg) + void *ctx; + ipmon_msg_t *msg; +{ + execute_opts_t *exe = ctx; + FILE *fp; + + fp = popen(exe->path, "w"); + if (fp != NULL) { + fwrite(msg->imm_msg, msg->imm_msglen, 1, fp); + pclose(fp); + } + return 0; +} + diff --git a/contrib/ipfilter/lib/save_file.c b/contrib/ipfilter/lib/save_file.c new file mode 100644 index 000000000000..b852bd601982 --- /dev/null +++ b/contrib/ipfilter/lib/save_file.c @@ -0,0 +1,130 @@ +#include "ipf.h" +#include "ipmon.h" + +static void *file_parse __P((char **)); +static void file_destroy __P((void *)); +static int file_send __P((void *, ipmon_msg_t *)); +static void file_print __P((void *)); +static int file_match __P((void *, void *)); +static void *file_dup __P((void *)); + +typedef struct file_opts_s { + FILE *fp; + int raw; + char *path; + int ref; +} file_opts_t; + +ipmon_saver_t filesaver = { + "file", + file_destroy, + file_dup, + file_match, + file_parse, + file_print, + file_send +}; + + +static void * +file_parse(strings) + char **strings; +{ + file_opts_t *ctx; + + ctx = calloc(1, sizeof(*ctx)); + if (ctx == NULL) + return NULL; + + if (strings[0] != NULL && strings[0][0] != '\0') { + ctx->ref = 1; + if (!strncmp(strings[0], "raw://", 6)) { + ctx->raw = 1; + ctx->path = strdup(strings[0] + 6); + ctx->fp = fopen(ctx->path, "ab"); + } else if (!strncmp(strings[0], "file://", 7)) { + ctx->path = strdup(strings[0] + 7); + ctx->fp = fopen(ctx->path, "a"); + } else { + free(ctx); + ctx = NULL; + } + } else { + free(ctx); + ctx = NULL; + } + + return ctx; +} + + +static int +file_match(ctx1, ctx2) + void *ctx1, *ctx2; +{ + file_opts_t *f1 = ctx1, *f2 = ctx2; + + if (f1->raw != f2->raw) + return 1; + if (strcmp(f1->path, f2->path)) + return 1; + return 0; +} + + +static void * +file_dup(ctx) + void *ctx; +{ + file_opts_t *f = ctx; + + f->ref++; + return f; +} + + +static void +file_print(ctx) + void *ctx; +{ + file_opts_t *file = ctx; + + if (file->raw) + printf("raw://"); + else + printf("file://"); + printf("%s", file->path); +} + + +static void +file_destroy(ctx) + void *ctx; +{ + file_opts_t *file = ctx; + + file->ref--; + if (file->ref > 0) + return; + + if (file->path != NULL) + free(file->path); + free(file); +} + + +static int +file_send(ctx, msg) + void *ctx; + ipmon_msg_t *msg; +{ + file_opts_t *file = ctx; + + if (file->raw) { + fwrite(msg->imm_data, msg->imm_dsize, 1, file->fp); + } else { + fprintf(file->fp, "%s", msg->imm_msg); + } + return 0; +} + diff --git a/contrib/ipfilter/lib/save_nothing.c b/contrib/ipfilter/lib/save_nothing.c new file mode 100644 index 000000000000..d25ab519bce1 --- /dev/null +++ b/contrib/ipfilter/lib/save_nothing.c @@ -0,0 +1,62 @@ +#include "ipf.h" +#include "ipmon.h" + +static void *nothing_parse __P((char **)); +static void nothing_destroy __P((void *)); +static int nothing_send __P((void *, ipmon_msg_t *)); + +typedef struct nothing_opts_s { + FILE *fp; + int raw; + char *path; +} nothing_opts_t; + +ipmon_saver_t nothingsaver = { + "nothing", + nothing_destroy, + NULL, /* dup */ + NULL, /* match */ + nothing_parse, + NULL, /* print */ + nothing_send +}; + + +static void * +nothing_parse(char **strings) +{ + void *ctx; + +#if 0 + strings = strings; /* gcc -Wextra */ +#endif + + ctx = calloc(1, sizeof(void *)); + + return ctx; +} + + +static void +nothing_destroy(ctx) + void *ctx; +{ + free(ctx); +} + + +static int +nothing_send(ctx, msg) + void *ctx; + ipmon_msg_t *msg; +{ +#if 0 + ctx = ctx; /* gcc -Wextra */ + msg = msg; /* gcc -Wextra */ +#endif + /* + * Do nothing + */ + return 0; +} + diff --git a/contrib/ipfilter/lib/save_syslog.c b/contrib/ipfilter/lib/save_syslog.c new file mode 100644 index 000000000000..c1efdf41d984 --- /dev/null +++ b/contrib/ipfilter/lib/save_syslog.c @@ -0,0 +1,137 @@ +#include "ipf.h" +#include "ipmon.h" +#include + +static void *syslog_parse __P((char **)); +static void syslog_destroy __P((void *)); +static int syslog_send __P((void *, ipmon_msg_t *)); +static void syslog_print __P((void *)); + +typedef struct syslog_opts_s { + int facpri; + int fac; + int pri; +} syslog_opts_t; + +ipmon_saver_t syslogsaver = { + "syslog", + syslog_destroy, + NULL, /* dup */ + NULL, /* match */ + syslog_parse, + syslog_print, + syslog_send +}; + + +static void * +syslog_parse(char **strings) +{ + syslog_opts_t *ctx; + char *str; + char *s; + + ctx = calloc(1, sizeof(*ctx)); + if (ctx == NULL) + return NULL; + + ctx->facpri = -1; + + if (strings[0] != NULL && strings[0][0] != '\0') { + str = strdup(*strings); + if (str != NULL && *str != '\0') { + int fac = -1, pri = -1; + + s = strchr(str, '.'); + if (s != NULL) + *s++ = '\0'; + + if (*str != '\0') { + fac = fac_findname(str); + if (fac == -1) { + free(str); + free(ctx); + return NULL; + } + } + + if (s != NULL && *s != '\0') { + pri = pri_findname(s); + if (pri == -1) { + free(str); + free(ctx); + return NULL; + } + } + free(str); + + ctx->fac = fac; + ctx->pri = pri; + if (pri == -1) + ctx->facpri = fac; + else if (fac == -1) + ctx->facpri = pri; + else + ctx->facpri = fac | pri; + } else { + if (str != NULL) + free(str); + free(ctx); + ctx = NULL; + } + } + + return ctx; +} + + +static void +syslog_print(ctx) + void *ctx; +{ + syslog_opts_t *sys = ctx; + + if (sys->facpri == -1) + return; + + if (sys->fac == -1) { + printf(".%s", pri_toname(sys->pri)); + } else if (sys->pri == -1) { + printf("%s.", fac_toname(sys->fac)); + } else { + printf("%s.%s", fac_toname(sys->facpri & LOG_FACMASK), + pri_toname(sys->facpri & LOG_PRIMASK)); + } +} + + +static void +syslog_destroy(ctx) + void *ctx; +{ + free(ctx); +} + + +static int +syslog_send(ctx, msg) + void *ctx; + ipmon_msg_t *msg; +{ + syslog_opts_t *sys = ctx; + int facpri; + + if (sys->facpri == -1) { + facpri = msg->imm_loglevel; + } else { + if (sys->pri == -1) { + facpri = sys->fac | (msg->imm_loglevel & LOG_PRIMASK); + } else if (sys->fac == -1) { + facpri = sys->pri | (msg->imm_loglevel & LOG_FACMASK); + } else { + facpri = sys->facpri; + } + } + syslog(facpri, "%s", msg->imm_msg); + return 0; +} diff --git a/contrib/ipfilter/lib/save_v1trap.c b/contrib/ipfilter/lib/save_v1trap.c new file mode 100644 index 000000000000..b17f62c722ca --- /dev/null +++ b/contrib/ipfilter/lib/save_v1trap.c @@ -0,0 +1,463 @@ +#include "ipf.h" +#include "netinet/ipl.h" +#include "ipmon.h" +#include + +#define IPF_ENTERPRISE 9932 +/* + * Enterprise number OID: + * 1.3.6.1.4.1.9932 + */ +static u_char ipf_enterprise[] = { 6, 7, 0x2b, 6, 1, 4, 1, 0xcd, 0x4c }; +static u_char ipf_trap0_1[] = { 6, 10, 0x2b, 6, 1, 4, 1, 0xcd, 0x4c, 1, 1, 1 }; +static u_char ipf_trap0_2[] = { 6, 10, 0x2b, 6, 1, 4, 1, 0xcd, 0x4c, 1, 1, 2 }; + +static int writeint __P((u_char *, int)); +static int writelength __P((u_char *, u_int)); +static int maketrap_v1 __P((char *, u_char *, int, u_char *, int, u_32_t, + time_t)); +static void snmpv1_destroy __P((void *)); +static void *snmpv1_dup __P((void *)); +static int snmpv1_match __P((void *, void *)); +static void *snmpv1_parse __P((char **)); +static void snmpv1_print __P((void *)); +static int snmpv1_send __P((void *, ipmon_msg_t *)); + +typedef struct snmpv1_opts_s { + char *community; + int fd; + int v6; + int ref; +#ifdef USE_INET6 + struct sockaddr_in6 sin6; +#endif + struct sockaddr_in sin; +} snmpv1_opts_t; + +ipmon_saver_t snmpv1saver = { + "snmpv1", + snmpv1_destroy, + snmpv1_dup, /* dup */ + snmpv1_match, /* match */ + snmpv1_parse, + snmpv1_print, + snmpv1_send +}; + + +static int +snmpv1_match(ctx1, ctx2) + void *ctx1, *ctx2; +{ + snmpv1_opts_t *s1 = ctx1, *s2 = ctx2; + + if (s1->v6 != s2->v6) + return 1; + + if (strcmp(s1->community, s2->community)) + return 1; + +#ifdef USE_INET6 + if (s1->v6 == 1) { + if (memcmp(&s1->sin6, &s2->sin6, sizeof(s1->sin6))) + return 1; + } else +#endif + { + if (memcmp(&s1->sin, &s2->sin, sizeof(s1->sin))) + return 1; + } + + return 0; +} + + +static void * +snmpv1_dup(ctx) + void *ctx; +{ + snmpv1_opts_t *s = ctx; + + s->ref++; + return s; +} + + +static void +snmpv1_print(ctx) + void *ctx; +{ + snmpv1_opts_t *snmpv1 = ctx; + + printf("%s ", snmpv1->community); +#ifdef USE_INET6 + if (snmpv1->v6 == 1) { + char buf[80]; + + printf("%s", inet_ntop(AF_INET6, &snmpv1->sin6.sin6_addr, buf, + sizeof(snmpv1->sin6.sin6_addr))); + } else +#endif + { + printf("%s", inet_ntoa(snmpv1->sin.sin_addr)); + } +} + + +static void * +snmpv1_parse(char **strings) +{ + snmpv1_opts_t *ctx; + int result; + char *str; + char *s; + + if (strings[0] == NULL || strings[0][0] == '\0') + return NULL; + + if (strchr(*strings, ' ') == NULL) + return NULL; + + str = strdup(*strings); + + ctx = calloc(1, sizeof(*ctx)); + if (ctx == NULL) + return NULL; + + ctx->fd = -1; + + s = strchr(str, ' '); + *s++ = '\0'; + ctx->community = str; + + while (ISSPACE(*s)) + s++; + if (!*s) { + free(str); + free(ctx); + return NULL; + } + +#ifdef USE_INET6 + if (strchr(s, ':') == NULL) { + result = inet_pton(AF_INET, s, &ctx->sin.sin_addr); + if (result == 1) { + ctx->fd = socket(AF_INET, SOCK_DGRAM, 0); + if (ctx->fd >= 0) { + ctx->sin.sin_family = AF_INET; + ctx->sin.sin_port = htons(162); + if (connect(ctx->fd, + (struct sockaddr *)&ctx->sin, + sizeof(ctx->sin)) != 0) { + snmpv1_destroy(ctx); + return NULL; + } + } + } + } else { + result = inet_pton(AF_INET6, s, &ctx->sin6.sin6_addr); + if (result == 1) { + ctx->v6 = 1; + ctx->fd = socket(AF_INET6, SOCK_DGRAM, 0); + if (ctx->fd >= 0) { + ctx->sin6.sin6_family = AF_INET6; + ctx->sin6.sin6_port = htons(162); + if (connect(ctx->fd, + (struct sockaddr *)&ctx->sin6, + sizeof(ctx->sin6)) != 0) { + snmpv1_destroy(ctx); + return NULL; + } + } + } + } +#else + result = inet_aton(s, &ctx->sin.sin_addr); + if (result == 1) { + ctx->fd = socket(AF_INET, SOCK_DGRAM, 0); + if (ctx->fd >= 0) { + ctx->sin.sin_family = AF_INET; + ctx->sin.sin_port = htons(162); + if (connect(ctx->fd, &ctx->sin, + sizeof(ctx->sin)) != 0) { + snmpv1_destroy(ctx); + return NULL; + } + } + } +#endif + + if (result != 1) { + free(str); + free(ctx); + return NULL; + } + + ctx->ref = 1; + + return ctx; +} + + +static void +snmpv1_destroy(ctx) + void *ctx; +{ + snmpv1_opts_t *v1 = ctx; + + v1->ref--; + if (v1->ref > 0) + return; + + if (v1->community) + free(v1->community); + if (v1->fd >= 0) + close(v1->fd); + free(v1); +} + + +static int +snmpv1_send(ctx, msg) + void *ctx; + ipmon_msg_t *msg; +{ + snmpv1_opts_t *v1 = ctx; + + return sendtrap_v1_0(v1->fd, v1->community, + msg->imm_msg, msg->imm_msglen, msg->imm_when); +} + +static char def_community[] = "public"; /* ublic */ + +static int +writelength(buffer, value) + u_char *buffer; + u_int value; +{ + u_int n = htonl(value); + int len; + + if (value < 128) { + *buffer = value; + return 1; + } + if (value > 0xffffff) + len = 4; + else if (value > 0xffff) + len = 3; + else if (value > 0xff) + len = 2; + else + len = 1; + + *buffer = 0x80 | len; + + bcopy((u_char *)&n + 4 - len, buffer + 1, len); + + return len + 1; +} + + +static int +writeint(buffer, value) + u_char *buffer; + int value; +{ + u_char *s = buffer; + u_int n = value; + + if (value == 0) { + *buffer = 0; + return 1; + } + + if (n > 4194304) { + *s++ = 0x80 | (n / 4194304); + n -= 4194304 * (n / 4194304); + } + if (n > 32768) { + *s++ = 0x80 | (n / 32768); + n -= 32768 * (n / 327678); + } + if (n > 128) { + *s++ = 0x80 | (n / 128); + n -= (n / 128) * 128; + } + *s++ = (u_char)n; + + return s - buffer; +} + + + +/* + * First style of traps is: + * 1.3.6.1.4.1.9932.1.1 + */ +static int +maketrap_v1(community, buffer, bufsize, msg, msglen, ipaddr, when) + char *community; + u_char *buffer; + int bufsize; + u_char *msg; + int msglen; + u_32_t ipaddr; + time_t when; +{ + u_char *s = buffer, *t, *pdulen, *varlen; + int basesize = 73; + u_short len; + int trapmsglen; + int pdulensz; + int varlensz; + int baselensz; + int n; + + if (community == NULL || *community == '\0') + community = def_community; + basesize += strlen(community) + msglen; + + if (basesize + 8 > bufsize) + return 0; + + memset(buffer, 0xff, bufsize); + *s++ = 0x30; /* Sequence */ + if (basesize - 1 >= 128) { + baselensz = 2; + basesize++; + } else { + baselensz = 1; + } + s += baselensz; + *s++ = 0x02; /* Integer32 */ + *s++ = 0x01; /* length 1 */ + *s++ = 0x00; /* version 1 */ + *s++ = 0x04; /* octet string */ + *s++ = strlen(community); /* length of "public" */ + bcopy(community, s, s[-1]); + s += s[-1]; + *s++ = 0xA4; /* PDU(4) */ + pdulen = s++; + if (basesize - (s - buffer) >= 128) { + pdulensz = 2; + basesize++; + s++; + } else { + pdulensz = 1; + } + + /* enterprise */ + bcopy(ipf_enterprise, s, sizeof(ipf_enterprise)); + s += sizeof(ipf_enterprise); + + /* Agent address */ + *s++ = 0x40; + *s++ = 0x4; + bcopy(&ipaddr, s, 4); + s += 4; + + /* Generic Trap code */ + *s++ = 0x2; + n = writeint(s + 1, 6); + if (n == 0) + return 0; + *s = n; + s += n + 1; + + /* Specific Trap code */ + *s++ = 0x2; + n = writeint(s + 1, 0); + if (n == 0) + return 0; + *s = n; + s += n + 1; + + /* Time stamp */ + *s++ = 0x43; /* TimeTicks */ + *s++ = 0x04; /* TimeTicks */ + s[0] = when >> 24; + s[1] = when >> 16; + s[2] = when >> 8; + s[3] = when & 0xff; + s += 4; + + /* + * The trap0 message is "ipfilter_version" followed by the message + */ + *s++ = 0x30; + varlen = s; + if (basesize - (s - buffer) >= 128) { + varlensz = 2; + basesize++; + } else { + varlensz = 1; + } + s += varlensz; + + *s++ = 0x30; + t = s + 1; + bcopy(ipf_trap0_1, t, sizeof(ipf_trap0_1)); + t += sizeof(ipf_trap0_1); + + *t++ = 0x2; /* Integer */ + n = writeint(t + 1, IPFILTER_VERSION); + *t = n; + t += n + 1; + + len = t - s - 1; + writelength(s, len); + + s = t; + *s++ = 0x30; + if (basesize - (s - buffer) >= 128) { + trapmsglen = 2; + basesize++; + } else { + trapmsglen = 1; + } + t = s + trapmsglen; + bcopy(ipf_trap0_2, t, sizeof(ipf_trap0_2)); + t += sizeof(ipf_trap0_2); + + *t++ = 0x4; /* Octet string */ + n = writelength(t, msglen); + t += n; + bcopy(msg, t, msglen); + t += msglen; + + len = t - s - trapmsglen; + writelength(s, len); + + len = t - varlen - varlensz; + writelength(varlen, len); /* pdu length */ + + len = t - pdulen - pdulensz; + writelength(pdulen, len); /* pdu length */ + + len = t - buffer - baselensz - 1; + writelength(buffer + 1, len); /* length of trap */ + + return t - buffer; +} + + +int +sendtrap_v1_0(fd, community, msg, msglen, when) + int fd; + char *community, *msg; + int msglen; + time_t when; +{ + + u_char buffer[1500]; + int n; + + n = maketrap_v1(community, buffer, sizeof(buffer), + (u_char *)msg, msglen, 0, when); + if (n > 0) { + return send(fd, buffer, n, 0); + } + + return 0; +} diff --git a/contrib/ipfilter/lib/save_v2trap.c b/contrib/ipfilter/lib/save_v2trap.c new file mode 100644 index 000000000000..24349bb40581 --- /dev/null +++ b/contrib/ipfilter/lib/save_v2trap.c @@ -0,0 +1,459 @@ +#include "ipf.h" +#include "netinet/ipl.h" +#include "ipmon.h" +#include + +static u_char sysuptime[] = { 6, 8, 0x2b, 6, 1, 2, 1, 1, 3, 0 }; +/* + * Enterprise number OID: + * 1.3.6.1.4.1.9932 + */ +static u_char ipf_trap0_1[] = { 6, 10, 0x2b, 6, 1, 4, 1, 0xcd, 0x4c, 1, 1, 1 }; +static u_char ipf_trap0_2[] = { 6, 10, 0x2b, 6, 1, 4, 1, 0xcd, 0x4c, 1, 1, 2 }; + +static int writeint __P((u_char *, int)); +static int writelength __P((u_char *, u_int)); +static int maketrap_v2 __P((char *, u_char *, int, u_char *, int)); +static void snmpv2_destroy __P((void *)); +static void *snmpv2_dup __P((void *)); +static int snmpv2_match __P((void *, void *)); +static void *snmpv2_parse __P((char **)); +static void snmpv2_print __P((void *)); +static int snmpv2_send __P((void *, ipmon_msg_t *)); + + +int sendtrap_v2_0 __P((int, char *, char *, int)); + +static char def_community[] = "public"; /* ublic */ + +typedef struct snmpv2_opts_s { + char *community; + char *server; + int fd; + int v6; + int ref; +#ifdef USE_INET6 + struct sockaddr_in6 sin6; +#endif + struct sockaddr_in sin; +} snmpv2_opts_t; + +ipmon_saver_t snmpv2saver = { + "snmpv2", + snmpv2_destroy, + snmpv2_dup, /* dup */ + snmpv2_match, /* match */ + snmpv2_parse, + snmpv2_print, + snmpv2_send +}; + + +static int +snmpv2_match(ctx1, ctx2) + void *ctx1, *ctx2; +{ + snmpv2_opts_t *s1 = ctx1, *s2 = ctx2; + + if (s1->v6 != s2->v6) + return 1; + + if (strcmp(s1->community, s2->community)) + return 1; + +#ifdef USE_INET6 + if (s1->v6 == 1) { + if (memcmp(&s1->sin6, &s2->sin6, sizeof(s1->sin6))) + return 1; + } else +#endif + { + if (memcmp(&s1->sin, &s2->sin, sizeof(s1->sin))) + return 1; + } + + return 0; +} + + +static void * +snmpv2_dup(ctx) + void *ctx; +{ + snmpv2_opts_t *s = ctx; + + s->ref++; + return s; +} + + +static void +snmpv2_print(ctx) + void *ctx; +{ + snmpv2_opts_t *snmpv2 = ctx; + + printf("%s ", snmpv2->community); +#ifdef USE_INET6 + if (snmpv2->v6 == 1) { + char buf[80]; + + printf("%s", inet_ntop(AF_INET6, &snmpv2->sin6.sin6_addr, buf, + sizeof(snmpv2->sin6.sin6_addr))); + } else +#endif + { + printf("%s", inet_ntoa(snmpv2->sin.sin_addr)); + } +} + + +static void * +snmpv2_parse(char **strings) +{ + snmpv2_opts_t *ctx; + int result; + char *str; + char *s; + + if (strings[0] == NULL || strings[0][0] == '\0') + return NULL; + if (strchr(*strings, ' ') == NULL) + return NULL; + + str = strdup(*strings); + + ctx = calloc(1, sizeof(*ctx)); + if (ctx == NULL) + return NULL; + + ctx->fd = -1; + + s = strchr(str, ' '); + *s++ = '\0'; + ctx->community = str; + + while (ISSPACE(*s)) + s++; + if (!*s) { + free(str); + free(ctx); + return NULL; + } + +#ifdef USE_INET6 + if (strchr(s, ':') == NULL) { + result = inet_pton(AF_INET, s, &ctx->sin.sin_addr); + if (result == 1) { + ctx->fd = socket(AF_INET, SOCK_DGRAM, 0); + if (ctx->fd >= 0) { + ctx->sin.sin_family = AF_INET; + ctx->sin.sin_port = htons(162); + if (connect(ctx->fd, + (struct sockaddr *)&ctx->sin, + sizeof(ctx->sin)) != 0) { + snmpv2_destroy(ctx); + return NULL; + } + } + } + } else { + result = inet_pton(AF_INET6, s, &ctx->sin6.sin6_addr); + if (result == 1) { + ctx->v6 = 1; + ctx->fd = socket(AF_INET6, SOCK_DGRAM, 0); + if (ctx->fd >= 0) { + ctx->sin6.sin6_family = AF_INET6; + ctx->sin6.sin6_port = htons(162); + if (connect(ctx->fd, + (struct sockaddr *)&ctx->sin6, + sizeof(ctx->sin6)) != 0) { + snmpv2_destroy(ctx); + return NULL; + } + } + } + } +#else + result = inet_aton(s, &ctx->sin.sin_addr); + if (result == 1) { + ctx->fd = socket(AF_INET, SOCK_DGRAM, 0); + if (ctx->fd >= 0) { + ctx->sin.sin_family = AF_INET; + ctx->sin.sin_port = htons(162); + if (connect(ctx->fd, &ctx->sin, + sizeof(ctx->sin)) != 0) { + snmpv2_destroy(ctx); + return NULL; + } + } + } +#endif + + if (result != 1) { + free(str); + free(ctx); + return NULL; + } + + ctx->ref = 1; + + return ctx; +} + + +static void +snmpv2_destroy(ctx) + void *ctx; +{ + snmpv2_opts_t *v2 = ctx; + + v2->ref--; + if (v2->ref > 0) + return; + + if (v2->community) + free(v2->community); + if (v2->fd >= 0) + close(v2->fd); + free(v2); +} + + +static int +snmpv2_send(ctx, msg) + void *ctx; + ipmon_msg_t *msg; +{ + snmpv2_opts_t *v2 = ctx; + + return sendtrap_v2_0(v2->fd, v2->community, + msg->imm_msg, msg->imm_msglen); +} +static int +writelength(buffer, value) + u_char *buffer; + u_int value; +{ + u_int n = htonl(value); + int len; + + if (value < 128) { + *buffer = value; + return 1; + } + if (value > 0xffffff) + len = 4; + else if (value > 0xffff) + len = 3; + else if (value > 0xff) + len = 2; + else + len = 1; + + *buffer = 0x80 | len; + + bcopy((u_char *)&n + 4 - len, buffer + 1, len); + + return len + 1; +} + + +static int +writeint(buffer, value) + u_char *buffer; + int value; +{ + u_char *s = buffer; + u_int n = value; + + if (value == 0) { + *buffer = 0; + return 1; + } + + if (n > 4194304) { + *s++ = 0x80 | (n / 4194304); + n -= 4194304 * (n / 4194304); + } + if (n > 32768) { + *s++ = 0x80 | (n / 32768); + n -= 32768 * (n / 327678); + } + if (n > 128) { + *s++ = 0x80 | (n / 128); + n -= (n / 128) * 128; + } + *s++ = (u_char)n; + + return s - buffer; +} + + + +/* + * First style of traps is: + * 1.3.6.1.4.1.9932.1.1 + */ +static int +maketrap_v2(community, buffer, bufsize, msg, msglen) + char *community; + u_char *buffer; + int bufsize; + u_char *msg; + int msglen; +{ + u_char *s = buffer, *t, *pdulen; + u_char *varlen; + int basesize = 77; + u_short len; + int trapmsglen; + int pdulensz; + int varlensz; + int baselensz; + int n; + + if (community == NULL || *community == '\0') + community = def_community; + basesize += strlen(community) + msglen; + + if (basesize + 8 > bufsize) + return 0; + + memset(buffer, 0xff, bufsize); + *s++ = 0x30; /* Sequence */ + + if (basesize - 1 >= 128) { + baselensz = 2; + basesize++; + } else { + baselensz = 1; + } + s += baselensz; + *s++ = 0x02; /* Integer32 */ + *s++ = 0x01; /* length 1 */ + *s++ = 0x01; /* version 2 */ + *s++ = 0x04; /* octet string */ + *s++ = strlen(community); /* length of "public" */ + bcopy(community, s, s[-1]); + s += s[-1]; + *s++ = 0xA7; /* PDU(7) */ + pdulen = s++; + if (basesize - (s - buffer) >= 128) { + pdulensz = 2; + basesize++; + s++; + } else { + pdulensz = 1; + } + /* request id */ + *s++ = 0x2; /* integer */ + *s++ = 0x4; /* len 4 */ + *s++ = 0x0; /* noError */ + *s++ = 0x0; /* noError */ + *s++ = 0x0; /* noError */ + *s++ = 0x0; /* noError */ + + /* error status */ + *s++ = 0x2; /* integer */ + *s++ = 0x1; /* len 1 */ + *s++ = 0x0; /* noError */ + + /* error-index */ + *s++ = 0x2; /* integer */ + *s++ = 0x1; /* len 1 */ + *s++ = 0x0; /* noError */ + + *s++ = 0x30; /* sequence */ + varlen = s++; + if (basesize - (s - buffer) >= 128) { + varlensz = 2; + basesize++; + s++; + } else { + varlensz = 1; + } + + *s++ = 0x30; /* sequence */ + *s++ = sizeof(sysuptime) + 6; + + bcopy(sysuptime, s, sizeof(sysuptime)); + s += sizeof(sysuptime); + + *s++ = 0x43; /* Timestamp */ + *s++ = 0x04; /* TimeTicks */ + *s++ = 0x0; + *s++ = 0x0; + *s++ = 0x0; + *s++ = 0x0; + + *s++ = 0x30; + t = s + 1; + bcopy(ipf_trap0_1, t, sizeof(ipf_trap0_1)); + t += sizeof(ipf_trap0_1); + + *t++ = 0x2; /* Integer */ + n = writeint(t + 1, IPFILTER_VERSION); + *t = n; + t += n + 1; + + len = t - s - 1; + writelength(s, len); + + s = t; + *s++ = 0x30; + if (msglen < 128) { + if (msglen + 1 + 1 + sizeof(ipf_trap0_2) >= 128) + trapmsglen = 2; + else + trapmsglen = 1; + } else { + if (msglen + 2 + 1 + sizeof(ipf_trap0_2) >= 128) + trapmsglen = 2; + else + trapmsglen = 1; + } + t = s + trapmsglen; + bcopy(ipf_trap0_2, t, sizeof(ipf_trap0_2)); + t += sizeof(ipf_trap0_2); + + *t++ = 0x4; /* Octet string */ + n = writelength(t, msglen); + t += n; + bcopy(msg, t, msglen); + t += msglen; + + len = t - s - trapmsglen; + writelength(s, len); + + len = t - varlen - varlensz; + writelength(varlen, len); /* pdu length */ + + len = t - pdulen - pdulensz; + writelength(pdulen, len); /* pdu length */ + + len = t - buffer - baselensz - 1; + writelength(buffer + 1, len); /* length of trap */ + + return t - buffer; +} + + +int +sendtrap_v2_0(fd, community, msg, msglen) + int fd; + char *community, *msg; + int msglen; +{ + + u_char buffer[1500]; + int n; + + n = maketrap_v2(community, buffer, sizeof(buffer), + (u_char *)msg, msglen); + if (n > 0) { + return send(fd, buffer, n, 0); + } + + return 0; +} diff --git a/contrib/ipfilter/lib/tcpflags.c b/contrib/ipfilter/lib/tcpflags.c index f01d7dc31573..feb3e8af04ac 100644 --- a/contrib/ipfilter/lib/tcpflags.c +++ b/contrib/ipfilter/lib/tcpflags.c @@ -1,11 +1,11 @@ /* $FreeBSD$ */ /* - * Copyright (C) 2001-2002 by Darren Reed. + * Copyright (C) 2012 by Darren Reed. * * See the IPFILTER.LICENCE file for details on licencing. * - * $Id: tcpflags.c,v 1.3.4.1 2006/06/16 17:21:17 darrenr Exp $ + * $Id$ */ #include "ipf.h" @@ -26,7 +26,7 @@ extern u_char flags[]; u_char tcpflags(flgs) -char *flgs; + char *flgs; { u_char tcpf = 0; char *s, *t; diff --git a/contrib/ipfilter/lib/tcpoptnames.c b/contrib/ipfilter/lib/tcpoptnames.c index 25e3b275a761..24e41bb18b8b 100644 --- a/contrib/ipfilter/lib/tcpoptnames.c +++ b/contrib/ipfilter/lib/tcpoptnames.c @@ -1,11 +1,11 @@ /* $FreeBSD$ */ /* - * Copyright (C) 2000-2002 by Darren Reed. + * Copyright (C) 2012 by Darren Reed. * * See the IPFILTER.LICENCE file for details on licencing. * - * $Id: tcpoptnames.c,v 1.5.4.1 2006/06/16 17:21:17 darrenr Exp $ + * $Id$ */ #include "ipf.h" diff --git a/contrib/ipfilter/lib/v6ionames.c b/contrib/ipfilter/lib/v6ionames.c index b57b301e67bc..9f1207f13431 100644 --- a/contrib/ipfilter/lib/v6ionames.c +++ b/contrib/ipfilter/lib/v6ionames.c @@ -1,11 +1,11 @@ /* $FreeBSD$ */ /* - * Copyright (C) 2003-2005 by Darren Reed. + * Copyright (C) 2012 by Darren Reed. * * See the IPFILTER.LICENCE file for details on licencing. * - * $Id: v6ionames.c,v 1.1.4.3 2006/06/16 17:21:18 darrenr Exp $ + * $Id$ */ #include "ipf.h" @@ -16,10 +16,10 @@ struct ipopt_names v6ionames[] ={ { IPPROTO_HOPOPTS, 0x000001, 0, "hopopts" }, { IPPROTO_IPV6, 0x000002, 0, "ipv6" }, { IPPROTO_ROUTING, 0x000004, 0, "routing" }, - { IPPROTO_FRAGMENT, 0x000008, 0, "frag" }, + { IPPROTO_FRAGMENT, 0x000008, 0, "frag" }, { IPPROTO_ESP, 0x000010, 0, "esp" }, { IPPROTO_AH, 0x000020, 0, "ah" }, - { IPPROTO_NONE, 0x000040, 0, "none" }, + { IPPROTO_NONE, 0x000040, 0, "none" }, { IPPROTO_DSTOPTS, 0x000080, 0, "dstopts" }, { IPPROTO_MOBILITY, 0x000100, 0, "mobility" }, { 0, 0, 0, (char *)NULL } diff --git a/contrib/ipfilter/lib/v6optvalue.c b/contrib/ipfilter/lib/v6optvalue.c index a60d076bfbb7..a6eff9221256 100644 --- a/contrib/ipfilter/lib/v6optvalue.c +++ b/contrib/ipfilter/lib/v6optvalue.c @@ -1,18 +1,18 @@ /* $FreeBSD$ */ /* - * Copyright (C) 2003 by Darren Reed. + * Copyright (C) 2012 by Darren Reed. * * See the IPFILTER.LICENCE file for details on licencing. * - * $Id: v6optvalue.c,v 1.1.4.1 2006/06/16 17:21:18 darrenr Exp $ + * $Id$ */ #include "ipf.h" u_32_t getv6optbyname(optname) -char *optname; + char *optname; { #ifdef USE_INET6 struct ipopt_names *io; @@ -26,7 +26,7 @@ char *optname; u_32_t getv6optbyvalue(optval) -int optval; + int optval; { #ifdef USE_INET6 struct ipopt_names *io; diff --git a/contrib/ipfilter/lib/var.c b/contrib/ipfilter/lib/var.c index 4a62d7aed2e7..e61c8d1cfea9 100644 --- a/contrib/ipfilter/lib/var.c +++ b/contrib/ipfilter/lib/var.c @@ -1,12 +1,12 @@ /* $FreeBSD$ */ /* - * Copyright (C) 2002-2004 by Darren Reed. - * - * See the IPFILTER.LICENCE file for details on licencing. - * - * $Id: var.c,v 1.4.2.3 2006/06/16 17:21:18 darrenr Exp $ - */ + * Copyright (C) 2012 by Darren Reed. + * + * See the IPFILTER.LICENCE file for details on licencing. + * + * $Id$ + */ #include @@ -25,7 +25,7 @@ static char *expand_string __P((char *, int)); static variable_t *find_var(name) -char *name; + char *name; { variable_t *v; @@ -37,8 +37,8 @@ char *name; char *get_variable(string, after, line) -char *string, **after; -int line; + char *string, **after; + int line; { char c, *s, *t, *value; variable_t *v; @@ -84,8 +84,8 @@ int line; static char *expand_string(oldstring, line) -char *oldstring; -int line; + char *oldstring; + int line; { char c, *s, *p1, *p2, *p3, *newstring, *value; int len; @@ -144,8 +144,8 @@ int line; void set_variable(name, value) -char *name; -char *value; + char *name; + char *value; { variable_t *v; int len; diff --git a/contrib/ipfilter/lib/verbose.c b/contrib/ipfilter/lib/verbose.c index f1b4516a96cd..710daab443e3 100644 --- a/contrib/ipfilter/lib/verbose.c +++ b/contrib/ipfilter/lib/verbose.c @@ -1,11 +1,11 @@ /* $FreeBSD$ */ /* - * Copyright (C) 2000-2001 by Darren Reed. + * Copyright (C) 2012 by Darren Reed. * * See the IPFILTER.LICENCE file for details on licencing. * - * $Id: verbose.c,v 1.6.4.1 2006/06/16 17:21:18 darrenr Exp $ + * $Id$ */ #if defined(__STDC__) @@ -15,16 +15,16 @@ #endif #include -#include "ipt.h" +#include "ipf.h" #include "opts.h" #if defined(__STDC__) -void verbose(char *fmt, ...) +void verbose(int level, char *fmt, ...) #else -void verbose(fmt, va_alist) -char *fmt; -va_dcl +void verbose(level, fmt, va_alist) + char *fmt; + va_dcl #endif { va_list pvar; @@ -35,3 +35,21 @@ va_dcl vprintf(fmt, pvar); va_end(pvar); } + + +#if defined(__STDC__) +void ipfkverbose(char *fmt, ...) +#else +void ipfkverbose(fmt, va_alist) + char *fmt; + va_dcl +#endif +{ + va_list pvar; + + va_start(pvar, fmt); + + if (opts & OPT_VERBOSE) + verbose(0x1fffffff, fmt, pvar); + va_end(pvar); +} diff --git a/contrib/ipfilter/lib/vtof.c b/contrib/ipfilter/lib/vtof.c new file mode 100644 index 000000000000..fd1a98432aa8 --- /dev/null +++ b/contrib/ipfilter/lib/vtof.c @@ -0,0 +1,16 @@ +#include "ipf.h" + +int +vtof(version) + int version; +{ +#ifdef USE_INET6 + if (version == 6) + return AF_INET6; +#endif + if (version == 4) + return AF_INET; + if (version == 0) + return AF_UNSPEC; + return -1; +} diff --git a/contrib/ipfilter/man/Makefile b/contrib/ipfilter/man/Makefile index 0b8f2a14c5a3..04e97fb30365 100644 --- a/contrib/ipfilter/man/Makefile +++ b/contrib/ipfilter/man/Makefile @@ -1,5 +1,5 @@ # -# Copyright (C) 1993-1998 by Darren Reed. +# Copyright (C) 2012 by Darren Reed. # # See the IPFILTER.LICENCE file for details on licencing. # diff --git a/contrib/ipfilter/man/ipf.4 b/contrib/ipfilter/man/ipf.4 index dfef858d5dd8..aaa050d21340 100644 --- a/contrib/ipfilter/man/ipf.4 +++ b/contrib/ipfilter/man/ipf.4 @@ -46,7 +46,6 @@ active and inactive, respectively. All of these ioctl's are implemented as being routing ioctls and thus the same rules for the various routing ioctls and the file descriptor are employed, mainly being that the fd must be that of the device associated with the module (i.e., /dev/ipl). -.LP .PP The three groups of ioctls above perform adding rules to the end of the list (SIOCAD*), deletion of rules from any place in the list (SIOCRM*) @@ -83,10 +82,10 @@ typedef struct frentry { u_short fr_icmp; u_char fr_scmp; /* data for port comparisons */ - u_char fr_dcmp; + u_char fr_dcmp; u_short fr_dport; u_short fr_sport; - u_short fr_stop; /* top port for <> and >< */ + u_short fr_stop; /* top port for <> and >< */ u_short fr_dtop; /* top port for <> and >< */ u_32_t fr_flags; /* per-rule flags && options (see below) */ u_short fr_skip; /* # of rules to skip */ @@ -96,7 +95,7 @@ typedef struct frentry { char fr_ifname[IFNAMSIZ]; #if BSD > 199306 char fr_oifname[IFNAMSIZ]; -#endif +#endif struct frdest fr_tif; /* "to" interface */ struct frdest fr_dif; /* duplicate packet interfaces */ } frentry_t; @@ -106,7 +105,6 @@ When adding a new rule, all unused fields (in the filter rule) should be initialised to be zero. To insert a rule, at a particular position in the filter list, the number of the rule which it is to be inserted before must be put in the "fr_hits" field (the first rule is number 0). -.LP .PP Flags which are recognised in fr_flags: .nf @@ -137,7 +135,7 @@ Flags which are recognised in fr_flags: FR_NOTDSTIP 0x100000 /* not the dst IP# */ FR_AUTH 0x200000 /* use authentication */ FR_PREAUTH 0x400000 /* require preauthentication */ - + .fi .PP Values for fr_scomp and fr_dcomp (source and destination port value diff --git a/contrib/ipfilter/man/ipf.5 b/contrib/ipfilter/man/ipf.5 index 8bdaedcba229..3e5e9b237d74 100644 --- a/contrib/ipfilter/man/ipf.5 +++ b/contrib/ipfilter/man/ipf.5 @@ -1,557 +1,1698 @@ .\" $FreeBSD$ .TH IPF 5 .SH NAME -ipf, ipf.conf, ipf6.conf \- IP packet filter rule syntax +ipf, ipf.conf \- IPFilter firewall rules file format .SH DESCRIPTION .PP -A rule file for \fBipf\fP may have any name or even be stdin. As -\fBipfstat\fP produces parsable rules as output when displaying the internal -kernel filter lists, it is quite plausible to use its output to feed back -into \fBipf\fP. Thus, to remove all filters on input packets, the following -could be done: -.nf - -\fC# ipfstat \-i | ipf \-rf \-\fP -.fi -.SH GRAMMAR +The ipf.conf file is used to specify rules for the firewall, packet +authentication and packet accounting components of IPFilter. To load rules +specified in the ipf.conf file, the ipf(8) program is used. +.PP +For use as a firewall, there are two important rule types: those that block +and drop packets (block rules) and those that allow packets through (pass +rules.) Accompanying the decision to apply is a collection of statements +that specify under what conditions the result is to be applied and how. +.PP +The simplest rules that can be used in ipf.conf are expressed like this: .PP -The format used by \fBipf\fP for construction of filtering rules can be -described using the following grammar in BNF: -\fC .nf -filter-rule = [ insert ] action in-out [ options ] [ tos ] [ ttl ] - [ proto ] ip [ group ]. - -insert = "@" decnumber . -action = block | "pass" | log | "count" | skip | auth | call . -in-out = "in" | "out" . -options = [ log ] [ tag ] [ "quick" ] [ "on" interface-name [ dup ] - [ froute ] [ replyto ] ] . -tos = "tos" decnumber | "tos" hexnumber . -ttl = "ttl" decnumber . -proto = "proto" protocol . -ip = srcdst [ flags ] [ with withopt ] [ icmp ] [ keep ] . -group = [ "head" decnumber ] [ "group" decnumber ] . - -block = "block" [ return-icmp[return-code] | "return-rst" ] . -log = "log" [ "body" ] [ "first" ] [ "or-block" ] [ "level" loglevel ] . -tag = "tag" tagid . -skip = "skip" decnumber . -auth = "auth" | "preauth" . -call = "call" [ "now" ] function-name . -dup = "dup-to" interface-name [ ":" ipaddr ] . -froute = "fastroute" | "to" interface-name [ ":" ipaddr ] . -replyto = "reply-to" interface-name [ ":" ipaddr ] . -protocol = "tcp/udp" | "udp" | "tcp" | "icmp" | decnumber . -srcdst = "all" | fromto . -fromto = "from" [ "!" ] object "to" [ "!" ] object . - -return-icmp = "return-icmp" | "return-icmp-as-dest" . -return-code = "(" icmp-code ")" . -object = addr [ port-comp | port-range ] . -addr = "any" | nummask | host-name [ "mask" ipaddr | "mask" hexnumber ] . -addr = "any" | "" | nummask | - host-name [ "mask" ipaddr | "mask" hexnumber ] . -port-comp = "port" compare port-num . -port-range = "port" port-num range port-num . -flags = "flags" flag { flag } [ "/" flag { flag } ] . -with = "with" | "and" . -icmp = "icmp-type" icmp-type [ "code" decnumber ] . -return-code = "(" icmp-code ")" . -keep = "keep" "state" [ "(" state-options ")" ] | "keep" "frags" . -loglevel = facility"."priority | priority . - -nummask = host-name [ "/" decnumber ] . -host-name = ipaddr | hostname | "any" . -ipaddr = host-num "." host-num "." host-num "." host-num . -host-num = digit [ digit [ digit ] ] . -port-num = service-name | decnumber . -state-options = state-opts [ "," state-options ] . - -state-opts = "age" decnumber [ "/" decnumber ] | "strict" | - "no-icmp-err" | "limit" decnumber | "newisn" | "sync" . -withopt = [ "not" | "no" ] opttype [ withopt ] . -opttype = "ipopts" | "short" | "frag" | "opt" optname . -optname = ipopts [ "," optname ] . -ipopts = optlist | "sec-class" [ secname ] . -secname = seclvl [ "," secname ] . -seclvl = "unclass" | "confid" | "reserv-1" | "reserv-2" | "reserv-3" | - "reserv-4" | "secret" | "topsecret" . -icmp-type = "unreach" | "echo" | "echorep" | "squench" | "redir" | - "timex" | "paramprob" | "timest" | "timestrep" | "inforeq" | - "inforep" | "maskreq" | "maskrep" | decnumber . -icmp-code = decumber | "net-unr" | "host-unr" | "proto-unr" | "port-unr" | - "needfrag" | "srcfail" | "net-unk" | "host-unk" | "isolate" | - "net-prohib" | "host-prohib" | "net-tos" | "host-tos" | - "filter-prohib" | "host-preced" | "cutoff-preced" . -optlist = "nop" | "rr" | "zsu" | "mtup" | "mtur" | "encode" | "ts" | - "tr" | "sec" | "lsrr" | "e-sec" | "cipso" | "satid" | "ssrr" | - "addext" | "visa" | "imitd" | "eip" | "finn" . -facility = "kern" | "user" | "mail" | "daemon" | "auth" | "syslog" | - "lpr" | "news" | "uucp" | "cron" | "ftp" | "authpriv" | - "audit" | "logalert" | "local0" | "local1" | "local2" | - "local3" | "local4" | "local5" | "local6" | "local7" . -priority = "emerg" | "alert" | "crit" | "err" | "warn" | "notice" | - "info" | "debug" . - -hexnumber = "0" "x" hexstring . -hexstring = hexdigit [ hexstring ] . -decnumber = digit [ decnumber ] . - -compare = "=" | "!=" | "<" | ">" | "<=" | ">=" | "eq" | "ne" | "lt" | - "gt" | "le" | "ge" . -range = "<>" | "><" . -hexdigit = digit | "a" | "b" | "c" | "d" | "e" | "f" . -digit = "0" | "1" | "2" | "3" | "4" | "5" | "6" | "7" | "8" | "9" . -flag = "F" | "S" | "R" | "P" | "A" | "U" . +block in all +pass out all .fi .PP -This syntax is somewhat simplified for readability, some combinations -that match this grammar are disallowed by the software because they do -not make sense (such as tcp \fBflags\fP for non-TCP packets). -.SH FILTER RULES +Each rule must contain at least the following three components +.RS +.IP * +a decision keyword (pass, block, etc.) +.IP * +the direction of the packet (in or out) +.IP * +address patterns or "all" to match any address information +.RE +.SS Long lines +.PP +For rules lines that are particularly long, it is possible to split +them over multiple lines implicity like this: .PP -The "briefest" valid rules are (currently) no-ops and are of the form: .nf - block in all - pass in all - log out all - count in all +pass in on bgeo proto tcp from 1.1.1.1 port > 1000 + to 2.2.2.2 port < 5000 flags S keep state .fi .PP -Filter rules are checked in order, with the last matching rule -determining the fate of the packet (but see the \fBquick\fP option, -below). +or explicitly using the backslash ('\\') character: .PP -Filters are installed by default at the end of the kernel's filter -lists, prepending the rule with \fB@n\fP will cause it to be inserted -as the n'th entry in the current list. This is especially useful when -modifying and testing active filter rulesets. See ipf(8) for more -information. -.SH ACTIONS -.PP -The action indicates what to do with the packet if it matches the rest -of the filter rule. Each rule MUST have an action. The following -actions are recognised: -.TP -.B block -indicates that the packet should be flagged to be dropped. In response -to blocking a packet, the filter may be instructed to send a reply -packet, either an ICMP packet (\fBreturn-icmp\fP), an ICMP packet -masquerading as being from the original packet's destination -(\fBreturn-icmp-as-dest\fP), or a TCP "reset" (\fBreturn-rst\fP). An -ICMP packet may be generated in response to any IP packet, and its -type may optionally be specified, but a TCP reset may only be used -with a rule which is being applied to TCP packets. When using -\fBreturn-icmp\fP or \fBreturn-icmp-as-dest\fP, it is possible to specify -the actual unreachable `type'. That is, whether it is a network -unreachable, port unreachable or even administratively -prohibited. This is done by enclosing the ICMP code associated with -it in parenthesis directly following \fBreturn-icmp\fP or -\fBreturn-icmp-as-dest\fP as follows: .nf - block return-icmp(11) ... +pass in on bgeo proto tcp from 1.1.1.1 port > 1000 \\ + to 2.2.2.2 port < 5000 flags S keep state +.fi +.SS Comments +.PP +Comments in the ipf.conf file are indicated by the use of the '#' character. +This can either be at the start of the line, like this: +.PP +.nf +# Allow all ICMP packets in +pass in proto icmp from any to any .fi .PP -Would return a Type-Of-Service (TOS) ICMP unreachable error. -.TP -.B pass -will flag the packet to be let through the filter. -.TP -.B log -causes the packet to be logged (as described in the LOGGING section -below) and has no effect on whether the packet will be allowed through -the filter. -.TP -.B count -causes the packet to be included in the accounting statistics kept by -the filter, and has no effect on whether the packet will be allowed through -the filter. These statistics are viewable with ipfstat(8). -.TP -.B call -this action is used to invoke the named function in the kernel, which -must conform to a specific calling interface. Customised actions and -semantics can thus be implemented to supplement those available. This -feature is for use by knowledgeable hackers, and is not currently -documented. -.TP -.B "skip " -causes the filter to skip over the next \fIn\fP filter rules. If a rule is -inserted or deleted inside the region being skipped over, then the value of -\fIn\fP is adjusted appropriately. -.TP -.B auth -this allows authentication to be performed by a user-space program running -and waiting for packet information to validate. The packet is held for a -period of time in an internal buffer whilst it waits for the program to return -to the kernel the \fIreal\fP flags for whether it should be allowed through -or not. Such a program might look at the source address and request some sort -of authentication from the user (such as a password) before allowing the -packet through or telling the kernel to drop it if from an unrecognised source. -.TP -.B preauth -tells the filter that for packets of this class, it should look in the -pre-authenticated list for further clarification. If no further matching -rule is found, the packet will be dropped (the FR_PREAUTH is not the same -as FR_PASS). If a further matching rule is found, the result from that is -used in its instead. This might be used in a situation where a person -\fIlogs in\fP to the firewall and it sets up some temporary rules defining -the access for that person. +Or at the end of a like, like this: .PP -The next word must be either \fBin\fP or \fBout\fP. Each packet -moving through the kernel is either inbound (just been received on an -interface, and moving towards the kernel's protocol processing) or -outbound (transmitted or forwarded by the stack, and on its way to an -interface). There is a requirement that each filter rule explicitly -state which side of the I/O it is to be used on. -.SH OPTIONS -.PP -The list of options is brief, and all are indeed optional. Where -options are used, they must be present in the order shown here. These -are the currently supported options: -.TP -.B log -indicates that, should this be the last matching rule, the packet -header will be written to the \fBipl\fP log (as described in the -LOGGING section below). -.TP -.B tag tagid -indicates that, if this rule causes the packet to be logged or entered -in the state table, the tagid will be logged as part of the log entry. -This can be used to quickly match "similar" rules in scripts that post -process the log files for e.g. generation of security reports or accounting -purposes. The tagid is a 32 bit unsigned integer. -.TP -.B quick -allows "short-cut" rules in order to speed up the filter or override -later rules. If a packet matches a filter rule which is marked as -\fBquick\fP, this rule will be the last rule checked, allowing a -"short-circuit" path to avoid processing later rules for this -packet. The current status of the packet (after any effects of the -current rule) will determine whether it is passed or blocked. -.IP -If this option is missing, the rule is taken to be a "fall-through" -rule, meaning that the result of the match (block/pass) is saved and -that processing will continue to see if there are any more matches. -.TP -.B on -allows an interface name to be incorporated into the matching -procedure. Interface names are as printed by "netstat \-i". If this -option is used, the rule will only match if the packet is going -through that interface in the specified direction (in/out). If this -option is absent, the rule is taken to be applied to a packet -regardless of the interface it is present on (i.e. on all interfaces). -Filter rulesets are common to all interfaces, rather than having a -filter list for each interface. -.IP -This option is especially useful for simple IP-spoofing protection: -packets should only be allowed to pass inbound on the interface from -which the specified source address would be expected, others may be -logged and/or dropped. -.TP -.B dup-to -causes the packet to be copied, and the duplicate packet to be sent -outbound on the specified interface, optionally with the destination -IP address changed to that specified. This is useful for off-host -logging, using a network sniffer. -.TP -.B to -causes the packet to be moved to the outbound queue on the -specified interface. This can be used to circumvent kernel routing -decisions, and even to bypass the rest of the kernel processing of the -packet (if applied to an inbound rule). It is thus possible to -construct a firewall that behaves transparently, like a filtering hub -or switch, rather than a router. The \fBfastroute\fP keyword is a -synonym for this option. -.SH MATCHING PARAMETERS -.PP -The keywords described in this section are used to describe attributes -of the packet to be used when determining whether rules match or don't -match. The following general-purpose attributes are provided for -matching, and must be used in this order: -.TP -.B tos -packets with different Type-Of-Service values can be filtered. -Individual service levels or combinations can be filtered upon. The -value for the TOS mask can either be represented as a hex number or a -decimal integer value. -.TP -.B ttl -packets may also be selected by their Time-To-Live value. The value given in -the filter rule must exactly match that in the packet for a match to occur. -This value can only be given as a decimal integer value. -.TP -.B proto -allows a specific protocol to be matched against. All protocol names -found in \fB/etc/protocols\fP are recognised and may be used. -However, the protocol may also be given as a DECIMAL number, allowing -for rules to match your own protocols, or new ones which would -out-date any attempted listing. -.IP -The special protocol keyword \fBtcp/udp\fP may be used to match either -a TCP or a UDP packet, and has been added as a convenience to save -duplication of otherwise-identical rules. -.\" XXX grammar should reflect this (/etc/protocols) -.PP -The \fBfrom\fP and \fBto\fP keywords are used to match against IP -addresses (and optionally port numbers). Rules must specify BOTH -source and destination parameters. -.PP -IP addresses may be specified in one of two ways: as a numerical -address\fB/\fPmask, or as a hostname \fBmask\fP netmask. The hostname -may either be a valid hostname, from either the hosts file or DNS -(depending on your configuration and library) or of the dotted numeric -form. There is no special designation for networks but network names -are recognised. Note that having your filter rules depend on DNS -results can introduce an avenue of attack, and is discouraged. -.PP -There is a special case for the hostname \fBany\fP which is taken to -be 0.0.0.0/0 (see below for mask syntax) and matches all IP addresses. -Only the presence of "any" has an implied mask, in all other -situations, a hostname MUST be accompanied by a mask. It is possible -to give "any" a hostmask, but in the context of this language, it is -non-sensical. -.PP -The numerical format "x\fB/\fPy" indicates that a mask of y -consecutive 1 bits set is generated, starting with the MSB, so a y value -of 16 would give 0xffff0000. The symbolic "x \fBmask\fP y" indicates -that the mask y is in dotted IP notation or a hexadecimal number of -the form 0x12345678. Note that all the bits of the IP address -indicated by the bitmask must match the address on the packet exactly; -there isn't currently a way to invert the sense of the match, or to -match ranges of IP addresses which do not express themselves easily as -bitmasks (anthropomorphization; it's not just for breakfast anymore). -.PP -If a \fBport\fP match is included, for either or both of source and -destination, then it is only applied to -.\" XXX - "may only be" ? how does this apply to other protocols? will it not match, or will it be ignored? -TCP and UDP packets. If there is no \fBproto\fP match parameter, -packets from both protocols are compared. This is equivalent to "proto -tcp/udp". When composing \fBport\fP comparisons, either the service -name or an integer port number may be used. Port comparisons may be -done in a number of forms, with a number of comparison operators, or -port ranges may be specified. When the port appears as part of the -\fBfrom\fP object, it matches the source port number, when it appears -as part of the \fBto\fP object, it matches the destination port number. -See the examples for more information. -.PP -The \fBall\fP keyword is essentially a synonym for "from any to any" -with no other match parameters. -.PP -Following the source and destination matching parameters, the -following additional parameters may be used: -.TP -.B with -is used to match irregular attributes that some packets may have -associated with them. To match the presence of IP options in general, -use \fBwith ipopts\fP. To match packets that are too short to contain -a complete header, use \fBwith short\fP. To match fragmented packets, -use \fBwith frag\fP. For more specific filtering on IP options, -individual options can be listed. -.IP -Before any parameter used after the \fBwith\fP keyword, the word -\fBnot\fP or \fBno\fP may be inserted to cause the filter rule to only -match if the option(s) is not present. -.IP -Multiple consecutive \fBwith\fP clauses are allowed. Alternatively, -the keyword \fBand\fP may be used in place of \fBwith\fP, this is -provided purely to make the rules more readable ("with ... and ..."). -When multiple clauses are listed, all those must match to cause a -match of the rule. -.\" XXX describe the options more specifically in a separate section -.TP -.B flags -is only effective for TCP filtering. Each of the letters possible -represents one of the possible flags that can be set in the TCP -header. The association is as follows: -.LP .nf - F - FIN - S - SYN - R - RST - P - PUSH - A - ACK - U - URG +pass in proto icmp from any to any # Allow all ICMP packets in +.fi +.SH Firewall rules +.PP +This section goes into detail on how to construct firewall rules that +are placed in the ipf.conf file. +.PP +It is beyond the scope of this document to describe what makes a good +firewall rule set or which packets should be blocked or allowed in. +Some suggestions will be provided but further reading is expected to +fully understand what is safe and unsafe to allow in/out. +.SS Filter rule keywords +.PP +The first word found in any filter rule describes what the eventual outcome +of a packet that matches it will be. Descriptions of the many and various +sections that can be used to match on the contents of packet headers will +follow on below. +.PP +The complete list of keywords, along with what they do is as follows: +.RS +.HP +pass +rules that match a packet indicate to ipfilter that it should be +allowed to continue on in the direction it is flowing. +.HP +block +rules are used when it is desirable to prevent a packet from going +any further. Packets that are blocked on the "in" side are never seen by +TCP/IP and those that are blocked going "out" are never seen on the wire. +.HP +log +when IPFilter successfully matches a packet against a log rule a log +record is generated and made available for ipmon(8) to read. These rules +have no impact on whether or not a packet is allowed through or not. +So if a packet first matched a block rule and then matched a log rule, +the status of the packet after the log rule is that it will still be +blocked. +.HP +count +rules provide the administrator with the ability to count packets and +bytes that match the criteria laid out in the configuration file. +The count rules are applied after NAT and filter rules on the inbound +path. For outbound packets, count rules are applied before NAT and +before the packet is dropped. Thus the count rule cannot be used as +a true indicator of link layer +.HP +auth +rules cause the matching packet to be queued up for processing by a +user space program. The user space program is responsible for making +an ioctl system call to collect the information about the queued +packet and another ioctl system call to return the verdict (block, +pass, etc) on what to do with the packet. In the event that the queue +becomes full, the packets will end up being dropped. +.HP +call +provides access to functions built into IPFilter that allow for more +complex actions to be taken as part of the decision making that goes +with the rule. +.HP +decapsulate +rules instruct ipfilter to remove any +other headers (IP, UDP, AH) and then process what is inside as a new packet. +For non-UDP packets, there are builtin checks that are applied in addition +to whatever is specified in the rule, to only allow decapsulation of +recognised protocols. After decapsulating the inner packet, any filtering +result that is applied to the inner packet is also applied to the other +packet. +.PP +The default way in which filter rules are applied is for the last +matching rule to be used as the decision maker. So even if the first +rule to match a packet is a pass, if there is a later matching rule +that is a block and no further rules match the packet, then it will +be blocked. +.SS Matching Network Interfaces +.PP +On systems with more than one network interface, it is necessary +to be able to specify different filter rules for each of them. +In the first instance, this is because different networks will send us +packets via each network interface but it is also because of the hosts, +the role and the resulting security policy that we need to be able to +distinguish which network interface a packet is on. +.PP +To accomodate systems where the presence of a network interface is +dynamic, it is not necessary for the network interface named in a +filter rule to be present in the system when the rule is loaded. +This can lead to silent errors being introduced and unexpected +behaviour with the simplest of keyboard mistakes - for example, +typing in hem0 instead of hme0 or hme2 instead of hme3. +.PP +On Solaris systems prior to Solaris 10 Update 4, it is not possible +to filter packets on the loopback interface (lo0) so filter rules +that specify it will have no impact on the corresponding flow of +packets. See below for Solaris specific tips on how to enable this. +.PP +Some examples of including the network interface in filter rules are: +.PP +.nf +block in on bge0 all +pass out on bge0 all +.fi +.SS Address matching (basic) +.PP +The first and most basic part of matching for filtering rules is to +specify IP addresses and TCP/UDP port numbers. The source address +information is matched by the "from" information in a filter rule +and the destination address information is matched with the "to" +information in a filter rule. +.PP +The typical format used for IP addresses is CIDR notation, where an +IP address (or network) is followed by a '/' and a number representing +the size of the netmask in bits. This notation is used for specifying +address matching in both IPv4 and IPv6. If the '/' and bitmask size +are excluded from the matching string, it is assumed that the address +specified is a host address and that the netmask applied should be +all 1's. +.PP +Some examples of this are: +.PP +.nf +pass in from 10.1.0.0/24 to any +block out from any to 10.1.1.1 +.fi +.PP +It is not possible to specify a range of addresses that does not +have a boundary that can be defined by a standard subnet mask. +.IP +.B Names instead of addresses +.RS +.PP +Hostnames, resolved either via DNS or /etc/hosts, or network names, +resolved via /etc/networks, may be used in place of actual addresses +in the filter rules. WARNING: if a hostname expands to more than one +address, only the *first* is used in building the filter rule. +.PP +Caution should be exercised when relying on DNS for filter rules in +case the sending and receiving of DNS packets is blocked when ipf(8) +is processing that part of the configuration file, leading to long +delays, if not errors, in loading the filter rules. +.RE +.SS Protocol Matching +.PP +To match packets based on TCP/UDP port information, it is first necessary +to indicate which protocol the packet must be. This is done using the +"proto" keyword, followed by either the protocol number or a name which +is mapped to the protocol number, usually through the /etc/protocols file. +.PP +.nf +pass in proto tcp from 10.1.0.0/24 to any +block out proto udp from any to 10.1.1.1 +pass in proto icmp from any to 192.168.0.0/16 +.fi +.SS Sending back error packets +.PP +When a packet is just discarded using a block rule, there is no feedback given +to the host that sent the packet. This is both good and bad. If this is the +desired behaviour and it is not desirable to send any feedback about packets +that are to be denied. The catch is that often a host trying to connect to a +TCP port or with a UDP based application will send more than one packet +because it assumes that just one packet may be discarded so a retry is +required. The end result being logs can become cluttered with duplicate +entries due to the retries. +.PP +To address this problem, a block rule can be qualified in two ways. +The first of these is specific to TCP and instructs IPFilter to send back +a reset (RST) packet. This packet indicates to the remote system that the +packet it sent has been rejected and that it shouldn't make any further +attempts to send packets to that port. Telling IPFilter to return a TCP +RST packet in response to something that has been received is achieved +with the return-rst keyword like this: +.PP +.nf +block return-rst in proto tcp from 10.0.0.0/8 to any +.fi +.PP +When sending back a TCP RST packet, IPFilter must construct a new packet +that has the source address of the intended target, not the source address +of the system it is running on (if they are different.) +.PP +For all of the other protocols handled by the IP protocol suite, to send +back an error indicating that the received packet was dropped requires +sending back an ICMP error packet. Whilst these can also be used for TCP, +the sending host may not treat the received ICMP error as a hard error +in the same way as it does the TCP RST packet. To return an ICMP error +it is necessary to place return-icmp after the block keyword like this: +.PP +.nf +block return-icmp in proto udp from any to 192.168.0.1/24 +.fi +.PP +When electing to return an ICMP error packet, it is also possible to +select what type of ICMP error is returned. Whilst the full compliment +of ICMP unreachable codes can be used by specifying a number instead of +the string below, only the following should be used in conjunction with +return-icmp. Which return code to use is a choice to be made when +weighing up the pro's and con's. Using some of the codes may make it +more obvious that a firewall is being used rather than just the host +not responding. +.RS +.HP +filter-prohib +(prohibited by filter) +sending packets to the destination given in the received packet is +prohibited due to the application of a packet filter +.HP +net-prohib +(prohibited network) +sending packets to the destination given in the received packet is +administratively prohibited. +.HP +host-unk +(host unknown) +the destination host address is not known by the system receiving +the packet and therefore cannot be reached. +.HP +host-unr +(host unreachable) +it is not possible to reach the host as given by the destination address +in the packet header. +.HP +net-unk +(network unknown) +the destination network address is not known by the system receiving +the packet and therefore cannot be reached. +.HP +net-unr +(network unreachable) +it is not possible to forward the packet on to its final destination +as given by the destination address +.HP +port-unr +(port unreachable) +there is no application using the given destination port and therefore +it is not possible to reach that port. +.HP +proto-unr +(protocol unreachable) +the IP protocol specified in the packet is not available to receive +packets. +.DE +.PP +An example that shows how to send back a port unreachable packet for +UDP packets to 192.168.1.0/24 is as follows: +.PP +.nf +block return-icmp(port-unr) in proto udp from any to 192.168.1.0/24 +.fi +.PP +In the above examples, when sending the ICMP packet, IPFilter will construct +a new ICMP packet with a source address of the network interface used to +send the packet back to the original source. This can give away that there +is an intermediate system blocking packets. To have IPFilter send back +ICMP packets where the source address is the original destination, regardless +of whether or not it is on the local host, return-icmp-as-dest is used like +this: +.PP +.nf +block return-icmp-as-dest(port-unr) in proto udp \\ + from any to 192.168.1.0/24 +.fi +.SS TCP/UDP Port Matching +.PP +Having specified which protocol is being matched, it is then possible to +indicate which port numbers a packet must have in order to match the rule. +Due to port numbers being used differently to addresses, it is therefore +possible to match on them in different ways. IPFilter allows you to use +the following logical operations: +.IP "< x" +is true if the port number is greater than or equal to x and less than or +equal to y +is true if the port number in the packet is less than x +.IP "<= x" +is true if the port number in the packet is less than or equal to x +.IP "> x" +is true if the port number in the packet is greater than x +.IP ">= x" +is true if the port number in the packet is greater or equal to x +.IP "= x" +is true if the port number in the packet is equal to x +.IP "!= x" +is true if the port number in the packet is not equal to x +.PP +Additionally, there are a number of ways to specify a range of ports: +.IP "x <> y" +is true if the port number is less than a and greater than y +.IP "x >< y" +is true if the port number is greater than x and less than y +.IP "x:y" +is true if the port number is greater than or equal to x and less than or +equal to y +.PP +Some examples of this are: +.PP +.nf +block in proto tcp from any port >= 1024 to any port < 1024 +pass in proto tcp from 10.1.0.0/24 to any port = 22 +block out proto udp from any to 10.1.1.1 port = 135 +pass in proto udp from 1.1.1.1 port = 123 to 10.1.1.1 port = 123 +pass in proto tcp from 127.0.0.0/8 to any port = 6000:6009 +.fi +.PP +If there is no desire to mention any specific source or destintion +information in a filter rule then the word "all" can be used to +indicate that all addresses are considered to match the rule. +.SS IPv4 or IPv6 +.PP +If a filter rule is constructed without any addresses then IPFilter +will attempt to match both IPv4 and IPv6 packets with it. In the +next list of rules, each one can be applied to either network protocol +because there is no address specified from which IPFilter can derive +with network protocol to expect. +.PP +.nf +pass in proto udp from any to any port = 53 +block in proto tcp from any port < 1024 to any +.fi +.PP +To explicitly match a particular network address family with a specific +rule, the family must be added to the rule. For IPv4 it is necessary to +add family inet and for IPv6, family inet6. Thus the next rule will +block all packets (both IPv4 and IPv6: +.PP +.nf +block in all +.fi +.PP +but in the following example, we block all IPv4 packets and only allow +in IPv6 packets: +.PP +.nf +block in family inet all +pass in family inet6 all +.fi +.PP +To continue on from the example where we allowed either IPv4 or IPv6 +packets to port 53 in, to change that such that only IPv6 packets to +port 53 need to allowed blocked then it is possible to add in a +protocol family qualifier: +.PP +.nf +pass in family inet6 proto udp from any to any port = 53 +.fi +.SS First match vs last match +.PP +To change the default behaviour from being the last matched rule decides +the outcome to being the first matched rule, the word "quick" is inserted +to the rule. +.SH Extended Packet Matching +.SS Beyond using plain addresses +.PP +On firewalls that are working with large numbers of hosts and networks +or simply trying to filter discretely against various hosts, it can +be an easier administration task to define a pool of addresses and have +a filter rule reference that address pool rather than have a rule for +each address. +.PP +In addition to being able to use address pools, it is possible to use +the interface name(s) in the from/to address fields of a rule. If the +name being used in the address section can be matched to any of the +interface names mentioned in the rule's "on" or "via" fields then it +can be used with one of the following keywords for extended effect: +.HP +broadcast +use the primary broadcast address of the network interface for matching +packets with this filter rule; +.IP +.nf +pass in on fxp0 proto udp from any to fxp0/broadcast port = 123 +.fi +.HP +peer +use the peer address on point to point network interfaces for matching +packets with this filter rule. This option typically only has meaningful +use with link protocols such as SLIP and PPP. +For example, this rule allows ICMP packets from the remote peer of ppp0 +to be received if they're destined for the address assigned to the link +at the firewall end. +.IP +.nf +pass in on ppp0 proto icmp from ppp0/peer to ppp0/32 +.fi +.HP +netmasked +use the primary network address, with its netmask, of the network interface +for matching packets with this filter rule. If a network interface had an +IP address of 192.168.1.1 and its netmask was 255.255.255.0 (/24), then +using the word "netmasked" after the interface name would match any +addresses that would match 192.168.1.0/24. If we assume that bge0 has +this IP address and netmask then the following two rules both serve +to produce the same effect: +.IP +.nf +pass in on bge0 proto icmp from any to 192.168.1.0/24 +pass in on bge0 proto icmp from any to bge0/netmasked +.fi +.HP +network +using the primary network address, and its netmask, of the network interface, +construct an address for exact matching. If a network interface has an +address of 192.168.1.1 and its netmask is 255.255.255.0, using this +option would only match packets to 192.168.1.0. +.IP +.nf +pass in on bge0 proto icmp from any to bge0/network +.fi +.PP +Another way to use the name of a network interface to get the address +is to wrap the name in ()'s. In the above method, IPFilter +looks at the interface names in use and to decide whether or not +the name given is a hostname or network interface name. With the +use of ()'s, it is possible to tell IPFilter that the name should +be treated as a network interface name even though it doesn't +appear in the list of network interface that the rule ias associated +with. +.IP +.nf +pass in proto icmp from any to (bge0)/32 +.fi +.SS Using address pools +.PP +Rather than list out multiple rules that either allow or deny specific +addresses, it is possible to create a single object, call an address +pool, that contains all of those addresses and reference that in the +filter rule. For documentation on how to write the configuration file +for those pools and load them, see ippool.conf(5) and ippool(8). +There are two types of address pools that can be defined in ippool.conf(5): +trees and hash tables. To refer to a tree defined in ippool.conf(5), +use this syntax: +.PP +.nf +pass in from pool/trusted to any +.fi +.PP +Either a name or number can be used after the '/', just so long as it +matches up with something that has already been defined in ipool.conf(5) +and loaded in with ippool(8). Loading a filter rule that references a +pool that does not exist will result in an error. +.PP +If hash tables have been used in ippool.conf(5) to store the addresses +in instead of a tree, then replace the word pool with hash: +.IP +.nf +pass in from any to hash/webservers +.fi +.PP +There are different operational characteristics with each, so there +may be some situations where a pool works better than hash and vice +versa. +.SS Matching TCP flags +.PP +The TCP header contains a field of flags that is used to decide if the +packet is a connection request, connection termination, data, etc. +By matching on the flags in conjunction with port numbers, it is +possible to restrict the way in which IPFilter allows connections to +be created. A quick overview of the TCP +flags is below. Each is listed with the letter used in IPFilter +rules, followed by its three or four letter pneumonic. +.HP +S +SYN - this bit is set when a host is setting up a connection. +The initiator typically sends a packet with the SYN bit and the +responder sends back SYN plus ACK. +.HP +A +ACK - this bit is set when the sender wishes to acknowledge the receipt +of a packet from another host +.HP +P +PUSH - this bit is set when a sending host has send some data that +is yet to be acknowledged and a reply is sought +.HP +F +FIN - this bit is set when one end of a connection starts to close +the connection down +.HP +U +URG - this bit is set to indicate that the packet contains urgent data +.HP +R +RST - this bit is set only in packets that are a reply to another +that has been received but is not targetted at any open port +.HP +C +CWN +.HP +E +ECN +.PP +When matching TCP flags, it is normal to just list the flag that you +wish to be set. By default the set of flags it is compared against +is "FSRPAU". Rules that say "flags S" will be displayed by ipfstat(8) +as having "flags S/FSRPAU". This is normal. +The last two flags, "C" and "E", are optional - they +may or may not be used by an end host and have no bearing on either +the acceptance of data nor control of the connection. Masking them +out with "flags S/FSRPAUCE" may cause problems for remote hosts +making a successful connection. +.PP +.nf +pass in quick proto tcp from any to any port = 22 flags S/SAFR +pass out quick proto tcp from any port = 22 to any flags SA +.fi +.PP +By itself, filtering based on the TCP flags becomes more work but when +combined with stateful filtering (see below), the situation changes. +.SS Matching on ICMP header information +.PP +The TCP and UDP are not the only protocols for which filtering beyond +just the IP header is possible, extended matching on ICMP packets is +also available. The list of valid ICMP types is different for IPv4 +vs IPv6. +.PP +As a practical example, to allow the ping command to work +against a specific target requires allowing two different types of +ICMP packets, like this: +.PP +.nf +pass in proto icmp from any to webserver icmp-type echo +pass out proto icmp from webserver to any icmp-type echorep +.fi +.PP +The ICMP header has two fields that are of interest for filtering: +the ICMP type and code. Filter rules can accept either a name or +number for both the type and code. The list of names supported for +ICMP types is listed below, however only ICMP unreachable errors +have named codes (see above.) +.PP +The list of ICMP types that are available for matching an IPv4 packet +are as follows: +.PP +echo (echo request), +echorep (echo reply), +inforeq (information request), +inforep (information reply), +maskreq (mask request), +maskrep (mask reply), +paramprob (parameter problem), +redir (redirect), +routerad (router advertisement), +routersol (router solicit), +squence (source quence), +timest (timestamp), +timestreq (timestamp reply), +timex (time exceeded), +unreach (unreachable). +.PP +The list of ICMP types that are available for matching an IPv6 packet +are as follows: +.PP +echo (echo request), +echorep (echo reply), +fqdnquery (FQDN query), +fqdnreply (FQDN reply), +inforeq (information request), +inforep (information reply), +listendone (MLD listener done), +listendqry (MLD listener query), +listendrep (MLD listener reply), +neighadvert (neighbour advert), +neighborsol (neighbour solicit), +paramprob (parameter problem), +redir (redirect), +renumber (router renumbering), +routerad (router advertisement), +routersol (router solicit), +timex (time exceeded), +toobig (packet too big), +unreach (unreachable, +whoreq (WRU request), +whorep (WRU reply). +.SH Stateful Packet Filtering +.PP +Stateful packet filtering is where IPFilter remembers some information from +one or more packets that it has seen and is able to apply it to future +packets that it receives from the network. +.PP +What this means for each transport layer protocol is different. +For TCP it means that if IPFilter +sees the very first packet of an attempt to make a connection, it has enough +information to allow all other subsequent packets without there needing to +be any explicit rules to match them. IPFilter uses the TCP port numbers, +TCP flags, window size and sequence numbers to determine which packets +should be matched. For UDP, only the UDP port numbers are available. +For ICMP, the ICMP types can be combined with the ICMP id field to +determine which reply packets match a request/query that has already +been seen. For all other protocols, only matching on IP address and +protocol number is available for determining if a packet received is a mate +to one that has already been let through. +.PP +The difference this makes is a reduction in the number of rules from +2 or 4 to 1. For example, these 4 rules: +.PP +.nf +pass in on bge0 proto tcp from any to any port = 22 +pass out on bge1 proto tcp from any to any port = 22 +pass in on bge1 proto tcp from any port = 22 to any +pass out on bge0 proto tcp from any port = 22 to any +.fi +.PP +can be replaced with this single rule: +.PP +.nf +pass in on bge0 proto tcp from any to any port = 22 flags S keep state +.fi +.PP +Similar rules for UDP and ICMP might be: +.PP +.nf +pass in on bge0 proto udp from any to any port = 53 keep state +pass in on bge0 proto icmp all icmp-type echo keep state +.fi +.PP +When using stateful filtering with TCP it is best to add "flags S" to the +rule to ensure that state is only created when a packet is seen that is +an indication of a new connection. Although IPFilter can gather some +information from packets in the middle of a TCP connection to do stateful +filtering, there are some options that are only sent at the start of the +connection which alter the valid window of what TCP accepts. The end result +of trying to pickup TCP state in mid connection is that some later packets +that are part of the connection may not match the known state information +and be dropped or blocked, causing problems. If a TCP packet matches IP +addresses and port numbers but does not fit into the recognised window, +it will not be automatically allowed and will be flagged inside of +IPFitler as "out of window" (oow). See below, "Extra packet attributes", +for how to match on this attribute. +.PP +Once a TCP connection has reached the established state, the default +timeout allows for it to be idle for 5 days before it is removed from +the state table. The timeouts for the other TCP connection states +vary from 240 seconds to 30 seconds. +Both UDP and ICMP state entries have asymetric timeouts where the timeout +set upon seeing packets in the forward direction is much larger than +for the reverse direction. For UDP the default timeouts are 120 and +12 seconds, for ICMP 60 and 6 seconds. This is a reflection of the +use of these protocols being more for query-response than for ongoing +connections. For all other protocols the +timeout is 60 seconds in both directions. +.SS Stateful filtering options +.PP +The following options can be used with stateful filtering: +.HP +limit +limit the number of state table entries that this rule can create to +the number given after limit. A rule that has a limit specified is +always permitted that many state table entries, even if creating an +additional entry would cause the table to have more entries than the +otherwise global limit. +.IP +.nf +pass ... keep state(limit 100) +.fi +.HP +age +sets the timeout for the state entry when it sees packets going through +it. Additionally it is possible to set the tieout for the reply packets +that come back through the firewall to a different value than for the +forward path. allowing a short timeout to be set after the reply has +been seen and the state no longer required. +.RS +.PP +.nf +pass in quick proto icmp all icmp-type echo \\ + keep state (age 3) +pass in quick proto udp from any \\ + to any port = 53 keep state (age 30/1) +.fi +.RE +.HP +strict +only has an impact when used with TCP. It forces all packets that are +allowed through the firewall to be sequential: no out of order delivery +of packets is allowed. This can cause significant slowdown for some +connections and may stall others. Use with caution. +.IP +.nf +pass in proto tcp ... keep state(strict) +.fi +.HP +noicmperr +prevents ICMP error packets from being able to match state table entries +created with this flag using the contents of the original packet included. +.IP +.nf +pass ... keep state(noicmperr) +.fi +.HP +sync +indicates to IPFilter that it needs to provide information to the user +land daemons responsible for syncing other machines state tables up +with this one. +.IP +.nf +pass ... keep state(sync) +.fi +.HP +nolog +do not generate any log records for the creation or deletion of state +table entries. +.IP +.nf +pass ... keep state(nolog) +.fi +.HP +icmp-head +rather than just precent ICMP error packets from being able to match +state table entries, allow an ACL to be processed that can filter in or +out ICMP error packets based as you would with normal firewall rules. +The icmp-head option requires a filter rule group number or name to +be present, just as you would use with head. +.RS +.PP +.nf +pass in quick proto tcp ... keep state(icmp-head 101) +block in proto icmp from 10.0.0.0/8 to any group 101 +.fi +.RE +.HP +max-srcs +allows the number of distinct hosts that can create a state entry to +be defined. +.IP +.nf +pass ... keep state(max-srcs 100) +pass ... keep state(limit 1000, max-srcs 100) +.fi +.HP +max-per-src +whilst max-srcs limits the number of individual hosts that may cause +the creation of a state table entry, each one of those hosts is still +table to fill up the state table with new entries until the global +maximum is reached. This option allows the number of state table entries +per address to be limited. +.IP +.nf +pass ... keep state(max-srcs 100, max-per-src 1) +pass ... keep state(limit 100, max-srcs 100, max-per-src 1) .fi .IP -The various flag symbols may be used in combination, so that "SA" -would represent a SYN-ACK combination present in a packet. There is -nothing preventing the specification of combinations, such as "SFR", -that would not normally be generated by law-abiding TCP -implementations. However, to guard against weird aberrations, it is -necessary to state which flags you are filtering against. To allow -this, it is possible to set a mask indicating which TCP flags you wish -to compare (i.e., those you deem significant). This is done by -appending "/" to the set of TCP flags you wish to match -against, e.g.: -.LP +Whilst these two rules might seem identical, in that they both +ultimately limit the number of hosts and state table entries created +from the rule to 100, there is a subtle difference: the second will +always allow up to 100 state table entries to be created whereas the +first may not if the state table fills up from other rules. +.IP +Further, it is possible to specify a netmask size after the per-host +limit that enables the per-host limit to become a per-subnet or +per-network limit. +.IP .nf - ... flags S - # becomes "flags S/AUPRFS" and will match - # packets with ONLY the SYN flag set. +pass ... keep state(max-srcs 100, max-per-src 1/24) +.fi +.IP +If there is no IP protocol implied by addresses or other features of +the rule, IPFilter will assume that no netmask is an all ones netmask +for both IPv4 and IPv6. +.SS Tieing down a connection +.PP +For any connection that transits a firewall, each packet will be seen +twice: once going in and once going out. Thus a connection has 4 flows +of packets: +.HP +forward +inbound packets +.HP +forward +outbound packets +.HP +reverse +inbound packets +.HP +reverse +outbound packets +.PP +IPFilter allows you to define the network interface to be used at all +four points in the flow of packets. For rules that match inbound packets, +out-via is used to specify which interfaces the packets go out, For rules +that match outbound packets, in-via is used to match the inbound packets. +In each case, the syntax generalises to this: +.PP +.nf +pass ... in on forward-in,reverse-in \\ + out-via forward-out,reverse-out ... - ... flags SA - # becomes "flags SA/AUPRFS" and will match any - # packet with only the SYN and ACK flags set. +pass ... out on forward-out,reverse-out \\ + in-via forward-in,reverse-in ... +.fi +.PP +An example that pins down all 4 network interfaces used by an ssh +connection might look something like this: +.PP +.nf +pass in on bge0,bge1 out-via bge1,bge0 proto tcp \\ + from any to any port = 22 flags S keep state +.fi +.SS Working with packet fragments +.PP +Fragmented packets result in 1 packet containing all of the layer 3 and 4 +header information whilst the data is split across a number of other packets. +.PP +To enforce access control on fragmented packets, one of two approaches +can be taken. The first is to allow through all of the data fragments +(those that made up the body of the original packet) and rely on matching +the header information in the "first" fragment, when it is seen. The +reception of body fragments without the first will result in the receiving +host being unable to completely reassemble the packet and discarding all +of the fragments. The following three rules deny all fragmented packets +from being received except those that are UDP and even then only allows +those destined for port 2049 to be completed. +.PP +.nf +block in all with frags +pass in proto udp from any to any with frag-body +pass in proto udp from any to any port = 2049 with frags +.fi +.PP +Another mechanism that is available is to track "fragment state". +This relies on the first fragment of a packet that arrives to be +the fragment that contains all of the layer 3 and layer 4 header +information. With the receipt of that fragment before any other, +it is possible to determine which other fragments are to be allowed +through without needing to explicitly allow all fragment body packets. +An example of how this is done is as follows: +.PP +.nf +pass in proto udp from any prot = 2049 to any with frags keep fags +.fi +.SH Building a tree of rules +.PP +Writing your filter rules as one long list of rules can be both inefficient +in terms of processing the rules and difficult to understand. To make the +construction of filter rules easier, it is possible to place them in groups. +A rule can be both a member of a group and the head of a new group. +.PP +Using filter groups requires at least two rules: one to be in the group +one one to send matchign packets to the group. If a packet matches a +filtre rule that is a group head but does not match any of the rules +in that group, then the packet is considered to have matched the head +rule. +.PP +Rules that are a member of a group contain the word group followed by +either a name or number that defines which group they're in. Rules that +form the branch point or starting point for the group must use the +word head, followed by either a group name or number. If rules are +loaded in that define a group but there is no matching head then they +will effectively be orphaned rules. It is possible to have more than +one head rule point to the same group, allowing groups to be used +like subroutines to implement specific common policies. +.PP +A common use of filter groups is to define head rules that exist in the +filter "main line" for each direction with the interfaces in use. For +example: +.PP +.nf +block in quick on bge0 all head 100 +block out quick on bge0 all head 101 +block in quick on fxp0 all head internal-in +block out quick on fxp0 all head internal-out +pass in quick proto icmp all icmp-type echo group 100 +.fi +.PP +In the above set of rules, there are four groups defined but only one +of them has a member rule. The only packets that would be allowed +through the above ruleset would be ICMP echo packets that are +received on bge0. +.PP +Rules can be both a member of a group and the head of a new group, +allowing groups to specialise. +.PP +.nf +block in quick on bge0 all head 100 +block in quick proto tcp all head 1006 group 100 +.fi +.PP +Another use of filter rule groups is to provide a place for rules to +be dynamically added without needing to worry about their specific +ordering amongst the entire ruleset. For example, if I was using this +simple ruleset: +.PP +.nf +block in quick all with bad +block in proto tcp from any to any port = smtp head spammers +pass in quick proto tcp from any to any port = smtp flags S keep state +.fi +.PP +and I was getting lots of connections to my email server from 10.1.1.1 +to deliver spam, I could load the following rule to complement the above: +.IP +.nf +block in quick from 10.1.1.1 to any group spammers +.fi +.SS Decapsulation +.PP +Rule groups also form a different but vital role for decapsulation rules. +With the following simple rule, if IPFilter receives an IP packet that has +an AH header as its layer 4 payload, IPFilter would adjust its view of the +packet internally and then jump to group 1001 using the data beyond the +AH header as the new transport header. +.PP +.nf +decapsulate in proto ah all head 1001 +.fi +.PP +For protocols that +are recognised as being used with tunnelling or otherwise encapsulating +IP protocols, IPFilter is able to decide what it has on the inside +without any assistance. Some tunnelling protocols use UDP as the +transport mechanism. In this case, it is necessary to instruct IPFilter +as to what protocol is inside UDP. +.PP +.nf +decapsulate l5-as(ip) in proto udp from any \\ + to any port = 1520 head 1001 +.fi +.PP +Currently IPFilter only supports finding IPv4 and IPv6 headers +directly after the UDP header. +.PP +If a packet matches a decapsulate rule but fails to match any of the rules +that are within the specified group, processing of the packet continues +to the next rule after the decapsulate and IPFilter's internal view of the +packet is returned to what it was prior to the decapsulate rule. +.PP +It is possible to construct a decapsulate rule without the group +head at the end that ipf(8) will accept but such rules will not +result in anything happening. +.SS Policy Based Routing +.PP +With firewalls being in the position they often are, at the boundary +of different networks connecting together and multiple connections that +have different properties, it is often desirable to have packets flow +in a direction different to what the routing table instructs the kernel. +These decisions can often be extended to changing the route based on +both source and destination address or even port numbers. +.PP +To support this kind of configuration, IPFilter allows the next hop +destination to be specified with a filter rule. The next hop is given +with the interface name to use for output. The syntax for this is +interface:ip.address. It is expected that the address given as the next +hop is directly connected to the network to which the interface is. +.PP +.nf +pass in on bge0 to bge1:1.1.1.1 proto tcp \\ + from 1.1.2.3 to any port = 80 flags S keep state +.fi +.PP +When this feature is combined with stateful filtering, it becomes +possible to influence the network interface used to transmit packets +in both directions because we now have a sense for what its reverse +flow of packets is. +.PP +.nf +pass in on bge0 to bge1:1.1.1.1 reply-to hme1:2.1.1.2 \\ + proto tcp from 1.1.2.3 to any port = 80 flags S keep state +.fi +.PP +If the actions of the routing table are perfectly acceptable, but +you would like to mask the presence of the firewall by not changing +the TTL in IP packets as they transit it, IPFilter can be instructed +to do a "fastroute" action like this: +.PP +.nf +pass in on bge0 fastroute proto icmp all +.fi +.PP +This should be used with caution as it can lead to endless packet +loops. Additionally, policy based routing does not change the IP +header's TTL value. +.PP +A variation on this type of rule supports a duplicate of the original +packet being created and sent out a different network. This can be +useful for monitoring traffic and other purposes. +.PP +.nf +pass in on bge0 to bge1:1.1.1.1 reply-to hme1:2.1.1.2 \\ + dup-to fxp0:10.0.0.1 proto tcp from 1.1.2.3 \\ + to any port = 80 flags S keep state +.fi +.SS Matching IPv4 options +.PP +The design for IPv4 allows for the header to be upto 64 bytes long, +however most traffic only uses the basic header which is 20 bytes long. +The other 44 bytes can be uesd to store IP options. These options are +generally not necessary for proper interaction and function on the +Internet today. For most people it is sufficient to block and drop +all packets that have any options set. This can be achieved with this +rule: +.PP +.nf +block in quick all with ipopts +.fi +.PP +This rule is usually placed towards the top of the configuration +so that all incoming packets are blocked. +.PP +If you wanted to allow in a specific IP option type, the syntax +changes slightly: +.PP +.nf +pass in quick proto igmp all with opt rtralrt +.fi +.PP +The following is a list of IP options that most people encounter and +what their use/threat is. +.HP +lsrr +(loose source route) the sender of the packet includes a list of addresses +that they wish the packet to be routed through to on the way to the +destination. Because replies to such packets are expected to use the +list of addresses in reverse, hackers are able to very effectively use +this header option in address spoofing attacks. +.HP +rr +(record route) the sender allocates some buffer space for recording the +IP address of each router that the packet goes through. This is most often +used with ping, where the ping response contains a copy of all addresses +from the original packet, telling the sender what route the packet took +to get there. Due to performance and security issues with IP header +options, this is almost no longer used. +.HP +rtralrt +(router alert) this option is often used in IGMP messages as a flag to +routers that the packet needs to be handled differently. It is unlikely +to ever be received from an unknown sender. It may be found on LANs or +otherwise controlled networks where the RSVP protocol and multicast +traffic is in heavy use. +.HP +ssrr +(strict source route) the sender of the packet includes a list of addresses +that they wish the packet to be routed through to on the way to the +destination. Where the lsrr option allows the sender to specify only +some of the nodes the packet must go through, with the ssrr option, +every next hop router must be specified. +.PP +The complete list of IPv4 options that can be matched on is: +addext (Address Extention), +cipso (Classical IP Security Option), +dps (Dynamic Packet State), +e-sec (Extended Security), +eip (Extended Internet Protocol), +encode (ENCODE), +finn (Experimental Flow Control), +imitd (IMI Traffic Descriptor), +lsrr (Loose Source Route), +mtup (MTU Probe - obsolete), +mtur (MTU response - obsolete), +nop (No Operation), +nsapa (NSAP Address), +rr (Record Route), +rtralrt (Router Alert), +satid (Stream Identifier), +sdb (Selective Directed Broadcast), +sec (Security), +ssrr (Strict Source Route), +tr (Tracerote), +ts (Timestamp), +ump (Upstream Multicast Packet), +visa (Experimental Access Control) +and zsu (Experimental Measurement). +.SS Security with CIPSO and IPSO +.PP +IPFilter supports filtering on IPv4 packets using security attributes embedded +in the IP options part of the packet. These options are usually only used on +networks and systems that are using lablled security. Unless you know that +you are using labelled security and your networking is also labelled, it +is highly unlikely that this section will be relevant to you. +.PP +With the traditional IP Security Options (IPSO), packets can be tagged with +a security level. The following keywords are recognised and match with the +relevant RFC with respect to the bit patterns matched: +confid (confidential), +rserve-1 (1st reserved value), +rserve-2 (2nd reserved value), +rserve-3 (3rd reserved value), +rserve-4 (4th reserved value), +secret (secret), +topsecret (top secret), +unclass (unclassified). +.PP +.nf +block in quick all with opt sec-class unclass +pass in all with opt sec-class secret +.fi +.SS Matching IPv6 extension headers +.PP +Just as it is possible to filter on the various IPv4 header options, +so too it is possible to filter on the IPv6 extension headers that are +placed between the IPv6 header and the transport protocol header. +.PP +dstopts (destination options), +esp (encrypted, secure, payload), +frag (fragment), +hopopts (hop-by-hop options), +ipv6 (IPv6 header), +mobility (IP mobility), +none, +routing. +.SS Logging +.PP +There are two ways in which packets can be logged with IPFilter. The +first is with a rule that specifically says log these types of packets +and the second is a qualifier to one of the other keywords. Thus it is +possible to both log and allow or deny a packet with a single rule. +.PP +.nf +pass in log quick proto tcp from any to any port = 22 +.fi +.PP +When using stateful filtering, the log action becomes part of the result +that is remembered about a packet. Thus if the above rule was qualified +with keep state, every packet in the connection would be logged. To only +log the first packet from every packet flow tracked with keep state, it +is necessary to indicate to IPFilter that you only wish to log the first +packet. +.PP +.nf +pass in log first quick proto tcp from any to any port = 22 \\ + flags S keep state +.fi +.PP +If it is a requirement that the logging provide an accurate representation +of which connections are allowed, the log action can be qualified with the +option or-block. This allows the administrator to instruct IPFilter to +block the packet if the attempt to record the packet in IPFilter's kernel +log records (which have an upper bound on size) failed. Unless the system +shuts down or reboots, once a log record is written into the kernel buffer, +it is there until ipmon(8) reads it. +.PP +.nf +block in log proto tcp from any to any port = smtp +pass in log or-block first quick proto tcp from any \\ + to any port = 22 flags S keep state +.fi +.PP +By default, IPFilter will only log the header portion of a packet received +on the network. A portion of the body of a packet, upto 128 bytes, can also +be logged with the body keyword. ipmon(8) will display the contents of the +portion of the body logged in hex. +.PP +.nf +block in log body proto icmp all +.fi +.PP +When logging packets from ipmon(8) to syslog, by default ipmon(8) will +control what syslog facility and priority a packet will be logged with. +This can be tuned on a per rule basis like this: +.PP +.nf +block in quick log level err all with bad +pass in log level local1.info proto tcp \\ + from any to any port = 22 flags S keep state +.fi +.PP +ipfstat(8) reports how many packets have been successfully logged and how +many failed attempts to log a packet there were. +.SS Filter rule comments +.PP +If there is a desire to associate a text string, be it an administrative +comment or otherwise, with an IPFilter rule, this can be achieved by giving +the filter rule a comment. The comment is loaded with the rule into the +kernel and can be seen when the rules are listed with ipfstat. +.PP +.nf +pass in quick proto tcp from any \\ + to port = 80 comment "all web server traffic is ok" +pass out quick proto tcp from any port = 80 \\ + to any comment "all web server traffic is ok" +.fi +.SS Tags +.PP +To enable filtering and NAT to correctly match up packets with rules, +tags can be added at with NAT (for inbound packets) and filtering (for +outbound packets.) This allows a filter to be correctly mated with its +NAT rule in the event that the NAT rule changed the packet in a way +that would mean it is not obvious what it was. +.PP +For inbound packets, IPFilter can match the tag used in the filter +rules with that set by NAT. For outbound rules, it is the reverse, +the filter sets the tag and the NAT rule matches up with it. +.PP +.nf +pass in ... match-tag(nat=proxy) +pass out ... set-tag(nat=proxy) +.fi +.PP +Another use of tags is to supply a number that is only used with logging. +When packets match these rules, the log tag is carried over into the +log file records generated by ipmon(8). With the correct use of tools +such as grep, extracting log records of interest is simplified. +.PP +.nf +block in quick log ... set-tag(log=33) +.fi +.SH Filter Rule Expiration +.PP +IPFilter allows rules to be added into the kernel that it will remove after +a specific period of time by specifying rule-ttl at the end of a rule. +When listing rules in the kernel using ipfstat(8), rules that are going +to expire will NOT display "rule-ttl" with the timeout, rather what will +be seen is a comment with how many ipfilter ticks left the rule has to +live. +.PP +The time to live is specified in seconds. +.PP +.nf +pass in on fxp0 proto tcp from any \\ + to port = 22 flags S keep state rule-ttl 30 +.fi +.SH Internal packet attributes +.PP +In addition to being able to filter on very specific network and transport +header fields, it is possible to filter on other attributes that IPFilter +attaches to a packet. These attributes are placed in a rule after the +keyword "with", as can be seen with frags and frag-body above. The +following is a list of the other attributes available: +.HP +oow +the packet's IP addresses and TCP ports match an existing entry in the +state table but the sequence numbers indicate that it is outside of the +accepted window. +.IP +.nf +block return-rst in quick proto tcp from any to any with not oow +.fi +.HP +bcast +this is set by IPFilter when it receives notification that the link +layer packet was a broadcast packet. No checking of the IP addresses +is performned to determine if it is a broadcast destination or not. +.IP +.nf +block in quick proto udp all with bcast +.fi +.HP +mcast +this is set by IPFilter when it receives notification that the link +layer packet was a multicast packet. No checking of the IP addresses +is performned to determine if it is a multicast destination or not. +.IP +.nf +pass in quick proto udp from any to any port = dns with mcast +.fi +.HP +mbcast +can be used to match a packet that is either a multicast or broadcast +packet at the link layer, as indicated by the operating system. +.IP +.nf +pass in quick proto udp from any to any port = ntp with mbcast +.fi +.HP +nat +the packet positively matched a NAT table entry. +.HP +bad +sanity checking of the packet failed. This could indicate that the +layer 3/4 headers are not properly formed. +.HP +bad-src +when reverse path verification is enabled, this flag will be set when +the interface the packet is received on does not match that which would +be used to send a packet out of to the source address in the received +packet. +.HP +bad-nat +an attempt to perform NAT on the packet failed. +.HP +not +each one of the attributes matched using the "with" keyword can also be +looked for to not be present. For example, to only allow in good packets, +I can do this: +.PP +.nf +block in all +pass in all with not bad +.fi +.SH Tuning IPFilter +.PP +The ipf.conf file can also be used to tune the behaviour of IPFilter, +allowing, for example, timeouts for the NAT/state table(s) to be set +along with their sizes. The presence and names of tunables may change +from one release of IPFilter to the next. The tunables that can be +changed via ipf.conf is the same as those that can be seen and modified +using the -T command line option to ipf(8). +.PP +NOTE: When parsing ipf.conf, ipf(8) will apply the settings before +loading any rules. Thus if your settings are at the top, these may +be applied whilst the rules not applied if there is an error further +down in the configuration file. +.PP +To set one of the values below, the syntax is simple: "set", followed +by the name of the tuneable to set and then the value to set it to. +.PP +.nf +set state_max 9999; +set state_size 10101; +.fi +.PP +A list of the currently available variables inside IPFilter that may +be tuned from ipf.conf are as follows: +.HP +active +set through -s command line switch of ipf(8). See ipf(8) for detals. +.HP +chksrc +when set, enables reverse path verification on source addresses and +for filters to match packets with bad-src attribute. +.HP +control_forwarding +when set turns off kernel forwarding when IPFilter is disabled or unloaded. +.HP +default_pass +the default policy - whether packets are blocked or passed, etc - is +represented by the value of this variable. It is a bit field and the +bits that can be set are found in . It is not +recommended to tune this value directly. +.HP +ftp_debug +set the debugging level of the in-kernel FTP proxy. +Debug messages will be printed to the system console. +.HP +ftp_forcepasv +when set the FTP proxy must see a PASV/EPSV command before creating +the state/NAT entries for the 227 response. +.HP +ftp_insecure +when set the FTP proxy will not wait for a user to login before allowing +data connections to be created. +.HP +ftp_pasvonly +when set the proxy will not create state/NAT entries for when it +sees either the PORT or EPRT command. +.HP +ftp_pasvrdr +when enabled causes the FTP proxy to create very insecure NAT/state +entries that will allow any connection between the client and server +hosts when a 227 reply is seen. Use with extreme caution. +.HP +ftp_single_xfer +when set the FTP proxy will only allow one data connection at a time. +.HP +hostmap_size +sets the size of the hostmap table used by NAT to store address mappings +for use with sticky rules. +.HP +icmp_ack_timeout +default timeout used for ICMP NAT/state when a reply packet is seen for +an ICMP state that already exists +.HP +icmp_minfragmtu +sets the minimum MTU that is considered acceptable in an ICMP error +before deciding it is a bad packet. +.HP +icmp_timeout +default timeout used for ICMP NAT/state when the packet matches the rule +.HP +ip_timeout +default timeout used for NAT/state entries that are not TCP/UDP/ICMP. +.HP +ipf_flags +.HP +ips_proxy_debug +this sets the debugging level for the proxy support code. +When enabled, debugging messages will be printed to the system console. +.HP +log_all +when set it changes the behaviour of "log body" to log the entire packet +rather than just the first 128 bytes. +.HP +log_size +sets the size of the in-kernel log buffer in bytes. +.HP +log_suppress +when set, IPFilter will check to see if the packet it is logging is +similar to the one it previously logged and if so, increases +the occurance count for that packet. The previously logged packet +must not have yet been read by ipmon(8). +.HP +min_ttl +is used to set the TTL value that packets below will be marked with +the low-ttl attribute. +.HP +nat_doflush +if set it will cause the NAT code to do a more aggressive flush of the +NAT table at the next opportunity. Once the flush has been done, the +value is reset to 0. +.HP +nat_lock +this should only be changed using ipfs(8) +.HP +nat_logging +when set, NAT will create log records that can be read from /dev/ipnat. +.HP +nat_maxbucket +maximum number of entries allowed to exist in each NAT hash bucket. +This prevents an attacker trying to load up the hash table with +entries in a single bucket, reducing performance. +.HP +nat_rules_size +size of the hash table to store map rules. +.HP +nat_table_max +maximum number of entries allowed into the NAT table +.HP +nat_table_size +size of the hash table used for NAT +.HP +nat_table_wm_high +when the fill percentage of the NAT table exceeds this mark, more +aggressive flushing is enabled. +.HP +nat_table_wm_low +this sets the percentage at which the NAT table's agressive flushing +will turn itself off at. +.HP +rdr_rules_size +size of the hash table to store rdr rules. +.HP +state_lock +this should only be changed using ipfs(8) +.HP +state_logging +when set, the stateful filtering will create log records +that can be read from /dev/ipstate. +.HP +state_max +maximum number of entries allowed into the state table +.HP +state_maxbucket +maximum number of entries allowed to exist in each state hash bucket. +This prevents an attacker trying to load up the hash table with +entries in a single bucket, reducing performance. +.HP +state_size +size of the hash table used for stateful filtering +.HP +state_wm_freq +this controls how often the agressive flushing should be run once the +state table exceeds state_wm_high in percentage full. +.HP +state_wm_high +when the fill percentage of the state table exceeds this mark, more +aggressive flushing is enabled. +.HP +state_wm_low +this sets the percentage at which the state table's agressive flushing +will turn itself off at. +.HP +tcp_close_wait +timeout used when a TCP state entry reaches the FIN_WAIT_2 state. +.HP +tcp_closed +timeout used when a TCP state entry is ready to be removed after either +a RST packet is seen. +.HP +tcp_half_closed +timeout used when a TCP state entry reaches the CLOSE_WAIT state. +.HP +tcp_idle_timeout +timeout used when a TCP state entry reaches the ESTABLISHED state. +.HP +tcp_last_ack +timeout used when a TCP NAT/state entry reaches the LAST_ACK state. +.HP +tcp_syn_received +timeout applied to a TCP NAT/state entry after SYN-ACK packet has been seen. +.HP +tcp_syn_sent +timeout applied to a TCP NAT/state entry after SYN packet has been seen. +.HP +tcp_time_wait +timeout used when a TCP NAT/state entry reaches the TIME_WAIT state. +.HP +tcp_timeout +timeout used when a TCP NAT/state entry reaches either the half established +state (one ack is seen after a SYN-ACK) or one side is in FIN_WAIT_1. +.HP +udp_ack_timeout +default timeout used for UDP NAT/state when a reply packet is seen for +a UDP state that already exists +.HP +udp_timeout +default timeout used for UDP NAT/state when the packet matches the rule +.HP +update_ipid +when set, turns on changing the IP id field in NAT'd packets to a random +number. +.SS Table of visible variables +.PP +A list of all of the tunables, their minimum, maximum and current +values is as follows. +.PP +.nf +Name Min Max Current +active 0 0 0 +chksrc 0 1 0 +control_forwarding 0 1 0 +default_pass 0 MAXUINT 134217730 +ftp_debug 0 10 0 +ftp_forcepasv 0 1 1 +ftp_insecure 0 1 0 +ftp_pasvonly 0 1 0 +ftp_pasvrdr 0 1 0 +ftp_single_xfer 0 1 0 +hostmap_size 1 MAXINT 2047 +icmp_ack_timeout 1 MAXINT 12 +icmp_minfragmtu 0 1 68 +icmp_timeout 1 MAXINT 120 +ip_timeout 1 MAXINT 120 +ipf_flags 0 MAXUINT 0 +ips_proxy_debug 0 10 0 +log_all 0 1 0 +log_size 0 524288 32768 +log_suppress 0 1 1 +min_ttl 0 1 4 +nat_doflush 0 1 0 +nat_lock 0 1 0 +nat_logging 0 1 1 +nat_maxbucket 1 MAXINT 22 +nat_rules_size 1 MAXINT 127 +nat_table_max 1 MAXINT 30000 +nat_table_size 1 MAXINT 2047 +nat_table_wm_high 2 100 99 +nat_table_wm_low 1 99 90 +rdr_rules_size 1 MAXINT 127 +state_lock 0 1 0 +state_logging 0 1 1 +state_max 1 MAXINT 4013 +state_maxbucket 1 MAXINT 26 +state_size 1 MAXINT 5737 +state_wm_freq 2 999999 20 +state_wm_high 2 100 99 +state_wm_low 1 99 90 +tcp_close_wait 1 MAXINT 480 +tcp_closed 1 MAXINT 60 +tcp_half_closed 1 MAXINT 14400 +tcp_idle_timeout 1 MAXINT 864000 +tcp_last_ack 1 MAXINT 60 +tcp_syn_received 1 MAXINT 480 +tcp_syn_sent 1 MAXINT 480 +tcp_time_wait 1 MAXINT 480 +tcp_timeout 1 MAXINT 480 +udp_ack_timeout 1 MAXINT 24 +udp_timeout 1 MAXINT 240 +update_ipid 0 1 0 +.fi +.SH Calling out to internal functions +.PP +IPFilter provides a pair of functions that can be called from a rule +that allow for a single rule to jump out to a group rather than walk +through a list of rules to find the group. If you've got multiple +networks, each with its own group of rules, this feature may help +provide better filtering performance. +.PP +The lookup to find which rule group to jump to is done on either the +source address or the destination address but not both. +.PP +In this example below, we are blocking all packets by default but then +doing a lookup on the source address from group 1010. The two rules in +the ipf.conf section are lone members of their group. For an incoming +packet that is from 1.1.1.1, it will go through three rules: (1) the +block rule, (2) the call rule and (3) the pass rule for group 1020. +For a packet that is from 3.3.2.2, it will also go through three rules: +(1) the block rule, (2) the call rule and (3) the pass rule for group +1030. Should a packet from 3.1.1.1 arrive, it will be blocked as it +does not match any of the entries in group 1010, leaving it to only +match the first rule. +.PP +.nf +from ipf.conf +------------- +block in all +call now srcgrpmap/1010 in all +pass in proto tcp from any to any port = 80 group 1020 +pass in proto icmp all icmp-type echo group 1030 - ... flags S/SA - # will match any packet with just the SYN flag set - # out of the SYN-ACK pair; the common "establish" - # keyword action. "S/SA" will NOT match a packet - # with BOTH SYN and ACK set, but WILL match "SFP". +from ippool.conf +---------------- +group-map in role=ipf number=1010 + { 1.1.1.1 group = 1020, 3.3.0.0/16 group = 1030; }; .fi -.TP -.B icmp-type -is only effective when used with \fBproto icmp\fP and must NOT be used -in conjunction with \fBflags\fP. There are a number of types, which can be -referred to by an abbreviation recognised by this language, or the numbers -with which they are associated can be used. The most important from -a security point of view is the ICMP redirect. -.SH KEEP HISTORY +.SS IPFilter matching expressions .PP -The second last parameter which can be set for a filter rule is whether or not -to record historical information for that packet, and what sort to keep. The -following information can be kept: -.TP -.B state -keeps information about the flow of a communication session. State can -be kept for TCP, UDP, and ICMP packets. -.TP -.B frags -keeps information on fragmented packets, to be applied to later -fragments. +An experimental feature that has been added to filter rules is to use +the same expression matching that is available with various commands +to flush and list state/NAT table entries. The use of such an expression +precludes the filter rule from using the normal IP header matching. .PP -allowing packets which match these to flow straight through, rather -than going through the access control list. -.SH GROUPS -The last pair of parameters control filter rule "grouping". By default, all -filter rules are placed in group 0 if no other group is specified. To add a -rule to a non-default group, the group must first be started by creating a -group \fIhead\fP. If a packet matches a rule which is the \fIhead\fP of a -group, the filter processing then switches to the group, using that rule as -the default for the group. If \fBquick\fP is used with a \fBhead\fP rule, rule -processing isn't stopped until it has returned from processing the group. -.PP -A rule may be both the head for a new group and a member of a non-default -group (\fBhead\fP and \fBgroup\fP may be used together in a rule). -.TP -.B "head " -indicates that a new group (number n) should be created. -.TP -.B "group " -indicates that the rule should be put in group (number n) rather than group 0. -.SH LOGGING -.PP -When a packet is logged, with either the \fBlog\fP action or option, -the headers of the packet are written to the \fBipl\fP packet logging -pseudo-device. Immediately following the \fBlog\fP keyword, the -following qualifiers may be used (in order): -.TP -.B body -indicates that the first 128 bytes of the packet contents will be -logged after the headers. -.TP -.B first -If log is being used in conjunction with a "keep" option, it is recommended -that this option is also applied so that only the triggering packet is logged -and not every packet which thereafter matches state information. -.TP -.B or-block -indicates that, if for some reason the filter is unable to log the -packet (such as the log reader being too slow) then the rule should be -interpreted as if the action was \fBblock\fP for this packet. -.TP -.B "level " -indicates what logging facility and priority, or just priority with -the default facility being used, will be used to log information about -this packet using ipmon's -s option. -.PP -See ipl(4) for the format of records written -to this device. The ipmon(8) program can be used to read and format -this log. -.SH EXAMPLES -.PP -The \fBquick\fP option is good for rules such as: -\fC .nf -block in quick from any to any with ipopts +pass in exp { "tcp.sport 23 or tcp.sport 50" } keep state .fi +.SS Filter rules with BPF .PP -which will match any packet with a non-standard header length (IP -options present) and abort further processing of later rules, -recording a match and also that the packet should be blocked. +On platforms that have the BPF built into the kernel, IPFilter can be +built to allow BPF expressions in filter rules. This allows for packet +matching to be on arbitrary data in the packt. The use of a BPF expression +replaces all of the other protocol header matching done by IPFilter. .PP -The "fall-through" rule parsing allows for effects such as this: -.LP .nf - block in from any to any port < 6000 - pass in from any to any port >= 6000 - block in from any to any port > 6003 +pass in bpf-v4 { "tcp and (src port 23 or src port 50)" } \\ + keep state .fi .PP -which sets up the range 6000-6003 as being permitted and all others being -denied. Note that the effect of the first rule is overridden by subsequent -rules. Another (easier) way to do the same is: -.LP +These rules tend to be +write-only because the act of compiling the filter expression into the +BPF instructions loaded into the kernel can make it difficut to +accurately reconstruct the original text filter. The end result is that +while ipf.conf() can be easy to read, understanding the output from +ipfstat might not be. +.SH VARIABLES +.PP +This configuration file, like all others used with IPFilter, supports the +use of variable substitution throughout the text. +.PP .nf - block in from any to any port 6000 <> 6003 - pass in from any to any port 5999 >< 6004 +nif="ppp0"; +pass in on $nif from any to any .fi .PP -Note that both the "block" and "pass" are needed here to effect a -result as a failed match on the "block" action does not imply a pass, -only that the rule hasn't taken effect. To then allow ports < 1024, a -rule such as: -.LP +would become +.PP .nf - pass in quick from any to any port < 1024 +pass in on ppp0 from any to any .fi .PP -would be needed before the first block. To create a new group for -processing all inbound packets on le0/le1/lo0, with the default being to block -all inbound packets, we would do something like: -.LP -.nf - block in all - block in quick on le0 all head 100 - block in quick on le1 all head 200 - block in quick on lo0 all head 300 -.fi +Variables can be used recursively, such as 'foo="$bar baz";', so long as +$bar exists when the parser reaches the assignment for foo. .PP - -and to then allow ICMP packets in on le0, only, we would do: -.LP -.nf - pass in proto icmp all group 100 -.fi -.PP -Note that because only inbound packets on le0 are used processed by group 100, -there is no need to respecify the interface name. Likewise, we could further -breakup processing of TCP, etc, as follows: -.LP -.nf - block in proto tcp all head 110 group 100 - pass in from any to any port = 23 group 110 -.fi -.PP -and so on. The last line, if written without the groups would be: -.LP -.nf - pass in on le0 proto tcp from any to any port = telnet -.fi -.PP -Note, that if we wanted to say "port = telnet", "proto tcp" would -need to be specified as the parser interprets each rule on its own and -qualifies all service/port names with the protocol specified. +See +.B ipf(8) +for instructions on how to define variables to be used from a shell +environment. +.DT .SH FILES -/dev/ipauth +/dev/ipf +/etc/ipf.conf .br -/dev/ipl -.br -/dev/ipstate -.br -/etc/hosts -.br -/etc/services +/usr/share/examples/ipf Directory with examples. .SH SEE ALSO -ipftest(1), iptest(1), mkfilters(1), ipf(4), ipnat(5), ipf(8), ipfstat(8) +ipf(8), ipfstat(8), ippool.conf(5), ippool(8) diff --git a/contrib/ipfilter/man/ipfilter.4 b/contrib/ipfilter/man/ipfilter.4 index 09eb4db8f1af..10fd18e0606f 100644 --- a/contrib/ipfilter/man/ipfilter.4 +++ b/contrib/ipfilter/man/ipfilter.4 @@ -28,7 +28,7 @@ send back an ICMP error/TCP reset for blocked packets .IP keep packet state information for TCP, UDP and ICMP packet flows .IP -keep fragment state information for any IP packet, applying the same rule +keep fragment state information for any IP packet, applying the same rule to all fragments. .IP act as a Network Address Translator (NAT) @@ -53,7 +53,7 @@ On any arbitrary combination of TCP flags .IP "short" (fragmented) IP packets with incomplete headers can be filtered .IP -any of the 19 IP options or 8 registered IP security classes TOS (Type of +any of the 19 IP options or 8 registered IP security classes TOS (Type of Service) field in packets .PP To keep track of the performance of the IP packet filter, a logging device @@ -73,12 +73,12 @@ it matches a rule setup to look for suspicious packets .PP IP Filter keeps its own set of statistics on: .IP -packets blocked +packets blocked .IP packets (and bytes!) used for accounting .IP packets passed -.lP +.IP packets logged .IP attempts to log which failed (buffer full) @@ -87,7 +87,7 @@ and much more, for packets going both in and out. .SH Tools The current implementation provides a small set of tools, which can easily -be used and integrated with regular unix shells and tools. A brief description +be used and integrated with regular unix shells and tools. A brief description of the tools provided: .PP ipf(8) @@ -100,7 +100,7 @@ ipfs(8) is a utility to temporarily lock the IP Filter kernel tables (state tables and NAT mappings) and write them to disk. After that the system can be rebooted, and ipfs can be used to read these tables from disk and restore -them into the kernel. This way the system can be rebooted without the +them into the kernel. This way the system can be rebooted without the connections being terminated. .PP ipfstat(8) @@ -117,7 +117,7 @@ ipmon(8) reads buffered data from the logging device (default is /dev/ipl) for output to either: .IP -screen (standard output) +screen (standard output) .IP file .IP @@ -147,13 +147,13 @@ documented in ipf(4). Documentation on ioctl's and the format of data saved to the logging character device is provided in ipl(4) -so that you may develop your own applications to work with or in place of any +so that you may develop your own applications to work with or in place of any of the above. Similar, the interface to the NAT code is documented in ipnat(4). .SH PACKET PROCESSING FLOW -The following diagram illustrates the flow of TCP/IP packets through the +The following diagram illustrates the flow of TCP/IP packets through the various stages introduced by IP Filter. .PP .nf diff --git a/contrib/ipfilter/man/ipfilter.4.mandoc b/contrib/ipfilter/man/ipfilter.4.mandoc index 72534a759761..22e1f36450b6 100644 --- a/contrib/ipfilter/man/ipfilter.4.mandoc +++ b/contrib/ipfilter/man/ipfilter.4.mandoc @@ -30,7 +30,7 @@ send back an ICMP error/TCP reset for blocked packets .It keep packet state information for TCP, UDP and ICMP packet flows .It -keep fragment state information for any IP packet, applying the same rule +keep fragment state information for any IP packet, applying the same rule to all fragments. .It act as a Network Address Translator (NAT) @@ -57,7 +57,7 @@ On any arbitrary combination of TCP flags .It "short" (fragmented) IP packets with incomplete headers can be filtered .It -any of the 19 IP options or 8 registered IP security classes TOS (Type of +any of the 19 IP options or 8 registered IP security classes TOS (Type of Service) field in packets .El .Pp @@ -83,7 +83,7 @@ it matches a rule setup to look for suspicious packets IP Filter keeps its own set of statistics on: .Bl -bullet -offset indent -compact .It -packets blocked +packets blocked .It packets (and bytes!) used for accounting .It @@ -97,7 +97,7 @@ and much more, for packets going both in and out. .Sh Tools The current implementation provides a small set of tools, which can easily -be used and integrated with regular unix shells and tools. A brief description +be used and integrated with regular unix shells and tools. A brief description of the tools provided: .Pp .Xr ipf 8 @@ -111,7 +111,7 @@ described in is a utility to temporarily lock the IP Filter kernel tables (state tables and NAT mappings) and write them to disk. After that the system can be rebooted, and ipfs can be used to read these tables from disk and restore -them into the kernel. This way the system can be rebooted without the +them into the kernel. This way the system can be rebooted without the connections being terminated. .Pp .Xr ipfstat 8 @@ -129,7 +129,7 @@ reads buffered data from the logging device (default is /dev/ipl) for output to either: .Bl -bullet -offset indent -compact .It -screen (standard output) +screen (standard output) .It file .It @@ -152,7 +152,7 @@ aimed at. WARNING: this may crash machine(s) targeted! reads in a set of rules, from either stdin or a file and adds them to the kernels current list of active NAT rules. NAT rules can also be deleted using ipnat. The format of the configuration file to be used -with ipnat is described in +with ipnat is described in .Xr ipnat 5 . .Pp For use in your own programs (e.g. for writing of transparent application @@ -162,15 +162,15 @@ documented in Documentation on ioctl's and the format of data saved to the logging character device is provided in -.Xr ipl 4 -so that you may develop your own applications to work with or in place of any +.Xr ipl 4 +so that you may develop your own applications to work with or in place of any of the above. -Similar, the interface to the NAT code is documented in +Similar, the interface to the NAT code is documented in .Xr ipnat 4 . .Sh PACKET PROCESSING FLOW -The following diagram illustrates the flow of TCP/IP packets through the +The following diagram illustrates the flow of TCP/IP packets through the various stages introduced by IP Filter. .Pp .nf diff --git a/contrib/ipfilter/man/ipfstat.8 b/contrib/ipfilter/man/ipfstat.8 index 44ba8ba0d430..cea8d5f4fbb7 100644 --- a/contrib/ipfilter/man/ipfstat.8 +++ b/contrib/ipfilter/man/ipfstat.8 @@ -43,7 +43,7 @@ Display the accounting filter list and show bytes counted against each rule. .TP .B \-A Display packet authentication statistics. -.TP +.TP .B \-C This option is only valid in combination with \fB\-t\fP. Display "closed" states as well in the top. Normally, a TCP connection is @@ -145,8 +145,8 @@ The number is incremented every half\-second. .SH STATE TOP Using the \fB\-t\fP option \fBipfstat\fP will enter the state top mode. In this mode the state table is displayed similar to the way \fBtop\fP displays -the process table. The \fB\-C\fP, \fB\-D\fP, \fB\-P\fP, \fB\-S\fP and \fB\-T\fP -command line options can be used to restrict the state entries that will be +the process table. The \fB\-C\fP, \fB\-D\fP, \fB\-P\fP, \fB\-S\fP and \fB\-T\fP +command line options can be used to restrict the state entries that will be shown and to specify the frequency of display updates. .PP In state top mode, the following keys can be used to influence the displayed @@ -158,7 +158,7 @@ information: .TP \fBl\fP redraw the screen. .TP -\fBq\fP quit the program. +\fBq\fP quit the program. .TP \fBs\fP switch between different sorting criterion. .TP diff --git a/contrib/ipfilter/man/ipftest.1 b/contrib/ipfilter/man/ipftest.1 index 402195f318e1..10232d338d9f 100644 --- a/contrib/ipfilter/man/ipftest.1 +++ b/contrib/ipfilter/man/ipftest.1 @@ -143,7 +143,6 @@ are: # a TCP packet going out of le0 with the SYN flag set. out on le0 tcp 10.4.12.1,2245 10.1.1.1,23 S .fi -.LP .RE .DT .TP diff --git a/contrib/ipfilter/man/ipmon.5 b/contrib/ipfilter/man/ipmon.5 index 081fc0856bc1..95126f0c83c3 100644 --- a/contrib/ipfilter/man/ipmon.5 +++ b/contrib/ipfilter/man/ipmon.5 @@ -4,56 +4,213 @@ .SH NAME ipmon, ipmon.conf \- ipmon configuration file format .SH DESCRIPTION -The format for files accepted by ipmon is described by the following grammar: -.LP +The +.B ipmon.conf +file is optionally loaded by +.B ipmon +when it starts. Its primary purpose is to direct +.B ipmon +to do extra actions when it sees a specific log entry from the kernel. +.PP +A line in the +.B ipmon.conf +file is either a comment or a +.B match +line. Each line must have a matching segment and an action segment. +These are to the left and right of the word "do", respectively. +A comment line is any line that starts with a #. +.PP +.B NOTE: +This file differs from all other IPFilter configuration files because it +attempts to match every line with every log record received. It does +.B not +stop at the +.B first +match or only use the +.B last +match. +.PP +For the action segment, a +.B match +line can delivery output to one of three destinations: +\fBfile\fR, \fBemail\fR or \fBcommand\fR. For example: .nf -"match" "{" matchlist "}" "do" "{" doing "}" ";" - -matchlist ::= matching [ "," matching ] . -matching ::= direction | dstip | dstport | every | group | interface | - logtag | nattag | protocol | result | rule | srcip | srcport . - -dolist ::= doing [ "," doing ] . -doing ::= execute | save | syslog . - -direction ::= "in" | "out" . -dstip ::= "dstip" "=" ipv4 "/" number . -dstport ::= "dstport" "=" number . -every ::= "every" every-options . -execute ::= "execute" "=" string . -group ::= "group" "=" string | "group" "=" number . -interface ::= "interface" "=" string . -logtag ::= "logtag" "=" string | "logtag" "=" number . -nattag ::= "nattag" "=" string . -protocol ::= "protocol" "=" string | "protocol" "=" number . -result ::= "result" "=" result-option . -rule ::= "rule" "=" number . -srcip ::= "srcip" "=" ipv4 "/" number . -srcport ::= "srcport" "=" number . -type ::= "type" "=" ipftype . -ipv4 ::= number "." number "." number "." number . - -every-options ::= "second" | number "seconds" | "packet" | number "packets" . -result-option ::= "pass" | "block" | "short" | "nomatch" | "log" . -ipftype ::= "ipf" | "nat" | "state" . +match { type = ipf; } do { save("file:///var/log/ipf-log"); }; +match { type = nat; } do { syslog; }; +match { type = state; } do { execute("/bin/mail root"); }; .fi .PP -In addition, lines that start with a # are considered to be comments. +and is roughly described like this: +.PP +match { \fImatch-it ,match-it, ...\fP } do { \fIaction, action, ...\fP}; +.PP +where there can be a list of matching expressions and a list of actions +to perform if all of the matching expressions are matched up with by +the current log entry. +.PP +The lines above would save all ipf log entries to /var/log/ipf-log, send +all of the entries for NAT (ipnat related) to syslog and generate an email +to root for each log entry from the state tables. +.SH SYNTAX - MATCHING +.PP +In the above example, the matching segment was confined to matching on +the type of log entry generated. The full list of fields that can be +used here is: .TP -.SH OVERVIEW -.PP -The ipmon configuration file is used for defining rules to be executed when -logging records are read from -.B /dev/ipl. -.PP +direction +This option is used to match on log records generated for packets going +in or out. +.TP +dstip
+This option is used to match against the destination address associated +with the packet being logged. A "/mask" must be given and given in CIDR +notation (/0-/32) so to specify host 192.2.2.1, 192.2.2.1/32 must be given. +.TP +dstport +This option is used to match against the destination port in log entries. +A number must be given, symbolic names (such as those from /etc/services) +are not recognised by the parser. +.TP +every +This option is used to regulate how often an \fBipmon.conf\fR entry is +actioned in response to an otherwise matching log record from the kernel. +.TP +group +.TP +interface +This option is used to match against the network interface name associated +with the action causing the logging to happen. In general this will be the +network interface where the packet is seen by IPFilter. +.TP +logtag +This option is used to match against tags set by ipf rules in \fBipf.conf\fR. +These tags are set with "set-tag(log=100)" appended to filter rules. +.TP +nattag +This option is used to match against tags set by NAT rules in \fBipnat.conf\fR. +.TP +protocol +This option is used to match against the IP protocol field in the packet +being logged. +.TP +result +This option is used to match against the result of packet matching in the +kernel. If a packet is logged, using a \fBlog\fR rule in \fBipf.conf\fR +then it will match "log" here. The "nomatch" option is for use with +matching log records generated for all packets as the default. +.TP +rule +This option is used to match against the \fInumber\fR of the rule +causing the record to be generated. The \fInumber\fR of a rule can be +observed using "ipfstat -ion". +.TP +srcip
+This option is used to match against the source address associated +with the packet being logged. A "/mask" must be given and given in CIDR +notation (/0-/32) so to specify host 192.2.2.1, 192.2.2.1/32 must be given. +.TP +srcport +This option is used to match against the source port in log entries. +A number must be given, symbolic names (such as those from /etc/services) +are not recognised by the parser. +.TP +type +The format for files accepted by ipmon is described by the following grammar: +.B NOTE: At present, only IPv4 matching is available for source/destination address matching. +.SH SYNTAX - ACTIONS +The list of actions supported is as follows: +.TP +save("file://") +save("raw://") +Write out the log record to the filename given. This file will be closed +and reopened on receipt of a SIGHUP. If the \fIraw\fP target is used, +binary log data, as read from the kernel, is written out rather than a +text log record. The filename should be an absolute target, including +the root directory. Thus, saving to /var/log/ipmon.log would be, as an +example, save("file:///var/log/ipmon.log"). +.TP +syslog(".") +syslog(".") +syslog(".") +To log a text record via syslog, the \fBsyslog\fP action word is used. +The facility used by default is determined at first by the default +compiled into \fBipmon\fP (usually LOG_LOCAL0), which can be changed +via the command line (-L ) or in an \fBipf.conf\fP rule +using the \fIlevel\fP option with logging. If the facility is +specified here, it takes precedence over all other settings. +The same applies to the syslog priority. By default, ipmon will +determine a priority for the packet, depending on whether or not it +has been blocked, passed, etc. It is possible to force the complete +facility/priority value for each log entry or to choose to replace +only one of them. +.TP +execute("") +The +.B execute +action runs the specified command each time the log entry matches +and feeds the log entry, as text, to the command being executed. +The command string given is executed using /bin/sh. +.TP +nothing +Literally, do nothing. Use this if you want to be verbose in your config +file about doing nothing for a particular log record. +.SH PLUGIN ACTIONS +It is possible to configure +.B ipmon +to use externally supplied modules to save log entries with. +These are added to +.B ipmon +using the +.I load_action +configuration line. The syntax of this line is: +.nf + +load_action ; +.fi +.TP +name +is a short name for the action. It does not need to correspond to the +name of the library file, but inside the library file, the functions +.B destroy +, +.B parse +and +.B store +must be present. +.TP +path +specifies the path in the filesystem to the shared object +that contains the implementation of the new action. After the new +action has been declared using +.I load_action +it can then be used in any +.I do +statement. +.SH EXAMPLES +.PP +Some further examples are: +.nf + +# +# log everything to syslog local4, regardless +# +match { ; } do { syslog("local4."); }; +# +# keep a local copy of things packets to/from port 80 +# +match { srcport = 80; } do { save("file:///var/log/web"); }; +match { dstport = 80; } do { save("file:///var/log/web"); }; +# +load_action local "/usr/lib/libmyaction.so"; +match { dstip 127.0.0.1; } do { local("local options"); }; +# +.fi .SH MATCHING .PP -Each rule for ipmon consists of two primary segments: the first describes how -the log record is to be matched, the second defines what action to take if -there is a positive match. All entries of the rules present in the file are +All entries of the rules present in the file are compared for matches - there is no first or last rule match. .SH FILES /dev/ipl diff --git a/contrib/ipfilter/man/ipnat.4 b/contrib/ipfilter/man/ipnat.4 index 095e4e5e1904..80c5ba444708 100644 --- a/contrib/ipfilter/man/ipnat.4 +++ b/contrib/ipfilter/man/ipnat.4 @@ -30,7 +30,6 @@ These ioctl's are implemented as being routing ioctls and thus the same rules for the various routing ioctls and the file descriptor are employed, mainly being that the fd must be that of the device associated with the module (i.e., /dev/ipl). -.LP .PP The structure used with the NAT interface is described below: .LP @@ -65,7 +64,6 @@ Recognised values for in_redir: #define NAT_MAP 0 #define NAT_REDIRECT 1 .fi -.PP .LP \fBNAT statistics\fP Statistics on the number of packets mapped, going in and out are kept, diff --git a/contrib/ipfilter/man/ipnat.5 b/contrib/ipfilter/man/ipnat.5 index 6d3f9bcff457..69163fc14407 100644 --- a/contrib/ipfilter/man/ipnat.5 +++ b/contrib/ipfilter/man/ipnat.5 @@ -2,159 +2,671 @@ .\" .TH IPNAT 5 .SH NAME -ipnat, ipnat.conf \- IP NAT file format +ipnat, ipnat.conf \- IPFilter NAT file format .SH DESCRIPTION -The format for files accepted by ipnat is described by the following grammar: -.LP -.nf -ipmap :: = mapblock | redir | map . - -map ::= mapit ifname lhs "->" dstipmask [ mapicmp | mapport | mapproxy ] - mapoptions . -mapblock ::= "map-block" ifname lhs "->" ipmask [ ports ] mapoptions . -redir ::= "rdr" ifname rlhs "->" ip [ "," ip ] rdrport rdroptions . - -lhs ::= ipmask | fromto . -rlhs ::= ipmask dport | fromto . -dport ::= "port" portnum [ "-" portnum ] . -ports ::= "ports" numports | "auto" . -rdrport ::= "port" portnum . -mapit ::= "map" | "bimap" . -fromto ::= "from" object "to" object . -ipmask ::= ip "/" bits | ip "/" mask | ip "netmask" mask . -dstipmask ::= ipmask | "range" ip "-" ip . -mapicmp ::= "icmpidmap" "icmp" number ":" number . -mapport ::= "portmap" tcpudp portspec . -mapoptions ::= [ tcpudp ] [ "frag" ] [ age ] [ clamp ] . -rdroptions ::= rdrproto [ rr ] [ "frag" ] [ age ] [ clamp ] [ rdrproxy ] . - -object :: = addr [ port-comp | port-range ] . -addr :: = "any" | nummask | host-name [ "mask" ipaddr | "mask" hexnumber ] . -port-comp :: = "port" compare port-num . -port-range :: = "port" port-num range port-num . -rdrproto ::= tcpudp | protocol . - -rr ::= "round-robin" . -age ::= "age" decnumber [ "/" decnumber ] . -clamp ::= "mssclamp" decnumber . -tcpudp ::= "tcp/udp" | protocol . -mapproxy ::= "proxy" "port" port proxy-name '/' protocol -rdrproxy ::= "proxy" proxy-name . - -protocol ::= protocol-name | decnumber . -nummask ::= host-name [ "/" decnumber ] . -portspec ::= "auto" | portnumber ":" portnumber . -port ::= portnumber | port-name . -portnumber ::= number { numbers } . -ifname ::= 'A' - 'Z' { 'A' - 'Z' } numbers . - -numbers ::= '0' | '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9' . -.fi +.PP +The +.B ipnat.conf +file is used to specify rules for the Network Address Translation (NAT) +component of IPFilter. To load rules specified in the +.B ipnat.conf +file, the +.B ipnat(8) +program is used. .PP For standard NAT functionality, a rule should start with \fBmap\fP and then proceeds to specify the interface for which outgoing packets will have their -source address rewritten. +source address rewritten. Following this it is expected that the old source +address, and optionally port number, will be specified. .PP -Packets which will be rewritten can only be selected by matching the original -source address. A netmask must be specified with the IP address. +In general, all NAT rules conform to the following layout: +the first word indicates what type of NAT rule is present, this is followed +by some stanzas to match a packet, followed by a "->" and this is then +followed by several more stanzas describing the new data to be put in the +packet. .PP -The address selected for replacing the original is chosen from an IP#/netmask -pair. A netmask of all 1's indicating a hostname is valid. A netmask of -31 1's (255.255.255.254) is considered invalid as there is no space for -allocating host IP#'s after consideration for broadcast and network -addresses. +In this text and in others, +use of the term "left hand side" (LHS) when talking about a NAT rule refers +to text that appears before the "->" and the "right hand side" (RHS) for text +that appears after it. In essence, the LHS is the packet matching and the +RHS is the new data to be used. +.SH VARIABLES .PP -When remapping TCP and UDP packets, it is also possible to change the source -port number. Either TCP or UDP or both can be selected by each rule, with a -range of port numbers to remap into given as \fBport-number:port-number\fP. -.SH COMMANDS -There are four commands recognised by IP Filter's NAT code: -.TP +This configuration file, like all others used with IPFilter, supports the +use of variable substitution throughout the text. +.nf + +nif="ppp0"; +map $nif 0/0 -> 0/32 +.fi +.PP +would become +.nf + +map ppp0 0/0 -> 0/32 +.fi +.PP +Variables can be used recursively, such as 'foo="$bar baz";', so long as +$bar exists when the parser reaches the assignment for foo. +.PP +See +.B ipnat(8) +for instructions on how to define variables to be used from a shell +environment. +.SH OUTBOUND SOURCE TRANSLATION (map'ing) +Changing the source address of a packet is traditionally performed using .B map -that is used for mapping one address or network to another in an unregulated -round robin fashion; -.TP -.B rdr -that is used for redirecting packets to one IP address and port pair to -another; -.TP -.B bimap -for setting up bidirectional NAT between an external IP address and an internal -IP address and +rules. Both the source address and optionally port number can be changed +according to various controls. +.PP +To start out with, a common rule used is of the form: +.nf + +map le0 0/0 -> 0/32 +.fi +.PP +Here we're saying change the source address of all packets going out of +le0 (the address/mask pair of 0/0 matching all packets) to that of the +interface le0 (0/32 is a synonym for the interface's own address at +the current point in time.) If we wanted to pass the packet through +with no change in address, we would write it as: +.nf + +map le0 0/0 -> 0/0 +.fi +.PP +If we only want to change a portion of our internal network and to a +different address that is routed back through this host, we might do: +.nf + +map le0 10.1.1.0/24 -> 192.168.55.3/32 +.fi +.PP +In some instances, we may have an entire subnet to map internal addresses +out onto, in which case we can express the translation as this: +.nf + +map le0 10.0.0.0/8 -> 192.168.55.0/24 +.fi +.PP +IPFilter will cycle through each of the 256 addresses in the 192.168.55.0/24 +address space to ensure that they all get used. +.PP +Of course this poses a problem for TCP and UDP, with many connections made, +each with its own port number pair. If we're unlucky, translations can be +dropped because the new address/port pair mapping already exists. To +mitigate this problem, we add in port translation or port mapping: +.nf + +map le0 10.0.0.0/8 -> 192.168.55.0/24 portmap tcp/udp auto +.fi +.PP +In this instance, the word "auto" tells IPFilter to calculate a private +range of port numbers for each address on the LHS to use without fear +of them being trampled by others. This can lead to problems if there are +connections being generated mire quickly than IPFilter can expire them. +In this instance, and if we want to get away from a private range of +port numbers, we can say: +.nf + +map le0 10.0.0.0/8 -> 192.168.55.0/24 portmap tcp/udp 5000:65000 +.fi +.PP +And now each connection through le0 will add to the enumeration of +the port number space 5000-65000 as well as the IP address subnet +of 192.168.55.0/24. +.PP +If the new addresses to be used are in a consecutive range, rather +than a complete subnet, we can express this as: +.nf + +map le0 10.0.0.0/8 -> range 192.168.55.10-192.168.55.249 + portmap tcp/udp 5000:65000 +.fi +.PP +This tells IPFilter that it has a range of 240 IP address to use, from +192.168.55.10 to 192.168.55.249, inclusive. +.PP +If there were several ranges of addresses for use, we can use each one +in a round-robin fashion as followed: +.nf + +map le0 10.0.0.0/8 -> range 192.168.55.10-192.168.55.29 + portmap tcp/udp 5000:65000 round-robin +map le0 10.0.0.0/8 -> range 192.168.55.40-192.168.55.49 + portmap tcp/udp 5000:65000 round-robin +.fi +.PP +To specify translation rules that impact a specific IP protocol, +the protocol name or number is appended to the rule like this: +.nf + +map le0 10.0.0.0/8 -> 192.168.55.0/24 tcp/udp +map le0 10.0.0.0/8 -> 192.168.55.1/32 icmp +map le0 10.0.0.0/8 -> 192.168.55.2/32 gre +.fi +.PP +For TCP connections exiting a connection such as PPPoE where the MTU is +slightly smaller than normal ethernet, it can be useful to reduce the +Maximum Segment Size (MSS) offered by the internal machines to match, +reducing the liklihood that the either end will attempt to send packets +that are too big and result in fragmentation. This is acheived using the +.B mssclamp +option with TCP +.B map +rules like this: +.nf + +map pppoe0 0/0 -> 0/32 mssclamp 1400 tcp +.fi +.PP +For ICMP packets, we can map the ICMP id space in query packets: +.nf + +map le0 10.0.0.0/8 -> 192.168.55.1/32 icmpidmap icmp 1000:20000 +.fi +.PP +If we wish to be more specific about our initial matching criteria on the +LHS, we can expand to using a syntax more similar to that in +.B ipf.conf(5) +: +.nf + +map le0 from 10.0.0.0/8 to 26.0.0.0/8 -> + 192.168.55.1 +map le0 from 10.0.0.0/8 port > 1024 to 26.0.0.0/8 -> + 192.168.55.2 portmap 5000:9999 tcp/udp +map le0 from 10.0.0.0/8 ! to 26.0.0.0/8 -> + 192.168.55.3 portmap 5000:9999 tcp/udp +.fi .TP +.B NOTE: +negation matching with source addresses is +.B NOT +possible with +.B map +/ .B map-block -which sets up static IP address based translation, based on a algorithm to -squeeze the addresses to be translated into the destination range. -.SH MATCHING +rules. .PP -For basic NAT and redirection of packets, the address subject to change is used -along with its protocol to check if a packet should be altered. The packet -\fImatching\fP part of the rule is to the left of the "->" in each rule. -.PP -Matching of packets has now been extended to allow more complex compares. -In place of the address which is to be translated, an IP address and port -number comparison can be made using the same expressions available with -\fBipf\fP. A simple NAT rule could be written as: -.LP +The NAT code has builtin default timeouts for TCP, UDP, ICMP and another +for all other protocols. In general, the timeout for an entry to be +deleted shrinks once a reply packet has been seen (excluding TCP.) +If you wish to specify your own timeouts, this can be achieved either +by setting one timeout for both directions: .nf -map de0 10.1.0.0/16 -> 201.2.3.4/32 + +map le0 0/0 -> 0/32 gre age 30 +.fi +.PP +or setting a different timeout for the reply: +.nf + +map le0 from any to any port = 53 -> 0/32 age 60/10 udp +.fi +.PP +A pressing problem that many people encounter when using NAT is that the +address protocol can be embedded inside an application's communication. +To address this problem, IPFilter provides a number of built-in proxies +for the more common trouble makers, such as FTP. These proxies can be +used as follows: +.nf + +map le0 0/0 -> 0/32 proxy port 21 ftp/tcp +.fi +.PP +In this rule, the word "proxy" tells us that we want to connect up this +translation with an internal proxy. The "port 21" is an extra restriction +that requires the destination port number to be 21 if this rule is to be +activated. The word "ftp" is the proxy identifier that the kernel will +try and resolve internally, "tcp" the protocol that packets must match. +.PP +See below for a list of proxies and their relative staus. +.PP +To associate NAT rules with filtering rules, it is possible to set and +match tags during either inbound or outbound processing. At present the +tags for forwarded packets are not preserved by forwarding, so once the +packet leaves IPFilter, the tag is forgotten. For +.B map +rules, we can match tags set by filter rules like this: +.nf + +map le0 0/0 -> 0/32 proxy portmap 5000:5999 tag lan1 tcp +.fi +.PP +This would be used with "pass out" rules that includes a stanza such +as "set-tag (nat = lan1)". +.PP +If the interface in which packets are received is different from the +interface on which packets are sent out, then the translation rule needs +to be written to take this into account: +.nf + +map hme0,le0 0/0 -> 0/32 +.fi +.PP +Although this might seem counterintuitive, the interfaces when listed +in rules for +.B ipnat.conf +are always in the +.I inbound +, +.I outbound +order. In this case, hme0 would be the return interface and le0 would be +the outgoing interface. If you wish to allow return packets on any +interface, the correct syntax to use would be: +.nf + +map *,le0 0/0 -> 0/32 .fi .LP -or as -.LP +A special variant of +.B map +rules exists, called +.B map-block. +This command is intended for use when there is a large network to be mapped +onto a smaller network, where the difference in netmasks is upto 14 bits +difference in size. This is achieved by dividing the address space and +port space up to ensure that each source address has its own private range +of ports to use. For example, this rule: .nf -map de0 from 10.1.0.0/16 to any -> 201.2.3.4/32 + +map-block ppp0 172.192.0.0/16 -> 209.1.2.0/24 ports auto .fi +.PP +would result in 172.192.0.0/24 being mapped to 209.1.2.0/32 +with each address, from 172.192.0.0 to 172.192.0.255 having 252 ports of its +own. As opposed to the above use of \fBmap\fP, if for some reason the user +of (say) 172.192.0.2 wanted 260 simultaneous connections going out, they would +be limited to 252 with \fBmap-block\fP but would just \fImove on\fP to the next +IP address with the \fBmap\fP command. +.SS Extended matching +.PP +If it is desirable to match on both the source and destination of a packet +before applying an address translation to it, this can be achieved by using +the same from-to syntax as is used in \fBipf.conf\fP(5). What follows +applies equally to the +.B map +rules discussed above and +.B rdr +rules discussed below. A simple example is as follows: +.nf + +map bge0 from 10.1.0.0/16 to 192.168.1.0/24 -> 172.12.1.4 +.fi +.PP +This would only match packets that are coming from hosts that have a source +address matching 10.1.0.0/16 and a destination matching 192.168.1.0/24. +This can be expanded upon with ports for TCP like this: +.nf + +rdr bge0 from 10.1.0.0/16 to any port = 25 -> 127.0.0.1 port 2501 tcp +.fi +.PP +Where only TCP packets from 10.1.0.0/16 to port 25 will be redirected to +port 2501. +.PP +As with \fBipf.conf\fR(5), if we have a large set of networks or addresses +that we would like to match up with then we can define a pool using +\fBippool\fR(8) in \fBippool.conf\fR(5) and then refer to it in an +\fBipnat\fR rule like this: +.nf + +map bge0 from pool/100 to any port = 25 -> 127.0.0.1 port 2501 tcp +.fi +.TP +.B NOTE: +In this situation, the rule is considered to have a netmask of "0" and +thus is looked at last, after any rules with /16's or /24's in them, +.I even if +the defined pool only has /24's or /32's. Pools may also be used +.I wherever +the from-to syntax in \fBipnat.conf\fR(5) is allowed. +.SH INBOUND DESTINATION TRANSLATION (redirection) +.PP +Redirection of packets is used to change the destination fields in a packet +and is supported for packets that are moving \fIin\fP on a network interface. +While the same general syntax for +.B map +rules is supported, there are differences and limitations. +.PP +Firstly, by default all redirection rules target a single IP address, not +a network or range of network addresses, so a rule written like this: +.nf + +rdr le0 0/0 -> 192.168.1.0 +.fi +.PP +Will not spread packets across all 256 IP addresses in that class C network. +If you were to try a rule like this: +.nf + +rdr le0 0/0 -> 192.168.1.0/24 +.fi +.PP +then you will receive a parsing error. +.PP +The from-to source-destination matching used with +.B map +rules can be used with rdr rules, along with negation, however the +restriction moves - only a source address match can be negated: +.nf + +rdr le0 from 1.1.0.0/16 to any -> 192.168.1.3 +rdr le0 ! from 1.1.0.0/16 to any -> 192.168.1.4 +.fi +.PP +If there is a consective set of addresses you wish to spread the packets +over, then this can be done in one of two ways, the word "range" optional +to preserve: +.nf + +rdr le0 0/0 -> 192.168.1.1 - 192.168.1.5 +rdr le0 0/0 -> range 192.168.1.1 - 192.168.1.5 +.fi +.PP +If there are only two addresses to split the packets across, the +recommended method is to use a comma (",") like this: +.nf + +rdr le0 0/0 -> 192.168.1.1,192.168.1.2 +.fi +.PP +If there is a large group of destination addresses that are somewhat +disjoint in nature, we can cycle through them using a +.B round-robin +technique like this: +.nf + +rdr le0 0/0 -> 192.168.1.1,192.168.1.2 round-robin +rdr le0 0/0 -> 192.168.1.5,192.168.1.7 round-robin +rdr le0 0/0 -> 192.168.1.9 round-robin +.fi +.PP +If there are a large number of redirect rules and hosts being targetted +then it may be desirable to have all those from a single source address +be targetted at the same destination address. To achieve this, the +word +.B sticky +is appended to the rule like this: +.nf + +rdr le0 0/0 -> 192.168.1.1,192.168.1.2 sticky +rdr le0 0/0 -> 192.168.1.5,192.168.1.7 round-robin sticky +rdr le0 0/0 -> 192.168.1.9 round-robin sticky +.fi +.PP +The +.B sticky +feature can only be combined with +.B round-robin +and the use of comma. +.PP +For TCP and UDP packets, it is possible to both match on the destiantion +port number and to modify it. For example, to change the destination port +from 80 to 3128, we would use a rule like this: +.nf + +rdr de0 0/0 port 80 -> 127.0.0.1 port 3128 tcp +.fi +.PP +If a range of ports is given on the LHS and a single port is given on the +RHS, the entire range of ports is moved. For example, if we had this: +.nf + +rdr le0 0/0 port 80-88 -> 127.0.0.1 port 3128 tcp +.fi +.PP +then port 80 would become 3128, port 81 would become 3129, etc. If we +want to redirect a number of different pots to just a single port, an +equals sign ("=") is placed before the port number on the RHS like this: +.nf + +rdr le0 0/0 port 80-88 -> 127.0.0.1 port = 3128 tcp +.fi +.PP +In this case, port 80 goes to 3128, port 81 to 3128, etc. +.PP +As with +.B map +rules, it is possible to manually set a timeout using the +.B age +option, like this: +.nf + +rdr le0 0/0 port 53 -> 127.0.0.1 port 10053 udp age 5/5 +.fi +.PP +The use of proxies is not restricted to +.B map +rules and outbound sessions. Proxies can also be used with redirect +rules, although the syntax is slightly different: +.nf + +rdr ge0 0/0 port 21 -> 127.0.0.1 port 21 tcp proxy ftp +.fi +.PP +For +.B rdr +rules, the interfaces supplied are in the same order as +.B map +rules - input first, then output. In situations where the outgoing interface +is not certain, it is also possible to use a wildcard ("*") to effect a match +on any interface. +.nf + +rdr le0,* 0/0 -> 192.168.1.0 +.fi +.PP +A single rule, with as many options set as possible would look something like +this: +.nf + +rdr le0,ppp0 9.8.7.6/32 port 80 -> 1.1.1.1,1.1.1.2 port 80 tcp + round-robin frag age 40/40 sticky mssclamp 1000 tag tagged +.fi +.SH REWRITING SOURCE AND DESTINATION +.PP +Whilst the above two commands provide a lot of flexibility in changing +addressing fields in packets, often it can be of benefit to translate +\fIboth\fP source \fBand\fR destination at the same time or to change +the source address on input or the destination address on output. +Doing all of these things can be accomplished using +.B rewrite +NAT rules. +.PP +A +.B rewrite +rule requires the same level of packet matching as before, protocol and +source/destination information but in addition allows either +.B in +or +.B out +to be specified like this: +.nf + +rewrite in on ppp0 proto tcp from any to any port = 80 -> + src 0/0 dst 127.0.0.1,3128; +rewrite out on ppp0 from any to any -> + src 0/32 dst 10.1.1.0/24; +.fi +.PP +On the RHS we can specify both new source and destination information to place +into the packet being sent out. As with other rules used in +\fBipnat.conf\fR, there are shortcuts syntaxes available to use the original +address information (\fB0/0\fR) and the address associated with the network +interface (\fB0/32\fR.) For TCP and UDP, both address and port information +can be changed. At present it is only possible to specify either a range of +port numbers to be used (\fBX-Y\fR) or a single port number (\fB= X\fR) as +follows: +.nf + +rewrite in on le0 proto tcp from any to any port = 80 -> + src 0/0,2000-20000 dst 127.0.0.1,port = 3128; +.fi +.PP +There are four fields that are stepped through in enumerating the number +space available for creating a new destination: .LP -Only IP address and port numbers can be compared against. This is available -with all NAT rules. -.SH TRANSLATION +source address +.LP +source port +.LP +destination address +.LP +destination port .PP -To the right of the "->" is the address and port specification which will be -written into the packet providing it has already successfully matched the -prior constraints. The case of redirections (\fBrdr\fP) is the simplest: -the new destination address is that specified in the rule. For \fBmap\fP -rules, the destination address will be one for which the tuple combining -the new source and destination is known to be unique. If the packet is -either a TCP or UDP packet, the destination and source ports come into the -equation too. If the tuple already exists, IP Filter will increment the -port number first, within the available range specified with \fBportmap\fP -and if there exists no unique tuple, the source address will be incremented -within the specified netmask. If a unique tuple cannot be determined, then -the packet will not be translated. The \fBmap-block\fP is more limited in -how it searches for a new, free and unique tuple, in that it will used an -algorithm to determine what the new source address should be, along with the -range of available ports - the IP address is never changed and nor does the -port number ever exceed its allotted range. -.SH ICMPIDMAP +If one of these happens to be a static then it will be skipped and the next +one incremented. As an example: +.nf + +rewrite out on le0 proto tcp from any to any port = 80 -> + src 1.0.0.0/8,5000-5999 dst 2.0.0.0/24,6000-6999; +.fi .PP -ICMP messages can be divided into two groups: "errors" and "queries". ICMP -errors are generated as a response of another IP packet. IP Filter will take -care that ICMP errors that are the response of a NAT-ed IP packet are -handled properly. +The translated packets would be: +.LP +1st src=1.0.0.1,5000 dst=2.0.0.1,6000 +.LP +2nd src=1.0.0.2,5000 dst=2.0.0.1,6000 +.LP +3rd src=1.0.0.2,5001 dst=2.0.0.1,6000 +.LP +4th src=1.0.0.2,5001 dst=2.0.0.2,6000 +.LP +5th src=1.0.0.2,5001 dst=2.0.0.2,6001 +.LP +6th src=1.0.0.3,5001 dst=2.0.0.2,6001 .PP -For 4 types of ICMP queries (echo request, timestamp request, information -request and address mask request) IP Filter supports an additional mapping -called "ICMP id mapping". All these 4 types of ICMP queries use a unique -identifier called the ICMP id. This id is set by the process sending the -ICMP query and it is usually equal to the process id. The receiver of the -ICMP query will use the same id in its response, thus enabling the -sender to recognize that the incoming ICMP reply is intended for him and is -an answer to a query that he made. The "ICMP id mapping" feature modifies -these ICMP id in a way identical to \fBportmap\fP for TCP or UDP. +and so on. .PP -The reason that you might want this, is that using this feature you don't -need an IP address per host behind the NAT box, that wants to do ICMP queries. -The two numbers behind the \fBicmpidmap\fP keyword are the first and the -last icmp id number that can be used. There is one important caveat: if you -map to an IP address that belongs to the NAT box itself (notably if you have -only a single public IP address), then you must ensure that the NAT box does -not use the \fBicmpidmap\fP range that you specified in the \fBmap\fP rule. -Since the ICMP id is usually the process id, it is wise to restrict the -largest permittable process id (PID) on your operating system to e.g. 63999 and -use the range 64000:65535 for ICMP id mapping. Changing the maximal PID is -system dependent. For most BSD derived systems can be done by changing -PID_MAX in /usr/include/sys/proc.h and then rebuild the system. +As with +.B map +rules, it is possible to specify a range of addresses by including the word +\fIrange\fR before the addresses: +.nf + +rewrite from any to any port = 80 -> + src 1.1.2.3 - 1.1.2.6 dst 2.2.3.4 - 2.2.3.6; +.fi +.SH DIVERTING PACKETS +.PP +If you'd like to send packets to a UDP socket rather than just another +computer to be decapsulated, this can be achieved using a +.B divert +rule. +.PP +Divert rules can be be used with both inbound and outbound packet +matching however the rule +.B must +specify host addresses for the outer packet, not ranges of addresses +or netmasks, just single addresses. +Additionally the syntax must supply required information for UDP. +An example of what a divert rule looks ike is as follows: +.nf + +divert in on le0 proto udp from any to any port = 53 -> + src 192.1.1.1,54 dst 192.168.1.22.1,5300; +.fi +.PP +On the LHS is a normal set of matching capabilities but on the RHS it is +a requirement to specify both the source and destination addresses and +ports. +.PP +As this feature is intended to be used with targetting packets at sockets +and not IPFilter running on other systems, there is no rule provided to +\fIundivert\fR packets. +.TP +.B NOTE: +Diverted packets \fImay\fP be fragmented if the addition of the +encapsulating IP header plus UDP header causes the packet to exceed +the size allowed by the outbound network interface. At present it is +not possible to cause Path MTU discovery to happen as this feature +is intended to be transparent to both endpoints. +.B Path MTU Discovery +If Path MTU discovery is being used and the "do not fragment" flag +is set in packets to be encapsulated, an ICMP error message will +be sent back to the sender if the new packet would need to be +fragmented. +.SH COMMON OPTIONS +This section deals with options that are available with all rules. +.TP +.B purge +When the purge keyword is added to the end of a NAT rule, it will +cause all of the active NAT sessions to be removed when the rule +is removed as an individual operation. If all of the NAT rules +are flushed out, it is expected that the operator will similarly +flush the NAT table and thus NAT sessions are not removed when the +NAT rules are flushed out. +.SH RULE ORDERING +.PP +.B NOTE: +Rules in +.B ipnat.conf +are read in sequentially as listed and loaded into the kernel in this +fashion +.B BUT +packet matching is done on \fBnetmask\fR, going from 32 down to 0. +If a rule uses +.B pool +or +.B hash +to reference a set of addresses or networks, the netmask value for +these fields is considered to be "0". +So if your +.B ipnat.conf +has the following rules: +.nf + +rdr le0 192.0.0.0/8 port 80 -> 127.0.0.1 3132 tcp +rdr le0 192.2.0.0/16 port 80 -> 127.0.0.1 3131 tcp +rdr le0 from any to pool/100 port 80 -> 127.0.0.1 port 3130 tcp +rdr le0 192.2.2.0/24 port 80 -> 127.0.0.1 3129 tcp +rdr le0 192.2.2.1 port 80 -> 127.0.0.1 3128 tcp +.fi +.PP +then the rule with 192.2.2.1 will match \fBfirst\fR, regardless of where +it appears in the ordering of the above rules. In fact, the order in +which they would be used to match a packet is: +.nf + +rdr le0 192.2.2.1 port 80 -> 127.0.0.1 3128 tcp +rdr le0 192.2.2.0/24 port 80 -> 127.0.0.1 3129 tcp +rdr le0 192.2.0.0/16 port 80 -> 127.0.0.1 3131 tcp +rdr le0 192.0.0.0/8 port 80 -> 127.0.0.1 3132 tcp +rdr le0 from any to pool/100 port 80 -> 127.0.0.1 port 3130 tcp +.fi +.PP +where the first line is actually a /32. +.PP +If your +.B ipnat.conf +file has entries with matching target fields (source address for +.B map +rules and destination address for +.B rdr +rules), then the ordering in the +.B ipnat.conf +file does matter. So if you had the following: +.nf + +rdr le0 from 1.1.0.0/16 to 192.2.2.1 port 80 -> 127.0.0.1 3129 tcp +rdr le0 from 1.1.1.0/24 to 192.2.2.1 port 80 -> 127.0.0.1 3128 tcp +.fi +.PP +Then no packets will match the 2nd rule, they'll all match the first. +.SH IPv6 +.PP +In all of the examples above, where an IPv4 address is present, an IPv6 +address can also be used. All rules must use either IPv4 addresses with +both halves of the NAT rule or IPv6 addresses for both halves. Mixing +IPv6 addresses with IPv4 addresses, in a single rule, will result in an +error. +.PP +For shorthand notations such as "0/32", the equivalent for IPv6 is +"0/128". IPFilter will treat any netmask greater than 32 as an +implicit direction that the address should be IPv6, not IPv4. +To be unambiguous with 0/0, for IPv6 use ::0/0. .SH KERNEL PROXIES .PP IP Filter comes with a few, simple, proxies built into the code that is loaded @@ -177,117 +689,38 @@ Mature - well tested, protocol is properly understood by the proxy; .PP The currently compiled in proxy list is as follows: -.HP +.TP FTP - Mature -.HP +(map ... proxy port ftp ftp/tcp) +.TP IRC - Experimental -.HP +(proxy port 6667 irc/tcp) +.TP rpcbind - Experimental -.HP +.TP +PPTP - Experimental +.TP H.323 - Experimental -.HP +(map ... proxy port 1720 h323/tcp) +.TP Real Audio (PNA) - Aging -.HP +.TP +DNS - Developmental +(map ... proxy port 53 dns/udp { block .cnn.com; }) +.TP IPsec - Developmental -.HP +(map ... proxy port 500 ipsec/tcp) +.TP netbios - Experimental -.HP +.TP R-command - Mature - -.SH TRANSPARENT PROXIES -.PP -True transparent proxying should be performed using the redirect (\fBrdr\fP) -rules directing ports to localhost (127.0.0.1) with the proxy program doing -a lookup through \fB/dev/ipnat\fP to determine the real source and address -of the connection. -.SH LOAD-BALANCING -.PP -Two options for use with \fBrdr\fP are available to support primitive, -\fIround-robin\fP based load balancing. The first option allows for a -\fBrdr\fP to specify a second destination, as follows: -.LP -.nf -rdr le0 203.1.2.3/32 port 80 -> 203.1.2.3,203.1.2.4 port 80 tcp -.fi -.LP -This would send alternate connections to either 203.1.2.3 or 203.1.2.4. -In scenarios where the load is being spread amongst a larger set of -servers, you can use: -.LP -.nf -rdr le0 203.1.2.3/32 port 80 -> 203.1.2.3,203.1.2.4 port 80 tcp round-robin -rdr le0 203.1.2.3/32 port 80 -> 203.1.2.5 port 80 tcp round-robin -.fi -.LP -In this case, a connection will be redirected to 203.1.2.3, then 203.1.2.4 -and then 203.1.2.5 before going back to 203.1.2.3. In accomplishing this, -the rule is removed from the top of the list and added to the end, -automatically, as required. This will not effect the display of rules -using "ipnat -l", only the internal application order. -.SH EXAMPLES -.PP -This section deals with the \fBmap\fP command and its variations. -.PP -To change IP#'s used internally from network 10 into an ISP provided 8 bit -subnet at 209.1.2.0 through the ppp0 interface, the following would be used: -.LP -.nf -map ppp0 10.0.0.0/8 -> 209.1.2.0/24 -.fi -.PP -The obvious problem here is we're trying to squeeze over 16,000,000 IP -addresses into a 254 address space. To increase the scope, remapping for TCP -and/or UDP, port remapping can be used; -.LP -.nf -map ppp0 10.0.0.0/8 -> 209.1.2.0/24 portmap tcp/udp 1025:65000 -.fi -.PP -which falls only 527,566 `addresses' short of the space available in network -10. If we were to combine these rules, they would need to be specified as -follows: -.LP -.nf -map ppp0 10.0.0.0/8 -> 209.1.2.0/24 portmap tcp/udp 1025:65000 -map ppp0 10.0.0.0/8 -> 209.1.2.0/24 -.fi -.PP -so that all TCP/UDP packets were port mapped and only other protocols, such as -ICMP, only have their IP# changed. In some instances, it is more appropriate -to use the keyword \fBauto\fP in place of an actual range of port numbers if -you want to guarantee simultaneous access to all within the given range. -However, in the above case, it would default to 1 port per IP address, since -we need to squeeze 24 bits of address space into 8. A good example of how -this is used might be: -.LP -.nf -map ppp0 172.192.0.0/16 -> 209.1.2.0/24 portmap tcp/udp auto -.fi -.PP -which would result in each IP address being given a small range of ports to -use (252). In all cases, the new port number that is used is deterministic. -That is, port X will always map to port Y. -WARNING: It is not advisable to use the \fBauto\fP feature if you are map'ing -to a /32 (i.e. 0/32) because the NAT code will try to map multiple hosts to -the same port number, outgoing and ultimately this will only succeed for one -of them. -The problem here is that the \fBmap\fP directive tells the NAT -code to use the next address/port pair available for an outgoing connection, -resulting in no easily discernible relation between external addresses/ports -and internal ones. This is overcome by using \fBmap-block\fP as follows: -.LP -.nf -map-block ppp0 172.192.0.0/16 -> 209.1.2.0/24 ports auto -.fi -.PP -For example, this would result in 172.192.0.0/24 being mapped to 209.1.2.0/32 -with each address, from 172.192.0.0 to 172.192.0.255 having 252 ports of its -own. As opposed to the above use of \fBmap\fP, if for some reason the user -of (say) 172.192.0.2 wanted 260 simultaneous connections going out, they would -be limited to 252 with \fBmap-block\fP but would just \fImove on\fP to the next -IP address with the \fBmap\fP command. +(map ... proxy port shell rcmd/tcp) +.SH KERNEL PROXIES +.SH FILES /dev/ipnat .br +/etc/protocols +.br /etc/services .br /etc/hosts diff --git a/contrib/ipfilter/man/ipnat.8 b/contrib/ipfilter/man/ipnat.8 index 432978615008..a49f33736b40 100644 --- a/contrib/ipfilter/man/ipnat.8 +++ b/contrib/ipfilter/man/ipnat.8 @@ -53,6 +53,11 @@ Show the list of current NAT table entry mappings. This flag (no-change) prevents \fBipf\fP from actually making any ioctl calls or doing anything which would alter the currently running kernel. .TP +.B \-p +This flag is used with the \fB-r\fP flag to cause any active NAT +sessions that were created by the rules being removed and that are +currently active to also be removed. +.TP .B \-r Remove matching NAT rules rather than add them to the internal lists. .TP diff --git a/contrib/ipfilter/man/ippool.5 b/contrib/ipfilter/man/ippool.5 index 367eb8d6f2bb..4de19a4b3625 100644 --- a/contrib/ipfilter/man/ippool.5 +++ b/contrib/ipfilter/man/ippool.5 @@ -4,146 +4,311 @@ .SH NAME ippool, ippool.conf \- IP Pool file format .SH DESCRIPTION -The format for files accepted by ippool is described by the following grammar: -.LP -.nf -line ::= table | groupmap . -table ::= "table" role tabletype . -groupmap ::= "group-map" inout role number ipfgroup -tabletype ::= ipftree | ipfhash . - -role ::= "role" "=" "ipf" . -inout ::= "in" | "out" . - -ipftree ::= "type" "=" "tree" number "{" addrlist "}" . -ipfhash ::= "type" "=" "hash" number hashopts "{" hashlist "}" . - -ipfgroup ::= setgroup hashopts "{" grouplist "}" | - hashopts "{" setgrouplist "}" . -setgroup ::= "group" "=" groupname . - -hashopts ::= size [ seed ] | seed . - -size ::= "size" number . -seed ::= "seed" number . - -addrlist ::= [ "!" ] addrmask ";" [ addrlist ] . -grouplist ::= groupentry ";" [ grouplist ] | addrmask ";" [ grouplist ] . - -setgrouplist ::= groupentry ";" [ setgrouplist ] . - -groupentry ::= addrmask "," setgroup . - -hashlist ::= hashentry ";" [ hashlist ] . -hashentry ::= addrmask . - -addrmask ::= ipaddr | ipaddr "/" mask . - -mask ::= number | ipaddr . - -groupname ::= number | name . - -number ::= digit { digit } . - -ipaddr = host-num "." host-num "." host-num "." host-num . -host-num = digit [ digit [ digit ] ] . - -digit ::= "0" | "1" | "2" | "3" | "4" | "5" | "6" | "7" | "8" | "9" . -name ::= letter { letter | digit } . -.fi +The file ippool.conf is used with ippool(8) to configure address pools for +use with ipnat(8) and ipf(8). .PP -The IP pool configuration file is used for defining a single object that -contains a reference to multiple IP address/netmask pairs. A pool may consist -of a mixture of netmask sizes, from 0 to 32. +There are four different types of address pools that can be configured +through ippool.conf. The various types are presented below with a brief +description of how they are used: +.HP +dstlist +.IP +destination list - is a collection of IP addresses with an optional +network interface name that can be used with either redirect (rdr) rules +in ipnat.conf(5) or as the destination in ipf.conf(5) for policy based +routing. +.HP +group-map +.IP +group maps - support the srcgrpmap and dstgrpmap call functions in +ipf.conf(5) by providing a list of addresses or networks rule group +numbers to start processing them with. +.HP +hash +.IP +hash tables - provide the means for performing a very efficient +lookup address or network when there is expected to be only one +exact match. These are best used with more static sets of addresses +so they can be sized optimally. +.HP +pool +.IP +address pools - are an alternative to hash tables that can perform just +as well in most circumstances. In addition, the address pools allow for +heirarchical matching, so it is possible to define a subnet as matching +but then exclude specific addresses from it. +.SS +Evolving Configuration .PP -At this point in time, only IPv4 addressing is supported. -.TP -.SH OVERVIEW -.PP -The IP pool configuration file provides for defining two different mechanisms -for improving speed in matching IP addresses with rules. -The first, -.B table -, defines a lookup -.I table -to provide a single reference in a -filter rule to multiple targets and the second, -.B group-map -, provides a mechanism to target multiple groups from a single filter line. -.PP -The -.B group-map -command can only be used with filter rules that use the -.B call -command to invoke either -.B fr_srcgrpmap -or -.B fr_dstgrpmap -, to use the source or destination address, -respectively, for determining which filter group to jump to next for -continuation of filter packet processing. -.SH POOL TYPES -.PP -Two storage formats are provided: hash tables and tree structure. The hash -table is intended for use with objects all containing the same netmask or a -few different sized netmasks of non-overlapping address space and the tree -is designed for being able to support exceptions to a covering mask, in -addition to normal searching as you would do with a table. It is not possible -to use the tree data storage type with -.B group-map -configuration entries. -.SH POOL ROLES -.PP -When a pool is defined in the configuration file, it must have an associated -role. At present the only supported role is -.B ipf. -Future development will see futher expansion of their use by other sections -of IPFilter code. -.SH EXAMPLES -The following examples show how the pool configuration file is used with -the ipf configuration file to enhance the ability for the ipf configuration -file to be succinct in meaning. -.TP -1 -The first example shows how a filter rule makes reference to a specific -pool for matching of the source address. -.nf -pass in from pool/100 to any -.fi -.PP -The pool configuration, which matches IP addresses 1.1.1.1 and any -in 2.2.0.0/16, except for those in 2.2.2.0/24. +Over time the configuration syntax used by ippool.conf(5) has evolved. +Originally the syntax used was more verbose about what a particular +value was being used for, for example: .PP .nf table role = ipf type = tree number = 100 - { 1.1.1.1/32; 2.2.0.0/16; !2.2.2.0/24 }; -.fi -.TP -2 -The following ipf.conf extract uses the -fr_srcgrpmap/fr_dstgrpmap lookups to use the -.B group-map -facility to lookup the next group to use for filter processing, providing -the -.B call -filter rule is matched. -.nf -call now fr_srcgrpmap/1010 in all -call now fr_dstgrpmap/2010 out all -pass in all group 1020 -block in all group 1030 -pass out all group 2020 -block out all group 2040 + { 1.1.1.1/32; !2.2.0.0/16; 2.2.2.0/24; ef00::5/128; }; .fi .PP -A ippool configuration to work with the above ipf.conf file might -look like this: +This is rather long winded. The evolution of the configuration syntax +has also replaced the use of numbers with names, although numbers can +still be used as can be seen here: +.PP +.nf +pool ipf/tree (name "100";) + { 1.1.1.1/32; !2.2.0.0/16; 2.2.2.0/24; ef00::5/128; }; +.fi +.PP +Both of the above examples produce the same configuration in the kernel +for use with ipf.conf(5). +.PP +Newer options for use in ippool.conf(5) will only be offered in the new +configuration syntax and all output using "ippool -l" will also be in the +new configuration syntax. +.SS +IPFilter devices and pools +.PP +To cater to different administration styles, ipool.conf(5) allows you to +tie a pool to a specific role in IPFilter. The recognised role names are: +.HP +ipf +.IP +pools defined for role "ipf" are available for use with all rules that are +found in ipf.conf(5) except for auth rules. +.HP +nat +.IP +pools defined for role "nat" are available for use with all rules that are +found in ipnat.conf(5). +.HP +auth +.IP +pools defined for role "auth" are available only for use with "auth" rules +that are found in ipf.conf(5) +.HP +all +.IP +pools that are defined for the "all" role are available to all types of +rules, be they NAT rules in ipnat.conf(5) or firewall rules in ipf.conf(5). +.SH Address Pools +.PP +An address pool can be used in ipf.conf(5) and ipnat.conf(5) for matching +the source or destination address of packets. They can be referred to either +by name or number and can hold an arbitrary number of address patterns to +match. +.PP +An address pool is considered to be a "tree type". In the older configuration +style, it was necessary to have "type=tree" in ippool.conf(5). In the new +style configuration, it follows the IPFilter device with which the pool +is being configured. +Now it is the default if left out. +.PP +For convenience, both IPv4 and IPv6 addresses can be stored in the same +address pool. It should go without saying that either type of packet can +only ever match an entry in a pool that is of the same address family. +.PP +The address pool searches the list of addresses configured for the best +match. The "best match" is considered to be the match that has the highest +number of bits set in the mask. Thus if both 2.2.0.0/16 and 2.2.2.0/24 are +present in an address pool, the addres 2.2.2.1 will match 2.2.2.0/24 and +2.2.1.1 will match 2.2.0.0/16. The reason for this is to allow exceptions +to be added through the use of negative matching. In the following example, +the pool contains "2.2.0.0/16" and "!2.2.2.0/24", meaning that all packets +that match 2.2.0.0/16, except those that match 2.2.2.0/24, will be considered +as a match for this pool. +.PP +table role = ipf type = tree number = 100 + { 1.1.1.1/32; 2.2.0.0/16; !2.2.2.0/24; ef00::5/128; }; +.PP +For the sake of clarity and to aid in managing large numbers of addresses +inside address pools, it is possible to specify a location to load the +addresses from. To do this simply use a "file://" URL where you would +specify an actual IP address. +.PP +.nf +pool ipf/tree (name rfc1918;) { file:///etc/ipf/rfc1918; }; +.fi +.PP +The contents of the file might look something like this: +.PP +.nf +# RFC 1918 networks +10.0.0.0/8 +!127.0.0.0/8 +172.16.0.0/12 +192.168.0.0/24 +.fi +.PP +In this example, the inclusion of the line "!127.0.0.0/8" is, strictly +speaking not correct and serves only as an example to show that negative +matching is also supported in this file. +.PP +Another format that ippool(8) recognises for input from a file is that +from whois servers. In the following example, output from a query to a +WHOIS server for information about which networks are associated with +the name "microsoft" has been saved in a file named "ms-networks". +There is no need to modify the output from the whois server, so using +either the whois command or dumping data directly from it over a TCP +connection works perfectly file as input. +.PP +.nf +pool ipf/tree (name microsoft;) { whois file "/etc/ipf/ms-networks"; }; +.fi +.PP +And to then block all packets to/from networks defined in that file, +a rule like this might be used: +.PP +.nf +block in from pool/microsoft to any +.fi +.PP +Note that there are limitations on the output returned by whois servers +so be aware that their output may not be 100% perfect for your goal. +.SH Destination Lists +.PP +Destination lists are provided for use primarily with NAT redirect rules +(rdr). Their purpose is to allow more sophisticated methods of selecting +which host to send traffic to next than the simple round-robin technique +that is present with with "round-robin" rules in ipnat.conf(5). +.PP +When building a list of hosts to use as a redirection list, it is +necessary to list each host to be used explicitly. Expressing a +collection of hosts as a range or a subnet is not supported. With each +address it is also possible to specify a network interface name. The +network interface name is ignored by NAT when using destination lists. +The network itnerface name is currently only used with policy based +routing (use of "to"/"dup-to" in ipf.conf(5)). +.PP +Unlike the other directives that can be expressed in this file, destination +lists must be written using the new configuration syntax. Each destination +list must have a name associated with it and a next hop selection policy. +Some policies have further options. The currently available selection +policies are: +.HP +round-robin +.IP +steps through the list of hosts configured with the destination list +one by one +.HP +random +.IP +the next hop is chosen by random selection from the list available +.HP +src-hash +.IP +a hash is made of the source address components of the packet +(address and port number) and this is used to select which +next hop address is used +.HP +dst-hash +.IP +a hash is made of the destination address components of the packet +(address and port number) and this is used to select which +next hop address is used +.HP +hash +.IP +a hash is made of all the address components in the packet +(addresses and port numbers) and this is used to select which +next hop address is used +.HP +weighted +.IP +selecting a weighted policy for destination selection needs further +clarification as to what type of weighted selection will be used. +The sub-options to a weighted policy are: +.RS +.HP +connection +.IP +the host that has received the least number of connections is selected +to be the next hop. When all hosts have the same connection count, +the last one used will be the next address selected. +.RE +.PP +The first example here shows 4 destinations that are used with a +round-robin selection policy. +.PP +.nf +pool nat/dstlist (name servers; policy round-robin;) + { 1.1.1.2; 1.1.1.4; 1.1.1.5; 1.1.1.9; }; +.fi +.PP +In the following example, the destination is chosen by whichever has +had the least number of connections. By placing the interface name +with each address and saying "all/dstlist", the destination list can +be used with both ipnat.conf(5) and ipf.conf(5). +.PP +.nf +pool all/dstlist (name servers; policy weighted connection;) + { bge0:1.1.1.2; bge0:1.1.1.4; bge1:1.1.1.5; bge1:1.1.1.9; }; +.fi +.SH Group maps +.PP +Group maps are provided to allow more efficient processing of packets +where there are a larger number of subnets and groups of rules for those +subnets. Group maps are used with "call" rules in ipf.conf(5) that +use the "srcgrpmap" and "dstgrpmap" functions. +.PP +A group map declaration must mention which group is the default group +for all matching addresses to be applied to. Then inside the list of +addresses and networks for the group, each one may optionally have +a group number associated with it. A simple example like this, where +the first two entries would map to group 2020 but 5.0.0.0/8 sends +rule processing to group 2040. .PP .nf -group-map in role = ipf number = 1010 - { 1.1.1.1/32, group = 1020; 3.3.0.0/16, group = 1030; }; group-map out role = ipf number = 2010 group = 2020 - { 2.2.2.2/32; 4.4.0.0/16; 5.0.0.0/8, group = 2040; }; + { 2.2.2.2/32; 4.4.0.0/16; 5.0.0.0/8, group = 2040; }; +.fi +.PP +An example that outlines the real purpose of group maps is below, +where each one of the 12 subnets is mapped to a different group +number. This might be because each subnet has its own policy and +rather than write a list of twelve rules in ipf.conf(5) that match +the subnet and branch off with a head statement, a single rule can +be used with this group map to achieve the same result. +.PP +.nf +group-map ( name "2010"; in; ) + { 192.168.1.0/24, group = 10010; 192.168.2.0/24, group = 10020; + 192.168.3.0/24, group = 10030; 192.168.4.0/24, group = 10040; + 192.168.5.0/24, group = 10050; 192.168.6.0/24, group = 10060; + 192.168.7.0/24, group = 10070; 192.168.8.0/24, group = 10080; + 192.168.9.0/24, group = 10090; 192.168.10.0/24, group = 10100; + 192.168.11.0/24, group = 10110; 192.168.12.0/24, group = 10120; + }; +.fi +.PP +The limitation with group maps is that only the source address or the +destination address can be used to map the packet to the starting group, +not both, in your ipf.conf(5) file. +.SH Hash Tables +.PP +The hash table is operationally similar to the address pool. It is +used as a store for a collection of address to match on, saving the +need to write a lengthy list of rules. As with address pools, searching +will attempt to find the best match - an address specification with the +largest contiguous netmask. +.PP +Hash tables are best used where the list of addresses, subnets and +networks is relatively static, which is something of a contrast to +the address pool that can work with either static or changing +address list sizes. +.PP +Further work is still needed to have IPFilter correctly size and tune +the hash table to optimise searching. The goal is to allow for small to +medium sized tables to achieve close to O(1) for either a positive or +negative match, in contrast to the address pool, which is O(logn). +.PP +The following two examples build the same table in the kernel, using +the old configuration format (first) and the new one (second). +.PP +.nf +table role=all type=hash name=servers size=5 + { 1.1.1.2/32; 1.1.1.3/32; 11.23.44.66/32; }; + +pool all/hash (name servers; size 5;) + { 1.1.1.2; 1.1.1.3; 11.23.44.66; }; .fi .SH FILES /dev/iplookup diff --git a/contrib/ipfilter/man/ippool.8 b/contrib/ipfilter/man/ippool.8 index 986812a14077..26cec206c264 100644 --- a/contrib/ipfilter/man/ippool.8 +++ b/contrib/ipfilter/man/ippool.8 @@ -6,7 +6,7 @@ ippool \- user interface to the IPFilter pools .SH SYNOPSIS .br .B ippool --a [-dnv] [-m ] [-o ] -i [/] +-a [-dnv] [-m ] [-o ] [-t ] [-T ttl] -i [/] .br .B ippool -A [-dnv] [-m ] [-o ] [-S ] [-t ] @@ -21,7 +21,7 @@ ippool \- user interface to the IPFilter pools -l [-dv] [-m ] [-t ] .br .B ippool --r [-dnv] [-m ] [-o ] -i [/] +-r [-dnv] [-m ] [-o ] [-t ] -i [/] .br .B ippool -R [-dnv] [-m ] [-o ] [-t ] @@ -113,6 +113,13 @@ Sets the type of pool being defined. Myst be one of .B hash, .B group-map. .TP +.B -T +Sets the expiration of the node being added. The timeout is expressed +as a number of seconds. +.B tree, +.B hash, +.B group-map. +.TP .B -u When parsing a configuration file, rather than load new pool data into the kernel, unload it. diff --git a/contrib/ipfilter/md5.c b/contrib/ipfilter/md5.c index 63dd4b415745..35756cdde7cc 100644 --- a/contrib/ipfilter/md5.c +++ b/contrib/ipfilter/md5.c @@ -35,10 +35,15 @@ *********************************************************************** */ -#if defined(_KERNEL) && !defined(__sgi) -# include +#if defined(linux) && defined(_KERNEL) +extern void *memcpy(void *, const void *, unsigned long); +# define bcopy(a,b,c) memcpy(b,a,c) #else -# include +# if defined(_KERNEL) && !defined(__sgi) +# include +# else +# include +# endif #endif #include "md5.h" diff --git a/contrib/ipfilter/mkfilters b/contrib/ipfilter/mkfilters index f0e6ff465940..fe15c55563ab 100644 --- a/contrib/ipfilter/mkfilters +++ b/contrib/ipfilter/mkfilters @@ -60,7 +60,7 @@ foreach $i (keys %ifaces) { sub irix_mkfilters { open(NETSTAT, "/usr/etc/netstat -i|") || return 0; - + while (defined($line = )) { if ($line =~ m/^Name/) @@ -113,4 +113,4 @@ sub scan_ifconfig } } } - + diff --git a/contrib/ipfilter/ml_ipl.c b/contrib/ipfilter/ml_ipl.c new file mode 100644 index 000000000000..aaf61a419c06 --- /dev/null +++ b/contrib/ipfilter/ml_ipl.c @@ -0,0 +1,164 @@ +/* $FreeBSD$ */ + +/* + * Copyright (C) 2012 by Darren Reed. + * + * See the IPFILTER.LICENCE file for details on licencing. + */ +/* + * 29/12/94 Added code from Marc Huber to allow it to allocate + * its own major char number! Way cool patch! + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#if defined(sun4c) || defined(sun4m) +#include +#endif + +#ifndef IPL_NAME +#define IPL_NAME "/dev/ipf" +#endif + +extern int ipfattach(), ipfopen(), ipfclose(), ipfioctl(), ipfread(); +extern int nulldev(), ipfidentify(), errno; + +struct cdevsw ipfdevsw = +{ + ipfopen, ipfclose, ipfread, nulldev, + ipfioctl, nulldev, nulldev, nulldev, + 0, nulldev, +}; + + +struct dev_ops ipf_ops = +{ + 1, + ipfidentify, + ipfattach, + ipfopen, + ipfclose, + ipfread, + NULL, /* write */ + NULL, /* strategy */ + NULL, /* dump */ + 0, /* psize */ + ipfioctl, + NULL, /* reset */ + NULL /* mmap */ +}; + +int ipf_major = 0; + +#ifdef sun4m +struct vdldrv vd = +{ + VDMAGIC_PSEUDO, + "ipf", + &ipf_ops, + NULL, + &ipfdevsw, + 0, + 0, + NULL, + NULL, + NULL, + 0, + 1, +}; +#else /* sun4m */ +struct vdldrv vd = +{ + VDMAGIC_PSEUDO, /* magic */ + "ipf", /* name */ +#ifdef sun4c + &ipf_ops, /* dev_ops */ +#else + NULL, /* struct mb_ctlr *mb_ctlr */ + NULL, /* struct mb_driver *mb_driver */ + NULL, /* struct mb_device *mb_device */ + 0, /* num ctlrs */ + 1, /* numdevs */ +#endif /* sun4c */ + NULL, /* bdevsw */ + &ipfdevsw, /* cdevsw */ + 0, /* block major */ + 0, /* char major */ +}; +#endif /* sun4m */ + +extern int vd_unuseddev(); +extern struct cdevsw cdevsw[]; +extern int nchrdev; + +xxxinit(fc, vdp, vdi, vds) + u_int fc; + struct vddrv *vdp; + caddr_t vdi; + struct vdstat *vds; +{ + struct vdlinkage *v; + int i; + + switch (fc) + { + case VDLOAD: + while (ipf_major < nchrdev && + cdevsw[ipf_major].d_open != vd_unuseddev) + ipf_major++; + if (ipf_major == nchrdev) + return ENODEV; + vd.Drv_charmajor = ipf_major; + vdp->vdd_vdtab = (struct vdlinkage *)&vd; + return ipf_attach(vdi); + case VDUNLOAD: + return unload(vdp, vdi); + + case VDSTAT: + return 0; + + default: + return EIO; + } +} + +static unload(vdp, vdi) + struct vddrv *vdp; + struct vdioctl_unload *vdi; +{ + int i; + + (void) vn_remove(IPL_NAME, UIO_SYSSPACE, FILE); + return ipfdetach(); +} + + +static int ipf_attach(vdi) +struct vdioctl_load *vdi; +{ + struct vnode *vp; + struct vattr vattr; + int error = 0, fmode = S_IFCHR|0600; + + (void) vn_remove(IPL_NAME, UIO_SYSSPACE, FILE); + vattr_null(&vattr); + vattr.va_type = MFTOVT(fmode); + vattr.va_mode = (fmode & 07777); + vattr.va_rdev = ipf_major<<8; + + error = vn_create(IPL_NAME, UIO_SYSSPACE, &vattr, EXCL, 0, &vp); + if (error == 0) + VN_RELE(vp); + return ipfattach(0); +} diff --git a/contrib/ipfilter/mlf_ipl.c b/contrib/ipfilter/mlf_ipl.c index ca79596e3844..93995af956f0 100644 --- a/contrib/ipfilter/mlf_ipl.c +++ b/contrib/ipfilter/mlf_ipl.c @@ -1,7 +1,7 @@ /* $FreeBSD$ */ /* - * Copyright (C) 1993-2001 by Darren Reed. + * Copyright (C) 2012 by Darren Reed. * * See the IPFILTER.LICENCE file for details on licencing. */ @@ -95,43 +95,43 @@ int sysctl_ipf_int SYSCTL_HANDLER_ARGS; # define CTLFLAG_OFF 0x00800000 /* IPFilter must be disabled */ # define CTLFLAG_RWO (CTLFLAG_RW|CTLFLAG_OFF) SYSCTL_NODE(_net_inet, OID_AUTO, ipf, CTLFLAG_RW, 0, "IPF"); -SYSCTL_IPF(_net_inet_ipf, OID_AUTO, fr_flags, CTLFLAG_RW, &fr_flags, 0, ""); -SYSCTL_IPF(_net_inet_ipf, OID_AUTO, fr_pass, CTLFLAG_RW, &fr_pass, 0, ""); -SYSCTL_IPF(_net_inet_ipf, OID_AUTO, fr_active, CTLFLAG_RD, &fr_active, 0, ""); -SYSCTL_IPF(_net_inet_ipf, OID_AUTO, fr_chksrc, CTLFLAG_RW, &fr_chksrc, 0, ""); -SYSCTL_IPF(_net_inet_ipf, OID_AUTO, fr_minttl, CTLFLAG_RW, &fr_minttl, 0, ""); +SYSCTL_IPF(_net_inet_ipf, OID_AUTO, fr_flags, CTLFLAG_RW, &ipf_flags, 0, ""); +SYSCTL_IPF(_net_inet_ipf, OID_AUTO, ipf_pass, CTLFLAG_RW, &ipf_pass, 0, ""); +SYSCTL_IPF(_net_inet_ipf, OID_AUTO, fr_active, CTLFLAG_RD, &ipf_active, 0, ""); +SYSCTL_IPF(_net_inet_ipf, OID_AUTO, fr_chksrc, CTLFLAG_RW, &ipf_chksrc, 0, ""); +SYSCTL_IPF(_net_inet_ipf, OID_AUTO, fr_minttl, CTLFLAG_RW, &ipf_minttl, 0, ""); SYSCTL_IPF(_net_inet_ipf, OID_AUTO, fr_tcpidletimeout, CTLFLAG_RWO, - &fr_tcpidletimeout, 0, ""); + &ipf_tcpidletimeout, 0, ""); SYSCTL_IPF(_net_inet_ipf, OID_AUTO, fr_tcphalfclosed, CTLFLAG_RWO, - &fr_tcphalfclosed, 0, ""); + &ipf_tcphalfclosed, 0, ""); SYSCTL_IPF(_net_inet_ipf, OID_AUTO, fr_tcpclosewait, CTLFLAG_RWO, - &fr_tcpclosewait, 0, ""); + &ipf_tcpclosewait, 0, ""); SYSCTL_IPF(_net_inet_ipf, OID_AUTO, fr_tcplastack, CTLFLAG_RWO, - &fr_tcplastack, 0, ""); + &ipf_tcplastack, 0, ""); SYSCTL_IPF(_net_inet_ipf, OID_AUTO, fr_tcptimeout, CTLFLAG_RWO, - &fr_tcptimeout, 0, ""); + &ipf_tcptimeout, 0, ""); SYSCTL_IPF(_net_inet_ipf, OID_AUTO, fr_tcpclosed, CTLFLAG_RWO, - &fr_tcpclosed, 0, ""); + &ipf_tcpclosed, 0, ""); SYSCTL_IPF(_net_inet_ipf, OID_AUTO, fr_udptimeout, CTLFLAG_RWO, - &fr_udptimeout, 0, ""); + &ipf_udptimeout, 0, ""); SYSCTL_IPF(_net_inet_ipf, OID_AUTO, fr_icmptimeout, CTLFLAG_RWO, - &fr_icmptimeout, 0, ""); + &ipf_icmptimeout, 0, ""); SYSCTL_IPF(_net_inet_ipf, OID_AUTO, fr_defnatage, CTLFLAG_RWO, - &fr_defnatage, 0, ""); + &ipf_defnatage, 0, ""); SYSCTL_IPF(_net_inet_ipf, OID_AUTO, fr_ipfrttl, CTLFLAG_RW, - &fr_ipfrttl, 0, ""); -SYSCTL_IPF(_net_inet_ipf, OID_AUTO, fr_running, CTLFLAG_RD, - &fr_running, 0, ""); + &ipf_ipfrttl, 0, ""); +SYSCTL_IPF(_net_inet_ipf, OID_AUTO, ipf_running, CTLFLAG_RD, + &ipf_running, 0, ""); SYSCTL_IPF(_net_inet_ipf, OID_AUTO, fr_statesize, CTLFLAG_RWO, - &fr_statesize, 0, ""); + &ipf_statesize, 0, ""); SYSCTL_IPF(_net_inet_ipf, OID_AUTO, fr_statemax, CTLFLAG_RWO, - &fr_statemax, 0, ""); + &ipf_statemax, 0, ""); SYSCTL_IPF(_net_inet_ipf, OID_AUTO, fr_authsize, CTLFLAG_RWO, - &fr_authsize, 0, ""); + &ipf_authsize, 0, ""); SYSCTL_IPF(_net_inet_ipf, OID_AUTO, fr_authused, CTLFLAG_RD, - &fr_authused, 0, ""); + &ipf_authused, 0, ""); SYSCTL_IPF(_net_inet_ipf, OID_AUTO, fr_defaultauthage, CTLFLAG_RW, - &fr_defaultauthage, 0, ""); + &ipf_defaultauthage, 0, ""); SYSCTL_IPF(_net_inet_ipf, OID_AUTO, ippr_ftp_pasvonly, CTLFLAG_RW, &ippr_ftp_pasvonly, 0, ""); #endif @@ -141,15 +141,15 @@ static void *ipf_devfs[IPL_LOGSIZE]; #endif #if !defined(__FreeBSD_version) || (__FreeBSD_version < 220000) -int ipl_major = 0; +int ipf_major = 0; -static struct cdevsw ipldevsw = +static struct cdevsw ipfdevsw = { - iplopen, /* open */ - iplclose, /* close */ - iplread, /* read */ + ipfopen, /* open */ + ipfclose, /* close */ + ipfread, /* read */ (void *)nullop, /* write */ - iplioctl, /* ioctl */ + ipfioctl, /* ioctl */ (void *)nullop, /* stop */ (void *)nullop, /* reset */ (void *)NULL, /* tty */ @@ -158,45 +158,45 @@ static struct cdevsw ipldevsw = NULL /* strategy */ }; -MOD_DEV(IPL_VERSION, LM_DT_CHAR, -1, &ipldevsw); +MOD_DEV(IPL_VERSION, LM_DT_CHAR, -1, &ipfdevsw); extern struct cdevsw cdevsw[]; extern int vd_unuseddev __P((void)); extern int nchrdev; #else -static struct cdevsw ipl_cdevsw = { - iplopen, iplclose, iplread, nowrite, /* 79 */ - iplioctl, nostop, noreset, nodevtotty, +static struct cdevsw ipf_cdevsw = { + ipfopen, ipfclose, ipfread, nowrite, /* 79 */ + ipfioctl, nostop, noreset, nodevtotty, #if (__FreeBSD_version >= 300000) - seltrue, nommap, nostrategy, "ipl", + seltrue, nommap, nostrategy, "ipf", #else - noselect, nommap, nostrategy, "ipl", + noselect, nommap, nostrategy, "ipf", #endif NULL, -1 }; #endif -static void ipl_drvinit __P((void *)); +static void ipf_drvinit __P((void *)); #ifdef ACTUALLY_LKM_NOT_KERNEL -static int if_ipl_unload __P((struct lkm_table *, int)); -static int if_ipl_load __P((struct lkm_table *, int)); -static int if_ipl_remove __P((void)); -static int ipl_major = CDEV_MAJOR; +static int if_ipf_unload __P((struct lkm_table *, int)); +static int if_ipf_load __P((struct lkm_table *, int)); +static int if_ipf_remove __P((void)); +static int ipf_major = CDEV_MAJOR; -static int iplaction __P((struct lkm_table *, int)); +static int ipfaction __P((struct lkm_table *, int)); static char *ipf_devfiles[] = { IPL_NAME, IPL_NAT, IPL_STATE, IPL_AUTH, IPL_SCAN, IPL_SYNC, IPL_POOL, NULL }; extern int lkmenodev __P((void)); -static int iplaction(lkmtp, cmd) -struct lkm_table *lkmtp; -int cmd; +static int ipfaction(lkmtp, cmd) + struct lkm_table *lkmtp; + int cmd; { #if !defined(__FreeBSD_version) || (__FreeBSD_version < 220000) - int i = ipl_major; + int i = ipf_major; struct lkm_dev *args = lkmtp->private.lkm_dev; #endif int err = 0; @@ -210,27 +210,27 @@ int cmd; #if !defined(__FreeBSD_version) || (__FreeBSD_version < 220000) for (i = 0; i < nchrdev; i++) if (cdevsw[i].d_open == lkmenodev || - cdevsw[i].d_open == iplopen) + cdevsw[i].d_open == ipfopen) break; if (i == nchrdev) { printf("IP Filter: No free cdevsw slots\n"); return ENODEV; } - ipl_major = i; + ipf_major = i; args->lkm_offset = i; /* slot in cdevsw[] */ #endif - printf("IP Filter: loaded into slot %d\n", ipl_major); - err = if_ipl_load(lkmtp, cmd); + printf("IP Filter: loaded into slot %d\n", ipf_major); + err = if_ipf_load(lkmtp, cmd); if (!err) - ipl_drvinit((void *)NULL); + ipf_drvinit((void *)NULL); return err; break; case LKM_E_UNLOAD : - err = if_ipl_unload(lkmtp, cmd); + err = if_ipf_unload(lkmtp, cmd); if (!err) { printf("IP Filter: unloaded from slot %d\n", - ipl_major); + ipf_major); #ifdef DEVFS if (ipf_devfs[IPL_LOGIPF]) devfs_remove_dev(ipf_devfs[IPL_LOGIPF]); @@ -259,7 +259,7 @@ int cmd; } -static int if_ipl_remove __P((void)) +static int if_ipf_remove __P((void)) { char *name; struct nameidata nd; @@ -292,32 +292,32 @@ static int if_ipl_remove __P((void)) } -static int if_ipl_unload(lkmtp, cmd) -struct lkm_table *lkmtp; -int cmd; +static int if_ipf_unload(lkmtp, cmd) + struct lkm_table *lkmtp; + int cmd; { int error = 0; - error = ipldetach(); + error = ipfdetach(); if (!error) - error = if_ipl_remove(); + error = if_ipf_remove(); return error; } -static int if_ipl_load(lkmtp, cmd) -struct lkm_table *lkmtp; -int cmd; +static int if_ipf_load(lkmtp, cmd) + struct lkm_table *lkmtp; + int cmd; { struct nameidata nd; struct vattr vattr; int error = 0, fmode = S_IFCHR|0600, i; char *name; - error = iplattach(); + error = ipfattach(); if (error) return error; - (void) if_ipl_remove(); + (void) if_ipf_remove(); for (i = 0; (name = ipf_devfiles[i]); i++) { NDINIT(&nd, CREATE, LOCKPARENT, UIO_SYSSPACE, name, curproc); @@ -335,7 +335,7 @@ int cmd; VATTR_NULL(&vattr); vattr.va_type = VCHR; vattr.va_mode = (fmode & 07777); - vattr.va_rdev = (ipl_major << 8) | i; + vattr.va_rdev = (ipf_major << 8) | i; VOP_LEASE(nd.ni_dvp, curproc, curproc->p_ucred, LEASE_WRITE); error = VOP_MKNOD(nd.ni_dvp, &nd.ni_vp, &nd.ni_cnd, &vattr); #if (__FreeBSD_version >= 300000) @@ -354,7 +354,7 @@ int cmd; * strlen isn't present in 2.1.* kernels. */ size_t strlen(string) -char *string; + char *string; { register char *s; @@ -365,19 +365,19 @@ char *string; int xxxinit(lkmtp, cmd, ver) -struct lkm_table *lkmtp; -int cmd, ver; + struct lkm_table *lkmtp; + int cmd, ver; { - DISPATCH(lkmtp, cmd, ver, iplaction, iplaction, iplaction); + DISPATCH(lkmtp, cmd, ver, ipfaction, ipfaction, ipfaction); } #else /* __FREEBSD_version >= 220000 */ # ifdef IPFILTER_LKM # include # if (__FreeBSD_version >= 300000) -MOD_DEV(if_ipl, LM_DT_CHAR, CDEV_MAJOR, &ipl_cdevsw); +MOD_DEV(if_ipf, LM_DT_CHAR, CDEV_MAJOR, &ipf_cdevsw); # else -MOD_DECL(if_ipl); +MOD_DECL(if_ipf); static struct lkm_dev _module = { @@ -386,48 +386,48 @@ static struct lkm_dev _module = { IPL_VERSION, CDEV_MAJOR, LM_DT_CHAR, - { (void *)&ipl_cdevsw } + { (void *)&ipf_cdevsw } }; # endif -int if_ipl __P((struct lkm_table *, int, int)); +int if_ipf __P((struct lkm_table *, int, int)); -int if_ipl(lkmtp, cmd, ver) -struct lkm_table *lkmtp; -int cmd, ver; +int if_ipf(lkmtp, cmd, ver) + struct lkm_table *lkmtp; + int cmd, ver; { # if (__FreeBSD_version >= 300000) - MOD_DISPATCH(if_ipl, lkmtp, cmd, ver, iplaction, iplaction, iplaction); + MOD_DISPATCH(if_ipf, lkmtp, cmd, ver, ipfaction, ipfaction, ipfaction); # else - DISPATCH(lkmtp, cmd, ver, iplaction, iplaction, iplaction); + DISPATCH(lkmtp, cmd, ver, ipfaction, ipfaction, ipfaction); # endif } # endif /* IPFILTER_LKM */ -static ipl_devsw_installed = 0; +static ipf_devsw_installed = 0; -static void ipl_drvinit __P((void *unused)) +static void ipf_drvinit __P((void *unused)) { dev_t dev; # ifdef DEVFS void **tp = ipf_devfs; # endif - if (!ipl_devsw_installed ) { + if (!ipf_devsw_installed ) { dev = makedev(CDEV_MAJOR, 0); - cdevsw_add(&dev, &ipl_cdevsw, NULL); - ipl_devsw_installed = 1; + cdevsw_add(&dev, &ipf_cdevsw, NULL); + ipf_devsw_installed = 1; # ifdef DEVFS - tp[IPL_LOGIPF] = devfs_add_devswf(&ipl_cdevsw, IPL_LOGIPF, + tp[IPL_LOGIPF] = devfs_add_devswf(&ipf_cdevsw, IPL_LOGIPF, DV_CHR, 0, 0, 0600, "ipf"); - tp[IPL_LOGNAT] = devfs_add_devswf(&ipl_cdevsw, IPL_LOGNAT, + tp[IPL_LOGNAT] = devfs_add_devswf(&ipf_cdevsw, IPL_LOGNAT, DV_CHR, 0, 0, 0600, "ipnat"); - tp[IPL_LOGSTATE] = devfs_add_devswf(&ipl_cdevsw, IPL_LOGSTATE, + tp[IPL_LOGSTATE] = devfs_add_devswf(&ipf_cdevsw, IPL_LOGSTATE, DV_CHR, 0, 0, 0600, "ipstate"); - tp[IPL_LOGAUTH] = devfs_add_devswf(&ipl_cdevsw, IPL_LOGAUTH, + tp[IPL_LOGAUTH] = devfs_add_devswf(&ipf_cdevsw, IPL_LOGAUTH, DV_CHR, 0, 0, 0600, "ipauth"); # endif @@ -452,7 +452,7 @@ sysctl_ipf_int SYSCTL_HANDLER_ARGS if (!arg1) error = EPERM; else { - if ((oidp->oid_kind & CTLFLAG_OFF) && (fr_running > 0)) + if ((oidp->oid_kind & CTLFLAG_OFF) && (ipf_running > 0)) error = EBUSY; else error = SYSCTL_IN(req, arg1, sizeof(int)); @@ -464,6 +464,133 @@ sysctl_ipf_int SYSCTL_HANDLER_ARGS # if defined(IPFILTER_LKM) || \ defined(__FreeBSD_version) && (__FreeBSD_version >= 220000) -SYSINIT(ipldev,SI_SUB_DRIVERS,SI_ORDER_MIDDLE+CDEV_MAJOR,ipl_drvinit,NULL) +SYSINIT(ipfdev,SI_SUB_DRIVERS,SI_ORDER_MIDDLE+CDEV_MAJOR,ipf_drvinit,NULL) # endif /* IPFILTER_LKM */ #endif /* _FreeBSD_version */ + + +/* + * routines below for saving IP headers to buffer + */ +int ipfopen(dev, flags +#if ((BSD >= 199506) || (__FreeBSD_version >= 220000)) +, devtype, p) + int devtype; +# if (__FreeBSD_version >= 500024) + struct thread *p; +# else + struct proc *p; +# endif /* __FreeBSD_version >= 500024 */ +#else +) +#endif +#if (__FreeBSD_version >= 502116) + struct cdev *dev; +#else + dev_t dev; +#endif + int flags; +{ + u_int unit = GET_MINOR(dev); + + if (IPL_LOGMAX < unit) + unit = ENXIO; + else + unit = 0; + return unit; +} + + +int ipfclose(dev, flags +#if ((BSD >= 199506) || (__FreeBSD_version >= 220000)) +, devtype, p) + int devtype; +# if (__FreeBSD_version >= 500024) + struct thread *p; +# else + struct proc *p; +# endif /* __FreeBSD_version >= 500024 */ +#else +) +#endif +#if (__FreeBSD_version >= 502116) + struct cdev *dev; +#else + dev_t dev; +#endif + int flags; +{ + u_int unit = GET_MINOR(dev); + + if (IPL_LOGMAX < unit) + unit = ENXIO; + else + unit = 0; + return unit; +} + +/* + * ipfread/ipflog + * both of these must operate with at least splnet() lest they be + * called during packet processing and cause an inconsistancy to appear in + * the filter lists. + */ +#if (BSD >= 199306) +int ipfread(dev, uio, ioflag) + int ioflag; +#else +int ipfread(dev, uio) +#endif +#if (__FreeBSD_version >= 502116) + struct cdev *dev; +#else + dev_t dev; +#endif + register struct uio *uio; +{ + u_int unit = GET_MINOR(dev); + + if (unit < 0) + return ENXIO; + + if (ipf_running < 1) + return EIO; + + if (unit == IPL_LOGSYNC) + return ipfsync_read(uio); + +#ifdef IPFILTER_LOG + return ipflog_read(unit, uio); +#else + return ENXIO; +#endif +} + + +/* + * ipfwrite + * both of these must operate with at least splnet() lest they be + * called during packet processing and cause an inconsistancy to appear in + * the filter lists. + */ +#if (BSD >= 199306) +int ipfwrite(dev, uio, ioflag) + int ioflag; +#else +int ipfwrite(dev, uio) +#endif +#if (__FreeBSD_version >= 502116) + struct cdev *dev; +#else + dev_t dev; +#endif + register struct uio *uio; +{ + + if (ipf_running < 1) + return EIO; + + if (GET_MINOR(dev) == IPL_LOGSYNC) + return ipfsync_write(uio); + return ENXIO; +} diff --git a/contrib/ipfilter/mlf_rule.c b/contrib/ipfilter/mlf_rule.c index 8b7b9d3a9409..babd2c64a93b 100644 --- a/contrib/ipfilter/mlf_rule.c +++ b/contrib/ipfilter/mlf_rule.c @@ -1,7 +1,7 @@ /* $FreeBSD$ */ /* - * Copyright (C) 1993-2001 by Darren Reed. + * Copyright (C) 2012 by Darren Reed. * * See the IPFILTER.LICENCE file for details on licencing. */ @@ -79,8 +79,8 @@ static int ipfrule_ioctl __P((struct lkm_table *, int)); #if defined(__FreeBSD_version) && (__FreeBSD_version < 220000) int xxxinit(lkmtp, cmd, ver) -struct lkm_table *lkmtp; -int cmd, ver; + struct lkm_table *lkmtp; + int cmd, ver; { DISPATCH(lkmtp, cmd, ver, ipfrule_ioctl, ipfrule_ioctl, ipfrule_ioctl); } @@ -107,8 +107,8 @@ int ipfrule __P((struct lkm_table *, int, int)); int ipfrule(lkmtp, cmd, ver) -struct lkm_table *lkmtp; -int cmd, ver; + struct lkm_table *lkmtp; + int cmd, ver; { # if (__FreeBSD_version >= 300000) MOD_DISPATCH(ipfrule, lkmtp, cmd, ver, ipfrule_ioctl, ipfrule_ioctl, @@ -121,24 +121,24 @@ int cmd, ver; int ipfrule_load(lkmtp, cmd) -struct lkm_table *lkmtp; -int cmd; + struct lkm_table *lkmtp; + int cmd; { return ipfrule_add(); } int ipfrule_unload(lkmtp, cmd) -struct lkm_table *lkmtp; -int cmd; + struct lkm_table *lkmtp; + int cmd; { return ipfrule_remove(); } static int ipfrule_ioctl(lkmtp, cmd) -struct lkm_table *lkmtp; -int cmd; + struct lkm_table *lkmtp; + int cmd; { int err = 0; @@ -150,12 +150,12 @@ int cmd; err = ipfrule_load(lkmtp, cmd); if (!err) - fr_refcnt++; + ipf_refcnt++; break; case LKM_E_UNLOAD : err = ipfrule_unload(lkmtp, cmd); if (!err) - fr_refcnt--; + ipf_refcnt--; break; case LKM_E_STAT : break; diff --git a/contrib/ipfilter/mlfk_ipl.c b/contrib/ipfilter/mlfk_ipl.c new file mode 100644 index 000000000000..ba1f44f0c105 --- /dev/null +++ b/contrib/ipfilter/mlfk_ipl.c @@ -0,0 +1,529 @@ +/* $FreeBSD$ */ + +/* + * Copyright (C) 2012 by Darren Reed. + * + * See the IPFILTER.LICENCE file for details on licencing. + */ + + +#include +#include +#include +#include +#include +#include +#include +#include +#if __FreeBSD_version >= 500000 +# include +#endif +#include +#include +#include + + +#include "netinet/ipl.h" +#include "netinet/ip_compat.h" +#include "netinet/ip_fil.h" +#include "netinet/ip_state.h" +#include "netinet/ip_nat.h" +#include "netinet/ip_auth.h" +#include "netinet/ip_frag.h" +#include "netinet/ip_sync.h" + +extern ipf_main_softc_t ipfmain; + +#if __FreeBSD_version >= 502116 +static struct cdev *ipf_devs[IPL_LOGSIZE]; +#else +static dev_t ipf_devs[IPL_LOGSIZE]; +#endif + +#if 0 +static int sysctl_ipf_int ( SYSCTL_HANDLER_ARGS ); +#endif +static int ipf_modload(void); +static int ipf_modunload(void); + +#if (__FreeBSD_version >= 500024) +# if (__FreeBSD_version >= 502116) +static int ipfopen __P((struct cdev*, int, int, struct thread *)); +static int ipfclose __P((struct cdev*, int, int, struct thread *)); +# else +static int ipfopen __P((dev_t, int, int, struct thread *)); +static int ipfclose __P((dev_t, int, int, struct thread *)); +# endif /* __FreeBSD_version >= 502116 */ +#else +static int ipfopen __P((dev_t, int, int, struct proc *)); +static int ipfclose __P((dev_t, int, int, struct proc *)); +#endif +#if (__FreeBSD_version >= 502116) +static int ipfread __P((struct cdev*, struct uio *, int)); +static int ipfwrite __P((struct cdev*, struct uio *, int)); +#else +static int ipfread __P((dev_t, struct uio *, int)); +static int ipfwrite __P((dev_t, struct uio *, int)); +#endif /* __FreeBSD_version >= 502116 */ + + + +SYSCTL_DECL(_net_inet); +#define SYSCTL_IPF(parent, nbr, name, access, ptr, val, descr) \ + SYSCTL_OID(parent, nbr, name, CTLTYPE_INT|access, \ + ptr, val, sysctl_ipf_int, "I", descr); +#define CTLFLAG_OFF 0x00800000 /* IPFilter must be disabled */ +#define CTLFLAG_RWO (CTLFLAG_RW|CTLFLAG_OFF) +SYSCTL_NODE(_net_inet, OID_AUTO, ipf, CTLFLAG_RW, 0, "IPF"); +#if 0 +SYSCTL_IPF(_net_inet_ipf, OID_AUTO, fr_flags, CTLFLAG_RW, &ipf_flags, 0, ""); +SYSCTL_IPF(_net_inet_ipf, OID_AUTO, ipf_pass, CTLFLAG_RW, &ipf_pass, 0, ""); +SYSCTL_IPF(_net_inet_ipf, OID_AUTO, fr_active, CTLFLAG_RD, &ipf_active, 0, ""); +SYSCTL_IPF(_net_inet_ipf, OID_AUTO, fr_tcpidletimeout, CTLFLAG_RWO, + &ipf_tcpidletimeout, 0, ""); +SYSCTL_IPF(_net_inet_ipf, OID_AUTO, fr_tcphalfclosed, CTLFLAG_RWO, + &ipf_tcphalfclosed, 0, ""); +SYSCTL_IPF(_net_inet_ipf, OID_AUTO, fr_tcpclosewait, CTLFLAG_RWO, + &ipf_tcpclosewait, 0, ""); +SYSCTL_IPF(_net_inet_ipf, OID_AUTO, fr_tcplastack, CTLFLAG_RWO, + &ipf_tcplastack, 0, ""); +SYSCTL_IPF(_net_inet_ipf, OID_AUTO, fr_tcptimeout, CTLFLAG_RWO, + &ipf_tcptimeout, 0, ""); +SYSCTL_IPF(_net_inet_ipf, OID_AUTO, fr_tcpclosed, CTLFLAG_RWO, + &ipf_tcpclosed, 0, ""); +SYSCTL_IPF(_net_inet_ipf, OID_AUTO, fr_udptimeout, CTLFLAG_RWO, + &ipf_udptimeout, 0, ""); +SYSCTL_IPF(_net_inet_ipf, OID_AUTO, fr_udpacktimeout, CTLFLAG_RWO, + &ipf_udpacktimeout, 0, ""); +SYSCTL_IPF(_net_inet_ipf, OID_AUTO, fr_icmptimeout, CTLFLAG_RWO, + &ipf_icmptimeout, 0, ""); +SYSCTL_IPF(_net_inet_ipf, OID_AUTO, fr_defnatage, CTLFLAG_RWO, + &ipf_nat_defage, 0, ""); +SYSCTL_IPF(_net_inet_ipf, OID_AUTO, fr_ipfrttl, CTLFLAG_RW, + &ipf_ipfrttl, 0, ""); +SYSCTL_IPF(_net_inet_ipf, OID_AUTO, ipf_running, CTLFLAG_RD, + &ipf_running, 0, ""); +SYSCTL_IPF(_net_inet_ipf, OID_AUTO, fr_statesize, CTLFLAG_RWO, + &ipf_state_size, 0, ""); +SYSCTL_IPF(_net_inet_ipf, OID_AUTO, fr_statemax, CTLFLAG_RWO, + &ipf_state_max, 0, ""); +SYSCTL_IPF(_net_inet_ipf, OID_AUTO, ipf_nattable_sz, CTLFLAG_RWO, + &ipf_nat_table_sz, 0, ""); +SYSCTL_IPF(_net_inet_ipf, OID_AUTO, ipf_natrules_sz, CTLFLAG_RWO, + &ipf_nat_maprules_sz, 0, ""); +SYSCTL_IPF(_net_inet_ipf, OID_AUTO, ipf_rdrrules_sz, CTLFLAG_RWO, + &ipf_nat_rdrrules_sz, 0, ""); +SYSCTL_IPF(_net_inet_ipf, OID_AUTO, ipf_hostmap_sz, CTLFLAG_RWO, + &ipf_nat_hostmap_sz, 0, ""); +SYSCTL_IPF(_net_inet_ipf, OID_AUTO, fr_authsize, CTLFLAG_RWO, + &ipf_auth_size, 0, ""); +SYSCTL_IPF(_net_inet_ipf, OID_AUTO, fr_authused, CTLFLAG_RD, + &ipf_auth_used, 0, ""); +SYSCTL_IPF(_net_inet_ipf, OID_AUTO, fr_defaultauthage, CTLFLAG_RW, + &ipf_auth_defaultage, 0, ""); +SYSCTL_IPF(_net_inet_ipf, OID_AUTO, fr_chksrc, CTLFLAG_RW, &ipf_chksrc, 0, ""); +SYSCTL_IPF(_net_inet_ipf, OID_AUTO, fr_minttl, CTLFLAG_RW, &ipf_minttl, 0, ""); +#endif + +#define CDEV_MAJOR 79 +#include +#if __FreeBSD_version >= 500043 +# include +static int ipfpoll(struct cdev *dev, int events, struct thread *td); + +static struct cdevsw ipf_cdevsw = { +#if __FreeBSD_version >= 502103 + .d_version = D_VERSION, + .d_flags = 0, /* D_NEEDGIANT - Should be SMP safe */ +#endif + .d_open = ipfopen, + .d_close = ipfclose, + .d_read = ipfread, + .d_write = ipfwrite, + .d_ioctl = ipfioctl, + .d_poll = ipfpoll, + .d_name = "ipf", +#if __FreeBSD_version < 600000 + .d_maj = CDEV_MAJOR, +#endif +}; +#else +static int ipfpoll(dev_t dev, int events, struct proc *td); + +static struct cdevsw ipf_cdevsw = { + /* open */ ipfopen, + /* close */ ipfclose, + /* read */ ipfread, + /* write */ ipfwrite, + /* ioctl */ ipfioctl, + /* poll */ ipfpoll, + /* mmap */ nommap, + /* strategy */ nostrategy, + /* name */ "ipf", + /* maj */ CDEV_MAJOR, + /* dump */ nodump, + /* psize */ nopsize, + /* flags */ 0, +# if (__FreeBSD_version < 500043) + /* bmaj */ -1, +# endif +# if (__FreeBSD_version >= 430000) + /* kqfilter */ NULL +# endif +}; +#endif + +static char *ipf_devfiles[] = { IPL_NAME, IPNAT_NAME, IPSTATE_NAME, IPAUTH_NAME, + IPSYNC_NAME, IPSCAN_NAME, IPLOOKUP_NAME, NULL }; + + +static int +ipfilter_modevent(module_t mod, int type, void *unused) +{ + int error = 0; + + switch (type) + { + case MOD_LOAD : + error = ipf_modload(); + break; + + case MOD_UNLOAD : + error = ipf_modunload(); + break; + default: + error = EINVAL; + break; + } + return error; +} + + +static int +ipf_modload() +{ + char *defpass, *c, *str; + int i, j, error; + + if (ipf_load_all() != 0) + return EIO; + + if (ipf_create_all(&ipfmain) == NULL) + return EIO; + + error = ipfattach(&ipfmain); + if (error) + return error; + + for (i = 0; i < IPL_LOGSIZE; i++) + ipf_devs[i] = NULL; + + for (i = 0; (str = ipf_devfiles[i]); i++) { + c = NULL; + for(j = strlen(str); j > 0; j--) + if (str[j] == '/') { + c = str + j + 1; + break; + } + if (!c) + c = str; + ipf_devs[i] = make_dev(&ipf_cdevsw, i, 0, 0, 0600, c); + } + + error = ipf_pfil_hook(); + if (error != 0) + return error; + ipf_event_reg(); + + if (FR_ISPASS(ipfmain.ipf_pass)) + defpass = "pass"; + else if (FR_ISBLOCK(ipfmain.ipf_pass)) + defpass = "block"; + else + defpass = "no-match -> block"; + + printf("%s initialized. Default = %s all, Logging = %s%s\n", + ipfilter_version, defpass, +#ifdef IPFILTER_LOG + "enabled", +#else + "disabled", +#endif +#ifdef IPFILTER_COMPILED + " (COMPILED)" +#else + "" +#endif + ); + return 0; +} + + +static int +ipf_modunload() +{ + int error, i; + + if (ipfmain.ipf_refcnt) + return EBUSY; + + error = ipf_pfil_unhook(); + if (error != 0) + return error; + + if (ipfmain.ipf_running >= 0) { + error = ipfdetach(&ipfmain); + if (error != 0) + return error; + + ipf_destroy_all(&ipfmain); + ipf_unload_all(); + } else + error = 0; + + ipfmain.ipf_running = -2; + + for (i = 0; ipf_devfiles[i]; i++) { + if (ipf_devs[i] != NULL) + destroy_dev(ipf_devs[i]); + } + + printf("%s unloaded\n", ipfilter_version); + + return error; +} + + +static moduledata_t ipfiltermod = { + "ipfilter", + ipfilter_modevent, + 0 +}; + + +DECLARE_MODULE(ipfilter, ipfiltermod, SI_SUB_PROTO_DOMAIN, SI_ORDER_ANY); +#ifdef MODULE_VERSION +MODULE_VERSION(ipfilter, 1); +#endif + + +#if 0 +#ifdef SYSCTL_IPF +int +sysctl_ipf_int ( SYSCTL_HANDLER_ARGS ) +{ + int error = 0; + + if (arg1) + error = SYSCTL_OUT(req, arg1, sizeof(int)); + else + error = SYSCTL_OUT(req, &arg2, sizeof(int)); + + if (error || !req->newptr) + return (error); + + if (!arg1) + error = EPERM; + else { + if ((oidp->oid_kind & CTLFLAG_OFF) && (ipfmain.ipf_running > 0)) + error = EBUSY; + else + error = SYSCTL_IN(req, arg1, sizeof(int)); + } + return (error); +} +#endif +#endif + + +static int +#if __FreeBSD_version >= 500043 +ipfpoll(struct cdev *dev, int events, struct thread *td) +#else +ipfpoll(dev_t dev, int events, struct proc *td) +#endif +{ + u_int unit = GET_MINOR(dev); + int revents; + + if (unit < 0 || unit > IPL_LOGMAX) + return 0; + + revents = 0; + + switch (unit) + { + case IPL_LOGIPF : + case IPL_LOGNAT : + case IPL_LOGSTATE : +#ifdef IPFILTER_LOG + if ((events & (POLLIN | POLLRDNORM)) && ipf_log_canread(&ipfmain, unit)) + revents |= events & (POLLIN | POLLRDNORM); +#endif + break; + case IPL_LOGAUTH : + if ((events & (POLLIN | POLLRDNORM)) && ipf_auth_waiting(&ipfmain)) + revents |= events & (POLLIN | POLLRDNORM); + break; + case IPL_LOGSYNC : + if ((events & (POLLIN | POLLRDNORM)) && ipf_sync_canread(&ipfmain)) + revents |= events & (POLLIN | POLLRDNORM); + if ((events & (POLLOUT | POLLWRNORM)) && ipf_sync_canwrite(&ipfmain)) + revents |= events & (POLLOUT | POLLWRNORM); + break; + case IPL_LOGSCAN : + case IPL_LOGLOOKUP : + default : + break; + } + + if ((revents == 0) && ((events & (POLLIN|POLLRDNORM)) != 0)) + selrecord(td, &ipfmain.ipf_selwait[unit]); + + return revents; +} + + +/* + * routines below for saving IP headers to buffer + */ +static int ipfopen(dev, flags +#if ((BSD >= 199506) || (__FreeBSD_version >= 220000)) +, devtype, p) + int devtype; +# if (__FreeBSD_version >= 500024) + struct thread *p; +# else + struct proc *p; +# endif /* __FreeBSD_version >= 500024 */ +#else +) +#endif +#if (__FreeBSD_version >= 502116) + struct cdev *dev; +#else + dev_t dev; +#endif + int flags; +{ + u_int unit = GET_MINOR(dev); + int error; + + if (IPL_LOGMAX < unit) + error = ENXIO; + else { + switch (unit) + { + case IPL_LOGIPF : + case IPL_LOGNAT : + case IPL_LOGSTATE : + case IPL_LOGAUTH : + case IPL_LOGLOOKUP : + case IPL_LOGSYNC : +#ifdef IPFILTER_SCAN + case IPL_LOGSCAN : +#endif + error = 0; + break; + default : + error = ENXIO; + break; + } + } + return error; +} + + +static int ipfclose(dev, flags +#if ((BSD >= 199506) || (__FreeBSD_version >= 220000)) +, devtype, p) + int devtype; +# if (__FreeBSD_version >= 500024) + struct thread *p; +# else + struct proc *p; +# endif /* __FreeBSD_version >= 500024 */ +#else +) +#endif +#if (__FreeBSD_version >= 502116) + struct cdev *dev; +#else + dev_t dev; +#endif + int flags; +{ + u_int unit = GET_MINOR(dev); + + if (IPL_LOGMAX < unit) + unit = ENXIO; + else + unit = 0; + return unit; +} + +/* + * ipfread/ipflog + * both of these must operate with at least splnet() lest they be + * called during packet processing and cause an inconsistancy to appear in + * the filter lists. + */ +#if (BSD >= 199306) +static int ipfread(dev, uio, ioflag) + int ioflag; +#else +static int ipfread(dev, uio) +#endif +#if (__FreeBSD_version >= 502116) + struct cdev *dev; +#else + dev_t dev; +#endif + struct uio *uio; +{ + u_int unit = GET_MINOR(dev); + + if (unit < 0) + return ENXIO; + + if (ipfmain.ipf_running < 1) + return EIO; + + if (unit == IPL_LOGSYNC) + return ipf_sync_read(&ipfmain, uio); + +#ifdef IPFILTER_LOG + return ipf_log_read(&ipfmain, unit, uio); +#else + return ENXIO; +#endif +} + + +/* + * ipfwrite + * both of these must operate with at least splnet() lest they be + * called during packet processing and cause an inconsistancy to appear in + * the filter lists. + */ +#if (BSD >= 199306) +static int ipfwrite(dev, uio, ioflag) + int ioflag; +#else +static int ipfwrite(dev, uio) +#endif +#if (__FreeBSD_version >= 502116) + struct cdev *dev; +#else + dev_t dev; +#endif + struct uio *uio; +{ + + if (ipfmain.ipf_running < 1) + return EIO; + + if (GET_MINOR(dev) == IPL_LOGSYNC) + return ipf_sync_write(&ipfmain, uio); + return ENXIO; +} diff --git a/contrib/ipfilter/mlfk_rule.c b/contrib/ipfilter/mlfk_rule.c index 5f7aed89a7dd..9f951cf6c31d 100644 --- a/contrib/ipfilter/mlfk_rule.c +++ b/contrib/ipfilter/mlfk_rule.c @@ -1,11 +1,11 @@ /* $FreeBSD$ */ /* - * Copyright (C) 2000 by Darren Reed. + * Copyright (C) 2012 by Darren Reed. * * See the IPFILTER.LICENCE file for details on licencing. * - * $Id: mlfk_rule.c,v 2.4.4.2 2004/04/16 23:32:08 darrenr Exp $ + * $Id$ */ @@ -30,6 +30,7 @@ #include "ip_rules.h" +extern ipf_main_softc_t ipfmain; static int ipfrule_modevent(module_t mod, int type, void *unused) @@ -41,12 +42,12 @@ ipfrule_modevent(module_t mod, int type, void *unused) case MOD_LOAD : error = ipfrule_add(); if (!error) - fr_refcnt++; + ipfmain.ipf_refcnt++; break; case MOD_UNLOAD : error = ipfrule_remove(); if (!error) - fr_refcnt--; + ipfmain.ipf_refcnt--; break; default: error = EINVAL; diff --git a/contrib/ipfilter/mlh_rule.c b/contrib/ipfilter/mlh_rule.c index dd350dfb7b4f..cc2a74c86264 100644 --- a/contrib/ipfilter/mlh_rule.c +++ b/contrib/ipfilter/mlh_rule.c @@ -1,7 +1,7 @@ /* $FreeBSD$ */ /* - * Copyright (C) 1993-1998 by Darren Reed. + * Copyright (C) 2012 by Darren Reed. * * See the IPFILTER.LICENCE file for details on licencing. * @@ -88,7 +88,7 @@ static int ipf_load(void *arg) i = ipfrule_add(); if (!i) - fr_refcnt--; + ipf_refcnt--; #ifdef IPFDEBUG printf("IP Filter Rules: ipfrule_add() = %d\n", i); #endif @@ -104,7 +104,7 @@ static int ipf_unload(void *arg) i = ipfrule_remove(); if (!i) - fr_refcnt--; + ipf_refcnt--; #ifdef IPFDEBUG printf("IP Filter Rules: ipfrule_remove() = %d\n", i); #endif diff --git a/contrib/ipfilter/mli_ipl.c b/contrib/ipfilter/mli_ipl.c new file mode 100644 index 000000000000..2a0024cb459b --- /dev/null +++ b/contrib/ipfilter/mli_ipl.c @@ -0,0 +1,683 @@ +/* $FreeBSD$ */ + +/* + * Copyright (C) 2012 by Darren Reed. + * (C)opyright 1997 by Marc Boucher. + * + * See the IPFILTER.LICENCE file for details on licencing. + * + */ + +/* TODO: (MARCXXX) + - ipl_init failure -> open ENODEV or whatever + - prevent multiple LKM loads + - surround access to ifnet structures by IFNET_LOCK()/IFNET_UNLOCK() ? + - m != m1 problem +*/ + +#include +#include +#ifdef IPFILTER_LKM +#include +#endif +#include +#include +#include +#include +#include +#ifdef IFF_DRVRLOCK /* IRIX6 */ +#include +#include +#endif +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "ipl.h" +#include "ip_compat.h" +#include "ip_fil.h" +#include "ip_nat.h" + +#ifndef MBUF_IS_CLUSTER +# define MBUF_IS_CLUSTER(m) ((m)->m_flags & MCL_CLUSTER) +#endif +#undef IPFDEBUG /* #define IPFDEBUG 9 */ + +#ifdef IPFILTER_LKM +u_int ipldevflag = D_MP; +char *iplmversion = M_VERSION; +#else +u_int ipfilterdevflag = D_MP; +char *ipfiltermversion = M_VERSION; +#endif + +ipfmutex_t ipl_mutex, ipfi_mutex, ipf_rw, ipf_stinsert, ipf_auth_mx; +ipfmutex_t ipf_nat_new, ipf_natio, ipf_timeoutlock; +ipfrwlock_t ipf_frag, ipf_state, ipf_nat, ipf_natfrag, ipf_auth; +ipfrwlock_t ipf_global, ipf_mutex, ipf_ipidfrag, ipf_frcache, ipf_tokens; + +int (*ipf_checkp) __P((struct ip *, int, void *, int, mb_t **)); + +#ifdef IPFILTER_LKM +static int *ipff_addr = 0; +static int ipff_value; +static __psunsigned_t *ipfk_addr = 0; +static __psunsigned_t ipfk_code[4]; +#endif +static void nifattach(); +static void nifdetach(); + +typedef struct nif { + struct nif *nf_next; + struct ifnet *nf_ifp; +#if (IRIX < 60500) + int (*nf_output)(struct ifnet *, struct mbuf *, struct sockaddr *); +#else + int (*nf_output)(struct ifnet *, struct mbuf *, struct sockaddr *, + struct rtentry *); +#endif + char nf_name[LIFNAMSIZ]; + int nf_unit; +} nif_t; + +static nif_t *nif_head = 0; +static int nif_interfaces = 0; +extern int in_interfaces; +#if IRIX >= 60500 +toid_t ipf_timer_id; +#endif + +extern ipnat_t *nat_list; + +#ifdef IPFDEBUG +static void ipf_dumppacket(m) + struct mbuf *m; +{ + u_char *s; + char *t, line[80]; + int len, off, i; + + off = 0; + + while (m != NULL) { + len = M_LEN(m); + s = mtod(m, u_char *); + printf("mbuf 0x%lx len %d flags %x type %d\n", + m, len, m->m_flags, m->m_type); + printf("dat 0x%lx off 0x%lx/%d s 0x%lx next 0x%lx\n", + m->m_dat, m->m_off, m->m_off, s, m->m_next); + while (len > 0) { + t = line; + for (i = 0; (i < 16) && (len > 0); len--, i++) + sprintf(t, " %02x", *s++), t += strlen(t); + *s = '\0'; + printf("mbuf:%x:%s\n", off, line); + off += 16; + } + m = m->m_next; + } +} +#endif + + +static int +#if IRIX < 60500 +ipl_if_output(struct ifnet *ifp, struct mbuf *m, struct sockaddr *dst) +#else +ipl_if_output(struct ifnet *ifp, struct mbuf *m, struct sockaddr *dst, + struct rtentry *rt) +#endif +{ +#if (IPFDEBUG >= 0) + static unsigned int cnt = 0; +#endif + nif_t *nif; + + MUTEX_ENTER(&ipfi_mutex); /* sets interrupt priority level to splhi */ + for (nif = nif_head; nif; nif = nif->nf_next) + if (nif->nf_ifp == ifp) + break; + MUTEX_EXIT(&ipfi_mutex); + + if (nif == NULL) { + printf("IP Filter: ipl_if_output intf %x NOT FOUND\n", ifp); + return ENETDOWN; + } + +#if (IPFDEBUG >= 7) + if ((++cnt % 200) == 0) + printf("IP Filter: ipl_if_output(ifp=0x%lx, m=0x%lx, dst=0x%lx), m_type=%d m_flags=0x%lx m_off=0x%lx\n", ifp, m, dst, m->m_type, (u_long)m->m_flags, m->m_off); +#endif + + if (ipf_checkp) { + struct mbuf *m1 = m; + struct ip *ip; + int hlen; + + switch(m->m_type) + { + case MT_HEADER: + if (m->m_len == 0) { + if (m->m_next == NULL) + break; + m = m->m_next; + } + /* FALLTHROUGH */ + case MT_DATA: + if (!MBUF_IS_CLUSTER(m) && + ((m->m_off < MMINOFF) || (m->m_off > MMAXOFF))) { +#if (IPFDEBUG >= 4) + printf("IP Filter: ipl_if_output: bad m_off m_type=%d m_flags=0x%lx m_off=0x%lx\n", m->m_type, (u_long)m->m_flags, m->m_off); +#endif + break; + } + if (m->m_len < sizeof(char)) { +#if (IPFDEBUG >= 3) + printf("IP Filter: ipl_if_output: mbuf block too small (m_len=%d) for IP vers+hlen, m_type=%d m_flags=0x%lx\n", m->m_len, m->m_type, (u_long)m->m_flags); +#endif + break; + } + ip = mtod(m, struct ip *); + if (ip->ip_v != IPVERSION) { +#if (IPFDEBUG >= 2) + ipf_dumppacket(m); + printf("IP Filter: ipl_if_output: bad ip_v m_type=%d m_flags=0x%lx m_off=0x%lx\n", m->m_type, (u_long)m->m_flags, m->m_off); +#endif + break; + } + + hlen = ip->ip_hl << 2; + if ((*ipf_checkp)(ip, hlen, ifp, 1, &m1) || (m1 == NULL)) + return EHOSTUNREACH; + + m = m1; + break; + + default: +#if (IPFDEBUG >= 2) + printf("IP Filter: ipl_if_output: bad m_type=%d m_flags=0x%lxm_off=0x%lx\n", m->m_type, (u_long)m->m_flags, m->m_off); +#endif + break; + } + } +#if (IRIX < 60500) + return (*nif->nf_output)(ifp, m, dst); +#else + return (*nif->nf_output)(ifp, m, dst, rt); +#endif +} + +int + + +#if !defined(IPFILTER_LKM) && (IRIX >= 60500) +ipfilter_kernel(struct ifnet *rcvif, struct mbuf *m) +#else +ipl_kernel(struct ifnet *rcvif, struct mbuf *m) +#endif +{ +#if (IPFDEBUG >= 7) + static unsigned int cnt = 0; + + if ((++cnt % 200) == 0) + printf("IP Filter: ipl_kernel(rcvif=0x%lx, m=0x%lx\n", + rcvif, m); +#endif + + if (ipf_running <= 0) + return IPF_ACCEPTIT; + + /* + * Check if we want to allow this packet to be processed. + * Consider it to be bad if not. + */ + if (ipf_checkp) { + struct mbuf *m1 = m; + struct ip *ip; + int hlen; + + if ((m->m_type != MT_DATA) && (m->m_type != MT_HEADER)) { +#if (IPFDEBUG >= 4) + printf("IP Filter: ipl_kernel: bad m_type=%d m_flags=0x%lx m_off=0x%lx\n", m->m_type, (u_long)m->m_flags, m->m_off); +#endif + return IPF_ACCEPTIT; + } + + if (!MBUF_IS_CLUSTER(m) && + ((m->m_off < MMINOFF) || (m->m_off > MMAXOFF))) { +#if (IPFDEBUG >= 4) + printf("IP Filter: ipl_kernel: bad m_off m_type=%d m_flags=0x%lx m_off=0x%lx\n", m->m_type, (u_long)m->m_flags, m->m_off); +#endif + return IPF_ACCEPTIT; + } + + if (m->m_len < sizeof(char)) { +#if (IPFDEBUG >= 1) + printf("IP Filter: ipl_kernel: mbuf block too small (m_len=%d) for IP vers+hlen, m_type=%d m_flags=0x%lx\n", m->m_len, m->m_type, (u_long)m->m_flags); +#endif + return IPF_ACCEPTIT; + } + + ip = mtod(m, struct ip *); + if (ip->ip_v != IPVERSION) { +#if (IPFDEBUG >= 4) + printf("IP Filter: ipl_kernel: bad ip_v\n"); +#endif + m_freem(m); + return IPF_DROPIT; + } + + ip->ip_len = htons(ip->ip_len); + ip->ip_off = htons(ip->ip_off); + hlen = ip->ip_hl << 2; + if ((*ipf_checkp)(ip, hlen, rcvif, 0, &m1) || !m1) + return IPF_DROPIT; + ip = mtod(m1, struct ip *); + ip->ip_len = ntohs(ip->ip_len); + ip->ip_off = ntohs(ip->ip_off); + +#if (IPFDEBUG >= 2) + if (m != m1) + printf("IP Filter: ipl_kernel: m != m1\n"); +#endif + } + + return IPF_ACCEPTIT; +} + +int +ipl_ipfilter_attach(void) +{ +#if defined(IPFILTER_LKM) + __psunsigned_t *addr_ff, *addr_fk; + + st_findaddr("ipfilterflag", &addr_ff); +# if (IPFDEBUG >= 1) + printf("IP Filter: st_findaddr ipfilterflag=0x%lx\n", addr_ff); +# endif + if (!addr_ff) + return ESRCH; + + st_findaddr("ipfilter_kernel", &addr_fk); +# if (IPFDEBUG >= 1) + printf("IP Filter: st_findaddr ipfilter_kernel=0x%lx\n", addr_fk); +# endif + if (!addr_fk) + return ESRCH; + + MUTEX_ENTER(&ipfi_mutex); /* sets interrupt priority level to splhi */ + + ipff_addr = (int *)addr_ff; + + ipff_value = *ipff_addr; + *ipff_addr = 0; + + + ipfk_addr = addr_fk; + + bcopy(ipfk_addr, ipfk_code, sizeof(ipfk_code)); + + /* write a "li t4, ipl_kernel" instruction */ + ipfk_addr[0] = 0x3c0c0000 | + (((__psunsigned_t)ipl_kernel >> 16) & 0xffff); + ipfk_addr[1] = 0x358c0000 | + ((__psunsigned_t)ipl_kernel & 0xffff); + /* write a "jr t4" instruction" */ + ipfk_addr[2] = 0x01800008; + + /* write a "nop" instruction */ + ipfk_addr[3] = 0; + + icache_inval(ipfk_addr, sizeof(ipfk_code)); + + *ipff_addr = 1; /* enable ipfilter_kernel */ + + MUTEX_EXIT(&ipfi_mutex); +#else + extern int ipfilterflag; + + ipfilterflag = 1; +#endif + nif_interfaces = 0; + nifattach(); + + return 0; +} + + +/* + * attach the packet filter to each non-loopback interface that is running + */ +static void +nifattach() +{ + nif_t *nif, *qf2; + struct ifnet *ifp; + struct frentry *f; + ipnat_t *np; + + MUTEX_ENTER(&ipfi_mutex); /* sets interrupt priority level to splhi */ + + for (ifp = ifnet; ifp; ifp = ifp->if_next) { + if ((!(ifp->if_flags & IFF_RUNNING)) || + (ifp->if_flags & IFF_LOOPBACK)) + continue; + + /* + * Look for entry already setup for this device + */ + for (nif = nif_head; nif; nif = nif->nf_next) + if (nif->nf_ifp == ifp) + break; + if (nif) + continue; + + if (ifp->if_output == ipl_if_output) { + printf("IP Filter: ERROR INTF 0x%lx STILL ATTACHED\n", + ifp); + continue; + } +#if (IPFDEBUG >= 2) + printf("IP Filter: nifattach nif %x opt %x\n", + ifp, ifp->if_output); +#endif + KMALLOC(nif, nif_t *); + if (!nif) { + printf("IP Filter: malloc(%d) for nif_t failed\n", + sizeof(nif_t)); + continue; + } + + nif->nf_ifp = ifp; + (void) strncpy(nif->nf_name, ifp->if_name, + sizeof(nif->nf_name)); + nif->nf_name[sizeof(nif->nf_name) - 1] = '\0'; + nif->nf_unit = ifp->if_unit; + + nif->nf_next = nif_head; + nif_head = nif; + + /* + * Activate any rules directly associated with this interface + */ + WRITE_ENTER(&ipf_mutex); + for (f = ipf_rules[0][0]; f; f = f->fr_next) { + if ((f->fr_ifa == (struct ifnet *)-1)) { + if (f->fr_ifname[0] && + (GETIFP(f->fr_ifname, 4) == ifp)) + f->fr_ifa = ifp; + } + } + for (f = ipf_rules[1][0]; f; f = f->fr_next) { + if ((f->fr_ifa == (struct ifnet *)-1)) { + if (f->fr_ifname[0] && + (GETIFP(f->fr_ifname, 4) == ifp)) + f->fr_ifa = ifp; + } + } + RWLOCK_EXIT(&ipf_mutex); + WRITE_ENTER(&ipf_nat); + for (np = nat_list; np; np = np->in_next) { + if ((np->in_ifps[0] == (void *)-1)) { + if (np->in_ifnames[0][0] && + (GETIFP(np->in_ifnames[0], 4) == ifp)) + np->in_ifps[0] = (void *)ifp; + } + if ((np->in_ifps[1] == (void *)-1)) { + if (np->in_ifnames[1][0] && + (GETIFP(np->in_ifnames[1], 4) == ifp)) + np->in_ifps[1] = (void *)ifp; + } + } + RWLOCK_EXIT(&ipf_nat); + + nif->nf_output = ifp->if_output; + ifp->if_output = ipl_if_output; + +#if (IPFDEBUG >= 2) + printf("IP Filter: nifattach: ifp(%lx)->if_output FROM %lx TO %lx\n", + ifp, nif->nf_output, ifp->if_output); +#endif + + printf("IP Filter: attach to [%s,%d]\n", + nif->nf_name, ifp->if_unit); + } + if (!nif_head) + printf("IP Filter: not attached to any interfaces\n"); + + nif_interfaces = in_interfaces; + + MUTEX_EXIT(&ipfi_mutex); + + return; +} + + +/* + * unhook the IP filter from all defined interfaces with IP addresses + */ +static void +nifdetach() +{ + nif_t *nif, *qf2, **qp; + struct ifnet *ifp; + + MUTEX_ENTER(&ipfi_mutex); /* sets interrupt priority level to splhi */ + /* + * Make two passes, first get rid of all the unknown devices, next + * unlink known devices. + */ + for (qp = &nif_head; (nif = *qp); ) { + for (ifp = ifnet; ifp; ifp = ifp->if_next) + if (nif->nf_ifp == ifp) + break; + if (ifp) { + qp = &nif->nf_next; + continue; + } + printf("IP Filter: removing [%s]\n", nif->nf_name); + *qp = nif->nf_next; + KFREE(nif); + } + + while ((nif = nif_head)) { + nif_head = nif->nf_next; + for (ifp = ifnet; ifp; ifp = ifp->if_next) + if (nif->nf_ifp == ifp) + break; + if (ifp) { + printf("IP Filter: detaching [%s,%d]\n", + nif->nf_name, ifp->if_unit); + +#if (IPFDEBUG >= 4) + printf("IP Filter: nifdetach: ifp(%lx)->if_output FROM %lx TO %lx\n", + ifp, ifp->if_output, nif->nf_output); +#endif + ifp->if_output = nif->nf_output; + } + KFREE(nif); + } + MUTEX_EXIT(&ipfi_mutex); + + return; +} + + +void +ipl_ipfilter_detach(void) +{ +#ifdef IPFILTER_LKM + nifdetach(); + MUTEX_ENTER(&ipfi_mutex); /* sets interrupt priority level to splhi */ + + if (ipff_addr) { + *ipff_addr = 0; + + if (ipfk_addr) { + bcopy(ipfk_code, ipfk_addr, sizeof(ipfk_code)); + icache_inval(ipfk_addr - 16, sizeof(ipfk_code)+32); + } + + *ipff_addr = ipff_value; + } + + MUTEX_EXIT(&ipfi_mutex); +#else + extern int ipfilterflag; + + nifdetach(); + + ipfilterflag = 0; +#endif +} + + +/* this function is called from ipf_slowtimer at 500ms intervals to + keep our interface list in sync */ +void +ipl_ipfilter_intfsync(void) +{ + MUTEX_ENTER(&ipfi_mutex); + if (nif_interfaces != in_interfaces) { + /* if the number of interfaces has changed, resync */ + MUTEX_EXIT(&ipfi_mutex); + ipf_sync(&ipfmain, NULL); + } else + MUTEX_EXIT(&ipfi_mutex); +} + +#ifdef IPFILTER_LKM +/* this routine should be treated as an interrupt routine and should + not call any routines that would cause it to sleep, such as: biowait(), + sleep(), psema() or delay(). +*/ +int +iplunload(void) +{ + int error = 0; + + if (ipf_refcnt) + return EBUSY; + + WRITE_ENTER(&ipf_global); + error = ipl_detach(); + if (error != 0) { + RWLOCK_EXIT(&ipf_global); + return error; + } + ipf_running = -2; + +#if (IRIX < 60500) + LOCK_DEALLOC(ipl_mutex.l); + LOCK_DEALLOC(ipf_rw.l); + LOCK_DEALLOC(ipf_auth.l); + LOCK_DEALLOC(ipf_natfrag.l); + LOCK_DEALLOC(ipf_ipidfrag.l); + LOCK_DEALLOC(ipf_tokens.l); + LOCK_DEALLOC(ipf_stinsert.l); + LOCK_DEALLOC(ipf_nat_new.l); + LOCK_DEALLOC(ipf_natio.l); + LOCK_DEALLOC(ipf_nat.l); + LOCK_DEALLOC(ipf_state.l); + LOCK_DEALLOC(ipf_frag.l); + LOCK_DEALLOC(ipf_auth_mx.l); + LOCK_DEALLOC(ipf_mutex.l); + LOCK_DEALLOC(ipf_frcache.l); + LOCK_DEALLOC(ipfi_mutex.l); + RWLOCK_EXIT(&ipf_global); + LOCK_DEALLOC(ipf_global.l); +#else + MUTEX_DESTROY(&ipf_rw); + MUTEX_DESTROY(&ipfi_mutex); + MUTEX_DESTROY(&ipf_timeoutlock); + RW_DESTROY(&ipf_mutex); + RW_DESTROY(&ipf_frcache); + RW_DESTROY(&ipf_tokens); + RWLOCK_EXIT(&ipf_global); + delay(hz); + RW_DESTROY(&ipf_global); +#endif + + printf("%s unloaded\n", ipfilter_version); + + delay(hz); + + return 0; +} +#endif + +void +ipfilterinit(void) +{ +#ifdef IPFILTER_LKM + int error; +#endif + +#if (IRIX < 60500) + ipfi_mutex.l = LOCK_ALLOC((uchar_t)-1, IPF_LOCK_PL, (lkinfo_t *)-1, KM_NOSLEEP); +ipf_mutex.l = LOCK_ALLOC((uchar_t)-1, IPF_LOCK_PL, (lkinfo_t *)-1, KM_NOSLEEP); +ipf_frcache.l = LOCK_ALLOC((uchar_t)-1, IPF_LOCK_PL, (lkinfo_t *)-1, KM_NOSLEEP); +ipf_timeoutlock.l = LOCK_ALLOC((uchar_t)-1, IPF_LOCK_PL, (lkinfo_t *)-1, KM_NOSLEEP); + ipf_global.l = LOCK_ALLOC((uchar_t)-1, IPF_LOCK_PL, (lkinfo_t *)-1, KM_NOSLEEP); + ipf_frag.l = LOCK_ALLOC((uchar_t)-1, IPF_LOCK_PL, (lkinfo_t *)-1, KM_NOSLEEP); + ipf_state.l = LOCK_ALLOC((uchar_t)-1, IPF_LOCK_PL, (lkinfo_t *)-1, KM_NOSLEEP); + ipf_nat.l = LOCK_ALLOC((uchar_t)-1, IPF_LOCK_PL, (lkinfo_t *)-1, KM_NOSLEEP); + ipf_stinsert.l = LOCK_ALLOC((uchar_t)-1, IPF_LOCK_PL, (lkinfo_t *)-1, KM_NOSLEEP); + ipf_natfrag.l = LOCK_ALLOC((uchar_t)-1, IPF_LOCK_PL, (lkinfo_t *)-1, KM_NOSLEEP); + ipf_ipidfrag.l = LOCK_ALLOC((uchar_t)-1, IPF_LOCK_PL, (lkinfo_t *)-1, KM_NOSLEEP); + ipf_tokens.l = LOCK_ALLOC((uchar_t)-1, IPF_LOCK_PL, (lkinfo_t *)-1, KM_NOSLEEP); + ipf_auth.l = LOCK_ALLOC((uchar_t)-1, IPF_LOCK_PL, (lkinfo_t *)-1, KM_NOSLEEP); + ipf_rw.l = LOCK_ALLOC((uchar_t)-1, IPF_LOCK_PL, (lkinfo_t *)-1, KM_NOSLEEP); + ipl_mutex.l = LOCK_ALLOC((uchar_t)-1, IPF_LOCK_PL, (lkinfo_t *)-1, KM_NOSLEEP); + + if (!ipfi_mutex.l || !ipf_mutex.l || !ipf_timeoutlock.l || + !ipf_frag.l || !ipf_state.l || !ipf_nat.l || !ipf_natfrag.l || + !ipf_auth.l || !ipf_rw.l || !ipf_ipidfrag.l || !ipl_mutex.l || + !ipf_stinsert.l || !ipf_auth_mx.l || !ipf_frcache.l || + !ipf_tokens.l) + panic("IP Filter: LOCK_ALLOC failed"); +#else + MUTEX_INIT(&ipf_rw, "ipf rw mutex"); + MUTEX_INIT(&ipf_timeoutlock, "ipf timeout mutex"); + RWLOCK_INIT(&ipf_global, "ipf filter load/unload mutex"); + RWLOCK_INIT(&ipf_mutex, "ipf filter rwlock"); + RWLOCK_INIT(&ipf_frcache, "ipf cache rwlock"); +#endif + +#ifdef IPFILTER_LKM + error = ipl_attach(); + if (error) { + iplunload(); + } else { + char *defpass; + + if (FR_ISPASS(ipf_pass)) + defpass = "pass"; + else if (FR_ISBLOCK(ipf_pass)) + defpass = "block"; + else + defpass = "no-match -> block"; + + printf("%s initialized. Default = %s all, Logging = %s%s\n", + ipfilter_version, defpass, +# ifdef IPFILTER_LOG + "enabled", +# else + "disabled", +# endif +# ifdef IPFILTER_COMPILED + " (COMPILED)" +# else + "" +# endif + ); + } +#endif + + return; +} diff --git a/contrib/ipfilter/mln_ipl.c b/contrib/ipfilter/mln_ipl.c new file mode 100644 index 000000000000..28b54071634d --- /dev/null +++ b/contrib/ipfilter/mln_ipl.c @@ -0,0 +1,355 @@ +/* $FreeBSD$ */ + +/* + * Copyright (C) 2012 by Darren Reed. + * + * See the IPFILTER.LICENCE file for details on licencing. + * + */ +/* + * 29/12/94 Added code from Marc Huber to allow it to allocate + * its own major char number! Way cool patch! + */ + + +#include + +/* + * Post NetBSD 1.2 has the PFIL interface for packet filters. This turns + * on those hooks. We don't need any special mods with this! + */ +#if (defined(NetBSD) && (NetBSD > 199609) && (NetBSD <= 1991011)) || \ + (defined(NetBSD1_2) && NetBSD1_2 > 1) +# define NETBSD_PF +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "ipl.h" +#include "ip_compat.h" +#include "ip_fil.h" +#include "ip_auth.h" +#include "ip_state.h" +#include "ip_nat.h" +#include "ip_sync.h" + +#if !defined(__NetBSD_Version__) || __NetBSD_Version__ < 103050000 +#define vn_lock(v,f) VOP_LOCK(v) +#endif + +#if !defined(VOP_LEASE) && defined(LEASE_CHECK) +#define VOP_LEASE LEASE_CHECK +#endif + + +extern int lkmenodev __P((void)); + +#if NetBSD >= 199706 +int ipflkm_lkmentry __P((struct lkm_table *, int, int)); +#else +int xxxinit __P((struct lkm_table *, int, int)); +#endif +static int ipf_unload __P((void)); +static int ipf_load __P((void)); +static int ipf_remove __P((void)); +static int ipfaction __P((struct lkm_table *, int)); +static char *ipf_devfiles[] = { IPL_NAME, IPNAT_NAME, IPSTATE_NAME, + IPAUTH_NAME, IPSYNC_NAME, IPSCAN_NAME, + IPLOOKUP_NAME, NULL }; + +int ipf_major = 0; +extern ipf_main_softc_t ipfmain; +extern const struct cdevsw ipl_cdevsw; + +#if defined(__NetBSD__) && (__NetBSD_Version__ >= 106080000) +MOD_DEV(IPL_VERSION, "ipf", NULL, -1, &ipl_cdevsw, -1); +#else +MOD_DEV(IPL_VERSION, LM_DT_CHAR, -1, &ipldevsw); +#endif + +extern int vd_unuseddev __P((void)); +extern struct cdevsw cdevsw[]; +extern int nchrdev; + + +int +#if NetBSD >= 199706 +ipflkm_lkmentry(lkmtp, cmd, ver) +#else +xxxinit(lkmtp, cmd, ver) +#endif + struct lkm_table *lkmtp; + int cmd, ver; +{ + DISPATCH(lkmtp, cmd, ver, ipfaction, ipfaction, ipfaction); +} + + +static int +ipfaction(lkmtp, cmd) + struct lkm_table *lkmtp; + int cmd; +{ +#if !defined(__NetBSD__) || (__NetBSD_Version__ < 106080000) + int i; +#endif + struct lkm_dev *args = lkmtp->private.lkm_dev; + int err = 0; + + switch (cmd) + { + case LKM_E_LOAD : + if (lkmexists(lkmtp)) + return EEXIST; + +#if defined(__NetBSD__) && (__NetBSD_Version__ >= 106080000) +# if (__NetBSD_Version__ < 200000000) + err = devsw_attach(args->lkm_devname, + args->lkm_bdev, &args->lkm_bdevmaj, + args->lkm_cdev, &args->lkm_cdevmaj); + if (err != 0) + return (err); +# endif + ipf_major = args->lkm_cdevmaj; +#else + for (i = 0; i < nchrdev; i++) + if (cdevsw[i].d_open == (dev_type_open((*)))lkmenodev || + cdevsw[i].d_open == ipfopen) + break; + if (i == nchrdev) { + printf("IP Filter: No free cdevsw slots\n"); + return ENODEV; + } + + ipf_major = i; + args->lkm_offset = i; /* slot in cdevsw[] */ +#endif + printf("IP Filter: loaded into slot %d\n", ipf_major); + return ipf_load(); + case LKM_E_UNLOAD : +#if defined(__NetBSD__) && (__NetBSD_Version__ >= 106080000) + devsw_detach(args->lkm_bdev, args->lkm_cdev); + args->lkm_bdevmaj = -1; + args->lkm_cdevmaj = -1; +#endif + err = ipf_unload(); + if (!err) + printf("IP Filter: unloaded from slot %d\n", + ipf_major); + break; + case LKM_E_STAT : + break; + default: + err = EIO; + break; + } + return err; +} + + +static int +ipf_remove() +{ + char *name; + struct nameidata nd; + int error, i; + + for (i = 0; (name = ipf_devfiles[i]); i++) { +#if (__NetBSD_Version__ > 106009999) +# if (__NetBSD_Version__ > 399001400) +# if (__NetBSD_Version__ > 499001400) + NDINIT(&nd, DELETE, LOCKPARENT|LOCKLEAF, UIO_SYSSPACE, + name); +# else + NDINIT(&nd, DELETE, LOCKPARENT|LOCKLEAF, UIO_SYSSPACE, + name, curlwp); +# endif +# else + NDINIT(&nd, DELETE, LOCKPARENT|LOCKLEAF, UIO_SYSSPACE, + name, curproc); +# endif +#else + NDINIT(&nd, DELETE, LOCKPARENT, UIO_SYSSPACE, name, curproc); +#endif + if ((error = namei(&nd))) + return (error); +#if (__NetBSD_Version__ > 399001400) +# if (__NetBSD_Version__ > 399002000) +# if (__NetBSD_Version__ < 499001400) + VOP_LEASE(nd.ni_dvp, curlwp, curlwp->l_cred, LEASE_WRITE); +# endif +# else + VOP_LEASE(nd.ni_dvp, curlwp, curlwp->l_proc->p_ucred, LEASE_WRITE); +# endif +#else + VOP_LEASE(nd.ni_dvp, curproc, curproc->p_ucred, LEASE_WRITE); +#endif +#if !defined(__NetBSD_Version__) || (__NetBSD_Version__ < 106000000) + vn_lock(nd.ni_vp, LK_EXCLUSIVE | LK_RETRY); +#endif +#if (__NetBSD_Version__ >= 399002000) +# if (__NetBSD_Version__ < 499001400) + VOP_LEASE(nd.ni_vp, curlwp, curlwp->l_cred, LEASE_WRITE); +# endif +#else +# if (__NetBSD_Version__ > 399001400) + VOP_LEASE(nd.ni_vp, curlwp, curlwp->l_proc->p_ucred, LEASE_WRITE); +# else + VOP_LEASE(nd.ni_vp, curproc, curproc->p_ucred, LEASE_WRITE); +# endif +#endif + (void) VOP_REMOVE(nd.ni_dvp, nd.ni_vp, &nd.ni_cnd); + } + return 0; +} + + +static int +ipf_unload() +{ + int error = 0; + + /* + * Unloading - remove the filter rule check from the IP + * input/output stream. + */ + if (ipfmain.ipf_refcnt) + error = EBUSY; + else if (ipfmain.ipf_running >= 0) { + error = ipfdetach(&ipfmain); + if (error == 0) { + ipf_destroy_all(&ipfmain); + ipf_unload_all(); + } + } + + if (error == 0) { + ipfmain.ipf_running = -2; + error = ipf_remove(); + printf("%s unloaded\n", ipfilter_version); + } + return error; +} + + +static int +ipf_load() +{ + struct nameidata nd; + struct vattr vattr; + int error = 0, fmode = S_IFCHR|0600, i; + char *name; + + /* + * XXX Remove existing device nodes prior to creating new ones + * XXX using the assigned LKM device slot's major number. In a + * XXX perfect world we could use the ones specified by cdevsw[]. + */ + (void)ipf_remove(); + + bzero((char *)&ipfmain, sizeof(ipfmain)); + error = ipf_load_all(); + if (error != 0) + return error; + if (ipf_create_all(&ipfmain) == NULL) { + ipf_unload_all(); + return EIO; + } + + error = ipfattach(&ipfmain); + if (error != 0) { + (void) ipf_unload(); + return error; + } + + for (i = 0; (error == 0) && (name = ipf_devfiles[i]); i++) { +#if (__NetBSD_Version__ > 399001400) +# if (__NetBSD_Version__ > 499001400) + NDINIT(&nd, CREATE, LOCKPARENT, UIO_SYSSPACE, name); +# else + NDINIT(&nd, CREATE, LOCKPARENT, UIO_SYSSPACE, name, curlwp); +# endif +#else + NDINIT(&nd, CREATE, LOCKPARENT, UIO_SYSSPACE, name, curproc); +#endif + if ((error = namei(&nd))) + break; + if (nd.ni_vp != NULL) { + VOP_ABORTOP(nd.ni_dvp, &nd.ni_cnd); + if (nd.ni_dvp == nd.ni_vp) + vrele(nd.ni_dvp); + else + vput(nd.ni_dvp); + vrele(nd.ni_vp); + error = EEXIST; + break; + } + VATTR_NULL(&vattr); + vattr.va_type = VCHR; + vattr.va_mode = (fmode & 07777); + vattr.va_rdev = (ipf_major << 8) | i; +#if (__NetBSD_Version__ > 399001400) +# if (__NetBSD_Version__ >= 399002000) +# if (__NetBSD_Version__ < 499001400) + VOP_LEASE(nd.ni_dvp, curlwp, curlwp->l_cred, LEASE_WRITE); +# endif +# else + VOP_LEASE(nd.ni_dvp, curlwp, curlwp->l_proc->p_ucred, LEASE_WRITE); +# endif +#else + VOP_LEASE(nd.ni_dvp, curproc, curproc->p_ucred, LEASE_WRITE); +#endif + error = VOP_MKNOD(nd.ni_dvp, &nd.ni_vp, &nd.ni_cnd, &vattr); + if (error == 0) + vput(nd.ni_vp); + } + + if (error == 0) { + char *defpass; + + if (FR_ISPASS(ipfmain.ipf_pass)) + defpass = "pass"; + else if (FR_ISBLOCK(ipfmain.ipf_pass)) + defpass = "block"; + else + defpass = "no-match -> block"; + + printf("%s initialized. Default = %s all, Logging = %s%s\n", + ipfilter_version, defpass, +#ifdef IPFILTER_LOG + "enabled", +#else + "disabled", +#endif +#ifdef IPFILTER_COMPILED + " (COMPILED)" +#else + "" +#endif + ); + ipfmain.ipf_running = 1; + } + return error; +} diff --git a/contrib/ipfilter/mln_rule.c b/contrib/ipfilter/mln_rule.c new file mode 100644 index 000000000000..2df3376816b4 --- /dev/null +++ b/contrib/ipfilter/mln_rule.c @@ -0,0 +1,83 @@ +/* + * Copyright (C) 2012 by Darren Reed. + * + * See the IPFILTER.LICENCE file for details on licencing. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "ip_compat.h" +#include "ip_fil.h" +#include "ip_rules.h" + + +static int ipfruleaction __P((struct lkm_table *, int)); + +#ifdef IPFILTER_LKM +# if NetBSD >= 199706 +int ipfrule_lkmentry __P((struct lkm_table *, int, int)); +# else +int xxxinit __P((struct lkm_table *, int, int)); +# endif + + +MOD_MISC("IPFilter Rules"); + +# if NetBSD >= 199706 +int ipfrule_lkmentry(lkmtp, cmd, ver) +# else +int xxxinit(lkmtp, cmd, ver) +# endif + struct lkm_table *lkmtp; + int cmd, ver; +{ + DISPATCH(lkmtp, cmd, ver, ipfruleaction, ipfruleaction, ipfruleaction); +} + +static int ipfruleaction(lkmtp, cmd) + struct lkm_table *lkmtp; + int cmd; +{ + int err = 0; + + switch (cmd) + { + case LKM_E_LOAD : + if (lkmexists(lkmtp)) + return EEXIST; + + err = ipfrule_add(); + if (!err) + ipf_refcnt++; + break; + case LKM_E_UNLOAD : + err = ipfrule_remove(); + if (!err) + ipf_refcnt--; + break; + case LKM_E_STAT : + break; + default: + err = EIO; + break; + } + return err; +} +#endif /* IPFILTER_LKM */ diff --git a/contrib/ipfilter/mlo_ipl.c b/contrib/ipfilter/mlo_ipl.c new file mode 100644 index 000000000000..35556fa33f54 --- /dev/null +++ b/contrib/ipfilter/mlo_ipl.c @@ -0,0 +1,364 @@ +/* $FreeBSD$ */ + +/* + * Copyright (C) 2012 by Darren Reed. + * + * See the IPFILTER.LICENCE file for details on licencing. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "ipl.h" +#include "ip_compat.h" +#include "ip_fil.h" + +#define vn_lock(v,f) VOP_LOCK(v) + +#if !defined(VOP_LEASE) && defined(LEASE_CHECK) +#define VOP_LEASE LEASE_CHECK +#endif + + +extern int lkmenodev __P((void)); + +#if OpenBSD >= 200311 +int if_ipf_lkmentry __P((struct lkm_table *, int, int)); +#else +int if_ipf __P((struct lkm_table *, int, int)); +#endif +static int ipf_unload __P((void)); +static int ipf_load __P((void)); +static int ipf_remove __P((void)); +static int ipfaction __P((struct lkm_table *, int)); +static char *ipf_devfiles[] = { IPL_NAME, IPNAT_NAME, IPSTATE_NAME, + IPAUTH_NAME, IPSYNC_NAME, IPSCAN_NAME, + IPLOOKUP_NAME, NULL }; + + +struct cdevsw ipfdevsw = +{ + ipfopen, /* open */ + ipfclose, /* close */ + ipfread, /* read */ + (void *)nullop, /* write */ + ipfioctl, /* ioctl */ + (void *)nullop, /* stop */ + (void *)NULL, /* tty */ + (void *)nullop, /* select */ + (void *)nullop, /* mmap */ + NULL /* strategy */ +}; + +int ipf_major = 0; + +MOD_DEV(IPL_VERSION, LM_DT_CHAR, -1, &ipfdevsw); + +extern int vd_unuseddev __P((void)); +extern struct cdevsw cdevsw[]; +extern int nchrdev; + + +#if OpenBSD >= 200311 +int if_ipf_lkmentry (lkmtp, cmd, ver) +#else +int if_ipf(lkmtp, cmd, ver) +#endif + struct lkm_table *lkmtp; + int cmd, ver; +{ + DISPATCH(lkmtp, cmd, ver, ipfaction, ipfaction, ipfaction); +} + +int lkmexists __P((struct lkm_table *)); /* defined in /sys/kern/kern_lkm.c */ + +static int ipfaction(lkmtp, cmd) + struct lkm_table *lkmtp; + int cmd; +{ + int i; + struct lkm_dev *args = lkmtp->private.lkm_dev; + int err = 0; + + switch (cmd) + { + case LKM_E_LOAD : + if (lkmexists(lkmtp)) + return EEXIST; + + for (i = 0; i < nchrdev; i++) + if (cdevsw[i].d_open == (dev_type_open((*)))lkmenodev || + cdevsw[i].d_open == ipfopen) + break; + if (i == nchrdev) { + printf("IP Filter: No free cdevsw slots\n"); + return ENODEV; + } + + ipf_major = i; + args->lkm_offset = i; /* slot in cdevsw[] */ + printf("IP Filter: loaded into slot %d\n", ipf_major); + return ipf_load(); + case LKM_E_UNLOAD : + err = ipf_unload(); + if (!err) + printf("IP Filter: unloaded from slot %d\n", + ipf_major); + break; + case LKM_E_STAT : + break; + default: + err = EIO; + break; + } + return err; +} + + +static int ipf_remove() +{ + struct nameidata nd; + int error, i; + char *name; + + for (i = 0; (name = ipf_devfiles[i]); i++) { +#if OpenBSD >= 200311 + NDINIT(&nd, DELETE, LOCKPARENT | LOCKLEAF, UIO_SYSSPACE, + name, curproc); +#else + NDINIT(&nd, DELETE, LOCKPARENT, UIO_SYSSPACE, name, curproc); +#endif + if ((error = namei(&nd))) + return (error); + VOP_LEASE(nd.ni_vp, curproc, curproc->p_ucred, LEASE_WRITE); +#if OpenBSD < 200311 + VOP_LOCK(nd.ni_vp, LK_EXCLUSIVE | LK_RETRY, curproc); + VOP_LEASE(nd.ni_dvp, curproc, curproc->p_ucred, LEASE_WRITE); +#else + (void)uvm_vnp_uncache(nd.ni_vp); + + VOP_LEASE(nd.ni_dvp, curproc, curproc->p_ucred, LEASE_WRITE); + VOP_LEASE(nd.ni_vp, curproc, curproc->p_ucred, LEASE_WRITE); +#endif + (void) VOP_REMOVE(nd.ni_dvp, nd.ni_vp, &nd.ni_cnd); + } + return 0; +} + + +static int ipf_unload() +{ + int error = 0; + + /* + * Unloading - remove the filter rule check from the IP + * input/output stream. + */ + if (ipf_refcnt) + error = EBUSY; + else if (ipf_running >= 0) + error = ipfdetach(); + + if (error == 0) { + ipf_running = -2; + error = ipf_remove(); + printf("%s unloaded\n", ipfilter_version); + } + return error; +} + + +static int ipf_load() +{ + struct nameidata nd; + struct vattr vattr; + int error = 0, fmode = S_IFCHR|0600, i; + char *name; + + /* + * XXX Remove existing device nodes prior to creating new ones + * XXX using the assigned LKM device slot's major number. In a + * XXX perfect world we could use the ones specified by cdevsw[]. + */ + (void)ipf_remove(); + + error = ipfattach(); + + for (i = 0; (error == 0) && (name = ipf_devfiles[i]); i++) { + NDINIT(&nd, CREATE, LOCKPARENT, UIO_SYSSPACE, name, curproc); + if ((error = namei(&nd))) + break; + if (nd.ni_vp != NULL) { + VOP_ABORTOP(nd.ni_dvp, &nd.ni_cnd); + if (nd.ni_dvp == nd.ni_vp) + vrele(nd.ni_dvp); + else + vput(nd.ni_dvp); + vrele(nd.ni_vp); + error = EEXIST; + break; + } + VATTR_NULL(&vattr); + vattr.va_type = VCHR; + vattr.va_mode = (fmode & 07777); + vattr.va_rdev = (ipf_major << 8) | i; + VOP_LEASE(nd.ni_dvp, curproc, curproc->p_ucred, LEASE_WRITE); + error = VOP_MKNOD(nd.ni_dvp, &nd.ni_vp, &nd.ni_cnd, &vattr); + } + + if (error == 0) { + char *defpass; + + if (FR_ISPASS(ipf_pass)) + defpass = "pass"; + else if (FR_ISBLOCK(ipf_pass)) + defpass = "block"; + else + defpass = "no-match -> block"; + + printf("%s initialized. Default = %s all, Logging = %s%s\n", + ipfilter_version, defpass, +#ifdef IPFILTER_LOG + "enabled", +#else + "disabled", +#endif +#ifdef IPFILTER_COMPILED + " (COMPILED)" +#else + "" +#endif + ); + ipf_running = 1; + } + return error; +} + + +/* + * routines below for saving IP headers to buffer + */ +int +ipfopen(dev, flags, devtype, p) + dev_t dev; + int flags; + int devtype; + struct proc *p; +{ + u_int min = GET_MINOR(dev); + int error; + + if (IPL_LOGMAX < min) { + error = ENXIO; + } else { + switch (unit) + { + case IPL_LOGIPF : + case IPL_LOGNAT : + case IPL_LOGSTATE : + case IPL_LOGAUTH : + case IPL_LOGLOOKUP : + case IPL_LOGSYNC : +#ifdef IPFILTER_SCAN + case IPL_LOGSCAN : +#endif + error = 0; + break; + default : + error = ENXIO; + break; + } + } + return error; +} + + +int +ipfclose(dev, flags, devtype, p) + dev_t dev; + int flags; + int devtype; + struct proc *p; +{ + u_int min = GET_MINOR(dev); + + if (IPL_LOGMAX < min) + min = ENXIO; + else + min = 0; + return min; +} + + +/* + * ipfread/ipflog + * both of these must operate with at least splnet() lest they be + * called during packet processing and cause an inconsistancy to appear in + * the filter lists. + */ +int +ipfread(dev, uio, ioflag) + dev_t dev; + register struct uio *uio; + int ioflag; +{ + + if (ipf_running < 1) + return EIO; + + if (GET_MINOR(dev) == IPL_LOGSYNC) + return ipfsync_read(uio); + +#ifdef IPFILTER_LOG + return ipflog_read(GET_MINOR(dev), uio); +#else + return ENXIO; +#endif +} + + +/* + * ipfwrite + * both of these must operate with at least splnet() lest they be + * called during packet processing and cause an inconsistancy to appear in + * the filter lists. + */ +int +#if (BSD >= 199306) +ipfwrite(dev, uio, ioflag) + int ioflag; +#else +ipfwrite(dev, uio) +#endif + dev_t dev; + register struct uio *uio; +{ + + if (ipf_running < 1) + return EIO; + + if (GET_MINOR(dev) == IPL_LOGSYNC) + return ipfsync_write(uio); + return ENXIO; +} diff --git a/contrib/ipfilter/mlo_rule.c b/contrib/ipfilter/mlo_rule.c new file mode 100644 index 000000000000..dbd4305970ee --- /dev/null +++ b/contrib/ipfilter/mlo_rule.c @@ -0,0 +1,80 @@ +/* $FreeBSD$ */ + +/* + * Copyright (C) 2012 by Darren Reed. + * + * See the IPFILTER.LICENCE file for details on licencing. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "ip_compat.h" +#include "ip_fil.h" +#include "ip_rules.h" + + +#ifdef IPFILTER_LKM + +static int ipfruleaction __P((struct lkm_table *, int)); + +int ipfrule __P((struct lkm_table *, int, int)); + + +MOD_MISC("IPFilter Rules"); + +int ipfrule(lkmtp, cmd, ver) + struct lkm_table *lkmtp; + int cmd, ver; +{ + DISPATCH(lkmtp, cmd, ver, ipfruleaction, ipfruleaction, ipfruleaction); +} + +int lkmexists __P((struct lkm_table *)); /* defined in /sys/kern/kern_lkm.c */ + +static int ipfruleaction(lkmtp, cmd) + struct lkm_table *lkmtp; + int cmd; +{ + int err = 0; + + switch (cmd) + { + case LKM_E_LOAD : + if (lkmexists(lkmtp)) + return EEXIST; + + err = ipfrule_add(); + if (!err) + ipf_refcnt++; + break; + case LKM_E_UNLOAD : + err = ipfrule_remove(); + if (!err) + ipf_refcnt--; + break; + case LKM_E_STAT : + break; + default: + err = EIO; + break; + } + return err; +} +#endif /* IPFILTER_LKM */ diff --git a/contrib/ipfilter/mls_ipl.c b/contrib/ipfilter/mls_ipl.c new file mode 100644 index 000000000000..4388b617e631 --- /dev/null +++ b/contrib/ipfilter/mls_ipl.c @@ -0,0 +1,351 @@ +/* $FreeBSD$ */ + +/* + * Copyright (C) 2012 by Darren Reed. + * + * See the IPFILTER.LICENCE file for details on licencing. + */ +/* + * 29/12/94 Added code from Marc Huber to allow it to allocate + * its own major char number! Way cool patch! + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#if defined(sun4c) || defined(sun4m) +# include +#endif +#include +#include +#include +#include +#include +#include +#include +#include "ipl.h" +#include "ip_compat.h" +#include "ip_fil.h" + + +#if !defined(lint) +static const char sccsid[] = "@(#)mls_ipl.c 2.6 10/15/95 (C) 1993-2000 Darren Reed"; +static const char rcsid[] = "@(#)$Id$"; +#endif + +extern int ipfdetach __P((void)); +#ifndef IPFILTER_LOG +#define ipfread nulldev +#endif +extern int nulldev __P((void)); +extern int errno; + +extern int nodev __P((void)); + +static int unload __P((void)); +static int ipf_attach __P((void)); +int xxxinit __P((u_int, struct vddrv *, caddr_t, struct vdstat *)); +static char *ipf_devfiles[] = { IPL_NAME, IPNAT_NAME, IPSTATE_NAME, + IPAUTH_NAME, IPSYNC_NAME, IPSCAN_NAME, + IPLOOKUP_NAME, NULL }; +static int ipfopen __P((dev_t, int)); +static int ipfclose __P((dev_t, int)); +static int ipfread __P((dev_t, struct uio *)); +static int ipfwrite __P((dev_t, struct uio *)); + + +struct cdevsw ipfdevsw = +{ + ipfopen, ipfclose, ipfread, nulldev, + ipfioctl, nulldev, nulldev, nulldev, + 0, nulldev, +}; + + +struct dev_ops ipf_ops = +{ + 1, + ipfidentify, + ipfattach, + ipfopen, + ipfclose, + ipfread, + ipfwrite, + NULL, /* strategy */ + NULL, /* dump */ + 0, /* psize */ + ipfioctl, + NULL, /* reset */ + NULL /* mmap */ +}; + +int ipf_major = 0; + +#ifdef sun4m +struct vdldrv vd = +{ + VDMAGIC_PSEUDO, + IPL_VERSION, + &ipf_ops, + NULL, + &ipfdevsw, + 0, + 0, + NULL, + NULL, + NULL, + 0, + 1, +}; +#else /* sun4m */ +struct vdldrv vd = +{ + VDMAGIC_PSEUDO, /* magic */ + IPL_VERSION, +#ifdef sun4c + &ipf_ops, /* dev_ops */ +#else + NULL, /* struct mb_ctlr *mb_ctlr */ + NULL, /* struct mb_driver *mb_driver */ + NULL, /* struct mb_device *mb_device */ + 0, /* num ctlrs */ + 1, /* numdevs */ +#endif /* sun4c */ + NULL, /* bdevsw */ + &ipfdevsw, /* cdevsw */ + 0, /* block major */ + 0, /* char major */ +}; +#endif /* sun4m */ + +extern int vd_unuseddev __P((void)); +extern struct cdevsw cdevsw[]; +extern int nchrdev; + +xxxinit(fc, vdp, data, vds) + u_int fc; + struct vddrv *vdp; + caddr_t data; + struct vdstat *vds; +{ + struct vdioctl_load *vdi = (struct vdioctl_load *)data; + + switch (fc) + { + case VDLOAD: + { + struct vdconf *vdc; + if (vdi && vdi->vdi_userconf) + for (vdc = vdi->vdi_userconf; vdc->vdc_type; vdc++) + if (vdc->vdc_type == VDCCHARMAJOR) { + ipf_major = vdc->vdc_data; + break; + } + + if (!ipf_major) { + while (ipf_major < nchrdev && + cdevsw[ipf_major].d_open != vd_unuseddev) + ipf_major++; + if (ipf_major == nchrdev) + return ENODEV; + } + vdp->vdd_vdtab = (struct vdlinkage *)&vd; + vd.Drv_charmajor = ipf_major; + return ipf_attach(); + } + case VDUNLOAD: + return unload(); + case VDSTAT: + return 0; + default: + return EIO; + } +} + + +static int +unload() +{ + int err = 0, i; + char *name; + + if (ipf_refcnt != 0) + err = EBUSY; + else if (ipf_running >= 0) + err = ipfdetach(); + if (err) + return err; + + ipf_running = -2; + for (i = 0; (name = ipf_devfiles[i]); i++) + (void) vn_remove(name, UIO_SYSSPACE, FILE); + printf("%s unloaded\n", ipfilter_version); + return 0; +} + + +static int +ipf_attach() +{ + struct vnode *vp; + struct vattr vattr; + int error = 0, fmode = S_IFCHR|0600, i; + char *name; + + error = ipfattach(); + if (error) + return error; + + for (i = 0; (name = ipf_devfiles[i]); i++) { + (void) vn_remove(name, UIO_SYSSPACE, FILE); + vattr_null(&vattr); + vattr.va_type = MFTOVT(fmode); + vattr.va_mode = (fmode & 07777); + vattr.va_rdev = (ipf_major << 8) | i; + + error = vn_create(name, UIO_SYSSPACE, &vattr, EXCL, 0, &vp); + if (error) { + printf("IP Filter: vn_create(%s) = %d\n", name, error); + break; + } else { + VN_RELE(vp); + } + } + + if (error == 0) { + char *defpass; + + if (FR_ISPASS(ipf_pass)) + defpass = "pass"; + else if (FR_ISBLOCK(ipf_pass)) + defpass = "block"; + else + defpass = "no-match -> block"; + + printf("%s initialized. Default = %s all, Logging = %s%s\n", + ipfilter_version, defpass, +#ifdef IPFILTER_LOG + "enabled", +#else + "disabled", +#endif +#ifdef IPFILTER_COMPILED + " (COMPILED)" +#else + "" +#endif + ); + ipf_running = 1; + } + return error; +} + + +/* + * routines below for saving IP headers to buffer + */ +static int +ipfopen(dev, flags) + dev_t dev; + int flags; +{ + u_int unit = GET_MINOR(dev); + int error; + + if (IPL_LOGMAX < unit) { + error = ENXIO; + } else { + switch (unit) + { + case IPL_LOGIPF : + case IPL_LOGNAT : + case IPL_LOGSTATE : + case IPL_LOGAUTH : + case IPL_LOGLOOKUP : + case IPL_LOGSYNC : +#ifdef IPFILTER_SCAN + case IPL_LOGSCAN : +#endif + error = 0; + break; + default : + error = ENXIO; + break; + } + } + return error; +} + + +static int +ipfclose(dev, flags) + dev_t dev; + int flags; +{ + u_int unit = GET_MINOR(dev); + + if (IPL_LOGMAX < unit) + unit = ENXIO; + else + unit = 0; + return unit; +} + + +/* + * ipfread/ipflog + * both of these must operate with at least splnet() lest they be + * called during packet processing and cause an inconsistancy to appear in + * the filter lists. + */ +static int +ipfread(dev, uio) + dev_t dev; + register struct uio *uio; +{ + + if (ipf_running < 1) { + ipfmain.ipf_interror = 130006; + return EIO; + } + +#ifdef IPFILTER_LOG + return ipflog_read(GET_MINOR(dev), uio); +#else + ipfmain.ipf_interror = 130007; + return ENXIO; +#endif +} + + +/* + * ipfwrite + */ +static int +ipfwrite(dev, uio) + dev_t dev; + register struct uio *uio; +{ + + if (ipf_running < 1) { + ipfmain.ipf_interror = 130008; + return EIO; + } + + if (getminor(dev) == IPL_LOGSYNC) + return ipfsync_write(uio); + ipfmain.ipf_interror = 130009; + return ENXIO; +} diff --git a/contrib/ipfilter/mls_rule.c b/contrib/ipfilter/mls_rule.c new file mode 100644 index 000000000000..e37df0c89314 --- /dev/null +++ b/contrib/ipfilter/mls_rule.c @@ -0,0 +1,116 @@ +/* $FreeBSD$ */ + +/* + * Copyright (C) 2012 by Darren Reed. + * + * See the IPFILTER.LICENCE file for details on licencing. + */ +/* + * 29/12/94 Added code from Marc Huber to allow it to allocate + * its own major char number! Way cool patch! + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#if defined(sun4c) || defined(sun4m) +# include +#endif +#include +#include +#include +#include +#include +#include +#include +#include "ip_compat.h" +#include "ip_fil.h" +#include "ip_rules.h" + + +extern int errno; + + +int xxxinit __P((u_int, struct vddrv *, caddr_t, struct vdstat *)); + +int ipl_major = 0; + +#ifdef sun4m +struct vdldrv vd = +{ + VDMAGIC_USER, + "IP Filter rules", + NULL, + NULL, + NULL, + 0, + 0, + NULL, + NULL, + NULL, + 0, + 1, +}; +#else /* sun4m */ +struct vdldrv vd = +{ + VDMAGIC_USER, /* magic */ + "IP Filter rules", +#ifdef sun4c + NULL, /* dev_ops */ +#else + NULL, /* struct mb_ctlr *mb_ctlr */ + NULL, /* struct mb_driver *mb_driver */ + NULL, /* struct mb_device *mb_device */ + 0, /* num ctlrs */ + 1, /* numdevs */ +#endif /* sun4c */ + NULL, /* bdevsw */ + NULL, /* cdevsw */ + 0, /* block major */ + 0, /* char major */ +}; +#endif /* sun4m */ + + +xxxinit(fc, vdp, data, vds) + u_int fc; + struct vddrv *vdp; + caddr_t data; + struct vdstat *vds; +{ + struct vdioctl_load *vdi = (struct vdioctl_load *)data; + int err; + + switch (fc) + { + case VDLOAD: + err = ipfrule_add(); + if (!err) + ipf_refcnt++; + break; + case VDUNLOAD: + err = ipfrule_remove(); + if (!err) + ipf_refcnt--; + break; + case VDSTAT: + err = 0; + break; + default: + err = EIO; + break; + } +} diff --git a/contrib/ipfilter/mlso_rule.c b/contrib/ipfilter/mlso_rule.c new file mode 100644 index 000000000000..a9395f2d2f71 --- /dev/null +++ b/contrib/ipfilter/mlso_rule.c @@ -0,0 +1,130 @@ +/* $FreeBSD$ */ + +/* + * Copyright (C) 2012 by Darren Reed. + * + * See the IPFILTER.LICENCE file for details on licencing. + */ +#pragma ident "@(#)$Id$" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#if SOLARIS2 >= 6 +# include +#endif +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "ip_compat.h" +#include "ip_fil.h" +#include "ip_rules.h" + +char _depends_on[] = "drv/ipf"; + + +extern ipf_main_softc_t ipfmain; +extern struct mod_ops mod_miscops; +static struct modlmisc ipfrulemod = { + &mod_miscops, + "IP Filter rules" +}; + +static struct modlinkage modlink1 = { + MODREV_1, + &ipfrulemod, + NULL +}; + + +int _init() +{ + int ipfruleinst; + + ipfruleinst = mod_install(&modlink1); +#ifdef IPFRULEDEBUG + cmn_err(CE_NOTE, "IP Filter Rules: _init() = %d", ipfruleinst); +#endif + + if (ipfruleinst == 0) { + if (ipfmain.ipf_running >= 0) { + ipfruleinst = ipfrule_add(); + if (!ipfruleinst) + ipfmain.ipf_refcnt++; + else { + cmn_err(CE_NOTE, + "IP Filter Rules: ipfrule_add failed"); + ipfruleinst = -1; + } + } else + ipfruleinst = -1; + } + if (ipfruleinst == 0) + cmn_err(CE_CONT, "IP Filter Rules: loaded\n"); + return ipfruleinst; +} + + +int _fini(void) +{ + int ipfruleinst; + + ipfruleinst = mod_remove(&modlink1); +#ifdef IPFRULEDEBUG + cmn_err(CE_NOTE, "IP Filter Rules: _fini() = %d", ipfruleinst); +#endif + if (ipfruleinst == 0) { + ipfruleinst = ipfrule_remove(); + if (!ipfruleinst) + ipfmain.ipf_refcnt--; + else + ipfruleinst = -1; + } + if (ipfruleinst == 0) + cmn_err(CE_CONT, "IP Filter Rules: unloaded\n"); + return ipfruleinst; +} + + +int _info(modinfop) + struct modinfo *modinfop; +{ + int ipfruleinst; + + ipfruleinst = mod_info(&modlink1, modinfop); +#ifdef IPFRULEDEBUG + cmn_err(CE_NOTE, "IP Filter Rules: _info(%x) = %x", + modinfop, ipfruleinst); +#endif + return ipfruleinst; +} diff --git a/contrib/ipfilter/net/.cvsignore b/contrib/ipfilter/net/.cvsignore deleted file mode 100644 index 19f86f493ab1..000000000000 --- a/contrib/ipfilter/net/.cvsignore +++ /dev/null @@ -1 +0,0 @@ -done diff --git a/contrib/ipfilter/opts.h b/contrib/ipfilter/opts.h index fa53c8f5fe90..3c8b88b2f037 100644 --- a/contrib/ipfilter/opts.h +++ b/contrib/ipfilter/opts.h @@ -1,11 +1,11 @@ /* $FreeBSD$ */ /* - * Copyright (C) 2000 by Darren Reed. + * Copyright (C) 2012 by Darren Reed. * * See the IPFILTER.LICENCE file for details on licencing. * - * $Id: opts.h,v 2.12 2003/08/14 14:24:27 darrenr Exp $ + * $Id$ */ #ifndef __OPTS_H__ @@ -42,6 +42,8 @@ #define OPT_HEX 0x2000000 #define OPT_ASCII 0x4000000 #define OPT_NORESOLVE 0x8000000 +#define OPT_DONTOPEN 0x10000000 +#define OPT_PURGE 0x20000000 #define OPT_STAT OPT_FRSTATES #define OPT_LIST OPT_SHOWLIST diff --git a/contrib/ipfilter/pcap-ipf.h b/contrib/ipfilter/pcap-ipf.h index 71250ad61389..b856760eaa53 100644 --- a/contrib/ipfilter/pcap-ipf.h +++ b/contrib/ipfilter/pcap-ipf.h @@ -1,7 +1,7 @@ /* $FreeBSD$ */ /* - * Copyright (C) 1993-2001 by Darren Reed. + * Copyright (C) 2012 by Darren Reed. * * See the IPFILTER.LICENCE file for details on licencing. * diff --git a/contrib/ipfilter/perl/Ipfanaly.pl b/contrib/ipfilter/perl/Ipfanaly.pl index 0fa7c17ef7fb..eda232ee9592 100644 --- a/contrib/ipfilter/perl/Ipfanaly.pl +++ b/contrib/ipfilter/perl/Ipfanaly.pl @@ -41,7 +41,7 @@ if ($maxout > $maxin) ($dayis,$monthis,$yearis)=split "/",$dateis; $month=$months{$monthis}; $dateis="$dayis " . "$month " . "$yearis "; -# split graphs in to 6 four hour spans for 24 hours +# split graphs in to 6 four hour spans for 24 hours $numgraphs=int($XMAX/240); $junk=0; @@ -62,7 +62,7 @@ while ($cnt1++ < $numgraphs) $filename3="graph$cnt1.conf"; open(OUTDATA,"> $filename2") || die "Couldnt open $filename2 for writing \n"; open(INDATA,"> $filename1") || die "Couldnt open $filename1 for writing \n"; - + $loop=$end; $end=($end + 240); @@ -144,7 +144,7 @@ sub packbytime { local ($xmax)=@_; $XMAX=$xmax; # pass in the dest port number or get graph for all packets -# at 1 minute intervals +# at 1 minute intervals # @shortrecs has form 209.24.1.217 123 192.216.16.2 123 udp len 20 76 # @recs has form 27/07/1998 00:01:05.216596 le0 @0:2 L 192.216.21.16,2733 -> 192.216.16.2,53 PR udp len 20 62 # @@ -175,9 +175,9 @@ while ($cnt++ <= $#recs ) if("$destip" eq "$gatekeep") { # TO GATEKEEP port lookat -# print "to gatekeep at $xpos\n"; +# print "to gatekeep at $xpos\n"; $value5=$inwards[$xpos] [1]; - $value5++ ; + $value5++ ; # $maxin = $value5 if $maxin < $value5 ; if($value5 > $maxin) @@ -190,9 +190,9 @@ while ($cnt++ <= $#recs ) else { # FROM GATEKEEP to port lookat -# print "from gatekeep at $xpos\n"; +# print "from gatekeep at $xpos\n"; $value4=$outwards[$xpos] [1]; - $value4++ ; + $value4++ ; # $maxout = $value4 if $maxout < $value4 ; if($value4 > $maxout) { @@ -212,18 +212,18 @@ while ($cnt++ <= $#recs ) if("$destip" eq "$gatekeep") { # TO GATEKEEP port lookat -# print "to gatekeep at $xpos\n"; +# print "to gatekeep at $xpos\n"; $value5=$inwards[$xpos] [1]; - $value5++ ; + $value5++ ; $maxin = $value5 if $maxin < $value5 ; $inwards[$xpos][1]=$value5; } else { # FROM GATEKEEP to port lookat -# print "from gatekeep at $xpos\n"; +# print "from gatekeep at $xpos\n"; $value4=$outwards[$xpos] [1]; - $value4++ ; + $value4++ ; $maxout = $value4 if $maxout < $value4 ; $outwards[$xpos][1]=$value4; } @@ -276,7 +276,7 @@ $loop=-1; while ($loop++ <= $#recs ) { ($srcip,$srcport,$destip,$destport,$pro)= split " " , @shortrecs[$loop]; - if ("$destip" eq "$gatekeep") + if ("$destip" eq "$gatekeep") { if ($destport < $ITRUSTABOVE ) { @@ -309,10 +309,10 @@ print "# Sites sending > $percsafe % of all packets to gatekeep MAY be attacking print "Trusted hosts are $safehosts\n"; print "\nTOTAL packets were $#recs \n"; print "########################################################################\n"; -while(($ipadd,$numpacketsent)=each %numpacks) +while(($ipadd,$numpacketsent)=each %numpacks) { $perc=$numpacketsent/$#recs*100; -if ($perc > $percsafe) +if ($perc > $percsafe) # dont believe safehosts are attacking! { $where=index($safehosts,$ipadd); @@ -326,7 +326,7 @@ if ($perc > $percsafe) } print "\n\n"; -} # end of subroutine toobusy_site +} # end of subroutine toobusy_site ############### END SUBROUTINE DECLARATIONS ########### @@ -339,7 +339,7 @@ if("$opt_t" eq "0") {usage;print "\n---->ERROR: You must psecify the IP address of the interface that collected the data!\n"; exit; } - + if("$opt_h" eq "1") {usage;exit 0}; if("$opt_H" eq "1") @@ -379,7 +379,7 @@ if("$opt_p" eq "") # -p arg must be all or AN INTEGER in range 1<=N<=64K if ("$opt_p" ne "all") { - $_=$opt_p; + $_=$opt_p; unless (/^[+-]?\d+$/) { usage; @@ -394,7 +394,7 @@ if ("$opt_p" ne "all") $lookat=$opt_p; # -o arg must be all or AN INTEGER in range 1<=N<=64K - $_=$opt_o; + $_=$opt_o; unless (/^[+-]?\d+$/) { usage; @@ -438,7 +438,7 @@ open (REC, $FILENAME) || die "Cant open $FILENAME: \n"; ($dev,$ino,$mode,$nlink,$uid,$gid,$rdev,$size,$junk)=stat REC; print "Log file $FILENAME is $size bytes in size\n"; #each record is an element of array rec[] now -while() +while() { @recs[$numrec++]=$_; } @@ -456,7 +456,7 @@ while ($loop++ < $#recs ) $bit=substr(@recs[$loop],39); $bit =~ s/,/ /g; ($sourceip,$junkit)= split " " , $bit ; - + # NOTE the . is the string concat command NOT + .......!!!! $sourceip =~ split " ", $sourceip; @@ -467,7 +467,7 @@ while ($loop++ < $#recs ) $allips = $allips . "$sourceip " ; } } - + print "Put all unique ip addresses into a 1D array\n"; @allips=split " ", $allips; @@ -490,7 +490,7 @@ while ($loop++ < $#recs ) { $a = $srcip . $icmp . $ptr . $destip . $icmp . $icmp . $lenst . $lenicmp ; } - + # dump the "->" and commas from logging $a =~ s/->//g; $a =~ s/PR//g; @@ -503,7 +503,7 @@ while ($loop++ < $#recs ) ($srcip,$junk) = split " ","$a"; $numpackets=$numpacks{"$srcip"}; $numpackets++ ; - $numpacks{"$srcip"}=$numpackets; + $numpacks{"$srcip"}=$numpackets; } @@ -546,7 +546,7 @@ while ($cnt++ < $#allips) while ($loop++ < $#recs ) { -# get src IP num, src port number, +# get src IP num, src port number, # destination IP num, destnation port number,protocol ($srcip,$srcport,$destip,$destport,$pro)= split " " , @shortrecs[$loop]; # loop over all records for the machine $uniqip @@ -564,7 +564,7 @@ while ($cnt++ < $#allips) { $srcportnam=$services{$srcport}; } -# try and get dest portname, if not there, leave it as the +# try and get dest portname, if not there, leave it as the # dest portnumber if ("$destport" eq "icmp") { $destportnam="icmp";} @@ -581,15 +581,15 @@ while ($cnt++ < $#allips) if ($srcportnam eq "") { # increment number of times a (high)/unknown port has gone to destport - $value1=$unknownsrcports{$destportnam}; - $value1++ ; + $value1=$unknownsrcports{$destportnam}; + $value1++ ; $unknownsrcports{$destportnam}=$value1; } else { # want tally(srcport) counter to be increased by 1 $value3=$tally{$srcportnam}; - $value3++ ; + $value3++ ; $tally{$srcportnam}=$value3; } } @@ -603,7 +603,7 @@ if ($set eq "N") $set="Y"; print "\n#### with $uniqip as the the source for packets ####\n"; -while(($key,$value)=each %tally) +while(($key,$value)=each %tally) { if (not "$uniqip" eq "$gatekeep") { @@ -617,7 +617,7 @@ while(($key,$value)=each %tally) -while(($key2,$value2)=each %unknownsrcports) +while(($key2,$value2)=each %unknownsrcports) { if (not "$uniqip" eq "$gatekeep") { @@ -632,7 +632,7 @@ while(($key2,$value2)=each %unknownsrcports) } # print if rests for UNIQIP IF flag is set to N then toggle flag -} # end of all IPs loop +} # end of all IPs loop } # end of if verbose option set block diff --git a/contrib/ipfilter/perl/Isbgraph b/contrib/ipfilter/perl/Isbgraph index c68b672322f0..8641099b608f 100644 --- a/contrib/ipfilter/perl/Isbgraph +++ b/contrib/ipfilter/perl/Isbgraph @@ -67,7 +67,7 @@ close(CNF); # number datapoints/24 hours is 1440 (minutes) # # Split into N graphs where each graph has max of 240 datapoints (4 hours) -# +# $barset=0; $m=0; @@ -117,7 +117,7 @@ $teal=$im->colorAllocate(51,153,153); $xspace= $XINIT+$option{'XCELLGRIDSIZE'}*$i +$i; # $im->line($xspace,$YINIT,$xspace,$YGRAPH,gdStyled); $num = $i+1; - + use integer; { $posis=$num - ($num/60)*60; @@ -157,7 +157,7 @@ $nextdata="N"; $count=0; $i=0; $fname=$_; - + print "fname $fname\n"; # change entry for red in colour table to green for packets LEAVING target host @@ -180,14 +180,14 @@ $nextdata="N"; if($nextdata eq "Y") { - + #$im->line($XINIT,$YGRAPH,$X,$Y,$orange); $im->line($xspaceold,$yspaceold,$xspace,$yspace,$green); } else { $im->line($xspaceold,$yspaceold,$xspace,$yspace,$red); - } + } } else { @@ -214,7 +214,7 @@ $nextdata="N"; $im->line(500,60,530,60,$green); $im->string(gdSmallFont,535,35,"Packets IN",$fg); $im->string(gdSmallFont,535,55,"Packets OUT",$fg); - + if ($option{'Bar'} ne 0) { if ($X eq $option{'XMAX'}) @@ -237,7 +237,7 @@ $nextdata="N"; $nextdata="Y"; # TOP LEFT is 0,0 on GIF (image) -# origin of plot is xinit,yinit +# origin of plot is xinit,yinit # print "little line\n"; $im->line($xspace,$yspace,$xspace,$YGRAPH,$blue); $im->line($xspace,$YGRAPH,$XINIT,$YGRAPH,$blue); diff --git a/contrib/ipfilter/perl/Services b/contrib/ipfilter/perl/Services index 401fff00dd03..e9ae317367c9 100644 --- a/contrib/ipfilter/perl/Services +++ b/contrib/ipfilter/perl/Services @@ -89,7 +89,7 @@ 110 pop3 PostOfficeProtocol-Version3 111 sunrpc SUNRemoteProcedureCall 112 mcidas McIDASDataTransmissionProtocol -113 ident +113 ident 114 audionews AudioNewsMulticast 115 sftp SimpleFileTransferProtocol 116 ansanotify ANSAREXNotify @@ -426,7 +426,7 @@ 515 printer spooler 516 videotex videotex 517 talk liketenexlink,butacross -518 ntalk +518 ntalk 519 utime unixtime 520 route 521 ripng ripng @@ -451,7 +451,7 @@ 540 uucp uucpd 541 uucp-rlogin uucp-rlogin 542 commerce commerce -543 klogin +543 klogin 544 kshell krcmd 545 appleqtcsrvr appleqtcsrvr 546 dhcpv6-client DHCPv6Client @@ -463,7 +463,7 @@ 552 deviceshare deviceshare 553 pirp pirp 554 rtsp RealTimeStreamControlProtocol -555 dsf +555 dsf 556 remotefs rfsserver 557 openvms-sysipc openvms-sysipc 558 sdnskmp SDNSKMP @@ -542,7 +542,7 @@ 637 lanserver lanserver 638 mcns-sec mcns-sec 639 msdp MSDP -666 mdqs +666 mdqs 667 disclose campaigncontributiondisclosures-SDRTechnologies 668 mecomm MeComm 669 meregister MeRegister @@ -569,32 +569,32 @@ 748 ris-cm RussellInfoSciCalendarManager 749 kerberos-adm kerberosadministration 750 kerberos-iv kerberosversioniv -751 pump -752 qrh -753 rrh +751 pump +752 qrh +753 rrh 754 tell send -758 nlogin -759 con -760 ns -761 rxe -762 quotad -763 cycleserv -764 omserv -765 webster +758 nlogin +759 con +760 ns +761 rxe +762 quotad +763 cycleserv +764 omserv +765 webster 767 phonebook phone -769 vid -770 cadlock -771 rtip -772 cycleserv2 -773 notify -774 rpasswd -775 acmaint_transd -776 wpages -780 wpgs +769 vid +770 cadlock +771 rtip +772 cycleserv2 +773 notify +774 rpasswd +775 acmaint_transd +776 wpages +780 wpgs 786 concert Concert 787 qsc QSC -800 mdbs_daemon -801 device +800 mdbs_daemon +801 device 829 pkix-3-ca-ra PKIX-3CA/RA 873 rsync rsync 886 iclcnet-locate ICLcoNETionlocateserver @@ -610,10 +610,10 @@ 994 ircs ircprotocoloverTLS/SSL 995 pop3s pop3protocoloverTLS/SSL(wasspop3) 996 vsinet vsinet -997 maitrd -998 busboy -999 garcon -1000 cadlock +997 maitrd +998 busboy +999 garcon +1000 cadlock 1008 ufsd 1010 surf surf 1011 Reserved @@ -654,7 +654,7 @@ 1222 nerv SNIR&Dnetwork 1234 search-agent InfoseekSearchAgent 1239 nmsd NMSD -1248 hermes +1248 hermes 1300 h323hostcallsc H323HostCallSecure 1313 bmc_patroldb BMC_PATROLDB 1314 pdps PhotoscriptDistributedPrintingSystem @@ -695,7 +695,7 @@ 1379 dbreporter IntegritySolutions 1380 telesis-licman TelesisNetworkLicenseManager 1381 apple-licman AppleNetworkLicenseManager -1382 udt_os +1382 udt_os 1383 gwha GWHannawayNetworkLicenseManager 1384 os-licman ObjectiveSolutionsLicenseManager 1385 atex_elmd AtexPublishingLicenseManager @@ -913,7 +913,7 @@ 1597 orbplus-iiop orbplus-iiop 1598 picknfs picknfs 1599 simbaservices simbaservices -1600 issd +1600 issd 1601 aas aas 1602 inspect inspect 1603 picodbc pickodbc @@ -1079,7 +1079,7 @@ 1772 essweb-gw EssWebGateway 1773 kmscontrol KMSControl 1774 global-dtserv global-dtserv -1775 Unknown +1775 Unknown 1776 femis FederalEmergencyManagementInformationSystem 1777 powerguardian powerguardian 1778 prodigy-intrnet prodigy-internet @@ -1180,49 +1180,49 @@ 1997 gdp-port ciscoGatewayDiscoveryProtocol 1998 x25-svc-port ciscoX.25service(XOT) 1999 tcp-id-port ciscoidentificationport -2000 callbook -2001 dc -2002 globe -2004 mailbox -2005 berknet -2006 invokator -2007 dectalk -2008 conf -2009 news -2010 search +2000 callbook +2001 dc +2002 globe +2004 mailbox +2005 berknet +2006 invokator +2007 dectalk +2008 conf +2009 news +2010 search 2011 raid-cc raid -2012 ttyinfo -2013 raid-am -2014 troff -2015 cypress -2016 bootserver -2017 cypress-stat -2018 terminaldb -2019 whosockami -2020 xinupageserver -2021 servexec -2022 down -2023 xinuexpansion3 -2024 xinuexpansion4 -2025 ellpack -2026 scrabble -2027 shadowserver -2028 submitserver -2030 device2 -2032 blackboard -2033 glogger -2034 scoremgr -2035 imsldoc -2038 objectmanager -2040 lam -2041 interbase +2012 ttyinfo +2013 raid-am +2014 troff +2015 cypress +2016 bootserver +2017 cypress-stat +2018 terminaldb +2019 whosockami +2020 xinupageserver +2021 servexec +2022 down +2023 xinuexpansion3 +2024 xinuexpansion4 +2025 ellpack +2026 scrabble +2027 shadowserver +2028 submitserver +2030 device2 +2032 blackboard +2033 glogger +2034 scoremgr +2035 imsldoc +2038 objectmanager +2040 lam +2041 interbase 2042 isis isis 2043 isis-bcast isis-bcast -2044 rimsl -2045 cdfunc -2046 sdfunc -2047 dls -2048 dls-monitor +2044 rimsl +2045 cdfunc +2046 sdfunc +2047 dls +2048 dls-monitor 2049 nfsd-or-shilp 2065 dlsrpn DataLinkSwitchReadPortNumber 2067 dlswpn DataLinkSwitchWritePortNumber @@ -1798,8 +1798,8 @@ 4868 phrelay PhotonRelay 4869 phrelaydbg PhotonRelayDebug 4885 abbs ABBS -5000 commplex-main -5001 commplex-link +5000 commplex-main +5001 commplex-link 5002 rfe radiofreeethernet 5003 fmpro-internal FileMaker,Inc.-Proprietarynamebinding 5004 avt-profile-1 avt-profile-1 @@ -1812,13 +1812,13 @@ 5051 ita-agent ITAAgent 5052 ita-manager ITAManager 5060 sip SIP -5145 rmonitor_secure +5145 rmonitor_secure 5150 atmp AscendTunnelManagementProtocol 5190 aol America-Online 5191 aol-1 AmericaOnline1 5192 aol-2 AmericaOnline2 5193 aol-3 AmericaOnline3 -5236 padl2sim +5236 padl2sim 5272 pk PK 5300 hacl-hb #HAclusterheartbeat 5301 hacl-gs #HAclustergeneralservices @@ -1975,7 +1975,7 @@ 6506 badm_pub BoKSAdminPublicPort 6507 bdir_priv BoKSDirServer,PrivatePort 6508 bdir_pub BoKSDirServer,PublicPort -6558 xdsxdm +6558 xdsxdm 6665 ircu 6666 ircu 6667 ircu @@ -2059,7 +2059,7 @@ 9000 cslistener CSlistener 9006 sctp SCTP 9090 websm WebSM -9535 man +9535 man 9594 msgsys MessageSystem 9595 pds PingDiscoveryService 9876 sd SessionDirector @@ -2093,7 +2093,7 @@ 13821 dsmcc-download DSMCCDownloadProtocol 13822 dsmcc-ccp DSMCCChannelChangeProtocol 14001 itu-sccp-ss7 ITUSCCP(SS7) -17007 isode-dua +17007 isode-dua 17219 chipper Chipper 18000 biimenu BeckmanInstruments,Inc. 19541 jcp JCPClient diff --git a/contrib/ipfilter/perl/ipfmeta.pl b/contrib/ipfilter/perl/ipfmeta.pl index 1a7bb3f1a0e7..decc35b8bd23 100644 --- a/contrib/ipfilter/perl/ipfmeta.pl +++ b/contrib/ipfilter/perl/ipfmeta.pl @@ -83,7 +83,7 @@ sub expand { return @retlines; } - + __END__ =head1 NAME @@ -164,7 +164,7 @@ block in from UNWANTED to any pass in from NOC to WEBSERVERS port = MGMT-PORTS pass out all - + I ipfmeta ipf.objs ipf.rules diff --git a/contrib/ipfilter/perl/logfilter.pl b/contrib/ipfilter/perl/logfilter.pl index 6ebe401ab4ee..fd0da6db181e 100644 --- a/contrib/ipfilter/perl/logfilter.pl +++ b/contrib/ipfilter/perl/logfilter.pl @@ -3,7 +3,7 @@ # Author: Chris Grant # Copyright 1999, Codetalker Communications, Inc. # -# This script takes a firewall log and breaks it into several +# This script takes a firewall log and breaks it into several # different files. Each file is named based on the service that # runs on the port that was recognized in log line. After # this script has run, you should end up with several files. @@ -18,11 +18,11 @@ # # You may be wondering why I haven't simply parsed RFC1700 to come up # with a list of port numbers and files. The reason is that I don't -# believe reading firewall logs should be all that automated. You +# believe reading firewall logs should be all that automated. You # should be familiar with what probes are hitting your system. By -# manually adding entries to the data section this ensures that I -# have at least educated myself about what this protocol is, what -# the potential exposure is, and why you might be seeing this traffic. +# manually adding entries to the data section this ensures that I +# have at least educated myself about what this protocol is, what +# the potential exposure is, and why you might be seeing this traffic. %icmp = (); %udp = (); @@ -61,30 +61,30 @@ while($line = ) { # determine the protocol - send to unknown.log if not found SWITCH: { - ($line =~ m /\sicmp\s/) && do { + ($line =~ m /\sicmp\s/) && do { # - # ICMP Protocol + # ICMP Protocol # # Extract the icmp packet information specifying the type. - # + # # Note: Must check for ICMP first because this may be an ICMP reply # to a TCP or UDP connection (eg Port Unreachable). - + ($icmptype) = $line =~ m/icmp (\d+)\/\d+/; $filename = $TIDBITSFILE; $filename = $icmp{$icmptype} if (defined($icmp{$icmptype})); - last SWITCH; + last SWITCH; }; - ($line =~ m /\stcp\s/) && do { + ($line =~ m /\stcp\s/) && do { - # + # # TCP Protocol # - # extract the source and destination ports and compare them to + # extract the source and destination ports and compare them to # known ports in the tcp hash. For the first match, place this # line in the file specified by the tcp hash. Ignore one of the # port matches if both ports happen to be known services. @@ -96,14 +96,14 @@ while($line = ) { $filename = $tcp{$sport} if (defined($tcp{$sport})); $filename = $tcp{$dport} if (defined($tcp{$dport})); - last SWITCH; + last SWITCH; }; - ($line =~ m /\sudp\s/) && do { + ($line =~ m /\sudp\s/) && do { # # UDP Protocol - same procedure as with TCP, different hash - # + # ($sport, $dport) = $line =~ m/\d+\.\d+\.\d+\.\d+,(\d+) -> \d+\.\d+\.\d+\.\d+,(\d+)/; @@ -111,7 +111,7 @@ while($line = ) { $filename = $udp{$sport} if (defined($udp{$sport})); $filename = $udp{$dport} if (defined($udp{$dport})); - last SWITCH; + last SWITCH; }; # @@ -126,7 +126,7 @@ while($line = ) { # check for filename in the openfiles hash. if it exists then write # to the given handle. otherwise open a handle to the file and add # it to the hash of open files. - + if (defined($openfiles{$filename})) { $handle = $openfiles{$filename}; } else { @@ -178,4 +178,4 @@ tcp 6667 irc.log tcp 7070 realaudio.log tcp 8080 http.log tcp 12345 netbus.log -udp 31337 backorifice.log \ No newline at end of file +udp 31337 backorifice.log diff --git a/contrib/ipfilter/radix.c b/contrib/ipfilter/radix.c deleted file mode 100644 index 8c67562553e2..000000000000 --- a/contrib/ipfilter/radix.c +++ /dev/null @@ -1,1214 +0,0 @@ -/* $FreeBSD$ */ - -/* - * Copyright (c) 1988, 1989, 1993 - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * @(#)radix.c 8.6 (Berkeley) 10/17/95 - */ - -/* - * Routines to build and maintain radix trees for routing lookups. - */ -#if defined(KERNEL) || defined(_KERNEL) -# undef KERNEL -# undef _KERNEL -# define KERNEL 1 -# define _KERNEL 1 -#endif -#define __SYS_ATOMIC_OPS_H__ -#if !defined(__svr4__) && !defined(__SVR4) && !defined(__osf__) && \ - !defined(__hpux) && !defined(__sgi) -#include -#endif -#ifndef __P -# ifdef __STDC__ -# define __P(x) x -# else -# define __P(x) () -# endif -#endif -#ifdef __osf__ -# define CONST -# define _IPV6_SWTAB_H -# define _PROTO_NET_H_ -# define _PROTO_IPV6_H -# include -#endif - -#include -#ifdef _KERNEL -#include -#else -void panic __P((char *str)); -#include -#include -#include -#include -#endif -#ifdef __hpux -#include -#else -#include -#endif -#include -#include -#include -#include -#ifdef SOLARIS2 -# define _RADIX_H_ -#endif -#include "netinet/ip_compat.h" -#include "netinet/ip_fil.h" -#ifdef SOLARIS2 -# undef _RADIX_H_ -#endif -/* END OF INCLUDES */ -#include "radix_ipf.h" -#ifndef min -# define min MIN -#endif -#ifndef max -# define max MAX -#endif - -int max_keylen = 16; -static struct radix_mask *rn_mkfreelist; -static struct radix_node_head *mask_rnhead; -static char *addmask_key; -static u_char normal_chars[] = {0, 0x80, 0xc0, 0xe0, 0xf0, 0xf8, 0xfc, 0xfe, 0xff}; -static char *rn_zeros = NULL, *rn_ones = NULL; - -#define rn_masktop (mask_rnhead->rnh_treetop) -#undef Bcmp -#define Bcmp(a, b, l) (l == 0 ? 0 : bcmp((caddr_t)(a), (caddr_t)(b), (u_long)l)) - -static int rn_satisfies_leaf __P((char *, struct radix_node *, int)); -static int rn_lexobetter __P((void *, void *)); -static struct radix_mask *rn_new_radix_mask __P((struct radix_node *, - struct radix_mask *)); -static int rn_freenode __P((struct radix_node *, void *)); -#if defined(AIX) && !defined(_KERNEL) -struct radix_node *rn_match __P((void *, struct radix_node_head *)); -struct radix_node *rn_addmask __P((int, int, void *)); -#define FreeS(x, y) KFREES(x, y) -#define Bcopy(x, y, z) bcopy(x, y, z) -#endif - -/* - * The data structure for the keys is a radix tree with one way - * branching removed. The index rn_b at an internal node n represents a bit - * position to be tested. The tree is arranged so that all descendants - * of a node n have keys whose bits all agree up to position rn_b - 1. - * (We say the index of n is rn_b.) - * - * There is at least one descendant which has a one bit at position rn_b, - * and at least one with a zero there. - * - * A route is determined by a pair of key and mask. We require that the - * bit-wise logical and of the key and mask to be the key. - * We define the index of a route to associated with the mask to be - * the first bit number in the mask where 0 occurs (with bit number 0 - * representing the highest order bit). - * - * We say a mask is normal if every bit is 0, past the index of the mask. - * If a node n has a descendant (k, m) with index(m) == index(n) == rn_b, - * and m is a normal mask, then the route applies to every descendant of n. - * If the index(m) < rn_b, this implies the trailing last few bits of k - * before bit b are all 0, (and hence consequently true of every descendant - * of n), so the route applies to all descendants of the node as well. - * - * Similar logic shows that a non-normal mask m such that - * index(m) <= index(n) could potentially apply to many children of n. - * Thus, for each non-host route, we attach its mask to a list at an internal - * node as high in the tree as we can go. - * - * The present version of the code makes use of normal routes in short- - * circuiting an explicit mask and compare operation when testing whether - * a key satisfies a normal route, and also in remembering the unique leaf - * that governs a subtree. - */ - -struct radix_node * -rn_search(v_arg, head) - void *v_arg; - struct radix_node *head; -{ - struct radix_node *x; - caddr_t v; - - for (x = head, v = v_arg; x->rn_b >= 0;) { - if (x->rn_bmask & v[x->rn_off]) - x = x->rn_r; - else - x = x->rn_l; - } - return (x); -} - -struct radix_node * -rn_search_m(v_arg, head, m_arg) - struct radix_node *head; - void *v_arg, *m_arg; -{ - struct radix_node *x; - caddr_t v = v_arg, m = m_arg; - - for (x = head; x->rn_b >= 0;) { - if ((x->rn_bmask & m[x->rn_off]) && - (x->rn_bmask & v[x->rn_off])) - x = x->rn_r; - else - x = x->rn_l; - } - return x; -} - -int -rn_refines(m_arg, n_arg) - void *m_arg, *n_arg; -{ - caddr_t m = m_arg, n = n_arg; - caddr_t lim, lim2 = lim = n + *(u_char *)n; - int longer = (*(u_char *)n++) - (int)(*(u_char *)m++); - int masks_are_equal = 1; - - if (longer > 0) - lim -= longer; - while (n < lim) { - if (*n & ~(*m)) - return 0; - if (*n++ != *m++) - masks_are_equal = 0; - } - while (n < lim2) - if (*n++) - return 0; - if (masks_are_equal && (longer < 0)) - for (lim2 = m - longer; m < lim2; ) - if (*m++) - return 1; - return (!masks_are_equal); -} - -struct radix_node * -rn_lookup(v_arg, m_arg, head) - void *v_arg, *m_arg; - struct radix_node_head *head; -{ - struct radix_node *x; - caddr_t netmask = 0; - - if (m_arg) { - if ((x = rn_addmask(m_arg, 1, head->rnh_treetop->rn_off)) == 0) - return (0); - netmask = x->rn_key; - } - x = rn_match(v_arg, head); - if (x && netmask) { - while (x && x->rn_mask != netmask) - x = x->rn_dupedkey; - } - return x; -} - -static int -rn_satisfies_leaf(trial, leaf, skip) - char *trial; - struct radix_node *leaf; - int skip; -{ - char *cp = trial, *cp2 = leaf->rn_key, *cp3 = leaf->rn_mask; - char *cplim; - int length = min(*(u_char *)cp, *(u_char *)cp2); - - if (cp3 == 0) - cp3 = rn_ones; - else - length = min(length, *(u_char *)cp3); - cplim = cp + length; - cp3 += skip; - cp2 += skip; - for (cp += skip; cp < cplim; cp++, cp2++, cp3++) - if ((*cp ^ *cp2) & *cp3) - return 0; - return 1; -} - -struct radix_node * -rn_match(v_arg, head) - void *v_arg; - struct radix_node_head *head; -{ - caddr_t v = v_arg; - struct radix_node *t = head->rnh_treetop, *x; - caddr_t cp = v, cp2; - caddr_t cplim; - struct radix_node *saved_t, *top = t; - int off = t->rn_off, vlen = *(u_char *)cp, matched_off; - int test, b, rn_b; - - /* - * Open code rn_search(v, top) to avoid overhead of extra - * subroutine call. - */ - for (; t->rn_b >= 0; ) { - if (t->rn_bmask & cp[t->rn_off]) - t = t->rn_r; - else - t = t->rn_l; - } - /* - * See if we match exactly as a host destination - * or at least learn how many bits match, for normal mask finesse. - * - * It doesn't hurt us to limit how many bytes to check - * to the length of the mask, since if it matches we had a genuine - * match and the leaf we have is the most specific one anyway; - * if it didn't match with a shorter length it would fail - * with a long one. This wins big for class B&C netmasks which - * are probably the most common case... - */ - if (t->rn_mask) - vlen = *(u_char *)t->rn_mask; - cp += off; - cp2 = t->rn_key + off; - cplim = v + vlen; - for (; cp < cplim; cp++, cp2++) - if (*cp != *cp2) - goto on1; - /* - * This extra grot is in case we are explicitly asked - * to look up the default. Ugh! - */ - if ((t->rn_flags & RNF_ROOT) && t->rn_dupedkey) - t = t->rn_dupedkey; - return t; -on1: - test = (*cp ^ *cp2) & 0xff; /* find first bit that differs */ - for (b = 7; (test >>= 1) > 0;) - b--; - matched_off = cp - v; - b += matched_off << 3; - rn_b = -1 - b; - /* - * If there is a host route in a duped-key chain, it will be first. - */ - if ((saved_t = t)->rn_mask == 0) - t = t->rn_dupedkey; - for (; t; t = t->rn_dupedkey) - /* - * Even if we don't match exactly as a host, - * we may match if the leaf we wound up at is - * a route to a net. - */ - if (t->rn_flags & RNF_NORMAL) { - if (rn_b <= t->rn_b) - return t; - } else if (rn_satisfies_leaf(v, t, matched_off)) - return t; - t = saved_t; - /* start searching up the tree */ - do { - struct radix_mask *m; - t = t->rn_p; - m = t->rn_mklist; - if (m) { - /* - * If non-contiguous masks ever become important - * we can restore the masking and open coding of - * the search and satisfaction test and put the - * calculation of "off" back before the "do". - */ - do { - if (m->rm_flags & RNF_NORMAL) { - if (rn_b <= m->rm_b) - return (m->rm_leaf); - } else { - off = min(t->rn_off, matched_off); - x = rn_search_m(v, t, m->rm_mask); - while (x && x->rn_mask != m->rm_mask) - x = x->rn_dupedkey; - if (x && rn_satisfies_leaf(v, x, off)) - return x; - } - m = m->rm_mklist; - } while (m); - } - } while (t != top); - return 0; -} - -#ifdef RN_DEBUG -int rn_nodenum; -struct radix_node *rn_clist; -int rn_saveinfo; -int rn_debug = 1; -#endif - -struct radix_node * -rn_newpair(v, b, nodes) - void *v; - int b; - struct radix_node nodes[2]; -{ - struct radix_node *tt = nodes, *t = tt + 1; - t->rn_b = b; - t->rn_bmask = 0x80 >> (b & 7); - t->rn_l = tt; - t->rn_off = b >> 3; - tt->rn_b = -1; - tt->rn_key = (caddr_t)v; - tt->rn_p = t; - tt->rn_flags = t->rn_flags = RNF_ACTIVE; -#ifdef RN_DEBUG - tt->rn_info = rn_nodenum++; - t->rn_info = rn_nodenum++; - tt->rn_twin = t; - tt->rn_ybro = rn_clist; - rn_clist = tt; -#endif - return t; -} - -struct radix_node * -rn_insert(v_arg, head, dupentry, nodes) - void *v_arg; - struct radix_node_head *head; - int *dupentry; - struct radix_node nodes[2]; -{ - caddr_t v = v_arg; - struct radix_node *top = head->rnh_treetop; - int head_off = top->rn_off, vlen = (int)*((u_char *)v); - struct radix_node *t = rn_search(v_arg, top); - caddr_t cp = v + head_off; - int b; - struct radix_node *tt; - -#ifdef RN_DEBUG - if (rn_debug) - log(LOG_DEBUG, "rn_insert(%p,%p,%p,%p)\n", v_arg, head, dupentry, nodes); -#endif - /* - * Find first bit at which v and t->rn_key differ - */ - { - caddr_t cp2 = t->rn_key + head_off; - int cmp_res; - caddr_t cplim = v + vlen; - - while (cp < cplim) - if (*cp2++ != *cp++) - goto on1; - *dupentry = 1; - return t; -on1: - *dupentry = 0; - cmp_res = (cp[-1] ^ cp2[-1]) & 0xff; - for (b = (cp - v) << 3; cmp_res; b--) - cmp_res >>= 1; - } - { - struct radix_node *p, *x = top; - cp = v; - do { - p = x; - if (cp[x->rn_off] & x->rn_bmask) - x = x->rn_r; - else - x = x->rn_l; - } while (b > (unsigned) x->rn_b); /* x->rn_b < b && x->rn_b >= 0 */ -#ifdef RN_DEBUG - if (rn_debug) - log(LOG_DEBUG, "rn_insert: Going In:\n"); // traverse(p); -#endif - t = rn_newpair(v_arg, b, nodes); - tt = t->rn_l; - if ((cp[p->rn_off] & p->rn_bmask) == 0) - p->rn_l = t; - else - p->rn_r = t; - x->rn_p = t; - t->rn_p = p; /* frees x, p as temp vars below */ - if ((cp[t->rn_off] & t->rn_bmask) == 0) { - t->rn_r = x; - } else { - t->rn_r = tt; - t->rn_l = x; - } -#ifdef RN_DEBUG - if (rn_debug) - log(LOG_DEBUG, "rn_insert: Coming Out:\n"); // traverse(p); -#endif - } - return (tt); -} - -struct radix_node * -rn_addmask(n_arg, search, skip) - int search, skip; - void *n_arg; -{ - caddr_t netmask = (caddr_t)n_arg; - struct radix_node *x; - caddr_t cp, cplim; - int b = 0, mlen, j; - int maskduplicated, m0, isnormal; - struct radix_node *saved_x; - static int last_zeroed = 0; - -#ifdef RN_DEBUG - if (rn_debug) - log(LOG_DEBUG, "rn_addmask(%p,%d,%d)\n", n_arg, search, skip); -#endif - mlen = *(u_char *)netmask; - if ((mlen = *(u_char *)netmask) > max_keylen) - mlen = max_keylen; - if (skip == 0) - skip = 1; - if (mlen <= skip) - return (mask_rnhead->rnh_nodes); - if (skip > 1) - Bcopy(rn_ones + 1, addmask_key + 1, skip - 1); - if ((m0 = mlen) > skip) - Bcopy(netmask + skip, addmask_key + skip, mlen - skip); - /* - * Trim trailing zeroes. - */ - for (cp = addmask_key + mlen; (cp > addmask_key) && cp[-1] == 0;) - cp--; - mlen = cp - addmask_key; - if (mlen <= skip) { - if (m0 >= last_zeroed) - last_zeroed = mlen; - return (mask_rnhead->rnh_nodes); - } - if (m0 < last_zeroed) - Bzero(addmask_key + m0, last_zeroed - m0); - *addmask_key = last_zeroed = mlen; - x = rn_search(addmask_key, rn_masktop); - if (Bcmp(addmask_key, x->rn_key, mlen) != 0) - x = 0; - if (x || search) - return (x); - R_Malloc(x, struct radix_node *, max_keylen + 2 * sizeof (*x)); - if ((saved_x = x) == 0) - return (0); - Bzero(x, max_keylen + 2 * sizeof (*x)); - netmask = cp = (caddr_t)(x + 2); - Bcopy(addmask_key, cp, mlen); - x = rn_insert(cp, mask_rnhead, &maskduplicated, x); - if (maskduplicated) { -#if 0 - log(LOG_ERR, "rn_addmask: mask impossibly already in tree\n"); -#endif - Free(saved_x); - return (x); - } - /* - * Calculate index of mask, and check for normalcy. - */ - cplim = netmask + mlen; - isnormal = 1; - for (cp = netmask + skip; (cp < cplim) && *(u_char *)cp == 0xff;) - cp++; - if (cp != cplim) { - for (j = 0x80; (j & *cp) != 0; j >>= 1) - b++; - if (*cp != normal_chars[b] || cp != (cplim - 1)) - isnormal = 0; - } - b += (cp - netmask) << 3; - x->rn_b = -1 - b; - if (isnormal) - x->rn_flags |= RNF_NORMAL; - return (x); -} - -static int /* XXX: arbitrary ordering for non-contiguous masks */ -rn_lexobetter(m_arg, n_arg) - void *m_arg, *n_arg; -{ - u_char *mp = m_arg, *np = n_arg, *lim; - - if (*mp > *np) - return 1; /* not really, but need to check longer one first */ - if (*mp == *np) - for (lim = mp + *mp; mp < lim;) - if (*mp++ > *np++) - return 1; - return 0; -} - -static struct radix_mask * -rn_new_radix_mask(tt, next) - struct radix_node *tt; - struct radix_mask *next; -{ - struct radix_mask *m; - - MKGet(m); - if (m == 0) { -#if 0 - log(LOG_ERR, "Mask for route not entered\n"); -#endif - return (0); - } - Bzero(m, sizeof *m); - m->rm_b = tt->rn_b; - m->rm_flags = tt->rn_flags; - if (tt->rn_flags & RNF_NORMAL) - m->rm_leaf = tt; - else - m->rm_mask = tt->rn_mask; - m->rm_mklist = next; - tt->rn_mklist = m; - return m; -} - -struct radix_node * -rn_addroute(v_arg, n_arg, head, treenodes) - void *v_arg, *n_arg; - struct radix_node_head *head; - struct radix_node treenodes[2]; -{ - caddr_t v = (caddr_t)v_arg, netmask = (caddr_t)n_arg; - struct radix_node *t, *x = NULL, *tt; - struct radix_node *saved_tt, *top = head->rnh_treetop; - short b = 0, b_leaf = 0; - int keyduplicated; - caddr_t mmask; - struct radix_mask *m, **mp; - -#ifdef RN_DEBUG - if (rn_debug) - log(LOG_DEBUG, "rn_addroute(%p,%p,%p,%p)\n", v_arg, n_arg, head, treenodes); -#endif - /* - * In dealing with non-contiguous masks, there may be - * many different routes which have the same mask. - * We will find it useful to have a unique pointer to - * the mask to speed avoiding duplicate references at - * nodes and possibly save time in calculating indices. - */ - if (netmask) { - if ((x = rn_addmask(netmask, 0, top->rn_off)) == 0) - return (0); - b_leaf = x->rn_b; - b = -1 - x->rn_b; - netmask = x->rn_key; - } - /* - * Deal with duplicated keys: attach node to previous instance - */ - saved_tt = tt = rn_insert(v, head, &keyduplicated, treenodes); - if (keyduplicated) { - for (t = tt; tt; t = tt, tt = tt->rn_dupedkey) { - if (tt->rn_mask == netmask) - return (0); - if (netmask == 0 || - (tt->rn_mask && - ((b_leaf < tt->rn_b) || /* index(netmask) > node */ - rn_refines(netmask, tt->rn_mask) || - rn_lexobetter(netmask, tt->rn_mask)))) - break; - } - /* - * If the mask is not duplicated, we wouldn't - * find it among possible duplicate key entries - * anyway, so the above test doesn't hurt. - * - * We sort the masks for a duplicated key the same way as - * in a masklist -- most specific to least specific. - * This may require the unfortunate nuisance of relocating - * the head of the list. - * - * We also reverse, or doubly link the list through the - * parent pointer. - */ - if (tt == saved_tt) { - struct radix_node *xx = x; - /* link in at head of list */ - (tt = treenodes)->rn_dupedkey = t; - tt->rn_flags = t->rn_flags; - tt->rn_p = x = t->rn_p; - t->rn_p = tt; - if (x->rn_l == t) - x->rn_l = tt; - else - x->rn_r = tt; - saved_tt = tt; - x = xx; - } else { - (tt = treenodes)->rn_dupedkey = t->rn_dupedkey; - t->rn_dupedkey = tt; - tt->rn_p = t; - if (tt->rn_dupedkey) - tt->rn_dupedkey->rn_p = tt; - } -#ifdef RN_DEBUG - t=tt+1; - tt->rn_info = rn_nodenum++; - t->rn_info = rn_nodenum++; - tt->rn_twin = t; - tt->rn_ybro = rn_clist; - rn_clist = tt; -#endif - tt->rn_key = (caddr_t) v; - tt->rn_b = -1; - tt->rn_flags = RNF_ACTIVE; - } - /* - * Put mask in tree. - */ - if (netmask) { - tt->rn_mask = netmask; - tt->rn_b = x->rn_b; - tt->rn_flags |= x->rn_flags & RNF_NORMAL; - } - t = saved_tt->rn_p; - if (keyduplicated) - goto on2; - b_leaf = -1 - t->rn_b; - if (t->rn_r == saved_tt) - x = t->rn_l; - else - x = t->rn_r; - /* Promote general routes from below */ - if (x->rn_b < 0) { - for (mp = &t->rn_mklist; x; x = x->rn_dupedkey) - if (x->rn_mask && (x->rn_b >= b_leaf) && x->rn_mklist == 0) { - *mp = m = rn_new_radix_mask(x, 0); - if (m) - mp = &m->rm_mklist; - } - } else if (x->rn_mklist) { - /* - * Skip over masks whose index is > that of new node - */ - for (mp = &x->rn_mklist; (m = *mp) != NULL; mp = &m->rm_mklist) - if (m->rm_b >= b_leaf) - break; - t->rn_mklist = m; - *mp = 0; - } -on2: - /* Add new route to highest possible ancestor's list */ - if ((netmask == 0) || (b > t->rn_b )) - return tt; /* can't lift at all */ - b_leaf = tt->rn_b; - do { - x = t; - t = t->rn_p; - } while (b <= t->rn_b && x != top); - /* - * Search through routes associated with node to - * insert new route according to index. - * Need same criteria as when sorting dupedkeys to avoid - * double loop on deletion. - */ - for (mp = &x->rn_mklist; (m = *mp) != NULL; mp = &m->rm_mklist) { - if (m->rm_b < b_leaf) - continue; - if (m->rm_b > b_leaf) - break; - if (m->rm_flags & RNF_NORMAL) { - mmask = m->rm_leaf->rn_mask; - if (tt->rn_flags & RNF_NORMAL) { -#if 0 - log(LOG_ERR, "Non-unique normal route," - " mask not entered\n"); -#endif - return tt; - } - } else - mmask = m->rm_mask; - if (mmask == netmask) { - m->rm_refs++; - tt->rn_mklist = m; - return tt; - } - if (rn_refines(netmask, mmask) - || rn_lexobetter(netmask, mmask)) - break; - } - *mp = rn_new_radix_mask(tt, *mp); - return tt; -} - -struct radix_node * -rn_delete(v_arg, netmask_arg, head) - void *v_arg, *netmask_arg; - struct radix_node_head *head; -{ - struct radix_node *t, *p, *x, *tt; - struct radix_mask *m, *saved_m, **mp; - struct radix_node *dupedkey, *saved_tt, *top; - caddr_t v, netmask; - int b, head_off, vlen; - - v = v_arg; - netmask = netmask_arg; - x = head->rnh_treetop; - tt = rn_search(v, x); - head_off = x->rn_off; - vlen = *(u_char *)v; - saved_tt = tt; - top = x; - if (tt == 0 || - Bcmp(v + head_off, tt->rn_key + head_off, vlen - head_off)) - return (0); - /* - * Delete our route from mask lists. - */ - if (netmask) { - if ((x = rn_addmask(netmask, 1, head_off)) == 0) - return (0); - netmask = x->rn_key; - while (tt->rn_mask != netmask) - if ((tt = tt->rn_dupedkey) == 0) - return (0); - } - if (tt->rn_mask == 0 || (saved_m = m = tt->rn_mklist) == 0) - goto on1; - if (tt->rn_flags & RNF_NORMAL) { - if (m->rm_leaf != tt || m->rm_refs > 0) { -#if 0 - log(LOG_ERR, "rn_delete: inconsistent annotation\n"); -#endif - return 0; /* dangling ref could cause disaster */ - } - } else { - if (m->rm_mask != tt->rn_mask) { -#if 0 - log(LOG_ERR, "rn_delete: inconsistent annotation\n"); -#endif - goto on1; - } - if (--m->rm_refs >= 0) - goto on1; - } - b = -1 - tt->rn_b; - t = saved_tt->rn_p; - if (b > t->rn_b) - goto on1; /* Wasn't lifted at all */ - do { - x = t; - t = t->rn_p; - } while (b <= t->rn_b && x != top); - for (mp = &x->rn_mklist; (m = *mp) != NULL; mp = &m->rm_mklist) - if (m == saved_m) { - *mp = m->rm_mklist; - MKFree(m); - break; - } - if (m == 0) { -#if 0 - log(LOG_ERR, "rn_delete: couldn't find our annotation\n"); -#endif - if (tt->rn_flags & RNF_NORMAL) - return (0); /* Dangling ref to us */ - } -on1: - /* - * Eliminate us from tree - */ - if (tt->rn_flags & RNF_ROOT) - return (0); -#ifdef RN_DEBUG - /* Get us out of the creation list */ - for (t = rn_clist; t && t->rn_ybro != tt; t = t->rn_ybro) - ; - if (t) t->rn_ybro = tt->rn_ybro; -#endif - t = tt->rn_p; - dupedkey = saved_tt->rn_dupedkey; - if (dupedkey) { - /* - * Here, tt is the deletion target and - * saved_tt is the head of the dupedkey chain. - */ - if (tt == saved_tt) { - x = dupedkey; - x->rn_p = t; - if (t->rn_l == tt) - t->rn_l = x; - else - t->rn_r = x; - } else { - /* find node in front of tt on the chain */ - for (x = p = saved_tt; p && p->rn_dupedkey != tt;) - p = p->rn_dupedkey; - if (p) { - p->rn_dupedkey = tt->rn_dupedkey; - if (tt->rn_dupedkey) - tt->rn_dupedkey->rn_p = p; - } -#if 0 - else - log(LOG_ERR, "rn_delete: couldn't find us\n"); -#endif - } - t = tt + 1; - if (t->rn_flags & RNF_ACTIVE) { -#ifndef RN_DEBUG - *++x = *t; - p = t->rn_p; -#else - b = t->rn_info; - *++x = *t; - t->rn_info = b; - p = t->rn_p; -#endif - if (p->rn_l == t) - p->rn_l = x; - else - p->rn_r = x; - x->rn_l->rn_p = x; - x->rn_r->rn_p = x; - } - goto out; - } - if (t->rn_l == tt) - x = t->rn_r; - else - x = t->rn_l; - p = t->rn_p; - if (p->rn_r == t) - p->rn_r = x; - else - p->rn_l = x; - x->rn_p = p; - /* - * Demote routes attached to us. - */ - if (t->rn_mklist) { - if (x->rn_b >= 0) { - for (mp = &x->rn_mklist; (m = *mp) != NULL;) - mp = &m->rm_mklist; - *mp = t->rn_mklist; - } else { - /* If there are any key,mask pairs in a sibling - duped-key chain, some subset will appear sorted - in the same order attached to our mklist */ - for (m = t->rn_mklist; m && x; x = x->rn_dupedkey) - if (m == x->rn_mklist) { - struct radix_mask *mm = m->rm_mklist; - x->rn_mklist = 0; - if (--(m->rm_refs) < 0) - MKFree(m); - m = mm; - } -#if 0 - if (m) - log(LOG_ERR, "%s %p at %p\n", - "rn_delete: Orphaned Mask", m, x); -#endif - } - } - /* - * We may be holding an active internal node in the tree. - */ - x = tt + 1; - if (t != x) { -#ifndef RN_DEBUG - *t = *x; -#else - b = t->rn_info; - *t = *x; - t->rn_info = b; -#endif - t->rn_l->rn_p = t; - t->rn_r->rn_p = t; - p = x->rn_p; - if (p->rn_l == x) - p->rn_l = t; - else - p->rn_r = t; - } -out: - tt->rn_flags &= ~RNF_ACTIVE; - tt[1].rn_flags &= ~RNF_ACTIVE; - return (tt); -} - -int -rn_walktree(h, f, w) - struct radix_node_head *h; - int (*f) __P((struct radix_node *, void *)); - void *w; -{ - int error; - struct radix_node *base, *next; - struct radix_node *rn = h->rnh_treetop; - /* - * This gets complicated because we may delete the node - * while applying the function f to it, so we need to calculate - * the successor node in advance. - */ - /* First time through node, go left */ - while (rn->rn_b >= 0) - rn = rn->rn_l; - for (;;) { - base = rn; - /* If at right child go back up, otherwise, go right */ - while (rn->rn_p->rn_r == rn && (rn->rn_flags & RNF_ROOT) == 0) - rn = rn->rn_p; - /* Find the next *leaf* since next node might vanish, too */ - for (rn = rn->rn_p->rn_r; rn->rn_b >= 0;) - rn = rn->rn_l; - next = rn; - /* Process leaves */ - while ((rn = base) != NULL) { - base = rn->rn_dupedkey; - if (!(rn->rn_flags & RNF_ROOT) - && (error = (*f)(rn, w))) - return (error); - } - rn = next; - if (rn->rn_flags & RNF_ROOT) - return (0); - } - /* NOTREACHED */ -} - -int -rn_inithead(head, off) - void **head; - int off; -{ - struct radix_node_head *rnh; - - if (*head) - return (1); - R_Malloc(rnh, struct radix_node_head *, sizeof (*rnh)); - if (rnh == 0) - return (0); - *head = rnh; - return rn_inithead0(rnh, off); -} - -int -rn_inithead0(rnh, off) - struct radix_node_head *rnh; - int off; -{ - struct radix_node *t, *tt, *ttt; - - Bzero(rnh, sizeof (*rnh)); - t = rn_newpair(rn_zeros, off, rnh->rnh_nodes); - ttt = rnh->rnh_nodes + 2; - t->rn_r = ttt; - t->rn_p = t; - tt = t->rn_l; - tt->rn_flags = t->rn_flags = RNF_ROOT | RNF_ACTIVE; - tt->rn_b = -1 - off; - *ttt = *tt; - ttt->rn_key = rn_ones; - rnh->rnh_addaddr = rn_addroute; - rnh->rnh_deladdr = rn_delete; - rnh->rnh_matchaddr = rn_match; - rnh->rnh_lookup = rn_lookup; - rnh->rnh_walktree = rn_walktree; - rnh->rnh_treetop = t; - return (1); -} - -void -rn_init() -{ - char *cp, *cplim; - - if (max_keylen == 0) { -#if 0 - log(LOG_ERR, - "rn_init: radix functions require max_keylen be set\n"); -#endif - return; - } - if (rn_zeros == NULL) { - R_Malloc(rn_zeros, char *, 3 * max_keylen); - } - if (rn_zeros == NULL) - panic("rn_init"); - Bzero(rn_zeros, 3 * max_keylen); - rn_ones = cp = rn_zeros + max_keylen; - addmask_key = cplim = rn_ones + max_keylen; - while (cp < cplim) - *cp++ = -1; - if (rn_inithead((void *)&mask_rnhead, 0) == 0) - panic("rn_init 2"); -} - - -static int -rn_freenode(struct radix_node *n, void *p) -{ - struct radix_node_head *rnh = p; - struct radix_node *d; - - d = rnh->rnh_deladdr(n->rn_key, NULL, rnh); - if (d != NULL) { - FreeS(d, max_keylen + 2 * sizeof (*d)); - } - return 0; -} - - -void -rn_freehead(rnh) - struct radix_node_head *rnh; -{ - - (void)rn_walktree(rnh, rn_freenode, rnh); - - rnh->rnh_addaddr = NULL; - rnh->rnh_deladdr = NULL; - rnh->rnh_matchaddr = NULL; - rnh->rnh_lookup = NULL; - rnh->rnh_walktree = NULL; - - Free(rnh); -} - - -void -rn_fini() -{ - struct radix_mask *m; - - if (rn_zeros != NULL) { - FreeS(rn_zeros, 3 * max_keylen); - rn_zeros = NULL; - } - - if (mask_rnhead != NULL) { - rn_freehead(mask_rnhead); - mask_rnhead = NULL; - } - - while ((m = rn_mkfreelist) != NULL) { - rn_mkfreelist = m->rm_mklist; - KFREE(m); - } -} - - -#ifdef USE_MAIN - -typedef struct myst { - addrfamily_t dst; - addrfamily_t mask; - struct radix_node nodes[2]; -} myst_t; - -int -main(int argc, char *argv[]) -{ - struct radix_node_head *rnh; - struct radix_node *rn; - addrfamily_t af, mf; - myst_t st1, st2, *stp; - - memset(&st1, 0, sizeof(st1)); - memset(&st2, 0, sizeof(st2)); - memset(&af, 0, sizeof(af)); - - rn_init(); - - rnh = NULL; - rn_inithead(&rnh, offsetof(addrfamily_t, adf_addr) << 3); - - st1.dst.adf_len = sizeof(st1); - st1.mask.adf_len = sizeof(st1); - st1.dst.adf_addr.in4.s_addr = inet_addr("127.0.0.0"); - st1.mask.adf_addr.in4.s_addr = inet_addr("255.0.0.0"); - rn = rnh->rnh_addaddr(&st1.dst, &st1.mask, rnh, st1.nodes); - printf("add.1 %p\n", rn); - - st2.dst.adf_len = sizeof(st2); - st2.mask.adf_len = sizeof(st2); - st2.dst.adf_addr.in4.s_addr = inet_addr("127.0.1.0"); - st2.mask.adf_addr.in4.s_addr = inet_addr("255.255.255.0"); - rn = rnh->rnh_addaddr(&st2.dst, &st2.mask, rnh, st2.nodes); - printf("add.2 %p\n", rn); - - af.adf_len = sizeof(af); - af.adf_addr.in4.s_addr = inet_addr("127.0.1.0"); - rn = rnh->rnh_matchaddr(&af, rnh); - if (rn != NULL) { - printf("1.lookup = %p key %p mask %p\n", rn, rn->rn_key, rn->rn_mask); - stp = rn->rn_key; - printf("%s/", inet_ntoa(stp->dst.adf_addr.in4)); - stp = rn->rn_mask; - printf("%s\n", inet_ntoa(stp->dst.adf_addr.in4)); - } - - mf.adf_len = sizeof(mf); - mf.adf_addr.in4.s_addr = inet_addr("255.255.255.0"); - rn = rnh->rnh_lookup(&af, &mf, rnh); - if (rn != NULL) { - printf("2.lookup = %p key %p mask %p\n", rn, rn->rn_key, rn->rn_mask); - stp = rn->rn_key; - printf("%s/", inet_ntoa(stp->dst.adf_addr.in4)); - stp = rn->rn_mask; - printf("%s\n", inet_ntoa(stp->dst.adf_addr.in4)); - } - - af.adf_len = sizeof(af); - af.adf_addr.in4.s_addr = inet_addr("126.0.0.1"); - rn = rnh->rnh_matchaddr(&af, rnh); - if (rn != NULL) { - printf("3.lookup = %p key %p mask %p\n", rn, rn->rn_key, rn->rn_mask); - stp = rn->rn_key; - printf("%s/", inet_ntoa(stp->dst.adf_addr.in4)); - stp = rn->rn_mask; - printf("%s\n", inet_ntoa(stp->dst.adf_addr.in4)); - } - - return 0; -} - - -void -log(int level, char *format, ...) -{ - va_list ap; - - va_start(ap, format); - vfprintf(stderr, format, ap); - va_end(ap); -} -#endif - - -#ifndef _KERNEL -void -panic(char *str) -{ - fputs(str, stderr); - abort(); -} -#endif diff --git a/contrib/ipfilter/radix_ipf.c b/contrib/ipfilter/radix_ipf.c new file mode 100644 index 000000000000..f145c38a94d6 --- /dev/null +++ b/contrib/ipfilter/radix_ipf.c @@ -0,0 +1,1528 @@ +/* + * Copyright (C) 2012 by Darren Reed. + * + * See the IPFILTER.LICENCE file for details on licencing. + */ +#include +#include +#include +#include +#include +#include +#if !defined(_KERNEL) +# include +# include +# include +# include +#endif +#include "netinet/ip_compat.h" +#include "netinet/ip_fil.h" +#ifdef RDX_DEBUG +# include +# include +# include +#endif +#include "netinet/radix_ipf.h" + +#define ADF_OFF offsetof(addrfamily_t, adf_addr) +#define ADF_OFF_BITS (ADF_OFF << 3) + +static ipf_rdx_node_t *ipf_rx_insert __P((ipf_rdx_head_t *, + ipf_rdx_node_t nodes[2], int *)); +static void ipf_rx_attach_mask __P((ipf_rdx_node_t *, ipf_rdx_mask_t *)); +static int count_mask_bits __P((addrfamily_t *, u_32_t **)); +static void buildnodes __P((addrfamily_t *, addrfamily_t *, + ipf_rdx_node_t n[2])); +static ipf_rdx_node_t *ipf_rx_find_addr __P((ipf_rdx_node_t *, u_32_t *)); +static ipf_rdx_node_t *ipf_rx_lookup __P((ipf_rdx_head_t *, addrfamily_t *, + addrfamily_t *)); +static ipf_rdx_node_t *ipf_rx_match __P((ipf_rdx_head_t *, addrfamily_t *)); + +/* + * Foreword. + * --------- + * The code in this file has been written to target using the addrfamily_t + * data structure to house the address information and no other. Thus there + * are certain aspects of thise code (such as offsets to the address itself) + * that are hard coded here whilst they might be more variable elsewhere. + * Similarly, this code enforces no maximum key length as that's implied by + * all keys needing to be stored in addrfamily_t. + */ + +/* ------------------------------------------------------------------------ */ +/* Function: count_mask_bits */ +/* Returns: number of consecutive bits starting at "mask". */ +/* */ +/* Count the number of bits set in the address section of addrfamily_t and */ +/* return both that number and a pointer to the last word with a bit set if */ +/* lastp is not NULL. The bit count is performed using network byte order */ +/* as the guide for which bit is the most significant bit. */ +/* ------------------------------------------------------------------------ */ +static int +count_mask_bits(mask, lastp) + addrfamily_t *mask; + u_32_t **lastp; +{ + u_32_t *mp = (u_32_t *)&mask->adf_addr; + u_32_t m; + int count = 0; + int mlen; + + mlen = mask->adf_len - offsetof(addrfamily_t, adf_addr); + for (; mlen > 0; mlen -= 4, mp++) { + if ((m = ntohl(*mp)) == 0) + break; + if (lastp != NULL) + *lastp = mp; + for (; m & 0x80000000; m <<= 1) + count++; + } + + return count; +} + + +/* ------------------------------------------------------------------------ */ +/* Function: buildnodes */ +/* Returns: Nil */ +/* Parameters: addr(I) - network address for this radix node */ +/* mask(I) - netmask associated with the above address */ +/* nodes(O) - pair of ipf_rdx_node_t's to initialise with data */ +/* associated with addr and mask. */ +/* */ +/* Initialise the fields in a pair of radix tree nodes according to the */ +/* data supplied in the paramters "addr" and "mask". It is expected that */ +/* "mask" will contain a consecutive string of bits set. Masks with gaps in */ +/* the middle are not handled by this implementation. */ +/* ------------------------------------------------------------------------ */ +static void +buildnodes(addr, mask, nodes) + addrfamily_t *addr, *mask; + ipf_rdx_node_t nodes[2]; +{ + u_32_t maskbits; + u_32_t lastbits; + u_32_t lastmask; + u_32_t *last; + int masklen; + + last = NULL; + maskbits = count_mask_bits(mask, &last); + if (last == NULL) { + masklen = 0; + lastmask = 0; + } else { + masklen = last - (u_32_t *)mask; + lastmask = *last; + } + lastbits = maskbits & 0x1f; + + bzero(&nodes[0], sizeof(ipf_rdx_node_t) * 2); + nodes[0].maskbitcount = maskbits; + nodes[0].index = -1 - (ADF_OFF_BITS + maskbits); + nodes[0].addrkey = (u_32_t *)addr; + nodes[0].maskkey = (u_32_t *)mask; + nodes[0].addroff = nodes[0].addrkey + masklen; + nodes[0].maskoff = nodes[0].maskkey + masklen; + nodes[0].parent = &nodes[1]; + nodes[0].offset = masklen; + nodes[0].lastmask = lastmask; + nodes[1].offset = masklen; + nodes[1].left = &nodes[0]; + nodes[1].maskbitcount = maskbits; +#ifdef RDX_DEBUG + (void) strcpy(nodes[0].name, "_BUILD.0"); + (void) strcpy(nodes[1].name, "_BUILD.1"); +#endif +} + + +/* ------------------------------------------------------------------------ */ +/* Function: ipf_rx_find_addr */ +/* Returns: ipf_rdx_node_t * - pointer to a node in the radix tree. */ +/* Parameters: tree(I) - pointer to first right node in tree to search */ +/* addr(I) - pointer to address to match */ +/* */ +/* Walk the radix tree given by "tree", looking for a leaf node that is a */ +/* match for the address given by "addr". */ +/* ------------------------------------------------------------------------ */ +static ipf_rdx_node_t * +ipf_rx_find_addr(tree, addr) + ipf_rdx_node_t *tree; + u_32_t *addr; +{ + ipf_rdx_node_t *cur; + + for (cur = tree; cur->index >= 0;) { + if (cur->bitmask & addr[cur->offset]) { + cur = cur->right; + } else { + cur = cur->left; + } + } + + return (cur); +} + + +/* ------------------------------------------------------------------------ */ +/* Function: ipf_rx_match */ +/* Returns: ipf_rdx_node_t * - NULL on error, else pointer to the node */ +/* added to the tree. */ +/* Paramters: head(I) - pointer to tree head to search */ +/* addr(I) - pointer to address to find */ +/* */ +/* Search the radix tree for the best match to the address pointed to by */ +/* "addr" and return a pointer to that node. This search will not match the */ +/* address information stored in either of the root leaves as neither of */ +/* them are considered to be part of the tree of data being stored. */ +/* ------------------------------------------------------------------------ */ +static ipf_rdx_node_t * +ipf_rx_match(head, addr) + ipf_rdx_head_t *head; + addrfamily_t *addr; +{ + ipf_rdx_mask_t *masknode; + ipf_rdx_node_t *prev; + ipf_rdx_node_t *node; + ipf_rdx_node_t *cur; + u_32_t *data; + u_32_t *mask; + u_32_t *key; + u_32_t *end; + int len; + int i; + + len = addr->adf_len; + end = (u_32_t *)((u_char *)addr + len); + node = ipf_rx_find_addr(head->root, (u_32_t *)addr); + + /* + * Search the dupkey list for a potential match. + */ + for (cur = node; (cur != NULL) && (cur->root == 0); cur = cur->dupkey) { + i = cur[0].addroff - cur[0].addrkey; + data = cur[0].addrkey + i; + mask = cur[0].maskkey + i; + key = (u_32_t *)addr + i; + for (; key < end; data++, key++, mask++) + if ((*key & *mask) != *data) + break; + if ((end == key) && (cur->root == 0)) + return (cur); /* Equal keys */ + } + prev = node->parent; + key = (u_32_t *)addr; + + for (node = prev; node->root == 0; node = node->parent) { + /* + * We know that the node hasn't matched so therefore only + * the entries in the mask list are searched, not the top + * node nor the dupkey list. + */ + masknode = node->masks; + for (; masknode != NULL; masknode = masknode->next) { + if (masknode->maskbitcount > node->maskbitcount) + continue; + cur = masknode->node; + for (i = ADF_OFF >> 2; i <= node->offset; i++) { + if ((key[i] & masknode->mask[i]) == + cur->addrkey[i]) + return (cur); + } + } + } + + return NULL; +} + + +/* ------------------------------------------------------------------------ */ +/* Function: ipf_rx_lookup */ +/* Returns: ipf_rdx_node_t * - NULL on error, else pointer to the node */ +/* added to the tree. */ +/* Paramters: head(I) - pointer to tree head to search */ +/* addr(I) - address part of the key to match */ +/* mask(I) - netmask part of the key to match */ +/* */ +/* ipf_rx_lookup searches for an exact match on (addr,mask). The intention */ +/* is to see if a given key is in the tree, not to see if a route exists. */ +/* ------------------------------------------------------------------------ */ +ipf_rdx_node_t * +ipf_rx_lookup(head, addr, mask) + ipf_rdx_head_t *head; + addrfamily_t *addr, *mask; +{ + ipf_rdx_node_t *found; + ipf_rdx_node_t *node; + u_32_t *akey; + int count; + + found = ipf_rx_find_addr(head->root, (u_32_t *)addr); + if (found->root == 1) + return NULL; + + /* + * It is possible to find a matching address in the tree but for the + * netmask to not match. If the netmask does not match and there is + * no list of alternatives present at dupkey, return a failure. + */ + count = count_mask_bits(mask, NULL); + if (count != found->maskbitcount && found->dupkey == NULL) + return (NULL); + + akey = (u_32_t *)addr; + if ((found->addrkey[found->offset] & found->maskkey[found->offset]) != + akey[found->offset]) + return NULL; + + if (found->dupkey != NULL) { + node = found; + while (node != NULL && node->maskbitcount != count) + node = node->dupkey; + if (node == NULL) + return (NULL); + found = node; + } + return found; +} + + +/* ------------------------------------------------------------------------ */ +/* Function: ipf_rx_attach_mask */ +/* Returns: Nil */ +/* Parameters: node(I) - pointer to a radix tree node */ +/* mask(I) - pointer to mask structure to add */ +/* */ +/* Add the netmask to the given node in an ordering where the most specific */ +/* netmask is at the top of the list. */ +/* ------------------------------------------------------------------------ */ +static void +ipf_rx_attach_mask(node, mask) + ipf_rdx_node_t *node; + ipf_rdx_mask_t *mask; +{ + ipf_rdx_mask_t **pm; + ipf_rdx_mask_t *m; + + for (pm = &node->masks; (m = *pm) != NULL; pm = &m->next) + if (m->maskbitcount < mask->maskbitcount) + break; + mask->next = *pm; + *pm = mask; +} + + +/* ------------------------------------------------------------------------ */ +/* Function: ipf_rx_insert */ +/* Returns: ipf_rdx_node_t * - NULL on error, else pointer to the node */ +/* added to the tree. */ +/* Paramters: head(I) - pointer to tree head to add nodes to */ +/* nodes(I) - pointer to radix nodes to be added */ +/* dup(O) - set to 1 if node is a duplicate, else 0. */ +/* */ +/* Add the new radix tree entry that owns nodes[] to the tree given by head.*/ +/* If there is already a matching key in the table, "dup" will be set to 1 */ +/* and the existing node pointer returned if there is a complete key match. */ +/* A complete key match is a matching of all key data that is presented by */ +/* by the netmask. */ +/* ------------------------------------------------------------------------ */ +static ipf_rdx_node_t * +ipf_rx_insert(head, nodes, dup) + ipf_rdx_head_t *head; + ipf_rdx_node_t nodes[2]; + int *dup; +{ + ipf_rdx_mask_t **pmask; + ipf_rdx_node_t *node; + ipf_rdx_node_t *prev; + ipf_rdx_mask_t *mask; + ipf_rdx_node_t *cur; + u_32_t nodemask; + u_32_t *addr; + u_32_t *data; + int nodebits; + u_32_t *key; + u_32_t *end; + u_32_t bits; + int nodekey; + int nodeoff; + int nlen; + int len; + + addr = nodes[0].addrkey; + + node = ipf_rx_find_addr(head->root, addr); + len = ((addrfamily_t *)addr)->adf_len; + key = (u_32_t *)&((addrfamily_t *)addr)->adf_addr; + data= (u_32_t *)&((addrfamily_t *)node->addrkey)->adf_addr; + end = (u_32_t *)((u_char *)addr + len); + for (nlen = 0; key < end; data++, key++, nlen += 32) + if (*key != *data) + break; + if (end == data) { + *dup = 1; + return (node); /* Equal keys */ + } + *dup = 0; + + bits = (ntohl(*data) ^ ntohl(*key)); + for (; bits != 0; nlen++) { + if ((bits & 0x80000000) != 0) + break; + bits <<= 1; + } + nlen += ADF_OFF_BITS; + nodes[1].index = nlen; + nodes[1].bitmask = htonl(0x80000000 >> (nlen & 0x1f)); + nodes[0].offset = nlen / 32; + nodes[1].offset = nlen / 32; + + /* + * Walk through the tree and look for the correct place to attach + * this node. ipf_rx_fin_addr is not used here because the place + * to attach this node may be an internal node (same key, different + * netmask.) Additionally, the depth of the search is forcibly limited + * here to not exceed the netmask, so that a short netmask will be + * added higher up the tree even if there are lower branches. + */ + cur = head->root; + key = nodes[0].addrkey; + do { + prev = cur; + if (key[cur->offset] & cur->bitmask) { + cur = cur->right; + } else { + cur = cur->left; + } + } while (nlen > (unsigned)cur->index); + + if ((key[prev->offset] & prev->bitmask) == 0) { + prev->left = &nodes[1]; + } else { + prev->right = &nodes[1]; + } + cur->parent = &nodes[1]; + nodes[1].parent = prev; + if ((key[nodes[1].offset] & nodes[1].bitmask) == 0) { + nodes[1].right = cur; + } else { + nodes[1].right = &nodes[0]; + nodes[1].left = cur; + } + + nodeoff = nodes[0].offset; + nodekey = nodes[0].addrkey[nodeoff]; + nodemask = nodes[0].lastmask; + nodebits = nodes[0].maskbitcount; + prev = NULL; + /* + * Find the node up the tree with the largest pattern that still + * matches the node being inserted to see if this mask can be + * moved there. + */ + for (cur = nodes[1].parent; cur->root == 0; cur = cur->parent) { + if (cur->maskbitcount <= nodebits) + break; + if (((cur - 1)->addrkey[nodeoff] & nodemask) != nodekey) + break; + prev = cur; + } + + KMALLOC(mask, ipf_rdx_mask_t *); + if (mask == NULL) + return NULL; + bzero(mask, sizeof(*mask)); + mask->next = NULL; + mask->node = &nodes[0]; + mask->maskbitcount = nodebits; + mask->mask = nodes[0].maskkey; + nodes[0].mymask = mask; + + if (prev != NULL) { + ipf_rdx_mask_t *m; + + for (pmask = &prev->masks; (m = *pmask) != NULL; + pmask = &m->next) { + if (m->maskbitcount < nodebits) + break; + } + } else { + /* + * No higher up nodes qualify, so attach mask locally. + */ + pmask = &nodes[0].masks; + } + mask->next = *pmask; + *pmask = mask; + + /* + * Search the mask list on each child to see if there are any masks + * there that can be moved up to this newly inserted node. + */ + cur = nodes[1].right; + if (cur->root == 0) { + for (pmask = &cur->masks; (mask = *pmask) != NULL; ) { + if (mask->maskbitcount < nodebits) { + *pmask = mask->next; + ipf_rx_attach_mask(&nodes[0], mask); + } else { + pmask = &mask->next; + } + } + } + cur = nodes[1].left; + if (cur->root == 0 && cur != &nodes[0]) { + for (pmask = &cur->masks; (mask = *pmask) != NULL; ) { + if (mask->maskbitcount < nodebits) { + *pmask = mask->next; + ipf_rx_attach_mask(&nodes[0], mask); + } else { + pmask = &mask->next; + } + } + } + return (&nodes[0]); +} + +/* ------------------------------------------------------------------------ */ +/* Function: ipf_rx_addroute */ +/* Returns: ipf_rdx_node_t * - NULL on error, else pointer to the node */ +/* added to the tree. */ +/* Paramters: head(I) - pointer to tree head to search */ +/* addr(I) - address portion of "route" to add */ +/* mask(I) - netmask portion of "route" to add */ +/* nodes(I) - radix tree data nodes inside allocate structure */ +/* */ +/* Attempt to add a node to the radix tree. The key for the node is the */ +/* (addr,mask). No memory allocation for the radix nodes themselves is */ +/* performed here, the data structure that this radix node is being used to */ +/* find is expected to house the node data itself however the call to */ +/* ipf_rx_insert() will attempt to allocate memory in order for netmask to */ +/* be promoted further up the tree. */ +/* In this case, the ip_pool_node_t structure from ip_pool.h contains both */ +/* the key material (addr,mask) and the radix tree nodes[]. */ +/* */ +/* The mechanics of inserting the node into the tree is handled by the */ +/* function ipf_rx_insert() above. Here, the code deals with the case */ +/* where the data to be inserted is a duplicate. */ +/* ------------------------------------------------------------------------ */ +ipf_rdx_node_t * +ipf_rx_addroute(head, addr, mask, nodes) + ipf_rdx_head_t *head; + addrfamily_t *addr, *mask; + ipf_rdx_node_t *nodes; +{ + ipf_rdx_node_t *node; + ipf_rdx_node_t *prev; + ipf_rdx_node_t *x; + int dup; + + buildnodes(addr, mask, nodes); + x = ipf_rx_insert(head, nodes, &dup); + if (x == NULL) + return NULL; + + if (dup == 1) { + node = &nodes[0]; + prev = NULL; + /* + * The duplicate list is kept sorted with the longest + * mask at the top, meaning that the most specific entry + * in the listis found first. This list thus allows for + * duplicates such as 128.128.0.0/32 and 128.128.0.0/16. + */ + while ((x != NULL) && (x->maskbitcount > node->maskbitcount)) { + prev = x; + x = x->dupkey; + } + + /* + * Is it a complete duplicate? If so, return NULL and + * fail the insert. Otherwise, insert it into the list + * of netmasks active for this key. + */ + if ((x != NULL) && (x->maskbitcount == node->maskbitcount)) + return (NULL); + + if (prev != NULL) { + nodes[0].dupkey = x; + prev->dupkey = &nodes[0]; + nodes[0].parent = prev; + if (x != NULL) + x->parent = &nodes[0]; + } else { + nodes[0].dupkey = x->dupkey; + prev = x->parent; + nodes[0].parent = prev; + x->parent = &nodes[0]; + if (prev->left == x) + prev->left = &nodes[0]; + else + prev->right = &nodes[0]; + } + } + + return &nodes[0]; +} + + +/* ------------------------------------------------------------------------ */ +/* Function: ipf_rx_delete */ +/* Returns: ipf_rdx_node_t * - NULL on error, else node removed from */ +/* the tree. */ +/* Paramters: head(I) - pointer to tree head to search */ +/* addr(I) - pointer to the address part of the key */ +/* mask(I) - pointer to the netmask part of the key */ +/* */ +/* Search for an entry in the radix tree that is an exact match for (addr, */ +/* mask) and remove it if it exists. In the case where (addr,mask) is a not */ +/* a unique key, the tree structure itself is not changed - only the list */ +/* of duplicate keys. */ +/* ------------------------------------------------------------------------ */ +ipf_rdx_node_t * +ipf_rx_delete(head, addr, mask) + ipf_rdx_head_t *head; + addrfamily_t *addr, *mask; +{ + ipf_rdx_mask_t **pmask; + ipf_rdx_node_t *parent; + ipf_rdx_node_t *found; + ipf_rdx_node_t *prev; + ipf_rdx_node_t *node; + ipf_rdx_node_t *cur; + ipf_rdx_mask_t *m; + int count; + + found = ipf_rx_find_addr(head->root, (u_32_t *)addr); + if (found == NULL) + return NULL; + if (found->root == 1) + return NULL; + count = count_mask_bits(mask, NULL); + parent = found->parent; + if (found->dupkey != NULL) { + node = found; + while (node != NULL && node->maskbitcount != count) + node = node->dupkey; + if (node == NULL) + return (NULL); + if (node != found) { + /* + * Remove from the dupkey list. Here, "parent" is + * the previous node on the list (rather than tree) + * and "dupkey" is the next node on the list. + */ + parent = node->parent; + parent->dupkey = node->dupkey; + node->dupkey->parent = parent; + } else { + /* + * + * When removing the top node of the dupkey list, + * the pointers at the top of the list that point + * to other tree nodes need to be preserved and + * any children must have their parent updated. + */ + node = node->dupkey; + node->parent = found->parent; + node->right = found->right; + node->left = found->left; + found->right->parent = node; + found->left->parent = node; + if (parent->left == found) + parent->left = node; + else + parent->right= node; + } + } else { + if (count != found->maskbitcount) + return (NULL); + /* + * Remove the node from the tree and reconnect the subtree + * below. + */ + /* + * If there is a tree to the left, look for something to + * attach in place of "found". + */ + prev = found + 1; + cur = parent->parent; + if (parent != found + 1) { + if ((found + 1)->parent->right == found + 1) + (found + 1)->parent->right = parent; + else + (found + 1)->parent->left = parent; + if (cur->right == parent) { + if (parent->left == found) { + cur->right = parent->right; + } else if (parent->left != parent - 1) { + cur->right = parent->left; + } else { + cur->right = parent - 1; + } + cur->right->parent = cur; + } else { + if (parent->right == found) { + cur->left = parent->left; + } else if (parent->right != parent - 1) { + cur->left = parent->right; + } else { + cur->left = parent - 1; + } + cur->left->parent = cur; + } + parent->left = (found + 1)->left; + if ((found + 1)->right != parent) + parent->right = (found + 1)->right; + parent->left->parent = parent; + parent->right->parent = parent; + parent->parent = (found + 1)->parent; + + parent->bitmask = prev->bitmask; + parent->offset = prev->offset; + parent->index = prev->index; + } else { + /* + * We found an edge node. + */ + cur = parent->parent; + if (cur->left == parent) { + if (parent->left == found) { + cur->left = parent->right; + parent->right->parent = cur; + } else { + cur->left = parent->left; + parent->left->parent = cur; + } + } else { + if (parent->right != found) { + cur->right = parent->right; + parent->right->parent = cur; + } else { + cur->right = parent->left; + prev->left->parent = cur; + } + } + } + } + + /* + * Remove mask associated with this node. + */ + for (cur = parent; cur->root == 0; cur = cur->parent) { + ipf_rdx_mask_t **pm; + + if (cur->maskbitcount <= found->maskbitcount) + break; + if (((cur - 1)->addrkey[found->offset] & found->bitmask) != + found->addrkey[found->offset]) + break; + for (pm = &cur->masks; (m = *pm) != NULL; ) + if (m->node == cur) { + *pm = m->next; + break; + } else { + pm = &m->next; + } + } + KFREE(found->mymask); + + /* + * Masks that have been brought up to this node from below need to + * be sent back down. + */ + for (pmask = &parent->masks; (m = *pmask) != NULL; ) { + *pmask = m->next; + cur = m->node; + if (cur == found) + continue; + if (found->addrkey[cur->offset] & cur->lastmask) { + ipf_rx_attach_mask(parent->right, m); + } else if (parent->left != found) { + ipf_rx_attach_mask(parent->left, m); + } + } + + return (found); +} + + +/* ------------------------------------------------------------------------ */ +/* Function: ipf_rx_walktree */ +/* Returns: Nil */ +/* Paramters: head(I) - pointer to tree head to search */ +/* walker(I) - function to call for each node in the tree */ +/* arg(I) - parameter to pass to walker, in addition to the */ +/* node pointer */ +/* */ +/* A standard tree walking function except that it is iterative, rather */ +/* than recursive and tracks the next node in case the "walker" function */ +/* should happen to delete and free the current node. It thus goes without */ +/* saying that the "walker" function is not permitted to cause any change */ +/* in the validity of the data found at either the left or right child. */ +/* ------------------------------------------------------------------------ */ +void +ipf_rx_walktree(head, walker, arg) + ipf_rdx_head_t *head; + radix_walk_func_t walker; + void *arg; +{ + ipf_rdx_node_t *next; + ipf_rdx_node_t *node = head->root; + ipf_rdx_node_t *base; + + while (node->index >= 0) + node = node->left; + + for (;;) { + base = node; + while ((node->parent->right == node) && (node->root == 0)) + node = node->parent; + + for (node = node->parent->right; node->index >= 0; ) + node = node->left; + next = node; + + for (node = base; node != NULL; node = base) { + base = node->dupkey; + if (node->root == 0) + walker(node, arg); + } + node = next; + if (node->root) + return; + } +} + + +/* ------------------------------------------------------------------------ */ +/* Function: ipf_rx_inithead */ +/* Returns: int - 0 = success, else failure */ +/* Paramters: softr(I) - pointer to radix context */ +/* headp(O) - location for where to store allocated tree head */ +/* */ +/* This function allocates and initialises a radix tree head structure. */ +/* As a traditional radix tree, node 0 is used as the "0" sentinel and node */ +/* "2" is used as the all ones sentinel, leaving node "1" as the root from */ +/* which the tree is hung with node "0" on its left and node "2" to the */ +/* right. The context, "softr", is used here to provide a common source of */ +/* the zeroes and ones data rather than have one per head. */ +/* ------------------------------------------------------------------------ */ +int +ipf_rx_inithead(softr, headp) + radix_softc_t *softr; + ipf_rdx_head_t **headp; +{ + ipf_rdx_head_t *ptr; + ipf_rdx_node_t *node; + + KMALLOC(ptr, ipf_rdx_head_t *); + *headp = ptr; + if (ptr == NULL) + return -1; + bzero(ptr, sizeof(*ptr)); + node = ptr->nodes; + ptr->root = node + 1; + node[0].index = ADF_OFF_BITS; + node[0].index = -1 - node[0].index; + node[1].index = ADF_OFF_BITS; + node[2].index = node[0].index; + node[0].parent = node + 1; + node[1].parent = node + 1; + node[2].parent = node + 1; + node[1].bitmask = htonl(0x80000000); + node[0].root = 1; + node[1].root = 1; + node[2].root = 1; + node[0].offset = ADF_OFF_BITS >> 5; + node[1].offset = ADF_OFF_BITS >> 5; + node[2].offset = ADF_OFF_BITS >> 5; + node[1].left = &node[0]; + node[1].right = &node[2]; + node[0].addrkey = (u_32_t *)softr->zeros; + node[2].addrkey = (u_32_t *)softr->ones; +#ifdef RDX_DEBUG + (void) strcpy(node[0].name, "0_ROOT"); + (void) strcpy(node[1].name, "1_ROOT"); + (void) strcpy(node[2].name, "2_ROOT"); +#endif + + ptr->addaddr = ipf_rx_addroute; + ptr->deladdr = ipf_rx_delete; + ptr->lookup = ipf_rx_lookup; + ptr->matchaddr = ipf_rx_match; + ptr->walktree = ipf_rx_walktree; + return 0; +} + + +/* ------------------------------------------------------------------------ */ +/* Function: ipf_rx_freehead */ +/* Returns: Nil */ +/* Paramters: head(I) - pointer to tree head to free */ +/* */ +/* This function simply free's up the radix tree head. Prior to calling */ +/* this function, it is expected that the tree will have been emptied. */ +/* ------------------------------------------------------------------------ */ +void +ipf_rx_freehead(head) + ipf_rdx_head_t *head; +{ + KFREE(head); +} + + +/* ------------------------------------------------------------------------ */ +/* Function: ipf_rx_create */ +/* Parameters: Nil */ +/* */ +/* ------------------------------------------------------------------------ */ +void * +ipf_rx_create() +{ + radix_softc_t *softr; + + KMALLOC(softr, radix_softc_t *); + if (softr == NULL) + return NULL; + bzero((char *)softr, sizeof(*softr)); + + KMALLOCS(softr->zeros, u_char *, 3 * sizeof(addrfamily_t)); + if (softr->zeros == NULL) { + KFREE(softr); + return (NULL); + } + softr->ones = softr->zeros + sizeof(addrfamily_t); + + return softr; +} + + +/* ------------------------------------------------------------------------ */ +/* Function: ipf_rx_init */ +/* Returns: int - 0 = success (always) */ +/* */ +/* ------------------------------------------------------------------------ */ +int +ipf_rx_init(ctx) + void *ctx; +{ + radix_softc_t *softr = ctx; + + memset(softr->zeros, 0, 3 * sizeof(addrfamily_t)); + memset(softr->ones, 0xff, sizeof(addrfamily_t)); + + return (0); +} + + +/* ------------------------------------------------------------------------ */ +/* Function: ipf_rx_destroy */ +/* Returns: Nil */ +/* */ +/* ------------------------------------------------------------------------ */ +void +ipf_rx_destroy(ctx) + void *ctx; +{ + radix_softc_t *softr = ctx; + + if (softr->zeros != NULL) + KFREES(softr->zeros, 3 * sizeof(addrfamily_t)); + KFREE(softr); +} + +/* ====================================================================== */ + +#ifdef RDX_DEBUG +/* + * To compile this file as a standalone test unit, use -DRDX_DEBUG=1 + */ +#define NAME(x) ((x)->index < 0 ? (x)->name : (x)->name) +#define GNAME(y) ((y) == NULL ? "NULL" : NAME(y)) + +typedef struct myst { + struct ipf_rdx_node nodes[2]; + addrfamily_t dst; + addrfamily_t mask; + struct myst *next; + int printed; +} myst_t; + +typedef struct tabe_s { + char *host; + char *mask; + char *what; +} tabe_t; + +tabe_t builtin[] = { +#if 1 + { "192:168:100::0", "48", "d" }, + { "192:168:100::2", "128", "d" }, +#else + { "127.192.0.0", "255.255.255.0", "d" }, + { "127.128.0.0", "255.255.255.0", "d" }, + { "127.96.0.0", "255.255.255.0", "d" }, + { "127.80.0.0", "255.255.255.0", "d" }, + { "127.72.0.0", "255.255.255.0", "d" }, + { "127.64.0.0", "255.255.255.0", "d" }, + { "127.56.0.0", "255.255.255.0", "d" }, + { "127.48.0.0", "255.255.255.0", "d" }, + { "127.40.0.0", "255.255.255.0", "d" }, + { "127.32.0.0", "255.255.255.0", "d" }, + { "127.24.0.0", "255.255.255.0", "d" }, + { "127.16.0.0", "255.255.255.0", "d" }, + { "127.8.0.0", "255.255.255.0", "d" }, + { "124.0.0.0", "255.0.0.0", "d" }, + { "125.0.0.0", "255.0.0.0", "d" }, + { "126.0.0.0", "255.0.0.0", "d" }, + { "127.0.0.0", "255.0.0.0", "d" }, + { "10.0.0.0", "255.0.0.0", "d" }, + { "128.250.0.0", "255.255.0.0", "d" }, + { "192.168.0.0", "255.255.0.0", "d" }, + { "192.168.1.0", "255.255.255.0", "d" }, +#endif + { NULL, NULL, NULL } +}; + +char *mtable[][1] = { +#if 1 + { "192:168:100::2" }, + { "192:168:101::2" }, +#else + { "9.0.0.0" }, + { "9.0.0.1" }, + { "11.0.0.0" }, + { "11.0.0.1" }, + { "127.0.0.1" }, + { "127.0.1.0" }, + { "255.255.255.0" }, + { "126.0.0.1" }, + { "128.251.0.0" }, + { "128.251.0.1" }, + { "128.251.255.255" }, + { "129.250.0.0" }, + { "129.250.0.1" }, + { "192.168.255.255" }, +#endif + { NULL } +}; + + +int forder[22] = { + 14, 13, 12, 5, 10, 3, 19, 7, 4, 20, 8, + 2, 17, 9, 16, 11, 15, 1, 6, 18, 0, 21 +}; + +static int nodecount = 0; +myst_t *myst_top = NULL; +tabe_t *ttable = NULL; + +void add_addr(ipf_rdx_head_t *, int , int); +void checktree(ipf_rdx_head_t *); +void delete_addr(ipf_rdx_head_t *rnh, int item); +void dumptree(ipf_rdx_head_t *rnh); +void nodeprinter(ipf_rdx_node_t *, void *); +void printroots(ipf_rdx_head_t *); +void random_add(ipf_rdx_head_t *); +void random_delete(ipf_rdx_head_t *); +void test_addr(ipf_rdx_head_t *rnh, int pref, addrfamily_t *, int); + + +static void +ipf_rx_freenode(node, arg) + ipf_rdx_node_t *node; + void *arg; +{ + ipf_rdx_head_t *head = arg; + ipf_rdx_node_t *rv; + myst_t *stp; + + stp = (myst_t *)node; + rv = ipf_rx_delete(head, &stp->dst, &stp->mask); + if (rv != NULL) { + free(rv); + } +} + + +const char * +addrname(ap) + addrfamily_t *ap; +{ + static char name[80]; + const char *txt; + + bzero((char *)name, sizeof(name)); + txt = inet_ntop(ap->adf_family, &ap->adf_addr, name, + sizeof(name)); + return txt; +} + + +void +fill6bits(bits, msk) + int bits; + u_int *msk; +{ + if (bits == 0) { + msk[0] = 0; + msk[1] = 0; + msk[2] = 0; + msk[3] = 0; + return; + } + + msk[0] = 0xffffffff; + msk[1] = 0xffffffff; + msk[2] = 0xffffffff; + msk[3] = 0xffffffff; + + if (bits == 128) + return; + if (bits > 96) { + msk[3] = htonl(msk[3] << (128 - bits)); + } else if (bits > 64) { + msk[3] = 0; + msk[2] = htonl(msk[2] << (96 - bits)); + } else if (bits > 32) { + msk[3] = 0; + msk[2] = 0; + msk[1] = htonl(msk[1] << (64 - bits)); + } else { + msk[3] = 0; + msk[2] = 0; + msk[1] = 0; + msk[0] = htonl(msk[0] << (32 - bits)); + } +} + + +void +setaddr(afp, str) + addrfamily_t *afp; + char *str; +{ + + bzero((char *)afp, sizeof(*afp)); + + if (strchr(str, ':') == NULL) { + afp->adf_family = AF_INET; + afp->adf_len = offsetof(addrfamily_t, adf_addr) + 4; + } else { + afp->adf_family = AF_INET6; + afp->adf_len = offsetof(addrfamily_t, adf_addr) + 16; + } + inet_pton(afp->adf_family, str, &afp->adf_addr); +} + + +void +setmask(afp, str) + addrfamily_t *afp; + char *str; +{ + if (strchr(str, '.') != NULL) { + afp->adf_addr.in4.s_addr = inet_addr(str); + afp->adf_len = offsetof(addrfamily_t, adf_addr) + 4; + } else if (afp->adf_family == AF_INET) { + afp->adf_addr.i6[0] = htonl(0xffffffff << (32 - atoi(str))); + afp->adf_len = offsetof(addrfamily_t, adf_addr) + 4; + } else if (afp->adf_family == AF_INET6) { + fill6bits(atoi(str), afp->adf_addr.i6); + afp->adf_len = offsetof(addrfamily_t, adf_addr) + 16; + } +} + + +void +nodeprinter(node, arg) + ipf_rdx_node_t *node; + void *arg; +{ + myst_t *stp = (myst_t *)node; + + printf("Node %-9.9s L %-9.9s R %-9.9s P %9.9s/%-9.9s %s/%d\n", + node[0].name, + GNAME(node[1].left), GNAME(node[1].right), + GNAME(node[0].parent), GNAME(node[1].parent), + addrname(&stp->dst), node[0].maskbitcount); + if (stp->printed == -1) + printf("!!! %d\n", stp->printed); + else + stp->printed = 1; +} + + +void +printnode(stp) + myst_t *stp; +{ + ipf_rdx_node_t *node = &stp->nodes[0]; + + if (stp->nodes[0].index > 0) + stp = (myst_t *)&stp->nodes[-1]; + + printf("Node %-9.9s ", node[0].name); + printf("L %-9.9s ", GNAME(node[1].left)); + printf("R %-9.9s ", GNAME(node[1].right)); + printf("P %9.9s", GNAME(node[0].parent)); + printf("/%-9.9s ", GNAME(node[1].parent)); + printf("%s P%d\n", addrname(&stp->dst), stp->printed); +} + + +void +buildtab(void) +{ + char line[80], *s; + tabe_t *tab; + int lines; + FILE *fp; + + lines = 0; + fp = fopen("hosts", "r"); + + while (fgets(line, sizeof(line), fp) != NULL) { + s = strchr(line, '\n'); + if (s != NULL) + *s = '\0'; + lines++; + if (lines == 1) + tab = malloc(sizeof(*tab) * 2); + else + tab = realloc(tab, (lines + 1) * sizeof(*tab)); + tab[lines - 1].host = strdup(line); + s = strchr(tab[lines - 1].host, '/'); + *s++ = '\0'; + tab[lines - 1].mask = s; + tab[lines - 1].what = "d"; + } + fclose(fp); + + tab[lines].host = NULL; + tab[lines].mask = NULL; + tab[lines].what = NULL; + ttable = tab; +} + + +void +printroots(rnh) + ipf_rdx_head_t *rnh; +{ + printf("Root.0.%s b %3d p %-9.9s l %-9.9s r %-9.9s\n", + GNAME(&rnh->nodes[0]), + rnh->nodes[0].index, GNAME(rnh->nodes[0].parent), + GNAME(rnh->nodes[0].left), GNAME(rnh->nodes[0].right)); + printf("Root.1.%s b %3d p %-9.9s l %-9.9s r %-9.9s\n", + GNAME(&rnh->nodes[1]), + rnh->nodes[1].index, GNAME(rnh->nodes[1].parent), + GNAME(rnh->nodes[1].left), GNAME(rnh->nodes[1].right)); + printf("Root.2.%s b %3d p %-9.9s l %-9.9s r %-9.9s\n", + GNAME(&rnh->nodes[2]), + rnh->nodes[2].index, GNAME(rnh->nodes[2].parent), + GNAME(rnh->nodes[2].left), GNAME(rnh->nodes[2].right)); +} + + +int +main(int argc, char *argv[]) +{ + addrfamily_t af; + ipf_rdx_head_t *rnh; + radix_softc_t *ctx; + int j; + int i; + + rnh = NULL; + + buildtab(); + ctx = ipf_rx_create(); + ipf_rx_init(ctx); + ipf_rx_inithead(ctx, &rnh); + + printf("=== ADD-0 ===\n"); + for (i = 0; ttable[i].host != NULL; i++) { + add_addr(rnh, i, i); + checktree(rnh); + } + printroots(rnh); + ipf_rx_walktree(rnh, nodeprinter, NULL); + printf("=== DELETE-0 ===\n"); + for (i = 0; ttable[i].host != NULL; i++) { + delete_addr(rnh, i); + printroots(rnh); + ipf_rx_walktree(rnh, nodeprinter, NULL); + } + printf("=== ADD-1 ===\n"); + for (i = 0; ttable[i].host != NULL; i++) { + setaddr(&af, ttable[i].host); + add_addr(rnh, i, i); /*forder[i]); */ + checktree(rnh); + } + dumptree(rnh); + ipf_rx_walktree(rnh, nodeprinter, NULL); + printf("=== TEST-1 ===\n"); + for (i = 0; ttable[i].host != NULL; i++) { + setaddr(&af, ttable[i].host); + test_addr(rnh, i, &af, -1); + } + + printf("=== TEST-2 ===\n"); + for (i = 0; mtable[i][0] != NULL; i++) { + setaddr(&af, mtable[i][0]); + test_addr(rnh, i, &af, -1); + } + printf("=== DELETE-1 ===\n"); + for (i = 0; ttable[i].host != NULL; i++) { + if (ttable[i].what[0] != 'd') + continue; + delete_addr(rnh, i); + for (j = 0; ttable[j].host != NULL; j++) { + setaddr(&af, ttable[j].host); + test_addr(rnh, i, &af, 3); + } + printroots(rnh); + ipf_rx_walktree(rnh, nodeprinter, NULL); + } + + dumptree(rnh); + + printf("=== ADD-2 ===\n"); + random_add(rnh); + checktree(rnh); + dumptree(rnh); + ipf_rx_walktree(rnh, nodeprinter, NULL); + printf("=== DELETE-2 ===\n"); + random_delete(rnh); + checktree(rnh); + dumptree(rnh); + + ipf_rx_walktree(rnh, ipf_rx_freenode, rnh); + + return 0; +} + + +void +dumptree(rnh) + ipf_rdx_head_t *rnh; +{ + myst_t *stp; + + printf("VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV\n"); + printroots(rnh); + for (stp = myst_top; stp; stp = stp->next) + printnode(stp); + printf("^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n"); +} + + +void +test_addr(rnh, pref, addr, limit) + ipf_rdx_head_t *rnh; + int pref; + addrfamily_t *addr; +{ + static int extras[14] = { 0, -1, 1, 3, 5, 8, 9, + 15, 16, 19, 255, 256, 65535, 65536 + }; + ipf_rdx_node_t *rn; + addrfamily_t af; + char name[80]; + myst_t *stp; + int i; + + memset(&af, 0, sizeof(af)); +#if 0 + if (limit < 0 || limit > 14) + limit = 14; + + for (i = 0; i < limit; i++) { + if (ttable[i].host == NULL) + break; + setaddr(&af, ttable[i].host); + printf("%d.%d.LOOKUP(%s)", pref, i, addrname(&af)); + rn = ipf_rx_match(rnh, &af); + stp = (myst_t *)rn; + printf(" = %s (%s/%d)\n", GNAME(rn), + rn ? addrname(&stp->dst) : "NULL", + rn ? rn->maskbitcount : 0); + } +#else + printf("%d.%d.LOOKUP(%s)", pref, -1, addrname(addr)); + rn = ipf_rx_match(rnh, addr); + stp = (myst_t *)rn; + printf(" = %s (%s/%d)\n", GNAME(rn), + rn ? addrname(&stp->dst) : "NULL", rn ? rn->maskbitcount : 0); +#endif +} + + +void +delete_addr(rnh, item) + ipf_rdx_head_t *rnh; + int item; +{ + ipf_rdx_node_t *rn; + addrfamily_t mask; + addrfamily_t af; + myst_t **pstp; + myst_t *stp; + + memset(&af, 0, sizeof(af)); + memset(&mask, 0, sizeof(mask)); + setaddr(&af, ttable[item].host); + mask.adf_family = af.adf_family; + setmask(&mask, ttable[item].mask); + + printf("DELETE(%s)\n", addrname(&af)); + rn = ipf_rx_delete(rnh, &af, &mask); + if (rn == NULL) { + printf("FAIL LOOKUP DELETE\n"); + checktree(rnh); + for (stp = myst_top; stp != NULL; stp = stp->next) + if (stp->printed != -1) + stp->printed = -2; + ipf_rx_walktree(rnh, nodeprinter, NULL); + dumptree(rnh); + abort(); + } + printf("%d.delete(%s) = %s\n", item, addrname(&af), GNAME(rn)); + + for (pstp = &myst_top; (stp = *pstp) != NULL; pstp = &stp->next) + if (stp == (myst_t *)rn) + break; + stp->printed = -1; + stp->nodes[0].parent = &stp->nodes[0]; + stp->nodes[1].parent = &stp->nodes[1]; + *pstp = stp->next; + free(stp); + nodecount--; + checktree(rnh); +} + + +void +add_addr(rnh, n, item) + ipf_rdx_head_t *rnh; + int n, item; +{ + ipf_rdx_node_t *rn; + myst_t *stp; + + stp = calloc(1, sizeof(*stp)); + rn = (ipf_rdx_node_t *)stp; + setaddr(&stp->dst, ttable[item].host); + stp->mask.adf_family = stp->dst.adf_family; + setmask(&stp->mask, ttable[item].mask); + stp->next = myst_top; + myst_top = stp; + (void) sprintf(rn[0].name, "_BORN.0"); + (void) sprintf(rn[1].name, "_BORN.1"); + rn = ipf_rx_addroute(rnh, &stp->dst, &stp->mask, stp->nodes); + (void) sprintf(rn[0].name, "%d_NODE.0", item); + (void) sprintf(rn[1].name, "%d_NODE.1", item); + printf("ADD %d/%d %s/%s\n", n, item, rn[0].name, rn[1].name); + nodecount++; + checktree(rnh); +} + + +void +checktree(ipf_rdx_head_t *head) +{ + myst_t *s1; + ipf_rdx_node_t *rn; + + if (nodecount <= 1) + return; + + for (s1 = myst_top; s1 != NULL; s1 = s1->next) { + int fault = 0; + if (s1->printed == -1) + continue; + rn = &s1->nodes[1]; + if (rn->right->parent != rn) + fault |= 1; + if (rn->left->parent != rn) + fault |= 2; + if (rn->parent->left != rn && rn->parent->right != rn) + fault |= 4; + if (fault != 0) { + printf("FAULT %#x %s\n", fault, rn->name); + dumptree(head); + ipf_rx_walktree(head, nodeprinter, NULL); + fflush(stdout); + fflush(stderr); + printf("--\n"); + abort(); + } + } +} + + +int * +randomize(int *pnitems) +{ + int *order; + int nitems; + int choice; + int j; + int i; + + nitems = sizeof(ttable) / sizeof(ttable[0]); + *pnitems = nitems; + order = calloc(nitems, sizeof(*order)); + srandom(getpid() * time(NULL)); + memset(order, 0xff, nitems * sizeof(*order)); + order[21] = 21; + for (i = 0; i < nitems - 1; i++) { + do { + choice = rand() % (nitems - 1); + for (j = 0; j < nitems; j++) + if (order[j] == choice) + break; + } while (j != nitems); + order[i] = choice; + } + + return order; +} + + +void +random_add(rnh) + ipf_rdx_head_t *rnh; +{ + int *order; + int nitems; + int i; + + order = randomize(&nitems); + + for (i = 0; i < nitems - 1; i++) { + add_addr(rnh, i, order[i]); + checktree(rnh); + } +} + + +void +random_delete(rnh) + ipf_rdx_head_t *rnh; +{ + int *order; + int nitems; + int i; + + order = randomize(&nitems); + + for (i = 0; i < nitems - 1; i++) { + delete_addr(rnh, i); + checktree(rnh); + } +} +#endif /* RDX_DEBUG */ diff --git a/contrib/ipfilter/radix_ipf.h b/contrib/ipfilter/radix_ipf.h index 11e4ba761aae..bbbf5592b990 100644 --- a/contrib/ipfilter/radix_ipf.h +++ b/contrib/ipfilter/radix_ipf.h @@ -1,214 +1,97 @@ /* $FreeBSD$ */ /* - * Copyright (c) 1988, 1989, 1993 - * The Regents of the University of California. All rights reserved. + * Copyright (C) 2012 by Darren Reed. * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * @(#)radix.h 8.2 (Berkeley) 10/31/94 + * See the IPFILTER.LICENCE file for details on licencing. */ +#ifndef __RADIX_IPF_H__ +#define __RADIX_IPF_H__ -#if !defined(_NET_RADIX_H_) && !defined(_RADIX_H_) -#define _NET_RADIX_H_ -#ifndef _RADIX_H_ -#define _RADIX_H_ -#endif /* _RADIX_H_ */ - -#ifndef __P -# ifdef __STDC__ -# define __P(x) x -# else -# define __P(x) () -# endif +#ifndef U_32_T +typedef unsigned int u_32_t; +# define U_32_T 1 #endif -#if defined(__sgi) || defined(__osf__) || defined(sun) -# define radix_mask ipf_radix_mask -# define radix_node ipf_radix_node -# define radix_node_head ipf_radix_node_head +typedef struct ipf_rdx_mask { + struct ipf_rdx_mask *next; + struct ipf_rdx_node *node; + u_32_t *mask; + int maskbitcount; +} ipf_rdx_mask_t; + +typedef struct ipf_rdx_node { + struct ipf_rdx_node *left; + struct ipf_rdx_node *right; + struct ipf_rdx_node *parent; + struct ipf_rdx_node *dupkey; + struct ipf_rdx_mask *masks; + struct ipf_rdx_mask *mymask; + u_32_t *addrkey; + u_32_t *maskkey; + u_32_t *addroff; + u_32_t *maskoff; + u_32_t lastmask; + u_32_t bitmask; + int offset; + int index; + int maskbitcount; + int root; +#ifdef RDX_DEBUG + char name[40]; #endif +} ipf_rdx_node_t; -/* - * Radix search tree node layout. - */ +struct ipf_rdx_head; -struct radix_node { - struct radix_mask *rn_mklist; /* list of masks contained in subtree */ - struct radix_node *rn_p; /* parent */ - short rn_b; /* bit offset; -1-index(netmask) */ - char rn_bmask; /* node: mask for bit test*/ - u_char rn_flags; /* enumerated next */ -#define RNF_NORMAL 1 /* leaf contains normal route */ -#define RNF_ROOT 2 /* leaf is root leaf for tree */ -#define RNF_ACTIVE 4 /* This node is alive (for rtfree) */ - union { - struct { /* leaf only data: */ - caddr_t rn_Key; /* object of search */ - caddr_t rn_Mask; /* netmask, if present */ - struct radix_node *rn_Dupedkey; - } rn_leaf; - struct { /* node only data: */ - int rn_Off; /* where to start compare */ - struct radix_node *rn_L;/* progeny */ - struct radix_node *rn_R;/* progeny */ - } rn_node; - } rn_u; -#ifdef RN_DEBUG - int rn_info; - struct radix_node *rn_twin; - struct radix_node *rn_ybro; -#endif -}; +typedef void (* radix_walk_func_t)(ipf_rdx_node_t *, void *); +typedef ipf_rdx_node_t *(* idx_hamn_func_t)(struct ipf_rdx_head *, + addrfamily_t *, addrfamily_t *, + ipf_rdx_node_t *); +typedef ipf_rdx_node_t *(* idx_ham_func_t)(struct ipf_rdx_head *, + addrfamily_t *, addrfamily_t *); +typedef ipf_rdx_node_t *(* idx_ha_func_t)(struct ipf_rdx_head *, + addrfamily_t *); +typedef void (* idx_walk_func_t)(struct ipf_rdx_head *, + radix_walk_func_t, void *); -#define rn_dupedkey rn_u.rn_leaf.rn_Dupedkey -#define rn_key rn_u.rn_leaf.rn_Key -#define rn_mask rn_u.rn_leaf.rn_Mask -#define rn_off rn_u.rn_node.rn_Off -#define rn_l rn_u.rn_node.rn_L -#define rn_r rn_u.rn_node.rn_R +typedef struct ipf_rdx_head { + ipf_rdx_node_t *root; + ipf_rdx_node_t nodes[3]; + ipfmutex_t lock; + idx_hamn_func_t addaddr; /* add addr/mask to tree */ + idx_ham_func_t deladdr; /* delete addr/mask from tree */ + idx_ham_func_t lookup; /* look for specific addr/mask */ + idx_ha_func_t matchaddr; /* search tree for address match */ + idx_walk_func_t walktree; /* walk entire tree */ +} ipf_rdx_head_t; -/* - * Annotations to tree concerning potential routes applying to subtrees. - */ +typedef struct radix_softc { + u_char *zeros; + u_char *ones; +} radix_softc_t; -struct radix_mask { - short rm_b; /* bit offset; -1-index(netmask) */ - char rm_unused; /* cf. rn_bmask */ - u_char rm_flags; /* cf. rn_flags */ - struct radix_mask *rm_mklist; /* more masks to try */ - union { - caddr_t rmu_mask; /* the mask */ - struct radix_node *rmu_leaf; /* for normal routes */ - } rm_rmu; - int rm_refs; /* # of references to this struct */ -}; - -#define rm_mask rm_rmu.rmu_mask -#define rm_leaf rm_rmu.rmu_leaf /* extra field would make 32 bytes */ - -#define MKGet(m) {\ - if (rn_mkfreelist) {\ - m = rn_mkfreelist; \ - rn_mkfreelist = (m)->rm_mklist; \ - } else \ - R_Malloc(m, struct radix_mask *, sizeof (*(m))); }\ - -#define MKFree(m) { (m)->rm_mklist = rn_mkfreelist; rn_mkfreelist = (m);} - -struct radix_node_head { - struct radix_node *rnh_treetop; - struct radix_node *rnh_leaflist; - u_long rnh_hits; - u_int rnh_number; - u_int rnh_ref; - int rnh_addrsize; /* permit, but not require fixed keys */ - int rnh_pktsize; /* permit, but not require fixed keys */ - struct radix_node *(*rnh_addaddr) /* add based on sockaddr */ - __P((void *v, void *mask, - struct radix_node_head *head, struct radix_node nodes[])); - struct radix_node *(*rnh_addpkt) /* add based on packet hdr */ - __P((void *v, void *mask, - struct radix_node_head *head, struct radix_node nodes[])); - struct radix_node *(*rnh_deladdr) /* remove based on sockaddr */ - __P((void *v, void *mask, struct radix_node_head *head)); - struct radix_node *(*rnh_delpkt) /* remove based on packet hdr */ - __P((void *v, void *mask, struct radix_node_head *head)); - struct radix_node *(*rnh_matchaddr) /* locate based on sockaddr */ - __P((void *v, struct radix_node_head *head)); - struct radix_node *(*rnh_lookup) /* locate based on sockaddr */ - __P((void *v, void *mask, struct radix_node_head *head)); - struct radix_node *(*rnh_matchpkt) /* locate based on packet hdr */ - __P((void *v, struct radix_node_head *head)); - int (*rnh_walktree) /* traverse tree */ - __P((struct radix_node_head *, - int (*)(struct radix_node *, void *), void *)); - struct radix_node rnh_nodes[3]; /* empty tree for common case */ -}; - - -#if defined(AIX) -# undef Bcmp -# undef Bzero -# undef R_Malloc -# undef Free -#endif -#define Bcmp(a, b, n) bcmp(((caddr_t)(a)), ((caddr_t)(b)), (unsigned)(n)) -#if defined(linux) && defined(_KERNEL) -# define Bcopy(a, b, n) memmove(((caddr_t)(b)), ((caddr_t)(a)), (unsigned)(n)) +#undef RADIX_NODE_HEAD_LOCK +#undef RADIX_NODE_HEAD_UNLOCK +#ifdef _KERNEL +# define RADIX_NODE_HEAD_LOCK(x) MUTEX_ENTER(&(x)->lock) +# define RADIX_NODE_HEAD_UNLOCK(x) MUTEX_UNLOCK(&(x)->lock) #else -# define Bcopy(a, b, n) bcopy(((caddr_t)(a)), ((caddr_t)(b)), (unsigned)(n)) -#endif -#define Bzero(p, n) bzero((caddr_t)(p), (unsigned)(n)); -#define R_Malloc(p, t, n) KMALLOCS(p, t, n) -#define FreeS(p, z) KFREES(p, z) -#define Free(p) KFREE(p) - -#if (defined(__osf__) || defined(AIX) || (IRIX >= 60516) || defined(sun)) && defined(_KERNEL) -# define rn_init ipf_rn_init -# define rn_fini ipf_rn_fini -# define rn_inithead ipf_rn_inithead -# define rn_freehead ipf_rn_freehead -# define rn_inithead0 ipf_rn_inithead0 -# define rn_refines ipf_rn_refines -# define rn_walktree ipf_rn_walktree -# define rn_addmask ipf_rn_addmask -# define rn_addroute ipf_rn_addroute -# define rn_delete ipf_rn_delete -# define rn_insert ipf_rn_insert -# define rn_lookup ipf_rn_lookup -# define rn_match ipf_rn_match -# define rn_newpair ipf_rn_newpair -# define rn_search ipf_rn_search -# define rn_search_m ipf_rn_search_m -# define max_keylen ipf_maxkeylen -# define rn_mkfreelist ipf_rn_mkfreelist -# define rn_zeros ipf_rn_zeros -# define rn_ones ipf_rn_ones -# define rn_satisfies_leaf ipf_rn_satisfies_leaf -# define rn_lexobetter ipf_rn_lexobetter -# define rn_new_radix_mask ipf_rn_new_radix_mask -# define rn_freenode ipf_rn_freenode +# define RADIX_NODE_HEAD_LOCK(x) +# define RADIX_NODE_HEAD_UNLOCK(x) #endif -void rn_init __P((void)); -void rn_fini __P((void)); -int rn_inithead __P((void **, int)); -void rn_freehead __P((struct radix_node_head *)); -int rn_inithead0 __P((struct radix_node_head *, int)); -int rn_refines __P((void *, void *)); -int rn_walktree __P((struct radix_node_head *, - int (*)(struct radix_node *, void *), void *)); -struct radix_node - *rn_addmask __P((void *, int, int)), - *rn_addroute __P((void *, void *, struct radix_node_head *, - struct radix_node [2])), - *rn_delete __P((void *, void *, struct radix_node_head *)), - *rn_insert __P((void *, struct radix_node_head *, int *, - struct radix_node [2])), - *rn_lookup __P((void *, void *, struct radix_node_head *)), - *rn_match __P((void *, struct radix_node_head *)), - *rn_newpair __P((void *, int, struct radix_node[2])), - *rn_search __P((void *, struct radix_node *)), - *rn_search_m __P((void *, struct radix_node *, void *)); +extern void *ipf_rx_create __P((void)); +extern int ipf_rx_init __P((void *)); +extern void ipf_rx_destroy __P((void *)); +extern int ipf_rx_inithead __P((radix_softc_t *, ipf_rdx_head_t **)); +extern void ipf_rx_freehead __P((ipf_rdx_head_t *)); +extern ipf_rdx_node_t *ipf_rx_addroute __P((ipf_rdx_head_t *, + addrfamily_t *, addrfamily_t *, + ipf_rdx_node_t *)); +extern ipf_rdx_node_t *ipf_rx_delete __P((ipf_rdx_head_t *, addrfamily_t *, + addrfamily_t *)); +extern void ipf_rx_walktree __P((ipf_rdx_head_t *, radix_walk_func_t, + void *)); -#endif /* _NET_RADIX_H_ */ +#endif /* __RADIX_IPF_H__ */ diff --git a/contrib/ipfilter/rules/.cvsignore b/contrib/ipfilter/rules/.cvsignore deleted file mode 100644 index 3e757656cf36..000000000000 --- a/contrib/ipfilter/rules/.cvsignore +++ /dev/null @@ -1 +0,0 @@ -new diff --git a/contrib/ipfilter/rules/BASIC_1.FW b/contrib/ipfilter/rules/BASIC_1.FW index d2bd60a31889..642dde061efd 100644 --- a/contrib/ipfilter/rules/BASIC_1.FW +++ b/contrib/ipfilter/rules/BASIC_1.FW @@ -22,10 +22,10 @@ block in log quick all with short # (especially for ed0) and needs to be further refined. # block in log on ppp0 all head 100 -block in log proto tcp all flags S/SA head 101 group 100 +block in log proto tcp all flags S/SA head 101 group 100 block out log on ppp0 all head 150 block in log on ed0 from w.x.y.z/24 to any head 200 -block in log proto tcp all flags S/SA head 201 group 200 +block in log proto tcp all flags S/SA head 201 group 200 block in log proto udp all head 202 group 200 block out log on ed0 all head 250 #------------------------------------------------------- diff --git a/contrib/ipfilter/rules/BASIC_2.FW b/contrib/ipfilter/rules/BASIC_2.FW index 46564f0ee412..1d4fd7317673 100644 --- a/contrib/ipfilter/rules/BASIC_2.FW +++ b/contrib/ipfilter/rules/BASIC_2.FW @@ -56,7 +56,7 @@ pass out quick on lo0 all # # Allow all outgoing connections (SSH, TELNET, FTP, WWW, gopher, etc) # -pass in log quick proto tcp all flags S/SA keep state group 200 +pass in log quick proto tcp all flags S/SA keep state group 200 # # Support all UDP `connections' initiated from inside. # diff --git a/contrib/ipfilter/rules/firewall b/contrib/ipfilter/rules/firewall index 681a81da20b6..f26b7150b98c 100644 --- a/contrib/ipfilter/rules/firewall +++ b/contrib/ipfilter/rules/firewall @@ -31,7 +31,7 @@ where closest to your internal network in terms of network hops. * "int-net" is the internal network IP# subnet address range. This might - be something like 10.1.0.0/16, or 128.33.1.0/24 + be something like 10.1.0.0/16, or 128.33.1.0/24 * "ext-service" is the service to which you wish to connect or if it doesn't have a proper name, a number can be used. The translation of "ext-service" diff --git a/contrib/ipfilter/rules/ipmon.conf b/contrib/ipfilter/rules/ipmon.conf index 47b01463575c..652afceb3ea1 100644 --- a/contrib/ipfilter/rules/ipmon.conf +++ b/contrib/ipfilter/rules/ipmon.conf @@ -2,23 +2,24 @@ # # # -match { logtag = 10000 } - do { execute "/usr/bin/mail -s 'logtag 10000' root" }; -match { logtag = 2000, every 10 seconds } - do { execute "echo 'XXXXXXXX tag 2000 packet XXXXXXXX'" }; +match { logtag = 10000; } +do { execute("/usr/bin/mail -s 'logtag 10000' root"); }; # -match { protocol = udp, result = block } - do { execute "/usr/bin/mail -s 'blocked udp' root" -}; +match { logtag = 2000, every 10 seconds; } +do { execute("echo 'XXXXXXXX tag 2000 packet XXXXXXXX'"); }; # -match { - srcip = 10.1.0.0/16, dstip = 192.168.1.0/24 } - do { execute "/usr/bin/mail -s 'from 10.1 to 192.168.1' root" -}; +match { protocol = udp, result = block; } +do { file("file:///var/log/udp-block"); }; +# +match { protocol = tcp, result = block, dstport = 25; } +do { syslog("local0.info"), syslog("local1."), syslog(".warn"); }; +# +match { srcip = 10.1.0.0/16, dstip = 192.168.1.0/24; } +do { execute("/usr/bin/mail -s 'from 10.1 to 192.168.1' root"); }; + # match { rule = 12, logtag = 101, direction = in, result = block, - protocol = udp, srcip = 10.1.0.0/16, dstip = 192.168.1.0/24 } - do { execute "run shell command" -}; + protocol = udp, srcip = 10.1.0.0/16, dstip = 192.168.1.0/24; } +do { nothing; }; # diff --git a/contrib/ipfilter/rules/server b/contrib/ipfilter/rules/server index f2fb2041faf0..de0e9bbd06d8 100644 --- a/contrib/ipfilter/rules/server +++ b/contrib/ipfilter/rules/server @@ -3,7 +3,7 @@ # 128.1.2.1 (le1), we want to block all IP spoofing attacks. le1 is # connected to the majority of the network, whilst le0 is connected to a # leaf subnet. We're not concerned about filtering individual services -# or +# or # pass in quick on le0 from 128.1.40.0/24 to any block in log quick on le0 from any to any diff --git a/contrib/ipfilter/samples/.cvsignore b/contrib/ipfilter/samples/.cvsignore deleted file mode 100644 index 4d38251c2f4f..000000000000 --- a/contrib/ipfilter/samples/.cvsignore +++ /dev/null @@ -1,4 +0,0 @@ -userauth -proxy -relay -trans_relay diff --git a/contrib/ipfilter/samples/proxy.c b/contrib/ipfilter/samples/proxy.c index 471cc736506a..483c4b5d768a 100644 --- a/contrib/ipfilter/samples/proxy.c +++ b/contrib/ipfilter/samples/proxy.c @@ -51,8 +51,8 @@ main(argc, argv) -int argc; -char *argv[]; + int argc; + char *argv[]; { struct sockaddr_in sin, sloc, sout; ipfobj_t obj; @@ -132,9 +132,9 @@ char *argv[]; #ifdef DO_NAT_OUT do_nat_out(in, out, fd, nlp, extif) -int fd; -natlookup_t *nlp; -char *extif; + int fd; + natlookup_t *nlp; + char *extif; { nat_save_t ns, *nsp = &ns; struct sockaddr_in usin; @@ -228,7 +228,7 @@ fflush(stdout); relay(in, out, net) -int in, out, net; + int in, out, net; { char netbuf[1024], outbuf[1024]; char *nwptr, *nrptr, *owptr, *orptr; diff --git a/contrib/ipfilter/samples/relay.c b/contrib/ipfilter/samples/relay.c index ac5c60243b8f..11b76b07c509 100644 --- a/contrib/ipfilter/samples/relay.c +++ b/contrib/ipfilter/samples/relay.c @@ -29,7 +29,7 @@ char ibuff[RELAY_BUFSZ]; char obuff[RELAY_BUFSZ]; int relay(ifd, ofd, rfd) -int ifd, ofd, rfd; + int ifd, ofd, rfd; { fd_set rfds, wfds; char *irh, *irt, *rrh, *rrt; @@ -103,8 +103,8 @@ int ifd, ofd, rfd; } main(argc, argv) -int argc; -char *argv[]; + int argc; + char *argv[]; { struct sockaddr_in sin; ipfobj_t obj; diff --git a/contrib/ipfilter/snoop.h b/contrib/ipfilter/snoop.h index 3cb54b99cc3f..74bc2470aefc 100644 --- a/contrib/ipfilter/snoop.h +++ b/contrib/ipfilter/snoop.h @@ -1,7 +1,7 @@ /* $FreeBSD$ */ /* - * Copyright (C) 1993-2001 by Darren Reed. + * Copyright (C) 2012 by Darren Reed. * * See the IPFILTER.LICENCE file for details on licencing. */ @@ -11,7 +11,7 @@ /* * written to comply with the RFC (1761) from Sun. - * $Id: snoop.h,v 2.3 2001/06/09 17:09:23 darrenr Exp $ + * $Id$ */ struct snoophdr { char s_id[8]; diff --git a/contrib/ipfilter/sys/tree.h b/contrib/ipfilter/sys/tree.h new file mode 100644 index 000000000000..585588544951 --- /dev/null +++ b/contrib/ipfilter/sys/tree.h @@ -0,0 +1,750 @@ +/* $NetBSD: tree.h,v 1.8 2004/03/28 19:38:30 provos Exp $ */ +/* $OpenBSD: tree.h,v 1.7 2002/10/17 21:51:54 art Exp $ */ +/* $FreeBSD: src/sys/sys/tree.h,v 1.7 2007/12/28 07:03:26 jasone Exp $ */ + +/*- + * Copyright 2002 Niels Provos + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _SYS_TREE_H_ +#define _SYS_TREE_H_ + +/* + * This file defines data structures for different types of trees: + * splay trees and red-black trees. + * + * A splay tree is a self-organizing data structure. Every operation + * on the tree causes a splay to happen. The splay moves the requested + * node to the root of the tree and partly rebalances it. + * + * This has the benefit that request locality causes faster lookups as + * the requested nodes move to the top of the tree. On the other hand, + * every lookup causes memory writes. + * + * The Balance Theorem bounds the total access time for m operations + * and n inserts on an initially empty tree as O((m + n)lg n). The + * amortized cost for a sequence of m accesses to a splay tree is O(lg n); + * + * A red-black tree is a binary search tree with the node color as an + * extra attribute. It fulfills a set of conditions: + * - every search path from the root to a leaf consists of the + * same number of black nodes, + * - each red node (except for the root) has a black parent, + * - each leaf node is black. + * + * Every operation on a red-black tree is bounded as O(lg n). + * The maximum height of a red-black tree is 2lg (n+1). + */ + +#define SPLAY_HEAD(name, type) \ +struct name { \ + struct type *sph_root; /* root of the tree */ \ +} + +#define SPLAY_INITIALIZER(root) \ + { NULL } + +#define SPLAY_INIT(root) do { \ + (root)->sph_root = NULL; \ +} while (/*CONSTCOND*/ 0) + +#define SPLAY_ENTRY(type) \ +struct { \ + struct type *spe_left; /* left element */ \ + struct type *spe_right; /* right element */ \ +} + +#define SPLAY_LEFT(elm, field) (elm)->field.spe_left +#define SPLAY_RIGHT(elm, field) (elm)->field.spe_right +#define SPLAY_ROOT(head) (head)->sph_root +#define SPLAY_EMPTY(head) (SPLAY_ROOT(head) == NULL) + +/* SPLAY_ROTATE_{LEFT,RIGHT} expect that tmp hold SPLAY_{RIGHT,LEFT} */ +#define SPLAY_ROTATE_RIGHT(head, tmp, field) do { \ + SPLAY_LEFT((head)->sph_root, field) = SPLAY_RIGHT(tmp, field); \ + SPLAY_RIGHT(tmp, field) = (head)->sph_root; \ + (head)->sph_root = tmp; \ +} while (/*CONSTCOND*/ 0) + +#define SPLAY_ROTATE_LEFT(head, tmp, field) do { \ + SPLAY_RIGHT((head)->sph_root, field) = SPLAY_LEFT(tmp, field); \ + SPLAY_LEFT(tmp, field) = (head)->sph_root; \ + (head)->sph_root = tmp; \ +} while (/*CONSTCOND*/ 0) + +#define SPLAY_LINKLEFT(head, tmp, field) do { \ + SPLAY_LEFT(tmp, field) = (head)->sph_root; \ + tmp = (head)->sph_root; \ + (head)->sph_root = SPLAY_LEFT((head)->sph_root, field); \ +} while (/*CONSTCOND*/ 0) + +#define SPLAY_LINKRIGHT(head, tmp, field) do { \ + SPLAY_RIGHT(tmp, field) = (head)->sph_root; \ + tmp = (head)->sph_root; \ + (head)->sph_root = SPLAY_RIGHT((head)->sph_root, field); \ +} while (/*CONSTCOND*/ 0) + +#define SPLAY_ASSEMBLE(head, node, left, right, field) do { \ + SPLAY_RIGHT(left, field) = SPLAY_LEFT((head)->sph_root, field); \ + SPLAY_LEFT(right, field) = SPLAY_RIGHT((head)->sph_root, field);\ + SPLAY_LEFT((head)->sph_root, field) = SPLAY_RIGHT(node, field); \ + SPLAY_RIGHT((head)->sph_root, field) = SPLAY_LEFT(node, field); \ +} while (/*CONSTCOND*/ 0) + +/* Generates prototypes and inline functions */ + +#define SPLAY_PROTOTYPE(name, type, field, cmp) \ +void name##_SPLAY(struct name *, struct type *); \ +void name##_SPLAY_MINMAX(struct name *, int); \ +struct type *name##_SPLAY_INSERT(struct name *, struct type *); \ +struct type *name##_SPLAY_REMOVE(struct name *, struct type *); \ + \ +/* Finds the node with the same key as elm */ \ +static __inline struct type * \ +name##_SPLAY_FIND(struct name *head, struct type *elm) \ +{ \ + if (SPLAY_EMPTY(head)) \ + return(NULL); \ + name##_SPLAY(head, elm); \ + if ((cmp)(elm, (head)->sph_root) == 0) \ + return (head->sph_root); \ + return (NULL); \ +} \ + \ +static __inline struct type * \ +name##_SPLAY_NEXT(struct name *head, struct type *elm) \ +{ \ + name##_SPLAY(head, elm); \ + if (SPLAY_RIGHT(elm, field) != NULL) { \ + elm = SPLAY_RIGHT(elm, field); \ + while (SPLAY_LEFT(elm, field) != NULL) { \ + elm = SPLAY_LEFT(elm, field); \ + } \ + } else \ + elm = NULL; \ + return (elm); \ +} \ + \ +static __inline struct type * \ +name##_SPLAY_MIN_MAX(struct name *head, int val) \ +{ \ + name##_SPLAY_MINMAX(head, val); \ + return (SPLAY_ROOT(head)); \ +} + +/* Main splay operation. + * Moves node close to the key of elm to top + */ +#define SPLAY_GENERATE(name, type, field, cmp) \ +struct type * \ +name##_SPLAY_INSERT(struct name *head, struct type *elm) \ +{ \ + if (SPLAY_EMPTY(head)) { \ + SPLAY_LEFT(elm, field) = SPLAY_RIGHT(elm, field) = NULL; \ + } else { \ + int __comp; \ + name##_SPLAY(head, elm); \ + __comp = (cmp)(elm, (head)->sph_root); \ + if(__comp < 0) { \ + SPLAY_LEFT(elm, field) = SPLAY_LEFT((head)->sph_root, field);\ + SPLAY_RIGHT(elm, field) = (head)->sph_root; \ + SPLAY_LEFT((head)->sph_root, field) = NULL; \ + } else if (__comp > 0) { \ + SPLAY_RIGHT(elm, field) = SPLAY_RIGHT((head)->sph_root, field);\ + SPLAY_LEFT(elm, field) = (head)->sph_root; \ + SPLAY_RIGHT((head)->sph_root, field) = NULL; \ + } else \ + return ((head)->sph_root); \ + } \ + (head)->sph_root = (elm); \ + return (NULL); \ +} \ + \ +struct type * \ +name##_SPLAY_REMOVE(struct name *head, struct type *elm) \ +{ \ + struct type *__tmp; \ + if (SPLAY_EMPTY(head)) \ + return (NULL); \ + name##_SPLAY(head, elm); \ + if ((cmp)(elm, (head)->sph_root) == 0) { \ + if (SPLAY_LEFT((head)->sph_root, field) == NULL) { \ + (head)->sph_root = SPLAY_RIGHT((head)->sph_root, field);\ + } else { \ + __tmp = SPLAY_RIGHT((head)->sph_root, field); \ + (head)->sph_root = SPLAY_LEFT((head)->sph_root, field);\ + name##_SPLAY(head, elm); \ + SPLAY_RIGHT((head)->sph_root, field) = __tmp; \ + } \ + return (elm); \ + } \ + return (NULL); \ +} \ + \ +void \ +name##_SPLAY(struct name *head, struct type *elm) \ +{ \ + struct type __node, *__left, *__right, *__tmp; \ + int __comp; \ +\ + SPLAY_LEFT(&__node, field) = SPLAY_RIGHT(&__node, field) = NULL;\ + __left = __right = &__node; \ +\ + while ((__comp = (cmp)(elm, (head)->sph_root)) != 0) { \ + if (__comp < 0) { \ + __tmp = SPLAY_LEFT((head)->sph_root, field); \ + if (__tmp == NULL) \ + break; \ + if ((cmp)(elm, __tmp) < 0){ \ + SPLAY_ROTATE_RIGHT(head, __tmp, field); \ + if (SPLAY_LEFT((head)->sph_root, field) == NULL)\ + break; \ + } \ + SPLAY_LINKLEFT(head, __right, field); \ + } else if (__comp > 0) { \ + __tmp = SPLAY_RIGHT((head)->sph_root, field); \ + if (__tmp == NULL) \ + break; \ + if ((cmp)(elm, __tmp) > 0){ \ + SPLAY_ROTATE_LEFT(head, __tmp, field); \ + if (SPLAY_RIGHT((head)->sph_root, field) == NULL)\ + break; \ + } \ + SPLAY_LINKRIGHT(head, __left, field); \ + } \ + } \ + SPLAY_ASSEMBLE(head, &__node, __left, __right, field); \ +} \ + \ +/* Splay with either the minimum or the maximum element \ + * Used to find minimum or maximum element in tree. \ + */ \ +void name##_SPLAY_MINMAX(struct name *head, int __comp) \ +{ \ + struct type __node, *__left, *__right, *__tmp; \ +\ + SPLAY_LEFT(&__node, field) = SPLAY_RIGHT(&__node, field) = NULL;\ + __left = __right = &__node; \ +\ + while (1) { \ + if (__comp < 0) { \ + __tmp = SPLAY_LEFT((head)->sph_root, field); \ + if (__tmp == NULL) \ + break; \ + if (__comp < 0){ \ + SPLAY_ROTATE_RIGHT(head, __tmp, field); \ + if (SPLAY_LEFT((head)->sph_root, field) == NULL)\ + break; \ + } \ + SPLAY_LINKLEFT(head, __right, field); \ + } else if (__comp > 0) { \ + __tmp = SPLAY_RIGHT((head)->sph_root, field); \ + if (__tmp == NULL) \ + break; \ + if (__comp > 0) { \ + SPLAY_ROTATE_LEFT(head, __tmp, field); \ + if (SPLAY_RIGHT((head)->sph_root, field) == NULL)\ + break; \ + } \ + SPLAY_LINKRIGHT(head, __left, field); \ + } \ + } \ + SPLAY_ASSEMBLE(head, &__node, __left, __right, field); \ +} + +#define SPLAY_NEGINF -1 +#define SPLAY_INF 1 + +#define SPLAY_INSERT(name, x, y) name##_SPLAY_INSERT(x, y) +#define SPLAY_REMOVE(name, x, y) name##_SPLAY_REMOVE(x, y) +#define SPLAY_FIND(name, x, y) name##_SPLAY_FIND(x, y) +#define SPLAY_NEXT(name, x, y) name##_SPLAY_NEXT(x, y) +#define SPLAY_MIN(name, x) (SPLAY_EMPTY(x) ? NULL \ + : name##_SPLAY_MIN_MAX(x, SPLAY_NEGINF)) +#define SPLAY_MAX(name, x) (SPLAY_EMPTY(x) ? NULL \ + : name##_SPLAY_MIN_MAX(x, SPLAY_INF)) + +#define SPLAY_FOREACH(x, name, head) \ + for ((x) = SPLAY_MIN(name, head); \ + (x) != NULL; \ + (x) = SPLAY_NEXT(name, head, x)) + +/* Macros that define a red-black tree */ +#define RB_HEAD(name, type) \ +struct name { \ + struct type *rbh_root; /* root of the tree */ \ +} + +#define RB_INITIALIZER(root) \ + { NULL } + +#define RB_INIT(root) do { \ + (root)->rbh_root = NULL; \ +} while (/*CONSTCOND*/ 0) + +/* + * Undef for Linux + */ +#undef RB_BLACK +#undef RB_RED +#undef RB_ROOT + +#define RB_BLACK 0 +#define RB_RED 1 +#define RB_ENTRY(type) \ +struct { \ + struct type *rbe_left; /* left element */ \ + struct type *rbe_right; /* right element */ \ + struct type *rbe_parent; /* parent element */ \ + int rbe_color; /* node color */ \ +} + +#define RB_LEFT(elm, field) (elm)->field.rbe_left +#define RB_RIGHT(elm, field) (elm)->field.rbe_right +#define RB_PARENT(elm, field) (elm)->field.rbe_parent +#define RB_COLOR(elm, field) (elm)->field.rbe_color +#define RB_ROOT(head) (head)->rbh_root +#define RB_EMPTY(head) (RB_ROOT(head) == NULL) + +#define RB_SET(elm, parent, field) do { \ + RB_PARENT(elm, field) = parent; \ + RB_LEFT(elm, field) = RB_RIGHT(elm, field) = NULL; \ + RB_COLOR(elm, field) = RB_RED; \ +} while (/*CONSTCOND*/ 0) + +#define RB_SET_BLACKRED(black, red, field) do { \ + RB_COLOR(black, field) = RB_BLACK; \ + RB_COLOR(red, field) = RB_RED; \ +} while (/*CONSTCOND*/ 0) + +#ifndef RB_AUGMENT +#define RB_AUGMENT(x) do {} while (0) +#endif + +#define RB_ROTATE_LEFT(head, elm, tmp, field) do { \ + (tmp) = RB_RIGHT(elm, field); \ + if ((RB_RIGHT(elm, field) = RB_LEFT(tmp, field)) != NULL) { \ + RB_PARENT(RB_LEFT(tmp, field), field) = (elm); \ + } \ + RB_AUGMENT(elm); \ + if ((RB_PARENT(tmp, field) = RB_PARENT(elm, field)) != NULL) { \ + if ((elm) == RB_LEFT(RB_PARENT(elm, field), field)) \ + RB_LEFT(RB_PARENT(elm, field), field) = (tmp); \ + else \ + RB_RIGHT(RB_PARENT(elm, field), field) = (tmp); \ + } else \ + (head)->rbh_root = (tmp); \ + RB_LEFT(tmp, field) = (elm); \ + RB_PARENT(elm, field) = (tmp); \ + RB_AUGMENT(tmp); \ + if ((RB_PARENT(tmp, field))) \ + RB_AUGMENT(RB_PARENT(tmp, field)); \ +} while (/*CONSTCOND*/ 0) + +#define RB_ROTATE_RIGHT(head, elm, tmp, field) do { \ + (tmp) = RB_LEFT(elm, field); \ + if ((RB_LEFT(elm, field) = RB_RIGHT(tmp, field)) != NULL) { \ + RB_PARENT(RB_RIGHT(tmp, field), field) = (elm); \ + } \ + RB_AUGMENT(elm); \ + if ((RB_PARENT(tmp, field) = RB_PARENT(elm, field)) != NULL) { \ + if ((elm) == RB_LEFT(RB_PARENT(elm, field), field)) \ + RB_LEFT(RB_PARENT(elm, field), field) = (tmp); \ + else \ + RB_RIGHT(RB_PARENT(elm, field), field) = (tmp); \ + } else \ + (head)->rbh_root = (tmp); \ + RB_RIGHT(tmp, field) = (elm); \ + RB_PARENT(elm, field) = (tmp); \ + RB_AUGMENT(tmp); \ + if ((RB_PARENT(tmp, field))) \ + RB_AUGMENT(RB_PARENT(tmp, field)); \ +} while (/*CONSTCOND*/ 0) + +/* Generates prototypes and inline functions */ +#define RB_PROTOTYPE(name, type, field, cmp) \ + RB_PROTOTYPE_INTERNAL(name, type, field, cmp,) +#define RB_PROTOTYPE_STATIC(name, type, field, cmp) \ + RB_PROTOTYPE_INTERNAL(name, type, field, cmp, __unused static) +#define RB_PROTOTYPE_INTERNAL(name, type, field, cmp, attr) \ +attr void name##_RB_INSERT_COLOR(struct name *, struct type *); \ +attr void name##_RB_REMOVE_COLOR(struct name *, struct type *, struct type *);\ +attr struct type *name##_RB_REMOVE(struct name *, struct type *); \ +attr struct type *name##_RB_INSERT(struct name *, struct type *); \ +attr struct type *name##_RB_FIND(struct name *, struct type *); \ +attr struct type *name##_RB_NFIND(struct name *, struct type *); \ +attr struct type *name##_RB_NEXT(struct type *); \ +attr struct type *name##_RB_PREV(struct type *); \ +attr struct type *name##_RB_MINMAX(struct name *, int); \ + \ + +/* Main rb operation. + * Moves node close to the key of elm to top + */ +#define RB_GENERATE(name, type, field, cmp) \ + RB_GENERATE_INTERNAL(name, type, field, cmp,) +#define RB_GENERATE_STATIC(name, type, field, cmp) \ + RB_GENERATE_INTERNAL(name, type, field, cmp, __unused static) +#define RB_GENERATE_INTERNAL(name, type, field, cmp, attr) \ +attr void \ +name##_RB_INSERT_COLOR(struct name *head, struct type *elm) \ +{ \ + struct type *parent, *gparent, *tmp; \ + while ((parent = RB_PARENT(elm, field)) != NULL && \ + RB_COLOR(parent, field) == RB_RED) { \ + gparent = RB_PARENT(parent, field); \ + if (parent == RB_LEFT(gparent, field)) { \ + tmp = RB_RIGHT(gparent, field); \ + if (tmp && RB_COLOR(tmp, field) == RB_RED) { \ + RB_COLOR(tmp, field) = RB_BLACK; \ + RB_SET_BLACKRED(parent, gparent, field);\ + elm = gparent; \ + continue; \ + } \ + if (RB_RIGHT(parent, field) == elm) { \ + RB_ROTATE_LEFT(head, parent, tmp, field);\ + tmp = parent; \ + parent = elm; \ + elm = tmp; \ + } \ + RB_SET_BLACKRED(parent, gparent, field); \ + RB_ROTATE_RIGHT(head, gparent, tmp, field); \ + } else { \ + tmp = RB_LEFT(gparent, field); \ + if (tmp && RB_COLOR(tmp, field) == RB_RED) { \ + RB_COLOR(tmp, field) = RB_BLACK; \ + RB_SET_BLACKRED(parent, gparent, field);\ + elm = gparent; \ + continue; \ + } \ + if (RB_LEFT(parent, field) == elm) { \ + RB_ROTATE_RIGHT(head, parent, tmp, field);\ + tmp = parent; \ + parent = elm; \ + elm = tmp; \ + } \ + RB_SET_BLACKRED(parent, gparent, field); \ + RB_ROTATE_LEFT(head, gparent, tmp, field); \ + } \ + } \ + RB_COLOR(head->rbh_root, field) = RB_BLACK; \ +} \ + \ +attr void \ +name##_RB_REMOVE_COLOR(struct name *head, struct type *parent, struct type *elm) \ +{ \ + struct type *tmp; \ + while ((elm == NULL || RB_COLOR(elm, field) == RB_BLACK) && \ + elm != RB_ROOT(head)) { \ + if (RB_LEFT(parent, field) == elm) { \ + tmp = RB_RIGHT(parent, field); \ + if (RB_COLOR(tmp, field) == RB_RED) { \ + RB_SET_BLACKRED(tmp, parent, field); \ + RB_ROTATE_LEFT(head, parent, tmp, field);\ + tmp = RB_RIGHT(parent, field); \ + } \ + if ((RB_LEFT(tmp, field) == NULL || \ + RB_COLOR(RB_LEFT(tmp, field), field) == RB_BLACK) &&\ + (RB_RIGHT(tmp, field) == NULL || \ + RB_COLOR(RB_RIGHT(tmp, field), field) == RB_BLACK)) {\ + RB_COLOR(tmp, field) = RB_RED; \ + elm = parent; \ + parent = RB_PARENT(elm, field); \ + } else { \ + if (RB_RIGHT(tmp, field) == NULL || \ + RB_COLOR(RB_RIGHT(tmp, field), field) == RB_BLACK) {\ + struct type *oleft; \ + if ((oleft = RB_LEFT(tmp, field)) \ + != NULL) \ + RB_COLOR(oleft, field) = RB_BLACK;\ + RB_COLOR(tmp, field) = RB_RED; \ + RB_ROTATE_RIGHT(head, tmp, oleft, field);\ + tmp = RB_RIGHT(parent, field); \ + } \ + RB_COLOR(tmp, field) = RB_COLOR(parent, field);\ + RB_COLOR(parent, field) = RB_BLACK; \ + if (RB_RIGHT(tmp, field)) \ + RB_COLOR(RB_RIGHT(tmp, field), field) = RB_BLACK;\ + RB_ROTATE_LEFT(head, parent, tmp, field);\ + elm = RB_ROOT(head); \ + break; \ + } \ + } else { \ + tmp = RB_LEFT(parent, field); \ + if (RB_COLOR(tmp, field) == RB_RED) { \ + RB_SET_BLACKRED(tmp, parent, field); \ + RB_ROTATE_RIGHT(head, parent, tmp, field);\ + tmp = RB_LEFT(parent, field); \ + } \ + if ((RB_LEFT(tmp, field) == NULL || \ + RB_COLOR(RB_LEFT(tmp, field), field) == RB_BLACK) &&\ + (RB_RIGHT(tmp, field) == NULL || \ + RB_COLOR(RB_RIGHT(tmp, field), field) == RB_BLACK)) {\ + RB_COLOR(tmp, field) = RB_RED; \ + elm = parent; \ + parent = RB_PARENT(elm, field); \ + } else { \ + if (RB_LEFT(tmp, field) == NULL || \ + RB_COLOR(RB_LEFT(tmp, field), field) == RB_BLACK) {\ + struct type *oright; \ + if ((oright = RB_RIGHT(tmp, field)) \ + != NULL) \ + RB_COLOR(oright, field) = RB_BLACK;\ + RB_COLOR(tmp, field) = RB_RED; \ + RB_ROTATE_LEFT(head, tmp, oright, field);\ + tmp = RB_LEFT(parent, field); \ + } \ + RB_COLOR(tmp, field) = RB_COLOR(parent, field);\ + RB_COLOR(parent, field) = RB_BLACK; \ + if (RB_LEFT(tmp, field)) \ + RB_COLOR(RB_LEFT(tmp, field), field) = RB_BLACK;\ + RB_ROTATE_RIGHT(head, parent, tmp, field);\ + elm = RB_ROOT(head); \ + break; \ + } \ + } \ + } \ + if (elm) \ + RB_COLOR(elm, field) = RB_BLACK; \ +} \ + \ +attr struct type * \ +name##_RB_REMOVE(struct name *head, struct type *elm) \ +{ \ + struct type *child, *parent, *old = elm; \ + int color; \ + if (RB_LEFT(elm, field) == NULL) \ + child = RB_RIGHT(elm, field); \ + else if (RB_RIGHT(elm, field) == NULL) \ + child = RB_LEFT(elm, field); \ + else { \ + struct type *left; \ + elm = RB_RIGHT(elm, field); \ + while ((left = RB_LEFT(elm, field)) != NULL) \ + elm = left; \ + child = RB_RIGHT(elm, field); \ + parent = RB_PARENT(elm, field); \ + color = RB_COLOR(elm, field); \ + if (child) \ + RB_PARENT(child, field) = parent; \ + if (parent) { \ + if (RB_LEFT(parent, field) == elm) \ + RB_LEFT(parent, field) = child; \ + else \ + RB_RIGHT(parent, field) = child; \ + RB_AUGMENT(parent); \ + } else \ + RB_ROOT(head) = child; \ + if (RB_PARENT(elm, field) == old) \ + parent = elm; \ + (elm)->field = (old)->field; \ + if (RB_PARENT(old, field)) { \ + if (RB_LEFT(RB_PARENT(old, field), field) == old)\ + RB_LEFT(RB_PARENT(old, field), field) = elm;\ + else \ + RB_RIGHT(RB_PARENT(old, field), field) = elm;\ + RB_AUGMENT(RB_PARENT(old, field)); \ + } else \ + RB_ROOT(head) = elm; \ + RB_PARENT(RB_LEFT(old, field), field) = elm; \ + if (RB_RIGHT(old, field)) \ + RB_PARENT(RB_RIGHT(old, field), field) = elm; \ + if (parent) { \ + left = parent; \ + do { \ + RB_AUGMENT(left); \ + } while ((left = RB_PARENT(left, field)) != NULL); \ + } \ + goto color; \ + } \ + parent = RB_PARENT(elm, field); \ + color = RB_COLOR(elm, field); \ + if (child) \ + RB_PARENT(child, field) = parent; \ + if (parent) { \ + if (RB_LEFT(parent, field) == elm) \ + RB_LEFT(parent, field) = child; \ + else \ + RB_RIGHT(parent, field) = child; \ + RB_AUGMENT(parent); \ + } else \ + RB_ROOT(head) = child; \ +color: \ + if (color == RB_BLACK) \ + name##_RB_REMOVE_COLOR(head, parent, child); \ + return (old); \ +} \ + \ +/* Inserts a node into the RB tree */ \ +attr struct type * \ +name##_RB_INSERT(struct name *head, struct type *elm) \ +{ \ + struct type *tmp; \ + struct type *parent = NULL; \ + int comp = 0; \ + tmp = RB_ROOT(head); \ + while (tmp) { \ + parent = tmp; \ + comp = (cmp)(elm, parent); \ + if (comp < 0) \ + tmp = RB_LEFT(tmp, field); \ + else if (comp > 0) \ + tmp = RB_RIGHT(tmp, field); \ + else \ + return (tmp); \ + } \ + RB_SET(elm, parent, field); \ + if (parent != NULL) { \ + if (comp < 0) \ + RB_LEFT(parent, field) = elm; \ + else \ + RB_RIGHT(parent, field) = elm; \ + RB_AUGMENT(parent); \ + } else \ + RB_ROOT(head) = elm; \ + name##_RB_INSERT_COLOR(head, elm); \ + return (NULL); \ +} \ + \ +/* Finds the node with the same key as elm */ \ +attr struct type * \ +name##_RB_FIND(struct name *head, struct type *elm) \ +{ \ + struct type *tmp = RB_ROOT(head); \ + int comp; \ + while (tmp) { \ + comp = cmp(elm, tmp); \ + if (comp < 0) \ + tmp = RB_LEFT(tmp, field); \ + else if (comp > 0) \ + tmp = RB_RIGHT(tmp, field); \ + else \ + return (tmp); \ + } \ + return (NULL); \ +} \ + \ +/* Finds the first node greater than or equal to the search key */ \ +attr struct type * \ +name##_RB_NFIND(struct name *head, struct type *elm) \ +{ \ + struct type *tmp = RB_ROOT(head); \ + struct type *res = NULL; \ + int comp; \ + while (tmp) { \ + comp = cmp(elm, tmp); \ + if (comp < 0) { \ + res = tmp; \ + tmp = RB_LEFT(tmp, field); \ + } \ + else if (comp > 0) \ + tmp = RB_RIGHT(tmp, field); \ + else \ + return (tmp); \ + } \ + return (res); \ +} \ + \ +/* ARGSUSED */ \ +attr struct type * \ +name##_RB_NEXT(struct type *elm) \ +{ \ + if (RB_RIGHT(elm, field)) { \ + elm = RB_RIGHT(elm, field); \ + while (RB_LEFT(elm, field)) \ + elm = RB_LEFT(elm, field); \ + } else { \ + if (RB_PARENT(elm, field) && \ + (elm == RB_LEFT(RB_PARENT(elm, field), field))) \ + elm = RB_PARENT(elm, field); \ + else { \ + while (RB_PARENT(elm, field) && \ + (elm == RB_RIGHT(RB_PARENT(elm, field), field)))\ + elm = RB_PARENT(elm, field); \ + elm = RB_PARENT(elm, field); \ + } \ + } \ + return (elm); \ +} \ + \ +/* ARGSUSED */ \ +attr struct type * \ +name##_RB_PREV(struct type *elm) \ +{ \ + if (RB_LEFT(elm, field)) { \ + elm = RB_LEFT(elm, field); \ + while (RB_RIGHT(elm, field)) \ + elm = RB_RIGHT(elm, field); \ + } else { \ + if (RB_PARENT(elm, field) && \ + (elm == RB_RIGHT(RB_PARENT(elm, field), field))) \ + elm = RB_PARENT(elm, field); \ + else { \ + while (RB_PARENT(elm, field) && \ + (elm == RB_LEFT(RB_PARENT(elm, field), field)))\ + elm = RB_PARENT(elm, field); \ + elm = RB_PARENT(elm, field); \ + } \ + } \ + return (elm); \ +} \ + \ +attr struct type * \ +name##_RB_MINMAX(struct name *head, int val) \ +{ \ + struct type *tmp = RB_ROOT(head); \ + struct type *parent = NULL; \ + while (tmp) { \ + parent = tmp; \ + if (val < 0) \ + tmp = RB_LEFT(tmp, field); \ + else \ + tmp = RB_RIGHT(tmp, field); \ + } \ + return (parent); \ +} + +#define RB_NEGINF -1 +#define RB_INF 1 + +#define RB_INSERT(name, x, y) name##_RB_INSERT(x, y) +#define RB_REMOVE(name, x, y) name##_RB_REMOVE(x, y) +#define RB_FIND(name, x, y) name##_RB_FIND(x, y) +#define RB_NFIND(name, x, y) name##_RB_NFIND(x, y) +#define RB_NEXT(name, x, y) name##_RB_NEXT(y) +#define RB_PREV(name, x, y) name##_RB_PREV(y) +#define RB_MIN(name, x) name##_RB_MINMAX(x, RB_NEGINF) +#define RB_MAX(name, x) name##_RB_MINMAX(x, RB_INF) + +#define RB_FOREACH(x, name, head) \ + for ((x) = RB_MIN(name, head); \ + (x) != NULL; \ + (x) = name##_RB_NEXT(x)) + +#define RB_FOREACH_REVERSE(x, name, head) \ + for ((x) = RB_MAX(name, head); \ + (x) != NULL; \ + (x) = name##_RB_PREV(x)) + +#endif /* _SYS_TREE_H_ */ diff --git a/contrib/ipfilter/test/.cvsignore b/contrib/ipfilter/test/.cvsignore deleted file mode 100644 index 5825abcde9c7..000000000000 --- a/contrib/ipfilter/test/.cvsignore +++ /dev/null @@ -1,87 +0,0 @@ -results -1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -11 -12 -i1 -i2 -i3 -i4 -i5 -i6 -i7 -i8 -i9 -i10 -i11 -f1 -f2 -f3 -f4 -f5 -f6 -f7 -f8 -f9 -f10 -f11 -f12 -f13 -f14 -n1 -n2 -n3 -n4 -n5 -n6 -n7 -f15 -f16 -ipv6.1 -ipv6.2 -l1 -ni1 -ni2 -ni3 -ni4 -f17 -in1 -in2 -in3 -in4 -p1 -p2 -i12 -ip1 -p3 -i13 -ni5 -ni6 -i14 -in5 -ipv6.3 -n8 -n9 -n10 -n11 -ni7 -ni8 -ni9 -ni10 -ni11 -ni12 -n12 -in6 -i15 -ni13 -ni14 -ni15 -ni16 diff --git a/contrib/ipfilter/test/Makefile b/contrib/ipfilter/test/Makefile index b0462f3f388d..89183117b4e6 100644 --- a/contrib/ipfilter/test/Makefile +++ b/contrib/ipfilter/test/Makefile @@ -3,6 +3,9 @@ # # See the IPFILTER.LICENCE file for details on licencing. # +POOLDEP=../ip_lookup.c ../ip_lookup.h ../ip_pool.c ../ip_pool.h \ + ../ip_htable.c ../ip_htable.h ../ip_dstlist.c ../ip_dstlist.h \ + ../tools/ippool_y.y BINDEST=/usr/local/bin SBINDEST=/sbin MANDIR=/usr/share/man @@ -14,86 +17,504 @@ expected.d: results: mkdir -p results -tests: ipf nat logtests ipv6 pools bpf +tests: ipf nat logtests ipv6 pools -ipf: ftests ptests +ipf: patests ftests -nat: ntests nitests intests +nat: intests ntests nitests first: -mkdir -p results # Filtering tests -ftests: f1 f2 f3 f4 f5 f6 f7 f8 f9 f10 f11 f12 f13 f14 f15 f16 f17 f18 f19 f20 f24 +ftests: f1 f2 f3 f4 f5 f6 f7 f8 f9 f10 f11 f12 f13 f14 f15 f16 f17 f18 f19 f20 f21 f22 f24 f25 f26 f27 f28 f29 f30 # Rule parsing tests -ptests: i1 i2 i3 i4 i5 i6 i7 i8 i9 i10 i11 i12 i13 i14 i15 i16 i17 i18 i19 \ - i20 i21 +patests: i1 i2 i3 i4 i5 i6 i7 i8 i9 i10 i11 i12 i13 i14 i15 i16 i17 i18 i19 \ + i20 i21 i22 i23 -ntests: n1 n2 n3 n4 n5 n6 n7 n8 n9 n10 n11 n12 n13 n14 n16 +ntests: n1 n2 n3 n4 n5 n6 n7 n8 n9 n10 n11 n12 n13 n14 n15 n16 n17 n18 n100 n101 n102 n103 n104 n105 n106 n200 + +ntests6: n1_6 n2_6 n4_6 n5_6 n6_6 n7_6 n8_6 n9_6 n11_6 n12_6 n15_6 nitests: ni1 ni2 ni3 ni4 ni5 ni6 ni7 ni8 ni9 ni10 ni11 ni12 ni13 ni14 ni15 \ - ni16 ni19 ni20 ni21 ni23 + ni16 ni17 ni18 ni19 ni20 ni21 ni23 -intests: in1 in2 in3 in4 in5 in6 +intests: in1 in2 in3 in4 in5 in6 in7 in8 in100 in101 in102 logtests: l1 -pools: p1 p2 p3 p5 ip1 ip2 +pools: p1 p2 p3 p4 p5 p6 p7 p9 p10 p11 p12 p13 ip1 ip2 ip3 -ipv6: ipv6.1 ipv6.2 ipv6.3 ipv6.5 ipv6.6 +ipv6: ipv6.1 ipv6.2 ipv6.3 ipv6.4 ipv6.5 ipv6.6 ntests6 bpf: bpf1 bpf-f1 -f1 f2 f3 f4 f5 f6 f7 f8 f9 f10 f11 f12 f13 f14 f19: +f1: expected/f1 input/f1 regress/f1 @/bin/sh ./dotest `awk "/^$@ / { print; } " test.format` -f15 f16 f17 f18 f20 f24: +f2: expected/f2 input/f2 regress/f2 + @/bin/sh ./dotest `awk "/^$@ / { print; } " test.format` + +f3: expected/f3 input/f3 regress/f3 + @/bin/sh ./dotest `awk "/^$@ / { print; } " test.format` + +f4: expected/f4 input/f4 regress/f4 + @/bin/sh ./dotest `awk "/^$@ / { print; } " test.format` + +f5: expected/f5 input/f5 regress/f5 + @/bin/sh ./dotest `awk "/^$@ / { print; } " test.format` + +f6: expected/f6 input/f6 regress/f6 + @/bin/sh ./dotest `awk "/^$@ / { print; } " test.format` + +f7: expected/f7 input/f7 regress/f7 + @/bin/sh ./dotest `awk "/^$@ / { print; } " test.format` + +f8: expected/f8 input/f8 regress/f8 + @/bin/sh ./dotest `awk "/^$@ / { print; } " test.format` + +f9: expected/f9 input/f9 regress/f9 + @/bin/sh ./dotest `awk "/^$@ / { print; } " test.format` + +f10: expected/f10 input/f10 regress/f10 + @/bin/sh ./dotest `awk "/^$@ / { print; } " test.format` + +f11: expected/f11 input/f11 regress/f11 + @/bin/sh ./dotest `awk "/^$@ / { print; } " test.format` + +f12: expected/f12 input/f12 regress/f12 + @/bin/sh ./dotest `awk "/^$@ / { print; } " test.format` + +f13: expected/f13 input/f13 regress/f13 + @/bin/sh ./dotest `awk "/^$@ / { print; } " test.format` + +f14: expected/f14 input/f14 regress/f14 + @/bin/sh ./dotest `awk "/^$@ / { print; } " test.format` + +f19: expected/f15 input/f15 regress/f15 + @/bin/sh ./dotest `awk "/^$@ / { print; } " test.format` + +f15: expected/f15 input/f15 regress/f15 @/bin/sh ./mtest `awk "/^$@ / { print; } " test.format` -i1 i2 i3 i4 i5 i6 i7 i8 i9 i10 i11 i12 i13 i14 i15 i16 i17 i18 i19 i20 i21 bpf1: +f16: expected/f16 input/f16 regress/f16 + @/bin/sh ./mtest `awk "/^$@ / { print; } " test.format` + +f17: expected/f17 input/f17 regress/f17 + @/bin/sh ./mtest `awk "/^$@ / { print; } " test.format` + +f18: expected/f18 input/f18 regress/f18 + @/bin/sh ./mtest `awk "/^$@ / { print; } " test.format` + +f20: expected/f20 input/f20 regress/f20 + @/bin/sh ./mtest `awk "/^$@ / { print; } " test.format` + +f21: expected/f21 input/f21 regress/f21 + @/bin/sh ./mtest `awk "/^$@ / { print; } " test.format` + +f22: expected/f22 input/f22 regress/f22 + @/bin/sh ./mtest `awk "/^$@ / { print; } " test.format` + +f24: expected/f24 input/f24 regress/f24 + @/bin/sh ./mtest `awk "/^$@ / { print; } " test.format` + +f25: expected/f25 input/f25 regress/f25 + @/bin/sh ./mtest `awk "/^$@ / { print; } " test.format` + +f26: expected/f26 input/f26 regress/f26 + @/bin/sh ./dotest `awk "/^$@ / { print; } " test.format` + +f27: expected/f27 input/f27 regress/f27 + @/bin/sh ./dotest `awk "/^$@ / { print; } " test.format` + +f28: expected/f28 input/f28 regress/f28.ipf regress/f28.pool $(POOLDEP) + @/bin/sh ./ptest `awk "/^$@ / { print; } " test.format` + +f29: expected/f29 input/f29 regress/f29.ipf regress/f29.pool $(POOLDEP) + @/bin/sh ./ptest `awk "/^$@ / { print; } " test.format` + +f30: expected/f30 input/f30 regress/f30 + @/bin/sh ./dotest `awk "/^$@ / { print; } " test.format` + +i1: expected/i1 regress/i1 @/bin/sh ./itest `awk "/^$@ / { print; } " test.format` -n1 n2 n3 n4 n5 n6 n7 n8 n9 n10 n11 n12 n13 n14 n16: +i2: expected/i2 regress/i2 + @/bin/sh ./itest `awk "/^$@ / { print; } " test.format` + +i3: expected/i3 regress/i3 + @/bin/sh ./itest `awk "/^$@ / { print; } " test.format` + +i4: expected/i4 regress/i4 + @/bin/sh ./itest `awk "/^$@ / { print; } " test.format` + +i5: expected/i5 regress/i5 + @/bin/sh ./itest `awk "/^$@ / { print; } " test.format` + +i6: expected/i6 regress/i6 + @/bin/sh ./itest `awk "/^$@ / { print; } " test.format` + +i7: expected/i7 regress/i7 + @/bin/sh ./itest `awk "/^$@ / { print; } " test.format` + +i8: expected/i8 regress/i8 + @/bin/sh ./itest `awk "/^$@ / { print; } " test.format` + +i9: expected/i9 regress/i9 + @/bin/sh ./itest `awk "/^$@ / { print; } " test.format` + +i10: expected/i10 regress/i10 + @/bin/sh ./itest `awk "/^$@ / { print; } " test.format` + +i11: expected/i11 regress/i11 + @/bin/sh ./itest `awk "/^$@ / { print; } " test.format` + +i12: expected/i12 regress/i12 + @/bin/sh ./itest `awk "/^$@ / { print; } " test.format` + +i13: expected/i13 regress/i13 + @/bin/sh ./itest `awk "/^$@ / { print; } " test.format` + +i14: expected/i14 regress/i14 + @/bin/sh ./itest `awk "/^$@ / { print; } " test.format` + +i15: expected/i15 regress/i15 + @/bin/sh ./itest `awk "/^$@ / { print; } " test.format` + +i16: expected/i16 regress/i16 + @/bin/sh ./itest `awk "/^$@ / { print; } " test.format` + +i17: expected/i17 regress/i17 + @/bin/sh ./itest `awk "/^$@ / { print; } " test.format` + +i18: expected/i18 regress/i18 + @/bin/sh ./itest `awk "/^$@ / { print; } " test.format` + +i19: expected/i19 regress/i19 + @/bin/sh ./itest `awk "/^$@ / { print; } " test.format` + +i20: expected/i20 regress/i20 + @/bin/sh ./itest `awk "/^$@ / { print; } " test.format` + +i21: expected/i21 regress/i21 + @/bin/sh ./itest `awk "/^$@ / { print; } " test.format` + +i22: expected/i22 regress/i22 + @/bin/sh ./itest `awk "/^$@ / { print; } " test.format` + +i23: expected/i23 regress/i23 + @/bin/sh ./itest `awk "/^$@ / { print; } " test.format` + +bpf1: expected/bpf1 regress/bpf1 + @/bin/sh ./itest `awk "/^$@ / { print; } " test.format` + +n1: expected/n1 regress/n1 input/n1 @/bin/sh ./nattest `awk "/^$@ / { print; } " test.format` -ni2 ni3 ni4 ni5 ni7 ni8 ni9 ni10 ni11 ni12 ni13 ni14 ni15 ni16 ni19 ni20: +n2: expected/n2 regress/n2 input/n2 + @/bin/sh ./nattest `awk "/^$@ / { print; } " test.format` + +n3: expected/n3 regress/n3 input/n3 + @/bin/sh ./nattest `awk "/^$@ / { print; } " test.format` + +n4: expected/n4 regress/n4 input/n4 + @/bin/sh ./nattest `awk "/^$@ / { print; } " test.format` + +n5: expected/n5 regress/n5 input/n5 + @/bin/sh ./nattest `awk "/^$@ / { print; } " test.format` + +n6: expected/n6 regress/n6 input/n6 + @/bin/sh ./nattest `awk "/^$@ / { print; } " test.format` + +n7: expected/n7 regress/n7 input/n7 + @/bin/sh ./nattest `awk "/^$@ / { print; } " test.format` + +n8: expected/n8 regress/n8 input/n8 + @/bin/sh ./nattest `awk "/^$@ / { print; } " test.format` + +n9: expected/n9 regress/n9 input/n9 + @/bin/sh ./nattest `awk "/^$@ / { print; } " test.format` + +n10: expected/n10 regress/n10 input/n10 + @/bin/sh ./nattest `awk "/^$@ / { print; } " test.format` + +n11: expected/n11 regress/n11 input/n11 + @/bin/sh ./nattest `awk "/^$@ / { print; } " test.format` + +n12: expected/n12 regress/n12 input/n12 + @/bin/sh ./nattest `awk "/^$@ / { print; } " test.format` + +n13: expected/n13 regress/n13 input/n13 + @/bin/sh ./nattest `awk "/^$@ / { print; } " test.format` + +n14: expected/n14 regress/n14 input/n14 + @/bin/sh ./nattest `awk "/^$@ / { print; } " test.format` + +n15: expected/n15 regress/n15 input/n15 + @/bin/sh ./nattest `awk "/^$@ / { print; } " test.format` + +n16: expected/n16 regress/n16 input/n16 + @/bin/sh ./nattest `awk "/^$@ / { print; } " test.format` + +n17: expected/n17 regress/n17 input/n17 + @/bin/sh ./nattest `awk "/^$@ / { print; } " test.format` + +n18: expected/n18 regress/n18 input/n18 + @/bin/sh ./nattest `awk "/^$@ / { print; } " test.format` + +n100: expected/n100 regress/n100 input/n100 + @/bin/sh ./nattest `awk "/^$@ / { print; } " test.format` + +n101: expected/n101 regress/n101 input/n101 + @/bin/sh ./nattest `awk "/^$@ / { print; } " test.format` + +n102: expected/n102 regress/n102 input/n102 + @/bin/sh ./nattest `awk "/^$@ / { print; } " test.format` + +n103: expected/n103 regress/n103 input/n103 + @/bin/sh ./nattest `awk "/^$@ / { print; } " test.format` + +n104: expected/n104 regress/n104 input/n104 + @/bin/sh ./nattest `awk "/^$@ / { print; } " test.format` + +n105: expected/n105 regress/n105 input/n105 + @/bin/sh ./nattest `awk "/^$@ / { print; } " test.format` + +n106: expected/n106 regress/n106 input/n106 + @/bin/sh ./nattest `awk "/^$@ / { print; } " test.format` + +n200: expected/n200 regress/n200 input/n200 + @/bin/sh ./nattest `awk "/^$@ / { print; } " test.format` + +n1_6: expected/n1_6 regress/n1_6 input/n1_6 + @/bin/sh ./nattest `awk "/^$@ / { print; } " test.format` + +n2_6: expected/n2_6 regress/n2_6 input/n2_6 + @/bin/sh ./nattest `awk "/^$@ / { print; } " test.format` + +n4_6: expected/n4_6 regress/n4_6 input/n4_6 + @/bin/sh ./nattest `awk "/^$@ / { print; } " test.format` + +n5_6: expected/n5_6 regress/n5_6 input/n5_6 + @/bin/sh ./nattest `awk "/^$@ / { print; } " test.format` + +n6_6: expected/n6_6 regress/n6_6 input/n6_6 + @/bin/sh ./nattest `awk "/^$@ / { print; } " test.format` + +n7_6: expected/n7_6 regress/n7_6 input/n7_6 + @/bin/sh ./nattest `awk "/^$@ / { print; } " test.format` + +n8_6: expected/n8_6 regress/n8_6 input/n8_6 + @/bin/sh ./nattest `awk "/^$@ / { print; } " test.format` + +n9_6: expected/n9_6 regress/n9_6 input/n9_6 + @/bin/sh ./nattest `awk "/^$@ / { print; } " test.format` + +n11_6: expected/n11_6 regress/n11_6 input/n11_6 + @/bin/sh ./nattest `awk "/^$@ / { print; } " test.format` + +n12_6: expected/n12_6 regress/n12_6 input/n12_6 + @/bin/sh ./nattest `awk "/^$@ / { print; } " test.format` + +n15_6: expected/n15_6 regress/n15_6 input/n15_6 + @/bin/sh ./nattest `awk "/^$@ / { print; } " test.format` + +ni2: expected/ni2 input/ni2 regress/ni2.nat regress/ni2.ipf @/bin/sh ./natipftest single `awk "/^$@ / { print; } " test.format` -ni1 ni6 ni21 ni23: +ni3: expected/ni3 input/ni3 regress/ni3.nat regress/ni3.ipf + @/bin/sh ./natipftest single `awk "/^$@ / { print; } " test.format` + +ni4: expected/ni4 input/ni4 regress/ni4.nat regress/ni4.ipf + @/bin/sh ./natipftest single `awk "/^$@ / { print; } " test.format` + +ni5: expected/ni5 input/ni5 regress/ni5.nat regress/ni5.ipf + @/bin/sh ./natipftest single `awk "/^$@ / { print; } " test.format` + +ni7: expected/ni7 input/ni7 regress/ni7.nat regress/ni7.ipf + @/bin/sh ./natipftest single `awk "/^$@ / { print; } " test.format` + +ni8: expected/ni8 input/ni8 regress/ni8.nat regress/ni8.ipf + @/bin/sh ./natipftest single `awk "/^$@ / { print; } " test.format` + +ni9: expected/ni9 input/ni9 regress/ni9.nat regress/ni9.ipf + @/bin/sh ./natipftest single `awk "/^$@ / { print; } " test.format` + +ni10: expected/ni10 input/ni10 regress/ni10.nat regress/ni10.ipf + @/bin/sh ./natipftest single `awk "/^$@ / { print; } " test.format` + +ni11: expected/ni11 input/ni11 regress/ni11.nat regress/ni11.ipf + @/bin/sh ./natipftest single `awk "/^$@ / { print; } " test.format` + +ni12: expected/ni12 input/ni12 regress/ni12.nat regress/ni12.ipf + @/bin/sh ./natipftest single `awk "/^$@ / { print; } " test.format` + +ni13: expected/ni13 input/ni13 regress/ni13.nat regress/ni13.ipf + @/bin/sh ./natipftest single `awk "/^$@ / { print; } " test.format` + +ni14: expected/ni14 input/ni14 regress/ni14.nat regress/ni14.ipf + @/bin/sh ./natipftest single `awk "/^$@ / { print; } " test.format` + +ni15: expected/ni15 input/ni15 regress/ni15.nat regress/ni15.ipf + @/bin/sh ./natipftest single `awk "/^$@ / { print; } " test.format` + +ni16: expected/ni16 input/ni16 regress/ni16.nat regress/ni16.ipf + @/bin/sh ./natipftest single `awk "/^$@ / { print; } " test.format` + +ni19: expected/ni19 input/ni19 regress/ni19.nat regress/ni19.ipf + @/bin/sh ./natipftest single `awk "/^$@ / { print; } " test.format` + +ni20: expected/ni20 input/ni20 regress/ni20.nat regress/ni20.ipf + @/bin/sh ./natipftest single `awk "/^$@ / { print; } " test.format` + +ni1: expected/ni1 input/ni1 regress/ni1.nat regress/ni1.ipf @/bin/sh ./natipftest multi `awk "/^$@ / { print; } " test.format` -in1 in2 in3 in4 in5 in6: +ni6: expected/ni6 input/ni6 regress/ni6.nat regress/ni6.ipf + @/bin/sh ./natipftest multi `awk "/^$@ / { print; } " test.format` + +ni17: expected/ni17 input/ni17 regress/ni17.nat regress/ni17.ipf + @/bin/sh ./natipftest multi `awk "/^$@ / { print; } " test.format` + +ni18: expected/ni18 input/ni18 regress/ni18.nat regress/ni18.ipf + @/bin/sh ./natipftest multi `awk "/^$@ / { print; } " test.format` + +ni21: expected/ni21 input/ni21 regress/ni21.nat regress/ni21.ipf + @/bin/sh ./natipftest multi `awk "/^$@ / { print; } " test.format` + +ni23: expected/ni23 input/ni23 regress/ni23.nat regress/ni23.ipf + @/bin/sh ./natipftest multi `awk "/^$@ / { print; } " test.format` + +in1: expected/in1 regress/in1 + @/bin/sh ./intest `awk "/^$@ / { print; } " test.format` + +in2: expected/in2 regress/in2 + @/bin/sh ./intest `awk "/^$@ / { print; } " test.format` + +in3: expected/in3 regress/in3 + @/bin/sh ./intest `awk "/^$@ / { print; } " test.format` + +in4: expected/in4 regress/in4 + @/bin/sh ./intest `awk "/^$@ / { print; } " test.format` + +in5: expected/in5 regress/in5 + @/bin/sh ./intest `awk "/^$@ / { print; } " test.format` + +in6: expected/in6 regress/in6 + @/bin/sh ./intest `awk "/^$@ / { print; } " test.format` + +in7: expected/in7 regress/in7 + @/bin/sh ./intest `awk "/^$@ / { print; } " test.format` + +in8: expected/in8 regress/in8 + @/bin/sh ./intest `awk "/^$@ / { print; } " test.format` + +in100: expected/in100 regress/in100 + @/bin/sh ./intest `awk "/^$@ / { print; } " test.format` + +in101: expected/in101 regress/in101 + @/bin/sh ./intest `awk "/^$@ / { print; } " test.format` + +in102: expected/in102 regress/in102 @/bin/sh ./intest `awk "/^$@ / { print; } " test.format` l1: @/bin/sh ./logtest `awk "/^$@ / { print; } " test.format` -ipv6.1 ipv6.2 ipv6.3 ipv6.5 ipv6.6: +ipv6.1: expected/ipv6.1 input/ipv6.1 regress/ipv6.1 @/bin/sh ./dotest6 `awk "/^$@ / { print; } " test.format` -p1 p2 p3 p5: +ipv6.2: expected/ipv6.2 input/ipv6.2 regress/ipv6.2 + @/bin/sh ./dotest6 `awk "/^$@ / { print; } " test.format` + +ipv6.3: expected/ipv6.3 input/ipv6.3 regress/ipv6.3 + @/bin/sh ./dotest6 `awk "/^$@ / { print; } " test.format` + +ipv6.4: expected/ipv6.4 input/ipv6.4 regress/ipv6.4 + @/bin/sh ./dotest6 `awk "/^$@ / { print; } " test.format` + +ipv6.5: expected/ipv6.5 input/ipv6.5 regress/ipv6.5 + @/bin/sh ./dotest6 `awk "/^$@ / { print; } " test.format` + +ipv6.6: expected/ipv6.6 input/ipv6.6 regress/ipv6.6 + @/bin/sh ./dotest6 `awk "/^$@ / { print; } " test.format` + +p1: expected/p1 input/p1 regress/p1.ipf regress/p1.pool $(POOLDEP) @/bin/sh ./ptest `awk "/^$@ / { print; } " test.format` -ip1 ip2: +p2: expected/p2 input/p2 regress/p2.ipf $(POOLDEP) + @/bin/sh ./ptest `awk "/^$@ / { print; } " test.format` + +p3: expected/p3 input/p3 regress/p3.ipf regress/p3.pool $(POOLDEP) + @/bin/sh ./ptest `awk "/^$@ / { print; } " test.format` + +p4: expected/p4 input/p4 regress/p4.nat regress/p4.pool $(POOLDEP) + @/bin/sh ./ptest `awk "/^$@ / { print; } " test.format` + +p5: expected/p5 input/p5 regress/p5.ipf regress/p5.pool $(POOLDEP) + @/bin/sh ./ptest `awk "/^$@ / { print; } " test.format` + +p6: expected/p6 input/p6 regress/p6.ipf regress/p6.pool $(POOLDEP) + @/bin/sh ./ptest `awk "/^$@ / { print; } " test.format` + +p7: expected/p7 input/p7 regress/p7.nat regress/p7.pool $(POOLDEP) + @/bin/sh ./ptest `awk "/^$@ / { print; } " test.format` + +p9: expected/p9 input/p9 regress/p9.nat regress/p9.pool $(POOLDEP) + @/bin/sh ./ptest `awk "/^$@ / { print; } " test.format` + +p10: expected/p10 input/p10 regress/p10.nat regress/p10.pool $(POOLDEP) + @/bin/sh ./ptest `awk "/^$@ / { print; } " test.format` + +p11: expected/p11 input/p11 regress/p11.nat regress/p11.pool $(POOLDEP) + @/bin/sh ./ptest `awk "/^$@ / { print; } " test.format` + +p12: expected/p12 input/p12 regress/p12.nat regress/p12.pool $(POOLDEP) + @/bin/sh ./ptest `awk "/^$@ / { print; } " test.format` + +p13: expected/p13 input/p13 regress/p13.ipf regress/p13.pool $(POOLDEP) + @/bin/sh ./ptest `awk "/^$@ / { print; } " test.format` + +ip1: expected/ip1 regress/ip1 $(POOLDEP) @/bin/sh ./iptest `awk "/^$@ / { print; } " test.format` -bpf-f1: +ip2: expected/ip2 input/ip2.data regress/ip2 $(POOLDEP) + @/bin/sh ./iptest `awk "/^$@ / { print; } " test.format` + +ip3: expected/ip3 regress/ip3 $(POOLDEP) + @/bin/sh ./iptest `awk "/^$@ / { print; } " test.format` + +bpf-f1: expected/bpf-f1 regress/bpf-f1 /bin/sh ./bpftest `awk "/^$@ / { print; } " test.format` clean: - /bin/rm -f f1 f2 f3 f4 f5 f6 f7 f8 f9 f10 f11 f12 f13 f14 f15 f16 f17 f18 f19 f20 f24 - /bin/rm -f i1 i2 i3 i4 i5 i6 i7 i8 i9 i10 i11 i12 i13 i14 i15 i16 i17 i18 i19 i20 i21 - /bin/rm -f n1 n2 n3 n4 n5 n6 n7 n8 n9 n10 n11 n12 n13 n14 n16 + /bin/rm -f f1 f2 f3 f4 f5 f6 f7 f8 f9 f10 f11 f12 f13 f14 f15 f16 f17 + /bin/rm -f f18 f19 f20 f21 f22 f24 f25 f26 f27 f28 f29 + /bin/rm -f i1 i2 i3 i4 i5 i6 i7 i8 i9 i10 i11 i12 i13 i14 i15 i16 i17 + /bin/rm -f i18 i19 i20 i21 i22 i23 + /bin/rm -f n1 n2 n3 n4 n5 n6 n7 n8 n9 n10 n11 n12 n13 n14 n15 n16 n17 n18 n100 n101 n102 n103 n104 n105 n106 n200 + /bin/rm -f n1_6 n2_6 n4_6 n5_6 n6_6 n7_6 n8_6 n9_6 n11_6 n12_6 n15_6 /bin/rm -f ni1 ni2 ni3 ni4 ni5 ni6 ni7 ni8 ni9 - /bin/rm -f ni10 ni11 ni12 ni13 ni14 ni15 ni16 ni19 ni20 ni21 ni23 - /bin/rm -f in1 in2 in3 in4 in5 in6 - /bin/rm -f p1 p2 p3 p5 ip1 ip2 + /bin/rm -f ni10 ni11 ni12 ni13 ni14 ni15 ni16 ni17 ni18 ni19 ni20 ni21 ni23 + /bin/rm -f in1 in2 in3 in4 in5 in6 in7 in100 in101 in102 + /bin/rm -f p1 p2 p3 p4 p5 p6 p7 p9 p10 p11 p12 p13 ip1 ip2 ip3 /bin/rm -f l1 - /bin/rm -f ipv6.1 ipv6.2 ipv6.3 ipv6.5 ipv6.6 + /bin/rm -f ipv6.1 ipv6.2 ipv6.3 ipv6.4 ipv6.5 ipv6.6 /bin/rm -f bpf1 bpf-f1 /bin/rm -f results/* logout (cd expected; make clean) diffs: -cd expected; for i in *; do if [ -f $$i -a ! -f ../$$i -a -f ../results/$$i ] ; then diff -c $$i ../results/$$i >> ../diff.out; fi done + +n6s: + for i in 1 2 4 5 6 7 11 13 14 15; do \ + sh i4to6 < input/n$${i} > input/n$${i}_6; \ + sh e4to6 < regress/n$${i} > regress/n$${i}_6; \ + sh e4to6 < expected/n$${i} > expected/n$${i}_6; \ + done + for i in 8 9 10 12 17; do \ + sh e4to6 < regress/n$${i} > regress/n$${i}_6; \ + perl h4to6 < input/n$${i} > input/n$${i}_6; \ + done diff --git a/contrib/ipfilter/test/bpftest b/contrib/ipfilter/test/bpftest index b24c0f16ae49..5449658f820e 100644 --- a/contrib/ipfilter/test/bpftest +++ b/contrib/ipfilter/test/bpftest @@ -1,28 +1,19 @@ #!/bin/sh -if [ -f /usr/ucb/touch ] ; then - TOUCH=/usr/ucb/touch -else - if [ -f /usr/bin/touch ] ; then - TOUCH=/usr/bin/touch - else - if [ -f /bin/touch ] ; then - TOUCH=/bin/touch - fi - fi -fi -echo "$1..."; -input=`expr $1 : 'bpf-\(.*\)'` -/bin/cp /dev/null results/$1 +name=$1 + +. ./ipflib.sh + +test_init + +echo "$name..."; +input=`expr $name : 'bpf-\(.*\)'` +/bin/cp /dev/null results/$name ( while read rule; do - echo "$rule" | ../ipftest -Rbr - -i input/$input >> results/$1; + echo "$rule" | ../ipftest -Rbr - -i input/$input >> results/$name if [ $? -ne 0 ] ; then exit 1; fi - echo "--------" >> results/$1 -done ) < regress/$1 -cmp expected/$1 results/$1 -status=$? -if [ $status = 0 ] ; then - $TOUCH $1 -fi + echo "--------" >> results/$name +done ) < regress/$name +check_results $name exit $status diff --git a/contrib/ipfilter/test/dotest b/contrib/ipfilter/test/dotest index 29891091da59..71c09b7b816e 100644 --- a/contrib/ipfilter/test/dotest +++ b/contrib/ipfilter/test/dotest @@ -1,19 +1,13 @@ #!/bin/sh -thistest=$1 +name=$1 format=$2 output=$3 tuning=$4 -if [ -f /usr/ucb/touch ] ; then - TOUCH=/usr/ucb/touch -else - if [ -f /usr/bin/touch ] ; then - TOUCH=/usr/bin/touch - else - if [ -f /bin/touch ] ; then - TOUCH=/bin/touch - fi - fi -fi + +. ./ipflib.sh + +test_init + if [ "$tuning" != "" ] ; then case $tuning in -*) @@ -23,18 +17,17 @@ if [ "$tuning" != "" ] ; then ;; esac fi -echo "${thistest}..."; -/bin/cp /dev/null results/${thistest} +echo "${name}..."; +n=1 +/bin/cp /dev/null results/${name} ( while read rule; do - echo "$rule" | ../ipftest -F $format -Rbr - -i input/${thistest} $tuning>> results/${thistest}; - if [ $? -ne 0 ] ; then - exit 1; - fi - echo "--------" >> results/${thistest} -done ) < regress/${thistest} -cmp expected/${thistest} results/${thistest} -status=$? -if [ $status = 0 ] ; then - $TOUCH ${thistest} -fi + set_core $name $n + echo "$rule" | ../ipftest -F $format -Rbr - -i input/${name} $tuning>> results/${name} & + back=$! + wait $back + test_end_leak $? + n=`expr $n + 1` + echo "--------" >> results/${name} +done ) < regress/${name} +check_results $name exit $status diff --git a/contrib/ipfilter/test/e4to6 b/contrib/ipfilter/test/e4to6 new file mode 100644 index 000000000000..87558993b133 --- /dev/null +++ b/contrib/ipfilter/test/e4to6 @@ -0,0 +1,61 @@ +sed \ +-e 's/192.168.126.0/c0a8:7e00::/' \ +-e 's/\/32/\/128/g' \ +-e 's/\/24/\/112/g' \ +-e 's/\/16/\/32/g' \ +-e 's/10\.2\.0\.0/10::2:0:0/g' \ +-e 's/1\.\([0-9]\)\.\([0-9]\)\.\([0-9]\)/1:0:0:0:0:\1:\2:\3/g' \ +-e 's/2\.\([0-9]\)\.\([0-9]\)\.\([0-9]\)/2:0:0:0:0:\1:\2:\3/g' \ +-e 's/4\.\([0-9]\)\.\([0-9]\)\.\([0-9]\)/4:\1:\2:0:0:0:0:\3/g' \ +-e 's/3\.\([0-9]\)\.\([0-9]\)\.\([0-9]\)/3:0:\1:0:0:0:\2:\3/g' \ +-e 's/5\.\([0-9]\)\.\([0-9]\)\.\([0-9]\)/5:\1:0:0:0:0:\2:\3/g' \ +-e 's/9\.\([0-9]\)\.\([0-9]\)\.\([0-9]\)/9:\1:\2:0:0:0:0:\3/g' \ +-e 's/10\.1\.\([0-9]\)\.\([0-9]\)/10:1:\1:0:0:0:0:\2/g' \ +-e 's/10\.10\.\([0-9]*\)\.\([0-9]\)/10:10:\1:0:0:0:0:\2/g' \ +-e 's/10\.2\.\([0-9]\)\.\([0-9]\)/10:0:0:0:0:2:\1:\2/g' \ +-e 's/10\.4\.3\.\([0-9]\)/10:4:3:0:0:0:0:\1/g' \ +-e 's/10\.3\.4\.\([0-9]\)/10:0:0:0:0:3:4:\1/g' \ +-e 's/10\.3\.\([0-9]\)\.\([0-9]\)/10:3:\1:0:0:0:0:\2/g' \ +-e 's/0\.0\.0\.0/any/g' \ +-e 's/ 0\/0 / any /g' \ +-e 's/ip #0/ip6\/0/' \ +-e 's/40(20) 6 /20 0 6 /' \ +-e 's/28(20) 17 /8 0 17 /' \ +-e 's/20(20) 0 /1 0 41 /' \ +-e 's/48(20) 1 /88 0 58 /g' \ +-e 's/20(20) 34 /1 0 34 /g' \ +-e 's/20(20) 35 /1 0 35 /g' \ +-e 's/20(20) 255 /1 0 255 /g' \ +-e 's/ */ /g' | sed \ +-e '/use/s/:0:0:0:0:/::/g' \ +-e '/map/s/:0:0:0:0:/::/g' \ +-e '/rdr/s/:0:0:0:0:/::/g' \ +-e '/map/s/:0:0:0:/::/g' \ +-e '/rdr/s/:0:0:0:/::/g' \ +-e '/MAP/s/:0:0:0:0:0:/::/g' \ +-e '/RDR/s/:0:0:0:0:0:/::/g' \ +-e '/MAP/s/:0:0:0:0:/::/g' \ +-e '/RDR/s/:0:0:0:0:/::/g' \ +-e '/MAP/s/:0:0:0:/::/g' \ +-e '/RDR/s/:0:0:0:/::/g' \ +| sed \ +-e '/MAP/s/ \([0-9][0-9][0-9][0-9]\) / \1 /g' \ +-e '/MAP/s/ \([0-9][0-9][0-9]\) / \1 /g' \ +-e '/MAP/s/ \([0-9][0-9]\) / \1 /g' \ +-e '/RDR/s/ \([0-9][0-9][0-9][0-9]\) / \1 /g' \ +-e '/RDR/s/ \([0-9][0-9][0-9]\) / \1 /g' \ +-e '/RDR/s/ \([0-9][0-9]\) / \1 /g' \ +-e 's/::0:0\//::\//g' \ +-e 's/:0:0\//::\//g' \ +-e 's/::0\([^:0-9]\)/::\1/g' \ +-e 's/::0,/::,/g' \ +-e 's/::0:0 \([^>]\)/:: \1/g' \ +-e 's/:0:0 \([^>]\)/:: \1/g' \ +-e 's/::0 \([^>]\)/:: \1/g' \ +| sed \ +-e 's@::\([0-9]*\)::/16@::/16@g' \ +-e 's@::\([0-9]*\)::/32@::/32@g' \ +-e 's@::\([0-9]*\)::@::\1:0:0@g' \ +-e 's@::\([0-9]*\)::@::\1:0:0@g' \ +-e 's@::[:0-9]*\([^0-9:]\)/16@::/16@g' \ +-e 's@::[:0-9]*\([^0-9:]\)/32@::/32@g' diff --git a/contrib/ipfilter/test/expected/f11 b/contrib/ipfilter/test/expected/f11 index c1eb060a7126..d7ab889dacdc 100644 --- a/contrib/ipfilter/test/expected/f11 +++ b/contrib/ipfilter/test/expected/f11 @@ -24,6 +24,15 @@ List of configured pools List of configured hash tables List of groups configured (set 0) List of groups configured (set 1) +Rules configured (set 0, in) +1 pass in proto tcp from any to any port = 23 flags S/SA keep state +Rules configured (set 0, out) +Rules configured (set 1, in) +Rules configured (set 1, out) +Accounting rules configured (set 0, in) +Accounting rules configured (set 0, out) +Accounting rules configured (set 1, in) +Accounting rules configured (set 1, out) -------- block nomatch @@ -51,6 +60,15 @@ List of configured pools List of configured hash tables List of groups configured (set 0) List of groups configured (set 1) +Rules configured (set 0, in) +1 block in proto tcp from any to any port = 23 flags S/SA keep state +Rules configured (set 0, out) +Rules configured (set 1, in) +Rules configured (set 1, out) +Accounting rules configured (set 0, in) +Accounting rules configured (set 0, out) +Accounting rules configured (set 1, in) +Accounting rules configured (set 1, out) -------- nomatch nomatch @@ -78,6 +96,15 @@ List of configured pools List of configured hash tables List of groups configured (set 0) List of groups configured (set 1) +Rules configured (set 0, in) +2 pass in proto udp from any to any port = 53 keep frags +Rules configured (set 0, out) +Rules configured (set 1, in) +Rules configured (set 1, out) +Accounting rules configured (set 0, in) +Accounting rules configured (set 0, out) +Accounting rules configured (set 1, in) +Accounting rules configured (set 1, out) -------- nomatch nomatch @@ -105,6 +132,15 @@ List of configured pools List of configured hash tables List of groups configured (set 0) List of groups configured (set 1) +Rules configured (set 0, in) +2 block in proto udp from any to any port = 53 keep frags +Rules configured (set 0, out) +Rules configured (set 1, in) +Rules configured (set 1, out) +Accounting rules configured (set 0, in) +Accounting rules configured (set 0, out) +Accounting rules configured (set 1, in) +Accounting rules configured (set 1, out) -------- nomatch nomatch @@ -128,30 +164,31 @@ List of active sessions: Hostmap table: List of active state sessions: -2.2.2.2 -> 4.4.4.4 pass 0x40008402 pr 17 state 0/0 - tag 0 ttl 240 2 -> 53 - forward: pkts in 1 bytes in 28 pkts out 0 bytes out 0 - backward: pkts in 0 bytes in 0 pkts out 0 bytes out 0 - pass in keep state IPv4 - pkt_flags & 0(0) = 0, pkt_options & ffffffff = 0, ffffffff = 0 - pkt_security & ffff = 0, pkt_auth & ffff = 0 - is_flx 0x8001 0 0 0 +4:udp src:2.2.2.2,2 dst:4.4.4.4,53 240 + FWD: IN pkts 1 bytes 28 OUT pkts 0 bytes 0 + REV: IN pkts 0 bytes 0 OUT pkts 0 bytes 0 + tag 0 pass 0x2008402 = pass in keep state interfaces: in X[e1],X[] out X[],X[] Sync status: not synchronized -1.1.1.1 -> 4.4.4.4 pass 0x40008402 pr 17 state 0/0 - tag 0 ttl 24 1 -> 53 - forward: pkts in 1 bytes in 28 pkts out 0 bytes out 0 - backward: pkts in 1 bytes in 28 pkts out 0 bytes out 0 - pass in keep state IPv4 - pkt_flags & 0(0) = 0, pkt_options & ffffffff = 0, ffffffff = 0 - pkt_security & ffff = 0, pkt_auth & ffff = 0 - is_flx 0x8001 0x8001 0 0 +4:udp src:1.1.1.1,1 dst:4.4.4.4,53 24 + FWD: IN pkts 1 bytes 28 OUT pkts 0 bytes 0 + REV: IN pkts 1 bytes 28 OUT pkts 0 bytes 0 + tag 0 pass 0x2008402 = pass in keep state interfaces: in X[e1],X[e0] out X[],X[] Sync status: not synchronized List of configured pools List of configured hash tables List of groups configured (set 0) List of groups configured (set 1) +Rules configured (set 0, in) +2 pass in proto udp from any to any port = 53 keep state +Rules configured (set 0, out) +Rules configured (set 1, in) +Rules configured (set 1, out) +Accounting rules configured (set 0, in) +Accounting rules configured (set 0, out) +Accounting rules configured (set 1, in) +Accounting rules configured (set 1, out) -------- nomatch nomatch @@ -175,30 +212,31 @@ List of active sessions: Hostmap table: List of active state sessions: -2.2.2.2 -> 4.4.4.4 pass 0x40008401 pr 17 state 0/0 - tag 0 ttl 240 2 -> 53 - forward: pkts in 1 bytes in 28 pkts out 0 bytes out 0 - backward: pkts in 0 bytes in 0 pkts out 0 bytes out 0 - block in keep state IPv4 - pkt_flags & 0(0) = 0, pkt_options & ffffffff = 0, ffffffff = 0 - pkt_security & ffff = 0, pkt_auth & ffff = 0 - is_flx 0x8001 0 0 0 +4:udp src:2.2.2.2,2 dst:4.4.4.4,53 240 + FWD: IN pkts 1 bytes 28 OUT pkts 0 bytes 0 + REV: IN pkts 0 bytes 0 OUT pkts 0 bytes 0 + tag 0 pass 0x2008401 = block in keep state interfaces: in X[e1],X[] out X[],X[] Sync status: not synchronized -1.1.1.1 -> 4.4.4.4 pass 0x40008401 pr 17 state 0/0 - tag 0 ttl 24 1 -> 53 - forward: pkts in 1 bytes in 28 pkts out 0 bytes out 0 - backward: pkts in 1 bytes in 28 pkts out 0 bytes out 0 - block in keep state IPv4 - pkt_flags & 0(0) = 0, pkt_options & ffffffff = 0, ffffffff = 0 - pkt_security & ffff = 0, pkt_auth & ffff = 0 - is_flx 0x8001 0x8001 0 0 +4:udp src:1.1.1.1,1 dst:4.4.4.4,53 24 + FWD: IN pkts 1 bytes 28 OUT pkts 0 bytes 0 + REV: IN pkts 1 bytes 28 OUT pkts 0 bytes 0 + tag 0 pass 0x2008401 = block in keep state interfaces: in X[e1],X[e0] out X[],X[] Sync status: not synchronized List of configured pools List of configured hash tables List of groups configured (set 0) List of groups configured (set 1) +Rules configured (set 0, in) +2 block in proto udp from any to any port = 53 keep state +Rules configured (set 0, out) +Rules configured (set 1, in) +Rules configured (set 1, out) +Accounting rules configured (set 0, in) +Accounting rules configured (set 0, out) +Accounting rules configured (set 1, in) +Accounting rules configured (set 1, out) -------- nomatch nomatch @@ -222,22 +260,24 @@ List of active sessions: Hostmap table: List of active state sessions: -1.1.1.1 -> 2.1.2.2 pass 0x40008402 pr 6 state 3/4 - tag 0 ttl 864000 - 1 -> 25 2:66 4096<<0:16384<<0 - cmsk 0000 smsk 0000 s0 00000000/00000000 - FWD:ISN inc 0 sumd 0 - REV:ISN inc 0 sumd 0 - forward: pkts in 1 bytes in 40 pkts out 0 bytes out 0 - backward: pkts in 1 bytes in 40 pkts out 0 bytes out 0 - pass in keep state IPv4 - pkt_flags & 0(0) = 0, pkt_options & ffffffff = 0, ffffffff = 0 - pkt_security & ffff = 0, pkt_auth & ffff = 0 - is_flx 0x8001 0x8001 0 0 +4:tcp src:1.1.1.1,1 dst:2.1.2.2,25 state:3/4 864000 + 2:66 4096<<0:16384<<0 + FWD: IN pkts 1 bytes 40 OUT pkts 0 bytes 0 + REV: IN pkts 1 bytes 40 OUT pkts 0 bytes 0 + tag 0 pass 0x2008402 = pass in keep state interfaces: in X[e0],X[e1] out X[],X[] Sync status: not synchronized List of configured pools List of configured hash tables List of groups configured (set 0) List of groups configured (set 1) +Rules configured (set 0, in) +1 pass in on e0 proto tcp from any to any port = 25 keep state +Rules configured (set 0, out) +Rules configured (set 1, in) +Rules configured (set 1, out) +Accounting rules configured (set 0, in) +Accounting rules configured (set 0, out) +Accounting rules configured (set 1, in) +Accounting rules configured (set 1, out) -------- diff --git a/contrib/ipfilter/test/expected/f13 b/contrib/ipfilter/test/expected/f13 index 99c05651cea6..ac7947bd2922 100644 --- a/contrib/ipfilter/test/expected/f13 +++ b/contrib/ipfilter/test/expected/f13 @@ -154,7 +154,27 @@ nomatch nomatch nomatch pass +block +block +pass +-------- +block +bad-packet +nomatch +pass +bad-packet +nomatch +nomatch +bad-packet +nomatch +bad-packet +nomatch +nomatch +nomatch nomatch nomatch pass +pass +pass +pass -------- diff --git a/contrib/ipfilter/test/expected/f18 b/contrib/ipfilter/test/expected/f18 index 801abd369426..1af5de53cd05 100644 --- a/contrib/ipfilter/test/expected/f18 +++ b/contrib/ipfilter/test/expected/f18 @@ -2,4 +2,26 @@ pass pass pass pass +List of active MAP/Redirect filters: + +List of active sessions: + +Hostmap table: +List of active state sessions: +List of configured pools +List of configured hash tables +List of groups configured (set 0) +List of groups configured (set 1) +Rules configured (set 0, in) +2 pass in inet from 1.1.1.1/32 to any +Rules configured (set 0, out) +2 pass out inet from 2.2.2.2/32 to any +Rules configured (set 1, in) +Rules configured (set 1, out) +Accounting rules configured (set 0, in) +1 count in inet from 1.1.1.1/32 to 3.3.3.3/32 +Accounting rules configured (set 0, out) +Accounting rules configured (set 1, in) +1 count out inet from 2.2.2.2/32 to 4.4.4.4/32 +Accounting rules configured (set 1, out) -------- diff --git a/contrib/ipfilter/test/expected/f21 b/contrib/ipfilter/test/expected/f21 new file mode 100644 index 000000000000..525dacaae720 --- /dev/null +++ b/contrib/ipfilter/test/expected/f21 @@ -0,0 +1,5 @@ +pass +pass +nomatch +nomatch +-------- diff --git a/contrib/ipfilter/test/expected/f22 b/contrib/ipfilter/test/expected/f22 new file mode 100644 index 000000000000..525dacaae720 --- /dev/null +++ b/contrib/ipfilter/test/expected/f22 @@ -0,0 +1,5 @@ +pass +pass +nomatch +nomatch +-------- diff --git a/contrib/ipfilter/test/expected/f25 b/contrib/ipfilter/test/expected/f25 new file mode 100644 index 000000000000..a87b084cdadd --- /dev/null +++ b/contrib/ipfilter/test/expected/f25 @@ -0,0 +1,35 @@ +pass +pass +pass +List of active MAP/Redirect filters: + +List of active sessions: + +Hostmap table: +List of active state sessions: +4:udp src:192.168.1.235,8008 dst:239.255.255.250,1900 240 + FWD: IN pkts 1 bytes 129 OUT pkts 0 bytes 0 + REV: IN pkts 0 bytes 0 OUT pkts 0 bytes 0 + tag 0 pass 0x2008402 = pass in keep state + interfaces: in X[hme0],X[] out X[],X[] + Sync status: not synchronized +4:udp src:192.168.1.235,8008 dst:192.168.1.254,1900 24 + FWD: IN pkts 1 bytes 129 OUT pkts 0 bytes 0 + REV: IN pkts 0 bytes 0 OUT pkts 1 bytes 264 + tag 0 pass 0x2008402 = pass in keep state + interfaces: in X[hme0],X[] out X[],X[hme0] + Sync status: not synchronized +List of configured pools +List of configured hash tables +List of groups configured (set 0) +List of groups configured (set 1) +Rules configured (set 0, in) +2 pass in on hme0 proto udp from any to any with mcast keep state +Rules configured (set 0, out) +Rules configured (set 1, in) +Rules configured (set 1, out) +Accounting rules configured (set 0, in) +Accounting rules configured (set 0, out) +Accounting rules configured (set 1, in) +Accounting rules configured (set 1, out) +-------- diff --git a/contrib/ipfilter/test/expected/f26 b/contrib/ipfilter/test/expected/f26 new file mode 100644 index 000000000000..9e4d62b51730 --- /dev/null +++ b/contrib/ipfilter/test/expected/f26 @@ -0,0 +1,84 @@ +pass +pass +pass +pass +pass +pass +nomatch +pass +pass +nomatch +pass +pass +nomatch +-------- +pass +nomatch +nomatch +nomatch +pass +pass +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +-------- +pass +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +-------- +pass +pass +pass +pass +pass +pass +nomatch +pass +pass +nomatch +pass +pass +nomatch +-------- +pass +nomatch +nomatch +nomatch +pass +pass +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +-------- +pass +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +-------- diff --git a/contrib/ipfilter/test/expected/f27 b/contrib/ipfilter/test/expected/f27 new file mode 100644 index 000000000000..c62f588e8b93 --- /dev/null +++ b/contrib/ipfilter/test/expected/f27 @@ -0,0 +1,90 @@ +pass +pass +pass +pass +pass +pass +nomatch +pass +pass +nomatch +pass +pass +nomatch +nomatch +-------- +pass +nomatch +nomatch +nomatch +pass +pass +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +-------- +pass +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +-------- +pass +pass +pass +pass +pass +pass +nomatch +pass +pass +nomatch +pass +pass +nomatch +nomatch +-------- +pass +nomatch +nomatch +nomatch +pass +pass +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +-------- +pass +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +pass +-------- diff --git a/contrib/ipfilter/test/expected/f28 b/contrib/ipfilter/test/expected/f28 new file mode 100644 index 000000000000..e5867e690103 --- /dev/null +++ b/contrib/ipfilter/test/expected/f28 @@ -0,0 +1,32 @@ +block +block +block +> nic0 ip #0 20(20) 0 4.4.3.1 > 4.2.3.2 +pass +> nic1 ip #0 20(20) 0 4.4.1.1 > 4.2.1.2 +pass +> nic2 ip #0 20(20) 0 4.4.2.1 > 4.2.2.2 +pass +> nic3 ip #0 20(20) 0 4.4.3.1 > 4.2.3.2 +pass +List of active MAP/Redirect filters: + +List of active sessions: + +Hostmap table: +List of active state sessions: +List of configured pools +List of configured hash tables +List of groups configured (set 0) +List of groups configured (set 1) +Rules configured (set 0, in) +7 block in all +4 pass in on nic0 to dstlist/spread inet from 4.4.0.0/16 to any +Rules configured (set 0, out) +Rules configured (set 1, in) +Rules configured (set 1, out) +Accounting rules configured (set 0, in) +Accounting rules configured (set 0, out) +Accounting rules configured (set 1, in) +Accounting rules configured (set 1, out) +------------------------------- diff --git a/contrib/ipfilter/test/expected/f29 b/contrib/ipfilter/test/expected/f29 new file mode 100644 index 000000000000..a650c1b45289 --- /dev/null +++ b/contrib/ipfilter/test/expected/f29 @@ -0,0 +1,64 @@ +block +block +block +> nic0 ip #0 28(20) 17 4.4.3.1,1000 > 4.2.3.2,2000 +pass +> nic0 ip #0 28(20) 17 4.4.3.1,1000 > 4.2.3.2,2000 +pass +> nic1 ip #0 28(20) 17 4.4.1.1,1001 > 4.2.1.2,2001 +pass +> nic1 ip #0 28(20) 17 4.4.1.1,1001 > 4.2.1.2,2001 +pass +> nic2 ip #0 28(20) 17 4.4.2.1,1002 > 4.2.2.2,2002 +pass +> nic2 ip #0 28(20) 17 4.4.2.1,1002 > 4.2.2.2,2002 +pass +> nic3 ip #0 28(20) 17 4.4.3.1,1003 > 4.2.3.2,2003 +pass +> nic3 ip #0 28(20) 17 4.4.3.1,1003 > 4.2.3.2,2003 +pass +List of active MAP/Redirect filters: + +List of active sessions: + +Hostmap table: +List of active state sessions: +4:udp src:4.4.3.1,1003 dst:4.2.3.2,2003 240 + FWD: IN pkts 2 bytes 56 OUT pkts 2 bytes 56 + REV: IN pkts 0 bytes 0 OUT pkts 0 bytes 0 + tag 0 pass 0x2008402 = pass in keep state + interfaces: in X[nic0],X[] out X[nic3],X[] + Sync status: not synchronized +4:udp src:4.4.2.1,1002 dst:4.2.2.2,2002 240 + FWD: IN pkts 2 bytes 56 OUT pkts 2 bytes 56 + REV: IN pkts 0 bytes 0 OUT pkts 0 bytes 0 + tag 0 pass 0x2008402 = pass in keep state + interfaces: in X[nic0],X[] out X[nic2],X[] + Sync status: not synchronized +4:udp src:4.4.1.1,1001 dst:4.2.1.2,2001 240 + FWD: IN pkts 2 bytes 56 OUT pkts 2 bytes 56 + REV: IN pkts 0 bytes 0 OUT pkts 0 bytes 0 + tag 0 pass 0x2008402 = pass in keep state + interfaces: in X[nic0],X[] out X[nic1],X[] + Sync status: not synchronized +4:udp src:4.4.3.1,1000 dst:4.2.3.2,2000 240 + FWD: IN pkts 2 bytes 56 OUT pkts 2 bytes 56 + REV: IN pkts 0 bytes 0 OUT pkts 0 bytes 0 + tag 0 pass 0x2008402 = pass in keep state + interfaces: in X[nic0],X[] out X[nic0],X[] + Sync status: not synchronized +List of configured pools +List of configured hash tables +List of groups configured (set 0) +List of groups configured (set 1) +Rules configured (set 0, in) +7 block in all +4 pass in on nic0 to dstlist/spread inet from 4.4.0.0/16 to any keep state +Rules configured (set 0, out) +Rules configured (set 1, in) +Rules configured (set 1, out) +Accounting rules configured (set 0, in) +Accounting rules configured (set 0, out) +Accounting rules configured (set 1, in) +Accounting rules configured (set 1, out) +------------------------------- diff --git a/contrib/ipfilter/test/expected/f30 b/contrib/ipfilter/test/expected/f30 new file mode 100644 index 000000000000..30b9d405d0ae --- /dev/null +++ b/contrib/ipfilter/test/expected/f30 @@ -0,0 +1,68 @@ +nomatch +nomatch +nomatch +pass +pass +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +-------- +pass +pass +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +-------- +nomatch +nomatch +nomatch +nomatch +nomatch +pass +nomatch +pass +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +-------- +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +pass +nomatch +nomatch +pass +nomatch +nomatch +-------- diff --git a/contrib/ipfilter/test/expected/i1 b/contrib/ipfilter/test/expected/i1 index 74d0f309b616..19ae393e58e0 100644 --- a/contrib/ipfilter/test/expected/i1 +++ b/contrib/ipfilter/test/expected/i1 @@ -5,8 +5,8 @@ log body in all count in from any to any pass in from !any to any pps 10 block in from any to !any -pass in on ed0(!) from 127.0.0.1/32 to 127.0.0.1/32 -pass in on ed0(!),vx0(!) from 127.0.0.1/32 to 127.0.0.1/32 +pass in on ed0(!) inet from 127.0.0.1/32 to 127.0.0.1/32 +pass in on ed0(!),vx0(!) inet from 127.0.0.1/32 to 127.0.0.1/32 block in log first on lo0(!) from any to any pass in log body or-block quick from any to any block return-rst in quick on le0(!) proto tcp from any to any @@ -14,4 +14,4 @@ block return-icmp in on qe0(!) from any to any block return-icmp(host-unr) in on qe0(!) from any to any block return-icmp-as-dest in on le0(!) from any to any block return-icmp-as-dest(port-unr) in on qe0(!) from any to any -pass out on longNICname0(!) from 254.220.186.152/32 to 254.220.186.152/32 +pass out on longNICname0(!) inet from 254.220.186.152/32 to 254.220.186.152/32 diff --git a/contrib/ipfilter/test/expected/i10 b/contrib/ipfilter/test/expected/i10 index 9e0a5d5ab8ba..24137c1e29c9 100644 --- a/contrib/ipfilter/test/expected/i10 +++ b/contrib/ipfilter/test/expected/i10 @@ -1,5 +1,5 @@ -pass in from 127.0.0.1/32 to 127.0.0.1/32 with opt sec -pass in from 127.0.0.1/32 to 127.0.0.1/32 with opt lsrr not opt sec -block in from any to any with not opt sec-class topsecret -block in from any to any with not opt sec-class topsecret,secret -pass in from any to any with opt sec-class topsecret,confid not opt sec-class unclass +pass in inet from 127.0.0.1/32 to 127.0.0.1/32 with opt sec +pass in inet from 127.0.0.1/32 to 127.0.0.1/32 with opt lsrr not opt sec +block in inet from any to any with not opt sec-class topsecret +block in inet from any to any with not opt sec-class topsecret,secret +pass in inet from any to any with opt sec-class topsecret,confid not opt sec-class unclass diff --git a/contrib/ipfilter/test/expected/i11 b/contrib/ipfilter/test/expected/i11 index 154f31e810bb..d1d2cf6c5742 100644 --- a/contrib/ipfilter/test/expected/i11 +++ b/contrib/ipfilter/test/expected/i11 @@ -1,11 +1,12 @@ -pass in on ed0(!) proto tcp from 127.0.0.1/32 to 127.0.0.1/32 port = 23 keep state # count 0 +pass in on ed0(!) inet proto tcp from 127.0.0.1/32 to 127.0.0.1/32 port = 23 keep state # count 0 block in log first on lo0(!) proto tcp/udp from any to any port = 7 keep state # count 0 -pass in proto udp from 127.0.0.1/32 to 127.0.0.1/32 port = 20499 keep frags -pass in proto udp from 127.0.0.1/32 to 127.0.0.1/32 port = 2049 keep frags (strict) -pass in proto udp from 127.0.0.1/32 to 127.0.0.1/32 port = 53 keep state keep frags # count 0 +pass in inet proto udp from 127.0.0.1/32 to 127.0.0.1/32 port = 20499 keep frags +pass in inet proto udp from 127.0.0.1/32 to 127.0.0.1/32 port = 2049 keep frags (strict) +pass in inet proto udp from 127.0.0.1/32 to 127.0.0.1/32 port = 53 keep state keep frags # count 0 pass in on ed0(!) out-via vx0(!) proto udp from any to any keep state # count 0 pass out on ppp0(!) in-via le0(!) proto tcp from any to any keep state # count 0 pass in on ed0(!),vx0(!) out-via vx0(!),ed0(!) proto udp from any to any keep state # count 0 -pass in proto tcp from any port > 1024 to 127.0.0.1/32 port = 1024 keep state # count 0 +pass in inet proto tcp from any port > 1024 to 127.0.0.1/32 port = 1024 keep state # count 0 pass in proto tcp from any to any flags S/FSRPAU keep state (limit 101,strict,newisn,no-icmp-err,age 600/600) # count 0 +pass in proto tcp from any to any flags S/FSRPAU keep state (limit 101,loose,newisn,no-icmp-err,age 600/600) # count 0 pass in proto udp from any to any keep state (sync,age 10/20) # count 0 diff --git a/contrib/ipfilter/test/expected/i12 b/contrib/ipfilter/test/expected/i12 index dadf597fc3df..6747d9338902 100644 --- a/contrib/ipfilter/test/expected/i12 +++ b/contrib/ipfilter/test/expected/i12 @@ -1,39 +1,39 @@ -pass in from 1.1.1.1/32 to 2.2.2.2/32 -pass in from 2.2.2.0/24 to 4.4.4.4/32 -pass in from 3.3.3.3/32 to 4.4.4.4/32 -pass in from 2.2.2.0/24 to 5.5.5.5/32 -pass in from 3.3.3.3/32 to 5.5.5.5/32 -pass in from 2.2.2.0/24 to 6.6.6.6/32 -pass in from 3.3.3.3/32 to 6.6.6.6/32 -pass in from 2.2.2.0/24 to 5.5.5.5/32 port = 22 -pass in from 3.3.3.3/32 to 5.5.5.5/32 port = 22 -pass in from 2.2.2.0/24 to 6.6.6.6/32 port = 22 -pass in from 3.3.3.3/32 to 6.6.6.6/32 port = 22 -pass in from 2.2.2.0/24 to 5.5.5.5/32 port = 25 -pass in from 3.3.3.3/32 to 5.5.5.5/32 port = 25 -pass in from 2.2.2.0/24 to 6.6.6.6/32 port = 25 -pass in from 3.3.3.3/32 to 6.6.6.6/32 port = 25 -pass in proto tcp from 2.2.2.0/24 port = 53 to 5.5.5.5/32 -pass in proto tcp from 3.3.3.3/32 port = 53 to 5.5.5.5/32 -pass in proto tcp from 2.2.2.0/24 port = 9 to 5.5.5.5/32 -pass in proto tcp from 3.3.3.3/32 port = 9 to 5.5.5.5/32 -pass in proto tcp from 2.2.2.0/24 port = 53 to 6.6.6.6/32 -pass in proto tcp from 3.3.3.3/32 port = 53 to 6.6.6.6/32 -pass in proto tcp from 2.2.2.0/24 port = 9 to 6.6.6.6/32 -pass in proto tcp from 3.3.3.3/32 port = 9 to 6.6.6.6/32 -pass in proto udp from 2.2.2.0/24 to 5.5.5.5/32 port = 53 -pass in proto udp from 3.3.3.3/32 to 5.5.5.5/32 port = 53 -pass in proto udp from 2.2.2.0/24 to 6.6.6.6/32 port = 53 -pass in proto udp from 3.3.3.3/32 to 6.6.6.6/32 port = 53 -pass in proto udp from 2.2.2.0/24 to 5.5.5.5/32 port = 9 -pass in proto udp from 3.3.3.3/32 to 5.5.5.5/32 port = 9 -pass in proto udp from 2.2.2.0/24 to 6.6.6.6/32 port = 9 -pass in proto udp from 3.3.3.3/32 to 6.6.6.6/32 port = 9 -pass in from 10.10.10.10/32 to 11.11.11.11/32 -pass in from pool/101(!) to hash/202(!) -pass in from hash/303(!) to pool/404(!) -table role = ipf type = tree name = - { ! 1.1.1.1/32; 2.2.2.2/32; ! 2.2.0.0/16; }; -table role = ipf type = tree name = +pass in inet from 1.1.1.1/32 to 2.2.2.2/32 +pass in inet from 2.2.2.0/24 to 4.4.4.4/32 +pass in inet from 3.3.3.3/32 to 4.4.4.4/32 +pass in inet from 2.2.2.0/24 to 5.5.5.5/32 +pass in inet from 3.3.3.3/32 to 5.5.5.5/32 +pass in inet from 2.2.2.0/24 to 6.6.6.6/32 +pass in inet from 3.3.3.3/32 to 6.6.6.6/32 +pass in inet from 2.2.2.0/24 to 5.5.5.5/32 port = 22 +pass in inet from 3.3.3.3/32 to 5.5.5.5/32 port = 22 +pass in inet from 2.2.2.0/24 to 6.6.6.6/32 port = 22 +pass in inet from 3.3.3.3/32 to 6.6.6.6/32 port = 22 +pass in inet from 2.2.2.0/24 to 5.5.5.5/32 port = 25 +pass in inet from 3.3.3.3/32 to 5.5.5.5/32 port = 25 +pass in inet from 2.2.2.0/24 to 6.6.6.6/32 port = 25 +pass in inet from 3.3.3.3/32 to 6.6.6.6/32 port = 25 +pass in inet proto tcp from 2.2.2.0/24 port = 53 to 5.5.5.5/32 +pass in inet proto tcp from 3.3.3.3/32 port = 53 to 5.5.5.5/32 +pass in inet proto tcp from 2.2.2.0/24 port = 9 to 5.5.5.5/32 +pass in inet proto tcp from 3.3.3.3/32 port = 9 to 5.5.5.5/32 +pass in inet proto tcp from 2.2.2.0/24 port = 53 to 6.6.6.6/32 +pass in inet proto tcp from 3.3.3.3/32 port = 53 to 6.6.6.6/32 +pass in inet proto tcp from 2.2.2.0/24 port = 9 to 6.6.6.6/32 +pass in inet proto tcp from 3.3.3.3/32 port = 9 to 6.6.6.6/32 +pass in inet proto udp from 2.2.2.0/24 to 5.5.5.5/32 port = 53 +pass in inet proto udp from 3.3.3.3/32 to 5.5.5.5/32 port = 53 +pass in inet proto udp from 2.2.2.0/24 to 6.6.6.6/32 port = 53 +pass in inet proto udp from 3.3.3.3/32 to 6.6.6.6/32 port = 53 +pass in inet proto udp from 2.2.2.0/24 to 5.5.5.5/32 port = 9 +pass in inet proto udp from 3.3.3.3/32 to 5.5.5.5/32 port = 9 +pass in inet proto udp from 2.2.2.0/24 to 6.6.6.6/32 port = 9 +pass in inet proto udp from 3.3.3.3/32 to 6.6.6.6/32 port = 9 +pass in inet from 10.10.10.10/32 to 11.11.11.11/32 +pass in from pool/101 to hash/202 +pass in from hash/303 to pool/404 +table role=ipf type=tree number= + { ! 2.2.0.0/16; 2.2.2.2/32; ! 1.1.1.1/32; }; +table role=ipf type=tree number= { 1.1.0.0/16; }; -pass in from pool/0(!) to pool/0(!) +pass in from pool/0 to pool/0 diff --git a/contrib/ipfilter/test/expected/i14 b/contrib/ipfilter/test/expected/i14 index 08ba19ad5588..bccdcac6deeb 100644 --- a/contrib/ipfilter/test/expected/i14 +++ b/contrib/ipfilter/test/expected/i14 @@ -3,8 +3,10 @@ pass in on eri0(!) proto icmp from any to any group 1 pass out on ed0(!) all head 1000000 block out on ed0(!) proto udp from any to any group 1000000 block in on vm0(!) proto tcp/udp from any to any head 101 -pass in proto tcp/udp from 1.1.1.1/32 to 2.2.2.2/32 group 101 -pass in proto tcp from 1.0.0.1/32 to 2.0.0.2/32 group 101 -pass in proto udp from 2.0.0.2/32 to 3.0.0.3/32 group 101 +pass in inet proto tcp/udp from 1.1.1.1/32 to 2.2.2.2/32 group 101 +pass in inet proto tcp from 1.0.0.1/32 to 2.0.0.2/32 group 101 +pass in inet proto udp from 2.0.0.2/32 to 3.0.0.3/32 group 101 block in on vm0(!) proto tcp/udp from any to any head vm0-group -pass in proto tcp/udp from 1.1.1.1/32 to 2.2.2.2/32 group vm0-group +pass in inet proto tcp/udp from 1.1.1.1/32 to 2.2.2.2/32 group vm0-group +block in on vm0(!) proto tcp/udp from any to any head vm0-group +pass in inet proto tcp/udp from 1.1.1.1/32 to 2.2.2.2/32 group vm0-group diff --git a/contrib/ipfilter/test/expected/i17 b/contrib/ipfilter/test/expected/i17 index bcc4d2d544a5..9e71cb100322 100644 --- a/contrib/ipfilter/test/expected/i17 +++ b/contrib/ipfilter/test/expected/i17 @@ -8,3 +8,22 @@ List of configured pools List of configured hash tables List of groups configured (set 0) List of groups configured (set 1) +Rules configured (set 0, in) +0 pass in inet from 1.1.1.1/32 to any +0 pass in all +0 pass in inet from 3.3.3.3/32 to any +0 pass in inet from any to 127.0.0.1/32 +0 pass in inet from 127.0.0.1/32 to any +0 100 pass in inet from 127.0.0.1/32 to any +0 100 pass in all +0 110 pass in proto udp from any to any +0 110 pass in inet from 2.2.2.2/32 to any +0 110 pass in inet from 127.0.0.1/32 to any +0 200 pass in proto tcp from any to any +Rules configured (set 0, out) +Rules configured (set 1, in) +Rules configured (set 1, out) +Accounting rules configured (set 0, in) +Accounting rules configured (set 0, out) +Accounting rules configured (set 1, in) +Accounting rules configured (set 1, out) diff --git a/contrib/ipfilter/test/expected/i18 b/contrib/ipfilter/test/expected/i18 index 88fca4744c46..2c7e4935d524 100644 --- a/contrib/ipfilter/test/expected/i18 +++ b/contrib/ipfilter/test/expected/i18 @@ -1,7 +1,7 @@ pass in tos 0x50 from any to any pass in tos 0x80 from any to any -pass in tos 0x80 from any to any -pass in tos 0x50 from any to any +pass out tos 0x80 from any to any +pass out tos 0x50 from any to any block in ttl 0 from any to any block in ttl 1 from any to any block in ttl 2 from any to any diff --git a/contrib/ipfilter/test/expected/i2 b/contrib/ipfilter/test/expected/i2 index 5ff18f4f924c..17b9d07883f7 100644 --- a/contrib/ipfilter/test/expected/i2 +++ b/contrib/ipfilter/test/expected/i2 @@ -1,8 +1,9 @@ log in proto tcp from any to any pass in proto tcp from any to any -pass in proto udp from 127.0.0.1/32 to 127.0.0.1/32 +pass in inet proto udp from 127.0.0.1/32 to 127.0.0.1/32 block in proto ipv6 from any to any block in proto udp from any to any block in proto 250 from any to any pass in proto tcp/udp from any to any block in proto tcp/udp from any to any +block in proto tcp/udp from any to any diff --git a/contrib/ipfilter/test/expected/i20 b/contrib/ipfilter/test/expected/i20 index 77eabdb55f0b..25e35cd9f5c6 100644 --- a/contrib/ipfilter/test/expected/i20 +++ b/contrib/ipfilter/test/expected/i20 @@ -1,4 +1,4 @@ -pass in on ppp0(!) from ppp0/peer to ppp0/32 -block in on hme0(!) from any to hme0/bcast -pass in on bge0(!) from bge0/net to bge0/32 -block in on eri0(!) from any to eri0/netmasked +pass in on ppp0(!) inet from ppp0/peer to ppp0/32 +block in on hme0(!) inet from any to hme0/bcast +pass in on bge0(!) inet from bge0/net to bge0/32 +block in on eri0(!) inet from any to eri0/netmasked diff --git a/contrib/ipfilter/test/expected/i22 b/contrib/ipfilter/test/expected/i22 new file mode 100644 index 000000000000..6e5a07d634b0 --- /dev/null +++ b/contrib/ipfilter/test/expected/i22 @@ -0,0 +1,5 @@ +pass in exp { "ip.src != 1.1.1.0/24; tcp.dport = 80;" } +pass in exp { "ip.addr = 1.2.3.4/32,5.6.7.8/32;" } +block out exp { "ip.dst = 127.0.0.0/8;" } +block in exp { "udp.sport = 53; udp.dport = 53;" } +pass out exp { "tcp.sport = 22; tcp.port = 25;" } diff --git a/contrib/ipfilter/test/expected/i23 b/contrib/ipfilter/test/expected/i23 new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/contrib/ipfilter/test/expected/i3 b/contrib/ipfilter/test/expected/i3 index 6150c7e55bd1..691ad257f389 100644 --- a/contrib/ipfilter/test/expected/i3 +++ b/contrib/ipfilter/test/expected/i3 @@ -1,11 +1,11 @@ log in all -pass in from 128.16.0.0/16 to 129.10.10.0/24 -pass in from 128.0.0.0/24 to 128.0.0.0/16 -pass in from 128.0.0.0/24 to 128.0.0.0/16 -pass in from 128.0.0.0/24 to 128.0.0.0/16 -pass in from 128.0.0.0/24 to 128.0.0.0/16 -pass in from 128.0.0.0/24 to 128.0.0.0/16 -pass in from 127.0.0.1/32 to 127.0.0.1/32 -block in log from any to any +pass in inet from 128.16.0.0/16 to 129.10.10.0/24 +pass in inet from 128.0.0.0/24 to 128.0.0.0/16 +pass in inet from 128.0.0.0/24 to 128.0.0.0/16 +pass in inet from 128.0.0.0/24 to 128.0.0.0/16 +pass in inet from 128.0.0.0/24 to 128.0.0.0/16 +pass in inet from 128.0.0.0/24 to 128.0.0.0/16 +pass in inet from 127.0.0.1/32 to 127.0.0.1/32 +block in log inet from any to any block in log level auth.info on hme0(!) all log level local5.warn out all diff --git a/contrib/ipfilter/test/expected/i4 b/contrib/ipfilter/test/expected/i4 index 49924555a27e..1198714fb55d 100644 --- a/contrib/ipfilter/test/expected/i4 +++ b/contrib/ipfilter/test/expected/i4 @@ -1,7 +1,7 @@ log in proto tcp from any port > 0 to any log in proto tcp from any to any port > 0 pass in proto tcp from any port != 0 to any port 0 >< 65535 -pass in proto udp from 127.0.0.1/32 port > 32000 to 127.0.0.1/32 port < 29000 +pass in inet proto udp from 127.0.0.1/32 port > 32000 to 127.0.0.1/32 port < 29000 block in proto udp from any port != 123 to any port < 7 block in proto tcp from any port = 25 to any port > 25 pass in proto tcp/udp from any port 1 >< 3 to any port 1 <> 3 diff --git a/contrib/ipfilter/test/expected/i5 b/contrib/ipfilter/test/expected/i5 index edf986558f26..0dbc859b9a4d 100644 --- a/contrib/ipfilter/test/expected/i5 +++ b/contrib/ipfilter/test/expected/i5 @@ -1,9 +1,9 @@ log in all count in tos 0x80 from any to any -pass in on ed0(!) tos 0x40 from 127.0.0.1/32 to 127.0.0.1/32 +pass in on ed0(!) inet tos 0x40 from 127.0.0.1/32 to 127.0.0.1/32 block in log on lo0(!) ttl 0 from any to any pass in quick ttl 1 from any to any -skip 3 out from 127.0.0.1/32 to any +skip 3 out inet from 127.0.0.1/32 to any auth out on foo0(!) proto tcp from any to any port = 80 preauth out on foo0(!) proto tcp from any to any port = 22 nomatch out on foo0(!) proto tcp from any port < 1024 to any diff --git a/contrib/ipfilter/test/expected/i6 b/contrib/ipfilter/test/expected/i6 index e4b14c328cbf..29c33a265f37 100644 --- a/contrib/ipfilter/test/expected/i6 +++ b/contrib/ipfilter/test/expected/i6 @@ -1,12 +1,12 @@ pass in on lo0(!) fastroute from any to any -pass in on lo0(!) to qe0(!) from 127.0.0.1/32 to 127.0.0.1/32 -pass in on le0(!) to qe0(!):127.0.0.1 from 127.0.0.1/32 to 127.0.0.1/32 -pass in on lo0(!) dup-to qe0(!) from 127.0.0.1/32 to 127.0.0.1/32 -pass in on le0(!) dup-to qe0(!):127.0.0.1 from 127.0.0.1/32 to 127.0.0.1/32 -pass in on le0(!) dup-to qe0(!):127.0.0.1 to hme0(!):10.1.1.1 from 127.0.0.1/32 to 127.0.0.1/32 +pass in on lo0(!) to qe0(!) inet from 127.0.0.1/32 to 127.0.0.1/32 +pass in on le0(!) to qe0:127.0.0.1 inet from 127.0.0.1/32 to 127.0.0.1/32 +pass in on lo0(!) dup-to qe0(!) inet from 127.0.0.1/32 to 127.0.0.1/32 +pass in on le0(!) dup-to qe0:127.0.0.1 inet from 127.0.0.1/32 to 127.0.0.1/32 +pass in on le0(!) to hme0:10.1.1.1 dup-to qe0:127.0.0.1 inet from 127.0.0.1/32 to 127.0.0.1/32 block in quick on qe0(!) to qe1(!) from any to any block in quick to qe1(!) from any to any pass out quick dup-to hme0(!) from any to any pass out quick on hme0(!) reply-to hme1(!) from any to any -pass in on le0(!) dup-to qe0(!):127.0.0.1 reply-to hme1(!):10.10.10.10 all +pass in on le0(!) dup-to qe0:127.0.0.1 reply-to hme1:10.10.10.10 inet all pass in quick fastroute all diff --git a/contrib/ipfilter/test/expected/i7 b/contrib/ipfilter/test/expected/i7 index 309cd28691b1..552f7f811ef3 100644 --- a/contrib/ipfilter/test/expected/i7 +++ b/contrib/ipfilter/test/expected/i7 @@ -1,4 +1,4 @@ -pass in on ed0(!) proto tcp from 127.0.0.1/32 to 127.0.0.1/32 port = 23 flags S/SA +pass in on ed0(!) inet proto tcp from 127.0.0.1/32 to 127.0.0.1/32 port = 23 flags S/SA block in on lo0(!) proto tcp from any to any flags A/FSRPAU pass in on lo0(!) proto tcp from any to any flags /SPA block in on lo0(!) proto tcp from any to any flags C/A @@ -7,3 +7,8 @@ block in on lo0(!) proto tcp from any to any flags S/SA pass in on lo0(!) proto tcp from any to any flags S/FSRPAU block in on lo0(!) proto tcp from any to any flags /A pass in on lo0(!) proto tcp from any to any flags S/SA +pass in on lo0(!) proto tcp from any to any flags S/SA +block in on lo0(!) proto tcp from any to any flags S/SA +pass in on lo0(!) proto tcp from any to any flags S/FSRPAU +block in on lo0(!) proto tcp from any to any flags /A +pass in on lo0(!) proto tcp from any to any flags S/SA diff --git a/contrib/ipfilter/test/expected/i8 b/contrib/ipfilter/test/expected/i8 index f033e6b8d891..a85f1deb270f 100644 --- a/contrib/ipfilter/test/expected/i8 +++ b/contrib/ipfilter/test/expected/i8 @@ -1,35 +1,66 @@ -pass in proto icmp from 127.0.0.1/32 to 127.0.0.1/32 icmp-type timest -block in proto icmp from any to any icmp-type unreach code 1 -pass in proto icmp from any to any icmp-type unreach code 15 -pass in proto icmp from any to any icmp-type unreach code 13 -pass in proto icmp from any to any icmp-type unreach code 8 -pass in proto icmp from any to any icmp-type unreach code 4 -pass in proto icmp from any to any icmp-type unreach code 9 -pass in proto icmp from any to any icmp-type unreach code 11 -pass in proto icmp from any to any icmp-type unreach code 14 -pass in proto icmp from any to any icmp-type unreach code 10 -pass in proto icmp from any to any icmp-type unreach code 12 -pass in proto icmp from any to any icmp-type unreach code 7 -pass in proto icmp from any to any icmp-type unreach code 1 -pass in proto icmp from any to any icmp-type unreach code 6 -pass in proto icmp from any to any icmp-type unreach code 0 -pass in proto icmp from any to any icmp-type unreach code 3 -pass in proto icmp from any to any icmp-type unreach code 2 -pass in proto icmp from any to any icmp-type unreach code 5 -pass in proto icmp from any to any icmp-type echo -pass in proto icmp from any to any icmp-type echorep -pass in proto icmp from any to any icmp-type inforeq -pass in proto icmp from any to any icmp-type inforep -pass in proto icmp from any to any icmp-type maskrep -pass in proto icmp from any to any icmp-type maskreq -pass in proto icmp from any to any icmp-type paramprob -pass in proto icmp from any to any icmp-type redir -pass in proto icmp from any to any icmp-type unreach -pass in proto icmp from any to any icmp-type routerad -pass in proto icmp from any to any icmp-type routersol -pass in proto icmp from any to any icmp-type squench -pass in proto icmp from any to any icmp-type timest -pass in proto icmp from any to any icmp-type timestrep -pass in proto icmp from any to any icmp-type timex -pass in proto icmp from any to any icmp-type 254 -pass in proto icmp from any to any icmp-type 253 code 254 +pass in inet proto icmp from 127.0.0.1/32 to 127.0.0.1/32 icmp-type timest +block in inet proto icmp from any to any icmp-type unreach code 1 +pass in inet proto icmp from any to any icmp-type unreach code 15 +pass in inet proto icmp from any to any icmp-type unreach code 13 +pass in inet proto icmp from any to any icmp-type unreach code 8 +pass in inet proto icmp from any to any icmp-type unreach code 4 +pass in inet proto icmp from any to any icmp-type unreach code 9 +pass in inet proto icmp from any to any icmp-type unreach code 11 +pass in inet proto icmp from any to any icmp-type unreach code 14 +pass in inet proto icmp from any to any icmp-type unreach code 10 +pass in inet proto icmp from any to any icmp-type unreach code 12 +pass in inet proto icmp from any to any icmp-type unreach code 7 +pass in inet proto icmp from any to any icmp-type unreach code 1 +pass in inet proto icmp from any to any icmp-type unreach code 6 +pass in inet proto icmp from any to any icmp-type unreach code 0 +pass in inet proto icmp from any to any icmp-type unreach code 3 +pass in inet proto icmp from any to any icmp-type unreach code 2 +pass in inet proto icmp from any to any icmp-type unreach code 5 +pass in inet proto icmp from any to any icmp-type echo +pass in inet proto icmp from any to any icmp-type echorep +pass in inet proto icmp from any to any icmp-type inforeq +pass in inet proto icmp from any to any icmp-type inforep +pass in inet proto icmp from any to any icmp-type maskrep +pass in inet proto icmp from any to any icmp-type maskreq +pass in inet proto icmp from any to any icmp-type paramprob +pass in inet proto icmp from any to any icmp-type redir +pass in inet proto icmp from any to any icmp-type unreach +pass in inet proto icmp from any to any icmp-type routerad +pass in inet proto icmp from any to any icmp-type routersol +pass in inet proto icmp from any to any icmp-type squench +pass in inet proto icmp from any to any icmp-type timest +pass in inet proto icmp from any to any icmp-type timestrep +pass in inet proto icmp from any to any icmp-type timex +pass in inet proto icmp from any to any icmp-type 254 +pass in inet proto icmp from any to any icmp-type 253 code 254 +pass in inet proto icmp from any to any icmp-type unreach code 15 +pass in inet proto icmp from any to any icmp-type unreach code 13 +pass in inet proto icmp from any to any icmp-type unreach code 8 +pass in inet proto icmp from any to any icmp-type unreach code 4 +pass in inet proto icmp from any to any icmp-type unreach code 9 +pass in inet proto icmp from any to any icmp-type unreach code 11 +pass in inet proto icmp from any to any icmp-type unreach code 14 +pass in inet proto icmp from any to any icmp-type unreach code 10 +pass in inet proto icmp from any to any icmp-type unreach code 12 +pass in inet proto icmp from any to any icmp-type unreach code 7 +pass in inet proto icmp from any to any icmp-type unreach code 1 +pass in inet proto icmp from any to any icmp-type unreach code 6 +pass in inet proto icmp from any to any icmp-type unreach code 0 +pass in inet proto icmp from any to any icmp-type unreach code 3 +pass in inet proto icmp from any to any icmp-type unreach code 2 +pass in inet proto icmp from any to any icmp-type unreach code 5 +pass in inet proto icmp from any to any icmp-type echo +pass in inet proto icmp from any to any icmp-type echorep +pass in inet proto icmp from any to any icmp-type inforeq +pass in inet proto icmp from any to any icmp-type inforep +pass in inet proto icmp from any to any icmp-type maskrep +pass in inet proto icmp from any to any icmp-type maskreq +pass in inet proto icmp from any to any icmp-type paramprob +pass in inet proto icmp from any to any icmp-type redir +pass in inet proto icmp from any to any icmp-type unreach +pass in inet proto icmp from any to any icmp-type routerad +pass in inet proto icmp from any to any icmp-type routersol +pass in inet proto icmp from any to any icmp-type squench +pass in inet proto icmp from any to any icmp-type timest +pass in inet proto icmp from any to any icmp-type timestrep +pass in inet proto icmp from any to any icmp-type timex diff --git a/contrib/ipfilter/test/expected/i9 b/contrib/ipfilter/test/expected/i9 index b128f99d57ac..deecd17d3a1d 100644 --- a/contrib/ipfilter/test/expected/i9 +++ b/contrib/ipfilter/test/expected/i9 @@ -1,9 +1,9 @@ -pass in from 127.0.0.1/32 to 127.0.0.1/32 with short,frag +pass in inet from 127.0.0.1/32 to 127.0.0.1/32 with short,frag block in from any to any with ipopts -pass in from any to any with opt nop,rr,zsu -pass in from any to any with opt nop,rr,zsu not opt lsrr,ssrr -pass in from 127.0.0.1/32 to 127.0.0.1/32 with not frag -pass in from 127.0.0.1/32 to 127.0.0.1/32 with frag,frag-body +pass in inet from any to any with opt nop,rr,zsu +pass in inet from any to any with opt nop,rr,zsu not opt lsrr,ssrr +pass in inet from 127.0.0.1/32 to 127.0.0.1/32 with not frag +pass in inet from 127.0.0.1/32 to 127.0.0.1/32 with frag,frag-body pass in proto tcp from any to any flags S/FSRPAU with not oow keep state # count 0 block in proto tcp from any to any with oow pass in proto tcp from any to any flags S/FSRPAU with not bad,bad-src,bad-nat @@ -14,4 +14,4 @@ pass in quick from any to any with not frag-body block in quick from any to any with not lowttl pass in from any to any with not ipopts,mbcast,not bcast,mcast,not state block in from any to any with not mbcast,bcast,not mcast,state -pass in from any to any with opt mtup,mtur,encode,ts,tr,sec,e-sec,cipso,satid,ssrr,addext,visa,imitd,eip,finn,dps,sdb,nsapa,rtralrt,ump +pass in inet from any to any with opt mtup,mtur,encode,ts,tr,sec,e-sec,cipso,satid,ssrr,addext,visa,imitd,eip,finn,dps,sdb,nsapa,rtralrt,ump diff --git a/contrib/ipfilter/test/expected/in1 b/contrib/ipfilter/test/expected/in1 index 03436b65a4dd..2f1cf31df00a 100644 --- a/contrib/ipfilter/test/expected/in1 +++ b/contrib/ipfilter/test/expected/in1 @@ -1,31 +1,31 @@ -map le0 0.0.0.0/0 -> 0.0.0.0/32 +map le0 0/0 -> 0/32 map le0 0.0.0.1/32 -> 0.0.0.1/32 -map le0 128.0.0.0/1 -> 0.0.0.0/0 +map le0 128.0.0.0/1 -> 0/0 map le0 10.0.0.0/8 -> 1.2.3.0/24 map le0 10.0.0.0/8 -> 1.2.3.0/24 map le0 10.0.0.0/8 -> 1.2.3.0/24 map le0 0.0.0.5/0.0.0.255 -> 1.2.3.0/24 map le0 192.168.0.0/16 -> range 203.1.1.23-203.1.3.45 -map ppp0 192.168.0.0/16 -> 0.0.0.0/32 portmap tcp 10000:19999 -map ppp0 192.168.0.0/16 -> 0.0.0.0/32 portmap udp 20000:29999 -map ppp0 192.168.0.0/16 -> 0.0.0.0/32 portmap tcp/udp 30000:39999 -map ppp0 192.168.0.0/16 -> 0.0.0.0/32 portmap tcp auto -map ppp0 192.168.0.0/16 -> 0.0.0.0/32 portmap udp auto -map ppp0 192.168.0.0/16 -> 0.0.0.0/32 portmap tcp/udp auto -map ppp0 192.168.0.0/16 -> 0.0.0.0/32 proxy port 21 ftp/tcp -map ppp0 192.168.0.0/16 -> 0.0.0.0/32 proxy port 1010 ftp/tcp -map le0 0.0.0.0/0 -> 0.0.0.0/32 frag +map ppp0 192.168.0.0/16 -> 0/32 portmap tcp 10000:19999 +map ppp0 192.168.0.0/16 -> 0/32 portmap udp 20000:29999 +map ppp0 192.168.0.0/16 -> 0/32 portmap tcp/udp 30000:39999 +map ppp0 192.168.0.0/16 -> 0/32 portmap tcp auto +map ppp0 192.168.0.0/16 -> 0/32 portmap udp auto +map ppp0 192.168.0.0/16 -> 0/32 portmap tcp/udp auto +map ppp0 192.168.0.0/16 -> 0/32 proxy port 21 ftp/tcp +map ppp0 192.168.0.0/16 -> 0/32 proxy port 1010 ftp/tcp +map le0 0/0 -> 0/32 frag map le0 192.168.0.0/16 -> range 203.1.1.23-203.1.3.45 frag -map ppp0 192.168.0.0/16 -> 0.0.0.0/32 portmap tcp 10000:19999 frag -map ppp0 192.168.0.0/16 -> 0.0.0.0/32 proxy port 21 ftp/tcp frag -map le0 0.0.0.0/0 -> 0.0.0.0/32 age 10/10 +map ppp0 192.168.0.0/16 -> 0/32 portmap tcp 10000:19999 frag +map ppp0 192.168.0.0/16 -> 0/32 proxy port 21 ftp/tcp frag +map le0 0/0 -> 0/32 age 10/10 map le0 192.168.0.0/16 -> range 203.1.1.23-203.1.3.45 age 10/20 -map ppp0 192.168.0.0/16 -> 0.0.0.0/32 portmap tcp 10000:19999 age 30/30 -map le0 0.0.0.0/0 -> 0.0.0.0/32 frag age 10/10 +map ppp0 192.168.0.0/16 -> 0/32 portmap tcp 10000:19999 age 30/30 +map le0 0/0 -> 0/32 frag age 10/10 map le0 192.168.0.0/16 -> range 203.1.1.23-203.1.3.45 frag age 10/20 -map ppp0 192.168.0.0/16 -> 0.0.0.0/32 portmap tcp 10000:19999 frag age 30/30 -map fxp0 from 192.168.0.0/18 to any port = 21 -> 1.2.3.4/32 proxy port 21 ftp/tcp -map thisisalonginte 0.0.0.0/0 -> 0.0.0.0/32 mssclamp 1452 tag freddyliveshere -map bar0 0.0.0.0/0 -> 0.0.0.0/32 icmpidmap icmp 1000:2000 -map ppp0,adsl0 0.0.0.0/0 -> 0.0.0.0/32 -map ppp0 from 192.168.0.0/16 to any port = 123 -> 0.0.0.0/32 age 30/1 udp +map ppp0 192.168.0.0/16 -> 0/32 portmap tcp 10000:19999 frag age 30/30 +map fxp0 from 192.168.0.0/18 to 0/0 port = 21 -> 1.2.3.4/32 proxy port 21 ftp/tcp +map thisisalonginte 0/0 -> 0/32 mssclamp 1452 tag freddyliveshere +map bar0 0/0 -> 0/32 icmpidmap icmp 1000:2000 +map ppp0,adsl0 0/0 -> 0/32 +map ppp0 from 192.168.0.0/16 to 0/0 port = 123 -> 0/32 age 30/1 udp diff --git a/contrib/ipfilter/test/expected/in100 b/contrib/ipfilter/test/expected/in100 new file mode 100644 index 000000000000..dcf309754410 --- /dev/null +++ b/contrib/ipfilter/test/expected/in100 @@ -0,0 +1,3 @@ +rewrite in on bge0 from 1.1.1.1/32 to 2.2.2.2/32 -> src 3.3.3.3/32 dst 4.4.4.4/32; +rewrite out on bge0 from 1.1.1.1/32 to 2.2.2.2/32 -> src 3.3.3.0/24 dst 4.4.4.4/32; +rewrite in on bge0 from 1.1.1.1/32 to 2.2.2.2/32 -> src 3.3.3.0/24 dst 4.4.4.0/24; diff --git a/contrib/ipfilter/test/expected/in101 b/contrib/ipfilter/test/expected/in101 new file mode 100644 index 000000000000..04e234c2f164 --- /dev/null +++ b/contrib/ipfilter/test/expected/in101 @@ -0,0 +1,4 @@ +rewrite in on bge0 proto icmp from 1.1.1.1/32 to 2.2.2.2/32 -> src 3.3.3.3/32 dst 4.4.4.4/32; +rewrite in on bge0 proto udp from 1.1.1.1/32 to 2.2.2.2/32 -> src 3.3.3.3/32 dst 4.4.4.4/32; +rewrite out on bge0 proto tcp from 1.1.1.1/32 to 2.2.2.2/32 -> src 3.3.3.0/24 dst 4.4.4.4/32; +rewrite in on bge0 proto tcp/udp from 1.1.1.1/32 to 2.2.2.2/32 -> src 3.3.3.0/24,20202 dst 4.4.4.0/24,10101; diff --git a/contrib/ipfilter/test/expected/in102 b/contrib/ipfilter/test/expected/in102 new file mode 100644 index 000000000000..0a1b612d2f73 --- /dev/null +++ b/contrib/ipfilter/test/expected/in102 @@ -0,0 +1,5 @@ +rewrite in on bge0 proto tcp from 0/0 to 0/0 -> src 0/0 dst dstlist/a; +rewrite in on bge0 proto tcp from 1.1.1.1/32 to 0/0 -> src 0/0 dst dstlist/bee; +rewrite in on bge0 proto tcp from 1.1.1.1/32 to 2.2.2.2/32 -> src 0/0 dst dstlist/cat; +rewrite in on bge0 proto tcp from pool/a to 2.2.2.2/32 -> src 0/0 dst dstlist/bat; +rewrite in on bge0 proto tcp from pool/a to pool/1 -> src 0/0 dst dstlist/ant; diff --git a/contrib/ipfilter/test/expected/in2 b/contrib/ipfilter/test/expected/in2 index f1239b122137..dc8f4ac5ba2d 100644 --- a/contrib/ipfilter/test/expected/in2 +++ b/contrib/ipfilter/test/expected/in2 @@ -1,71 +1,71 @@ -rdr le0 9.8.7.6/32 port 0 -> 1.1.1.1 port 0 tcp -rdr le0 9.8.7.6/32 -> 1.1.1.1 255 -rdr le0 9.8.7.6/32 port 80 -> 1.1.1.1 port 80 tcp -rdr le0 9.8.7.6/32 -> 1.1.1.1 ip -rdr le0 9.0.0.0/8 -> 1.1.1.1 ip -rdr le0 9.8.0.0/16 -> 1.1.1.1 ip -rdr le0 9.8.7.6/32 port 80 -> 1.1.1.1 port 80 tcp -rdr le0 9.8.7.6/32 port 80 -> 0.0.0.0/0 port 80 tcp -rdr le0 9.8.7.6/32 port 80 -> 1.1.1.1 port 80 udp -rdr le0 9.8.7.6/32 port 80 -> 1.1.1.1 port 80 tcp/udp -rdr le0 9.8.7.6/32 -> 1.1.1.1 icmp +rdr le0 9.8.7.6/32 port 0 -> 1.1.1.1/32 port 0 tcp +rdr le0 9.8.7.6/32 -> 1.1.1.1/32 255 +rdr le0 9.8.7.6/32 port 80 -> 1.1.1.1/32 port 80 tcp +rdr le0 9.8.7.6/32 -> 1.1.1.1/32 ip +rdr le0 9.0.0.0/8 -> 1.1.1.1/32 ip +rdr le0 9.8.0.0/16 -> 1.1.1.1/32 ip +rdr le0 9.8.7.6/32 port 80 -> 1.1.1.1/32 port 80 tcp +rdr le0 9.8.7.6/32 port 80 -> 0/0 port 80 tcp +rdr le0 9.8.7.6/32 port 80 -> 1.1.1.1/32 port 80 udp +rdr le0 9.8.7.6/32 port 80 -> 1.1.1.1/32 port 80 tcp/udp +rdr le0 9.8.7.6/32 -> 1.1.1.1/32 icmp rdr le0 9.8.7.6/32 port 80 -> 1.1.1.1,1.1.1.2 port 80 tcp -rdr le0 9.8.7.6/32 port 80 -> 1.1.1.1 port 80 tcp round-robin +rdr le0 9.8.7.6/32 port 80 -> 1.1.1.1/32 port 80 tcp round-robin rdr le0 9.8.7.6/32 port 80 -> 1.1.1.1,1.1.1.2 port 80 tcp round-robin -rdr le0 9.8.7.6/32 -> 1.1.1.1 ip frag -rdr le0 9.8.7.6/32 -> 1.1.1.1 icmp frag +rdr le0 9.8.7.6/32 -> 1.1.1.1/32 ip frag +rdr le0 9.8.7.6/32 -> 1.1.1.1/32 icmp frag rdr le0 9.8.7.6/32 port 80 -> 1.1.1.1,1.1.1.2 port 80 tcp/udp frag -rdr le0 9.8.7.6/32 port 80 -> 1.1.1.1 port 80 tcp round-robin frag +rdr le0 9.8.7.6/32 port 80 -> 1.1.1.1/32 port 80 tcp round-robin frag rdr le0 9.8.7.6/32 port 80 -> 1.1.1.1,1.1.1.2 port 80 tcp round-robin frag -rdr le0 9.8.7.6/32 -> 1.1.1.1 ip frag age 10/10 -rdr le0 9.8.7.6/32 -> 1.1.1.1 ip frag age 10/20 -rdr le0 9.8.7.6/32 -> 1.1.1.1 icmp frag age 10/10 +rdr le0 9.8.7.6/32 -> 1.1.1.1/32 ip frag age 10/10 +rdr le0 9.8.7.6/32 -> 1.1.1.1/32 ip frag age 10/20 +rdr le0 9.8.7.6/32 -> 1.1.1.1/32 icmp frag age 10/10 rdr le0 9.8.7.6/32 port 80 -> 1.1.1.1,1.1.1.2 port 80 tcp frag age 20/20 -rdr le0 9.8.7.6/32 port 80 -> 1.1.1.1 port 80 tcp round-robin frag age 30/30 +rdr le0 9.8.7.6/32 port 80 -> 1.1.1.1/32 port 80 tcp round-robin frag age 30/30 rdr le0 9.8.7.6/32 port 80 -> 1.1.1.1,1.1.1.2 port 80 tcp round-robin frag age 40/40 -rdr le0 9.8.7.6/32 -> 1.1.1.1 ip -rdr le0 9.8.7.6/32 -> 1.1.1.1 ip frag -rdr le0 9.8.7.6/32 -> 1.1.1.1 icmp frag +rdr le0 9.8.7.6/32 -> 1.1.1.1/32 ip +rdr le0 9.8.7.6/32 -> 1.1.1.1/32 ip frag +rdr le0 9.8.7.6/32 -> 1.1.1.1/32 icmp frag rdr le0 9.8.7.6/32 port 80 -> 1.1.1.1,1.1.1.2 port 80 tcp frag sticky -rdr le0 9.8.7.6/32 port 80 -> 1.1.1.1 port 80 tcp round-robin frag sticky +rdr le0 9.8.7.6/32 port 80 -> 1.1.1.1/32 port 80 tcp round-robin frag sticky rdr le0 9.8.7.6/32 port 80 -> 1.1.1.1,1.1.1.2 port 80 tcp round-robin frag sticky -rdr le0 9.8.7.6/32 -> 1.1.1.1 ip frag age 10/10 -rdr le0 9.8.7.6/32 -> 1.1.1.1 ip frag age 10/20 -rdr le0 9.8.7.6/32 -> 1.1.1.1 icmp frag age 10/10 +rdr le0 9.8.7.6/32 -> 1.1.1.1/32 ip frag age 10/10 +rdr le0 9.8.7.6/32 -> 1.1.1.1/32 ip frag age 10/20 +rdr le0 9.8.7.6/32 -> 1.1.1.1/32 icmp frag age 10/10 rdr le0 9.8.7.6/32 port 80 -> 1.1.1.1,1.1.1.2 port 80 tcp frag age 20/20 sticky -rdr le0 9.8.7.6/32 port 80 -> 1.1.1.1 port 80 tcp round-robin frag age 30/30 sticky +rdr le0 9.8.7.6/32 port 80 -> 1.1.1.1/32 port 80 tcp round-robin frag age 30/30 sticky rdr le0 9.8.7.6/32 port 80 -> 1.1.1.1,1.1.1.2 port 80 tcp round-robin frag age 40/40 sticky -rdr le0 9.8.7.6/32 -> 1.1.1.1 ip mssclamp 1000 -rdr le0 9.8.7.6/32 -> 1.1.1.1 ip mssclamp 1000 -rdr le0 9.8.7.6/32 -> 1.1.1.1 ip frag mssclamp 1000 -rdr le0 9.8.7.6/32 -> 1.1.1.1 icmp frag mssclamp 1000 +rdr le0 9.8.7.6/32 -> 1.1.1.1/32 ip mssclamp 1000 +rdr le0 9.8.7.6/32 -> 1.1.1.1/32 ip mssclamp 1000 +rdr le0 9.8.7.6/32 -> 1.1.1.1/32 ip frag mssclamp 1000 +rdr le0 9.8.7.6/32 -> 1.1.1.1/32 icmp frag mssclamp 1000 rdr le0 9.8.7.6/32 port 80 -> 1.1.1.1,1.1.1.2 port 80 tcp frag sticky mssclamp 1000 -rdr le0 9.8.7.6/32 port 80 -> 1.1.1.1 port 80 tcp round-robin frag sticky mssclamp 1000 +rdr le0 9.8.7.6/32 port 80 -> 1.1.1.1/32 port 80 tcp round-robin frag sticky mssclamp 1000 rdr le0 9.8.7.6/32 port 80 -> 1.1.1.1,1.1.1.2 port 80 tcp round-robin frag sticky mssclamp 1000 -rdr le0 9.8.7.6/32 -> 1.1.1.1 ip frag age 10/10 mssclamp 1000 -rdr le0 9.8.7.6/32 -> 1.1.1.1 ip frag age 10/20 mssclamp 1000 -rdr le0 9.8.7.6/32 -> 1.1.1.1 icmp frag age 10/10 mssclamp 1000 +rdr le0 9.8.7.6/32 -> 1.1.1.1/32 ip frag age 10/10 mssclamp 1000 +rdr le0 9.8.7.6/32 -> 1.1.1.1/32 ip frag age 10/20 mssclamp 1000 +rdr le0 9.8.7.6/32 -> 1.1.1.1/32 icmp frag age 10/10 mssclamp 1000 rdr le0 9.8.7.6/32 port 80 -> 1.1.1.1,1.1.1.2 port 80 tcp frag age 20/20 sticky mssclamp 1000 -rdr le0 9.8.7.6/32 port 80 -> 1.1.1.1 port 80 tcp round-robin frag age 30/30 sticky mssclamp 1000 +rdr le0 9.8.7.6/32 port 80 -> 1.1.1.1/32 port 80 tcp round-robin frag age 30/30 sticky mssclamp 1000 rdr le0 9.8.7.6/32 port 80 -> 1.1.1.1,1.1.1.2 port 80 tcp round-robin frag age 40/40 sticky mssclamp 1000 -rdr le0 9.8.7.6/32 -> 1.1.1.1 ip tag nattagcacheline -rdr le0 9.8.7.6/32 -> 1.1.1.1 ip mssclamp 1000 tag nattagcacheline -rdr le0 9.8.7.6/32 -> 1.1.1.1 ip mssclamp 1000 tag nattagcacheline -rdr le0 9.8.7.6/32 -> 1.1.1.1 ip frag mssclamp 1000 tag nattagcacheline -rdr le0 9.8.7.6/32 -> 1.1.1.1 icmp frag mssclamp 1000 tag nattagcacheline +rdr le0 9.8.7.6/32 -> 1.1.1.1/32 ip tag nattagcacheline +rdr le0 9.8.7.6/32 -> 1.1.1.1/32 ip mssclamp 1000 tag nattagcacheline +rdr le0 9.8.7.6/32 -> 1.1.1.1/32 ip mssclamp 1000 tag nattagcacheline +rdr le0 9.8.7.6/32 -> 1.1.1.1/32 ip frag mssclamp 1000 tag nattagcacheline +rdr le0 9.8.7.6/32 -> 1.1.1.1/32 icmp frag mssclamp 1000 tag nattagcacheline rdr le0 9.8.7.6/32 port 80 -> 1.1.1.1,1.1.1.2 port 80 tcp frag sticky mssclamp 1000 tag nattagcacheline -rdr le0 9.8.7.6/32 port 80 -> 1.1.1.1 port 80 tcp round-robin frag sticky mssclamp 1000 tag nattagcacheline +rdr le0 9.8.7.6/32 port 80 -> 1.1.1.1/32 port 80 tcp round-robin frag sticky mssclamp 1000 tag nattagcacheline rdr le0 9.8.7.6/32 port 80 -> 1.1.1.1,1.1.1.2 port 80 tcp round-robin frag sticky mssclamp 1000 tag nattagcacheline -rdr le0 9.8.7.6/32 -> 1.1.1.1 ip frag age 10/10 mssclamp 1000 tag nattagcacheline -rdr le0 9.8.7.6/32 -> 1.1.1.1 ip frag age 10/20 mssclamp 1000 tag nattagcacheline -rdr le0 9.8.7.6/32 -> 1.1.1.1 icmp frag age 10/10 mssclamp 1000 tag nattagcacheline +rdr le0 9.8.7.6/32 -> 1.1.1.1/32 ip frag age 10/10 mssclamp 1000 tag nattagcacheline +rdr le0 9.8.7.6/32 -> 1.1.1.1/32 ip frag age 10/20 mssclamp 1000 tag nattagcacheline +rdr le0 9.8.7.6/32 -> 1.1.1.1/32 icmp frag age 10/10 mssclamp 1000 tag nattagcacheline rdr le0 9.8.7.6/32 port 80 -> 1.1.1.1,1.1.1.2 port 80 tcp frag age 20/20 sticky mssclamp 1000 tag nattagcacheline -rdr le0 9.8.7.6/32 port 80 -> 1.1.1.1 port 80 tcp round-robin frag age 30/30 sticky mssclamp 1000 tag nattagcacheline +rdr le0 9.8.7.6/32 port 80 -> 1.1.1.1/32 port 80 tcp round-robin frag age 30/30 sticky mssclamp 1000 tag nattagcacheline rdr le0 9.8.7.6/32 port 80 -> 1.1.1.1,1.1.1.2 port 80 tcp round-robin frag age 40/40 sticky mssclamp 1000 tag nattagcacheline -rdr ge0 9.8.7.6/32 port 21 -> 1.1.1.1 port 21 tcp proxy ftp -rdr ge0 9.8.7.6/32 port 21 -> 1.1.1.1 port 21 tcp proxy ftp -rdr le0 9.8.7.6/32 port 1000-2000 -> 1.1.1.1 port 5555 tcp -rdr le0 9.8.7.6/32 port 1000-2000 -> 1.1.1.1 port = 5555 tcp -rdr le0 0.0.0.0/0 -> 254.220.186.152 ip -rdr le0 0.0.0.0/0 -> 254.220.186.152,254.220.186.152 ip -rdr adsl0,ppp0 0.0.0.0/0 port 25 -> 127.0.0.1 port 25 tcp +rdr ge0 9.8.7.6/32 port 21 -> 1.1.1.1/32 port 21 tcp proxy ftp +rdr ge0 9.8.7.6/32 port 21 -> 1.1.1.1/32 port 21 tcp proxy ftp +rdr le0 9.8.7.6/32 port 1000-2000 -> 1.1.1.1/32 port 5555 tcp +rdr le0 9.8.7.6/32 port 1000-2000 -> 1.1.1.1/32 port = 5555 tcp +rdr le0 0/0 -> 254.220.186.152/32 ip +rdr le0 0/0 -> 254.220.186.152,254.220.186.152 ip +rdr adsl0,ppp0 9.8.7.6/32 port 1000-2000 -> 1.1.1.1/32 port 5555-7777 tcp diff --git a/contrib/ipfilter/test/expected/in3 b/contrib/ipfilter/test/expected/in3 index b8a85bf9f380..dac97c7d9cc1 100644 --- a/contrib/ipfilter/test/expected/in3 +++ b/contrib/ipfilter/test/expected/in3 @@ -1,5 +1,5 @@ -bimap le0 0.0.0.0/0 -> 0.0.0.0/32 +bimap le0 0/0 -> 0/32 bimap le0 0.0.0.1/32 -> 0.0.0.1/32 -bimap le0 128.0.0.0/1 -> 0.0.0.0/0 +bimap le0 128.0.0.0/1 -> 0/0 bimap le0 10.0.0.0/8 -> 1.2.3.0/24 bimap le0 10.0.5.0/24 -> 1.2.3.0/24 diff --git a/contrib/ipfilter/test/expected/in5 b/contrib/ipfilter/test/expected/in5 index e77de714a90d..b7c6ef5d4125 100644 --- a/contrib/ipfilter/test/expected/in5 +++ b/contrib/ipfilter/test/expected/in5 @@ -1,24 +1,24 @@ -map le0 from 9.8.7.6/32 port > 1024 to any -> 1.1.1.1/32 portmap tcp 10000:20000 +map le0 from 9.8.7.6/32 port > 1024 to 0/0 -> 1.1.1.1/32 portmap tcp 10000:20000 map le0 from 9.8.7.6/32 port > 1024 ! to 1.2.3.4/32 -> 1.1.1.1/32 portmap tcp 10000:20000 -rdr le0 from any to 9.8.7.6/32 port = 0 -> 1.1.1.1 port 0 tcp -rdr le0 from any to 9.8.7.6/32 -> 1.1.1.1 ip -rdr le0 ! from 1.2.3.4/32 to 9.8.7.6/32 port = 8888 -> 1.1.1.1 port 888 tcp -rdr le0 from any to 9.8.7.6/32 -> 1.1.1.1 ip -rdr le0 from any to 9.8.7.6/32 port = 8888 -> 1.1.1.1 port 888 tcp -rdr le0 from any to 9.8.7.6/32 port = 8888 -> 1.1.1.1 port 888 udp -rdr le0 from any to 9.8.7.6/32 port = 8888 -> 1.1.1.1 port 888 tcp/udp -rdr le0 from any to 9.8.7.6/32 -> 1.1.1.1 icmp -rdr le0 from any to 9.8.7.6/32 port = 8888 -> 1.1.1.1,1.1.1.2 port 888 tcp -rdr le0 from any to 9.8.7.6/32 port = 8888 -> 1.1.1.1 port 888 tcp round-robin -rdr le0 from any to 9.8.7.6/32 port = 8888 -> 1.1.1.1,1.1.1.2 port 888 tcp round-robin -rdr le0 from any to 9.8.7.6/32 -> 1.1.1.1 ip frag -rdr le0 from any to 9.8.7.6/32 -> 1.1.1.1 icmp frag -rdr le0 from any to 9.8.7.6/32 port = 8888 -> 1.1.1.1,1.1.1.2 port 888 tcp frag -rdr le0 from any to 9.8.7.6/32 port = 8888 -> 1.1.1.1 port 888 tcp round-robin frag -rdr le0 from any to 9.8.7.6/32 port = 8888 -> 1.1.1.1,1.1.1.2 port 888 tcp round-robin frag -rdr le0 from any to 9.8.7.6/32 -> 1.1.1.1 ip frag age 10/10 -rdr le0 from any to 9.8.7.6/32 -> 1.1.1.1 ip frag age 10/20 -rdr le0 from any to 9.8.7.6/32 -> 1.1.1.1 icmp frag age 10/10 -rdr le0 from any to 9.8.7.6/32 port = 8888 -> 1.1.1.1,1.1.1.2 port 888 tcp frag age 20/20 -rdr le0 from any to 9.8.7.6/32 port = 8888 -> 1.1.1.1 port 888 tcp round-robin frag age 30/30 -rdr le0 from any to 9.8.7.6/32 port = 8888 -> 1.1.1.1,1.1.1.2 port 888 tcp round-robin frag age 40/40 +rdr le0 from 0/0 to 9.8.7.6/32 port = 0 -> 1.1.1.1/32 port 0 tcp +rdr le0 from 0/0 to 9.8.7.6/32 -> 1.1.1.1/32 ip +rdr le0 ! from 1.2.3.4/32 to 9.8.7.6/32 port = 8888 -> 1.1.1.1/32 port 888 tcp +rdr le0 from 0/0 to 9.8.7.6/32 -> 1.1.1.1/32 ip +rdr le0 from 0/0 to 9.8.7.6/32 port = 8888 -> 1.1.1.1/32 port 888 tcp +rdr le0 from 0/0 to 9.8.7.6/32 port = 8888 -> 1.1.1.1/32 port 888 udp +rdr le0 from 0/0 to 9.8.7.6/32 port = 8888 -> 1.1.1.1/32 port 888 tcp/udp +rdr le0 from 0/0 to 9.8.7.6/32 -> 1.1.1.1/32 icmp +rdr le0 from 0/0 to 9.8.7.6/32 port = 8888 -> 1.1.1.1,1.1.1.2 port 888 tcp +rdr le0 from 0/0 to 9.8.7.6/32 port = 8888 -> 1.1.1.1/32 port 888 tcp round-robin +rdr le0 from 0/0 to 9.8.7.6/32 port = 8888 -> 1.1.1.1,1.1.1.2 port 888 tcp round-robin +rdr le0 from 0/0 to 9.8.7.6/32 -> 1.1.1.1/32 ip frag +rdr le0 from 0/0 to 9.8.7.6/32 -> 1.1.1.1/32 icmp frag +rdr le0 from 0/0 to 9.8.7.6/32 port = 8888 -> 1.1.1.1,1.1.1.2 port 888 tcp frag +rdr le0 from 0/0 to 9.8.7.6/32 port = 8888 -> 1.1.1.1/32 port 888 tcp round-robin frag +rdr le0 from 0/0 to 9.8.7.6/32 port = 8888 -> 1.1.1.1,1.1.1.2 port 888 tcp round-robin frag +rdr le0 from 0/0 to 9.8.7.6/32 -> 1.1.1.1/32 ip frag age 10/10 +rdr le0 from 0/0 to 9.8.7.6/32 -> 1.1.1.1/32 ip frag age 10/20 +rdr le0 from 0/0 to 9.8.7.6/32 -> 1.1.1.1/32 icmp frag age 10/10 +rdr le0 from 0/0 to 9.8.7.6/32 port = 8888 -> 1.1.1.1,1.1.1.2 port 888 tcp frag age 20/20 +rdr le0 from 0/0 to 9.8.7.6/32 port = 8888 -> 1.1.1.1/32 port 888 tcp round-robin frag age 30/30 +rdr le0 from 0/0 to 9.8.7.6/32 port = 8888 -> 1.1.1.1,1.1.1.2 port 888 tcp round-robin frag age 40/40 diff --git a/contrib/ipfilter/test/expected/in6 b/contrib/ipfilter/test/expected/in6 index 05426e7a8dc2..fefc0522c7d8 100644 --- a/contrib/ipfilter/test/expected/in6 +++ b/contrib/ipfilter/test/expected/in6 @@ -1,8 +1,8 @@ -map foo0 from any port = 1 to any port != 0 -> 0.0.0.0/32 udp -map foo0 from any port = 1 to any port != 0 -> 0.0.0.0/32 udp -map foo0 from any port < 1 to any port > 0 -> 0.0.0.0/32 tcp -map foo0 from any port < 1 to any port > 0 -> 0.0.0.0/32 tcp -map foo0 from any port <= 1 to any port >= 0 -> 0.0.0.0/32 tcp/udp -map foo0 from any port <= 1 to any port >= 0 -> 0.0.0.0/32 tcp/udp -map foo0 from any port 1 >< 20 to any port 20 <> 40 -> 0.0.0.0/32 tcp/udp -map foo0 from any port 10:20 to any port 30:40 -> 0.0.0.0/32 tcp/udp +map foo0 from 0/0 port = 1 to 0/0 port != 0 -> 0/32 udp +map foo0 from 0/0 port = 1 to 0/0 port != 0 -> 0/32 udp +map foo0 from 0/0 port < 1 to 0/0 port > 0 -> 0/32 tcp +map foo0 from 0/0 port < 1 to 0/0 port > 0 -> 0/32 tcp +map foo0 from 0/0 port <= 1 to 0/0 port >= 0 -> 0/32 tcp/udp +map foo0 from 0/0 port <= 1 to 0/0 port >= 0 -> 0/32 tcp/udp +map foo0 from 0/0 port 1 >< 20 to 0/0 port 20 <> 40 -> 0/32 tcp/udp +map foo0 from 0/0 port 10:20 to 0/0 port 30:40 -> 0/32 tcp/udp diff --git a/contrib/ipfilter/test/expected/in7 b/contrib/ipfilter/test/expected/in7 new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/contrib/ipfilter/test/expected/ip1 b/contrib/ipfilter/test/expected/ip1 index b04fa9d1ad62..cee783193867 100644 --- a/contrib/ipfilter/test/expected/ip1 +++ b/contrib/ipfilter/test/expected/ip1 @@ -1,68 +1,68 @@ -table role = ipf type = tree number = 1 +table role=ipf type=tree number=1 {; }; -table role = ipf type = tree number = 100 - { 2.2.2.0/24; ! 2.2.0.0/16; 1.2.3.4/32; }; -table role = ipf type = tree number = 110 - { 2.2.2.0/24; ! 2.2.0.0/16; 1.2.3.4/32; }; -table role = ipf type = tree number = 120 - { 2.2.2.0/24; ! 2.2.0.0/16; 1.2.3.4/32; }; -table role = ipf type = tree number = 130 - { 2.2.2.0/24; ! 2.2.0.0/16; 1.2.3.4/32; }; -table role = ipf type = hash number = 2 size = 1 +table role=ipf type=tree number=100 + { 1.2.3.4/32; ! 2.2.0.0/16; 2.2.2.0/24; }; +table role=nat type=tree number=110 + { 1.2.3.4/32; ! 2.2.0.0/16; 2.2.2.0/24; }; +table role=auth type=tree number=120 + { 1.2.3.4/32; ! 2.2.0.0/16; 2.2.2.0/24; }; +table role=count type=tree number=130 + { 1.2.3.4/32; ! 2.2.0.0/16; 2.2.2.0/24; }; +table role=ipf type=hash number=2 size=1 {; }; -table role = ipf type = hash number = 200 size = 5 +table role=ipf type=hash number=200 size=5 { 0/0; 1/32; 1.2.3.4/32; }; -table role = nat type = hash number = 210 size = 5 +table role=nat type=hash number=210 size=5 { 0/0; 2/32; 1.2.3.4/32; }; -table role = auth type = hash number = 220 size = 5 +table role=auth type=hash number=220 size=5 { 0/0; 3/32; 1.2.3.4/32; }; -table role = count type = hash number = 230 size = 5 +table role=count type=hash number=230 size=5 { 0/0; 4/32; 1.2.3.4/32; }; -table role = ipf type = hash number = 240 size = 5 seed = 101 +table role=ipf type=hash number=240 size=5 seed=101 { 0/0; 1/32; 1.2.3.4/32; }; -table role = nat type = hash number = 250 size = 5 seed = 101 +table role=nat type=hash number=250 size=5 seed=101 { 0/0; 2/32; 1.2.3.4/32; }; -table role = auth type = hash number = 260 size = 5 seed = 101 +table role=auth type=hash number=260 size=5 seed=101 { 0/0; 3/32; 1.2.3.4/32; }; -table role = count type = hash number = 270 size = 5 seed = 101 +table role=count type=hash number=270 size=5 seed=101 { 0/0; 4/32; 1.2.3.4/32; }; -table role = ipf type = hash number = 2000 size = 1001 +table role=ipf type=hash number=2000 size=1001 { 0/0; 1/32; 1.2.3.4/32; }; -table role = nat type = hash number = 2000 size = 1001 +table role=nat type=hash number=2000 size=1001 { 0/0; 2/32; 1.2.3.4/32; }; -table role = auth type = hash number = 2000 size = 1001 +table role=auth type=hash number=2000 size=1001 { 0/0; 3/32; 1.2.3.4/32; }; -table role = count type = hash number = 2000 size = 1001 +table role=count type=hash number=2000 size=1001 { 0/0; 4/32; 1.2.3.4/32; }; -table role = ipf type = hash number = 100 size = 1001 seed = 101 +table role=ipf type=hash number=100 size=1001 seed=101 { 0/0; 1/32; 1.2.3.4/32; }; -table role = nat type = hash number = 100 size = 1001 seed = 101 +table role=nat type=hash number=100 size=1001 seed=101 { 0/0; 2/32; 1.2.3.4/32; }; -table role = auth type = hash number = 100 size = 1001 seed = 101 +table role=auth type=hash number=100 size=1001 seed=101 { 0/0; 3/32; 1.2.3.4/32; }; -table role = count type = hash number = 100 size = 1001 seed = 101 +table role=count type=hash number=100 size=1001 seed=101 { 0/0; 4/32; 1.2.3.4/32; }; -group-map in role = ipf number = 300 size = 5 - { 0/0, group = 303; 5/32, group = 303; 1.2.3.4/32, group = 303; }; -group-map in role = nat number = 300 size = 5 - { 0/0, group = 303; 6/32, group = 303; 1.2.3.4/32, group = 303; }; -group-map in role = auth number = 300 size = 5 - { 0/0, group = 303; 7/32, group = 303; 1.2.3.4/32, group = 303; }; -group-map in role = count number = 300 size = 5 - { 0/0, group = 303; 8/32, group = 303; 1.2.3.4/32, group = 303; }; -group-map out role = ipf number = 400 size = 5 - { 0/0, group = 303; 5/32, group = 303; 1.2.3.4/32, group = 606; }; -group-map out role = nat number = 400 size = 5 - { 0/0, group = 303; 6/32, group = 303; 1.2.3.4/32, group = 606; }; -group-map out role = auth number = 400 size = 5 - { 0/0, group = 303; 7/32, group = 303; 1.2.3.4/32, group = 606; }; -group-map out role = count number = 400 size = 5 - { 0/0, group = 303; 8/32, group = 303; 1.2.3.4/32, group = 606; }; -group-map in role = ipf number = 500 size = 5 - { 0/0, group = 10; 5/32, group = 800; 1.2.3.4/32, group = 606; }; -group-map in role = nat number = 500 size = 5 - { 0/0, group = 10; 6/32, group = 800; 1.2.3.4/32, group = 606; }; -group-map in role = auth number = 500 size = 5 - { 0/0, group = 10; 7/32, group = 800; 1.2.3.4/32, group = 606; }; -group-map in role = count number = 500 size = 5 - { 0/0, group = 10; 8/32, group = 800; 1.2.3.4/32, group = 606; }; +group-map in role=ipf number=300 size=5 + { 0/0, group=303; 5/32, group=303; 1.2.3.4/32, group=303; }; +group-map in role=nat number=300 size=5 + { 0/0, group=303; 6/32, group=303; 1.2.3.4/32, group=303; }; +group-map in role=auth number=300 size=5 + { 0/0, group=303; 7/32, group=303; 1.2.3.4/32, group=303; }; +group-map in role=count number=300 size=5 + { 0/0, group=303; 8/32, group=303; 1.2.3.4/32, group=303; }; +group-map out role=ipf number=400 size=5 + { 0/0, group=303; 5/32, group=303; 1.2.3.4/32, group=606; }; +group-map out role=nat number=400 size=5 + { 0/0, group=303; 6/32, group=303; 1.2.3.4/32, group=606; }; +group-map out role=auth number=400 size=5 + { 0/0, group=303; 7/32, group=303; 1.2.3.4/32, group=606; }; +group-map out role=count number=400 size=5 + { 0/0, group=303; 8/32, group=303; 1.2.3.4/32, group=606; }; +group-map in role=ipf number=500 size=5 + { 0/0, group=10; 5/32, group=800; 1.2.3.4/32, group=606; }; +group-map in role=nat number=500 size=5 + { 0/0, group=10; 6/32, group=800; 1.2.3.4/32, group=606; }; +group-map in role=auth number=500 size=5 + { 0/0, group=10; 7/32, group=800; 1.2.3.4/32, group=606; }; +group-map in role=count number=500 size=5 + { 0/0, group=10; 8/32, group=800; 1.2.3.4/32, group=606; }; diff --git a/contrib/ipfilter/test/expected/ip2 b/contrib/ipfilter/test/expected/ip2 index 9b0ed2babae6..3de3c471fc92 100644 --- a/contrib/ipfilter/test/expected/ip2 +++ b/contrib/ipfilter/test/expected/ip2 @@ -1,2 +1,2 @@ -table role = ipf type = tree name = letters - { 2.2.2.0/24; ! 2.2.0.0/16; 1.1.1.1/32; }; +table role=ipf type=tree name=letters + { 1.1.1.1/32; ! 2.2.0.0/16; 2.2.2.0/24; }; diff --git a/contrib/ipfilter/test/expected/ip3 b/contrib/ipfilter/test/expected/ip3 new file mode 100644 index 000000000000..48dd074a4c04 --- /dev/null +++ b/contrib/ipfilter/test/expected/ip3 @@ -0,0 +1,14 @@ +pool ipf/dstlist (name fred; policy round-robin;) + { 3.3.3.3; }; +pool ipf/dstlist (name jack; policy weighting connection;) + { 4.4.4.4; bge0:5.5.5.5; }; +pool ipf/dstlist (name jill; policy random;) + { 1.1.1.1; bge0:2.2.2.2; }; +table role=nat type=hash name=noproxy size=3 + { 1.1.1.1/32; 2.2.2.2/32; }; +table role=nat type=tree name=raw + { 1.1.1.1/32; 2.2.2.2/32; }; +pool all/dstlist (name jill; policy random;) + { 1.1.1.1; bge0:2.2.2.2; }; +table role=all type=hash name=noproxy size=3 + { 1.1.1.1/32; 2.2.2.2/32; }; diff --git a/contrib/ipfilter/test/expected/ipv6.4 b/contrib/ipfilter/test/expected/ipv6.4 new file mode 100644 index 000000000000..e3ae842a7474 --- /dev/null +++ b/contrib/ipfilter/test/expected/ipv6.4 @@ -0,0 +1,51 @@ +pass +pass +nomatch +nomatch +pass +pass +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +-------- +pass +pass +pass +pass +pass +pass +pass +pass +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +-------- +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +pass +pass +block +nomatch +nomatch +nomatch +pass +pass +-------- diff --git a/contrib/ipfilter/test/expected/ipv6.6 b/contrib/ipfilter/test/expected/ipv6.6 index abc0e87c6917..efd04212578c 100644 --- a/contrib/ipfilter/test/expected/ipv6.6 +++ b/contrib/ipfilter/test/expected/ipv6.6 @@ -1,3 +1,10 @@ pass pass +pass +pass +-------- +nomatch +nomatch +block +nomatch -------- diff --git a/contrib/ipfilter/test/expected/l1 b/contrib/ipfilter/test/expected/l1 index ba0de69b9239..e4a081d8e825 100644 --- a/contrib/ipfilter/test/expected/l1 +++ b/contrib/ipfilter/test/expected/l1 @@ -1,11 +1,13 @@ log in all +missed 1 ipf log entries: 0 1 01/01/1970 00:00:00.000000 anon0 @-1:-1 L 1.1.1.1,1025 -> 2.2.2.2,25 PR tcp len 20 40 -S IN 01/01/1970 00:00:00.000000 anon0 @-1:-1 L 1.1.1.1,1025 -> 2.2.2.2,25 PR tcp len 20 40 -A IN 01/01/1970 00:00:00.000000 anon0 @-1:-1 L 2.2.2.2,25 -> 1.1.1.1,1025 PR tcp len 20 40 -AS IN 01/01/1970 00:00:00.000000 anon0 @-1:-1 L 1.1.1.1,1025 -> 2.2.2.2,25 PR tcp len 20 40 -AF IN 01/01/1970 00:00:00.000000 2x anon0 @-1:-1 L 1.1.1.1,1025 -> 2.2.2.2,25 PR tcp len 20 40 -A IN 01/01/1970 00:00:00.000000 anon0 @-1:-1 L 1.1.1.1,1 -> 4.4.4.4,53 PR udp len 20 40 IN -01/01/1970 00:00:00.000000 2x anon0 @-1:-1 L 2.2.2.2,1 -> 4.4.4.4,53 PR udp len 20 40 IN +01/01/1970 00:00:00.000000 anon0 @-1:-1 L 2.2.2.2,1 -> 4.4.4.4,53 PR udp len 20 40 IN +01/01/1970 00:00:00.000000 anon0 @-1:-1 L 2.2.2.2,1 -> 4.4.4.4,53 PR udp len 20 56 IN 01/01/1970 00:00:00.000000 anon0 @-1:-1 L 2.2.2.2 -> 4.4.4.4 PR ip len 20 (20) IN 01/01/1970 00:00:00.000000 anon0 @-1:-1 L 3.3.3.3,1023 -> 1.1.1.1,2049 PR udp len 20 28 IN 01/01/1970 00:00:00.000000 anon0 @-1:-1 L 1.1.1.1,2049 -> 3.3.3.3,1023 PR udp len 20 28 IN @@ -15,11 +17,14 @@ pass in on anon0 all head 100 pass in log quick from 3.3.3.3 to any group 100 -------- pass in log body quick from 2.2.2.2 to any +missed 1 ipf log entries: 0 1 01/01/1970 00:00:00.000000 anon0 @0:1 p 2.2.2.2,25 -> 1.1.1.1,1025 PR tcp len 20 40 -AS IN -01/01/1970 00:00:00.000000 2x anon0 @0:1 p 2.2.2.2,1 -> 4.4.4.4,53 PR udp len 20 40 IN +01/01/1970 00:00:00.000000 anon0 @0:1 p 2.2.2.2,1 -> 4.4.4.4,53 PR udp len 20 40 IN +01/01/1970 00:00:00.000000 anon0 @0:1 p 2.2.2.2,1 -> 4.4.4.4,53 PR udp len 20 56 IN 01/01/1970 00:00:00.000000 anon0 @0:1 p 2.2.2.2 -> 4.4.4.4 PR ip len 20 (20) IN -------- pass in log quick proto tcp from 1.1.1.1 to any flags S keep state +missed 1 ipf log entries: 0 1 01/01/1970 00:00:00.000000 anon0 @0:1 p 1.1.1.1,1025 -> 2.2.2.2,25 PR tcp len 20 40 -S K-S IN 01/01/1970 00:00:00.000000 anon0 @0:1 p 1.1.1.1,1025 -> 2.2.2.2,25 PR tcp len 20 40 -A K-S IN 01/01/1970 00:00:00.000000 anon0 @0:1 p 2.2.2.2,25 -> 1.1.1.1,1025 PR tcp len 20 40 -AS K-S IN @@ -27,8 +32,10 @@ pass in log quick proto tcp from 1.1.1.1 to any flags S keep state 01/01/1970 00:00:00.000000 anon0 @0:1 p 1.1.1.1,1025 -> 2.2.2.2,25 PR tcp len 20 40 -AF K-S IN -------- pass in log first quick proto tcp from 1.1.1.1 to any flags S keep state +missed 1 ipf log entries: 0 1 01/01/1970 00:00:00.000000 anon0 @0:1 p 1.1.1.1,1025 -> 2.2.2.2,25 PR tcp len 20 40 -S K-S IN -------- +missed 1 ipf log entries: 0 1 01/01/1970 00:00:00.000000 anon0 @-1:-1 L 1.1.1.1,1025 -> 2.2.2.2,25 PR tcp len 20 40 -S IN 01/01/1970 00:00:00.000000 anon0 @0:4 p 1.1.1.1,1025 -> 2.2.2.2,25 PR tcp len 20 40 -S K-S IN 01/01/1970 00:00:00.000000 anon0 @0:4 p 1.1.1.1,1025 -> 2.2.2.2,25 PR tcp len 20 40 -A K-S IN diff --git a/contrib/ipfilter/test/expected/l1.b b/contrib/ipfilter/test/expected/l1.b index c060086d8df4..e06e486fcf3a 100644 --- a/contrib/ipfilter/test/expected/l1.b +++ b/contrib/ipfilter/test/expected/l1.b @@ -1,29 +1,38 @@ +missed 1 ipf log entries: 0 1 01/01/1970 00:00:00.000000 anon0 @-1:-1 L 1.1.1.1,1025 -> 2.2.2.2,25 PR tcp len 20 40 -S IN 01/01/1970 00:00:00.000000 anon0 @-1:-1 L 1.1.1.1,1025 -> 2.2.2.2,25 PR tcp len 20 40 -A IN 01/01/1970 00:00:00.000000 anon0 @-1:-1 L 2.2.2.2,25 -> 1.1.1.1,1025 PR tcp len 20 40 -AS IN 01/01/1970 00:00:00.000000 anon0 @-1:-1 L 1.1.1.1,1025 -> 2.2.2.2,25 PR tcp len 20 40 -AF IN 01/01/1970 00:00:00.000000 2x anon0 @-1:-1 L 1.1.1.1,1025 -> 2.2.2.2,25 PR tcp len 20 40 -A IN 01/01/1970 00:00:00.000000 anon0 @-1:-1 L 1.1.1.1,1 -> 4.4.4.4,53 PR udp len 20 40 IN -01/01/1970 00:00:00.000000 2x anon0 @-1:-1 L 2.2.2.2,1 -> 4.4.4.4,53 PR udp len 20 40 IN +01/01/1970 00:00:00.000000 anon0 @-1:-1 L 2.2.2.2,1 -> 4.4.4.4,53 PR udp len 20 40 IN +01/01/1970 00:00:00.000000 anon0 @-1:-1 L 2.2.2.2,1 -> 4.4.4.4,53 PR udp len 20 56 IN 01/01/1970 00:00:00.000000 anon0 @-1:-1 L 2.2.2.2 -> 4.4.4.4 PR ip len 20 (20) IN 01/01/1970 00:00:00.000000 anon0 @-1:-1 L 3.3.3.3,1023 -> 1.1.1.1,2049 PR udp len 20 28 IN 01/01/1970 00:00:00.000000 anon0 @-1:-1 L 1.1.1.1,2049 -> 3.3.3.3,1023 PR udp len 20 28 IN -------- -------- -------- +missed 1 ipf log entries: 0 1 01/01/1970 00:00:00.000000 anon0 @0:1 p 2.2.2.2,25 -> 1.1.1.1,1025 PR tcp len 20 40 -AS IN -01/01/1970 00:00:00.000000 2x anon0 @0:1 p 2.2.2.2,1 -> 4.4.4.4,53 PR udp len 20 40 IN +01/01/1970 00:00:00.000000 anon0 @0:1 p 2.2.2.2,1 -> 4.4.4.4,53 PR udp len 20 40 IN 01 02 03 04 05 06 07 08 09 0a 0b 0d ............ +01/01/1970 00:00:00.000000 anon0 @0:1 p 2.2.2.2,1 -> 4.4.4.4,53 PR udp len 20 56 IN +01 02 03 04 05 06 07 08 09 0a 0b 0d 0e 0f 40 61 ..............@a +42 63 44 65 46 67 48 69 4a 6b 4c 6d BcDeFgHiJkLm 01/01/1970 00:00:00.000000 anon0 @0:1 p 2.2.2.2 -> 4.4.4.4 PR ip len 20 (20) IN -------- +missed 1 ipf log entries: 0 1 01/01/1970 00:00:00.000000 anon0 @0:1 p 1.1.1.1,1025 -> 2.2.2.2,25 PR tcp len 20 40 -S K-S IN 01/01/1970 00:00:00.000000 anon0 @0:1 p 1.1.1.1,1025 -> 2.2.2.2,25 PR tcp len 20 40 -A K-S IN 01/01/1970 00:00:00.000000 anon0 @0:1 p 2.2.2.2,25 -> 1.1.1.1,1025 PR tcp len 20 40 -AS K-S IN 01/01/1970 00:00:00.000000 e1 @0:1 p 2.2.2.2,25 -> 1.1.1.1,1025 PR tcp len 20 40 -A K-S OUT 01/01/1970 00:00:00.000000 anon0 @0:1 p 1.1.1.1,1025 -> 2.2.2.2,25 PR tcp len 20 40 -AF K-S IN -------- +missed 1 ipf log entries: 0 1 01/01/1970 00:00:00.000000 anon0 @0:1 p 1.1.1.1,1025 -> 2.2.2.2,25 PR tcp len 20 40 -S K-S IN -------- +missed 1 ipf log entries: 0 1 01/01/1970 00:00:00.000000 anon0 @-1:-1 L 1.1.1.1,1025 -> 2.2.2.2,25 PR tcp len 20 40 -S IN 01/01/1970 00:00:00.000000 anon0 @0:4 p 1.1.1.1,1025 -> 2.2.2.2,25 PR tcp len 20 40 -S K-S IN 01/01/1970 00:00:00.000000 anon0 @0:4 p 1.1.1.1,1025 -> 2.2.2.2,25 PR tcp len 20 40 -A K-S IN diff --git a/contrib/ipfilter/test/expected/n1 b/contrib/ipfilter/test/expected/n1 index 537f9bb65503..20eaedc8ea89 100644 --- a/contrib/ipfilter/test/expected/n1 +++ b/contrib/ipfilter/test/expected/n1 @@ -1,105 +1,197 @@ -ip #0 20(20) 255 10.1.1.0 > 10.1.1.2 -ip #0 20(20) 255 10.2.2.2 > 10.1.1.2 -ip #0 20(20) 255 10.1.1.2 > 10.1.1.1 -ip #0 40(20) 6 10.1.1.2,1025 > 10.1.1.1,1025 -ip #0 40(20) 6 10.1.1.2,1026 > 10.1.1.1,1025 -ip #0 20(20) 255 10.2.2.1 > 10.1.2.1 -ip #0 20(20) 255 10.2.2.2 > 10.1.2.1 -ip #0 20(20) 255 10.1.1.1 > 10.1.1.2 -ip #0 20(20) 255 10.1.1.2 > 10.1.1.1 -ip #0 20(20) 255 10.2.2.1 > 10.2.1.1 -ip #0 20(20) 255 10.2.2.2 > 10.2.1.1 -ip #0 20(20) 255 10.2.2.3 > 10.1.1.1 -ip #0 20(20) 255 10.2.3.4 > 10.2.2.2 -ip #0 20(20) 255 10.1.1.1 > 10.2.2.2 -ip #0 20(20) 255 10.1.1.2 > 10.1.1.1 -ip #0 20(20) 255 10.1.1.0 > 10.3.4.5 -ip #0 20(20) 255 10.1.1.1 > 10.3.4.5 -ip #0 20(20) 255 10.1.1.2 > 10.3.4.5 -ip #0 40(20) 6 10.1.1.1,1025 > 10.3.4.5,1025 -ip #0 48(20) 1 10.2.2.2 > 10.4.3.2 -ip #0 48(20) 1 10.4.3.2 > 10.1.1.1 -ip #0 48(20) 1 10.4.3.2 > 10.3.4.1 -ip #0 48(20) 1 10.4.3.2 > 10.3.4.2 -ip #0 48(20) 1 10.4.3.2 > 10.3.4.3 -ip #0 48(20) 1 10.4.3.2 > 10.3.4.4 -ip #0 48(20) 1 10.4.3.2 > 10.3.4.5 -ip #0 20(20) 34 10.1.1.2 > 10.4.3.2 -ip #0 20(20) 34 10.4.3.2 > 10.3.4.4 -ip #0 20(20) 34 10.1.1.2 > 10.4.3.4 -ip #0 20(20) 34 10.4.3.4 > 10.3.4.5 -ip #0 20(20) 34 10.1.1.3 > 10.4.3.4 -ip #0 20(20) 34 10.4.3.4 > 10.3.4.6 -ip #0 20(20) 35 10.1.1.3 > 10.4.3.4 -ip #0 20(20) 35 10.4.3.4 > 10.3.4.7 +> zx0 ip #0 20(20) 255 10.1.1.0 > 10.1.1.2 +> zx0 ip #0 20(20) 255 10.2.2.2 > 10.1.1.2 +> zx0 ip #0 20(20) 255 10.1.1.2 > 10.1.1.1 +> zx0 ip #0 40(20) 6 10.1.1.2,1025 > 10.1.1.1,1025 +> zx0 ip #0 40(20) 6 10.1.1.2,1026 > 10.1.1.1,1025 +> zx0 ip #0 20(20) 255 10.2.2.1 > 10.1.2.1 +> zx0 ip #0 20(20) 255 10.2.2.2 > 10.1.2.1 +< zx0 ip #0 20(20) 255 10.1.1.1 > 10.1.1.2 +< zx0 ip #0 20(20) 255 10.1.1.2 > 10.1.1.1 +< zx0 ip #0 20(20) 255 10.2.2.1 > 10.2.1.1 +< zx0 ip #0 20(20) 255 10.2.2.2 > 10.2.1.1 +< zx0 ip #0 20(20) 255 10.2.2.3 > 10.1.1.1 +< zx0 ip #0 20(20) 255 10.2.3.4 > 10.2.2.2 +< zx0 ip #0 20(20) 255 10.1.1.1 > 10.2.2.2 +< zx0 ip #0 20(20) 255 10.1.1.2 > 10.1.1.1 +< zx0 ip #0 20(20) 255 10.1.1.0 > 10.3.4.5 +< zx0 ip #0 20(20) 255 10.1.1.1 > 10.3.4.5 +< zx0 ip #0 20(20) 255 10.1.1.2 > 10.3.4.5 +< zx0 ip #0 40(20) 6 10.1.1.1,1025 > 10.3.4.5,1025 +> zx0 ip #0 48(20) 1 10.2.2.2 > 10.4.3.2 +< zx0 ip #0 48(20) 1 10.4.3.2 > 10.1.1.1 +< zx0 ip #0 48(20) 1 10.4.3.2 > 10.3.4.1 +< zx0 ip #0 48(20) 1 10.4.3.2 > 10.3.4.2 +< zx0 ip #0 48(20) 1 10.4.3.2 > 10.3.4.3 +< zx0 ip #0 48(20) 1 10.4.3.2 > 10.3.4.4 +< zx0 ip #0 48(20) 1 10.4.3.2 > 10.3.4.5 +> zx0 ip #0 20(20) 34 10.1.1.2 > 10.4.3.2 +< zx0 ip #0 20(20) 34 10.4.3.2 > 10.3.4.4 +> zx0 ip #0 20(20) 34 10.1.1.2 > 10.4.3.4 +< zx0 ip #0 20(20) 34 10.4.3.4 > 10.3.4.5 +> zx0 ip #0 20(20) 34 10.1.1.3 > 10.4.3.4 +< zx0 ip #0 20(20) 34 10.4.3.4 > 10.3.4.6 +> zx0 ip #0 20(20) 35 10.1.1.3 > 10.4.3.4 +< zx0 ip #0 20(20) 35 10.4.3.4 > 10.3.4.7 +List of active MAP/Redirect filters: +map zx0 10.1.1.1/32 -> 10.2.2.2/32 + +List of active sessions: +MAP 10.1.1.1 <- -> 10.2.2.2 [10.4.3.2] +MAP 10.1.1.1 <- -> 10.2.2.2 [10.1.1.2] + +Hostmap table: +10.1.1.1,10.4.3.2 -> 10.2.2.2,0.0.0.0 (use = 1) +10.1.1.1,10.1.1.2 -> 10.2.2.2,0.0.0.0 (use = 1) +List of active state sessions: +List of configured pools +List of configured hash tables +List of groups configured (set 0) +List of groups configured (set 1) +Rules configured (set 0, in) +Rules configured (set 0, out) +Rules configured (set 1, in) +Rules configured (set 1, out) +Accounting rules configured (set 0, in) +Accounting rules configured (set 0, out) +Accounting rules configured (set 1, in) +Accounting rules configured (set 1, out) ------------------------------- -ip #0 20(20) 255 10.3.4.5 > 10.1.1.2 -ip #0 20(20) 255 10.1.1.1 > 10.1.1.2 -ip #0 20(20) 255 10.3.4.5 > 10.1.1.1 -ip #0 40(20) 6 10.3.4.5,1025 > 10.1.1.1,1025 -ip #0 40(20) 6 10.3.4.5,1026 > 10.1.1.1,1025 -ip #0 20(20) 255 10.2.2.1 > 10.1.2.1 -ip #0 20(20) 255 10.2.2.2 > 10.1.2.1 -ip #0 20(20) 255 10.1.1.1 > 10.1.1.2 -ip #0 20(20) 255 10.1.1.2 > 10.1.1.1 -ip #0 20(20) 255 10.2.2.1 > 10.2.1.1 -ip #0 20(20) 255 10.2.2.2 > 10.2.1.1 -ip #0 20(20) 255 10.2.2.3 > 10.1.1.1 -ip #0 20(20) 255 10.2.3.4 > 10.2.2.2 -ip #0 20(20) 255 10.1.1.1 > 10.2.2.2 -ip #0 20(20) 255 10.1.1.2 > 10.2.2.2 -ip #0 20(20) 255 10.1.1.0 > 10.3.4.5 -ip #0 20(20) 255 10.1.1.1 > 10.1.1.2 -ip #0 20(20) 255 10.1.1.2 > 10.1.1.0 -ip #0 40(20) 6 10.1.1.1,1025 > 10.1.1.2,1025 -ip #0 48(20) 1 10.3.4.5 > 10.4.3.2 -ip #0 48(20) 1 10.4.3.2 > 10.2.2.2 -ip #0 48(20) 1 10.4.3.2 > 10.3.4.1 -ip #0 48(20) 1 10.4.3.2 > 10.3.4.2 -ip #0 48(20) 1 10.4.3.2 > 10.3.4.3 -ip #0 48(20) 1 10.4.3.2 > 10.3.4.4 -ip #0 48(20) 1 10.4.3.2 > 10.1.1.1 -ip #0 20(20) 34 10.3.4.5 > 10.4.3.2 -ip #0 20(20) 34 10.4.3.2 > 10.3.4.4 -ip #0 20(20) 34 10.3.4.5 > 10.4.3.4 -ip #0 20(20) 34 10.4.3.4 > 10.1.1.2 -ip #0 20(20) 34 10.1.1.3 > 10.4.3.4 -ip #0 20(20) 34 10.4.3.4 > 10.3.4.6 -ip #0 20(20) 35 10.3.4.5 > 10.4.3.4 -ip #0 20(20) 35 10.4.3.4 > 10.3.4.7 +> zx0 ip #0 20(20) 255 10.3.4.5 > 10.1.1.2 +15 +> zx0 ip #0 20(20) 255 10.3.4.5 > 10.1.1.1 +> zx0 ip #0 40(20) 6 10.3.4.5,1025 > 10.1.1.1,1025 +> zx0 ip #0 40(20) 6 10.3.4.5,1026 > 10.1.1.1,1025 +> zx0 ip #0 20(20) 255 10.2.2.1 > 10.1.2.1 +> zx0 ip #0 20(20) 255 10.2.2.2 > 10.1.2.1 +< zx0 ip #0 20(20) 255 10.1.1.1 > 10.1.1.2 +< zx0 ip #0 20(20) 255 10.1.1.2 > 10.1.1.1 +< zx0 ip #0 20(20) 255 10.2.2.1 > 10.2.1.1 +< zx0 ip #0 20(20) 255 10.2.2.2 > 10.2.1.1 +< zx0 ip #0 20(20) 255 10.2.2.3 > 10.1.1.1 +< zx0 ip #0 20(20) 255 10.2.3.4 > 10.2.2.2 +< zx0 ip #0 20(20) 255 10.1.1.1 > 10.2.2.2 +< zx0 ip #0 20(20) 255 10.1.1.2 > 10.2.2.2 +< zx0 ip #0 20(20) 255 10.1.1.0 > 10.3.4.5 +< zx0 ip #0 20(20) 255 10.1.1.1 > 10.1.1.2 +< zx0 ip #0 20(20) 255 10.1.1.2 > 10.1.1.0 +< zx0 ip #0 40(20) 6 10.1.1.1,1025 > 10.1.1.2,1025 +> zx0 ip #0 48(20) 1 10.3.4.5 > 10.4.3.2 +< zx0 ip #0 48(20) 1 10.4.3.2 > 10.2.2.2 +< zx0 ip #0 48(20) 1 10.4.3.2 > 10.3.4.1 +< zx0 ip #0 48(20) 1 10.4.3.2 > 10.3.4.2 +< zx0 ip #0 48(20) 1 10.4.3.2 > 10.3.4.3 +< zx0 ip #0 48(20) 1 10.4.3.2 > 10.3.4.4 +< zx0 ip #0 48(20) 1 10.4.3.2 > 10.1.1.1 +> zx0 ip #0 20(20) 34 10.3.4.5 > 10.4.3.2 +< zx0 ip #0 20(20) 34 10.4.3.2 > 10.3.4.4 +> zx0 ip #0 20(20) 34 10.3.4.5 > 10.4.3.4 +< zx0 ip #0 20(20) 34 10.4.3.4 > 10.1.1.2 +15 +< zx0 ip #0 20(20) 34 10.4.3.4 > 10.3.4.6 +> zx0 ip #0 20(20) 35 10.3.4.5 > 10.4.3.4 +< zx0 ip #0 20(20) 35 10.4.3.4 > 10.3.4.7 +List of active MAP/Redirect filters: +map zx0 10.1.1.0/24 -> 10.3.4.5/32 + +List of active sessions: +MAP 10.1.1.3 <- -> 10.3.4.5 [10.4.3.4] +MAP 10.1.1.2 <- -> 10.3.4.5 [10.4.3.4] +MAP 10.1.1.2 <- -> 10.3.4.5 [10.4.3.2] +MAP 10.1.1.1 <- -> 10.3.4.5 [10.4.3.2] +MAP 10.1.1.2 1026 <- -> 10.3.4.5 1026 [10.1.1.1 1025] +MAP 10.1.1.2 1025 <- -> 10.3.4.5 1025 [10.1.1.1 1025] +MAP 10.1.1.2 <- -> 10.3.4.5 [10.1.1.1] +MAP 10.1.1.0 <- -> 10.3.4.5 [10.1.1.2] + +Hostmap table: +10.1.1.3,10.4.3.4 -> 10.3.4.5,0.0.0.0 (use = 1) +10.1.1.2,10.4.3.4 -> 10.3.4.5,0.0.0.0 (use = 1) +10.1.1.2,10.4.3.2 -> 10.3.4.5,0.0.0.0 (use = 1) +10.1.1.1,10.4.3.2 -> 10.3.4.5,0.0.0.0 (use = 1) +10.1.1.2,10.1.1.1 -> 10.3.4.5,0.0.0.0 (use = 3) +10.1.1.0,10.1.1.2 -> 10.3.4.5,0.0.0.0 (use = 1) +List of active state sessions: +List of configured pools +List of configured hash tables +List of groups configured (set 0) +List of groups configured (set 1) +Rules configured (set 0, in) +Rules configured (set 0, out) +Rules configured (set 1, in) +Rules configured (set 1, out) +Accounting rules configured (set 0, in) +Accounting rules configured (set 0, out) +Accounting rules configured (set 1, in) +Accounting rules configured (set 1, out) ------------------------------- -ip #0 20(20) 255 10.3.4.1 > 10.1.1.2 -ip #0 20(20) 255 10.3.4.2 > 10.1.1.2 -ip #0 20(20) 255 10.3.4.3 > 10.1.1.1 -ip #0 40(20) 6 10.3.4.3,1025 > 10.1.1.1,1025 -ip #0 40(20) 6 10.3.4.3,1026 > 10.1.1.1,1025 -ip #0 20(20) 255 10.2.2.1 > 10.1.2.1 -ip #0 20(20) 255 10.2.2.2 > 10.1.2.1 -ip #0 20(20) 255 10.1.1.1 > 10.1.1.2 -ip #0 20(20) 255 10.1.1.2 > 10.1.1.1 -ip #0 20(20) 255 10.2.2.1 > 10.2.1.1 -ip #0 20(20) 255 10.2.2.2 > 10.2.1.1 -ip #0 20(20) 255 10.2.2.3 > 10.1.1.1 -ip #0 20(20) 255 10.2.3.4 > 10.2.2.2 -ip #0 20(20) 255 10.1.1.1 > 10.2.2.2 -ip #0 20(20) 255 10.1.1.2 > 10.2.2.2 -ip #0 20(20) 255 10.1.1.0 > 10.3.4.5 -ip #0 20(20) 255 10.1.1.1 > 10.3.4.5 -ip #0 20(20) 255 10.1.1.2 > 10.3.4.5 -ip #0 40(20) 6 10.1.1.1,1025 > 10.3.4.5,1025 -ip #0 48(20) 1 10.3.4.3 > 10.4.3.2 -ip #0 48(20) 1 10.4.3.2 > 10.2.2.2 -ip #0 48(20) 1 10.4.3.2 > 10.3.4.1 -ip #0 48(20) 1 10.4.3.2 > 10.3.4.2 -ip #0 48(20) 1 10.4.3.2 > 10.1.1.1 -ip #0 48(20) 1 10.4.3.2 > 10.3.4.4 -ip #0 48(20) 1 10.4.3.2 > 10.3.4.5 -ip #0 20(20) 34 10.3.4.3 > 10.4.3.2 -ip #0 20(20) 34 10.4.3.2 > 10.3.4.4 -ip #0 20(20) 34 10.3.4.3 > 10.4.3.4 -ip #0 20(20) 34 10.4.3.4 > 10.3.4.5 -ip #0 20(20) 34 10.3.4.4 > 10.4.3.4 -ip #0 20(20) 34 10.4.3.4 > 10.3.4.6 -ip #0 20(20) 35 10.3.4.4 > 10.4.3.4 -ip #0 20(20) 35 10.4.3.4 > 10.3.4.7 +> zx0 ip #0 20(20) 255 10.3.4.1 > 10.1.1.2 +> zx0 ip #0 20(20) 255 10.3.4.2 > 10.1.1.2 +> zx0 ip #0 20(20) 255 10.3.4.3 > 10.1.1.1 +> zx0 ip #0 40(20) 6 10.3.4.3,1025 > 10.1.1.1,1025 +> zx0 ip #0 40(20) 6 10.3.4.3,1026 > 10.1.1.1,1025 +> zx0 ip #0 20(20) 255 10.2.2.1 > 10.1.2.1 +> zx0 ip #0 20(20) 255 10.2.2.2 > 10.1.2.1 +< zx0 ip #0 20(20) 255 10.1.1.1 > 10.1.1.2 +< zx0 ip #0 20(20) 255 10.1.1.2 > 10.1.1.1 +< zx0 ip #0 20(20) 255 10.2.2.1 > 10.2.1.1 +< zx0 ip #0 20(20) 255 10.2.2.2 > 10.2.1.1 +< zx0 ip #0 20(20) 255 10.2.2.3 > 10.1.1.1 +< zx0 ip #0 20(20) 255 10.2.3.4 > 10.2.2.2 +< zx0 ip #0 20(20) 255 10.1.1.1 > 10.2.2.2 +< zx0 ip #0 20(20) 255 10.1.1.2 > 10.2.2.2 +< zx0 ip #0 20(20) 255 10.1.1.0 > 10.3.4.5 +< zx0 ip #0 20(20) 255 10.1.1.1 > 10.3.4.5 +< zx0 ip #0 20(20) 255 10.1.1.2 > 10.3.4.5 +< zx0 ip #0 40(20) 6 10.1.1.1,1025 > 10.3.4.5,1025 +> zx0 ip #0 48(20) 1 10.3.4.3 > 10.4.3.2 +< zx0 ip #0 48(20) 1 10.4.3.2 > 10.2.2.2 +< zx0 ip #0 48(20) 1 10.4.3.2 > 10.3.4.1 +< zx0 ip #0 48(20) 1 10.4.3.2 > 10.3.4.2 +< zx0 ip #0 48(20) 1 10.4.3.2 > 10.1.1.1 +< zx0 ip #0 48(20) 1 10.4.3.2 > 10.3.4.4 +< zx0 ip #0 48(20) 1 10.4.3.2 > 10.3.4.5 +> zx0 ip #0 20(20) 34 10.3.4.3 > 10.4.3.2 +< zx0 ip #0 20(20) 34 10.4.3.2 > 10.3.4.4 +> zx0 ip #0 20(20) 34 10.3.4.3 > 10.4.3.4 +< zx0 ip #0 20(20) 34 10.4.3.4 > 10.3.4.5 +> zx0 ip #0 20(20) 34 10.3.4.4 > 10.4.3.4 +< zx0 ip #0 20(20) 34 10.4.3.4 > 10.3.4.6 +> zx0 ip #0 20(20) 35 10.3.4.4 > 10.4.3.4 +< zx0 ip #0 20(20) 35 10.4.3.4 > 10.3.4.7 +List of active MAP/Redirect filters: +map zx0 10.1.1.0/24 -> 10.3.4.0/24 + +List of active sessions: +MAP 10.1.1.3 <- -> 10.3.4.4 [10.4.3.4] +MAP 10.1.1.3 <- -> 10.3.4.4 [10.4.3.4] +MAP 10.1.1.2 <- -> 10.3.4.3 [10.4.3.4] +MAP 10.1.1.2 <- -> 10.3.4.3 [10.4.3.2] +MAP 10.1.1.1 <- -> 10.3.4.3 [10.4.3.2] +MAP 10.1.1.2 1026 <- -> 10.3.4.3 1026 [10.1.1.1 1025] +MAP 10.1.1.2 1025 <- -> 10.3.4.3 1025 [10.1.1.1 1025] +MAP 10.1.1.2 <- -> 10.3.4.3 [10.1.1.1] +MAP 10.1.1.1 <- -> 10.3.4.2 [10.1.1.2] +MAP 10.1.1.0 <- -> 10.3.4.1 [10.1.1.2] + +Hostmap table: +10.1.1.3,10.4.3.4 -> 10.3.4.4,0.0.0.0 (use = 2) +10.1.1.2,10.4.3.4 -> 10.3.4.3,0.0.0.0 (use = 1) +10.1.1.2,10.4.3.2 -> 10.3.4.3,0.0.0.0 (use = 1) +10.1.1.1,10.4.3.2 -> 10.3.4.3,0.0.0.0 (use = 1) +10.1.1.2,10.1.1.1 -> 10.3.4.3,0.0.0.0 (use = 3) +10.1.1.1,10.1.1.2 -> 10.3.4.2,0.0.0.0 (use = 1) +10.1.1.0,10.1.1.2 -> 10.3.4.1,0.0.0.0 (use = 1) +List of active state sessions: +List of configured pools +List of configured hash tables +List of groups configured (set 0) +List of groups configured (set 1) +Rules configured (set 0, in) +Rules configured (set 0, out) +Rules configured (set 1, in) +Rules configured (set 1, out) +Accounting rules configured (set 0, in) +Accounting rules configured (set 0, out) +Accounting rules configured (set 1, in) +Accounting rules configured (set 1, out) ------------------------------- diff --git a/contrib/ipfilter/test/expected/n10 b/contrib/ipfilter/test/expected/n10 index ae541d158571..0c03ff088b70 100644 --- a/contrib/ipfilter/test/expected/n10 +++ b/contrib/ipfilter/test/expected/n10 @@ -1,9 +1,72 @@ 4500 002c 10c9 4000 ff06 5c9d cbcb cbcb 96cb e002 8032 0015 bd6b c9c8 0000 0000 6002 2238 655d 0000 0204 0064 +List of active MAP/Redirect filters: +map ppp0 0/0 -> 203.203.203.203/32 mssclamp 100 + +List of active sessions: +MAP 192.168.1.3 32818 <- -> 203.203.203.203 32818 [150.203.224.2 21] + +Hostmap table: +192.168.1.3,150.203.224.2 -> 203.203.203.203,0.0.0.0 (use = 1) +List of active state sessions: +List of configured pools +List of configured hash tables +List of groups configured (set 0) +List of groups configured (set 1) +Rules configured (set 0, in) +Rules configured (set 0, out) +Rules configured (set 1, in) +Rules configured (set 1, out) +Accounting rules configured (set 0, in) +Accounting rules configured (set 0, out) +Accounting rules configured (set 1, in) +Accounting rules configured (set 1, out) ------------------------------- 4500 002c 10c9 4000 ff06 5c9d cbcb cbcb 96cb e002 8032 0015 bd6b c9c8 0000 0000 6002 2238 61d9 0000 0204 03e8 +List of active MAP/Redirect filters: +map ppp0 0/0 -> 203.203.203.203/32 mssclamp 1000 + +List of active sessions: +MAP 192.168.1.3 32818 <- -> 203.203.203.203 32818 [150.203.224.2 21] + +Hostmap table: +192.168.1.3,150.203.224.2 -> 203.203.203.203,0.0.0.0 (use = 1) +List of active state sessions: +List of configured pools +List of configured hash tables +List of groups configured (set 0) +List of groups configured (set 1) +Rules configured (set 0, in) +Rules configured (set 0, out) +Rules configured (set 1, in) +Rules configured (set 1, out) +Accounting rules configured (set 0, in) +Accounting rules configured (set 0, out) +Accounting rules configured (set 1, in) +Accounting rules configured (set 1, out) ------------------------------- 4500 002c 10c9 4000 ff06 5c9d cbcb cbcb 96cb e002 8032 0015 bd6b c9c8 0000 0000 6002 2238 600d 0000 0204 05b4 +List of active MAP/Redirect filters: +map ppp0 0/0 -> 203.203.203.203/32 mssclamp 10000 + +List of active sessions: +MAP 192.168.1.3 32818 <- -> 203.203.203.203 32818 [150.203.224.2 21] + +Hostmap table: +192.168.1.3,150.203.224.2 -> 203.203.203.203,0.0.0.0 (use = 1) +List of active state sessions: +List of configured pools +List of configured hash tables +List of groups configured (set 0) +List of groups configured (set 1) +Rules configured (set 0, in) +Rules configured (set 0, out) +Rules configured (set 1, in) +Rules configured (set 1, out) +Accounting rules configured (set 0, in) +Accounting rules configured (set 0, out) +Accounting rules configured (set 1, in) +Accounting rules configured (set 1, out) ------------------------------- diff --git a/contrib/ipfilter/test/expected/n100 b/contrib/ipfilter/test/expected/n100 new file mode 100644 index 000000000000..80f00a178f30 --- /dev/null +++ b/contrib/ipfilter/test/expected/n100 @@ -0,0 +1,33 @@ +> zx0 ip #0 20(20) 255 1.1.1.1 > 2.3.2.3 +> zx0 ip #0 20(20) 255 4.4.4.4 > 6.6.0.1 +> zx0 ip #0 20(20) 255 4.4.4.4 > 6.6.0.2 +> zx0 ip #0 20(20) 255 4.4.4.4 > 6.6.0.3 +> zx0 ip #0 20(20) 255 4.4.4.4 > 6.6.0.4 +> zx0 ip #0 20(20) 255 4.4.4.4 > 6.6.0.1 +> zx0 ip #0 40(20) 6 1.1.1.1,101 > 2.3.2.3,203 +> zx0 ip #0 40(20) 6 4.4.4.4,101 > 6.6.0.5,203 +List of active MAP/Redirect filters: +rewrite out on zx0 from 0/0 to 2.2.0.0/16 -> src 4.4.4.4/32 dst 6.6.0.0/16; + +List of active sessions: +RWR-MAP 1.1.1.1 101 2.2.2.3 203 <- -> 4.4.4.4 101 6.6.0.5 203 +RWR-MAP 1.1.1.1 2.2.2.4 <- -> 4.4.4.4 6.6.0.4 +RWR-MAP 1.2.1.2 2.2.2.3 <- -> 4.4.4.4 6.6.0.3 +RWR-MAP 1.1.1.2 2.2.2.3 <- -> 4.4.4.4 6.6.0.2 +RWR-MAP 1.1.1.1 2.2.2.3 <- -> 4.4.4.4 6.6.0.1 + +Hostmap table: +List of active state sessions: +List of configured pools +List of configured hash tables +List of groups configured (set 0) +List of groups configured (set 1) +Rules configured (set 0, in) +Rules configured (set 0, out) +Rules configured (set 1, in) +Rules configured (set 1, out) +Accounting rules configured (set 0, in) +Accounting rules configured (set 0, out) +Accounting rules configured (set 1, in) +Accounting rules configured (set 1, out) +------------------------------- diff --git a/contrib/ipfilter/test/expected/n101 b/contrib/ipfilter/test/expected/n101 new file mode 100644 index 000000000000..ad0ad97bc3a6 --- /dev/null +++ b/contrib/ipfilter/test/expected/n101 @@ -0,0 +1,29 @@ +> zx0 ip #0 20(20) 255 1.1.1.1 > 2.3.2.3 +> zx0 ip #0 20(20) 255 1.1.1.1 > 2.2.2.3 +> zx0 ip #0 20(20) 255 1.1.1.2 > 2.2.2.3 +> zx0 ip #0 20(20) 255 1.2.1.2 > 2.2.2.3 +> zx0 ip #0 20(20) 255 1.1.1.1 > 2.2.2.4 +> zx0 ip #0 20(20) 255 1.1.1.1 > 2.2.2.3 +> zx0 ip #0 40(20) 6 1.1.1.1,101 > 2.3.2.3,203 +> zx0 ip #0 40(20) 6 4.4.4.4,101 > 6.6.0.1,203 +List of active MAP/Redirect filters: +rewrite out on zx0 proto tcp from 0/0 to 2.2.0.0/16 -> src 4.4.4.4/32 dst 6.6.0.0/16; + +List of active sessions: +RWR-MAP 1.1.1.1 101 2.2.2.3 203 <- -> 4.4.4.4 101 6.6.0.1 203 + +Hostmap table: +List of active state sessions: +List of configured pools +List of configured hash tables +List of groups configured (set 0) +List of groups configured (set 1) +Rules configured (set 0, in) +Rules configured (set 0, out) +Rules configured (set 1, in) +Rules configured (set 1, out) +Accounting rules configured (set 0, in) +Accounting rules configured (set 0, out) +Accounting rules configured (set 1, in) +Accounting rules configured (set 1, out) +------------------------------- diff --git a/contrib/ipfilter/test/expected/n102 b/contrib/ipfilter/test/expected/n102 new file mode 100644 index 000000000000..a2f130ee8a52 --- /dev/null +++ b/contrib/ipfilter/test/expected/n102 @@ -0,0 +1,29 @@ +> zx0 ip #0 20(20) 255 1.1.1.1 > 2.3.2.3 +> zx0 ip #0 20(20) 255 1.1.1.1 > 2.2.2.3 +> zx0 ip #0 20(20) 255 1.1.1.2 > 2.2.2.3 +> zx0 ip #0 20(20) 255 1.2.1.2 > 2.2.2.3 +> zx0 ip #0 20(20) 255 1.1.1.1 > 2.2.2.4 +> zx0 ip #0 20(20) 255 1.1.1.1 > 2.2.2.3 +> zx0 ip #0 40(20) 6 1.1.1.1,101 > 2.3.2.3,203 +> zx0 ip #0 40(20) 6 4.4.4.4,1000 > 6.6.0.1,203 +List of active MAP/Redirect filters: +rewrite out on zx0 proto tcp from 0/0 to 2.2.0.0/16 -> src 4.4.4.4/32,1000-2000 dst 6.6.0.0/16; + +List of active sessions: +RWR-MAP 1.1.1.1 101 2.2.2.3 203 <- -> 4.4.4.4 1000 6.6.0.1 203 + +Hostmap table: +List of active state sessions: +List of configured pools +List of configured hash tables +List of groups configured (set 0) +List of groups configured (set 1) +Rules configured (set 0, in) +Rules configured (set 0, out) +Rules configured (set 1, in) +Rules configured (set 1, out) +Accounting rules configured (set 0, in) +Accounting rules configured (set 0, out) +Accounting rules configured (set 1, in) +Accounting rules configured (set 1, out) +------------------------------- diff --git a/contrib/ipfilter/test/expected/n103 b/contrib/ipfilter/test/expected/n103 new file mode 100644 index 000000000000..31ed7404a063 --- /dev/null +++ b/contrib/ipfilter/test/expected/n103 @@ -0,0 +1,33 @@ +> zx0 ip #0 40(20) 6 1.1.1.1,101 > 2.3.2.3,203 +> zx0 ip #0 40(20) 6 4.4.4.4,1000 > 6.6.0.1,4000 +> zx0 ip #0 40(20) 6 4.4.4.4,1000 > 6.6.0.1,4000 +> zx0 ip #0 40(20) 6 4.4.4.4,1001 > 6.6.0.1,4000 +> zx0 ip #0 40(20) 6 4.4.4.4,1001 > 6.6.0.2,4000 +> zx0 ip #0 40(20) 6 4.4.4.4,1001 > 6.6.0.2,4001 +< zx0 ip #0 40(20) 6 2.2.2.3,4000 > 4.4.4.4,1000 +> zx0 ip #0 40(20) 6 4.4.4.4,1000 > 6.6.0.2,4001 +List of active MAP/Redirect filters: +rewrite out on zx0 proto tcp from 0/0 to 2.2.0.0/16 -> src 4.4.4.4/32,1000-1001 dst 6.6.0.0/16,4000-4001; + +List of active sessions: +RWR-MAP 7.7.7.7 101 2.2.2.3 203 <- -> 4.4.4.4 1000 6.6.0.2 4001 +RWR-MAP 5.5.5.5 101 2.2.2.3 203 <- -> 4.4.4.4 1001 6.6.0.2 4001 +RWR-MAP 10.10.10.10 101 2.2.2.3 203 <- -> 4.4.4.4 1001 6.6.0.2 4000 +RWR-MAP 1.1.1.2 101 2.2.2.3 203 <- -> 4.4.4.4 1001 6.6.0.1 4000 +RWR-MAP 1.1.1.1 101 2.2.2.3 203 <- -> 4.4.4.4 1000 6.6.0.1 4000 + +Hostmap table: +List of active state sessions: +List of configured pools +List of configured hash tables +List of groups configured (set 0) +List of groups configured (set 1) +Rules configured (set 0, in) +Rules configured (set 0, out) +Rules configured (set 1, in) +Rules configured (set 1, out) +Accounting rules configured (set 0, in) +Accounting rules configured (set 0, out) +Accounting rules configured (set 1, in) +Accounting rules configured (set 1, out) +------------------------------- diff --git a/contrib/ipfilter/test/expected/n104 b/contrib/ipfilter/test/expected/n104 new file mode 100644 index 000000000000..3b8a9de2e87b --- /dev/null +++ b/contrib/ipfilter/test/expected/n104 @@ -0,0 +1,50 @@ +4500 0028 0001 0000 ff06 b1c3 0404 0001 0606 0001 03e8 0fa0 0000 0001 1000 0001 5010 2000 623f 0000 + +4500 0028 0002 0000 ff06 b5c8 0202 0202 0101 0101 00cb 0065 0000 0001 1000 0001 5010 2000 789d 0000 + +4500 0028 0003 0000 ff06 b1c0 0404 0002 0606 0001 03e8 0fa0 0000 0001 1000 0001 5010 2000 623e 0000 + +4500 0028 0004 0000 ff06 b5c6 0202 0202 0101 0101 00cb 0066 0000 0001 1000 0001 5010 2000 789c 0000 + +4500 0028 0005 0000 ff06 b1be 0404 0002 0606 0001 03e9 0fa0 0000 0001 1000 0001 5010 2000 623d 0000 + +4500 0028 0006 0000 ff06 b5c4 0202 0202 0101 0101 00cb 0067 0000 0001 1000 0001 5010 2000 789b 0000 + +4500 0028 0007 0000 ff06 b1bb 0404 0002 0606 0002 03e9 0fa0 0000 0001 1000 0001 5010 2000 623c 0000 + +4500 0028 0008 0000 ff06 b5c2 0202 0202 0101 0101 00cb 0068 0000 0001 1000 0001 5010 2000 789a 0000 + +4500 0028 0009 0000 ff06 b1b9 0404 0002 0606 0002 03e9 0fa1 0000 0001 1000 0001 5010 2000 623b 0000 + +4500 0028 000a 0000 ff06 b5c0 0202 0202 0101 0101 00cb 0069 0000 0001 1000 0001 5010 2000 7899 0000 + +4500 0028 000b 0000 ff06 b1b6 0404 0003 0606 0002 03e9 0fa1 0000 0001 1000 0001 5010 2000 623a 0000 + +4500 0028 000c 0000 ff06 b5be 0202 0202 0101 0101 00cb 006a 0000 0001 1000 0001 5010 2000 7898 0000 + +List of active MAP/Redirect filters: +rewrite out on zx0 proto tcp from 0/0 to 2.2.0.0/16 -> src 4.4.0.0/24,1000-1001 dst 6.6.0.0/16,4000-4001; + +List of active sessions: +RWR-MAP 1.1.1.1 106 2.2.2.2 203 <- -> 4.4.0.3 1001 6.6.0.2 4001 +RWR-MAP 1.1.1.1 105 2.2.2.2 203 <- -> 4.4.0.2 1001 6.6.0.2 4001 +RWR-MAP 1.1.1.1 104 2.2.2.2 203 <- -> 4.4.0.2 1001 6.6.0.2 4000 +RWR-MAP 1.1.1.1 103 2.2.2.2 203 <- -> 4.4.0.2 1001 6.6.0.1 4000 +RWR-MAP 1.1.1.1 102 2.2.2.2 203 <- -> 4.4.0.2 1000 6.6.0.1 4000 +RWR-MAP 1.1.1.1 101 2.2.2.2 203 <- -> 4.4.0.1 1000 6.6.0.1 4000 + +Hostmap table: +List of active state sessions: +List of configured pools +List of configured hash tables +List of groups configured (set 0) +List of groups configured (set 1) +Rules configured (set 0, in) +Rules configured (set 0, out) +Rules configured (set 1, in) +Rules configured (set 1, out) +Accounting rules configured (set 0, in) +Accounting rules configured (set 0, out) +Accounting rules configured (set 1, in) +Accounting rules configured (set 1, out) +------------------------------- diff --git a/contrib/ipfilter/test/expected/n105 b/contrib/ipfilter/test/expected/n105 new file mode 100644 index 000000000000..d45a4af9840e --- /dev/null +++ b/contrib/ipfilter/test/expected/n105 @@ -0,0 +1,25 @@ +4500 0028 0001 0000 ff06 adc0 0404 0404 0606 0001 03e8 0c38 0000 0001 1000 0001 5010 2000 61a4 0000 + +4500 0028 0001 0000 ff06 b5c9 0202 0202 0101 0101 0050 0065 0000 0001 1000 0001 5010 2000 7918 0000 + +List of active MAP/Redirect filters: +rewrite in on zx0 proto tcp from 0/0 to 2.2.0.0/16 port = 80 -> src 4.4.4.4/32,1000-1001 dst 6.6.0.0/16,port = 3128; + +List of active sessions: +RWR-RDR 1.1.1.1 101 2.2.2.2 80 <- -> 4.4.4.4 1000 6.6.0.1 3128 + +Hostmap table: +List of active state sessions: +List of configured pools +List of configured hash tables +List of groups configured (set 0) +List of groups configured (set 1) +Rules configured (set 0, in) +Rules configured (set 0, out) +Rules configured (set 1, in) +Rules configured (set 1, out) +Accounting rules configured (set 0, in) +Accounting rules configured (set 0, out) +Accounting rules configured (set 1, in) +Accounting rules configured (set 1, out) +------------------------------- diff --git a/contrib/ipfilter/test/expected/n106 b/contrib/ipfilter/test/expected/n106 new file mode 100644 index 000000000000..d466e6553353 --- /dev/null +++ b/contrib/ipfilter/test/expected/n106 @@ -0,0 +1,25 @@ +4500 0028 0001 0000 ff06 adc0 0404 0404 0606 0001 03e8 0c38 0000 0001 1000 0001 5010 2000 61a4 0000 + +4500 0028 0001 0000 ff06 b5c9 0202 0202 0101 0101 0050 0065 0000 0001 1000 0001 5010 2000 7918 0000 + +List of active MAP/Redirect filters: +rewrite out on zx0 proto tcp from 0/0 to 2.2.0.0/16 port = 80 -> src 4.4.4.4/32,1000-1001 dst 6.6.0.0/16,port = 3128; + +List of active sessions: +RWR-MAP 1.1.1.1 101 2.2.2.2 80 <- -> 4.4.4.4 1000 6.6.0.1 3128 + +Hostmap table: +List of active state sessions: +List of configured pools +List of configured hash tables +List of groups configured (set 0) +List of groups configured (set 1) +Rules configured (set 0, in) +Rules configured (set 0, out) +Rules configured (set 1, in) +Rules configured (set 1, out) +Accounting rules configured (set 0, in) +Accounting rules configured (set 0, out) +Accounting rules configured (set 1, in) +Accounting rules configured (set 1, out) +------------------------------- diff --git a/contrib/ipfilter/test/expected/n11 b/contrib/ipfilter/test/expected/n11 index 5257a64a1f08..ea11b93e7caf 100644 --- a/contrib/ipfilter/test/expected/n11 +++ b/contrib/ipfilter/test/expected/n11 @@ -1,51 +1,124 @@ -ip #0 20(20) 255 10.1.1.0 > 10.1.1.2 -ip #0 20(20) 255 1.6.7.8 > 10.1.1.2 -ip #0 20(20) 255 10.1.1.2 > 10.1.1.1 -ip #0 20(20) 255 10.2.2.1 > 10.1.2.1 -ip #0 20(20) 255 10.2.2.2 > 10.1.2.1 -ip #0 20(20) 255 10.1.1.1 > 10.1.1.2 -ip #0 20(20) 255 10.1.1.2 > 10.1.1.1 -ip #0 20(20) 255 10.2.2.1 > 10.2.1.1 -ip #0 20(20) 255 10.2.2.2 > 10.2.1.1 -ip #0 20(20) 255 10.2.2.3 > 10.1.1.1 -ip #0 20(20) 255 10.2.3.4 > 10.2.2.2 -ip #0 20(20) 255 10.1.1.1 > 10.2.2.2 -ip #0 20(20) 255 10.1.1.2 > 10.2.2.2 -ip #0 20(20) 255 10.1.1.0 > 10.3.4.5 -ip #0 20(20) 255 10.1.1.1 > 10.3.4.5 -ip #0 20(20) 255 10.1.1.2 > 10.3.4.5 +> zx0 ip #0 20(20) 255 10.1.1.0 > 10.1.1.2 +> zx0 ip #0 20(20) 255 1.6.7.8 > 10.1.1.2 +> zx0 ip #0 20(20) 255 10.1.1.2 > 10.1.1.1 +> zx0 ip #0 20(20) 255 10.2.2.1 > 10.1.2.1 +> zx0 ip #0 20(20) 255 10.2.2.2 > 10.1.2.1 +< zx0 ip #0 20(20) 255 10.1.1.1 > 10.1.1.2 +< zx0 ip #0 20(20) 255 10.1.1.2 > 10.1.1.1 +< zx0 ip #0 20(20) 255 10.2.2.1 > 10.2.1.1 +< zx0 ip #0 20(20) 255 10.2.2.2 > 10.2.1.1 +< zx0 ip #0 20(20) 255 10.2.2.3 > 10.1.1.1 +< zx0 ip #0 20(20) 255 10.2.3.4 > 10.2.2.2 +< zx0 ip #0 20(20) 255 10.1.1.1 > 10.2.2.2 +< zx0 ip #0 20(20) 255 10.1.1.2 > 10.2.2.2 +< zx0 ip #0 20(20) 255 10.1.1.0 > 10.3.4.5 +< zx0 ip #0 20(20) 255 10.1.1.1 > 10.3.4.5 +< zx0 ip #0 20(20) 255 10.1.1.2 > 10.3.4.5 +List of active MAP/Redirect filters: +bimap zx0 10.1.1.1/32 -> 1.6.7.8/32 + +List of active sessions: +BIMAP 10.1.1.1 <- -> 1.6.7.8 [10.1.1.2] + +Hostmap table: +10.1.1.1,10.1.1.2 -> 1.6.7.8,0.0.0.0 (use = 1) +List of active state sessions: +List of configured pools +List of configured hash tables +List of groups configured (set 0) +List of groups configured (set 1) +Rules configured (set 0, in) +Rules configured (set 0, out) +Rules configured (set 1, in) +Rules configured (set 1, out) +Accounting rules configured (set 0, in) +Accounting rules configured (set 0, out) +Accounting rules configured (set 1, in) +Accounting rules configured (set 1, out) ------------------------------- -ip #0 20(20) 255 10.2.2.2 > 10.1.1.2 -ip #0 20(20) 255 10.1.1.1 > 10.1.1.2 -ip #0 20(20) 255 10.2.2.2 > 10.1.1.1 -ip #0 20(20) 255 10.2.2.1 > 10.1.2.1 -ip #0 20(20) 255 10.2.2.2 > 10.1.2.1 -ip #0 20(20) 255 10.1.1.1 > 10.1.1.2 -ip #0 20(20) 255 10.1.1.2 > 10.1.1.1 -ip #0 20(20) 255 10.2.2.1 > 10.2.1.1 -ip #0 20(20) 255 10.2.2.2 > 10.2.1.1 -ip #0 20(20) 255 10.2.2.3 > 10.1.1.1 -ip #0 20(20) 255 10.2.3.4 > 10.1.1.0 -ip #0 20(20) 255 10.1.1.1 > 10.1.1.2 -ip #0 20(20) 255 10.1.1.2 > 10.1.1.0 -ip #0 20(20) 255 10.1.1.0 > 10.3.4.5 -ip #0 20(20) 255 10.1.1.1 > 10.3.4.5 -ip #0 20(20) 255 10.1.1.2 > 10.3.4.5 +> zx0 ip #0 20(20) 255 10.2.2.2 > 10.1.1.2 +15 +> zx0 ip #0 20(20) 255 10.2.2.2 > 10.1.1.1 +> zx0 ip #0 20(20) 255 10.2.2.1 > 10.1.2.1 +> zx0 ip #0 20(20) 255 10.2.2.2 > 10.1.2.1 +< zx0 ip #0 20(20) 255 10.1.1.1 > 10.1.1.2 +< zx0 ip #0 20(20) 255 10.1.1.2 > 10.1.1.1 +< zx0 ip #0 20(20) 255 10.2.2.1 > 10.2.1.1 +< zx0 ip #0 20(20) 255 10.2.2.2 > 10.2.1.1 +< zx0 ip #0 20(20) 255 10.2.2.3 > 10.1.1.1 +< zx0 ip #0 20(20) 255 10.2.3.4 > 10.1.1.0 +< zx0 ip #0 20(20) 255 10.1.1.1 > 10.1.1.2 +< zx0 ip #0 20(20) 255 10.1.1.2 > 10.1.1.0 +< zx0 ip #0 20(20) 255 10.1.1.0 > 10.3.4.5 +< zx0 ip #0 20(20) 255 10.1.1.1 > 10.3.4.5 +< zx0 ip #0 20(20) 255 10.1.1.2 > 10.3.4.5 +List of active MAP/Redirect filters: +bimap zx0 10.1.1.0/24 -> 10.2.2.2/32 + +List of active sessions: +BIMAP 10.1.1.0 <- -> 10.2.2.2 [10.2.3.4] +BIMAP 10.1.1.2 <- -> 10.2.2.2 [10.1.1.1] +BIMAP 10.1.1.0 <- -> 10.2.2.2 [10.1.1.2] + +Hostmap table: +10.1.1.2,10.1.1.1 -> 10.2.2.2,0.0.0.0 (use = 1) +10.1.1.0,10.1.1.2 -> 10.2.2.2,0.0.0.0 (use = 1) +List of active state sessions: +List of configured pools +List of configured hash tables +List of groups configured (set 0) +List of groups configured (set 1) +Rules configured (set 0, in) +Rules configured (set 0, out) +Rules configured (set 1, in) +Rules configured (set 1, out) +Accounting rules configured (set 0, in) +Accounting rules configured (set 0, out) +Accounting rules configured (set 1, in) +Accounting rules configured (set 1, out) ------------------------------- -ip #0 20(20) 255 10.3.4.0 > 10.1.1.2 -ip #0 20(20) 255 10.3.4.1 > 10.1.1.2 -ip #0 20(20) 255 10.3.4.2 > 10.1.1.1 -ip #0 20(20) 255 10.2.2.1 > 10.1.2.1 -ip #0 20(20) 255 10.2.2.2 > 10.1.2.1 -ip #0 20(20) 255 10.1.1.1 > 10.1.1.2 -ip #0 20(20) 255 10.1.1.2 > 10.1.1.1 -ip #0 20(20) 255 10.2.2.1 > 10.2.1.1 -ip #0 20(20) 255 10.2.2.2 > 10.2.1.1 -ip #0 20(20) 255 10.2.2.3 > 10.1.1.1 -ip #0 20(20) 255 10.2.3.4 > 10.2.2.2 -ip #0 20(20) 255 10.1.1.1 > 10.2.2.2 -ip #0 20(20) 255 10.1.1.2 > 10.2.2.2 -ip #0 20(20) 255 10.1.1.0 > 10.1.1.5 -ip #0 20(20) 255 10.1.1.1 > 10.1.1.5 -ip #0 20(20) 255 10.1.1.2 > 10.1.1.5 +> zx0 ip #0 20(20) 255 10.3.4.0 > 10.1.1.2 +> zx0 ip #0 20(20) 255 10.3.4.1 > 10.1.1.2 +> zx0 ip #0 20(20) 255 10.3.4.2 > 10.1.1.1 +> zx0 ip #0 20(20) 255 10.2.2.1 > 10.1.2.1 +> zx0 ip #0 20(20) 255 10.2.2.2 > 10.1.2.1 +< zx0 ip #0 20(20) 255 10.1.1.1 > 10.1.1.2 +< zx0 ip #0 20(20) 255 10.1.1.2 > 10.1.1.1 +< zx0 ip #0 20(20) 255 10.2.2.1 > 10.2.1.1 +< zx0 ip #0 20(20) 255 10.2.2.2 > 10.2.1.1 +< zx0 ip #0 20(20) 255 10.2.2.3 > 10.1.1.1 +< zx0 ip #0 20(20) 255 10.2.3.4 > 10.2.2.2 +< zx0 ip #0 20(20) 255 10.1.1.1 > 10.2.2.2 +< zx0 ip #0 20(20) 255 10.1.1.2 > 10.2.2.2 +< zx0 ip #0 20(20) 255 10.1.1.0 > 10.1.1.5 +< zx0 ip #0 20(20) 255 10.1.1.1 > 10.1.1.5 +< zx0 ip #0 20(20) 255 10.1.1.2 > 10.1.1.5 +List of active MAP/Redirect filters: +bimap zx0 10.1.1.0/24 -> 10.3.4.0/24 + +List of active sessions: +BIMAP 10.1.1.5 <- -> 10.3.4.5 [10.1.1.2] +BIMAP 10.1.1.5 <- -> 10.3.4.5 [10.1.1.1] +BIMAP 10.1.1.5 <- -> 10.3.4.5 [10.1.1.0] +BIMAP 10.1.1.2 <- -> 10.3.4.2 [10.1.1.1] +BIMAP 10.1.1.1 <- -> 10.3.4.1 [10.1.1.2] +BIMAP 10.1.1.0 <- -> 10.3.4.0 [10.1.1.2] + +Hostmap table: +10.1.1.2,10.1.1.1 -> 10.3.4.1,0.0.0.0 (use = 1) +10.1.1.1,10.1.1.2 -> 10.3.4.1,0.0.0.0 (use = 1) +10.1.1.0,10.1.1.2 -> 10.3.4.1,0.0.0.0 (use = 1) +List of active state sessions: +List of configured pools +List of configured hash tables +List of groups configured (set 0) +List of groups configured (set 1) +Rules configured (set 0, in) +Rules configured (set 0, out) +Rules configured (set 1, in) +Rules configured (set 1, out) +Accounting rules configured (set 0, in) +Accounting rules configured (set 0, out) +Accounting rules configured (set 1, in) +Accounting rules configured (set 1, out) ------------------------------- diff --git a/contrib/ipfilter/test/expected/n11_6 b/contrib/ipfilter/test/expected/n11_6 new file mode 100644 index 000000000000..f1c80de81ba9 --- /dev/null +++ b/contrib/ipfilter/test/expected/n11_6 @@ -0,0 +1,124 @@ +> zx0 ip6/0 1 0 255 10:1:1:0:0:0:0:0 > 10:1:1:0:0:0:0:2 +> zx0 ip6/0 1 0 255 1:0:0:0:0:6:7:8 > 10:1:1:0:0:0:0:2 +> zx0 ip6/0 1 0 255 10:1:1:0:0:0:0:2 > 10:1:1:0:0:0:0:1 +> zx0 ip6/0 1 0 255 10:0:0:0:0:2:2:1 > 10:1:2:0:0:0:0:1 +> zx0 ip6/0 1 0 255 10:0:0:0:0:2:2:2 > 10:1:2:0:0:0:0:1 +< zx0 ip6/0 1 0 255 10:1:1:0:0:0:0:1 > 10:1:1:0:0:0:0:2 +< zx0 ip6/0 1 0 255 10:1:1:0:0:0:0:2 > 10:1:1:0:0:0:0:1 +< zx0 ip6/0 1 0 255 10:0:0:0:0:2:2:1 > 10:0:0:0:0:2:1:1 +< zx0 ip6/0 1 0 255 10:0:0:0:0:2:2:2 > 10:0:0:0:0:2:1:1 +< zx0 ip6/0 1 0 255 10:0:0:0:0:2:2:3 > 10:1:1:0:0:0:0:1 +< zx0 ip6/0 1 0 255 10:0:0:0:0:2:3:4 > 10:0:0:0:0:2:2:2 +< zx0 ip6/0 1 0 255 10:1:1:0:0:0:0:1 > 10:0:0:0:0:2:2:2 +< zx0 ip6/0 1 0 255 10:1:1:0:0:0:0:2 > 10:0:0:0:0:2:2:2 +< zx0 ip6/0 1 0 255 10:1:1:0:0:0:0:0 > 10:0:0:0:0:3:4:5 +< zx0 ip6/0 1 0 255 10:1:1:0:0:0:0:1 > 10:0:0:0:0:3:4:5 +< zx0 ip6/0 1 0 255 10:1:1:0:0:0:0:2 > 10:0:0:0:0:3:4:5 +List of active MAP/Redirect filters: +bimap zx0 inet6 10:1:1::1/128 -> 1::6:7:8/128 + +List of active sessions: +BIMAP 10:1:1::1 <- -> 1::6:7:8 [10:1:1::2] + +Hostmap table: +10:1:1::1,10:1:1::2 -> 1::6:7:8,any (use = 1) +List of active state sessions: +List of configured pools +List of configured hash tables +List of groups configured (set 0) +List of groups configured (set 1) +Rules configured (set 0, in) +Rules configured (set 0, out) +Rules configured (set 1, in) +Rules configured (set 1, out) +Accounting rules configured (set 0, in) +Accounting rules configured (set 0, out) +Accounting rules configured (set 1, in) +Accounting rules configured (set 1, out) +------------------------------- +> zx0 ip6/0 1 0 255 10:0:0:0:0:2:2:2 > 10:1:1:0:0:0:0:2 +16 +> zx0 ip6/0 1 0 255 10:0:0:0:0:2:2:2 > 10:1:1:0:0:0:0:1 +> zx0 ip6/0 1 0 255 10:0:0:0:0:2:2:1 > 10:1:2:0:0:0:0:1 +> zx0 ip6/0 1 0 255 10:0:0:0:0:2:2:2 > 10:1:2:0:0:0:0:1 +< zx0 ip6/0 1 0 255 10:1:1:0:0:0:0:1 > 10:1:1:0:0:0:0:2 +< zx0 ip6/0 1 0 255 10:1:1:0:0:0:0:2 > 10:1:1:0:0:0:0:1 +< zx0 ip6/0 1 0 255 10:0:0:0:0:2:2:1 > 10:0:0:0:0:2:1:1 +< zx0 ip6/0 1 0 255 10:0:0:0:0:2:2:2 > 10:0:0:0:0:2:1:1 +< zx0 ip6/0 1 0 255 10:0:0:0:0:2:2:3 > 10:1:1:0:0:0:0:1 +< zx0 ip6/0 1 0 255 10:0:0:0:0:2:3:4 > 10:1:1:0:0:0:0:0 +< zx0 ip6/0 1 0 255 10:1:1:0:0:0:0:1 > 10:1:1:0:0:0:0:2 +< zx0 ip6/0 1 0 255 10:1:1:0:0:0:0:2 > 10:1:1:0:0:0:0:0 +< zx0 ip6/0 1 0 255 10:1:1:0:0:0:0:0 > 10:0:0:0:0:3:4:5 +< zx0 ip6/0 1 0 255 10:1:1:0:0:0:0:1 > 10:0:0:0:0:3:4:5 +< zx0 ip6/0 1 0 255 10:1:1:0:0:0:0:2 > 10:0:0:0:0:3:4:5 +List of active MAP/Redirect filters: +bimap zx0 inet6 10:1:1::/112 -> 10::2:2:2/128 + +List of active sessions: +BIMAP 10:1:1:: <- -> 10::2:2:2 [10::2:3:4] +BIMAP 10:1:1::2 <- -> 10::2:2:2 [10:1:1::1] +BIMAP 10:1:1:: <- -> 10::2:2:2 [10:1:1::2] + +Hostmap table: +10:1:1::2,10:1:1::1 -> 10::2:2:2,any (use = 1) +10:1:1::,10:1:1::2 -> 10::2:2:2,any (use = 1) +List of active state sessions: +List of configured pools +List of configured hash tables +List of groups configured (set 0) +List of groups configured (set 1) +Rules configured (set 0, in) +Rules configured (set 0, out) +Rules configured (set 1, in) +Rules configured (set 1, out) +Accounting rules configured (set 0, in) +Accounting rules configured (set 0, out) +Accounting rules configured (set 1, in) +Accounting rules configured (set 1, out) +------------------------------- +> zx0 ip6/0 1 0 255 10:0:0:0:0:3:4:0 > 10:1:1:0:0:0:0:2 +> zx0 ip6/0 1 0 255 10:0:0:0:0:3:4:1 > 10:1:1:0:0:0:0:2 +> zx0 ip6/0 1 0 255 10:0:0:0:0:3:4:2 > 10:1:1:0:0:0:0:1 +> zx0 ip6/0 1 0 255 10:0:0:0:0:2:2:1 > 10:1:2:0:0:0:0:1 +> zx0 ip6/0 1 0 255 10:0:0:0:0:2:2:2 > 10:1:2:0:0:0:0:1 +< zx0 ip6/0 1 0 255 10:1:1:0:0:0:0:1 > 10:1:1:0:0:0:0:2 +< zx0 ip6/0 1 0 255 10:1:1:0:0:0:0:2 > 10:1:1:0:0:0:0:1 +< zx0 ip6/0 1 0 255 10:0:0:0:0:2:2:1 > 10:0:0:0:0:2:1:1 +< zx0 ip6/0 1 0 255 10:0:0:0:0:2:2:2 > 10:0:0:0:0:2:1:1 +< zx0 ip6/0 1 0 255 10:0:0:0:0:2:2:3 > 10:1:1:0:0:0:0:1 +< zx0 ip6/0 1 0 255 10:0:0:0:0:2:3:4 > 10:0:0:0:0:2:2:2 +< zx0 ip6/0 1 0 255 10:1:1:0:0:0:0:1 > 10:0:0:0:0:2:2:2 +< zx0 ip6/0 1 0 255 10:1:1:0:0:0:0:2 > 10:0:0:0:0:2:2:2 +< zx0 ip6/0 1 0 255 10:1:1:0:0:0:0:0 > 10:1:1:0:0:0:0:5 +< zx0 ip6/0 1 0 255 10:1:1:0:0:0:0:1 > 10:1:1:0:0:0:0:5 +< zx0 ip6/0 1 0 255 10:1:1:0:0:0:0:2 > 10:1:1:0:0:0:0:5 +List of active MAP/Redirect filters: +bimap zx0 inet6 10:1:1::/112 -> 10::3:4:0/112 + +List of active sessions: +BIMAP 10:1:1::5 <- -> 10::3:4:5 [10:1:1::2] +BIMAP 10:1:1::5 <- -> 10::3:4:5 [10:1:1::1] +BIMAP 10:1:1::5 <- -> 10::3:4:5 [10:1:1::] +BIMAP 10:1:1::2 <- -> 10::3:4:2 [10:1:1::1] +BIMAP 10:1:1::1 <- -> 10::3:4:1 [10:1:1::2] +BIMAP 10:1:1:: <- -> 10::3:4:0 [10:1:1::2] + +Hostmap table: +10:1:1::2,10:1:1::1 -> 10::3:4:1,any (use = 1) +10:1:1::1,10:1:1::2 -> 10::3:4:1,any (use = 1) +10:1:1::,10:1:1::2 -> 10::3:4:1,any (use = 1) +List of active state sessions: +List of configured pools +List of configured hash tables +List of groups configured (set 0) +List of groups configured (set 1) +Rules configured (set 0, in) +Rules configured (set 0, out) +Rules configured (set 1, in) +Rules configured (set 1, out) +Accounting rules configured (set 0, in) +Accounting rules configured (set 0, out) +Accounting rules configured (set 1, in) +Accounting rules configured (set 1, out) +------------------------------- diff --git a/contrib/ipfilter/test/expected/n12 b/contrib/ipfilter/test/expected/n12 index 0d5cefbf7e77..56b3a781c9fd 100644 --- a/contrib/ipfilter/test/expected/n12 +++ b/contrib/ipfilter/test/expected/n12 @@ -4,4 +4,25 @@ 4510 0034 493b 4000 4006 6b69 c0a8 01bc c0a8 0303 2710 0017 4e33 298f f674 e02d 8010 4000 f673 0000 0101 080a 0c72 549e 2c05 b797 +List of active MAP/Redirect filters: +map le0 192.168.126.0/24 -> 0/32 portmap tcp/udp 10000:20000 sequential + +List of active sessions: +MAP 192.168.126.83 4802 <- -> 192.168.1.188 10000 [192.168.3.3 23] + +Hostmap table: +192.168.126.83,192.168.3.3 -> 0.0.0.0,0.0.0.0 (use = 1) +List of active state sessions: +List of configured pools +List of configured hash tables +List of groups configured (set 0) +List of groups configured (set 1) +Rules configured (set 0, in) +Rules configured (set 0, out) +Rules configured (set 1, in) +Rules configured (set 1, out) +Accounting rules configured (set 0, in) +Accounting rules configured (set 0, out) +Accounting rules configured (set 1, in) +Accounting rules configured (set 1, out) ------------------------------- diff --git a/contrib/ipfilter/test/expected/n12_6 b/contrib/ipfilter/test/expected/n12_6 new file mode 100644 index 000000000000..9ef040aaafd9 --- /dev/null +++ b/contrib/ipfilter/test/expected/n12_6 @@ -0,0 +1,28 @@ +6000 0000 002c 0640 c0a8 0100 0000 0000 0000 0000 0000 00bc c0a8 0300 0000 0000 0000 0000 0000 0003 2710 0017 4e33 298e 0000 0000 b002 4000 6ff8 0000 0204 05b4 0101 0402 0103 0300 0101 080a 0c72 549e 0000 0000 + +6000 0000 0028 06fe c0a8 0300 0000 0000 0000 0000 0000 0003 c0a8 7e00 0000 0000 0000 0000 0000 0053 0017 12c2 f674 e02c 4e33 298f a012 2798 7ace 0000 0101 080a 2c05 b797 0c72 549e 0103 0300 0204 05b4 + +6000 0000 0020 0640 c0a8 0100 0000 0000 0000 0000 0000 00bc c0a8 0300 0000 0000 0000 0000 0000 0003 2710 0017 4e33 298f f674 e02d 8010 4000 f673 0000 0101 080a 0c72 549e 2c05 b797 + +List of active MAP/Redirect filters: +map le0 inet6 c0a8:7e00::/112 -> ::/128 portmap tcp/udp 10000:20000 + +List of active sessions: +MAP c0a8:7e00::53 4802 <- -> c0a8:100::bc 10000 [c0a8:300::3 23] + +Hostmap table: +c0a8:7e00::53,c0a8:300::3 -> any,any (use = 1) +List of active state sessions: +List of configured pools +List of configured hash tables +List of groups configured (set 0) +List of groups configured (set 1) +Rules configured (set 0, in) +Rules configured (set 0, out) +Rules configured (set 1, in) +Rules configured (set 1, out) +Accounting rules configured (set 0, in) +Accounting rules configured (set 0, out) +Accounting rules configured (set 1, in) +Accounting rules configured (set 1, out) +------------------------------- diff --git a/contrib/ipfilter/test/expected/n13 b/contrib/ipfilter/test/expected/n13 index bfe201886528..e6d26b2a5480 100644 --- a/contrib/ipfilter/test/expected/n13 +++ b/contrib/ipfilter/test/expected/n13 @@ -1,5 +1,32 @@ -ip #0 20(20) 0 203.1.1.23 > 150.1.1.1 -ip #0 20(20) 0 203.1.1.23 > 150.1.1.2 -ip #0 20(20) 0 203.1.1.24 > 150.1.1.2 -ip #0 20(20) 0 203.1.1.25 > 150.1.1.1 +> le0 ip #0 20(20) 0 203.1.1.23 > 150.1.1.1 +> le0 ip #0 20(20) 0 203.1.1.23 > 150.1.1.2 +> le0 ip #0 20(20) 0 203.1.1.24 > 150.1.1.2 +> le0 ip #0 20(20) 0 203.1.1.25 > 150.1.1.1 +List of active MAP/Redirect filters: +map le0 192.168.0.0/16 -> range 203.1.1.23-203.1.3.45 + +List of active sessions: +MAP 192.168.1.3 <- -> 203.1.1.25 [150.1.1.1] +MAP 192.168.1.2 <- -> 203.1.1.24 [150.1.1.2] +MAP 192.168.1.1 <- -> 203.1.1.23 [150.1.1.2] +MAP 192.168.1.1 <- -> 203.1.1.23 [150.1.1.1] + +Hostmap table: +192.168.1.3,150.1.1.1 -> 203.1.1.25,0.0.0.0 (use = 1) +192.168.1.2,150.1.1.2 -> 203.1.1.24,0.0.0.0 (use = 1) +192.168.1.1,150.1.1.2 -> 203.1.1.23,0.0.0.0 (use = 1) +192.168.1.1,150.1.1.1 -> 203.1.1.23,0.0.0.0 (use = 1) +List of active state sessions: +List of configured pools +List of configured hash tables +List of groups configured (set 0) +List of groups configured (set 1) +Rules configured (set 0, in) +Rules configured (set 0, out) +Rules configured (set 1, in) +Rules configured (set 1, out) +Accounting rules configured (set 0, in) +Accounting rules configured (set 0, out) +Accounting rules configured (set 1, in) +Accounting rules configured (set 1, out) ------------------------------- diff --git a/contrib/ipfilter/test/expected/n13_6 b/contrib/ipfilter/test/expected/n13_6 new file mode 100644 index 000000000000..d3b5fe7fb99d --- /dev/null +++ b/contrib/ipfilter/test/expected/n13_6 @@ -0,0 +1,32 @@ +> le0 ip6/0 1 0 41 203:0:1:0:0:0:1:23 > 150.1.1.1 +> le0 ip6/0 1 0 41 203:0:1:0:0:0:1:23 > 150.1.1.2 +> le0 ip6/0 1 0 41 203:0:1:0:0:0:1:24 > 150.1.1.2 +> le0 ip6/0 1 0 41 203:0:1:0:0:0:1:25 > 150.1.1.1 +List of active MAP/Redirect filters: +map le0 inet6 192:168:0::0/48 -> range 203:0:1::1:23-203:0:1::3:45 + +List of active sessions: +MAP 192.168.1.3 <- -> 203:0:1::1:25 [150.1.1.1] +MAP 192.168.1.2 <- -> 203:0:1::1:24 [150.1.1.2] +MAP 192.168.1.1 <- -> 203:0:1::1:23 [150.1.1.2] +MAP 192.168.1.1 <- -> 203:0:1::1:23 [150.1.1.1] + +Hostmap table: +192.168.1.3,150.1.1.1 -> 203:0:1:0:0:0:1:25,any (use = 1) +192.168.1.2,150.1.1.2 -> 203:0:1:0:0:0:1:24,any (use = 1) +192.168.1.1,150.1.1.2 -> 203:0:1:0:0:0:1:23,any (use = 1) +192.168.1.1,150.1.1.1 -> 203:0:1:0:0:0:1:23,any (use = 1) +List of active state sessions: +List of configured pools +List of configured hash tables +List of groups configured (set 0) +List of groups configured (set 1) +Rules configured (set 0, in) +Rules configured (set 0, out) +Rules configured (set 1, in) +Rules configured (set 1, out) +Accounting rules configured (set 0, in) +Accounting rules configured (set 0, out) +Accounting rules configured (set 1, in) +Accounting rules configured (set 1, out) +------------------------------- diff --git a/contrib/ipfilter/test/expected/n14 b/contrib/ipfilter/test/expected/n14 index 46693001a444..7b1a19ea931a 100644 --- a/contrib/ipfilter/test/expected/n14 +++ b/contrib/ipfilter/test/expected/n14 @@ -1,5 +1,30 @@ -ip #0 40(20) 6 10.2.2.5,2000 > 10.1.1.254,80 -ip #0 40(20) 6 10.2.2.6,2000 > 10.1.1.253,80 -ip #0 40(20) 6 10.2.2.7,2000 > 10.1.1.254,80 -ip #0 40(20) 6 10.2.2.5,2001 > 10.1.1.254,80 +< gre0 ip #0 40(20) 6 10.2.2.5,2000 > 10.1.1.254,80 +< gre0 ip #0 40(20) 6 10.2.2.6,2000 > 10.1.1.253,80 +< gre0 ip #0 40(20) 6 10.2.2.7,2000 > 10.1.1.254,80 +15 +List of active MAP/Redirect filters: +rdr gre0 0/0 port 80 -> 10.1.1.254,10.1.1.253 port 80 tcp sticky + +List of active sessions: +RDR 10.1.1.254 80 <- -> 203.1.1.1 80 [10.2.2.7 2000] +RDR 10.1.1.253 80 <- -> 203.1.1.1 80 [10.2.2.6 2000] +RDR 10.1.1.254 80 <- -> 203.1.1.1 80 [10.2.2.5 2000] + +Hostmap table: +10.2.2.7,203.1.1.1 -> 254.1.1.10,0.0.0.0 (use = 1) +10.2.2.6,203.1.1.1 -> 253.1.1.10,0.0.0.0 (use = 1) +10.2.2.5,203.1.1.1 -> 254.1.1.10,0.0.0.0 (use = 1) +List of active state sessions: +List of configured pools +List of configured hash tables +List of groups configured (set 0) +List of groups configured (set 1) +Rules configured (set 0, in) +Rules configured (set 0, out) +Rules configured (set 1, in) +Rules configured (set 1, out) +Accounting rules configured (set 0, in) +Accounting rules configured (set 0, out) +Accounting rules configured (set 1, in) +Accounting rules configured (set 1, out) ------------------------------- diff --git a/contrib/ipfilter/test/expected/n14_6 b/contrib/ipfilter/test/expected/n14_6 new file mode 100644 index 000000000000..b999ee971d80 --- /dev/null +++ b/contrib/ipfilter/test/expected/n14_6 @@ -0,0 +1,30 @@ +< gre0 ip6/0 20 0 6 10:0:0:0:0:2:2:5,2000 > 10:1:1:0:0:0:0:254,80 +< gre0 ip6/0 20 0 6 10:0:0:0:0:2:2:6,2000 > 10:1:1:0:0:0:0:253,80 +< gre0 ip6/0 20 0 6 10:0:0:0:0:2:2:7,2000 > 10:1:1:0:0:0:0:254,80 +< gre0 ip6/0 20 0 6 10:0:0:0:0:2:2:5,2001 > 203:0:1:0:0:0:1:1,80 +List of active MAP/Redirect filters: +rdr gre0 inet6 any port 80 -> 10:1:1::254,10:1:1::253 port 80 tcp sticky + +List of active sessions: +RDR 10:1:1::254 80 <- -> 203:0:1::1:1 80 [10::2:2:7 2000] +RDR 10:1:1::253 80 <- -> 203:0:1::1:1 80 [10::2:2:6 2000] +RDR 10:1:1::254 80 <- -> 203:0:1::1:1 80 [10::2:2:5 2000] + +Hostmap table: +10::2:2:7,203:0:1:0:0:0:1:1 -> 254:1:1::10,any (use = 1) +10::2:2:6,203:0:1:0:0:0:1:1 -> 253:0:1:0:0:0:1:10,any (use = 1) +10::2:2:5,203:0:1:0:0:0:1:1 -> 254:1:1::10,any (use = 3) +List of active state sessions: +List of configured pools +List of configured hash tables +List of groups configured (set 0) +List of groups configured (set 1) +Rules configured (set 0, in) +Rules configured (set 0, out) +Rules configured (set 1, in) +Rules configured (set 1, out) +Accounting rules configured (set 0, in) +Accounting rules configured (set 0, out) +Accounting rules configured (set 1, in) +Accounting rules configured (set 1, out) +------------------------------- diff --git a/contrib/ipfilter/test/expected/n15 b/contrib/ipfilter/test/expected/n15 new file mode 100644 index 000000000000..3889f82081df --- /dev/null +++ b/contrib/ipfilter/test/expected/n15 @@ -0,0 +1,47 @@ +< le0 ip #0 40(20) 6 9.9.9.9,10011 > 3.3.3.3,80 +15 +List of active MAP/Redirect filters: +rdr le0 0/0 port 80 -> 3.3.3.3/32 port 80 tcp + +List of active sessions: +RDR 3.3.3.3 80 <- -> 5.5.5.5 80 [9.9.9.9 10011] + +Hostmap table: +List of active state sessions: +List of configured pools +List of configured hash tables +List of groups configured (set 0) +List of groups configured (set 1) +Rules configured (set 0, in) +Rules configured (set 0, out) +Rules configured (set 1, in) +Rules configured (set 1, out) +Accounting rules configured (set 0, in) +Accounting rules configured (set 0, out) +Accounting rules configured (set 1, in) +Accounting rules configured (set 1, out) +------------------------------- +< le0 ip #0 40(20) 6 9.9.9.9,10011 > 3.3.3.3,80 +< le0 ip #0 40(20) 6 9.9.9.9,10011 > 3.3.3.3,81 +List of active MAP/Redirect filters: +rdr le0 0/0 port 80 -> 3.3.3.3/32 port 80-88 tcp + +List of active sessions: +RDR 3.3.3.3 81 <- -> 2.2.2.2 80 [9.9.9.9 10011] +RDR 3.3.3.3 80 <- -> 5.5.5.5 80 [9.9.9.9 10011] + +Hostmap table: +List of active state sessions: +List of configured pools +List of configured hash tables +List of groups configured (set 0) +List of groups configured (set 1) +Rules configured (set 0, in) +Rules configured (set 0, out) +Rules configured (set 1, in) +Rules configured (set 1, out) +Accounting rules configured (set 0, in) +Accounting rules configured (set 0, out) +Accounting rules configured (set 1, in) +Accounting rules configured (set 1, out) +------------------------------- diff --git a/contrib/ipfilter/test/expected/n15_6 b/contrib/ipfilter/test/expected/n15_6 new file mode 100644 index 000000000000..f01b72b68056 --- /dev/null +++ b/contrib/ipfilter/test/expected/n15_6 @@ -0,0 +1,47 @@ +< le0 ip6/0 20 0 6 9:9:9:0:0:0:0:9,10011 > 3:0:3:0:0:0:3:3,80 +16 +List of active MAP/Redirect filters: +rdr le0 inet6 any port 80 -> 3:0:3::3:3/128 port 80 tcp + +List of active sessions: +RDR 3:0:3::3:3 80 <- -> 5:5::5:5 80 [9:9:9::9 10011] + +Hostmap table: +List of active state sessions: +List of configured pools +List of configured hash tables +List of groups configured (set 0) +List of groups configured (set 1) +Rules configured (set 0, in) +Rules configured (set 0, out) +Rules configured (set 1, in) +Rules configured (set 1, out) +Accounting rules configured (set 0, in) +Accounting rules configured (set 0, out) +Accounting rules configured (set 1, in) +Accounting rules configured (set 1, out) +------------------------------- +< le0 ip6/0 20 0 6 9:9:9:0:0:0:0:9,10011 > 3:0:3:0:0:0:3:3,80 +< le0 ip6/0 20 0 6 9:9:9:0:0:0:0:9,10011 > 3:0:3:0:0:0:3:3,81 +List of active MAP/Redirect filters: +rdr le0 inet6 any port 80 -> 3:0:3::3:3/128 port 80-88 tcp + +List of active sessions: +RDR 3:0:3::3:3 81 <- -> 2::2:2:2 80 [9:9:9::9 10011] +RDR 3:0:3::3:3 80 <- -> 5:5::5:5 80 [9:9:9::9 10011] + +Hostmap table: +List of active state sessions: +List of configured pools +List of configured hash tables +List of groups configured (set 0) +List of groups configured (set 1) +Rules configured (set 0, in) +Rules configured (set 0, out) +Rules configured (set 1, in) +Rules configured (set 1, out) +Accounting rules configured (set 0, in) +Accounting rules configured (set 0, out) +Accounting rules configured (set 1, in) +Accounting rules configured (set 1, out) +------------------------------- diff --git a/contrib/ipfilter/test/expected/n16 b/contrib/ipfilter/test/expected/n16 index da617d9d3600..0eb3954e8572 100644 --- a/contrib/ipfilter/test/expected/n16 +++ b/contrib/ipfilter/test/expected/n16 @@ -7,7 +7,7 @@ 4500 0084 ee0f 0000 8001 4a21 45f8 4fc1 c05b ac33 0303 bf85 0000 0000 4520 0068 17e4 0000 6a11 3639 c05b ac33 45f8 4fc1 1194 94f8 0054 0000 a5a5 a5a5 a5a5 a5a5 a5a5 a5a5 a5a5 a5a5 a5a5 a5a5 a5a5 a5a5 a5a5 a5a5 a5a5 a5a5 a5a5 a5a5 a5a5 a5a5 a5a5 a5a5 a5a5 a5a5 a5a5 a5a5 a5a5 a5a5 a5a5 a5a5 a5a5 a5a5 a5a5 a5a5 a5a5 a5a5 a5a5 a5a5 List of active MAP/Redirect filters: -rdr vlan0 from any to 69.248.79.193/32 port = 38136 -> 172.31.83.24 port 2013 udp +rdr vlan0 from 0/0 to 69.248.79.193/32 port = 38136 -> 172.31.83.24/32 port 2013 udp List of active sessions: RDR 172.31.83.24 2013 <- -> 69.248.79.193 38136 [192.91.172.51 4500] @@ -18,4 +18,12 @@ List of configured pools List of configured hash tables List of groups configured (set 0) List of groups configured (set 1) +Rules configured (set 0, in) +Rules configured (set 0, out) +Rules configured (set 1, in) +Rules configured (set 1, out) +Accounting rules configured (set 0, in) +Accounting rules configured (set 0, out) +Accounting rules configured (set 1, in) +Accounting rules configured (set 1, out) ------------------------------- diff --git a/contrib/ipfilter/test/expected/n17 b/contrib/ipfilter/test/expected/n17 new file mode 100644 index 000000000000..f336bb0fb8d7 --- /dev/null +++ b/contrib/ipfilter/test/expected/n17 @@ -0,0 +1,24 @@ +4500 00a0 0000 0100 3f06 7555 0101 0101 0201 0101 0401 0019 0000 0000 0000 0000 5010 2000 86b7 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 + +4500 00a0 0000 0100 3f06 7553 0201 0101 0101 0103 0401 0019 0000 0000 0000 0000 5010 2000 86b7 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 + +List of active MAP/Redirect filters: +bimap zx0 0/0 -> 1.1.1.3/32 + +List of active sessions: + +Hostmap table: +List of active state sessions: +List of configured pools +List of configured hash tables +List of groups configured (set 0) +List of groups configured (set 1) +Rules configured (set 0, in) +Rules configured (set 0, out) +Rules configured (set 1, in) +Rules configured (set 1, out) +Accounting rules configured (set 0, in) +Accounting rules configured (set 0, out) +Accounting rules configured (set 1, in) +Accounting rules configured (set 1, out) +------------------------------- diff --git a/contrib/ipfilter/test/expected/n18 b/contrib/ipfilter/test/expected/n18 new file mode 100644 index 000000000000..c51c11c9a52e --- /dev/null +++ b/contrib/ipfilter/test/expected/n18 @@ -0,0 +1,111 @@ +> z0 ip #0 40(20) 6 1.1.1.1,1 > 3.3.3.3,30 +> z0 ip #0 40(20) 6 1.1.1.1,2 > 3.3.3.3,31 +> z0 ip #0 40(20) 6 1.1.1.1,3 > 3.3.3.3,32 +> z0 ip #0 40(20) 6 1.1.1.1,4 > 3.3.3.3,33 +> z0 ip #0 40(20) 6 1.1.1.1,1 > 3.3.3.3,34 +> z0 ip #0 40(20) 6 1.1.1.1,2 > 3.3.3.3,35 +> z0 ip #0 40(20) 6 1.1.1.1,3 > 3.3.3.3,36 +> z0 ip #0 40(20) 6 1.1.1.1,4 > 3.3.3.3,37 +List of active MAP/Redirect filters: +map z0 0/0 -> 1.1.1.1/32 portmap tcp/udp 1:4 sequential + +List of active sessions: +MAP 2.2.2.2 29 <- -> 1.1.1.1 4 [3.3.3.3 37] +MAP 2.2.2.2 28 <- -> 1.1.1.1 3 [3.3.3.3 36] +MAP 2.2.2.2 27 <- -> 1.1.1.1 2 [3.3.3.3 35] +MAP 2.2.2.2 26 <- -> 1.1.1.1 1 [3.3.3.3 34] +MAP 2.2.2.2 25 <- -> 1.1.1.1 4 [3.3.3.3 33] +MAP 2.2.2.2 24 <- -> 1.1.1.1 3 [3.3.3.3 32] +MAP 2.2.2.2 23 <- -> 1.1.1.1 2 [3.3.3.3 31] +MAP 2.2.2.2 22 <- -> 1.1.1.1 1 [3.3.3.3 30] + +Hostmap table: +2.2.2.2,3.3.3.3 -> 1.1.1.1,0.0.0.0 (use = 8) +List of active state sessions: +List of configured pools +List of configured hash tables +List of groups configured (set 0) +List of groups configured (set 1) +Rules configured (set 0, in) +Rules configured (set 0, out) +Rules configured (set 1, in) +Rules configured (set 1, out) +Accounting rules configured (set 0, in) +Accounting rules configured (set 0, out) +Accounting rules configured (set 1, in) +Accounting rules configured (set 1, out) +------------------------------- +> z0 ip #0 40(20) 6 1.1.1.1,1000 > 3.3.3.3,30 +> z0 ip #0 40(20) 6 1.1.1.1,1001 > 3.3.3.3,31 +> z0 ip #0 40(20) 6 1.1.1.1,1002 > 3.3.3.3,32 +> z0 ip #0 40(20) 6 1.1.1.1,1003 > 3.3.3.3,33 +> z0 ip #0 40(20) 6 1.1.1.1,1004 > 3.3.3.3,34 +> z0 ip #0 40(20) 6 1.1.1.1,1005 > 3.3.3.3,35 +> z0 ip #0 40(20) 6 1.1.1.1,1006 > 3.3.3.3,36 +> z0 ip #0 40(20) 6 1.1.1.1,1007 > 3.3.3.3,37 +List of active MAP/Redirect filters: +map z0 0/0 -> 1.1.1.1/32 portmap tcp/udp 1000:5000 sequential + +List of active sessions: +MAP 2.2.2.2 29 <- -> 1.1.1.1 1007 [3.3.3.3 37] +MAP 2.2.2.2 28 <- -> 1.1.1.1 1006 [3.3.3.3 36] +MAP 2.2.2.2 27 <- -> 1.1.1.1 1005 [3.3.3.3 35] +MAP 2.2.2.2 26 <- -> 1.1.1.1 1004 [3.3.3.3 34] +MAP 2.2.2.2 25 <- -> 1.1.1.1 1003 [3.3.3.3 33] +MAP 2.2.2.2 24 <- -> 1.1.1.1 1002 [3.3.3.3 32] +MAP 2.2.2.2 23 <- -> 1.1.1.1 1001 [3.3.3.3 31] +MAP 2.2.2.2 22 <- -> 1.1.1.1 1000 [3.3.3.3 30] + +Hostmap table: +2.2.2.2,3.3.3.3 -> 1.1.1.1,0.0.0.0 (use = 8) +List of active state sessions: +List of configured pools +List of configured hash tables +List of groups configured (set 0) +List of groups configured (set 1) +Rules configured (set 0, in) +Rules configured (set 0, out) +Rules configured (set 1, in) +Rules configured (set 1, out) +Accounting rules configured (set 0, in) +Accounting rules configured (set 0, out) +Accounting rules configured (set 1, in) +Accounting rules configured (set 1, out) +------------------------------- +> z0 ip #0 40(20) 6 1.1.1.1,1000 > 3.3.3.3,30 +> z0 ip #0 40(20) 6 1.1.1.1,1001 > 3.3.3.3,31 +> z0 ip #0 40(20) 6 1.1.1.1,1002 > 3.3.3.3,32 +> z0 ip #0 40(20) 6 1.1.1.1,1003 > 3.3.3.3,33 +> z0 ip #0 40(20) 6 1.1.1.1,1004 > 3.3.3.3,34 +> z0 ip #0 40(20) 6 1.1.1.1,1005 > 3.3.3.3,35 +> z0 ip #0 40(20) 6 1.1.1.1,1006 > 3.3.3.3,36 +> z0 ip #0 40(20) 6 1.1.1.1,1007 > 3.3.3.3,37 +List of active MAP/Redirect filters: +map z0 0/0 -> 1.1.1.1/32 portmap tcp/udp 1000:50000 sequential + +List of active sessions: +MAP 2.2.2.2 29 <- -> 1.1.1.1 1007 [3.3.3.3 37] +MAP 2.2.2.2 28 <- -> 1.1.1.1 1006 [3.3.3.3 36] +MAP 2.2.2.2 27 <- -> 1.1.1.1 1005 [3.3.3.3 35] +MAP 2.2.2.2 26 <- -> 1.1.1.1 1004 [3.3.3.3 34] +MAP 2.2.2.2 25 <- -> 1.1.1.1 1003 [3.3.3.3 33] +MAP 2.2.2.2 24 <- -> 1.1.1.1 1002 [3.3.3.3 32] +MAP 2.2.2.2 23 <- -> 1.1.1.1 1001 [3.3.3.3 31] +MAP 2.2.2.2 22 <- -> 1.1.1.1 1000 [3.3.3.3 30] + +Hostmap table: +2.2.2.2,3.3.3.3 -> 1.1.1.1,0.0.0.0 (use = 8) +List of active state sessions: +List of configured pools +List of configured hash tables +List of groups configured (set 0) +List of groups configured (set 1) +Rules configured (set 0, in) +Rules configured (set 0, out) +Rules configured (set 1, in) +Rules configured (set 1, out) +Accounting rules configured (set 0, in) +Accounting rules configured (set 0, out) +Accounting rules configured (set 1, in) +Accounting rules configured (set 1, out) +------------------------------- diff --git a/contrib/ipfilter/test/expected/n1_6 b/contrib/ipfilter/test/expected/n1_6 new file mode 100644 index 000000000000..347bf4aac4bc --- /dev/null +++ b/contrib/ipfilter/test/expected/n1_6 @@ -0,0 +1,197 @@ +> zx0 ip6/0 1 0 255 10:1:1:0:0:0:0:0 > 10:1:1:0:0:0:0:2 +> zx0 ip6/0 1 0 255 10:0:0:0:0:2:2:2 > 10:1:1:0:0:0:0:2 +> zx0 ip6/0 1 0 255 10:1:1:0:0:0:0:2 > 10:1:1:0:0:0:0:1 +> zx0 ip6/0 20 0 6 10:1:1:0:0:0:0:2,1025 > 10:1:1:0:0:0:0:1,1025 +> zx0 ip6/0 20 0 6 10:1:1:0:0:0:0:2,1026 > 10:1:1:0:0:0:0:1,1025 +> zx0 ip6/0 1 0 255 10:0:0:0:0:2:2:1 > 10:1:2:0:0:0:0:1 +> zx0 ip6/0 1 0 255 10:0:0:0:0:2:2:2 > 10:1:2:0:0:0:0:1 +< zx0 ip6/0 1 0 255 10:1:1:0:0:0:0:1 > 10:1:1:0:0:0:0:2 +< zx0 ip6/0 1 0 255 10:1:1:0:0:0:0:2 > 10:1:1:0:0:0:0:1 +< zx0 ip6/0 1 0 255 10:0:0:0:0:2:2:1 > 10:0:0:0:0:2:1:1 +< zx0 ip6/0 1 0 255 10:0:0:0:0:2:2:2 > 10:0:0:0:0:2:1:1 +< zx0 ip6/0 1 0 255 10:0:0:0:0:2:2:3 > 10:1:1:0:0:0:0:1 +< zx0 ip6/0 1 0 255 10:0:0:0:0:2:3:4 > 10:0:0:0:0:2:2:2 +< zx0 ip6/0 1 0 255 10:1:1:0:0:0:0:1 > 10:0:0:0:0:2:2:2 +< zx0 ip6/0 1 0 255 10:1:1:0:0:0:0:2 > 10:1:1:0:0:0:0:1 +< zx0 ip6/0 1 0 255 10:1:1:0:0:0:0:0 > 10:0:0:0:0:3:4:5 +< zx0 ip6/0 1 0 255 10:1:1:0:0:0:0:1 > 10:0:0:0:0:3:4:5 +< zx0 ip6/0 1 0 255 10:1:1:0:0:0:0:2 > 10:0:0:0:0:3:4:5 +< zx0 ip6/0 20 0 6 10:1:1:0:0:0:0:1,1025 > 10:0:0:0:0:3:4:5,1025 +> zx0 ip6/0 88 0 58 10:0:0:0:0:2:2:2 > 10:4:3:0:0:0:0:2 +< zx0 ip6/0 88 0 58 10:4:3:0:0:0:0:2 > 10:1:1:0:0:0:0:1 +< zx0 ip6/0 88 0 58 10:4:3:0:0:0:0:2 > 10:0:0:0:0:3:4:1 +< zx0 ip6/0 88 0 58 10:4:3:0:0:0:0:2 > 10:0:0:0:0:3:4:2 +< zx0 ip6/0 88 0 58 10:4:3:0:0:0:0:2 > 10:0:0:0:0:3:4:3 +< zx0 ip6/0 88 0 58 10:4:3:0:0:0:0:2 > 10:0:0:0:0:3:4:4 +< zx0 ip6/0 88 0 58 10:4:3:0:0:0:0:2 > 10:0:0:0:0:3:4:5 +> zx0 ip6/0 1 0 34 10:1:1:0:0:0:0:2 > 10:4:3:0:0:0:0:2 +< zx0 ip6/0 1 0 34 10:4:3:0:0:0:0:2 > 10:0:0:0:0:3:4:4 +> zx0 ip6/0 1 0 34 10:1:1:0:0:0:0:2 > 10:4:3:0:0:0:0:4 +< zx0 ip6/0 1 0 34 10:4:3:0:0:0:0:4 > 10:0:0:0:0:3:4:5 +> zx0 ip6/0 1 0 34 10:1:1:0:0:0:0:3 > 10:4:3:0:0:0:0:4 +< zx0 ip6/0 1 0 34 10:4:3:0:0:0:0:4 > 10:0:0:0:0:3:4:6 +> zx0 ip6/0 1 0 35 10:1:1:0:0:0:0:3 > 10:4:3:0:0:0:0:4 +< zx0 ip6/0 1 0 35 10:4:3:0:0:0:0:4 > 10:0:0:0:0:3:4:7 +List of active MAP/Redirect filters: +map zx0 inet6 10:1:1::1/128 -> 10::2:2:2/128 + +List of active sessions: +MAP 10:1:1::1 <- -> 10::2:2:2 [10:4:3::2] +MAP 10:1:1::1 <- -> 10::2:2:2 [10:1:1::2] + +Hostmap table: +10:1:1::1,10:4:3::2 -> 10::2:2:2,any (use = 1) +10:1:1::1,10:1:1::2 -> 10::2:2:2,any (use = 1) +List of active state sessions: +List of configured pools +List of configured hash tables +List of groups configured (set 0) +List of groups configured (set 1) +Rules configured (set 0, in) +Rules configured (set 0, out) +Rules configured (set 1, in) +Rules configured (set 1, out) +Accounting rules configured (set 0, in) +Accounting rules configured (set 0, out) +Accounting rules configured (set 1, in) +Accounting rules configured (set 1, out) +------------------------------- +> zx0 ip6/0 1 0 255 10:0:0:0:0:3:4:5 > 10:1:1:0:0:0:0:2 +16 +> zx0 ip6/0 1 0 255 10:0:0:0:0:3:4:5 > 10:1:1:0:0:0:0:1 +> zx0 ip6/0 20 0 6 10:0:0:0:0:3:4:5,1025 > 10:1:1:0:0:0:0:1,1025 +> zx0 ip6/0 20 0 6 10:0:0:0:0:3:4:5,1026 > 10:1:1:0:0:0:0:1,1025 +> zx0 ip6/0 1 0 255 10:0:0:0:0:2:2:1 > 10:1:2:0:0:0:0:1 +> zx0 ip6/0 1 0 255 10:0:0:0:0:2:2:2 > 10:1:2:0:0:0:0:1 +< zx0 ip6/0 1 0 255 10:1:1:0:0:0:0:1 > 10:1:1:0:0:0:0:2 +< zx0 ip6/0 1 0 255 10:1:1:0:0:0:0:2 > 10:1:1:0:0:0:0:1 +< zx0 ip6/0 1 0 255 10:0:0:0:0:2:2:1 > 10:0:0:0:0:2:1:1 +< zx0 ip6/0 1 0 255 10:0:0:0:0:2:2:2 > 10:0:0:0:0:2:1:1 +< zx0 ip6/0 1 0 255 10:0:0:0:0:2:2:3 > 10:1:1:0:0:0:0:1 +< zx0 ip6/0 1 0 255 10:0:0:0:0:2:3:4 > 10:0:0:0:0:2:2:2 +< zx0 ip6/0 1 0 255 10:1:1:0:0:0:0:1 > 10:0:0:0:0:2:2:2 +< zx0 ip6/0 1 0 255 10:1:1:0:0:0:0:2 > 10:0:0:0:0:2:2:2 +< zx0 ip6/0 1 0 255 10:1:1:0:0:0:0:0 > 10:0:0:0:0:3:4:5 +< zx0 ip6/0 1 0 255 10:1:1:0:0:0:0:1 > 10:1:1:0:0:0:0:2 +< zx0 ip6/0 1 0 255 10:1:1:0:0:0:0:2 > 10:1:1:0:0:0:0:0 +< zx0 ip6/0 20 0 6 10:1:1:0:0:0:0:1,1025 > 10:1:1:0:0:0:0:2,1025 +> zx0 ip6/0 88 0 58 10:0:0:0:0:3:4:5 > 10:4:3:0:0:0:0:2 +< zx0 ip6/0 88 0 58 10:4:3:0:0:0:0:2 > 10:0:0:0:0:2:2:2 +< zx0 ip6/0 88 0 58 10:4:3:0:0:0:0:2 > 10:0:0:0:0:3:4:1 +< zx0 ip6/0 88 0 58 10:4:3:0:0:0:0:2 > 10:0:0:0:0:3:4:2 +< zx0 ip6/0 88 0 58 10:4:3:0:0:0:0:2 > 10:0:0:0:0:3:4:3 +< zx0 ip6/0 88 0 58 10:4:3:0:0:0:0:2 > 10:0:0:0:0:3:4:4 +< zx0 ip6/0 88 0 58 10:4:3:0:0:0:0:2 > 10:1:1:0:0:0:0:1 +> zx0 ip6/0 1 0 34 10:0:0:0:0:3:4:5 > 10:4:3:0:0:0:0:2 +< zx0 ip6/0 1 0 34 10:4:3:0:0:0:0:2 > 10:0:0:0:0:3:4:4 +> zx0 ip6/0 1 0 34 10:0:0:0:0:3:4:5 > 10:4:3:0:0:0:0:4 +< zx0 ip6/0 1 0 34 10:4:3:0:0:0:0:4 > 10:1:1:0:0:0:0:2 +16 +< zx0 ip6/0 1 0 34 10:4:3:0:0:0:0:4 > 10:0:0:0:0:3:4:6 +> zx0 ip6/0 1 0 35 10:0:0:0:0:3:4:5 > 10:4:3:0:0:0:0:4 +< zx0 ip6/0 1 0 35 10:4:3:0:0:0:0:4 > 10:0:0:0:0:3:4:7 +List of active MAP/Redirect filters: +map zx0 inet6 10:1:1::/112 -> 10::3:4:5/128 + +List of active sessions: +MAP 10:1:1::3 <- -> 10::3:4:5 [10:4:3::4] +MAP 10:1:1::2 <- -> 10::3:4:5 [10:4:3::4] +MAP 10:1:1::2 <- -> 10::3:4:5 [10:4:3::2] +MAP 10:1:1::1 <- -> 10::3:4:5 [10:4:3::2] +MAP 10:1:1::2 1026 <- -> 10::3:4:5 1026 [10:1:1::1 1025] +MAP 10:1:1::2 1025 <- -> 10::3:4:5 1025 [10:1:1::1 1025] +MAP 10:1:1::2 <- -> 10::3:4:5 [10:1:1::1] +MAP 10:1:1:: <- -> 10::3:4:5 [10:1:1::2] + +Hostmap table: +10:1:1::3,10:4:3::4 -> 10::3:4:5,any (use = 1) +10:1:1::2,10:4:3::4 -> 10::3:4:5,any (use = 1) +10:1:1::2,10:4:3::2 -> 10::3:4:5,any (use = 1) +10:1:1::1,10:4:3::2 -> 10::3:4:5,any (use = 1) +10:1:1::2,10:1:1::1 -> 10::3:4:5,any (use = 3) +10:1:1::,10:1:1::2 -> 10::3:4:5,any (use = 1) +List of active state sessions: +List of configured pools +List of configured hash tables +List of groups configured (set 0) +List of groups configured (set 1) +Rules configured (set 0, in) +Rules configured (set 0, out) +Rules configured (set 1, in) +Rules configured (set 1, out) +Accounting rules configured (set 0, in) +Accounting rules configured (set 0, out) +Accounting rules configured (set 1, in) +Accounting rules configured (set 1, out) +------------------------------- +> zx0 ip6/0 1 0 255 10:0:0:0:0:3:4:1 > 10:1:1:0:0:0:0:2 +> zx0 ip6/0 1 0 255 10:0:0:0:0:3:4:2 > 10:1:1:0:0:0:0:2 +> zx0 ip6/0 1 0 255 10:0:0:0:0:3:4:3 > 10:1:1:0:0:0:0:1 +> zx0 ip6/0 20 0 6 10:0:0:0:0:3:4:3,1025 > 10:1:1:0:0:0:0:1,1025 +> zx0 ip6/0 20 0 6 10:0:0:0:0:3:4:3,1026 > 10:1:1:0:0:0:0:1,1025 +> zx0 ip6/0 1 0 255 10:0:0:0:0:2:2:1 > 10:1:2:0:0:0:0:1 +> zx0 ip6/0 1 0 255 10:0:0:0:0:2:2:2 > 10:1:2:0:0:0:0:1 +< zx0 ip6/0 1 0 255 10:1:1:0:0:0:0:1 > 10:1:1:0:0:0:0:2 +< zx0 ip6/0 1 0 255 10:1:1:0:0:0:0:2 > 10:1:1:0:0:0:0:1 +< zx0 ip6/0 1 0 255 10:0:0:0:0:2:2:1 > 10:0:0:0:0:2:1:1 +< zx0 ip6/0 1 0 255 10:0:0:0:0:2:2:2 > 10:0:0:0:0:2:1:1 +< zx0 ip6/0 1 0 255 10:0:0:0:0:2:2:3 > 10:1:1:0:0:0:0:1 +< zx0 ip6/0 1 0 255 10:0:0:0:0:2:3:4 > 10:0:0:0:0:2:2:2 +< zx0 ip6/0 1 0 255 10:1:1:0:0:0:0:1 > 10:0:0:0:0:2:2:2 +< zx0 ip6/0 1 0 255 10:1:1:0:0:0:0:2 > 10:0:0:0:0:2:2:2 +< zx0 ip6/0 1 0 255 10:1:1:0:0:0:0:0 > 10:0:0:0:0:3:4:5 +< zx0 ip6/0 1 0 255 10:1:1:0:0:0:0:1 > 10:0:0:0:0:3:4:5 +< zx0 ip6/0 1 0 255 10:1:1:0:0:0:0:2 > 10:0:0:0:0:3:4:5 +< zx0 ip6/0 20 0 6 10:1:1:0:0:0:0:1,1025 > 10:0:0:0:0:3:4:5,1025 +> zx0 ip6/0 88 0 58 10:0:0:0:0:3:4:3 > 10:4:3:0:0:0:0:2 +< zx0 ip6/0 88 0 58 10:4:3:0:0:0:0:2 > 10:0:0:0:0:2:2:2 +< zx0 ip6/0 88 0 58 10:4:3:0:0:0:0:2 > 10:0:0:0:0:3:4:1 +< zx0 ip6/0 88 0 58 10:4:3:0:0:0:0:2 > 10:0:0:0:0:3:4:2 +< zx0 ip6/0 88 0 58 10:4:3:0:0:0:0:2 > 10:1:1:0:0:0:0:1 +< zx0 ip6/0 88 0 58 10:4:3:0:0:0:0:2 > 10:0:0:0:0:3:4:4 +< zx0 ip6/0 88 0 58 10:4:3:0:0:0:0:2 > 10:0:0:0:0:3:4:5 +> zx0 ip6/0 1 0 34 10:0:0:0:0:3:4:3 > 10:4:3:0:0:0:0:2 +< zx0 ip6/0 1 0 34 10:4:3:0:0:0:0:2 > 10:0:0:0:0:3:4:4 +> zx0 ip6/0 1 0 34 10:0:0:0:0:3:4:3 > 10:4:3:0:0:0:0:4 +< zx0 ip6/0 1 0 34 10:4:3:0:0:0:0:4 > 10:0:0:0:0:3:4:5 +> zx0 ip6/0 1 0 34 10:0:0:0:0:3:4:4 > 10:4:3:0:0:0:0:4 +< zx0 ip6/0 1 0 34 10:4:3:0:0:0:0:4 > 10:0:0:0:0:3:4:6 +> zx0 ip6/0 1 0 35 10:0:0:0:0:3:4:4 > 10:4:3:0:0:0:0:4 +< zx0 ip6/0 1 0 35 10:4:3:0:0:0:0:4 > 10:0:0:0:0:3:4:7 +List of active MAP/Redirect filters: +map zx0 inet6 10:1:1::/112 -> 10::3:4:0/112 + +List of active sessions: +MAP 10:1:1::3 <- -> 10::3:4:4 [10:4:3::4] +MAP 10:1:1::3 <- -> 10::3:4:4 [10:4:3::4] +MAP 10:1:1::2 <- -> 10::3:4:3 [10:4:3::4] +MAP 10:1:1::2 <- -> 10::3:4:3 [10:4:3::2] +MAP 10:1:1::1 <- -> 10::3:4:3 [10:4:3::2] +MAP 10:1:1::2 1026 <- -> 10::3:4:3 1026 [10:1:1::1 1025] +MAP 10:1:1::2 1025 <- -> 10::3:4:3 1025 [10:1:1::1 1025] +MAP 10:1:1::2 <- -> 10::3:4:3 [10:1:1::1] +MAP 10:1:1::1 <- -> 10::3:4:2 [10:1:1::2] +MAP 10:1:1:: <- -> 10::3:4:1 [10:1:1::2] + +Hostmap table: +10:1:1::3,10:4:3::4 -> 10::3:4:4,any (use = 2) +10:1:1::2,10:4:3::4 -> 10::3:4:3,any (use = 1) +10:1:1::2,10:4:3::2 -> 10::3:4:3,any (use = 1) +10:1:1::1,10:4:3::2 -> 10::3:4:3,any (use = 1) +10:1:1::2,10:1:1::1 -> 10::3:4:3,any (use = 3) +10:1:1::1,10:1:1::2 -> 10::3:4:2,any (use = 1) +10:1:1::,10:1:1::2 -> 10::3:4:1,any (use = 1) +List of active state sessions: +List of configured pools +List of configured hash tables +List of groups configured (set 0) +List of groups configured (set 1) +Rules configured (set 0, in) +Rules configured (set 0, out) +Rules configured (set 1, in) +Rules configured (set 1, out) +Accounting rules configured (set 0, in) +Accounting rules configured (set 0, out) +Accounting rules configured (set 1, in) +Accounting rules configured (set 1, out) +------------------------------- diff --git a/contrib/ipfilter/test/expected/n2 b/contrib/ipfilter/test/expected/n2 index 827272e91031..836608a46ad7 100644 --- a/contrib/ipfilter/test/expected/n2 +++ b/contrib/ipfilter/test/expected/n2 @@ -1,80 +1,191 @@ -ip #0 40(20) 6 10.2.2.2,10000 > 10.1.1.1,1025 -ip #0 40(20) 6 10.2.2.2,10001 > 10.1.1.2,1025 -ip #0 20(20) 0 10.1.1.0 > 10.1.1.2 -ip #0 20(20) 0 10.1.1.1 > 10.1.2.1 -ip #0 40(20) 6 10.1.1.2,1025 > 10.1.1.1,1025 -ip #0 40(20) 6 10.1.1.2,1025 > 10.1.1.1,1025 -ip #0 40(20) 6 10.1.1.2,1026 > 10.1.1.1,1025 -ip #0 28(20) 17 10.1.1.2,1025 > 10.1.1.1,1025 -ip #0 40(20) 6 10.1.1.3,2000 > 10.1.2.1,80 -ip #0 40(20) 6 10.1.1.3,2001 > 10.1.3.1,80 -ip #0 40(20) 6 10.1.1.3,2002 > 10.1.4.1,80 -ip #0 40(20) 6 10.1.1.3,2003 > 10.1.4.1,80 -ip #0 20(20) 0 10.1.1.1 > 10.1.1.2 -ip #0 40(20) 6 10.1.1.1,1025 > 10.1.1.2,1025 -ip #0 20(20) 0 10.1.1.2 > 10.1.1.1 -ip #0 40(20) 6 10.1.1.1,1026 > 10.3.4.5,40000 -ip #0 40(20) 6 10.1.1.1,1025 > 10.3.4.5,40000 -ip #0 28(20) 17 10.1.1.2,1025 > 10.3.4.5,40001 -ip #0 40(20) 6 10.1.2.1,80 > 10.3.4.5,40001 +> zx0 ip #0 40(20) 6 10.2.2.2,10000 > 10.1.1.1,1025 +> zx0 ip #0 40(20) 6 10.2.2.2,10001 > 10.1.1.2,1025 +> zx0 ip #0 20(20) 0 10.1.1.0 > 10.1.1.2 +> zx0 ip #0 20(20) 0 10.1.1.1 > 10.1.2.1 +> zx0 ip #0 40(20) 6 10.1.1.2,1025 > 10.1.1.1,1025 +> zx0 ip #0 40(20) 6 10.1.1.2,1025 > 10.1.1.1,1025 +> zx0 ip #0 40(20) 6 10.1.1.2,1026 > 10.1.1.1,1025 +> zx0 ip #0 28(20) 17 10.1.1.2,1025 > 10.1.1.1,1025 +> zx0 ip #0 40(20) 6 10.1.1.3,2000 > 10.1.2.1,80 +> zx0 ip #0 40(20) 6 10.1.1.3,2001 > 10.1.3.1,80 +> zx0 ip #0 40(20) 6 10.1.1.3,2002 > 10.1.4.1,80 +> zx0 ip #0 40(20) 6 10.1.1.3,2003 > 10.1.4.1,80 +< zx0 ip #0 20(20) 0 10.1.1.1 > 10.1.1.2 +< zx0 ip #0 40(20) 6 10.1.1.1,1025 > 10.1.1.2,1025 +< zx0 ip #0 20(20) 0 10.1.1.2 > 10.1.1.1 +< zx0 ip #0 40(20) 6 10.1.1.1,1026 > 10.3.4.5,40000 +< zx0 ip #0 40(20) 6 10.1.1.1,1025 > 10.3.4.5,40000 +< zx0 ip #0 28(20) 17 10.1.1.2,1025 > 10.3.4.5,40001 +< zx0 ip #0 40(20) 6 10.1.2.1,80 > 10.3.4.5,40001 +List of active MAP/Redirect filters: +map zx0 10.1.1.1/32 -> 10.2.2.2/32 portmap tcp 10000:20000 sequential + +List of active sessions: +MAP 10.1.1.1 1025 <- -> 10.2.2.2 10001 [10.1.1.2 1025] +MAP 10.1.1.1 1025 <- -> 10.2.2.2 10000 [10.1.1.1 1025] + +Hostmap table: +10.1.1.1,10.1.1.2 -> 10.2.2.2,0.0.0.0 (use = 1) +10.1.1.1,10.1.1.1 -> 10.2.2.2,0.0.0.0 (use = 1) +List of active state sessions: +List of configured pools +List of configured hash tables +List of groups configured (set 0) +List of groups configured (set 1) +Rules configured (set 0, in) +Rules configured (set 0, out) +Rules configured (set 1, in) +Rules configured (set 1, out) +Accounting rules configured (set 0, in) +Accounting rules configured (set 0, out) +Accounting rules configured (set 1, in) +Accounting rules configured (set 1, out) ------------------------------- -ip #0 40(20) 6 10.1.1.1,1025 > 10.1.1.1,1025 -ip #0 40(20) 6 10.1.1.1,1025 > 10.1.1.2,1025 -ip #0 20(20) 0 10.1.1.0 > 10.1.1.2 -ip #0 20(20) 0 10.1.1.1 > 10.1.2.1 -ip #0 40(20) 6 10.1.1.2,1025 > 10.1.1.1,1025 -ip #0 40(20) 6 10.1.1.2,1025 > 10.1.1.1,1025 -ip #0 40(20) 6 10.1.1.2,1026 > 10.1.1.1,1025 -ip #0 28(20) 17 10.3.4.5,10000 > 10.1.1.1,1025 -ip #0 40(20) 6 10.1.1.3,2000 > 10.1.2.1,80 -ip #0 40(20) 6 10.1.1.3,2001 > 10.1.3.1,80 -ip #0 40(20) 6 10.1.1.3,2002 > 10.1.4.1,80 -ip #0 40(20) 6 10.1.1.3,2003 > 10.1.4.1,80 -ip #0 20(20) 0 10.1.1.1 > 10.1.1.2 -ip #0 40(20) 6 10.1.1.1,1025 > 10.1.1.2,1025 -ip #0 20(20) 0 10.1.1.2 > 10.1.1.1 -ip #0 40(20) 6 10.1.1.1,1026 > 10.3.4.5,40000 -ip #0 40(20) 6 10.1.1.1,1025 > 10.3.4.5,40000 -ip #0 28(20) 17 10.1.1.2,1025 > 10.3.4.5,40001 -ip #0 40(20) 6 10.1.2.1,80 > 10.3.4.5,40001 +> zx0 ip #0 40(20) 6 10.1.1.1,1025 > 10.1.1.1,1025 +> zx0 ip #0 40(20) 6 10.1.1.1,1025 > 10.1.1.2,1025 +> zx0 ip #0 20(20) 0 10.1.1.0 > 10.1.1.2 +> zx0 ip #0 20(20) 0 10.1.1.1 > 10.1.2.1 +> zx0 ip #0 40(20) 6 10.1.1.2,1025 > 10.1.1.1,1025 +> zx0 ip #0 40(20) 6 10.1.1.2,1025 > 10.1.1.1,1025 +> zx0 ip #0 40(20) 6 10.1.1.2,1026 > 10.1.1.1,1025 +> zx0 ip #0 28(20) 17 10.3.4.5,10000 > 10.1.1.1,1025 +> zx0 ip #0 40(20) 6 10.1.1.3,2000 > 10.1.2.1,80 +> zx0 ip #0 40(20) 6 10.1.1.3,2001 > 10.1.3.1,80 +> zx0 ip #0 40(20) 6 10.1.1.3,2002 > 10.1.4.1,80 +> zx0 ip #0 40(20) 6 10.1.1.3,2003 > 10.1.4.1,80 +< zx0 ip #0 20(20) 0 10.1.1.1 > 10.1.1.2 +< zx0 ip #0 40(20) 6 10.1.1.1,1025 > 10.1.1.2,1025 +< zx0 ip #0 20(20) 0 10.1.1.2 > 10.1.1.1 +< zx0 ip #0 40(20) 6 10.1.1.1,1026 > 10.3.4.5,40000 +< zx0 ip #0 40(20) 6 10.1.1.1,1025 > 10.3.4.5,40000 +< zx0 ip #0 28(20) 17 10.1.1.2,1025 > 10.3.4.5,40001 +< zx0 ip #0 40(20) 6 10.1.2.1,80 > 10.3.4.5,40001 +List of active MAP/Redirect filters: +map zx0 10.1.1.0/24 -> 10.3.4.5/32 portmap udp 10000:20000 sequential + +List of active sessions: +MAP 10.1.1.2 1025 <- -> 10.3.4.5 10000 [10.1.1.1 1025] + +Hostmap table: +10.1.1.2,10.1.1.1 -> 10.3.4.5,0.0.0.0 (use = 1) +List of active state sessions: +List of configured pools +List of configured hash tables +List of groups configured (set 0) +List of groups configured (set 1) +Rules configured (set 0, in) +Rules configured (set 0, out) +Rules configured (set 1, in) +Rules configured (set 1, out) +Accounting rules configured (set 0, in) +Accounting rules configured (set 0, out) +Accounting rules configured (set 1, in) +Accounting rules configured (set 1, out) ------------------------------- -ip #0 40(20) 6 10.3.4.1,10000 > 10.1.1.1,1025 -ip #0 40(20) 6 10.3.4.1,10001 > 10.1.1.2,1025 -ip #0 20(20) 0 10.1.1.0 > 10.1.1.2 -ip #0 20(20) 0 10.1.1.1 > 10.1.2.1 -ip #0 40(20) 6 10.3.4.1,10002 > 10.1.1.1,1025 -ip #0 40(20) 6 10.3.4.1,10002 > 10.1.1.1,1025 -ip #0 40(20) 6 10.3.4.1,10003 > 10.1.1.1,1025 -ip #0 28(20) 17 10.3.4.1,10004 > 10.1.1.1,1025 -ip #0 40(20) 6 10.3.4.1,10005 > 10.1.2.1,80 -ip #0 40(20) 6 10.3.4.1,10006 > 10.1.3.1,80 -ip #0 40(20) 6 10.3.4.1,10007 > 10.1.4.1,80 -ip #0 40(20) 6 10.3.4.1,10008 > 10.1.4.1,80 -ip #0 20(20) 0 10.1.1.1 > 10.1.1.2 -ip #0 40(20) 6 10.1.1.1,1025 > 10.1.1.2,1025 -ip #0 20(20) 0 10.1.1.2 > 10.1.1.1 -ip #0 40(20) 6 10.1.1.1,1026 > 10.3.4.5,40000 -ip #0 40(20) 6 10.1.1.1,1025 > 10.3.4.5,40000 -ip #0 28(20) 17 10.1.1.2,1025 > 10.3.4.5,40001 -ip #0 40(20) 6 10.1.2.1,80 > 10.3.4.5,40001 +> zx0 ip #0 40(20) 6 10.3.4.1,10000 > 10.1.1.1,1025 +> zx0 ip #0 40(20) 6 10.3.4.1,10001 > 10.1.1.2,1025 +> zx0 ip #0 20(20) 0 10.1.1.0 > 10.1.1.2 +> zx0 ip #0 20(20) 0 10.1.1.1 > 10.1.2.1 +> zx0 ip #0 40(20) 6 10.3.4.1,10002 > 10.1.1.1,1025 +> zx0 ip #0 40(20) 6 10.3.4.1,10002 > 10.1.1.1,1025 +> zx0 ip #0 40(20) 6 10.3.4.1,10003 > 10.1.1.1,1025 +> zx0 ip #0 28(20) 17 10.3.4.1,10004 > 10.1.1.1,1025 +> zx0 ip #0 40(20) 6 10.3.4.1,10005 > 10.1.2.1,80 +> zx0 ip #0 40(20) 6 10.3.4.1,10006 > 10.1.3.1,80 +> zx0 ip #0 40(20) 6 10.3.4.1,10007 > 10.1.4.1,80 +> zx0 ip #0 40(20) 6 10.3.4.1,10008 > 10.1.4.1,80 +< zx0 ip #0 20(20) 0 10.1.1.1 > 10.1.1.2 +< zx0 ip #0 40(20) 6 10.1.1.1,1025 > 10.1.1.2,1025 +< zx0 ip #0 20(20) 0 10.1.1.2 > 10.1.1.1 +< zx0 ip #0 40(20) 6 10.1.1.1,1026 > 10.3.4.5,40000 +< zx0 ip #0 40(20) 6 10.1.1.1,1025 > 10.3.4.5,40000 +< zx0 ip #0 28(20) 17 10.1.1.2,1025 > 10.3.4.5,40001 +< zx0 ip #0 40(20) 6 10.1.2.1,80 > 10.3.4.5,40001 +List of active MAP/Redirect filters: +map zx0 10.1.0.0/16 -> 10.3.4.0/24 portmap tcp/udp 10000:20000 sequential + +List of active sessions: +MAP 10.1.1.3 2003 <- -> 10.3.4.1 10008 [10.1.4.1 80] +MAP 10.1.1.3 2002 <- -> 10.3.4.1 10007 [10.1.4.1 80] +MAP 10.1.1.3 2001 <- -> 10.3.4.1 10006 [10.1.3.1 80] +MAP 10.1.1.3 2000 <- -> 10.3.4.1 10005 [10.1.2.1 80] +MAP 10.1.1.2 1025 <- -> 10.3.4.1 10004 [10.1.1.1 1025] +MAP 10.1.1.2 1026 <- -> 10.3.4.1 10003 [10.1.1.1 1025] +MAP 10.1.1.2 1025 <- -> 10.3.4.1 10002 [10.1.1.1 1025] +MAP 10.1.1.1 1025 <- -> 10.3.4.1 10001 [10.1.1.2 1025] +MAP 10.1.1.1 1025 <- -> 10.3.4.1 10000 [10.1.1.1 1025] + +Hostmap table: +10.1.1.3,10.1.4.1 -> 10.3.4.1,0.0.0.0 (use = 2) +10.1.1.3,10.1.3.1 -> 10.3.4.1,0.0.0.0 (use = 1) +10.1.1.3,10.1.2.1 -> 10.3.4.1,0.0.0.0 (use = 1) +10.1.1.2,10.1.1.1 -> 10.3.4.1,0.0.0.0 (use = 3) +10.1.1.1,10.1.1.2 -> 10.3.4.1,0.0.0.0 (use = 1) +10.1.1.1,10.1.1.1 -> 10.3.4.1,0.0.0.0 (use = 1) +List of active state sessions: +List of configured pools +List of configured hash tables +List of groups configured (set 0) +List of groups configured (set 1) +Rules configured (set 0, in) +Rules configured (set 0, out) +Rules configured (set 1, in) +Rules configured (set 1, out) +Accounting rules configured (set 0, in) +Accounting rules configured (set 0, out) +Accounting rules configured (set 1, in) +Accounting rules configured (set 1, out) ------------------------------- -ip #0 40(20) 6 10.3.4.5,40000 > 10.1.1.1,1025 -ip #0 40(20) 6 10.3.4.5,40001 > 10.1.1.2,1025 -ip #0 20(20) 0 10.1.1.0 > 10.1.1.2 -ip #0 20(20) 0 10.1.1.1 > 10.1.2.1 -ip #0 40(20) 6 10.3.4.5,40001 > 10.1.1.1,1025 -ip #0 40(20) 6 10.3.4.5,40001 > 10.1.1.1,1025 -ip #0 40(20) 6 10.1.1.2,1026 > 10.1.1.1,1025 -ip #0 28(20) 17 10.3.4.5,40000 > 10.1.1.1,1025 -ip #0 40(20) 6 10.3.4.5,40001 > 10.1.2.1,80 -ip #0 40(20) 6 10.3.4.5,40000 > 10.1.3.1,80 -ip #0 40(20) 6 10.3.4.5,40001 > 10.1.4.1,80 -ip #0 40(20) 6 10.3.4.5,40000 > 10.1.4.1,80 -ip #0 20(20) 0 10.1.1.1 > 10.1.1.2 -ip #0 40(20) 6 10.1.1.1,1025 > 10.1.1.2,1025 -ip #0 20(20) 0 10.1.1.2 > 10.1.1.1 -ip #0 40(20) 6 10.1.1.1,1026 > 10.3.4.5,40000 -ip #0 40(20) 6 10.1.1.1,1025 > 10.1.1.1,1025 -ip #0 28(20) 17 10.1.1.2,1025 > 10.3.4.5,40001 -ip #0 40(20) 6 10.1.2.1,80 > 10.1.1.3,2000 +> zx0 ip #0 40(20) 6 10.3.4.5,40000 > 10.1.1.1,1025 +> zx0 ip #0 40(20) 6 10.3.4.5,40001 > 10.1.1.2,1025 +> zx0 ip #0 20(20) 0 10.1.1.0 > 10.1.1.2 +> zx0 ip #0 20(20) 0 10.1.1.1 > 10.1.2.1 +> zx0 ip #0 40(20) 6 10.3.4.5,40001 > 10.1.1.1,1025 +> zx0 ip #0 40(20) 6 10.3.4.5,40001 > 10.1.1.1,1025 +15 +> zx0 ip #0 28(20) 17 10.3.4.5,40000 > 10.1.1.1,1025 +> zx0 ip #0 40(20) 6 10.3.4.5,40001 > 10.1.2.1,80 +> zx0 ip #0 40(20) 6 10.3.4.5,40000 > 10.1.3.1,80 +> zx0 ip #0 40(20) 6 10.3.4.5,40001 > 10.1.4.1,80 +> zx0 ip #0 40(20) 6 10.3.4.5,40000 > 10.1.4.1,80 +< zx0 ip #0 20(20) 0 10.1.1.1 > 10.1.1.2 +< zx0 ip #0 40(20) 6 10.1.1.1,1025 > 10.1.1.2,1025 +< zx0 ip #0 20(20) 0 10.1.1.2 > 10.1.1.1 +< zx0 ip #0 40(20) 6 10.1.1.1,1026 > 10.3.4.5,40000 +< zx0 ip #0 40(20) 6 10.1.1.1,1025 > 10.1.1.1,1025 +< zx0 ip #0 28(20) 17 10.1.1.2,1025 > 10.3.4.5,40001 +< zx0 ip #0 40(20) 6 10.1.2.1,80 > 10.1.1.3,2000 +List of active MAP/Redirect filters: +map zx0 10.1.1.0/24 -> 10.3.4.5/32 portmap tcp/udp 40000:40001 sequential + +List of active sessions: +MAP 10.1.1.3 2003 <- -> 10.3.4.5 40000 [10.1.4.1 80] +MAP 10.1.1.3 2002 <- -> 10.3.4.5 40001 [10.1.4.1 80] +MAP 10.1.1.3 2001 <- -> 10.3.4.5 40000 [10.1.3.1 80] +MAP 10.1.1.3 2000 <- -> 10.3.4.5 40001 [10.1.2.1 80] +MAP 10.1.1.2 1025 <- -> 10.3.4.5 40000 [10.1.1.1 1025] +MAP 10.1.1.2 1025 <- -> 10.3.4.5 40001 [10.1.1.1 1025] +MAP 10.1.1.1 1025 <- -> 10.3.4.5 40001 [10.1.1.2 1025] +MAP 10.1.1.1 1025 <- -> 10.3.4.5 40000 [10.1.1.1 1025] + +Hostmap table: +10.1.1.3,10.1.4.1 -> 10.3.4.5,0.0.0.0 (use = 2) +10.1.1.3,10.1.3.1 -> 10.3.4.5,0.0.0.0 (use = 1) +10.1.1.3,10.1.2.1 -> 10.3.4.5,0.0.0.0 (use = 1) +10.1.1.2,10.1.1.1 -> 10.3.4.5,0.0.0.0 (use = 2) +10.1.1.1,10.1.1.2 -> 10.3.4.5,0.0.0.0 (use = 1) +10.1.1.1,10.1.1.1 -> 10.3.4.5,0.0.0.0 (use = 1) +List of active state sessions: +List of configured pools +List of configured hash tables +List of groups configured (set 0) +List of groups configured (set 1) +Rules configured (set 0, in) +Rules configured (set 0, out) +Rules configured (set 1, in) +Rules configured (set 1, out) +Accounting rules configured (set 0, in) +Accounting rules configured (set 0, out) +Accounting rules configured (set 1, in) +Accounting rules configured (set 1, out) ------------------------------- diff --git a/contrib/ipfilter/test/expected/n200 b/contrib/ipfilter/test/expected/n200 new file mode 100644 index 000000000000..0f3c6a5adece --- /dev/null +++ b/contrib/ipfilter/test/expected/n200 @@ -0,0 +1,25 @@ +4500 0044 0000 0000 ff11 bda6 7f00 0001 7f00 0001 2775 2775 0030 0000 4500 0028 0000 0000 0006 435a 6363 6363 5858 5858 038d 0050 0000 0000 0000 0000 5000 1000 2491 0000 + +4500 0028 0000 0000 0006 435a 6363 6363 5858 5858 038d 0050 0000 0000 0000 0000 5000 1000 2491 0000 + +List of active MAP/Redirect filters: +divert in on bar0 proto tcp from 0/0 to 0/0 -> src 127.0.0.1/32,10101 dst 127.0.0.1/32,10101 udp; + +List of active sessions: +DIV-RDR 127.0.0.1 10101 <- -> 88.88.88.88 80 [99.99.99.99 909] + +Hostmap table: +List of active state sessions: +List of configured pools +List of configured hash tables +List of groups configured (set 0) +List of groups configured (set 1) +Rules configured (set 0, in) +Rules configured (set 0, out) +Rules configured (set 1, in) +Rules configured (set 1, out) +Accounting rules configured (set 0, in) +Accounting rules configured (set 0, out) +Accounting rules configured (set 1, in) +Accounting rules configured (set 1, out) +------------------------------- diff --git a/contrib/ipfilter/test/expected/n2_6 b/contrib/ipfilter/test/expected/n2_6 new file mode 100644 index 000000000000..08abc8f5b69c --- /dev/null +++ b/contrib/ipfilter/test/expected/n2_6 @@ -0,0 +1,191 @@ +> zx0 ip6/0 20 0 6 10:0:0:0:0:2:2:2,10000 > 10:1:1:0:0:0:0:1,1025 +> zx0 ip6/0 20 0 6 10:0:0:0:0:2:2:2,10001 > 10:1:1:0:0:0:0:2,1025 +> zx0 ip6/0 1 0 41 10:1:1:0:0:0:0:0 > 10:1:1:0:0:0:0:2 +> zx0 ip6/0 1 0 41 10:1:1:0:0:0:0:1 > 10:1:2:0:0:0:0:1 +> zx0 ip6/0 20 0 6 10:1:1:0:0:0:0:2,1025 > 10:1:1:0:0:0:0:1,1025 +> zx0 ip6/0 20 0 6 10:1:1:0:0:0:0:2,1025 > 10:1:1:0:0:0:0:1,1025 +> zx0 ip6/0 20 0 6 10:1:1:0:0:0:0:2,1026 > 10:1:1:0:0:0:0:1,1025 +> zx0 ip6/0 8 0 17 10:1:1:0:0:0:0:2,1025 > 10:1:1:0:0:0:0:1,1025 +> zx0 ip6/0 20 0 6 10:1:1:0:0:0:0:3,2000 > 10:1:2:0:0:0:0:1,80 +> zx0 ip6/0 20 0 6 10:1:1:0:0:0:0:3,2001 > 10:1:3:0:0:0:0:1,80 +> zx0 ip6/0 20 0 6 10:1:1:0:0:0:0:3,2002 > 10:1:4:0:0:0:0:1,80 +> zx0 ip6/0 20 0 6 10:1:1:0:0:0:0:3,2003 > 10:1:4:0:0:0:0:1,80 +< zx0 ip6/0 1 0 41 10:1:1:0:0:0:0:1 > 10:1:1:0:0:0:0:2 +< zx0 ip6/0 20 0 6 10:1:1:0:0:0:0:1,1025 > 10:1:1:0:0:0:0:2,1025 +< zx0 ip6/0 1 0 41 10:1:1:0:0:0:0:2 > 10:1:1:0:0:0:0:1 +< zx0 ip6/0 20 0 6 10:1:1:0:0:0:0:1,1026 > 10:0:0:0:0:3:4:5,40000 +< zx0 ip6/0 20 0 6 10:1:1:0:0:0:0:1,1025 > 10:0:0:0:0:3:4:5,40000 +< zx0 ip6/0 8 0 17 10:1:1:0:0:0:0:2,1025 > 10:0:0:0:0:3:4:5,40001 +< zx0 ip6/0 20 0 6 10:1:2:0:0:0:0:1,80 > 10:0:0:0:0:3:4:5,40001 +List of active MAP/Redirect filters: +map zx0 inet6 10:1:1::1/128 -> 10::2:2:2/128 portmap tcp 10000:20000 sequential + +List of active sessions: +MAP 10:1:1::1 1025 <- -> 10::2:2:2 10001 [10:1:1::2 1025] +MAP 10:1:1::1 1025 <- -> 10::2:2:2 10000 [10:1:1::1 1025] + +Hostmap table: +10:1:1::1,10:1:1::2 -> 10::2:2:2,any (use = 1) +10:1:1::1,10:1:1::1 -> 10::2:2:2,any (use = 1) +List of active state sessions: +List of configured pools +List of configured hash tables +List of groups configured (set 0) +List of groups configured (set 1) +Rules configured (set 0, in) +Rules configured (set 0, out) +Rules configured (set 1, in) +Rules configured (set 1, out) +Accounting rules configured (set 0, in) +Accounting rules configured (set 0, out) +Accounting rules configured (set 1, in) +Accounting rules configured (set 1, out) +------------------------------- +> zx0 ip6/0 20 0 6 10:1:1:0:0:0:0:1,1025 > 10:1:1:0:0:0:0:1,1025 +> zx0 ip6/0 20 0 6 10:1:1:0:0:0:0:1,1025 > 10:1:1:0:0:0:0:2,1025 +> zx0 ip6/0 1 0 41 10:1:1:0:0:0:0:0 > 10:1:1:0:0:0:0:2 +> zx0 ip6/0 1 0 41 10:1:1:0:0:0:0:1 > 10:1:2:0:0:0:0:1 +> zx0 ip6/0 20 0 6 10:1:1:0:0:0:0:2,1025 > 10:1:1:0:0:0:0:1,1025 +> zx0 ip6/0 20 0 6 10:1:1:0:0:0:0:2,1025 > 10:1:1:0:0:0:0:1,1025 +> zx0 ip6/0 20 0 6 10:1:1:0:0:0:0:2,1026 > 10:1:1:0:0:0:0:1,1025 +> zx0 ip6/0 8 0 17 10:0:0:0:0:3:4:5,10000 > 10:1:1:0:0:0:0:1,1025 +> zx0 ip6/0 20 0 6 10:1:1:0:0:0:0:3,2000 > 10:1:2:0:0:0:0:1,80 +> zx0 ip6/0 20 0 6 10:1:1:0:0:0:0:3,2001 > 10:1:3:0:0:0:0:1,80 +> zx0 ip6/0 20 0 6 10:1:1:0:0:0:0:3,2002 > 10:1:4:0:0:0:0:1,80 +> zx0 ip6/0 20 0 6 10:1:1:0:0:0:0:3,2003 > 10:1:4:0:0:0:0:1,80 +< zx0 ip6/0 1 0 41 10:1:1:0:0:0:0:1 > 10:1:1:0:0:0:0:2 +< zx0 ip6/0 20 0 6 10:1:1:0:0:0:0:1,1025 > 10:1:1:0:0:0:0:2,1025 +< zx0 ip6/0 1 0 41 10:1:1:0:0:0:0:2 > 10:1:1:0:0:0:0:1 +< zx0 ip6/0 20 0 6 10:1:1:0:0:0:0:1,1026 > 10:0:0:0:0:3:4:5,40000 +< zx0 ip6/0 20 0 6 10:1:1:0:0:0:0:1,1025 > 10:0:0:0:0:3:4:5,40000 +< zx0 ip6/0 8 0 17 10:1:1:0:0:0:0:2,1025 > 10:0:0:0:0:3:4:5,40001 +< zx0 ip6/0 20 0 6 10:1:2:0:0:0:0:1,80 > 10:0:0:0:0:3:4:5,40001 +List of active MAP/Redirect filters: +map zx0 inet6 10:1:1::/112 -> 10::3:4:5/128 portmap udp 10000:20000 sequential + +List of active sessions: +MAP 10:1:1::2 1025 <- -> 10::3:4:5 10000 [10:1:1::1 1025] + +Hostmap table: +10:1:1::2,10:1:1::1 -> 10::3:4:5,any (use = 1) +List of active state sessions: +List of configured pools +List of configured hash tables +List of groups configured (set 0) +List of groups configured (set 1) +Rules configured (set 0, in) +Rules configured (set 0, out) +Rules configured (set 1, in) +Rules configured (set 1, out) +Accounting rules configured (set 0, in) +Accounting rules configured (set 0, out) +Accounting rules configured (set 1, in) +Accounting rules configured (set 1, out) +------------------------------- +> zx0 ip6/0 20 0 6 10:0:0:0:0:3:4:1,10000 > 10:1:1:0:0:0:0:1,1025 +> zx0 ip6/0 20 0 6 10:0:0:0:0:3:4:1,10001 > 10:1:1:0:0:0:0:2,1025 +> zx0 ip6/0 1 0 41 10:1:1:0:0:0:0:0 > 10:1:1:0:0:0:0:2 +> zx0 ip6/0 1 0 41 10:1:1:0:0:0:0:1 > 10:1:2:0:0:0:0:1 +> zx0 ip6/0 20 0 6 10:0:0:0:0:3:4:1,10002 > 10:1:1:0:0:0:0:1,1025 +> zx0 ip6/0 20 0 6 10:0:0:0:0:3:4:1,10002 > 10:1:1:0:0:0:0:1,1025 +> zx0 ip6/0 20 0 6 10:0:0:0:0:3:4:1,10003 > 10:1:1:0:0:0:0:1,1025 +> zx0 ip6/0 8 0 17 10:0:0:0:0:3:4:1,10004 > 10:1:1:0:0:0:0:1,1025 +> zx0 ip6/0 20 0 6 10:0:0:0:0:3:4:1,10005 > 10:1:2:0:0:0:0:1,80 +> zx0 ip6/0 20 0 6 10:0:0:0:0:3:4:1,10006 > 10:1:3:0:0:0:0:1,80 +> zx0 ip6/0 20 0 6 10:0:0:0:0:3:4:1,10007 > 10:1:4:0:0:0:0:1,80 +> zx0 ip6/0 20 0 6 10:0:0:0:0:3:4:1,10008 > 10:1:4:0:0:0:0:1,80 +< zx0 ip6/0 1 0 41 10:1:1:0:0:0:0:1 > 10:1:1:0:0:0:0:2 +< zx0 ip6/0 20 0 6 10:1:1:0:0:0:0:1,1025 > 10:1:1:0:0:0:0:2,1025 +< zx0 ip6/0 1 0 41 10:1:1:0:0:0:0:2 > 10:1:1:0:0:0:0:1 +< zx0 ip6/0 20 0 6 10:1:1:0:0:0:0:1,1026 > 10:0:0:0:0:3:4:5,40000 +< zx0 ip6/0 20 0 6 10:1:1:0:0:0:0:1,1025 > 10:0:0:0:0:3:4:5,40000 +< zx0 ip6/0 8 0 17 10:1:1:0:0:0:0:2,1025 > 10:0:0:0:0:3:4:5,40001 +< zx0 ip6/0 20 0 6 10:1:2:0:0:0:0:1,80 > 10:0:0:0:0:3:4:5,40001 +List of active MAP/Redirect filters: +map zx0 inet6 10:1::/32 -> 10::3:4:0/112 portmap tcp/udp 10000:20000 sequential + +List of active sessions: +MAP 10:1:1::3 2003 <- -> 10::3:4:1 10008 [10:1:4::1 80] +MAP 10:1:1::3 2002 <- -> 10::3:4:1 10007 [10:1:4::1 80] +MAP 10:1:1::3 2001 <- -> 10::3:4:1 10006 [10:1:3::1 80] +MAP 10:1:1::3 2000 <- -> 10::3:4:1 10005 [10:1:2::1 80] +MAP 10:1:1::2 1025 <- -> 10::3:4:1 10004 [10:1:1::1 1025] +MAP 10:1:1::2 1026 <- -> 10::3:4:1 10003 [10:1:1::1 1025] +MAP 10:1:1::2 1025 <- -> 10::3:4:1 10002 [10:1:1::1 1025] +MAP 10:1:1::1 1025 <- -> 10::3:4:1 10001 [10:1:1::2 1025] +MAP 10:1:1::1 1025 <- -> 10::3:4:1 10000 [10:1:1::1 1025] + +Hostmap table: +10:1:1::3,10:1:4::1 -> 10::3:4:1,any (use = 2) +10:1:1::3,10:1:3::1 -> 10::3:4:1,any (use = 1) +10:1:1::3,10:1:2::1 -> 10::3:4:1,any (use = 1) +10:1:1::2,10:1:1::1 -> 10::3:4:1,any (use = 3) +10:1:1::1,10:1:1::2 -> 10::3:4:1,any (use = 1) +10:1:1::1,10:1:1::1 -> 10::3:4:1,any (use = 1) +List of active state sessions: +List of configured pools +List of configured hash tables +List of groups configured (set 0) +List of groups configured (set 1) +Rules configured (set 0, in) +Rules configured (set 0, out) +Rules configured (set 1, in) +Rules configured (set 1, out) +Accounting rules configured (set 0, in) +Accounting rules configured (set 0, out) +Accounting rules configured (set 1, in) +Accounting rules configured (set 1, out) +------------------------------- +> zx0 ip6/0 20 0 6 10:0:0:0:0:3:4:5,40000 > 10:1:1:0:0:0:0:1,1025 +> zx0 ip6/0 20 0 6 10:0:0:0:0:3:4:5,40001 > 10:1:1:0:0:0:0:2,1025 +> zx0 ip6/0 1 0 41 10:1:1:0:0:0:0:0 > 10:1:1:0:0:0:0:2 +> zx0 ip6/0 1 0 41 10:1:1:0:0:0:0:1 > 10:1:2:0:0:0:0:1 +> zx0 ip6/0 20 0 6 10:0:0:0:0:3:4:5,40001 > 10:1:1:0:0:0:0:1,1025 +> zx0 ip6/0 20 0 6 10:0:0:0:0:3:4:5,40001 > 10:1:1:0:0:0:0:1,1025 +16 +> zx0 ip6/0 8 0 17 10:0:0:0:0:3:4:5,40000 > 10:1:1:0:0:0:0:1,1025 +> zx0 ip6/0 20 0 6 10:0:0:0:0:3:4:5,40001 > 10:1:2:0:0:0:0:1,80 +> zx0 ip6/0 20 0 6 10:0:0:0:0:3:4:5,40000 > 10:1:3:0:0:0:0:1,80 +> zx0 ip6/0 20 0 6 10:0:0:0:0:3:4:5,40001 > 10:1:4:0:0:0:0:1,80 +> zx0 ip6/0 20 0 6 10:0:0:0:0:3:4:5,40000 > 10:1:4:0:0:0:0:1,80 +< zx0 ip6/0 1 0 41 10:1:1:0:0:0:0:1 > 10:1:1:0:0:0:0:2 +< zx0 ip6/0 20 0 6 10:1:1:0:0:0:0:1,1025 > 10:1:1:0:0:0:0:2,1025 +< zx0 ip6/0 1 0 41 10:1:1:0:0:0:0:2 > 10:1:1:0:0:0:0:1 +< zx0 ip6/0 20 0 6 10:1:1:0:0:0:0:1,1026 > 10:0:0:0:0:3:4:5,40000 +< zx0 ip6/0 20 0 6 10:1:1:0:0:0:0:1,1025 > 10:1:1:0:0:0:0:1,1025 +< zx0 ip6/0 8 0 17 10:1:1:0:0:0:0:2,1025 > 10:0:0:0:0:3:4:5,40001 +< zx0 ip6/0 20 0 6 10:1:2:0:0:0:0:1,80 > 10:1:1:0:0:0:0:3,2000 +List of active MAP/Redirect filters: +map zx0 inet6 10:1:1::/112 -> 10::3:4:5/128 portmap tcp/udp 40000:40001 sequential + +List of active sessions: +MAP 10:1:1::3 2003 <- -> 10::3:4:5 40000 [10:1:4::1 80] +MAP 10:1:1::3 2002 <- -> 10::3:4:5 40001 [10:1:4::1 80] +MAP 10:1:1::3 2001 <- -> 10::3:4:5 40000 [10:1:3::1 80] +MAP 10:1:1::3 2000 <- -> 10::3:4:5 40001 [10:1:2::1 80] +MAP 10:1:1::2 1025 <- -> 10::3:4:5 40000 [10:1:1::1 1025] +MAP 10:1:1::2 1025 <- -> 10::3:4:5 40001 [10:1:1::1 1025] +MAP 10:1:1::1 1025 <- -> 10::3:4:5 40001 [10:1:1::2 1025] +MAP 10:1:1::1 1025 <- -> 10::3:4:5 40000 [10:1:1::1 1025] + +Hostmap table: +10:1:1::3,10:1:4::1 -> 10::3:4:5,any (use = 2) +10:1:1::3,10:1:3::1 -> 10::3:4:5,any (use = 1) +10:1:1::3,10:1:2::1 -> 10::3:4:5,any (use = 1) +10:1:1::2,10:1:1::1 -> 10::3:4:5,any (use = 2) +10:1:1::1,10:1:1::2 -> 10::3:4:5,any (use = 1) +10:1:1::1,10:1:1::1 -> 10::3:4:5,any (use = 1) +List of active state sessions: +List of configured pools +List of configured hash tables +List of groups configured (set 0) +List of groups configured (set 1) +Rules configured (set 0, in) +Rules configured (set 0, out) +Rules configured (set 1, in) +Rules configured (set 1, out) +Accounting rules configured (set 0, in) +Accounting rules configured (set 0, out) +Accounting rules configured (set 1, in) +Accounting rules configured (set 1, out) +------------------------------- diff --git a/contrib/ipfilter/test/expected/n3 b/contrib/ipfilter/test/expected/n3 index 0e019aefb2ba..66ada76e930a 100644 --- a/contrib/ipfilter/test/expected/n3 +++ b/contrib/ipfilter/test/expected/n3 @@ -1,12 +1,66 @@ -ip #0 40(20) 6 192.168.2.1,1488 > 203.1.1.1,80 -ip #0 40(20) 6 192.168.2.1,1276 > 203.1.1.1,80 -ip #0 40(20) 6 192.168.2.1,1032 > 203.1.1.1,80 -ip #0 28(20) 17 192.168.2.1,1032 > 203.1.1.1,80 -ip #0 40(20) 6 192.168.2.1,65299 > 203.1.1.1,80 +> zz0 ip #0 40(20) 6 192.168.2.1,1488 > 203.1.1.1,80 +> zz0 ip #0 40(20) 6 192.168.2.1,1276 > 203.1.1.1,80 +> zz0 ip #0 40(20) 6 192.168.2.1,1032 > 203.1.1.1,80 +> zz0 ip #0 28(20) 17 192.168.2.1,1032 > 203.1.1.1,80 +> zz0 ip #0 40(20) 6 192.168.2.1,65299 > 203.1.1.1,80 +List of active MAP/Redirect filters: +map zz0 10.1.0.0/16 -> 192.168.2.0/24 portmap tcp/udp auto + +List of active sessions: +MAP 10.1.255.255 65535 <- -> 192.168.2.1 65299 [203.1.1.1 80] +MAP 10.1.0.0 32768 <- -> 192.168.2.1 1032 [203.1.1.1 80] +MAP 10.1.0.0 32768 <- -> 192.168.2.1 1032 [203.1.1.1 80] +MAP 10.1.1.1 252 <- -> 192.168.2.1 1276 [203.1.1.1 80] +MAP 10.1.1.1 5000 <- -> 192.168.2.1 1488 [203.1.1.1 80] + +Hostmap table: +10.1.255.255,203.1.1.1 -> 192.168.2.1,0.0.0.0 (use = 1) +10.1.0.0,203.1.1.1 -> 192.168.2.1,0.0.0.0 (use = 2) +10.1.1.1,203.1.1.1 -> 192.168.2.1,0.0.0.0 (use = 2) +List of active state sessions: +List of configured pools +List of configured hash tables +List of groups configured (set 0) +List of groups configured (set 1) +Rules configured (set 0, in) +Rules configured (set 0, out) +Rules configured (set 1, in) +Rules configured (set 1, out) +Accounting rules configured (set 0, in) +Accounting rules configured (set 0, out) +Accounting rules configured (set 1, in) +Accounting rules configured (set 1, out) ------------------------------- -ip #0 40(20) 6 192.168.1.1,1488 > 203.1.1.1,80 -ip #0 40(20) 6 192.168.1.1,1276 > 203.1.1.1,80 -ip #0 40(20) 6 192.168.1.0,1032 > 203.1.1.1,80 -ip #0 28(20) 17 192.168.1.0,1032 > 203.1.1.1,80 -ip #0 40(20) 6 192.168.1.255,65299 > 203.1.1.1,80 +> zz0 ip #0 40(20) 6 192.168.1.1,1488 > 203.1.1.1,80 +> zz0 ip #0 40(20) 6 192.168.1.1,1276 > 203.1.1.1,80 +> zz0 ip #0 40(20) 6 192.168.1.0,1032 > 203.1.1.1,80 +> zz0 ip #0 28(20) 17 192.168.1.0,1032 > 203.1.1.1,80 +> zz0 ip #0 40(20) 6 192.168.1.255,65299 > 203.1.1.1,80 +List of active MAP/Redirect filters: +map-block zz0 10.1.0.0/16 -> 192.168.1.0/24 ports 252 + +List of active sessions: +MAP-BLOCK 10.1.255.255 65535 <- -> 192.168.1.255 65299 [203.1.1.1 80] +MAP-BLOCK 10.1.0.0 32768 <- -> 192.168.1.0 1032 [203.1.1.1 80] +MAP-BLOCK 10.1.0.0 32768 <- -> 192.168.1.0 1032 [203.1.1.1 80] +MAP-BLOCK 10.1.1.1 252 <- -> 192.168.1.1 1276 [203.1.1.1 80] +MAP-BLOCK 10.1.1.1 5000 <- -> 192.168.1.1 1488 [203.1.1.1 80] + +Hostmap table: +10.1.255.255,203.1.1.1 -> 192.168.1.1,0.0.0.0 (use = 1) +10.1.0.0,203.1.1.1 -> 192.168.1.1,0.0.0.0 (use = 2) +10.1.1.1,203.1.1.1 -> 192.168.1.1,0.0.0.0 (use = 2) +List of active state sessions: +List of configured pools +List of configured hash tables +List of groups configured (set 0) +List of groups configured (set 1) +Rules configured (set 0, in) +Rules configured (set 0, out) +Rules configured (set 1, in) +Rules configured (set 1, out) +Accounting rules configured (set 0, in) +Accounting rules configured (set 0, out) +Accounting rules configured (set 1, in) +Accounting rules configured (set 1, out) ------------------------------- diff --git a/contrib/ipfilter/test/expected/n4 b/contrib/ipfilter/test/expected/n4 index 863217c1db79..746ef7e18583 100644 --- a/contrib/ipfilter/test/expected/n4 +++ b/contrib/ipfilter/test/expected/n4 @@ -1,66 +1,190 @@ -ip #0 40(20) 6 10.3.3.3,12345 > 10.2.2.1,10023 -ip #0 40(20) 6 10.1.1.1,23 > 10.3.3.3,12345 -ip #0 40(20) 6 10.3.3.3,12345 > 10.1.1.1,53 -ip #0 40(20) 6 10.2.2.1,10053 > 10.3.3.3,12345 -ip #0 40(20) 6 10.3.3.3,12346 > 10.1.0.0,23 -ip #0 40(20) 6 10.2.2.1,10023 > 10.3.3.3,12346 -ip #0 28(20) 17 10.3.3.3,12345 > 10.1.1.0,53 -ip #0 28(20) 17 10.2.2.1,10053 > 10.3.3.3,12345 -ip #0 40(20) 6 10.3.3.3,12345 > 10.1.1.0,53 -ip #0 40(20) 6 10.2.2.1,53 > 10.3.3.3,12345 +< zx0 ip #0 40(20) 6 10.3.3.3,12345 > 10.2.2.1,10023 +> zx0 ip #0 40(20) 6 10.1.1.1,23 > 10.3.3.3,12345 +< zx0 ip #0 40(20) 6 10.3.3.3,12345 > 10.1.1.1,53 +> zx0 ip #0 40(20) 6 10.2.2.1,10053 > 10.3.3.3,12345 +< zx0 ip #0 40(20) 6 10.3.3.3,12346 > 10.1.0.0,23 +> zx0 ip #0 40(20) 6 10.2.2.1,10023 > 10.3.3.3,12346 +< zx0 ip #0 28(20) 17 10.3.3.3,12345 > 10.1.1.0,53 +> zx0 ip #0 28(20) 17 10.2.2.1,10053 > 10.3.3.3,12345 +< zx0 ip #0 40(20) 6 10.3.3.3,12345 > 10.1.1.0,53 +> zx0 ip #0 40(20) 6 10.2.2.1,53 > 10.3.3.3,12345 +List of active MAP/Redirect filters: +rdr zx0 10.1.1.1/32 port 23 -> 10.2.2.1/32 port 10023 tcp + +List of active sessions: +RDR 10.2.2.1 10023 <- -> 10.1.1.1 23 [10.3.3.3 12345] + +Hostmap table: +List of active state sessions: +List of configured pools +List of configured hash tables +List of groups configured (set 0) +List of groups configured (set 1) +Rules configured (set 0, in) +Rules configured (set 0, out) +Rules configured (set 1, in) +Rules configured (set 1, out) +Accounting rules configured (set 0, in) +Accounting rules configured (set 0, out) +Accounting rules configured (set 1, in) +Accounting rules configured (set 1, out) ------------------------------- -ip #0 40(20) 6 10.3.3.3,12345 > 10.2.2.1,10023 -ip #0 40(20) 6 10.1.1.1,23 > 10.3.3.3,12345 -ip #0 40(20) 6 10.3.3.3,12345 > 10.1.1.1,53 -ip #0 40(20) 6 10.2.2.1,10053 > 10.3.3.3,12345 -ip #0 40(20) 6 10.3.3.3,12346 > 10.1.0.0,23 -ip #0 40(20) 6 10.2.2.1,10023 > 10.3.3.3,12346 -ip #0 28(20) 17 10.3.3.3,12345 > 10.1.1.0,53 -ip #0 28(20) 17 10.2.2.1,10053 > 10.3.3.3,12345 -ip #0 40(20) 6 10.3.3.3,12345 > 10.1.1.0,53 -ip #0 40(20) 6 10.2.2.1,53 > 10.3.3.3,12345 +< zx0 ip #0 40(20) 6 10.3.3.3,12345 > 10.2.2.1,10023 +> zx0 ip #0 40(20) 6 10.1.1.1,23 > 10.3.3.3,12345 +< zx0 ip #0 40(20) 6 10.3.3.3,12345 > 10.1.1.1,53 +> zx0 ip #0 40(20) 6 10.2.2.1,10053 > 10.3.3.3,12345 +< zx0 ip #0 40(20) 6 10.3.3.3,12346 > 10.1.0.0,23 +> zx0 ip #0 40(20) 6 10.2.2.1,10023 > 10.3.3.3,12346 +< zx0 ip #0 28(20) 17 10.3.3.3,12345 > 10.1.1.0,53 +> zx0 ip #0 28(20) 17 10.2.2.1,10053 > 10.3.3.3,12345 +< zx0 ip #0 40(20) 6 10.3.3.3,12345 > 10.1.1.0,53 +> zx0 ip #0 40(20) 6 10.2.2.1,53 > 10.3.3.3,12345 +List of active MAP/Redirect filters: +rdr zx0 10.1.1.0/24 port 23 -> 10.2.2.1/32 port 10023 tcp + +List of active sessions: +RDR 10.2.2.1 10023 <- -> 10.1.1.1 23 [10.3.3.3 12345] + +Hostmap table: +List of active state sessions: +List of configured pools +List of configured hash tables +List of groups configured (set 0) +List of groups configured (set 1) +Rules configured (set 0, in) +Rules configured (set 0, out) +Rules configured (set 1, in) +Rules configured (set 1, out) +Accounting rules configured (set 0, in) +Accounting rules configured (set 0, out) +Accounting rules configured (set 1, in) +Accounting rules configured (set 1, out) ------------------------------- -ip #0 40(20) 6 10.3.3.3,12345 > 10.2.2.1,10023 -ip #0 40(20) 6 10.1.1.1,23 > 10.3.3.3,12345 -ip #0 40(20) 6 10.3.3.3,12345 > 10.1.1.1,53 -ip #0 40(20) 6 10.2.2.1,10053 > 10.3.3.3,12345 -ip #0 40(20) 6 10.3.3.3,12346 > 10.2.2.1,10023 -ip #0 40(20) 6 10.1.0.0,23 > 10.3.3.3,12346 -ip #0 28(20) 17 10.3.3.3,12345 > 10.1.1.0,53 -ip #0 28(20) 17 10.2.2.1,10053 > 10.3.3.3,12345 -ip #0 40(20) 6 10.3.3.3,12345 > 10.1.1.0,53 -ip #0 40(20) 6 10.2.2.1,53 > 10.3.3.3,12345 +< zx0 ip #0 40(20) 6 10.3.3.3,12345 > 10.2.2.1,10023 +> zx0 ip #0 40(20) 6 10.1.1.1,23 > 10.3.3.3,12345 +< zx0 ip #0 40(20) 6 10.3.3.3,12345 > 10.1.1.1,53 +> zx0 ip #0 40(20) 6 10.2.2.1,10053 > 10.3.3.3,12345 +< zx0 ip #0 40(20) 6 10.3.3.3,12346 > 10.2.2.1,10023 +> zx0 ip #0 40(20) 6 10.1.0.0,23 > 10.3.3.3,12346 +< zx0 ip #0 28(20) 17 10.3.3.3,12345 > 10.1.1.0,53 +> zx0 ip #0 28(20) 17 10.2.2.1,10053 > 10.3.3.3,12345 +< zx0 ip #0 40(20) 6 10.3.3.3,12345 > 10.1.1.0,53 +> zx0 ip #0 40(20) 6 10.2.2.1,53 > 10.3.3.3,12345 +List of active MAP/Redirect filters: +rdr zx0 0/0 port 23 -> 10.2.2.1/32 port 10023 tcp + +List of active sessions: +RDR 10.2.2.1 10023 <- -> 10.1.0.0 23 [10.3.3.3 12346] +RDR 10.2.2.1 10023 <- -> 10.1.1.1 23 [10.3.3.3 12345] + +Hostmap table: +List of active state sessions: +List of configured pools +List of configured hash tables +List of groups configured (set 0) +List of groups configured (set 1) +Rules configured (set 0, in) +Rules configured (set 0, out) +Rules configured (set 1, in) +Rules configured (set 1, out) +Accounting rules configured (set 0, in) +Accounting rules configured (set 0, out) +Accounting rules configured (set 1, in) +Accounting rules configured (set 1, out) ------------------------------- -ip #0 40(20) 6 10.3.3.3,12345 > 10.1.1.1,23 -ip #0 40(20) 6 10.2.2.1,10023 > 10.3.3.3,12345 -ip #0 40(20) 6 10.3.3.3,12345 > 10.1.1.1,53 -ip #0 40(20) 6 10.2.2.1,10053 > 10.3.3.3,12345 -ip #0 40(20) 6 10.3.3.3,12346 > 10.1.0.0,23 -ip #0 40(20) 6 10.2.2.1,10023 > 10.3.3.3,12346 -ip #0 28(20) 17 10.3.3.3,12345 > 10.2.2.1,10053 -ip #0 28(20) 17 10.1.1.0,53 > 10.3.3.3,12345 -ip #0 40(20) 6 10.3.3.3,12345 > 10.1.1.0,53 -ip #0 40(20) 6 10.2.2.1,53 > 10.3.3.3,12345 +< zx0 ip #0 40(20) 6 10.3.3.3,12345 > 10.1.1.1,23 +> zx0 ip #0 40(20) 6 10.2.2.1,10023 > 10.3.3.3,12345 +< zx0 ip #0 40(20) 6 10.3.3.3,12345 > 10.1.1.1,53 +> zx0 ip #0 40(20) 6 10.2.2.1,10053 > 10.3.3.3,12345 +< zx0 ip #0 40(20) 6 10.3.3.3,12346 > 10.1.0.0,23 +> zx0 ip #0 40(20) 6 10.2.2.1,10023 > 10.3.3.3,12346 +< zx0 ip #0 28(20) 17 10.3.3.3,12345 > 10.2.2.1,10053 +> zx0 ip #0 28(20) 17 10.1.1.0,53 > 10.3.3.3,12345 +< zx0 ip #0 40(20) 6 10.3.3.3,12345 > 10.1.1.0,53 +> zx0 ip #0 40(20) 6 10.2.2.1,53 > 10.3.3.3,12345 +List of active MAP/Redirect filters: +rdr zx0 10.1.1.0/24 port 53 -> 10.2.2.1/32 port 10053 udp + +List of active sessions: +RDR 10.2.2.1 10053 <- -> 10.1.1.0 53 [10.3.3.3 12345] + +Hostmap table: +List of active state sessions: +List of configured pools +List of configured hash tables +List of groups configured (set 0) +List of groups configured (set 1) +Rules configured (set 0, in) +Rules configured (set 0, out) +Rules configured (set 1, in) +Rules configured (set 1, out) +Accounting rules configured (set 0, in) +Accounting rules configured (set 0, out) +Accounting rules configured (set 1, in) +Accounting rules configured (set 1, out) ------------------------------- -ip #0 40(20) 6 10.3.3.3,12345 > 10.2.2.1,23 -ip #0 40(20) 6 10.2.2.1,10023 > 10.3.3.3,12345 -ip #0 40(20) 6 10.3.3.3,12345 > 10.2.2.1,53 -ip #0 40(20) 6 10.2.2.1,10053 > 10.3.3.3,12345 -ip #0 40(20) 6 10.3.3.3,12346 > 10.1.0.0,23 -ip #0 40(20) 6 10.2.2.1,10023 > 10.3.3.3,12346 -ip #0 28(20) 17 10.3.3.3,12345 > 10.1.1.0,53 -ip #0 28(20) 17 10.2.2.1,10053 > 10.3.3.3,12345 -ip #0 40(20) 6 10.3.3.3,12345 > 10.1.1.0,53 -ip #0 40(20) 6 10.1.1.1,53 > 10.3.3.3,12345 +< zx0 ip #0 40(20) 6 10.3.3.3,12345 > 10.2.2.1,23 +> zx0 ip #0 40(20) 6 10.2.2.1,10023 > 10.3.3.3,12345 +< zx0 ip #0 40(20) 6 10.3.3.3,12345 > 10.2.2.1,53 +> zx0 ip #0 40(20) 6 10.2.2.1,10053 > 10.3.3.3,12345 +< zx0 ip #0 40(20) 6 10.3.3.3,12346 > 10.1.0.0,23 +> zx0 ip #0 40(20) 6 10.2.2.1,10023 > 10.3.3.3,12346 +< zx0 ip #0 28(20) 17 10.3.3.3,12345 > 10.1.1.0,53 +> zx0 ip #0 28(20) 17 10.2.2.1,10053 > 10.3.3.3,12345 +15 +> zx0 ip #0 40(20) 6 10.1.1.1,53 > 10.3.3.3,12345 +List of active MAP/Redirect filters: +rdr zx0 10.1.1.0/24 port 0 -> 10.2.2.1/32 port 0 tcp + +List of active sessions: +RDR 10.2.2.1 53 <- -> 10.1.1.1 53 [10.3.3.3 12345] +RDR 10.2.2.1 23 <- -> 10.1.1.1 23 [10.3.3.3 12345] + +Hostmap table: +List of active state sessions: +List of configured pools +List of configured hash tables +List of groups configured (set 0) +List of groups configured (set 1) +Rules configured (set 0, in) +Rules configured (set 0, out) +Rules configured (set 1, in) +Rules configured (set 1, out) +Accounting rules configured (set 0, in) +Accounting rules configured (set 0, out) +Accounting rules configured (set 1, in) +Accounting rules configured (set 1, out) ------------------------------- -ip #0 40(20) 6 10.3.3.3,12345 > 10.2.2.1,23 -ip #0 40(20) 6 10.2.2.1,10023 > 10.3.3.3,12345 -ip #0 40(20) 6 10.3.3.3,12345 > 10.2.2.1,53 -ip #0 40(20) 6 10.2.2.1,10053 > 10.3.3.3,12345 -ip #0 40(20) 6 10.3.3.3,12346 > 10.1.0.0,23 -ip #0 40(20) 6 10.2.2.1,10023 > 10.3.3.3,12346 -ip #0 28(20) 17 10.3.3.3,12345 > 10.2.2.1,53 -ip #0 28(20) 17 10.2.2.1,10053 > 10.3.3.3,12345 -ip #0 40(20) 6 10.3.3.3,12345 > 10.1.1.0,53 -ip #0 40(20) 6 10.1.1.1,53 > 10.3.3.3,12345 +< zx0 ip #0 40(20) 6 10.3.3.3,12345 > 10.2.2.1,23 +> zx0 ip #0 40(20) 6 10.2.2.1,10023 > 10.3.3.3,12345 +< zx0 ip #0 40(20) 6 10.3.3.3,12345 > 10.2.2.1,53 +> zx0 ip #0 40(20) 6 10.2.2.1,10053 > 10.3.3.3,12345 +< zx0 ip #0 40(20) 6 10.3.3.3,12346 > 10.1.0.0,23 +> zx0 ip #0 40(20) 6 10.2.2.1,10023 > 10.3.3.3,12346 +< zx0 ip #0 28(20) 17 10.3.3.3,12345 > 10.2.2.1,53 +> zx0 ip #0 28(20) 17 10.2.2.1,10053 > 10.3.3.3,12345 +15 +> zx0 ip #0 40(20) 6 10.1.1.1,53 > 10.3.3.3,12345 +List of active MAP/Redirect filters: +rdr zx0 10.1.1.0/24 -> 10.2.2.1/32 ip + +List of active sessions: +RDR 10.2.2.1 53 <- -> 10.1.1.0 53 [10.3.3.3 12345] +RDR 10.2.2.1 53 <- -> 10.1.1.1 53 [10.3.3.3 12345] +RDR 10.2.2.1 23 <- -> 10.1.1.1 23 [10.3.3.3 12345] + +Hostmap table: +List of active state sessions: +List of configured pools +List of configured hash tables +List of groups configured (set 0) +List of groups configured (set 1) +Rules configured (set 0, in) +Rules configured (set 0, out) +Rules configured (set 1, in) +Rules configured (set 1, out) +Accounting rules configured (set 0, in) +Accounting rules configured (set 0, out) +Accounting rules configured (set 1, in) +Accounting rules configured (set 1, out) ------------------------------- diff --git a/contrib/ipfilter/test/expected/n4_6 b/contrib/ipfilter/test/expected/n4_6 new file mode 100644 index 000000000000..e9a5ce34507c --- /dev/null +++ b/contrib/ipfilter/test/expected/n4_6 @@ -0,0 +1,190 @@ +< zx0 ip6/0 20 0 6 10:3:3:0:0:0:0:3,12345 > 10:0:0:0:0:2:2:1,10023 +> zx0 ip6/0 20 0 6 10:1:1:0:0:0:0:1,23 > 10:3:3:0:0:0:0:3,12345 +< zx0 ip6/0 20 0 6 10:3:3:0:0:0:0:3,12345 > 10:1:1:0:0:0:0:1,53 +> zx0 ip6/0 20 0 6 10:0:0:0:0:2:2:1,10053 > 10:3:3:0:0:0:0:3,12345 +< zx0 ip6/0 20 0 6 10:3:3:0:0:0:0:3,12346 > 10:1:0:0:0:0:0:0,23 +> zx0 ip6/0 20 0 6 10:0:0:0:0:2:2:1,10023 > 10:3:3:0:0:0:0:3,12346 +< zx0 ip6/0 8 0 17 10:3:3:0:0:0:0:3,12345 > 10:1:1:0:0:0:0:0,53 +> zx0 ip6/0 8 0 17 10:0:0:0:0:2:2:1,10053 > 10:3:3:0:0:0:0:3,12345 +< zx0 ip6/0 20 0 6 10:3:3:0:0:0:0:3,12345 > 10:1:1:0:0:0:0:0,53 +> zx0 ip6/0 20 0 6 10:0:0:0:0:2:2:1,53 > 10:3:3:0:0:0:0:3,12345 +List of active MAP/Redirect filters: +rdr zx0 inet6 10:1:1::1/128 port 23 -> 10::2:2:1/128 port 10023 tcp + +List of active sessions: +RDR 10::2:2:1 10023 <- -> 10:1:1::1 23 [10:3:3::3 12345] + +Hostmap table: +List of active state sessions: +List of configured pools +List of configured hash tables +List of groups configured (set 0) +List of groups configured (set 1) +Rules configured (set 0, in) +Rules configured (set 0, out) +Rules configured (set 1, in) +Rules configured (set 1, out) +Accounting rules configured (set 0, in) +Accounting rules configured (set 0, out) +Accounting rules configured (set 1, in) +Accounting rules configured (set 1, out) +------------------------------- +< zx0 ip6/0 20 0 6 10:3:3:0:0:0:0:3,12345 > 10:0:0:0:0:2:2:1,10023 +> zx0 ip6/0 20 0 6 10:1:1:0:0:0:0:1,23 > 10:3:3:0:0:0:0:3,12345 +< zx0 ip6/0 20 0 6 10:3:3:0:0:0:0:3,12345 > 10:1:1:0:0:0:0:1,53 +> zx0 ip6/0 20 0 6 10:0:0:0:0:2:2:1,10053 > 10:3:3:0:0:0:0:3,12345 +< zx0 ip6/0 20 0 6 10:3:3:0:0:0:0:3,12346 > 10:1:0:0:0:0:0:0,23 +> zx0 ip6/0 20 0 6 10:0:0:0:0:2:2:1,10023 > 10:3:3:0:0:0:0:3,12346 +< zx0 ip6/0 8 0 17 10:3:3:0:0:0:0:3,12345 > 10:1:1:0:0:0:0:0,53 +> zx0 ip6/0 8 0 17 10:0:0:0:0:2:2:1,10053 > 10:3:3:0:0:0:0:3,12345 +< zx0 ip6/0 20 0 6 10:3:3:0:0:0:0:3,12345 > 10:1:1:0:0:0:0:0,53 +> zx0 ip6/0 20 0 6 10:0:0:0:0:2:2:1,53 > 10:3:3:0:0:0:0:3,12345 +List of active MAP/Redirect filters: +rdr zx0 inet6 10:1:1::/112 port 23 -> 10::2:2:1/128 port 10023 tcp + +List of active sessions: +RDR 10::2:2:1 10023 <- -> 10:1:1::1 23 [10:3:3::3 12345] + +Hostmap table: +List of active state sessions: +List of configured pools +List of configured hash tables +List of groups configured (set 0) +List of groups configured (set 1) +Rules configured (set 0, in) +Rules configured (set 0, out) +Rules configured (set 1, in) +Rules configured (set 1, out) +Accounting rules configured (set 0, in) +Accounting rules configured (set 0, out) +Accounting rules configured (set 1, in) +Accounting rules configured (set 1, out) +------------------------------- +< zx0 ip6/0 20 0 6 10:3:3:0:0:0:0:3,12345 > 10:0:0:0:0:2:2:1,10023 +> zx0 ip6/0 20 0 6 10:1:1:0:0:0:0:1,23 > 10:3:3:0:0:0:0:3,12345 +< zx0 ip6/0 20 0 6 10:3:3:0:0:0:0:3,12345 > 10:1:1:0:0:0:0:1,53 +> zx0 ip6/0 20 0 6 10:0:0:0:0:2:2:1,10053 > 10:3:3:0:0:0:0:3,12345 +< zx0 ip6/0 20 0 6 10:3:3:0:0:0:0:3,12346 > 10:0:0:0:0:2:2:1,10023 +> zx0 ip6/0 20 0 6 10:1:0:0:0:0:0:0,23 > 10:3:3:0:0:0:0:3,12346 +< zx0 ip6/0 8 0 17 10:3:3:0:0:0:0:3,12345 > 10:1:1:0:0:0:0:0,53 +> zx0 ip6/0 8 0 17 10:0:0:0:0:2:2:1,10053 > 10:3:3:0:0:0:0:3,12345 +< zx0 ip6/0 20 0 6 10:3:3:0:0:0:0:3,12345 > 10:1:1:0:0:0:0:0,53 +> zx0 ip6/0 20 0 6 10:0:0:0:0:2:2:1,53 > 10:3:3:0:0:0:0:3,12345 +List of active MAP/Redirect filters: +rdr zx0 inet6 any port 23 -> 10::2:2:1/128 port 10023 tcp + +List of active sessions: +RDR 10::2:2:1 10023 <- -> 10:1:: 23 [10:3:3::3 12346] +RDR 10::2:2:1 10023 <- -> 10:1:1::1 23 [10:3:3::3 12345] + +Hostmap table: +List of active state sessions: +List of configured pools +List of configured hash tables +List of groups configured (set 0) +List of groups configured (set 1) +Rules configured (set 0, in) +Rules configured (set 0, out) +Rules configured (set 1, in) +Rules configured (set 1, out) +Accounting rules configured (set 0, in) +Accounting rules configured (set 0, out) +Accounting rules configured (set 1, in) +Accounting rules configured (set 1, out) +------------------------------- +< zx0 ip6/0 20 0 6 10:3:3:0:0:0:0:3,12345 > 10:1:1:0:0:0:0:1,23 +> zx0 ip6/0 20 0 6 10:0:0:0:0:2:2:1,10023 > 10:3:3:0:0:0:0:3,12345 +< zx0 ip6/0 20 0 6 10:3:3:0:0:0:0:3,12345 > 10:1:1:0:0:0:0:1,53 +> zx0 ip6/0 20 0 6 10:0:0:0:0:2:2:1,10053 > 10:3:3:0:0:0:0:3,12345 +< zx0 ip6/0 20 0 6 10:3:3:0:0:0:0:3,12346 > 10:1:0:0:0:0:0:0,23 +> zx0 ip6/0 20 0 6 10:0:0:0:0:2:2:1,10023 > 10:3:3:0:0:0:0:3,12346 +< zx0 ip6/0 8 0 17 10:3:3:0:0:0:0:3,12345 > 10:0:0:0:0:2:2:1,10053 +> zx0 ip6/0 8 0 17 10:1:1:0:0:0:0:0,53 > 10:3:3:0:0:0:0:3,12345 +< zx0 ip6/0 20 0 6 10:3:3:0:0:0:0:3,12345 > 10:1:1:0:0:0:0:0,53 +> zx0 ip6/0 20 0 6 10:0:0:0:0:2:2:1,53 > 10:3:3:0:0:0:0:3,12345 +List of active MAP/Redirect filters: +rdr zx0 inet6 10:1:1::/112 port 53 -> 10::2:2:1/128 port 10053 udp + +List of active sessions: +RDR 10::2:2:1 10053 <- -> 10:1:1:: 53 [10:3:3::3 12345] + +Hostmap table: +List of active state sessions: +List of configured pools +List of configured hash tables +List of groups configured (set 0) +List of groups configured (set 1) +Rules configured (set 0, in) +Rules configured (set 0, out) +Rules configured (set 1, in) +Rules configured (set 1, out) +Accounting rules configured (set 0, in) +Accounting rules configured (set 0, out) +Accounting rules configured (set 1, in) +Accounting rules configured (set 1, out) +------------------------------- +< zx0 ip6/0 20 0 6 10:3:3:0:0:0:0:3,12345 > 10:0:0:0:0:2:2:1,23 +> zx0 ip6/0 20 0 6 10:0:0:0:0:2:2:1,10023 > 10:3:3:0:0:0:0:3,12345 +< zx0 ip6/0 20 0 6 10:3:3:0:0:0:0:3,12345 > 10:0:0:0:0:2:2:1,53 +> zx0 ip6/0 20 0 6 10:0:0:0:0:2:2:1,10053 > 10:3:3:0:0:0:0:3,12345 +< zx0 ip6/0 20 0 6 10:3:3:0:0:0:0:3,12346 > 10:1:0:0:0:0:0:0,23 +> zx0 ip6/0 20 0 6 10:0:0:0:0:2:2:1,10023 > 10:3:3:0:0:0:0:3,12346 +< zx0 ip6/0 8 0 17 10:3:3:0:0:0:0:3,12345 > 10:1:1:0:0:0:0:0,53 +> zx0 ip6/0 8 0 17 10:0:0:0:0:2:2:1,10053 > 10:3:3:0:0:0:0:3,12345 +16 +> zx0 ip6/0 20 0 6 10:1:1:0:0:0:0:1,53 > 10:3:3:0:0:0:0:3,12345 +List of active MAP/Redirect filters: +rdr zx0 inet6 10:1:1::/112 port 0 -> 10::2:2:1/128 port 0 tcp + +List of active sessions: +RDR 10::2:2:1 53 <- -> 10:1:1::1 53 [10:3:3::3 12345] +RDR 10::2:2:1 23 <- -> 10:1:1::1 23 [10:3:3::3 12345] + +Hostmap table: +List of active state sessions: +List of configured pools +List of configured hash tables +List of groups configured (set 0) +List of groups configured (set 1) +Rules configured (set 0, in) +Rules configured (set 0, out) +Rules configured (set 1, in) +Rules configured (set 1, out) +Accounting rules configured (set 0, in) +Accounting rules configured (set 0, out) +Accounting rules configured (set 1, in) +Accounting rules configured (set 1, out) +------------------------------- +< zx0 ip6/0 20 0 6 10:3:3:0:0:0:0:3,12345 > 10:0:0:0:0:2:2:1,23 +> zx0 ip6/0 20 0 6 10:0:0:0:0:2:2:1,10023 > 10:3:3:0:0:0:0:3,12345 +< zx0 ip6/0 20 0 6 10:3:3:0:0:0:0:3,12345 > 10:0:0:0:0:2:2:1,53 +> zx0 ip6/0 20 0 6 10:0:0:0:0:2:2:1,10053 > 10:3:3:0:0:0:0:3,12345 +< zx0 ip6/0 20 0 6 10:3:3:0:0:0:0:3,12346 > 10:1:0:0:0:0:0:0,23 +> zx0 ip6/0 20 0 6 10:0:0:0:0:2:2:1,10023 > 10:3:3:0:0:0:0:3,12346 +< zx0 ip6/0 8 0 17 10:3:3:0:0:0:0:3,12345 > 10:0:0:0:0:2:2:1,53 +> zx0 ip6/0 8 0 17 10:0:0:0:0:2:2:1,10053 > 10:3:3:0:0:0:0:3,12345 +16 +> zx0 ip6/0 20 0 6 10:1:1:0:0:0:0:1,53 > 10:3:3:0:0:0:0:3,12345 +List of active MAP/Redirect filters: +rdr zx0 inet6 10:1:1::/112 -> 10::2:2:1/128 ip + +List of active sessions: +RDR 10::2:2:1 53 <- -> 10:1:1:: 53 [10:3:3::3 12345] +RDR 10::2:2:1 53 <- -> 10:1:1::1 53 [10:3:3::3 12345] +RDR 10::2:2:1 23 <- -> 10:1:1::1 23 [10:3:3::3 12345] + +Hostmap table: +List of active state sessions: +List of configured pools +List of configured hash tables +List of groups configured (set 0) +List of groups configured (set 1) +Rules configured (set 0, in) +Rules configured (set 0, out) +Rules configured (set 1, in) +Rules configured (set 1, out) +Accounting rules configured (set 0, in) +Accounting rules configured (set 0, out) +Accounting rules configured (set 1, in) +Accounting rules configured (set 1, out) +------------------------------- diff --git a/contrib/ipfilter/test/expected/n5 b/contrib/ipfilter/test/expected/n5 index 0e578b64bcfc..423bf485008c 100644 --- a/contrib/ipfilter/test/expected/n5 +++ b/contrib/ipfilter/test/expected/n5 @@ -1,330 +1,533 @@ -ip #0 20(20) 255 10.1.1.0 > 10.1.1.2 -ip #0 20(20) 255 10.2.2.2 > 10.1.1.2 -ip #0 20(20) 255 10.1.1.2 > 10.1.1.1 -ip #0 40(20) 6 10.1.1.2,1025 > 10.1.1.1,1025 -ip #0 40(20) 6 10.1.1.2,1026 > 10.1.1.1,1025 -ip #0 20(20) 255 10.2.2.1 > 10.1.2.1 -ip #0 20(20) 255 10.2.2.2 > 10.1.2.1 -ip #0 20(20) 255 10.1.1.1 > 10.1.1.2 -ip #0 20(20) 255 10.1.1.2 > 10.1.1.1 -ip #0 20(20) 255 10.2.2.1 > 10.2.1.1 -ip #0 20(20) 255 10.2.2.2 > 10.2.1.1 -ip #0 20(20) 255 10.2.2.3 > 10.1.1.1 -ip #0 20(20) 255 10.2.3.4 > 10.2.2.2 -ip #0 20(20) 255 10.1.1.1 > 10.2.2.2 -ip #0 20(20) 255 10.1.1.2 > 10.1.1.1 -ip #0 20(20) 255 10.1.1.0 > 10.3.4.5 -ip #0 20(20) 255 10.1.1.1 > 10.3.4.5 -ip #0 20(20) 255 10.1.1.2 > 10.3.4.5 -ip #0 40(20) 6 10.1.1.1,1025 > 10.3.4.5,1025 -ip #0 48(20) 1 10.2.2.2 > 10.4.3.2 -ip #0 48(20) 1 10.4.3.2 > 10.1.1.1 -ip #0 48(20) 1 10.4.3.2 > 10.3.4.3 -ip #0 48(20) 1 10.4.3.2 > 10.3.4.5 -ip #0 20(20) 34 10.1.1.2 > 10.4.3.2 -ip #0 20(20) 34 10.4.3.2 > 10.3.4.4 -ip #0 20(20) 34 10.1.1.2 > 10.4.3.4 -ip #0 20(20) 34 10.4.3.4 > 10.3.4.5 -ip #0 20(20) 34 10.1.1.3 > 10.4.3.4 -ip #0 20(20) 34 10.4.3.4 > 10.3.4.6 -ip #0 20(20) 35 10.1.1.3 > 10.4.3.4 -ip #0 20(20) 35 10.4.3.4 > 10.3.4.7 -ip #0 40(20) 6 10.2.2.2,1025 > 10.1.1.1,1025 -ip #0 40(20) 6 10.2.2.2,1025 > 10.1.1.2,1025 -ip #0 20(20) 0 10.1.1.0 > 10.1.1.2 -ip #0 20(20) 0 10.2.2.2 > 10.1.2.1 -ip #0 40(20) 6 10.1.1.2,1025 > 10.1.1.1,1025 -ip #0 40(20) 6 10.1.1.2,1025 > 10.1.1.1,1025 -ip #0 40(20) 6 10.1.1.2,1026 > 10.1.1.1,1025 -ip #0 28(20) 17 10.1.1.2,1025 > 10.1.1.1,1025 -ip #0 40(20) 6 10.1.1.3,2000 > 10.1.2.1,80 -ip #0 40(20) 6 10.1.1.3,2001 > 10.1.3.1,80 -ip #0 40(20) 6 10.1.1.3,2002 > 10.1.4.1,80 -ip #0 40(20) 6 10.1.1.3,2003 > 10.1.4.1,80 -ip #0 20(20) 0 10.1.1.1 > 10.1.1.2 -ip #0 40(20) 6 10.1.1.1,1025 > 10.1.1.2,1025 -ip #0 20(20) 0 10.1.1.2 > 10.1.1.1 -ip #0 40(20) 6 10.2.2.2,1026 > 10.3.4.5,40000 -ip #0 40(20) 6 10.1.1.1,1026 > 10.3.4.5,40000 -ip #0 40(20) 6 10.2.2.2,1025 > 10.3.4.5,40000 -ip #0 40(20) 6 10.1.1.1,1025 > 10.3.4.5,40000 -ip #0 28(20) 17 10.1.1.2,1025 > 10.3.4.5,40001 -ip #0 28(20) 17 10.1.1.2,1025 > 10.3.4.5,40001 -ip #0 40(20) 6 10.1.2.1,80 > 10.3.4.5,40001 -ip #0 40(20) 6 10.1.2.1,80 > 10.3.4.5,40001 +> zx0 ip #0 20(20) 255 10.1.1.0 > 10.1.1.2 +> zx0 ip #0 20(20) 255 10.2.2.2 > 10.1.1.2 +> zx0 ip #0 20(20) 255 10.1.1.2 > 10.1.1.1 +> zx0 ip #0 40(20) 6 10.1.1.2,1025 > 10.1.1.1,1025 +> zx0 ip #0 40(20) 6 10.1.1.2,1026 > 10.1.1.1,1025 +> zx0 ip #0 20(20) 255 10.2.2.1 > 10.1.2.1 +> zx0 ip #0 20(20) 255 10.2.2.2 > 10.1.2.1 +< zx0 ip #0 20(20) 255 10.1.1.1 > 10.1.1.2 +< zx0 ip #0 20(20) 255 10.1.1.2 > 10.1.1.1 +< zx0 ip #0 20(20) 255 10.2.2.1 > 10.2.1.1 +< zx0 ip #0 20(20) 255 10.2.2.2 > 10.2.1.1 +< zx0 ip #0 20(20) 255 10.2.2.3 > 10.1.1.1 +< zx0 ip #0 20(20) 255 10.2.3.4 > 10.2.2.2 +< zx0 ip #0 20(20) 255 10.1.1.1 > 10.2.2.2 +< zx0 ip #0 20(20) 255 10.1.1.2 > 10.1.1.1 +< zx0 ip #0 20(20) 255 10.1.1.0 > 10.3.4.5 +< zx0 ip #0 20(20) 255 10.1.1.1 > 10.3.4.5 +< zx0 ip #0 20(20) 255 10.1.1.2 > 10.3.4.5 +< zx0 ip #0 40(20) 6 10.1.1.1,1025 > 10.3.4.5,1025 +> zx0 ip #0 48(20) 1 10.2.2.2 > 10.4.3.2 +< zx0 ip #0 48(20) 1 10.4.3.2 > 10.1.1.1 +< zx0 ip #0 48(20) 1 10.4.3.2 > 10.3.4.3 +< zx0 ip #0 48(20) 1 10.4.3.2 > 10.3.4.5 +> zx0 ip #0 20(20) 34 10.1.1.2 > 10.4.3.2 +< zx0 ip #0 20(20) 34 10.4.3.2 > 10.3.4.4 +> zx0 ip #0 20(20) 34 10.1.1.2 > 10.4.3.4 +< zx0 ip #0 20(20) 34 10.4.3.4 > 10.3.4.5 +> zx0 ip #0 20(20) 34 10.1.1.3 > 10.4.3.4 +< zx0 ip #0 20(20) 34 10.4.3.4 > 10.3.4.6 +> zx0 ip #0 20(20) 35 10.1.1.3 > 10.4.3.4 +< zx0 ip #0 20(20) 35 10.4.3.4 > 10.3.4.7 +> zx0 ip #0 40(20) 6 10.2.2.2,1025 > 10.1.1.1,1025 +> zx0 ip #0 40(20) 6 10.2.2.2,1025 > 10.1.1.2,1025 +> zx0 ip #0 20(20) 0 10.1.1.0 > 10.1.1.2 +> zx0 ip #0 20(20) 0 10.2.2.2 > 10.1.2.1 +> zx0 ip #0 40(20) 6 10.1.1.2,1025 > 10.1.1.1,1025 +> zx0 ip #0 40(20) 6 10.1.1.2,1025 > 10.1.1.1,1025 +> zx0 ip #0 40(20) 6 10.1.1.2,1026 > 10.1.1.1,1025 +> zx0 ip #0 28(20) 17 10.1.1.2,1025 > 10.1.1.1,1025 +> zx0 ip #0 40(20) 6 10.1.1.3,2000 > 10.1.2.1,80 +> zx0 ip #0 40(20) 6 10.1.1.3,2001 > 10.1.3.1,80 +> zx0 ip #0 40(20) 6 10.1.1.3,2002 > 10.1.4.1,80 +> zx0 ip #0 40(20) 6 10.1.1.3,2003 > 10.1.4.1,80 +< zx0 ip #0 20(20) 0 10.1.1.1 > 10.1.1.2 +< zx0 ip #0 40(20) 6 10.1.1.1,1025 > 10.1.1.2,1025 +< zx0 ip #0 20(20) 0 10.1.1.2 > 10.1.1.1 +> zx0 ip #0 40(20) 6 10.2.2.2,1026 > 10.3.4.5,40000 +< zx0 ip #0 40(20) 6 10.1.1.1,1026 > 10.3.4.5,40000 +> zx0 ip #0 40(20) 6 10.2.2.2,1025 > 10.3.4.5,40000 +< zx0 ip #0 40(20) 6 10.1.1.1,1025 > 10.3.4.5,40000 +> zx0 ip #0 28(20) 17 10.1.1.2,1025 > 10.3.4.5,40001 +< zx0 ip #0 28(20) 17 10.1.1.2,1025 > 10.3.4.5,40001 +> zx0 ip #0 40(20) 6 10.1.2.1,80 > 10.3.4.5,40001 +< zx0 ip #0 40(20) 6 10.1.2.1,80 > 10.3.4.5,40001 +List of active MAP/Redirect filters: +map zx0 10.1.1.1/32 -> 10.2.2.2/32 + +List of active sessions: +MAP 10.1.1.1 1025 <- -> 10.2.2.2 1025 [10.3.4.5 40000] +MAP 10.1.1.1 1026 <- -> 10.2.2.2 1026 [10.3.4.5 40000] +MAP 10.1.1.1 <- -> 10.2.2.2 [10.1.2.1] +MAP 10.1.1.1 1025 <- -> 10.2.2.2 1025 [10.1.1.2 1025] +MAP 10.1.1.1 1025 <- -> 10.2.2.2 1025 [10.1.1.1 1025] +MAP 10.1.1.1 <- -> 10.2.2.2 [10.4.3.2] +MAP 10.1.1.1 <- -> 10.2.2.2 [10.1.1.2] + +Hostmap table: +10.1.1.1,10.3.4.5 -> 10.2.2.2,0.0.0.0 (use = 2) +10.1.1.1,10.1.2.1 -> 10.2.2.2,0.0.0.0 (use = 1) +10.1.1.1,10.1.1.1 -> 10.2.2.2,0.0.0.0 (use = 1) +10.1.1.1,10.4.3.2 -> 10.2.2.2,0.0.0.0 (use = 1) +10.1.1.1,10.1.1.2 -> 10.2.2.2,0.0.0.0 (use = 2) +List of active state sessions: +List of configured pools +List of configured hash tables +List of groups configured (set 0) +List of groups configured (set 1) +Rules configured (set 0, in) +Rules configured (set 0, out) +Rules configured (set 1, in) +Rules configured (set 1, out) +Accounting rules configured (set 0, in) +Accounting rules configured (set 0, out) +Accounting rules configured (set 1, in) +Accounting rules configured (set 1, out) ------------------------------- -ip #0 20(20) 255 10.3.4.5 > 10.1.1.2 -ip #0 20(20) 255 10.1.1.1 > 10.1.1.2 -ip #0 20(20) 255 10.3.4.5 > 10.1.1.1 -ip #0 40(20) 6 10.3.4.5,1025 > 10.1.1.1,1025 -ip #0 40(20) 6 10.3.4.5,1026 > 10.1.1.1,1025 -ip #0 20(20) 255 10.2.2.1 > 10.1.2.1 -ip #0 20(20) 255 10.2.2.2 > 10.1.2.1 -ip #0 20(20) 255 10.1.1.1 > 10.1.1.2 -ip #0 20(20) 255 10.1.1.2 > 10.1.1.1 -ip #0 20(20) 255 10.2.2.1 > 10.2.1.1 -ip #0 20(20) 255 10.2.2.2 > 10.2.1.1 -ip #0 20(20) 255 10.2.2.3 > 10.1.1.1 -ip #0 20(20) 255 10.2.3.4 > 10.2.2.2 -ip #0 20(20) 255 10.1.1.1 > 10.2.2.2 -ip #0 20(20) 255 10.1.1.2 > 10.2.2.2 -ip #0 20(20) 255 10.1.1.0 > 10.3.4.5 -ip #0 20(20) 255 10.1.1.1 > 10.1.1.2 -ip #0 20(20) 255 10.1.1.2 > 10.1.1.0 -ip #0 40(20) 6 10.1.1.1,1025 > 10.1.1.2,1025 -ip #0 48(20) 1 10.1.1.1 > 10.4.3.2 -ip #0 48(20) 1 10.4.3.2 > 10.2.2.2 -ip #0 48(20) 1 10.4.3.2 > 10.3.4.3 -ip #0 48(20) 1 10.4.3.2 > 10.3.4.5 -ip #0 20(20) 34 10.1.1.2 > 10.4.3.2 -ip #0 20(20) 34 10.4.3.2 > 10.3.4.4 -ip #0 20(20) 34 10.1.1.2 > 10.4.3.4 -ip #0 20(20) 34 10.4.3.4 > 10.3.4.5 -ip #0 20(20) 34 10.1.1.3 > 10.4.3.4 -ip #0 20(20) 34 10.4.3.4 > 10.3.4.6 -ip #0 20(20) 35 10.1.1.3 > 10.4.3.4 -ip #0 20(20) 35 10.4.3.4 > 10.3.4.7 -ip #0 40(20) 6 10.1.1.1,1025 > 10.1.1.1,1025 -ip #0 40(20) 6 10.3.4.5,1025 > 10.1.1.2,1025 -ip #0 20(20) 0 10.3.4.5 > 10.1.1.2 -ip #0 20(20) 0 10.3.4.5 > 10.1.2.1 -ip #0 40(20) 6 10.3.4.5,1025 > 10.1.1.1,1025 -ip #0 40(20) 6 10.3.4.5,1025 > 10.1.1.1,1025 -ip #0 40(20) 6 10.3.4.5,1026 > 10.1.1.1,1025 -ip #0 28(20) 17 10.3.4.5,1025 > 10.1.1.1,1025 -ip #0 40(20) 6 10.3.4.5,2000 > 10.1.2.1,80 -ip #0 40(20) 6 10.3.4.5,2001 > 10.1.3.1,80 -ip #0 40(20) 6 10.3.4.5,2002 > 10.1.4.1,80 -ip #0 40(20) 6 10.3.4.5,2003 > 10.1.4.1,80 -ip #0 20(20) 0 10.1.1.1 > 10.1.1.2 -ip #0 40(20) 6 10.1.1.1,1025 > 10.1.1.2,1025 -ip #0 20(20) 0 10.1.1.2 > 10.1.1.1 -ip #0 40(20) 6 10.1.1.1,1026 > 10.3.4.5,40000 -ip #0 40(20) 6 10.1.1.1,1026 > 10.3.4.5,40000 -ip #0 40(20) 6 10.1.1.1,1025 > 10.3.4.5,40000 -ip #0 40(20) 6 10.1.1.1,1025 > 10.3.4.5,40000 -ip #0 28(20) 17 10.1.1.2,1025 > 10.3.4.5,40001 -ip #0 28(20) 17 10.1.1.2,1025 > 10.3.4.5,40001 -ip #0 40(20) 6 10.1.2.1,80 > 10.3.4.5,40001 -ip #0 40(20) 6 10.1.2.1,80 > 10.3.4.5,40001 +> zx0 ip #0 20(20) 255 10.3.4.5 > 10.1.1.2 +15 +> zx0 ip #0 20(20) 255 10.3.4.5 > 10.1.1.1 +> zx0 ip #0 40(20) 6 10.3.4.5,1025 > 10.1.1.1,1025 +> zx0 ip #0 40(20) 6 10.3.4.5,1026 > 10.1.1.1,1025 +> zx0 ip #0 20(20) 255 10.2.2.1 > 10.1.2.1 +> zx0 ip #0 20(20) 255 10.2.2.2 > 10.1.2.1 +< zx0 ip #0 20(20) 255 10.1.1.1 > 10.1.1.2 +< zx0 ip #0 20(20) 255 10.1.1.2 > 10.1.1.1 +< zx0 ip #0 20(20) 255 10.2.2.1 > 10.2.1.1 +< zx0 ip #0 20(20) 255 10.2.2.2 > 10.2.1.1 +< zx0 ip #0 20(20) 255 10.2.2.3 > 10.1.1.1 +< zx0 ip #0 20(20) 255 10.2.3.4 > 10.2.2.2 +< zx0 ip #0 20(20) 255 10.1.1.1 > 10.2.2.2 +< zx0 ip #0 20(20) 255 10.1.1.2 > 10.2.2.2 +< zx0 ip #0 20(20) 255 10.1.1.0 > 10.3.4.5 +< zx0 ip #0 20(20) 255 10.1.1.1 > 10.1.1.2 +< zx0 ip #0 20(20) 255 10.1.1.2 > 10.1.1.0 +< zx0 ip #0 40(20) 6 10.1.1.1,1025 > 10.1.1.2,1025 +> zx0 ip #0 48(20) 1 10.1.1.1 > 10.4.3.2 +< zx0 ip #0 48(20) 1 10.4.3.2 > 10.2.2.2 +< zx0 ip #0 48(20) 1 10.4.3.2 > 10.3.4.3 +< zx0 ip #0 48(20) 1 10.4.3.2 > 10.3.4.5 +> zx0 ip #0 20(20) 34 10.1.1.2 > 10.4.3.2 +< zx0 ip #0 20(20) 34 10.4.3.2 > 10.3.4.4 +> zx0 ip #0 20(20) 34 10.1.1.2 > 10.4.3.4 +< zx0 ip #0 20(20) 34 10.4.3.4 > 10.3.4.5 +> zx0 ip #0 20(20) 34 10.1.1.3 > 10.4.3.4 +< zx0 ip #0 20(20) 34 10.4.3.4 > 10.3.4.6 +> zx0 ip #0 20(20) 35 10.1.1.3 > 10.4.3.4 +< zx0 ip #0 20(20) 35 10.4.3.4 > 10.3.4.7 +15 +> zx0 ip #0 40(20) 6 10.3.4.5,1025 > 10.1.1.2,1025 +> zx0 ip #0 20(20) 0 10.3.4.5 > 10.1.1.2 +> zx0 ip #0 20(20) 0 10.3.4.5 > 10.1.2.1 +> zx0 ip #0 40(20) 6 10.3.4.5,1025 > 10.1.1.1,1025 +> zx0 ip #0 40(20) 6 10.3.4.5,1025 > 10.1.1.1,1025 +> zx0 ip #0 40(20) 6 10.3.4.5,1026 > 10.1.1.1,1025 +> zx0 ip #0 28(20) 17 10.3.4.5,1025 > 10.1.1.1,1025 +> zx0 ip #0 40(20) 6 10.3.4.5,2000 > 10.1.2.1,80 +> zx0 ip #0 40(20) 6 10.3.4.5,2001 > 10.1.3.1,80 +> zx0 ip #0 40(20) 6 10.3.4.5,2002 > 10.1.4.1,80 +> zx0 ip #0 40(20) 6 10.3.4.5,2003 > 10.1.4.1,80 +< zx0 ip #0 20(20) 0 10.1.1.1 > 10.1.1.2 +< zx0 ip #0 40(20) 6 10.1.1.1,1025 > 10.1.1.2,1025 +< zx0 ip #0 20(20) 0 10.1.1.2 > 10.1.1.1 +> zx0 ip #0 40(20) 6 10.1.1.1,1026 > 10.3.4.5,40000 +< zx0 ip #0 40(20) 6 10.1.1.1,1026 > 10.3.4.5,40000 +> zx0 ip #0 40(20) 6 10.1.1.1,1025 > 10.3.4.5,40000 +< zx0 ip #0 40(20) 6 10.1.1.1,1025 > 10.3.4.5,40000 +> zx0 ip #0 28(20) 17 10.1.1.2,1025 > 10.3.4.5,40001 +< zx0 ip #0 28(20) 17 10.1.1.2,1025 > 10.3.4.5,40001 +> zx0 ip #0 40(20) 6 10.1.2.1,80 > 10.3.4.5,40001 +< zx0 ip #0 40(20) 6 10.1.2.1,80 > 10.3.4.5,40001 +List of active MAP/Redirect filters: +map zx0 from 10.1.1.0/24 to 10.1.0.0/16 -> 10.3.4.5/32 + +List of active sessions: +MAP 10.1.1.3 2003 <- -> 10.3.4.5 2003 [10.1.4.1 80] +MAP 10.1.1.3 2002 <- -> 10.3.4.5 2002 [10.1.4.1 80] +MAP 10.1.1.3 2001 <- -> 10.3.4.5 2001 [10.1.3.1 80] +MAP 10.1.1.3 2000 <- -> 10.3.4.5 2000 [10.1.2.1 80] +MAP 10.1.1.2 1025 <- -> 10.3.4.5 1025 [10.1.1.1 1025] +MAP 10.1.1.1 <- -> 10.3.4.5 [10.1.2.1] +MAP 10.1.1.0 <- -> 10.3.4.5 [10.1.1.2] +MAP 10.1.1.1 1025 <- -> 10.3.4.5 1025 [10.1.1.2 1025] +MAP 10.1.1.2 1026 <- -> 10.3.4.5 1026 [10.1.1.1 1025] +MAP 10.1.1.2 1025 <- -> 10.3.4.5 1025 [10.1.1.1 1025] +MAP 10.1.1.2 <- -> 10.3.4.5 [10.1.1.1] +MAP 10.1.1.0 <- -> 10.3.4.5 [10.1.1.2] + +Hostmap table: +10.1.1.3,10.1.4.1 -> 10.3.4.5,0.0.0.0 (use = 2) +10.1.1.3,10.1.3.1 -> 10.3.4.5,0.0.0.0 (use = 1) +10.1.1.3,10.1.2.1 -> 10.3.4.5,0.0.0.0 (use = 1) +10.1.1.1,10.1.2.1 -> 10.3.4.5,0.0.0.0 (use = 1) +10.1.1.1,10.1.1.2 -> 10.3.4.5,0.0.0.0 (use = 1) +10.1.1.2,10.1.1.1 -> 10.3.4.5,0.0.0.0 (use = 4) +10.1.1.0,10.1.1.2 -> 10.3.4.5,0.0.0.0 (use = 2) +List of active state sessions: +List of configured pools +List of configured hash tables +List of groups configured (set 0) +List of groups configured (set 1) +Rules configured (set 0, in) +Rules configured (set 0, out) +Rules configured (set 1, in) +Rules configured (set 1, out) +Accounting rules configured (set 0, in) +Accounting rules configured (set 0, out) +Accounting rules configured (set 1, in) +Accounting rules configured (set 1, out) ------------------------------- -ip #0 20(20) 255 10.1.1.0 > 10.1.1.2 -ip #0 20(20) 255 10.1.1.1 > 10.1.1.2 -ip #0 20(20) 255 10.1.1.2 > 10.1.1.1 -ip #0 40(20) 6 10.1.1.2,1025 > 10.1.1.1,1025 -ip #0 40(20) 6 10.1.1.2,1026 > 10.1.1.1,1025 -ip #0 20(20) 255 10.2.2.1 > 10.1.2.1 -ip #0 20(20) 255 10.2.2.2 > 10.1.2.1 -ip #0 20(20) 255 10.1.1.1 > 10.1.1.2 -ip #0 20(20) 255 10.1.1.2 > 10.1.1.1 -ip #0 20(20) 255 10.2.2.1 > 10.2.1.1 -ip #0 20(20) 255 10.2.2.2 > 10.2.1.1 -ip #0 20(20) 255 10.2.2.3 > 10.1.1.1 -ip #0 20(20) 255 10.2.3.4 > 10.2.2.2 -ip #0 20(20) 255 10.1.1.1 > 10.2.2.2 -ip #0 20(20) 255 10.1.1.2 > 10.2.2.2 -ip #0 20(20) 255 10.1.1.0 > 10.3.4.5 -ip #0 20(20) 255 10.1.1.1 > 10.3.4.5 -ip #0 20(20) 255 10.1.1.2 > 10.3.4.5 -ip #0 40(20) 6 10.1.1.1,1025 > 10.3.4.5,1025 -ip #0 48(20) 1 10.3.4.1 > 10.4.3.2 -ip #0 48(20) 1 10.4.3.2 > 10.2.2.2 -ip #0 48(20) 1 10.4.3.2 > 10.3.4.3 -ip #0 48(20) 1 10.4.3.2 > 10.3.4.5 -ip #0 20(20) 34 10.3.4.1 > 10.4.3.2 -ip #0 20(20) 34 10.4.3.2 > 10.3.4.4 -ip #0 20(20) 34 10.3.4.1 > 10.4.3.4 -ip #0 20(20) 34 10.4.3.4 > 10.3.4.5 -ip #0 20(20) 34 10.3.4.2 > 10.4.3.4 -ip #0 20(20) 34 10.4.3.4 > 10.3.4.6 -ip #0 20(20) 35 10.3.4.2 > 10.4.3.4 -ip #0 20(20) 35 10.4.3.4 > 10.3.4.7 -ip #0 40(20) 6 10.1.1.1,1025 > 10.1.1.1,1025 -ip #0 40(20) 6 10.1.1.1,1025 > 10.1.1.2,1025 -ip #0 20(20) 0 10.1.1.0 > 10.1.1.2 -ip #0 20(20) 0 10.1.1.1 > 10.1.2.1 -ip #0 40(20) 6 10.1.1.2,1025 > 10.1.1.1,1025 -ip #0 40(20) 6 10.1.1.2,1025 > 10.1.1.1,1025 -ip #0 40(20) 6 10.1.1.2,1026 > 10.1.1.1,1025 -ip #0 28(20) 17 10.1.1.2,1025 > 10.1.1.1,1025 -ip #0 40(20) 6 10.1.1.3,2000 > 10.1.2.1,80 -ip #0 40(20) 6 10.1.1.3,2001 > 10.1.3.1,80 -ip #0 40(20) 6 10.1.1.3,2002 > 10.1.4.1,80 -ip #0 40(20) 6 10.1.1.3,2003 > 10.1.4.1,80 -ip #0 20(20) 0 10.1.1.1 > 10.1.1.2 -ip #0 40(20) 6 10.1.1.1,1025 > 10.1.1.2,1025 -ip #0 20(20) 0 10.1.1.2 > 10.1.1.1 -ip #0 40(20) 6 10.3.4.3,1026 > 10.3.4.5,40000 -ip #0 40(20) 6 10.1.1.1,1026 > 10.3.4.5,40000 -ip #0 40(20) 6 10.3.4.3,1025 > 10.3.4.5,40000 -ip #0 40(20) 6 10.1.1.1,1025 > 10.3.4.5,40000 -ip #0 28(20) 17 10.3.4.3,1025 > 10.3.4.5,40001 -ip #0 28(20) 17 10.1.1.2,1025 > 10.3.4.5,40001 -ip #0 40(20) 6 10.1.2.1,80 > 10.3.4.5,40001 -ip #0 40(20) 6 10.1.2.1,80 > 10.3.4.5,40001 +> zx0 ip #0 20(20) 255 10.1.1.0 > 10.1.1.2 +> zx0 ip #0 20(20) 255 10.1.1.1 > 10.1.1.2 +> zx0 ip #0 20(20) 255 10.1.1.2 > 10.1.1.1 +> zx0 ip #0 40(20) 6 10.1.1.2,1025 > 10.1.1.1,1025 +> zx0 ip #0 40(20) 6 10.1.1.2,1026 > 10.1.1.1,1025 +> zx0 ip #0 20(20) 255 10.2.2.1 > 10.1.2.1 +> zx0 ip #0 20(20) 255 10.2.2.2 > 10.1.2.1 +< zx0 ip #0 20(20) 255 10.1.1.1 > 10.1.1.2 +< zx0 ip #0 20(20) 255 10.1.1.2 > 10.1.1.1 +< zx0 ip #0 20(20) 255 10.2.2.1 > 10.2.1.1 +< zx0 ip #0 20(20) 255 10.2.2.2 > 10.2.1.1 +< zx0 ip #0 20(20) 255 10.2.2.3 > 10.1.1.1 +< zx0 ip #0 20(20) 255 10.2.3.4 > 10.2.2.2 +< zx0 ip #0 20(20) 255 10.1.1.1 > 10.2.2.2 +< zx0 ip #0 20(20) 255 10.1.1.2 > 10.2.2.2 +< zx0 ip #0 20(20) 255 10.1.1.0 > 10.3.4.5 +< zx0 ip #0 20(20) 255 10.1.1.1 > 10.3.4.5 +< zx0 ip #0 20(20) 255 10.1.1.2 > 10.3.4.5 +< zx0 ip #0 40(20) 6 10.1.1.1,1025 > 10.3.4.5,1025 +> zx0 ip #0 48(20) 1 10.3.4.1 > 10.4.3.2 +< zx0 ip #0 48(20) 1 10.4.3.2 > 10.2.2.2 +< zx0 ip #0 48(20) 1 10.4.3.2 > 10.3.4.3 +< zx0 ip #0 48(20) 1 10.4.3.2 > 10.3.4.5 +> zx0 ip #0 20(20) 34 10.3.4.1 > 10.4.3.2 +< zx0 ip #0 20(20) 34 10.4.3.2 > 10.3.4.4 +> zx0 ip #0 20(20) 34 10.3.4.1 > 10.4.3.4 +< zx0 ip #0 20(20) 34 10.4.3.4 > 10.3.4.5 +> zx0 ip #0 20(20) 34 10.3.4.2 > 10.4.3.4 +< zx0 ip #0 20(20) 34 10.4.3.4 > 10.3.4.6 +> zx0 ip #0 20(20) 35 10.3.4.2 > 10.4.3.4 +< zx0 ip #0 20(20) 35 10.4.3.4 > 10.3.4.7 +> zx0 ip #0 40(20) 6 10.1.1.1,1025 > 10.1.1.1,1025 +> zx0 ip #0 40(20) 6 10.1.1.1,1025 > 10.1.1.2,1025 +> zx0 ip #0 20(20) 0 10.1.1.0 > 10.1.1.2 +> zx0 ip #0 20(20) 0 10.1.1.1 > 10.1.2.1 +> zx0 ip #0 40(20) 6 10.1.1.2,1025 > 10.1.1.1,1025 +> zx0 ip #0 40(20) 6 10.1.1.2,1025 > 10.1.1.1,1025 +> zx0 ip #0 40(20) 6 10.1.1.2,1026 > 10.1.1.1,1025 +> zx0 ip #0 28(20) 17 10.1.1.2,1025 > 10.1.1.1,1025 +> zx0 ip #0 40(20) 6 10.1.1.3,2000 > 10.1.2.1,80 +> zx0 ip #0 40(20) 6 10.1.1.3,2001 > 10.1.3.1,80 +> zx0 ip #0 40(20) 6 10.1.1.3,2002 > 10.1.4.1,80 +> zx0 ip #0 40(20) 6 10.1.1.3,2003 > 10.1.4.1,80 +< zx0 ip #0 20(20) 0 10.1.1.1 > 10.1.1.2 +< zx0 ip #0 40(20) 6 10.1.1.1,1025 > 10.1.1.2,1025 +< zx0 ip #0 20(20) 0 10.1.1.2 > 10.1.1.1 +> zx0 ip #0 40(20) 6 10.3.4.3,1026 > 10.3.4.5,40000 +< zx0 ip #0 40(20) 6 10.1.1.1,1026 > 10.3.4.5,40000 +> zx0 ip #0 40(20) 6 10.3.4.3,1025 > 10.3.4.5,40000 +< zx0 ip #0 40(20) 6 10.1.1.1,1025 > 10.3.4.5,40000 +> zx0 ip #0 28(20) 17 10.3.4.3,1025 > 10.3.4.5,40001 +< zx0 ip #0 28(20) 17 10.1.1.2,1025 > 10.3.4.5,40001 +> zx0 ip #0 40(20) 6 10.1.2.1,80 > 10.3.4.5,40001 +< zx0 ip #0 40(20) 6 10.1.2.1,80 > 10.3.4.5,40001 +List of active MAP/Redirect filters: +map zx0 from 10.1.1.0/24 ! to 10.1.0.0/16 -> 10.3.4.0/24 + +List of active sessions: +MAP 10.1.1.2 1025 <- -> 10.3.4.3 1025 [10.3.4.5 40001] +MAP 10.1.1.1 1025 <- -> 10.3.4.3 1025 [10.3.4.5 40000] +MAP 10.1.1.1 1026 <- -> 10.3.4.3 1026 [10.3.4.5 40000] +MAP 10.1.1.3 <- -> 10.3.4.2 [10.4.3.4] +MAP 10.1.1.3 <- -> 10.3.4.2 [10.4.3.4] +MAP 10.1.1.2 <- -> 10.3.4.1 [10.4.3.4] +MAP 10.1.1.2 <- -> 10.3.4.1 [10.4.3.2] +MAP 10.1.1.1 <- -> 10.3.4.1 [10.4.3.2] + +Hostmap table: +10.1.1.2,10.3.4.5 -> 10.3.4.3,0.0.0.0 (use = 1) +10.1.1.1,10.3.4.5 -> 10.3.4.3,0.0.0.0 (use = 2) +10.1.1.3,10.4.3.4 -> 10.3.4.2,0.0.0.0 (use = 2) +10.1.1.2,10.4.3.4 -> 10.3.4.1,0.0.0.0 (use = 1) +10.1.1.2,10.4.3.2 -> 10.3.4.1,0.0.0.0 (use = 1) +10.1.1.1,10.4.3.2 -> 10.3.4.1,0.0.0.0 (use = 1) +List of active state sessions: +List of configured pools +List of configured hash tables +List of groups configured (set 0) +List of groups configured (set 1) +Rules configured (set 0, in) +Rules configured (set 0, out) +Rules configured (set 1, in) +Rules configured (set 1, out) +Accounting rules configured (set 0, in) +Accounting rules configured (set 0, out) +Accounting rules configured (set 1, in) +Accounting rules configured (set 1, out) ------------------------------- -ip #0 20(20) 255 10.1.1.0 > 10.1.1.2 -ip #0 20(20) 255 10.1.1.1 > 10.1.1.2 -ip #0 20(20) 255 10.1.1.2 > 10.1.1.1 -ip #0 40(20) 6 10.1.1.2,1025 > 10.1.1.1,1025 -ip #0 40(20) 6 10.1.1.2,1026 > 10.1.1.1,1025 -ip #0 20(20) 255 10.2.2.1 > 10.1.2.1 -ip #0 20(20) 255 10.2.2.2 > 10.1.2.1 -ip #0 20(20) 255 10.1.1.1 > 10.1.1.2 -ip #0 20(20) 255 10.1.1.2 > 10.1.1.1 -ip #0 20(20) 255 10.2.2.1 > 10.2.1.1 -ip #0 20(20) 255 10.2.2.2 > 10.2.1.1 -ip #0 20(20) 255 10.2.2.3 > 10.1.1.1 -ip #0 20(20) 255 10.2.3.4 > 10.2.2.2 -ip #0 20(20) 255 10.1.1.1 > 10.2.2.2 -ip #0 20(20) 255 10.1.1.2 > 10.2.2.2 -ip #0 20(20) 255 10.1.1.0 > 10.3.4.5 -ip #0 20(20) 255 10.1.1.1 > 10.3.4.5 -ip #0 20(20) 255 10.1.1.2 > 10.3.4.5 -ip #0 40(20) 6 10.1.1.1,1025 > 10.3.4.5,1025 -ip #0 48(20) 1 10.1.1.1 > 10.4.3.2 -ip #0 48(20) 1 10.4.3.2 > 10.2.2.2 -ip #0 48(20) 1 10.4.3.2 > 10.3.4.3 -ip #0 48(20) 1 10.4.3.2 > 10.3.4.5 -ip #0 20(20) 34 10.1.1.2 > 10.4.3.2 -ip #0 20(20) 34 10.4.3.2 > 10.3.4.4 -ip #0 20(20) 34 10.1.1.2 > 10.4.3.4 -ip #0 20(20) 34 10.4.3.4 > 10.3.4.5 -ip #0 20(20) 34 10.1.1.3 > 10.4.3.4 -ip #0 20(20) 34 10.4.3.4 > 10.3.4.6 -ip #0 20(20) 35 10.1.1.3 > 10.4.3.4 -ip #0 20(20) 35 10.4.3.4 > 10.3.4.7 -ip #0 40(20) 6 10.1.1.1,1025 > 10.1.1.1,1025 -ip #0 40(20) 6 10.1.1.1,1025 > 10.1.1.2,1025 -ip #0 20(20) 0 10.1.1.0 > 10.1.1.2 -ip #0 20(20) 0 10.1.1.1 > 10.1.2.1 -ip #0 40(20) 6 10.1.1.2,1025 > 10.1.1.1,1025 -ip #0 40(20) 6 10.1.1.2,1025 > 10.1.1.1,1025 -ip #0 40(20) 6 10.1.1.2,1026 > 10.1.1.1,1025 -ip #0 28(20) 17 10.3.4.5,10000 > 10.1.1.1,1025 -ip #0 40(20) 6 10.1.1.3,2000 > 10.1.2.1,80 -ip #0 40(20) 6 10.1.1.3,2001 > 10.1.3.1,80 -ip #0 40(20) 6 10.1.1.3,2002 > 10.1.4.1,80 -ip #0 40(20) 6 10.1.1.3,2003 > 10.1.4.1,80 -ip #0 20(20) 0 10.1.1.1 > 10.1.1.2 -ip #0 40(20) 6 10.1.1.1,1025 > 10.1.1.2,1025 -ip #0 20(20) 0 10.1.1.2 > 10.1.1.1 -ip #0 40(20) 6 10.1.1.1,1026 > 10.3.4.5,40000 -ip #0 40(20) 6 10.1.1.1,1026 > 10.3.4.5,40000 -ip #0 40(20) 6 10.1.1.1,1025 > 10.3.4.5,40000 -ip #0 40(20) 6 10.1.1.1,1025 > 10.3.4.5,40000 -ip #0 28(20) 17 10.3.4.5,10001 > 10.3.4.5,40001 -ip #0 28(20) 17 10.1.1.2,1025 > 10.3.4.5,40001 -ip #0 40(20) 6 10.1.2.1,80 > 10.3.4.5,40001 -ip #0 40(20) 6 10.1.2.1,80 > 10.3.4.5,40001 +> zx0 ip #0 20(20) 255 10.1.1.0 > 10.1.1.2 +> zx0 ip #0 20(20) 255 10.1.1.1 > 10.1.1.2 +> zx0 ip #0 20(20) 255 10.1.1.2 > 10.1.1.1 +> zx0 ip #0 40(20) 6 10.1.1.2,1025 > 10.1.1.1,1025 +> zx0 ip #0 40(20) 6 10.1.1.2,1026 > 10.1.1.1,1025 +> zx0 ip #0 20(20) 255 10.2.2.1 > 10.1.2.1 +> zx0 ip #0 20(20) 255 10.2.2.2 > 10.1.2.1 +< zx0 ip #0 20(20) 255 10.1.1.1 > 10.1.1.2 +< zx0 ip #0 20(20) 255 10.1.1.2 > 10.1.1.1 +< zx0 ip #0 20(20) 255 10.2.2.1 > 10.2.1.1 +< zx0 ip #0 20(20) 255 10.2.2.2 > 10.2.1.1 +< zx0 ip #0 20(20) 255 10.2.2.3 > 10.1.1.1 +< zx0 ip #0 20(20) 255 10.2.3.4 > 10.2.2.2 +< zx0 ip #0 20(20) 255 10.1.1.1 > 10.2.2.2 +< zx0 ip #0 20(20) 255 10.1.1.2 > 10.2.2.2 +< zx0 ip #0 20(20) 255 10.1.1.0 > 10.3.4.5 +< zx0 ip #0 20(20) 255 10.1.1.1 > 10.3.4.5 +< zx0 ip #0 20(20) 255 10.1.1.2 > 10.3.4.5 +< zx0 ip #0 40(20) 6 10.1.1.1,1025 > 10.3.4.5,1025 +> zx0 ip #0 48(20) 1 10.1.1.1 > 10.4.3.2 +< zx0 ip #0 48(20) 1 10.4.3.2 > 10.2.2.2 +< zx0 ip #0 48(20) 1 10.4.3.2 > 10.3.4.3 +< zx0 ip #0 48(20) 1 10.4.3.2 > 10.3.4.5 +> zx0 ip #0 20(20) 34 10.1.1.2 > 10.4.3.2 +< zx0 ip #0 20(20) 34 10.4.3.2 > 10.3.4.4 +> zx0 ip #0 20(20) 34 10.1.1.2 > 10.4.3.4 +< zx0 ip #0 20(20) 34 10.4.3.4 > 10.3.4.5 +> zx0 ip #0 20(20) 34 10.1.1.3 > 10.4.3.4 +< zx0 ip #0 20(20) 34 10.4.3.4 > 10.3.4.6 +> zx0 ip #0 20(20) 35 10.1.1.3 > 10.4.3.4 +< zx0 ip #0 20(20) 35 10.4.3.4 > 10.3.4.7 +> zx0 ip #0 40(20) 6 10.1.1.1,1025 > 10.1.1.1,1025 +> zx0 ip #0 40(20) 6 10.1.1.1,1025 > 10.1.1.2,1025 +> zx0 ip #0 20(20) 0 10.1.1.0 > 10.1.1.2 +> zx0 ip #0 20(20) 0 10.1.1.1 > 10.1.2.1 +> zx0 ip #0 40(20) 6 10.1.1.2,1025 > 10.1.1.1,1025 +> zx0 ip #0 40(20) 6 10.1.1.2,1025 > 10.1.1.1,1025 +> zx0 ip #0 40(20) 6 10.1.1.2,1026 > 10.1.1.1,1025 +> zx0 ip #0 28(20) 17 10.3.4.5,10000 > 10.1.1.1,1025 +> zx0 ip #0 40(20) 6 10.1.1.3,2000 > 10.1.2.1,80 +> zx0 ip #0 40(20) 6 10.1.1.3,2001 > 10.1.3.1,80 +> zx0 ip #0 40(20) 6 10.1.1.3,2002 > 10.1.4.1,80 +> zx0 ip #0 40(20) 6 10.1.1.3,2003 > 10.1.4.1,80 +< zx0 ip #0 20(20) 0 10.1.1.1 > 10.1.1.2 +< zx0 ip #0 40(20) 6 10.1.1.1,1025 > 10.1.1.2,1025 +< zx0 ip #0 20(20) 0 10.1.1.2 > 10.1.1.1 +> zx0 ip #0 40(20) 6 10.1.1.1,1026 > 10.3.4.5,40000 +< zx0 ip #0 40(20) 6 10.1.1.1,1026 > 10.3.4.5,40000 +> zx0 ip #0 40(20) 6 10.1.1.1,1025 > 10.3.4.5,40000 +< zx0 ip #0 40(20) 6 10.1.1.1,1025 > 10.3.4.5,40000 +> zx0 ip #0 28(20) 17 10.3.4.5,10001 > 10.3.4.5,40001 +< zx0 ip #0 28(20) 17 10.1.1.2,1025 > 10.3.4.5,40001 +> zx0 ip #0 40(20) 6 10.1.2.1,80 > 10.3.4.5,40001 +< zx0 ip #0 40(20) 6 10.1.2.1,80 > 10.3.4.5,40001 +List of active MAP/Redirect filters: +map zx0 10.1.1.0/24 -> 10.3.4.5/32 portmap udp 10000:20000 sequential + +List of active sessions: +MAP 10.1.1.2 1025 <- -> 10.3.4.5 10001 [10.3.4.5 40001] +MAP 10.1.1.2 1025 <- -> 10.3.4.5 10000 [10.1.1.1 1025] + +Hostmap table: +10.1.1.2,10.3.4.5 -> 10.3.4.5,0.0.0.0 (use = 1) +10.1.1.2,10.1.1.1 -> 10.3.4.5,0.0.0.0 (use = 1) +List of active state sessions: +List of configured pools +List of configured hash tables +List of groups configured (set 0) +List of groups configured (set 1) +Rules configured (set 0, in) +Rules configured (set 0, out) +Rules configured (set 1, in) +Rules configured (set 1, out) +Accounting rules configured (set 0, in) +Accounting rules configured (set 0, out) +Accounting rules configured (set 1, in) +Accounting rules configured (set 1, out) ------------------------------- -ip #0 20(20) 255 10.1.1.0 > 10.1.1.2 -ip #0 20(20) 255 10.1.1.1 > 10.1.1.2 -ip #0 20(20) 255 10.1.1.2 > 10.1.1.1 -ip #0 40(20) 6 10.3.4.1,10000 > 10.1.1.1,1025 -ip #0 40(20) 6 10.3.4.1,10001 > 10.1.1.1,1025 -ip #0 20(20) 255 10.2.2.1 > 10.1.2.1 -ip #0 20(20) 255 10.2.2.2 > 10.1.2.1 -ip #0 20(20) 255 10.1.1.1 > 10.1.1.2 -ip #0 20(20) 255 10.1.1.2 > 10.1.1.1 -ip #0 20(20) 255 10.2.2.1 > 10.2.1.1 -ip #0 20(20) 255 10.2.2.2 > 10.2.1.1 -ip #0 20(20) 255 10.2.2.3 > 10.1.1.1 -ip #0 20(20) 255 10.2.3.4 > 10.2.2.2 -ip #0 20(20) 255 10.1.1.1 > 10.2.2.2 -ip #0 20(20) 255 10.1.1.2 > 10.2.2.2 -ip #0 20(20) 255 10.1.1.0 > 10.3.4.5 -ip #0 20(20) 255 10.1.1.1 > 10.3.4.5 -ip #0 20(20) 255 10.1.1.2 > 10.3.4.5 -ip #0 40(20) 6 10.1.1.1,1025 > 10.3.4.5,1025 -ip #0 48(20) 1 10.1.1.1 > 10.4.3.2 -ip #0 48(20) 1 10.4.3.2 > 10.2.2.2 -ip #0 48(20) 1 10.4.3.2 > 10.3.4.3 -ip #0 48(20) 1 10.4.3.2 > 10.3.4.5 -ip #0 20(20) 34 10.1.1.2 > 10.4.3.2 -ip #0 20(20) 34 10.4.3.2 > 10.3.4.4 -ip #0 20(20) 34 10.1.1.2 > 10.4.3.4 -ip #0 20(20) 34 10.4.3.4 > 10.3.4.5 -ip #0 20(20) 34 10.1.1.3 > 10.4.3.4 -ip #0 20(20) 34 10.4.3.4 > 10.3.4.6 -ip #0 20(20) 35 10.1.1.3 > 10.4.3.4 -ip #0 20(20) 35 10.4.3.4 > 10.3.4.7 -ip #0 40(20) 6 10.3.4.1,10002 > 10.1.1.1,1025 -ip #0 40(20) 6 10.3.4.1,10003 > 10.1.1.2,1025 -ip #0 20(20) 0 10.1.1.0 > 10.1.1.2 -ip #0 20(20) 0 10.1.1.1 > 10.1.2.1 -ip #0 40(20) 6 10.3.4.1,10000 > 10.1.1.1,1025 -ip #0 40(20) 6 10.3.4.1,10000 > 10.1.1.1,1025 -ip #0 40(20) 6 10.3.4.1,10001 > 10.1.1.1,1025 -ip #0 28(20) 17 10.3.4.1,10004 > 10.1.1.1,1025 -ip #0 40(20) 6 10.3.4.1,10005 > 10.1.2.1,80 -ip #0 40(20) 6 10.3.4.1,10006 > 10.1.3.1,80 -ip #0 40(20) 6 10.3.4.1,10007 > 10.1.4.1,80 -ip #0 40(20) 6 10.3.4.1,10008 > 10.1.4.1,80 -ip #0 20(20) 0 10.1.1.1 > 10.1.1.2 -ip #0 40(20) 6 10.1.1.1,1025 > 10.1.1.2,1025 -ip #0 20(20) 0 10.1.1.2 > 10.1.1.1 -ip #0 40(20) 6 10.3.4.1,10009 > 10.3.4.5,40000 -ip #0 40(20) 6 10.1.1.1,1026 > 10.3.4.5,40000 -ip #0 40(20) 6 10.3.4.1,10010 > 10.3.4.5,40000 -ip #0 40(20) 6 10.1.1.1,1025 > 10.3.4.5,40000 -ip #0 28(20) 17 10.3.4.1,10011 > 10.3.4.5,40001 -ip #0 28(20) 17 10.1.1.2,1025 > 10.3.4.5,40001 -ip #0 40(20) 6 10.3.4.1,10012 > 10.3.4.5,40001 -ip #0 40(20) 6 10.1.2.1,80 > 10.3.4.5,40001 +> zx0 ip #0 20(20) 255 10.1.1.0 > 10.1.1.2 +> zx0 ip #0 20(20) 255 10.1.1.1 > 10.1.1.2 +> zx0 ip #0 20(20) 255 10.1.1.2 > 10.1.1.1 +> zx0 ip #0 40(20) 6 10.3.4.1,10000 > 10.1.1.1,1025 +> zx0 ip #0 40(20) 6 10.3.4.1,10001 > 10.1.1.1,1025 +> zx0 ip #0 20(20) 255 10.2.2.1 > 10.1.2.1 +> zx0 ip #0 20(20) 255 10.2.2.2 > 10.1.2.1 +< zx0 ip #0 20(20) 255 10.1.1.1 > 10.1.1.2 +< zx0 ip #0 20(20) 255 10.1.1.2 > 10.1.1.1 +< zx0 ip #0 20(20) 255 10.2.2.1 > 10.2.1.1 +< zx0 ip #0 20(20) 255 10.2.2.2 > 10.2.1.1 +< zx0 ip #0 20(20) 255 10.2.2.3 > 10.1.1.1 +< zx0 ip #0 20(20) 255 10.2.3.4 > 10.2.2.2 +< zx0 ip #0 20(20) 255 10.1.1.1 > 10.2.2.2 +< zx0 ip #0 20(20) 255 10.1.1.2 > 10.2.2.2 +< zx0 ip #0 20(20) 255 10.1.1.0 > 10.3.4.5 +< zx0 ip #0 20(20) 255 10.1.1.1 > 10.3.4.5 +< zx0 ip #0 20(20) 255 10.1.1.2 > 10.3.4.5 +< zx0 ip #0 40(20) 6 10.1.1.1,1025 > 10.3.4.5,1025 +> zx0 ip #0 48(20) 1 10.1.1.1 > 10.4.3.2 +< zx0 ip #0 48(20) 1 10.4.3.2 > 10.2.2.2 +< zx0 ip #0 48(20) 1 10.4.3.2 > 10.3.4.3 +< zx0 ip #0 48(20) 1 10.4.3.2 > 10.3.4.5 +> zx0 ip #0 20(20) 34 10.1.1.2 > 10.4.3.2 +< zx0 ip #0 20(20) 34 10.4.3.2 > 10.3.4.4 +> zx0 ip #0 20(20) 34 10.1.1.2 > 10.4.3.4 +< zx0 ip #0 20(20) 34 10.4.3.4 > 10.3.4.5 +> zx0 ip #0 20(20) 34 10.1.1.3 > 10.4.3.4 +< zx0 ip #0 20(20) 34 10.4.3.4 > 10.3.4.6 +> zx0 ip #0 20(20) 35 10.1.1.3 > 10.4.3.4 +< zx0 ip #0 20(20) 35 10.4.3.4 > 10.3.4.7 +> zx0 ip #0 40(20) 6 10.3.4.1,10002 > 10.1.1.1,1025 +> zx0 ip #0 40(20) 6 10.3.4.1,10003 > 10.1.1.2,1025 +> zx0 ip #0 20(20) 0 10.1.1.0 > 10.1.1.2 +> zx0 ip #0 20(20) 0 10.1.1.1 > 10.1.2.1 +> zx0 ip #0 40(20) 6 10.3.4.1,10000 > 10.1.1.1,1025 +> zx0 ip #0 40(20) 6 10.3.4.1,10000 > 10.1.1.1,1025 +> zx0 ip #0 40(20) 6 10.3.4.1,10001 > 10.1.1.1,1025 +> zx0 ip #0 28(20) 17 10.3.4.1,10004 > 10.1.1.1,1025 +> zx0 ip #0 40(20) 6 10.3.4.1,10005 > 10.1.2.1,80 +> zx0 ip #0 40(20) 6 10.3.4.1,10006 > 10.1.3.1,80 +> zx0 ip #0 40(20) 6 10.3.4.1,10007 > 10.1.4.1,80 +> zx0 ip #0 40(20) 6 10.3.4.1,10008 > 10.1.4.1,80 +< zx0 ip #0 20(20) 0 10.1.1.1 > 10.1.1.2 +< zx0 ip #0 40(20) 6 10.1.1.1,1025 > 10.1.1.2,1025 +< zx0 ip #0 20(20) 0 10.1.1.2 > 10.1.1.1 +> zx0 ip #0 40(20) 6 10.3.4.1,10009 > 10.3.4.5,40000 +< zx0 ip #0 40(20) 6 10.1.1.1,1026 > 10.3.4.5,40000 +> zx0 ip #0 40(20) 6 10.3.4.1,10010 > 10.3.4.5,40000 +< zx0 ip #0 40(20) 6 10.1.1.1,1025 > 10.3.4.5,40000 +> zx0 ip #0 28(20) 17 10.3.4.1,10011 > 10.3.4.5,40001 +< zx0 ip #0 28(20) 17 10.1.1.2,1025 > 10.3.4.5,40001 +> zx0 ip #0 40(20) 6 10.3.4.1,10012 > 10.3.4.5,40001 +< zx0 ip #0 40(20) 6 10.1.2.1,80 > 10.3.4.5,40001 +List of active MAP/Redirect filters: +map zx0 10.1.0.0/16 -> 10.3.4.0/24 portmap tcp/udp 10000:20000 sequential + +List of active sessions: +MAP 10.1.2.1 80 <- -> 10.3.4.1 10012 [10.3.4.5 40001] +MAP 10.1.1.2 1025 <- -> 10.3.4.1 10011 [10.3.4.5 40001] +MAP 10.1.1.1 1025 <- -> 10.3.4.1 10010 [10.3.4.5 40000] +MAP 10.1.1.1 1026 <- -> 10.3.4.1 10009 [10.3.4.5 40000] +MAP 10.1.1.3 2003 <- -> 10.3.4.1 10008 [10.1.4.1 80] +MAP 10.1.1.3 2002 <- -> 10.3.4.1 10007 [10.1.4.1 80] +MAP 10.1.1.3 2001 <- -> 10.3.4.1 10006 [10.1.3.1 80] +MAP 10.1.1.3 2000 <- -> 10.3.4.1 10005 [10.1.2.1 80] +MAP 10.1.1.2 1025 <- -> 10.3.4.1 10004 [10.1.1.1 1025] +MAP 10.1.1.1 1025 <- -> 10.3.4.1 10003 [10.1.1.2 1025] +MAP 10.1.1.1 1025 <- -> 10.3.4.1 10002 [10.1.1.1 1025] +MAP 10.1.1.2 1026 <- -> 10.3.4.1 10001 [10.1.1.1 1025] +MAP 10.1.1.2 1025 <- -> 10.3.4.1 10000 [10.1.1.1 1025] + +Hostmap table: +10.1.2.1,10.3.4.5 -> 10.3.4.1,0.0.0.0 (use = 1) +10.1.1.2,10.3.4.5 -> 10.3.4.1,0.0.0.0 (use = 1) +10.1.1.1,10.3.4.5 -> 10.3.4.1,0.0.0.0 (use = 2) +10.1.1.3,10.1.4.1 -> 10.3.4.1,0.0.0.0 (use = 2) +10.1.1.3,10.1.3.1 -> 10.3.4.1,0.0.0.0 (use = 1) +10.1.1.3,10.1.2.1 -> 10.3.4.1,0.0.0.0 (use = 1) +10.1.1.1,10.1.1.2 -> 10.3.4.1,0.0.0.0 (use = 1) +10.1.1.1,10.1.1.1 -> 10.3.4.1,0.0.0.0 (use = 1) +10.1.1.2,10.1.1.1 -> 10.3.4.1,0.0.0.0 (use = 3) +List of active state sessions: +List of configured pools +List of configured hash tables +List of groups configured (set 0) +List of groups configured (set 1) +Rules configured (set 0, in) +Rules configured (set 0, out) +Rules configured (set 1, in) +Rules configured (set 1, out) +Accounting rules configured (set 0, in) +Accounting rules configured (set 0, out) +Accounting rules configured (set 1, in) +Accounting rules configured (set 1, out) ------------------------------- -ip #0 20(20) 255 10.1.1.0 > 10.1.1.2 -ip #0 20(20) 255 10.1.1.1 > 10.1.1.2 -ip #0 20(20) 255 10.1.1.2 > 10.1.1.1 -ip #0 40(20) 6 10.3.4.5,40000 > 10.1.1.1,1025 -ip #0 40(20) 6 10.3.4.5,40001 > 10.1.1.1,1025 -ip #0 20(20) 255 10.2.2.1 > 10.1.2.1 -ip #0 20(20) 255 10.2.2.2 > 10.1.2.1 -ip #0 20(20) 255 10.1.1.1 > 10.1.1.2 -ip #0 20(20) 255 10.1.1.2 > 10.1.1.1 -ip #0 20(20) 255 10.2.2.1 > 10.2.1.1 -ip #0 20(20) 255 10.2.2.2 > 10.2.1.1 -ip #0 20(20) 255 10.2.2.3 > 10.1.1.1 -ip #0 20(20) 255 10.2.3.4 > 10.2.2.2 -ip #0 20(20) 255 10.1.1.1 > 10.2.2.2 -ip #0 20(20) 255 10.1.1.2 > 10.2.2.2 -ip #0 20(20) 255 10.1.1.0 > 10.3.4.5 -ip #0 20(20) 255 10.1.1.1 > 10.3.4.5 -ip #0 20(20) 255 10.1.1.2 > 10.3.4.5 -ip #0 40(20) 6 10.1.1.1,1025 > 10.3.4.5,1025 -ip #0 48(20) 1 10.1.1.1 > 10.4.3.2 -ip #0 48(20) 1 10.4.3.2 > 10.2.2.2 -ip #0 48(20) 1 10.4.3.2 > 10.3.4.3 -ip #0 48(20) 1 10.4.3.2 > 10.3.4.5 -ip #0 20(20) 34 10.1.1.2 > 10.4.3.2 -ip #0 20(20) 34 10.4.3.2 > 10.3.4.4 -ip #0 20(20) 34 10.1.1.2 > 10.4.3.4 -ip #0 20(20) 34 10.4.3.4 > 10.3.4.5 -ip #0 20(20) 34 10.1.1.3 > 10.4.3.4 -ip #0 20(20) 34 10.4.3.4 > 10.3.4.6 -ip #0 20(20) 35 10.1.1.3 > 10.4.3.4 -ip #0 20(20) 35 10.4.3.4 > 10.3.4.7 -ip #0 40(20) 6 10.1.1.1,1025 > 10.1.1.1,1025 -ip #0 40(20) 6 10.3.4.5,40000 > 10.1.1.2,1025 -ip #0 20(20) 0 10.1.1.0 > 10.1.1.2 -ip #0 20(20) 0 10.1.1.1 > 10.1.2.1 -ip #0 40(20) 6 10.3.4.5,40000 > 10.1.1.1,1025 -ip #0 40(20) 6 10.3.4.5,40000 > 10.1.1.1,1025 -ip #0 40(20) 6 10.3.4.5,40001 > 10.1.1.1,1025 -ip #0 28(20) 17 10.3.4.5,40001 > 10.1.1.1,1025 -ip #0 40(20) 6 10.3.4.5,40000 > 10.1.2.1,80 -ip #0 40(20) 6 10.3.4.5,40001 > 10.1.3.1,80 -ip #0 40(20) 6 10.3.4.5,40000 > 10.1.4.1,80 -ip #0 40(20) 6 10.3.4.5,40001 > 10.1.4.1,80 -ip #0 20(20) 0 10.1.1.1 > 10.1.1.2 -ip #0 40(20) 6 10.1.1.1,1025 > 10.1.1.2,1025 -ip #0 20(20) 0 10.1.1.2 > 10.1.1.1 -ip #0 40(20) 6 10.3.4.5,40000 > 10.3.4.5,40000 -ip #0 40(20) 6 10.1.1.1,1026 > 10.3.4.5,40000 -ip #0 40(20) 6 10.3.4.5,40001 > 10.3.4.5,40000 -ip #0 40(20) 6 10.1.1.1,1025 > 10.1.1.2,1025 -ip #0 28(20) 17 10.3.4.5,40000 > 10.3.4.5,40001 -ip #0 28(20) 17 10.1.1.2,1025 > 10.3.4.5,40001 -ip #0 40(20) 6 10.1.2.1,80 > 10.3.4.5,40001 -ip #0 40(20) 6 10.1.2.1,80 > 10.3.4.5,40001 +> zx0 ip #0 20(20) 255 10.1.1.0 > 10.1.1.2 +> zx0 ip #0 20(20) 255 10.1.1.1 > 10.1.1.2 +> zx0 ip #0 20(20) 255 10.1.1.2 > 10.1.1.1 +> zx0 ip #0 40(20) 6 10.3.4.5,40000 > 10.1.1.1,1025 +> zx0 ip #0 40(20) 6 10.3.4.5,40001 > 10.1.1.1,1025 +> zx0 ip #0 20(20) 255 10.2.2.1 > 10.1.2.1 +> zx0 ip #0 20(20) 255 10.2.2.2 > 10.1.2.1 +< zx0 ip #0 20(20) 255 10.1.1.1 > 10.1.1.2 +< zx0 ip #0 20(20) 255 10.1.1.2 > 10.1.1.1 +< zx0 ip #0 20(20) 255 10.2.2.1 > 10.2.1.1 +< zx0 ip #0 20(20) 255 10.2.2.2 > 10.2.1.1 +< zx0 ip #0 20(20) 255 10.2.2.3 > 10.1.1.1 +< zx0 ip #0 20(20) 255 10.2.3.4 > 10.2.2.2 +< zx0 ip #0 20(20) 255 10.1.1.1 > 10.2.2.2 +< zx0 ip #0 20(20) 255 10.1.1.2 > 10.2.2.2 +< zx0 ip #0 20(20) 255 10.1.1.0 > 10.3.4.5 +< zx0 ip #0 20(20) 255 10.1.1.1 > 10.3.4.5 +< zx0 ip #0 20(20) 255 10.1.1.2 > 10.3.4.5 +< zx0 ip #0 40(20) 6 10.1.1.1,1025 > 10.3.4.5,1025 +> zx0 ip #0 48(20) 1 10.1.1.1 > 10.4.3.2 +< zx0 ip #0 48(20) 1 10.4.3.2 > 10.2.2.2 +< zx0 ip #0 48(20) 1 10.4.3.2 > 10.3.4.3 +< zx0 ip #0 48(20) 1 10.4.3.2 > 10.3.4.5 +> zx0 ip #0 20(20) 34 10.1.1.2 > 10.4.3.2 +< zx0 ip #0 20(20) 34 10.4.3.2 > 10.3.4.4 +> zx0 ip #0 20(20) 34 10.1.1.2 > 10.4.3.4 +< zx0 ip #0 20(20) 34 10.4.3.4 > 10.3.4.5 +> zx0 ip #0 20(20) 34 10.1.1.3 > 10.4.3.4 +< zx0 ip #0 20(20) 34 10.4.3.4 > 10.3.4.6 +> zx0 ip #0 20(20) 35 10.1.1.3 > 10.4.3.4 +< zx0 ip #0 20(20) 35 10.4.3.4 > 10.3.4.7 +15 +> zx0 ip #0 40(20) 6 10.3.4.5,40000 > 10.1.1.2,1025 +> zx0 ip #0 20(20) 0 10.1.1.0 > 10.1.1.2 +> zx0 ip #0 20(20) 0 10.1.1.1 > 10.1.2.1 +> zx0 ip #0 40(20) 6 10.3.4.5,40000 > 10.1.1.1,1025 +> zx0 ip #0 40(20) 6 10.3.4.5,40000 > 10.1.1.1,1025 +> zx0 ip #0 40(20) 6 10.3.4.5,40001 > 10.1.1.1,1025 +> zx0 ip #0 28(20) 17 10.3.4.5,40001 > 10.1.1.1,1025 +> zx0 ip #0 40(20) 6 10.3.4.5,40000 > 10.1.2.1,80 +> zx0 ip #0 40(20) 6 10.3.4.5,40001 > 10.1.3.1,80 +> zx0 ip #0 40(20) 6 10.3.4.5,40000 > 10.1.4.1,80 +> zx0 ip #0 40(20) 6 10.3.4.5,40001 > 10.1.4.1,80 +< zx0 ip #0 20(20) 0 10.1.1.1 > 10.1.1.2 +< zx0 ip #0 40(20) 6 10.1.1.1,1025 > 10.1.1.2,1025 +< zx0 ip #0 20(20) 0 10.1.1.2 > 10.1.1.1 +> zx0 ip #0 40(20) 6 10.3.4.5,40000 > 10.3.4.5,40000 +< zx0 ip #0 40(20) 6 10.1.1.1,1026 > 10.3.4.5,40000 +> zx0 ip #0 40(20) 6 10.3.4.5,40001 > 10.3.4.5,40000 +< zx0 ip #0 40(20) 6 10.1.1.1,1025 > 10.1.1.2,1025 +> zx0 ip #0 28(20) 17 10.3.4.5,40000 > 10.3.4.5,40001 +< zx0 ip #0 28(20) 17 10.1.1.2,1025 > 10.3.4.5,40001 +> zx0 ip #0 40(20) 6 10.1.2.1,80 > 10.3.4.5,40001 +< zx0 ip #0 40(20) 6 10.1.2.1,80 > 10.3.4.5,40001 +List of active MAP/Redirect filters: +map zx0 10.1.1.0/24 -> 10.3.4.5/32 portmap tcp/udp 40000:40001 sequential + +List of active sessions: +MAP 10.1.1.2 1025 <- -> 10.3.4.5 40000 [10.3.4.5 40001] +MAP 10.1.1.1 1025 <- -> 10.3.4.5 40001 [10.3.4.5 40000] +MAP 10.1.1.1 1026 <- -> 10.3.4.5 40000 [10.3.4.5 40000] +MAP 10.1.1.3 2003 <- -> 10.3.4.5 40001 [10.1.4.1 80] +MAP 10.1.1.3 2002 <- -> 10.3.4.5 40000 [10.1.4.1 80] +MAP 10.1.1.3 2001 <- -> 10.3.4.5 40001 [10.1.3.1 80] +MAP 10.1.1.3 2000 <- -> 10.3.4.5 40000 [10.1.2.1 80] +MAP 10.1.1.2 1025 <- -> 10.3.4.5 40001 [10.1.1.1 1025] +MAP 10.1.1.1 1025 <- -> 10.3.4.5 40000 [10.1.1.2 1025] +MAP 10.1.1.2 1026 <- -> 10.3.4.5 40001 [10.1.1.1 1025] +MAP 10.1.1.2 1025 <- -> 10.3.4.5 40000 [10.1.1.1 1025] + +Hostmap table: +10.1.1.2,10.3.4.5 -> 10.3.4.5,0.0.0.0 (use = 1) +10.1.1.1,10.3.4.5 -> 10.3.4.5,0.0.0.0 (use = 2) +10.1.1.3,10.1.4.1 -> 10.3.4.5,0.0.0.0 (use = 2) +10.1.1.3,10.1.3.1 -> 10.3.4.5,0.0.0.0 (use = 1) +10.1.1.3,10.1.2.1 -> 10.3.4.5,0.0.0.0 (use = 1) +10.1.1.1,10.1.1.2 -> 10.3.4.5,0.0.0.0 (use = 1) +10.1.1.2,10.1.1.1 -> 10.3.4.5,0.0.0.0 (use = 3) +List of active state sessions: +List of configured pools +List of configured hash tables +List of groups configured (set 0) +List of groups configured (set 1) +Rules configured (set 0, in) +Rules configured (set 0, out) +Rules configured (set 1, in) +Rules configured (set 1, out) +Accounting rules configured (set 0, in) +Accounting rules configured (set 0, out) +Accounting rules configured (set 1, in) +Accounting rules configured (set 1, out) ------------------------------- diff --git a/contrib/ipfilter/test/expected/n5_6 b/contrib/ipfilter/test/expected/n5_6 new file mode 100644 index 000000000000..1e7bc8eff5ad --- /dev/null +++ b/contrib/ipfilter/test/expected/n5_6 @@ -0,0 +1,533 @@ +> zx0 ip6/0 1 0 255 10:1:1:0:0:0:0:0 > 10:1:1:0:0:0:0:2 +> zx0 ip6/0 1 0 255 10:0:0:0:0:2:2:2 > 10:1:1:0:0:0:0:2 +> zx0 ip6/0 1 0 255 10:1:1:0:0:0:0:2 > 10:1:1:0:0:0:0:1 +> zx0 ip6/0 20 0 6 10:1:1:0:0:0:0:2,1025 > 10:1:1:0:0:0:0:1,1025 +> zx0 ip6/0 20 0 6 10:1:1:0:0:0:0:2,1026 > 10:1:1:0:0:0:0:1,1025 +> zx0 ip6/0 1 0 255 10:0:0:0:0:2:2:1 > 10:1:2:0:0:0:0:1 +> zx0 ip6/0 1 0 255 10:0:0:0:0:2:2:2 > 10:1:2:0:0:0:0:1 +< zx0 ip6/0 1 0 255 10:1:1:0:0:0:0:1 > 10:1:1:0:0:0:0:2 +< zx0 ip6/0 1 0 255 10:1:1:0:0:0:0:2 > 10:1:1:0:0:0:0:1 +< zx0 ip6/0 1 0 255 10:0:0:0:0:2:2:1 > 10:0:0:0:0:2:1:1 +< zx0 ip6/0 1 0 255 10:0:0:0:0:2:2:2 > 10:0:0:0:0:2:1:1 +< zx0 ip6/0 1 0 255 10:0:0:0:0:2:2:3 > 10:1:1:0:0:0:0:1 +< zx0 ip6/0 1 0 255 10:0:0:0:0:2:3:4 > 10:0:0:0:0:2:2:2 +< zx0 ip6/0 1 0 255 10:1:1:0:0:0:0:1 > 10:0:0:0:0:2:2:2 +< zx0 ip6/0 1 0 255 10:1:1:0:0:0:0:2 > 10:1:1:0:0:0:0:1 +< zx0 ip6/0 1 0 255 10:1:1:0:0:0:0:0 > 10:0:0:0:0:3:4:5 +< zx0 ip6/0 1 0 255 10:1:1:0:0:0:0:1 > 10:0:0:0:0:3:4:5 +< zx0 ip6/0 1 0 255 10:1:1:0:0:0:0:2 > 10:0:0:0:0:3:4:5 +< zx0 ip6/0 20 0 6 10:1:1:0:0:0:0:1,1025 > 10:0:0:0:0:3:4:5,1025 +> zx0 ip6/0 88 0 58 10:0:0:0:0:2:2:2 > 10:4:3:0:0:0:0:2 +< zx0 ip6/0 88 0 58 10:4:3:0:0:0:0:2 > 10:1:1:0:0:0:0:1 +< zx0 ip6/0 88 0 58 10:4:3:0:0:0:0:2 > 10:0:0:0:0:3:4:3 +< zx0 ip6/0 88 0 58 10:4:3:0:0:0:0:2 > 10:0:0:0:0:3:4:5 +> zx0 ip6/0 1 0 34 10:1:1:0:0:0:0:2 > 10:4:3:0:0:0:0:2 +< zx0 ip6/0 1 0 34 10:4:3:0:0:0:0:2 > 10:0:0:0:0:3:4:4 +> zx0 ip6/0 1 0 34 10:1:1:0:0:0:0:2 > 10:4:3:0:0:0:0:4 +< zx0 ip6/0 1 0 34 10:4:3:0:0:0:0:4 > 10:0:0:0:0:3:4:5 +> zx0 ip6/0 1 0 34 10:1:1:0:0:0:0:3 > 10:4:3:0:0:0:0:4 +< zx0 ip6/0 1 0 34 10:4:3:0:0:0:0:4 > 10:0:0:0:0:3:4:6 +> zx0 ip6/0 1 0 35 10:1:1:0:0:0:0:3 > 10:4:3:0:0:0:0:4 +< zx0 ip6/0 1 0 35 10:4:3:0:0:0:0:4 > 10:0:0:0:0:3:4:7 +> zx0 ip6/0 20 0 6 10:0:0:0:0:2:2:2,1025 > 10:1:1:0:0:0:0:1,1025 +> zx0 ip6/0 20 0 6 10:0:0:0:0:2:2:2,1025 > 10:1:1:0:0:0:0:2,1025 +> zx0 ip6/0 1 0 41 10:1:1:0:0:0:0:0 > 10:1:1:0:0:0:0:2 +> zx0 ip6/0 1 0 41 10:0:0:0:0:2:2:2 > 10:1:2:0:0:0:0:1 +> zx0 ip6/0 20 0 6 10:1:1:0:0:0:0:2,1025 > 10:1:1:0:0:0:0:1,1025 +> zx0 ip6/0 20 0 6 10:1:1:0:0:0:0:2,1025 > 10:1:1:0:0:0:0:1,1025 +> zx0 ip6/0 20 0 6 10:1:1:0:0:0:0:2,1026 > 10:1:1:0:0:0:0:1,1025 +> zx0 ip6/0 8 0 17 10:1:1:0:0:0:0:2,1025 > 10:1:1:0:0:0:0:1,1025 +> zx0 ip6/0 20 0 6 10:1:1:0:0:0:0:3,2000 > 10:1:2:0:0:0:0:1,80 +> zx0 ip6/0 20 0 6 10:1:1:0:0:0:0:3,2001 > 10:1:3:0:0:0:0:1,80 +> zx0 ip6/0 20 0 6 10:1:1:0:0:0:0:3,2002 > 10:1:4:0:0:0:0:1,80 +> zx0 ip6/0 20 0 6 10:1:1:0:0:0:0:3,2003 > 10:1:4:0:0:0:0:1,80 +< zx0 ip6/0 1 0 41 10:1:1:0:0:0:0:1 > 10:1:1:0:0:0:0:2 +< zx0 ip6/0 20 0 6 10:1:1:0:0:0:0:1,1025 > 10:1:1:0:0:0:0:2,1025 +< zx0 ip6/0 1 0 41 10:1:1:0:0:0:0:2 > 10:1:1:0:0:0:0:1 +> zx0 ip6/0 20 0 6 10:0:0:0:0:2:2:2,1026 > 10:0:0:0:0:3:4:5,40000 +< zx0 ip6/0 20 0 6 10:1:1:0:0:0:0:1,1026 > 10:0:0:0:0:3:4:5,40000 +> zx0 ip6/0 20 0 6 10:0:0:0:0:2:2:2,1025 > 10:0:0:0:0:3:4:5,40000 +< zx0 ip6/0 20 0 6 10:1:1:0:0:0:0:1,1025 > 10:0:0:0:0:3:4:5,40000 +> zx0 ip6/0 8 0 17 10:1:1:0:0:0:0:2,1025 > 10:0:0:0:0:3:4:5,40001 +< zx0 ip6/0 8 0 17 10:1:1:0:0:0:0:2,1025 > 10:0:0:0:0:3:4:5,40001 +> zx0 ip6/0 20 0 6 10:1:2:0:0:0:0:1,80 > 10:0:0:0:0:3:4:5,40001 +< zx0 ip6/0 20 0 6 10:1:2:0:0:0:0:1,80 > 10:0:0:0:0:3:4:5,40001 +List of active MAP/Redirect filters: +map zx0 inet6 10:1:1::1/128 -> 10::2:2:2/128 + +List of active sessions: +MAP 10:1:1::1 1025 <- -> 10::2:2:2 1025 [10::3:4:5 40000] +MAP 10:1:1::1 1026 <- -> 10::2:2:2 1026 [10::3:4:5 40000] +MAP 10:1:1::1 <- -> 10::2:2:2 [10:1:2::1] +MAP 10:1:1::1 1025 <- -> 10::2:2:2 1025 [10:1:1::2 1025] +MAP 10:1:1::1 1025 <- -> 10::2:2:2 1025 [10:1:1::1 1025] +MAP 10:1:1::1 <- -> 10::2:2:2 [10:4:3::2] +MAP 10:1:1::1 <- -> 10::2:2:2 [10:1:1::2] + +Hostmap table: +10:1:1::1,10::3:4:5 -> 10::2:2:2,any (use = 2) +10:1:1::1,10:1:2::1 -> 10::2:2:2,any (use = 1) +10:1:1::1,10:1:1::1 -> 10::2:2:2,any (use = 1) +10:1:1::1,10:4:3::2 -> 10::2:2:2,any (use = 1) +10:1:1::1,10:1:1::2 -> 10::2:2:2,any (use = 2) +List of active state sessions: +List of configured pools +List of configured hash tables +List of groups configured (set 0) +List of groups configured (set 1) +Rules configured (set 0, in) +Rules configured (set 0, out) +Rules configured (set 1, in) +Rules configured (set 1, out) +Accounting rules configured (set 0, in) +Accounting rules configured (set 0, out) +Accounting rules configured (set 1, in) +Accounting rules configured (set 1, out) +------------------------------- +> zx0 ip6/0 1 0 255 10:0:0:0:0:3:4:5 > 10:1:1:0:0:0:0:2 +16 +> zx0 ip6/0 1 0 255 10:0:0:0:0:3:4:5 > 10:1:1:0:0:0:0:1 +> zx0 ip6/0 20 0 6 10:0:0:0:0:3:4:5,1025 > 10:1:1:0:0:0:0:1,1025 +> zx0 ip6/0 20 0 6 10:0:0:0:0:3:4:5,1026 > 10:1:1:0:0:0:0:1,1025 +> zx0 ip6/0 1 0 255 10:0:0:0:0:2:2:1 > 10:1:2:0:0:0:0:1 +> zx0 ip6/0 1 0 255 10:0:0:0:0:2:2:2 > 10:1:2:0:0:0:0:1 +< zx0 ip6/0 1 0 255 10:1:1:0:0:0:0:1 > 10:1:1:0:0:0:0:2 +< zx0 ip6/0 1 0 255 10:1:1:0:0:0:0:2 > 10:1:1:0:0:0:0:1 +< zx0 ip6/0 1 0 255 10:0:0:0:0:2:2:1 > 10:0:0:0:0:2:1:1 +< zx0 ip6/0 1 0 255 10:0:0:0:0:2:2:2 > 10:0:0:0:0:2:1:1 +< zx0 ip6/0 1 0 255 10:0:0:0:0:2:2:3 > 10:1:1:0:0:0:0:1 +< zx0 ip6/0 1 0 255 10:0:0:0:0:2:3:4 > 10:0:0:0:0:2:2:2 +< zx0 ip6/0 1 0 255 10:1:1:0:0:0:0:1 > 10:0:0:0:0:2:2:2 +< zx0 ip6/0 1 0 255 10:1:1:0:0:0:0:2 > 10:0:0:0:0:2:2:2 +< zx0 ip6/0 1 0 255 10:1:1:0:0:0:0:0 > 10:0:0:0:0:3:4:5 +< zx0 ip6/0 1 0 255 10:1:1:0:0:0:0:1 > 10:1:1:0:0:0:0:2 +< zx0 ip6/0 1 0 255 10:1:1:0:0:0:0:2 > 10:1:1:0:0:0:0:0 +< zx0 ip6/0 20 0 6 10:1:1:0:0:0:0:1,1025 > 10:1:1:0:0:0:0:2,1025 +> zx0 ip6/0 88 0 58 10:1:1:0:0:0:0:1 > 10:4:3:0:0:0:0:2 +< zx0 ip6/0 88 0 58 10:4:3:0:0:0:0:2 > 10:0:0:0:0:2:2:2 +< zx0 ip6/0 88 0 58 10:4:3:0:0:0:0:2 > 10:0:0:0:0:3:4:3 +< zx0 ip6/0 88 0 58 10:4:3:0:0:0:0:2 > 10:0:0:0:0:3:4:5 +> zx0 ip6/0 1 0 34 10:1:1:0:0:0:0:2 > 10:4:3:0:0:0:0:2 +< zx0 ip6/0 1 0 34 10:4:3:0:0:0:0:2 > 10:0:0:0:0:3:4:4 +> zx0 ip6/0 1 0 34 10:1:1:0:0:0:0:2 > 10:4:3:0:0:0:0:4 +< zx0 ip6/0 1 0 34 10:4:3:0:0:0:0:4 > 10:0:0:0:0:3:4:5 +> zx0 ip6/0 1 0 34 10:1:1:0:0:0:0:3 > 10:4:3:0:0:0:0:4 +< zx0 ip6/0 1 0 34 10:4:3:0:0:0:0:4 > 10:0:0:0:0:3:4:6 +> zx0 ip6/0 1 0 35 10:1:1:0:0:0:0:3 > 10:4:3:0:0:0:0:4 +< zx0 ip6/0 1 0 35 10:4:3:0:0:0:0:4 > 10:0:0:0:0:3:4:7 +16 +> zx0 ip6/0 20 0 6 10:0:0:0:0:3:4:5,1025 > 10:1:1:0:0:0:0:2,1025 +> zx0 ip6/0 1 0 41 10:0:0:0:0:3:4:5 > 10:1:1:0:0:0:0:2 +> zx0 ip6/0 1 0 41 10:0:0:0:0:3:4:5 > 10:1:2:0:0:0:0:1 +> zx0 ip6/0 20 0 6 10:0:0:0:0:3:4:5,1025 > 10:1:1:0:0:0:0:1,1025 +> zx0 ip6/0 20 0 6 10:0:0:0:0:3:4:5,1025 > 10:1:1:0:0:0:0:1,1025 +> zx0 ip6/0 20 0 6 10:0:0:0:0:3:4:5,1026 > 10:1:1:0:0:0:0:1,1025 +> zx0 ip6/0 8 0 17 10:0:0:0:0:3:4:5,1025 > 10:1:1:0:0:0:0:1,1025 +> zx0 ip6/0 20 0 6 10:0:0:0:0:3:4:5,2000 > 10:1:2:0:0:0:0:1,80 +> zx0 ip6/0 20 0 6 10:0:0:0:0:3:4:5,2001 > 10:1:3:0:0:0:0:1,80 +> zx0 ip6/0 20 0 6 10:0:0:0:0:3:4:5,2002 > 10:1:4:0:0:0:0:1,80 +> zx0 ip6/0 20 0 6 10:0:0:0:0:3:4:5,2003 > 10:1:4:0:0:0:0:1,80 +< zx0 ip6/0 1 0 41 10:1:1:0:0:0:0:1 > 10:1:1:0:0:0:0:2 +< zx0 ip6/0 20 0 6 10:1:1:0:0:0:0:1,1025 > 10:1:1:0:0:0:0:2,1025 +< zx0 ip6/0 1 0 41 10:1:1:0:0:0:0:2 > 10:1:1:0:0:0:0:1 +> zx0 ip6/0 20 0 6 10:1:1:0:0:0:0:1,1026 > 10:0:0:0:0:3:4:5,40000 +< zx0 ip6/0 20 0 6 10:1:1:0:0:0:0:1,1026 > 10:0:0:0:0:3:4:5,40000 +> zx0 ip6/0 20 0 6 10:1:1:0:0:0:0:1,1025 > 10:0:0:0:0:3:4:5,40000 +< zx0 ip6/0 20 0 6 10:1:1:0:0:0:0:1,1025 > 10:0:0:0:0:3:4:5,40000 +> zx0 ip6/0 8 0 17 10:1:1:0:0:0:0:2,1025 > 10:0:0:0:0:3:4:5,40001 +< zx0 ip6/0 8 0 17 10:1:1:0:0:0:0:2,1025 > 10:0:0:0:0:3:4:5,40001 +> zx0 ip6/0 20 0 6 10:1:2:0:0:0:0:1,80 > 10:0:0:0:0:3:4:5,40001 +< zx0 ip6/0 20 0 6 10:1:2:0:0:0:0:1,80 > 10:0:0:0:0:3:4:5,40001 +List of active MAP/Redirect filters: +map zx0 inet6 from 10:1:1::/112 to 10:1::/32 -> 10::3:4:5/128 + +List of active sessions: +MAP 10:1:1::3 2003 <- -> 10::3:4:5 2003 [10:1:4::1 80] +MAP 10:1:1::3 2002 <- -> 10::3:4:5 2002 [10:1:4::1 80] +MAP 10:1:1::3 2001 <- -> 10::3:4:5 2001 [10:1:3::1 80] +MAP 10:1:1::3 2000 <- -> 10::3:4:5 2000 [10:1:2::1 80] +MAP 10:1:1::2 1025 <- -> 10::3:4:5 1025 [10:1:1::1 1025] +MAP 10:1:1::1 <- -> 10::3:4:5 [10:1:2::1] +MAP 10:1:1:: <- -> 10::3:4:5 [10:1:1::2] +MAP 10:1:1::1 1025 <- -> 10::3:4:5 1025 [10:1:1::2 1025] +MAP 10:1:1::2 1026 <- -> 10::3:4:5 1026 [10:1:1::1 1025] +MAP 10:1:1::2 1025 <- -> 10::3:4:5 1025 [10:1:1::1 1025] +MAP 10:1:1::2 <- -> 10::3:4:5 [10:1:1::1] +MAP 10:1:1:: <- -> 10::3:4:5 [10:1:1::2] + +Hostmap table: +10:1:1::3,10:1:4::1 -> 10::3:4:5,any (use = 2) +10:1:1::3,10:1:3::1 -> 10::3:4:5,any (use = 1) +10:1:1::3,10:1:2::1 -> 10::3:4:5,any (use = 1) +10:1:1::1,10:1:2::1 -> 10::3:4:5,any (use = 1) +10:1:1::1,10:1:1::2 -> 10::3:4:5,any (use = 1) +10:1:1::2,10:1:1::1 -> 10::3:4:5,any (use = 4) +10:1:1::,10:1:1::2 -> 10::3:4:5,any (use = 2) +List of active state sessions: +List of configured pools +List of configured hash tables +List of groups configured (set 0) +List of groups configured (set 1) +Rules configured (set 0, in) +Rules configured (set 0, out) +Rules configured (set 1, in) +Rules configured (set 1, out) +Accounting rules configured (set 0, in) +Accounting rules configured (set 0, out) +Accounting rules configured (set 1, in) +Accounting rules configured (set 1, out) +------------------------------- +> zx0 ip6/0 1 0 255 10:1:1:0:0:0:0:0 > 10:1:1:0:0:0:0:2 +> zx0 ip6/0 1 0 255 10:1:1:0:0:0:0:1 > 10:1:1:0:0:0:0:2 +> zx0 ip6/0 1 0 255 10:1:1:0:0:0:0:2 > 10:1:1:0:0:0:0:1 +> zx0 ip6/0 20 0 6 10:1:1:0:0:0:0:2,1025 > 10:1:1:0:0:0:0:1,1025 +> zx0 ip6/0 20 0 6 10:1:1:0:0:0:0:2,1026 > 10:1:1:0:0:0:0:1,1025 +> zx0 ip6/0 1 0 255 10:0:0:0:0:2:2:1 > 10:1:2:0:0:0:0:1 +> zx0 ip6/0 1 0 255 10:0:0:0:0:2:2:2 > 10:1:2:0:0:0:0:1 +< zx0 ip6/0 1 0 255 10:1:1:0:0:0:0:1 > 10:1:1:0:0:0:0:2 +< zx0 ip6/0 1 0 255 10:1:1:0:0:0:0:2 > 10:1:1:0:0:0:0:1 +< zx0 ip6/0 1 0 255 10:0:0:0:0:2:2:1 > 10:0:0:0:0:2:1:1 +< zx0 ip6/0 1 0 255 10:0:0:0:0:2:2:2 > 10:0:0:0:0:2:1:1 +< zx0 ip6/0 1 0 255 10:0:0:0:0:2:2:3 > 10:1:1:0:0:0:0:1 +< zx0 ip6/0 1 0 255 10:0:0:0:0:2:3:4 > 10:0:0:0:0:2:2:2 +< zx0 ip6/0 1 0 255 10:1:1:0:0:0:0:1 > 10:0:0:0:0:2:2:2 +< zx0 ip6/0 1 0 255 10:1:1:0:0:0:0:2 > 10:0:0:0:0:2:2:2 +< zx0 ip6/0 1 0 255 10:1:1:0:0:0:0:0 > 10:0:0:0:0:3:4:5 +< zx0 ip6/0 1 0 255 10:1:1:0:0:0:0:1 > 10:0:0:0:0:3:4:5 +< zx0 ip6/0 1 0 255 10:1:1:0:0:0:0:2 > 10:0:0:0:0:3:4:5 +< zx0 ip6/0 20 0 6 10:1:1:0:0:0:0:1,1025 > 10:0:0:0:0:3:4:5,1025 +> zx0 ip6/0 88 0 58 10:0:0:0:0:3:4:1 > 10:4:3:0:0:0:0:2 +< zx0 ip6/0 88 0 58 10:4:3:0:0:0:0:2 > 10:0:0:0:0:2:2:2 +< zx0 ip6/0 88 0 58 10:4:3:0:0:0:0:2 > 10:0:0:0:0:3:4:3 +< zx0 ip6/0 88 0 58 10:4:3:0:0:0:0:2 > 10:0:0:0:0:3:4:5 +> zx0 ip6/0 1 0 34 10:0:0:0:0:3:4:1 > 10:4:3:0:0:0:0:2 +< zx0 ip6/0 1 0 34 10:4:3:0:0:0:0:2 > 10:0:0:0:0:3:4:4 +> zx0 ip6/0 1 0 34 10:0:0:0:0:3:4:1 > 10:4:3:0:0:0:0:4 +< zx0 ip6/0 1 0 34 10:4:3:0:0:0:0:4 > 10:0:0:0:0:3:4:5 +> zx0 ip6/0 1 0 34 10:0:0:0:0:3:4:2 > 10:4:3:0:0:0:0:4 +< zx0 ip6/0 1 0 34 10:4:3:0:0:0:0:4 > 10:0:0:0:0:3:4:6 +> zx0 ip6/0 1 0 35 10:0:0:0:0:3:4:2 > 10:4:3:0:0:0:0:4 +< zx0 ip6/0 1 0 35 10:4:3:0:0:0:0:4 > 10:0:0:0:0:3:4:7 +> zx0 ip6/0 20 0 6 10:1:1:0:0:0:0:1,1025 > 10:1:1:0:0:0:0:1,1025 +> zx0 ip6/0 20 0 6 10:1:1:0:0:0:0:1,1025 > 10:1:1:0:0:0:0:2,1025 +> zx0 ip6/0 1 0 41 10:1:1:0:0:0:0:0 > 10:1:1:0:0:0:0:2 +> zx0 ip6/0 1 0 41 10:1:1:0:0:0:0:1 > 10:1:2:0:0:0:0:1 +> zx0 ip6/0 20 0 6 10:1:1:0:0:0:0:2,1025 > 10:1:1:0:0:0:0:1,1025 +> zx0 ip6/0 20 0 6 10:1:1:0:0:0:0:2,1025 > 10:1:1:0:0:0:0:1,1025 +> zx0 ip6/0 20 0 6 10:1:1:0:0:0:0:2,1026 > 10:1:1:0:0:0:0:1,1025 +> zx0 ip6/0 8 0 17 10:1:1:0:0:0:0:2,1025 > 10:1:1:0:0:0:0:1,1025 +> zx0 ip6/0 20 0 6 10:1:1:0:0:0:0:3,2000 > 10:1:2:0:0:0:0:1,80 +> zx0 ip6/0 20 0 6 10:1:1:0:0:0:0:3,2001 > 10:1:3:0:0:0:0:1,80 +> zx0 ip6/0 20 0 6 10:1:1:0:0:0:0:3,2002 > 10:1:4:0:0:0:0:1,80 +> zx0 ip6/0 20 0 6 10:1:1:0:0:0:0:3,2003 > 10:1:4:0:0:0:0:1,80 +< zx0 ip6/0 1 0 41 10:1:1:0:0:0:0:1 > 10:1:1:0:0:0:0:2 +< zx0 ip6/0 20 0 6 10:1:1:0:0:0:0:1,1025 > 10:1:1:0:0:0:0:2,1025 +< zx0 ip6/0 1 0 41 10:1:1:0:0:0:0:2 > 10:1:1:0:0:0:0:1 +> zx0 ip6/0 20 0 6 10:0:0:0:0:3:4:3,1026 > 10:0:0:0:0:3:4:5,40000 +< zx0 ip6/0 20 0 6 10:1:1:0:0:0:0:1,1026 > 10:0:0:0:0:3:4:5,40000 +> zx0 ip6/0 20 0 6 10:0:0:0:0:3:4:3,1025 > 10:0:0:0:0:3:4:5,40000 +< zx0 ip6/0 20 0 6 10:1:1:0:0:0:0:1,1025 > 10:0:0:0:0:3:4:5,40000 +> zx0 ip6/0 8 0 17 10:0:0:0:0:3:4:3,1025 > 10:0:0:0:0:3:4:5,40001 +< zx0 ip6/0 8 0 17 10:1:1:0:0:0:0:2,1025 > 10:0:0:0:0:3:4:5,40001 +> zx0 ip6/0 20 0 6 10:1:2:0:0:0:0:1,80 > 10:0:0:0:0:3:4:5,40001 +< zx0 ip6/0 20 0 6 10:1:2:0:0:0:0:1,80 > 10:0:0:0:0:3:4:5,40001 +List of active MAP/Redirect filters: +map zx0 inet6 from 10:1:1::/112 ! to 10:1::/32 -> 10::3:4:0/112 + +List of active sessions: +MAP 10:1:1::2 1025 <- -> 10::3:4:3 1025 [10::3:4:5 40001] +MAP 10:1:1::1 1025 <- -> 10::3:4:3 1025 [10::3:4:5 40000] +MAP 10:1:1::1 1026 <- -> 10::3:4:3 1026 [10::3:4:5 40000] +MAP 10:1:1::3 <- -> 10::3:4:2 [10:4:3::4] +MAP 10:1:1::3 <- -> 10::3:4:2 [10:4:3::4] +MAP 10:1:1::2 <- -> 10::3:4:1 [10:4:3::4] +MAP 10:1:1::2 <- -> 10::3:4:1 [10:4:3::2] +MAP 10:1:1::1 <- -> 10::3:4:1 [10:4:3::2] + +Hostmap table: +10:1:1::2,10::3:4:5 -> 10::3:4:3,any (use = 1) +10:1:1::1,10::3:4:5 -> 10::3:4:3,any (use = 2) +10:1:1::3,10:4:3::4 -> 10::3:4:2,any (use = 2) +10:1:1::2,10:4:3::4 -> 10::3:4:1,any (use = 1) +10:1:1::2,10:4:3::2 -> 10::3:4:1,any (use = 1) +10:1:1::1,10:4:3::2 -> 10::3:4:1,any (use = 1) +List of active state sessions: +List of configured pools +List of configured hash tables +List of groups configured (set 0) +List of groups configured (set 1) +Rules configured (set 0, in) +Rules configured (set 0, out) +Rules configured (set 1, in) +Rules configured (set 1, out) +Accounting rules configured (set 0, in) +Accounting rules configured (set 0, out) +Accounting rules configured (set 1, in) +Accounting rules configured (set 1, out) +------------------------------- +> zx0 ip6/0 1 0 255 10:1:1:0:0:0:0:0 > 10:1:1:0:0:0:0:2 +> zx0 ip6/0 1 0 255 10:1:1:0:0:0:0:1 > 10:1:1:0:0:0:0:2 +> zx0 ip6/0 1 0 255 10:1:1:0:0:0:0:2 > 10:1:1:0:0:0:0:1 +> zx0 ip6/0 20 0 6 10:1:1:0:0:0:0:2,1025 > 10:1:1:0:0:0:0:1,1025 +> zx0 ip6/0 20 0 6 10:1:1:0:0:0:0:2,1026 > 10:1:1:0:0:0:0:1,1025 +> zx0 ip6/0 1 0 255 10:0:0:0:0:2:2:1 > 10:1:2:0:0:0:0:1 +> zx0 ip6/0 1 0 255 10:0:0:0:0:2:2:2 > 10:1:2:0:0:0:0:1 +< zx0 ip6/0 1 0 255 10:1:1:0:0:0:0:1 > 10:1:1:0:0:0:0:2 +< zx0 ip6/0 1 0 255 10:1:1:0:0:0:0:2 > 10:1:1:0:0:0:0:1 +< zx0 ip6/0 1 0 255 10:0:0:0:0:2:2:1 > 10:0:0:0:0:2:1:1 +< zx0 ip6/0 1 0 255 10:0:0:0:0:2:2:2 > 10:0:0:0:0:2:1:1 +< zx0 ip6/0 1 0 255 10:0:0:0:0:2:2:3 > 10:1:1:0:0:0:0:1 +< zx0 ip6/0 1 0 255 10:0:0:0:0:2:3:4 > 10:0:0:0:0:2:2:2 +< zx0 ip6/0 1 0 255 10:1:1:0:0:0:0:1 > 10:0:0:0:0:2:2:2 +< zx0 ip6/0 1 0 255 10:1:1:0:0:0:0:2 > 10:0:0:0:0:2:2:2 +< zx0 ip6/0 1 0 255 10:1:1:0:0:0:0:0 > 10:0:0:0:0:3:4:5 +< zx0 ip6/0 1 0 255 10:1:1:0:0:0:0:1 > 10:0:0:0:0:3:4:5 +< zx0 ip6/0 1 0 255 10:1:1:0:0:0:0:2 > 10:0:0:0:0:3:4:5 +< zx0 ip6/0 20 0 6 10:1:1:0:0:0:0:1,1025 > 10:0:0:0:0:3:4:5,1025 +> zx0 ip6/0 88 0 58 10:1:1:0:0:0:0:1 > 10:4:3:0:0:0:0:2 +< zx0 ip6/0 88 0 58 10:4:3:0:0:0:0:2 > 10:0:0:0:0:2:2:2 +< zx0 ip6/0 88 0 58 10:4:3:0:0:0:0:2 > 10:0:0:0:0:3:4:3 +< zx0 ip6/0 88 0 58 10:4:3:0:0:0:0:2 > 10:0:0:0:0:3:4:5 +> zx0 ip6/0 1 0 34 10:1:1:0:0:0:0:2 > 10:4:3:0:0:0:0:2 +< zx0 ip6/0 1 0 34 10:4:3:0:0:0:0:2 > 10:0:0:0:0:3:4:4 +> zx0 ip6/0 1 0 34 10:1:1:0:0:0:0:2 > 10:4:3:0:0:0:0:4 +< zx0 ip6/0 1 0 34 10:4:3:0:0:0:0:4 > 10:0:0:0:0:3:4:5 +> zx0 ip6/0 1 0 34 10:1:1:0:0:0:0:3 > 10:4:3:0:0:0:0:4 +< zx0 ip6/0 1 0 34 10:4:3:0:0:0:0:4 > 10:0:0:0:0:3:4:6 +> zx0 ip6/0 1 0 35 10:1:1:0:0:0:0:3 > 10:4:3:0:0:0:0:4 +< zx0 ip6/0 1 0 35 10:4:3:0:0:0:0:4 > 10:0:0:0:0:3:4:7 +> zx0 ip6/0 20 0 6 10:1:1:0:0:0:0:1,1025 > 10:1:1:0:0:0:0:1,1025 +> zx0 ip6/0 20 0 6 10:1:1:0:0:0:0:1,1025 > 10:1:1:0:0:0:0:2,1025 +> zx0 ip6/0 1 0 41 10:1:1:0:0:0:0:0 > 10:1:1:0:0:0:0:2 +> zx0 ip6/0 1 0 41 10:1:1:0:0:0:0:1 > 10:1:2:0:0:0:0:1 +> zx0 ip6/0 20 0 6 10:1:1:0:0:0:0:2,1025 > 10:1:1:0:0:0:0:1,1025 +> zx0 ip6/0 20 0 6 10:1:1:0:0:0:0:2,1025 > 10:1:1:0:0:0:0:1,1025 +> zx0 ip6/0 20 0 6 10:1:1:0:0:0:0:2,1026 > 10:1:1:0:0:0:0:1,1025 +> zx0 ip6/0 8 0 17 10:0:0:0:0:3:4:5,10000 > 10:1:1:0:0:0:0:1,1025 +> zx0 ip6/0 20 0 6 10:1:1:0:0:0:0:3,2000 > 10:1:2:0:0:0:0:1,80 +> zx0 ip6/0 20 0 6 10:1:1:0:0:0:0:3,2001 > 10:1:3:0:0:0:0:1,80 +> zx0 ip6/0 20 0 6 10:1:1:0:0:0:0:3,2002 > 10:1:4:0:0:0:0:1,80 +> zx0 ip6/0 20 0 6 10:1:1:0:0:0:0:3,2003 > 10:1:4:0:0:0:0:1,80 +< zx0 ip6/0 1 0 41 10:1:1:0:0:0:0:1 > 10:1:1:0:0:0:0:2 +< zx0 ip6/0 20 0 6 10:1:1:0:0:0:0:1,1025 > 10:1:1:0:0:0:0:2,1025 +< zx0 ip6/0 1 0 41 10:1:1:0:0:0:0:2 > 10:1:1:0:0:0:0:1 +> zx0 ip6/0 20 0 6 10:1:1:0:0:0:0:1,1026 > 10:0:0:0:0:3:4:5,40000 +< zx0 ip6/0 20 0 6 10:1:1:0:0:0:0:1,1026 > 10:0:0:0:0:3:4:5,40000 +> zx0 ip6/0 20 0 6 10:1:1:0:0:0:0:1,1025 > 10:0:0:0:0:3:4:5,40000 +< zx0 ip6/0 20 0 6 10:1:1:0:0:0:0:1,1025 > 10:0:0:0:0:3:4:5,40000 +> zx0 ip6/0 8 0 17 10:0:0:0:0:3:4:5,10001 > 10:0:0:0:0:3:4:5,40001 +< zx0 ip6/0 8 0 17 10:1:1:0:0:0:0:2,1025 > 10:0:0:0:0:3:4:5,40001 +> zx0 ip6/0 20 0 6 10:1:2:0:0:0:0:1,80 > 10:0:0:0:0:3:4:5,40001 +< zx0 ip6/0 20 0 6 10:1:2:0:0:0:0:1,80 > 10:0:0:0:0:3:4:5,40001 +List of active MAP/Redirect filters: +map zx0 inet6 10:1:1::/112 -> 10::3:4:5/128 portmap udp 10000:20000 sequential + +List of active sessions: +MAP 10:1:1::2 1025 <- -> 10::3:4:5 10001 [10::3:4:5 40001] +MAP 10:1:1::2 1025 <- -> 10::3:4:5 10000 [10:1:1::1 1025] + +Hostmap table: +10:1:1::2,10::3:4:5 -> 10::3:4:5,any (use = 1) +10:1:1::2,10:1:1::1 -> 10::3:4:5,any (use = 1) +List of active state sessions: +List of configured pools +List of configured hash tables +List of groups configured (set 0) +List of groups configured (set 1) +Rules configured (set 0, in) +Rules configured (set 0, out) +Rules configured (set 1, in) +Rules configured (set 1, out) +Accounting rules configured (set 0, in) +Accounting rules configured (set 0, out) +Accounting rules configured (set 1, in) +Accounting rules configured (set 1, out) +------------------------------- +> zx0 ip6/0 1 0 255 10:1:1:0:0:0:0:0 > 10:1:1:0:0:0:0:2 +> zx0 ip6/0 1 0 255 10:1:1:0:0:0:0:1 > 10:1:1:0:0:0:0:2 +> zx0 ip6/0 1 0 255 10:1:1:0:0:0:0:2 > 10:1:1:0:0:0:0:1 +> zx0 ip6/0 20 0 6 10:0:0:0:0:3:4:1,10000 > 10:1:1:0:0:0:0:1,1025 +> zx0 ip6/0 20 0 6 10:0:0:0:0:3:4:1,10001 > 10:1:1:0:0:0:0:1,1025 +> zx0 ip6/0 1 0 255 10:0:0:0:0:2:2:1 > 10:1:2:0:0:0:0:1 +> zx0 ip6/0 1 0 255 10:0:0:0:0:2:2:2 > 10:1:2:0:0:0:0:1 +< zx0 ip6/0 1 0 255 10:1:1:0:0:0:0:1 > 10:1:1:0:0:0:0:2 +< zx0 ip6/0 1 0 255 10:1:1:0:0:0:0:2 > 10:1:1:0:0:0:0:1 +< zx0 ip6/0 1 0 255 10:0:0:0:0:2:2:1 > 10:0:0:0:0:2:1:1 +< zx0 ip6/0 1 0 255 10:0:0:0:0:2:2:2 > 10:0:0:0:0:2:1:1 +< zx0 ip6/0 1 0 255 10:0:0:0:0:2:2:3 > 10:1:1:0:0:0:0:1 +< zx0 ip6/0 1 0 255 10:0:0:0:0:2:3:4 > 10:0:0:0:0:2:2:2 +< zx0 ip6/0 1 0 255 10:1:1:0:0:0:0:1 > 10:0:0:0:0:2:2:2 +< zx0 ip6/0 1 0 255 10:1:1:0:0:0:0:2 > 10:0:0:0:0:2:2:2 +< zx0 ip6/0 1 0 255 10:1:1:0:0:0:0:0 > 10:0:0:0:0:3:4:5 +< zx0 ip6/0 1 0 255 10:1:1:0:0:0:0:1 > 10:0:0:0:0:3:4:5 +< zx0 ip6/0 1 0 255 10:1:1:0:0:0:0:2 > 10:0:0:0:0:3:4:5 +< zx0 ip6/0 20 0 6 10:1:1:0:0:0:0:1,1025 > 10:0:0:0:0:3:4:5,1025 +> zx0 ip6/0 88 0 58 10:1:1:0:0:0:0:1 > 10:4:3:0:0:0:0:2 +< zx0 ip6/0 88 0 58 10:4:3:0:0:0:0:2 > 10:0:0:0:0:2:2:2 +< zx0 ip6/0 88 0 58 10:4:3:0:0:0:0:2 > 10:0:0:0:0:3:4:3 +< zx0 ip6/0 88 0 58 10:4:3:0:0:0:0:2 > 10:0:0:0:0:3:4:5 +> zx0 ip6/0 1 0 34 10:1:1:0:0:0:0:2 > 10:4:3:0:0:0:0:2 +< zx0 ip6/0 1 0 34 10:4:3:0:0:0:0:2 > 10:0:0:0:0:3:4:4 +> zx0 ip6/0 1 0 34 10:1:1:0:0:0:0:2 > 10:4:3:0:0:0:0:4 +< zx0 ip6/0 1 0 34 10:4:3:0:0:0:0:4 > 10:0:0:0:0:3:4:5 +> zx0 ip6/0 1 0 34 10:1:1:0:0:0:0:3 > 10:4:3:0:0:0:0:4 +< zx0 ip6/0 1 0 34 10:4:3:0:0:0:0:4 > 10:0:0:0:0:3:4:6 +> zx0 ip6/0 1 0 35 10:1:1:0:0:0:0:3 > 10:4:3:0:0:0:0:4 +< zx0 ip6/0 1 0 35 10:4:3:0:0:0:0:4 > 10:0:0:0:0:3:4:7 +> zx0 ip6/0 20 0 6 10:0:0:0:0:3:4:1,10002 > 10:1:1:0:0:0:0:1,1025 +> zx0 ip6/0 20 0 6 10:0:0:0:0:3:4:1,10003 > 10:1:1:0:0:0:0:2,1025 +> zx0 ip6/0 1 0 41 10:1:1:0:0:0:0:0 > 10:1:1:0:0:0:0:2 +> zx0 ip6/0 1 0 41 10:1:1:0:0:0:0:1 > 10:1:2:0:0:0:0:1 +> zx0 ip6/0 20 0 6 10:0:0:0:0:3:4:1,10000 > 10:1:1:0:0:0:0:1,1025 +> zx0 ip6/0 20 0 6 10:0:0:0:0:3:4:1,10000 > 10:1:1:0:0:0:0:1,1025 +> zx0 ip6/0 20 0 6 10:0:0:0:0:3:4:1,10001 > 10:1:1:0:0:0:0:1,1025 +> zx0 ip6/0 8 0 17 10:0:0:0:0:3:4:1,10004 > 10:1:1:0:0:0:0:1,1025 +> zx0 ip6/0 20 0 6 10:0:0:0:0:3:4:1,10005 > 10:1:2:0:0:0:0:1,80 +> zx0 ip6/0 20 0 6 10:0:0:0:0:3:4:1,10006 > 10:1:3:0:0:0:0:1,80 +> zx0 ip6/0 20 0 6 10:0:0:0:0:3:4:1,10007 > 10:1:4:0:0:0:0:1,80 +> zx0 ip6/0 20 0 6 10:0:0:0:0:3:4:1,10008 > 10:1:4:0:0:0:0:1,80 +< zx0 ip6/0 1 0 41 10:1:1:0:0:0:0:1 > 10:1:1:0:0:0:0:2 +< zx0 ip6/0 20 0 6 10:1:1:0:0:0:0:1,1025 > 10:1:1:0:0:0:0:2,1025 +< zx0 ip6/0 1 0 41 10:1:1:0:0:0:0:2 > 10:1:1:0:0:0:0:1 +> zx0 ip6/0 20 0 6 10:0:0:0:0:3:4:1,10009 > 10:0:0:0:0:3:4:5,40000 +< zx0 ip6/0 20 0 6 10:1:1:0:0:0:0:1,1026 > 10:0:0:0:0:3:4:5,40000 +> zx0 ip6/0 20 0 6 10:0:0:0:0:3:4:1,10010 > 10:0:0:0:0:3:4:5,40000 +< zx0 ip6/0 20 0 6 10:1:1:0:0:0:0:1,1025 > 10:0:0:0:0:3:4:5,40000 +> zx0 ip6/0 8 0 17 10:0:0:0:0:3:4:1,10011 > 10:0:0:0:0:3:4:5,40001 +< zx0 ip6/0 8 0 17 10:1:1:0:0:0:0:2,1025 > 10:0:0:0:0:3:4:5,40001 +> zx0 ip6/0 20 0 6 10:0:0:0:0:3:4:1,10012 > 10:0:0:0:0:3:4:5,40001 +< zx0 ip6/0 20 0 6 10:1:2:0:0:0:0:1,80 > 10:0:0:0:0:3:4:5,40001 +List of active MAP/Redirect filters: +map zx0 inet6 10:1::/32 -> 10::3:4:0/112 portmap tcp/udp 10000:20000 sequential + +List of active sessions: +MAP 10:1:2::1 80 <- -> 10::3:4:1 10012 [10::3:4:5 40001] +MAP 10:1:1::2 1025 <- -> 10::3:4:1 10011 [10::3:4:5 40001] +MAP 10:1:1::1 1025 <- -> 10::3:4:1 10010 [10::3:4:5 40000] +MAP 10:1:1::1 1026 <- -> 10::3:4:1 10009 [10::3:4:5 40000] +MAP 10:1:1::3 2003 <- -> 10::3:4:1 10008 [10:1:4::1 80] +MAP 10:1:1::3 2002 <- -> 10::3:4:1 10007 [10:1:4::1 80] +MAP 10:1:1::3 2001 <- -> 10::3:4:1 10006 [10:1:3::1 80] +MAP 10:1:1::3 2000 <- -> 10::3:4:1 10005 [10:1:2::1 80] +MAP 10:1:1::2 1025 <- -> 10::3:4:1 10004 [10:1:1::1 1025] +MAP 10:1:1::1 1025 <- -> 10::3:4:1 10003 [10:1:1::2 1025] +MAP 10:1:1::1 1025 <- -> 10::3:4:1 10002 [10:1:1::1 1025] +MAP 10:1:1::2 1026 <- -> 10::3:4:1 10001 [10:1:1::1 1025] +MAP 10:1:1::2 1025 <- -> 10::3:4:1 10000 [10:1:1::1 1025] + +Hostmap table: +10:1:2::1,10::3:4:5 -> 10::3:4:1,any (use = 1) +10:1:1::2,10::3:4:5 -> 10::3:4:1,any (use = 1) +10:1:1::1,10::3:4:5 -> 10::3:4:1,any (use = 2) +10:1:1::3,10:1:4::1 -> 10::3:4:1,any (use = 2) +10:1:1::3,10:1:3::1 -> 10::3:4:1,any (use = 1) +10:1:1::3,10:1:2::1 -> 10::3:4:1,any (use = 1) +10:1:1::1,10:1:1::2 -> 10::3:4:1,any (use = 1) +10:1:1::1,10:1:1::1 -> 10::3:4:1,any (use = 1) +10:1:1::2,10:1:1::1 -> 10::3:4:1,any (use = 3) +List of active state sessions: +List of configured pools +List of configured hash tables +List of groups configured (set 0) +List of groups configured (set 1) +Rules configured (set 0, in) +Rules configured (set 0, out) +Rules configured (set 1, in) +Rules configured (set 1, out) +Accounting rules configured (set 0, in) +Accounting rules configured (set 0, out) +Accounting rules configured (set 1, in) +Accounting rules configured (set 1, out) +------------------------------- +> zx0 ip6/0 1 0 255 10:1:1:0:0:0:0:0 > 10:1:1:0:0:0:0:2 +> zx0 ip6/0 1 0 255 10:1:1:0:0:0:0:1 > 10:1:1:0:0:0:0:2 +> zx0 ip6/0 1 0 255 10:1:1:0:0:0:0:2 > 10:1:1:0:0:0:0:1 +> zx0 ip6/0 20 0 6 10:0:0:0:0:3:4:5,40000 > 10:1:1:0:0:0:0:1,1025 +> zx0 ip6/0 20 0 6 10:0:0:0:0:3:4:5,40001 > 10:1:1:0:0:0:0:1,1025 +> zx0 ip6/0 1 0 255 10:0:0:0:0:2:2:1 > 10:1:2:0:0:0:0:1 +> zx0 ip6/0 1 0 255 10:0:0:0:0:2:2:2 > 10:1:2:0:0:0:0:1 +< zx0 ip6/0 1 0 255 10:1:1:0:0:0:0:1 > 10:1:1:0:0:0:0:2 +< zx0 ip6/0 1 0 255 10:1:1:0:0:0:0:2 > 10:1:1:0:0:0:0:1 +< zx0 ip6/0 1 0 255 10:0:0:0:0:2:2:1 > 10:0:0:0:0:2:1:1 +< zx0 ip6/0 1 0 255 10:0:0:0:0:2:2:2 > 10:0:0:0:0:2:1:1 +< zx0 ip6/0 1 0 255 10:0:0:0:0:2:2:3 > 10:1:1:0:0:0:0:1 +< zx0 ip6/0 1 0 255 10:0:0:0:0:2:3:4 > 10:0:0:0:0:2:2:2 +< zx0 ip6/0 1 0 255 10:1:1:0:0:0:0:1 > 10:0:0:0:0:2:2:2 +< zx0 ip6/0 1 0 255 10:1:1:0:0:0:0:2 > 10:0:0:0:0:2:2:2 +< zx0 ip6/0 1 0 255 10:1:1:0:0:0:0:0 > 10:0:0:0:0:3:4:5 +< zx0 ip6/0 1 0 255 10:1:1:0:0:0:0:1 > 10:0:0:0:0:3:4:5 +< zx0 ip6/0 1 0 255 10:1:1:0:0:0:0:2 > 10:0:0:0:0:3:4:5 +< zx0 ip6/0 20 0 6 10:1:1:0:0:0:0:1,1025 > 10:0:0:0:0:3:4:5,1025 +> zx0 ip6/0 88 0 58 10:1:1:0:0:0:0:1 > 10:4:3:0:0:0:0:2 +< zx0 ip6/0 88 0 58 10:4:3:0:0:0:0:2 > 10:0:0:0:0:2:2:2 +< zx0 ip6/0 88 0 58 10:4:3:0:0:0:0:2 > 10:0:0:0:0:3:4:3 +< zx0 ip6/0 88 0 58 10:4:3:0:0:0:0:2 > 10:0:0:0:0:3:4:5 +> zx0 ip6/0 1 0 34 10:1:1:0:0:0:0:2 > 10:4:3:0:0:0:0:2 +< zx0 ip6/0 1 0 34 10:4:3:0:0:0:0:2 > 10:0:0:0:0:3:4:4 +> zx0 ip6/0 1 0 34 10:1:1:0:0:0:0:2 > 10:4:3:0:0:0:0:4 +< zx0 ip6/0 1 0 34 10:4:3:0:0:0:0:4 > 10:0:0:0:0:3:4:5 +> zx0 ip6/0 1 0 34 10:1:1:0:0:0:0:3 > 10:4:3:0:0:0:0:4 +< zx0 ip6/0 1 0 34 10:4:3:0:0:0:0:4 > 10:0:0:0:0:3:4:6 +> zx0 ip6/0 1 0 35 10:1:1:0:0:0:0:3 > 10:4:3:0:0:0:0:4 +< zx0 ip6/0 1 0 35 10:4:3:0:0:0:0:4 > 10:0:0:0:0:3:4:7 +16 +> zx0 ip6/0 20 0 6 10:0:0:0:0:3:4:5,40000 > 10:1:1:0:0:0:0:2,1025 +> zx0 ip6/0 1 0 41 10:1:1:0:0:0:0:0 > 10:1:1:0:0:0:0:2 +> zx0 ip6/0 1 0 41 10:1:1:0:0:0:0:1 > 10:1:2:0:0:0:0:1 +> zx0 ip6/0 20 0 6 10:0:0:0:0:3:4:5,40000 > 10:1:1:0:0:0:0:1,1025 +> zx0 ip6/0 20 0 6 10:0:0:0:0:3:4:5,40000 > 10:1:1:0:0:0:0:1,1025 +> zx0 ip6/0 20 0 6 10:0:0:0:0:3:4:5,40001 > 10:1:1:0:0:0:0:1,1025 +> zx0 ip6/0 8 0 17 10:0:0:0:0:3:4:5,40001 > 10:1:1:0:0:0:0:1,1025 +> zx0 ip6/0 20 0 6 10:0:0:0:0:3:4:5,40000 > 10:1:2:0:0:0:0:1,80 +> zx0 ip6/0 20 0 6 10:0:0:0:0:3:4:5,40001 > 10:1:3:0:0:0:0:1,80 +> zx0 ip6/0 20 0 6 10:0:0:0:0:3:4:5,40000 > 10:1:4:0:0:0:0:1,80 +> zx0 ip6/0 20 0 6 10:0:0:0:0:3:4:5,40001 > 10:1:4:0:0:0:0:1,80 +< zx0 ip6/0 1 0 41 10:1:1:0:0:0:0:1 > 10:1:1:0:0:0:0:2 +< zx0 ip6/0 20 0 6 10:1:1:0:0:0:0:1,1025 > 10:1:1:0:0:0:0:2,1025 +< zx0 ip6/0 1 0 41 10:1:1:0:0:0:0:2 > 10:1:1:0:0:0:0:1 +> zx0 ip6/0 20 0 6 10:0:0:0:0:3:4:5,40000 > 10:0:0:0:0:3:4:5,40000 +< zx0 ip6/0 20 0 6 10:1:1:0:0:0:0:1,1026 > 10:0:0:0:0:3:4:5,40000 +> zx0 ip6/0 20 0 6 10:0:0:0:0:3:4:5,40001 > 10:0:0:0:0:3:4:5,40000 +< zx0 ip6/0 20 0 6 10:1:1:0:0:0:0:1,1025 > 10:1:1:0:0:0:0:2,1025 +> zx0 ip6/0 8 0 17 10:0:0:0:0:3:4:5,40000 > 10:0:0:0:0:3:4:5,40001 +< zx0 ip6/0 8 0 17 10:1:1:0:0:0:0:2,1025 > 10:0:0:0:0:3:4:5,40001 +> zx0 ip6/0 20 0 6 10:1:2:0:0:0:0:1,80 > 10:0:0:0:0:3:4:5,40001 +< zx0 ip6/0 20 0 6 10:1:2:0:0:0:0:1,80 > 10:0:0:0:0:3:4:5,40001 +List of active MAP/Redirect filters: +map zx0 inet6 10:1:1::/112 -> 10::3:4:5/128 portmap tcp/udp 40000:40001 sequential + +List of active sessions: +MAP 10:1:1::2 1025 <- -> 10::3:4:5 40000 [10::3:4:5 40001] +MAP 10:1:1::1 1025 <- -> 10::3:4:5 40001 [10::3:4:5 40000] +MAP 10:1:1::1 1026 <- -> 10::3:4:5 40000 [10::3:4:5 40000] +MAP 10:1:1::3 2003 <- -> 10::3:4:5 40001 [10:1:4::1 80] +MAP 10:1:1::3 2002 <- -> 10::3:4:5 40000 [10:1:4::1 80] +MAP 10:1:1::3 2001 <- -> 10::3:4:5 40001 [10:1:3::1 80] +MAP 10:1:1::3 2000 <- -> 10::3:4:5 40000 [10:1:2::1 80] +MAP 10:1:1::2 1025 <- -> 10::3:4:5 40001 [10:1:1::1 1025] +MAP 10:1:1::1 1025 <- -> 10::3:4:5 40000 [10:1:1::2 1025] +MAP 10:1:1::2 1026 <- -> 10::3:4:5 40001 [10:1:1::1 1025] +MAP 10:1:1::2 1025 <- -> 10::3:4:5 40000 [10:1:1::1 1025] + +Hostmap table: +10:1:1::2,10::3:4:5 -> 10::3:4:5,any (use = 1) +10:1:1::1,10::3:4:5 -> 10::3:4:5,any (use = 2) +10:1:1::3,10:1:4::1 -> 10::3:4:5,any (use = 2) +10:1:1::3,10:1:3::1 -> 10::3:4:5,any (use = 1) +10:1:1::3,10:1:2::1 -> 10::3:4:5,any (use = 1) +10:1:1::1,10:1:1::2 -> 10::3:4:5,any (use = 1) +10:1:1::2,10:1:1::1 -> 10::3:4:5,any (use = 3) +List of active state sessions: +List of configured pools +List of configured hash tables +List of groups configured (set 0) +List of groups configured (set 1) +Rules configured (set 0, in) +Rules configured (set 0, out) +Rules configured (set 1, in) +Rules configured (set 1, out) +Accounting rules configured (set 0, in) +Accounting rules configured (set 0, out) +Accounting rules configured (set 1, in) +Accounting rules configured (set 1, out) +------------------------------- diff --git a/contrib/ipfilter/test/expected/n6 b/contrib/ipfilter/test/expected/n6 index cbdad9f1388e..1afd94e54e46 100644 --- a/contrib/ipfilter/test/expected/n6 +++ b/contrib/ipfilter/test/expected/n6 @@ -1,70 +1,173 @@ -ip #0 40(20) 6 10.2.2.2,12345 > 10.2.2.1,10023 -ip #0 40(20) 6 10.2.2.2,12345 > 10.1.1.2,23 -ip #0 40(20) 6 10.3.0.1,12345 > 10.1.2.2,23 -ip #0 40(20) 6 10.3.0.1,12345 > 10.2.2.2,23 -ip #0 40(20) 6 10.3.3.3,12345 > 10.2.2.1,10023 -ip #0 40(20) 6 10.2.2.2,12345 > 10.1.1.1,53 -ip #0 40(20) 6 10.3.3.3,12345 > 10.1.1.1,53 -ip #0 40(20) 6 10.2.2.2,12345 > 10.1.0.0,23 -ip #0 40(20) 6 10.3.3.3,12345 > 10.1.0.0,23 -ip #0 28(20) 17 10.2.2.2,12345 > 10.1.1.0,53 -ip #0 28(20) 17 10.3.3.3,12345 > 10.1.1.0,53 -ip #0 40(20) 6 10.2.2.2,12345 > 10.1.1.0,53 -ip #0 40(20) 6 10.3.3.3,12345 > 10.1.1.0,53 +< zx0 ip #0 40(20) 6 10.2.2.2,12345 > 10.2.2.1,10023 +< zx0 ip #0 40(20) 6 10.2.2.2,12345 > 10.1.1.2,23 +< zx0 ip #0 40(20) 6 10.3.0.1,12345 > 10.1.2.2,23 +< zx0 ip #0 40(20) 6 10.3.0.1,12345 > 10.2.2.2,23 +< zx0 ip #0 40(20) 6 10.3.3.3,12345 > 10.2.2.1,10023 +< zx0 ip #0 40(20) 6 10.2.2.2,12345 > 10.1.1.1,53 +< zx0 ip #0 40(20) 6 10.3.3.3,12345 > 10.1.1.1,53 +< zx0 ip #0 40(20) 6 10.2.2.2,12345 > 10.1.0.0,23 +< zx0 ip #0 40(20) 6 10.3.3.3,12345 > 10.1.0.0,23 +< zx0 ip #0 28(20) 17 10.2.2.2,12345 > 10.1.1.0,53 +< zx0 ip #0 28(20) 17 10.3.3.3,12345 > 10.1.1.0,53 +< zx0 ip #0 40(20) 6 10.2.2.2,12345 > 10.1.1.0,53 +< zx0 ip #0 40(20) 6 10.3.3.3,12345 > 10.1.1.0,53 +List of active MAP/Redirect filters: +rdr zx0 10.1.1.1/32 port 23 -> 10.2.2.1/32 port 10023 tcp + +List of active sessions: +RDR 10.2.2.1 10023 <- -> 10.1.1.1 23 [10.3.3.3 12345] +RDR 10.2.2.1 10023 <- -> 10.1.1.1 23 [10.2.2.2 12345] + +Hostmap table: +List of active state sessions: +List of configured pools +List of configured hash tables +List of groups configured (set 0) +List of groups configured (set 1) +Rules configured (set 0, in) +Rules configured (set 0, out) +Rules configured (set 1, in) +Rules configured (set 1, out) +Accounting rules configured (set 0, in) +Accounting rules configured (set 0, out) +Accounting rules configured (set 1, in) +Accounting rules configured (set 1, out) ------------------------------- -ip #0 40(20) 6 10.2.2.2,12345 > 10.2.2.1,10023 -ip #0 40(20) 6 10.2.2.2,12345 > 10.1.1.2,23 -ip #0 40(20) 6 10.3.0.1,12345 > 10.1.2.2,23 -ip #0 40(20) 6 10.3.0.1,12345 > 10.2.2.2,23 -ip #0 40(20) 6 10.3.3.3,12345 > 10.2.2.1,10023 -ip #0 40(20) 6 10.2.2.2,12345 > 10.1.1.1,53 -ip #0 40(20) 6 10.3.3.3,12345 > 10.1.1.1,53 -ip #0 40(20) 6 10.2.2.2,12345 > 10.1.0.0,23 -ip #0 40(20) 6 10.3.3.3,12345 > 10.1.0.0,23 -ip #0 28(20) 17 10.2.2.2,12345 > 10.1.1.0,53 -ip #0 28(20) 17 10.3.3.3,12345 > 10.1.1.0,53 -ip #0 40(20) 6 10.2.2.2,12345 > 10.1.1.0,53 -ip #0 40(20) 6 10.3.3.3,12345 > 10.1.1.0,53 +< zx0 ip #0 40(20) 6 10.2.2.2,12345 > 10.2.2.1,10023 +15 +< zx0 ip #0 40(20) 6 10.3.0.1,12345 > 10.1.2.2,23 +< zx0 ip #0 40(20) 6 10.3.0.1,12345 > 10.2.2.2,23 +< zx0 ip #0 40(20) 6 10.3.3.3,12345 > 10.2.2.1,10023 +< zx0 ip #0 40(20) 6 10.2.2.2,12345 > 10.1.1.1,53 +< zx0 ip #0 40(20) 6 10.3.3.3,12345 > 10.1.1.1,53 +< zx0 ip #0 40(20) 6 10.2.2.2,12345 > 10.1.0.0,23 +< zx0 ip #0 40(20) 6 10.3.3.3,12345 > 10.1.0.0,23 +< zx0 ip #0 28(20) 17 10.2.2.2,12345 > 10.1.1.0,53 +< zx0 ip #0 28(20) 17 10.3.3.3,12345 > 10.1.1.0,53 +< zx0 ip #0 40(20) 6 10.2.2.2,12345 > 10.1.1.0,53 +< zx0 ip #0 40(20) 6 10.3.3.3,12345 > 10.1.1.0,53 +List of active MAP/Redirect filters: +rdr zx0 from 0/0 to 10.1.1.0/24 port = 23 -> 10.2.2.1/32 port 10023 tcp + +List of active sessions: +RDR 10.2.2.1 10023 <- -> 10.1.1.1 23 [10.3.3.3 12345] +RDR 10.2.2.1 10023 <- -> 10.1.1.1 23 [10.2.2.2 12345] + +Hostmap table: +List of active state sessions: +List of configured pools +List of configured hash tables +List of groups configured (set 0) +List of groups configured (set 1) +Rules configured (set 0, in) +Rules configured (set 0, out) +Rules configured (set 1, in) +Rules configured (set 1, out) +Accounting rules configured (set 0, in) +Accounting rules configured (set 0, out) +Accounting rules configured (set 1, in) +Accounting rules configured (set 1, out) ------------------------------- -ip #0 40(20) 6 10.2.2.2,12345 > 10.2.2.1,10023 -ip #0 40(20) 6 10.2.2.2,12345 > 10.1.1.2,23 -ip #0 40(20) 6 10.3.0.1,12345 > 10.1.2.2,23 -ip #0 40(20) 6 10.3.0.1,12345 > 10.2.2.2,23 -ip #0 40(20) 6 10.3.3.3,12345 > 10.1.1.1,23 -ip #0 40(20) 6 10.2.2.2,12345 > 10.1.1.1,53 -ip #0 40(20) 6 10.3.3.3,12345 > 10.1.1.1,53 -ip #0 40(20) 6 10.2.2.2,12345 > 10.1.0.0,23 -ip #0 40(20) 6 10.3.3.3,12345 > 10.1.0.0,23 -ip #0 28(20) 17 10.2.2.2,12345 > 10.1.1.0,53 -ip #0 28(20) 17 10.3.3.3,12345 > 10.1.1.0,53 -ip #0 40(20) 6 10.2.2.2,12345 > 10.1.1.0,53 -ip #0 40(20) 6 10.3.3.3,12345 > 10.1.1.0,53 +< zx0 ip #0 40(20) 6 10.2.2.2,12345 > 10.2.2.1,10023 +15 +< zx0 ip #0 40(20) 6 10.3.0.1,12345 > 10.1.2.2,23 +< zx0 ip #0 40(20) 6 10.3.0.1,12345 > 10.2.2.2,23 +< zx0 ip #0 40(20) 6 10.3.3.3,12345 > 10.1.1.1,23 +< zx0 ip #0 40(20) 6 10.2.2.2,12345 > 10.1.1.1,53 +< zx0 ip #0 40(20) 6 10.3.3.3,12345 > 10.1.1.1,53 +< zx0 ip #0 40(20) 6 10.2.2.2,12345 > 10.1.0.0,23 +< zx0 ip #0 40(20) 6 10.3.3.3,12345 > 10.1.0.0,23 +< zx0 ip #0 28(20) 17 10.2.2.2,12345 > 10.1.1.0,53 +< zx0 ip #0 28(20) 17 10.3.3.3,12345 > 10.1.1.0,53 +< zx0 ip #0 40(20) 6 10.2.2.2,12345 > 10.1.1.0,53 +< zx0 ip #0 40(20) 6 10.3.3.3,12345 > 10.1.1.0,53 +List of active MAP/Redirect filters: +rdr zx0 from 10.2.0.0/16 to 10.1.1.0/24 port = 23 -> 10.2.2.1/32 port 10023 tcp + +List of active sessions: +RDR 10.2.2.1 10023 <- -> 10.1.1.1 23 [10.2.2.2 12345] + +Hostmap table: +List of active state sessions: +List of configured pools +List of configured hash tables +List of groups configured (set 0) +List of groups configured (set 1) +Rules configured (set 0, in) +Rules configured (set 0, out) +Rules configured (set 1, in) +Rules configured (set 1, out) +Accounting rules configured (set 0, in) +Accounting rules configured (set 0, out) +Accounting rules configured (set 1, in) +Accounting rules configured (set 1, out) ------------------------------- -ip #0 40(20) 6 10.2.2.2,12345 > 10.1.1.1,23 -ip #0 40(20) 6 10.2.2.2,12345 > 10.1.1.2,23 -ip #0 40(20) 6 10.3.0.1,12345 > 10.2.2.1,10023 -ip #0 40(20) 6 10.3.0.1,12345 > 10.2.2.2,23 -ip #0 40(20) 6 10.3.3.3,12345 > 10.2.2.1,10023 -ip #0 40(20) 6 10.2.2.2,12345 > 10.1.1.1,53 -ip #0 40(20) 6 10.3.3.3,12345 > 10.1.1.1,53 -ip #0 40(20) 6 10.2.2.2,12345 > 10.1.0.0,23 -ip #0 40(20) 6 10.3.3.3,12345 > 10.1.0.0,23 -ip #0 28(20) 17 10.2.2.2,12345 > 10.1.1.0,53 -ip #0 28(20) 17 10.3.3.3,12345 > 10.1.1.0,53 -ip #0 40(20) 6 10.2.2.2,12345 > 10.1.1.0,53 -ip #0 40(20) 6 10.3.3.3,12345 > 10.1.1.0,53 +< zx0 ip #0 40(20) 6 10.2.2.2,12345 > 10.1.1.1,23 +< zx0 ip #0 40(20) 6 10.2.2.2,12345 > 10.1.1.2,23 +< zx0 ip #0 40(20) 6 10.3.0.1,12345 > 10.2.2.1,10023 +< zx0 ip #0 40(20) 6 10.3.0.1,12345 > 10.2.2.2,23 +< zx0 ip #0 40(20) 6 10.3.3.3,12345 > 10.2.2.1,10023 +< zx0 ip #0 40(20) 6 10.2.2.2,12345 > 10.1.1.1,53 +< zx0 ip #0 40(20) 6 10.3.3.3,12345 > 10.1.1.1,53 +< zx0 ip #0 40(20) 6 10.2.2.2,12345 > 10.1.0.0,23 +15 +< zx0 ip #0 28(20) 17 10.2.2.2,12345 > 10.1.1.0,53 +< zx0 ip #0 28(20) 17 10.3.3.3,12345 > 10.1.1.0,53 +< zx0 ip #0 40(20) 6 10.2.2.2,12345 > 10.1.1.0,53 +< zx0 ip #0 40(20) 6 10.3.3.3,12345 > 10.1.1.0,53 +List of active MAP/Redirect filters: +rdr zx0 from 10.3.0.0/16 to 10.1.0.0/16 port = 23 -> 10.2.2.1/32 port 10023 tcp + +List of active sessions: +RDR 10.2.2.1 10023 <- -> 10.1.1.1 23 [10.3.3.3 12345] +RDR 10.2.2.1 10023 <- -> 10.1.2.2 23 [10.3.0.1 12345] + +Hostmap table: +List of active state sessions: +List of configured pools +List of configured hash tables +List of groups configured (set 0) +List of groups configured (set 1) +Rules configured (set 0, in) +Rules configured (set 0, out) +Rules configured (set 1, in) +Rules configured (set 1, out) +Accounting rules configured (set 0, in) +Accounting rules configured (set 0, out) +Accounting rules configured (set 1, in) +Accounting rules configured (set 1, out) ------------------------------- -ip #0 40(20) 6 10.2.2.2,12345 > 10.1.1.1,23 -ip #0 40(20) 6 10.2.2.2,12345 > 10.1.1.2,23 -ip #0 40(20) 6 10.3.0.1,12345 > 10.1.2.2,23 -ip #0 40(20) 6 10.3.0.1,12345 > 10.2.2.2,23 -ip #0 40(20) 6 10.3.3.3,12345 > 10.1.1.1,23 -ip #0 40(20) 6 10.2.2.2,12345 > 10.1.1.1,53 -ip #0 40(20) 6 10.3.3.3,12345 > 10.1.1.1,53 -ip #0 40(20) 6 10.2.2.2,12345 > 10.1.0.0,23 -ip #0 40(20) 6 10.3.3.3,12345 > 10.1.0.0,23 -ip #0 28(20) 17 10.2.2.2,12345 > 10.1.1.0,53 -ip #0 28(20) 17 10.3.3.3,12345 > 10.2.2.1,10053 -ip #0 40(20) 6 10.2.2.2,12345 > 10.1.1.0,53 -ip #0 40(20) 6 10.3.3.3,12345 > 10.1.1.0,53 +< zx0 ip #0 40(20) 6 10.2.2.2,12345 > 10.1.1.1,23 +< zx0 ip #0 40(20) 6 10.2.2.2,12345 > 10.1.1.2,23 +< zx0 ip #0 40(20) 6 10.3.0.1,12345 > 10.1.2.2,23 +< zx0 ip #0 40(20) 6 10.3.0.1,12345 > 10.2.2.2,23 +< zx0 ip #0 40(20) 6 10.3.3.3,12345 > 10.1.1.1,23 +< zx0 ip #0 40(20) 6 10.2.2.2,12345 > 10.1.1.1,53 +< zx0 ip #0 40(20) 6 10.3.3.3,12345 > 10.1.1.1,53 +< zx0 ip #0 40(20) 6 10.2.2.2,12345 > 10.1.0.0,23 +< zx0 ip #0 40(20) 6 10.3.3.3,12345 > 10.1.0.0,23 +< zx0 ip #0 28(20) 17 10.2.2.2,12345 > 10.1.1.0,53 +< zx0 ip #0 28(20) 17 10.3.3.3,12345 > 10.2.2.1,10053 +< zx0 ip #0 40(20) 6 10.2.2.2,12345 > 10.1.1.0,53 +< zx0 ip #0 40(20) 6 10.3.3.3,12345 > 10.1.1.0,53 +List of active MAP/Redirect filters: +rdr zx0 ! from 10.2.0.0/16 to 10.1.1.0/24 port = 53 -> 10.2.2.1/32 port 10053 udp + +List of active sessions: +RDR 10.2.2.1 10053 <- -> 10.1.1.0 53 [10.3.3.3 12345] + +Hostmap table: +List of active state sessions: +List of configured pools +List of configured hash tables +List of groups configured (set 0) +List of groups configured (set 1) +Rules configured (set 0, in) +Rules configured (set 0, out) +Rules configured (set 1, in) +Rules configured (set 1, out) +Accounting rules configured (set 0, in) +Accounting rules configured (set 0, out) +Accounting rules configured (set 1, in) +Accounting rules configured (set 1, out) ------------------------------- diff --git a/contrib/ipfilter/test/expected/n6_6 b/contrib/ipfilter/test/expected/n6_6 new file mode 100644 index 000000000000..e10f9bd8f435 --- /dev/null +++ b/contrib/ipfilter/test/expected/n6_6 @@ -0,0 +1,173 @@ +< zx0 ip6/0 20 0 6 10:0:0:0:0:2:2:2,12345 > 10:0:0:0:0:2:2:1,10023 +< zx0 ip6/0 20 0 6 10:0:0:0:0:2:2:2,12345 > 10:1:1:0:0:0:0:2,23 +< zx0 ip6/0 20 0 6 10:3:0:0:0:0:0:1,12345 > 10:1:2:0:0:0:0:2,23 +< zx0 ip6/0 20 0 6 10:3:0:0:0:0:0:1,12345 > 10:0:0:0:0:2:2:2,23 +< zx0 ip6/0 20 0 6 10:3:3:0:0:0:0:3,12345 > 10:0:0:0:0:2:2:1,10023 +< zx0 ip6/0 20 0 6 10:0:0:0:0:2:2:2,12345 > 10:1:1:0:0:0:0:1,53 +< zx0 ip6/0 20 0 6 10:3:3:0:0:0:0:3,12345 > 10:1:1:0:0:0:0:1,53 +< zx0 ip6/0 20 0 6 10:0:0:0:0:2:2:2,12345 > 10:1:0:0:0:0:0:0,23 +< zx0 ip6/0 20 0 6 10:3:3:0:0:0:0:3,12345 > 10:1:0:0:0:0:0:0,23 +< zx0 ip6/0 8 0 17 10:0:0:0:0:2:2:2,12345 > 10:1:1:0:0:0:0:0,53 +< zx0 ip6/0 8 0 17 10:3:3:0:0:0:0:3,12345 > 10:1:1:0:0:0:0:0,53 +< zx0 ip6/0 20 0 6 10:0:0:0:0:2:2:2,12345 > 10:1:1:0:0:0:0:0,53 +< zx0 ip6/0 20 0 6 10:3:3:0:0:0:0:3,12345 > 10:1:1:0:0:0:0:0,53 +List of active MAP/Redirect filters: +rdr zx0 inet6 10:1:1::1/128 port 23 -> 10::2:2:1/128 port 10023 tcp + +List of active sessions: +RDR 10::2:2:1 10023 <- -> 10:1:1::1 23 [10:3:3::3 12345] +RDR 10::2:2:1 10023 <- -> 10:1:1::1 23 [10::2:2:2 12345] + +Hostmap table: +List of active state sessions: +List of configured pools +List of configured hash tables +List of groups configured (set 0) +List of groups configured (set 1) +Rules configured (set 0, in) +Rules configured (set 0, out) +Rules configured (set 1, in) +Rules configured (set 1, out) +Accounting rules configured (set 0, in) +Accounting rules configured (set 0, out) +Accounting rules configured (set 1, in) +Accounting rules configured (set 1, out) +------------------------------- +< zx0 ip6/0 20 0 6 10:0:0:0:0:2:2:2,12345 > 10:0:0:0:0:2:2:1,10023 +16 +< zx0 ip6/0 20 0 6 10:3:0:0:0:0:0:1,12345 > 10:1:2:0:0:0:0:2,23 +< zx0 ip6/0 20 0 6 10:3:0:0:0:0:0:1,12345 > 10:0:0:0:0:2:2:2,23 +< zx0 ip6/0 20 0 6 10:3:3:0:0:0:0:3,12345 > 10:0:0:0:0:2:2:1,10023 +< zx0 ip6/0 20 0 6 10:0:0:0:0:2:2:2,12345 > 10:1:1:0:0:0:0:1,53 +< zx0 ip6/0 20 0 6 10:3:3:0:0:0:0:3,12345 > 10:1:1:0:0:0:0:1,53 +< zx0 ip6/0 20 0 6 10:0:0:0:0:2:2:2,12345 > 10:1:0:0:0:0:0:0,23 +< zx0 ip6/0 20 0 6 10:3:3:0:0:0:0:3,12345 > 10:1:0:0:0:0:0:0,23 +< zx0 ip6/0 8 0 17 10:0:0:0:0:2:2:2,12345 > 10:1:1:0:0:0:0:0,53 +< zx0 ip6/0 8 0 17 10:3:3:0:0:0:0:3,12345 > 10:1:1:0:0:0:0:0,53 +< zx0 ip6/0 20 0 6 10:0:0:0:0:2:2:2,12345 > 10:1:1:0:0:0:0:0,53 +< zx0 ip6/0 20 0 6 10:3:3:0:0:0:0:3,12345 > 10:1:1:0:0:0:0:0,53 +List of active MAP/Redirect filters: +rdr zx0 inet6 from any to 10:1:1::/112 port = 23 -> 10::2:2:1/128 port 10023 tcp + +List of active sessions: +RDR 10::2:2:1 10023 <- -> 10:1:1::1 23 [10:3:3::3 12345] +RDR 10::2:2:1 10023 <- -> 10:1:1::1 23 [10::2:2:2 12345] + +Hostmap table: +List of active state sessions: +List of configured pools +List of configured hash tables +List of groups configured (set 0) +List of groups configured (set 1) +Rules configured (set 0, in) +Rules configured (set 0, out) +Rules configured (set 1, in) +Rules configured (set 1, out) +Accounting rules configured (set 0, in) +Accounting rules configured (set 0, out) +Accounting rules configured (set 1, in) +Accounting rules configured (set 1, out) +------------------------------- +< zx0 ip6/0 20 0 6 10:0:0:0:0:2:2:2,12345 > 10:0:0:0:0:2:2:1,10023 +16 +< zx0 ip6/0 20 0 6 10:3:0:0:0:0:0:1,12345 > 10:1:2:0:0:0:0:2,23 +< zx0 ip6/0 20 0 6 10:3:0:0:0:0:0:1,12345 > 10:0:0:0:0:2:2:2,23 +< zx0 ip6/0 20 0 6 10:3:3:0:0:0:0:3,12345 > 10:1:1:0:0:0:0:1,23 +< zx0 ip6/0 20 0 6 10:0:0:0:0:2:2:2,12345 > 10:1:1:0:0:0:0:1,53 +< zx0 ip6/0 20 0 6 10:3:3:0:0:0:0:3,12345 > 10:1:1:0:0:0:0:1,53 +< zx0 ip6/0 20 0 6 10:0:0:0:0:2:2:2,12345 > 10:1:0:0:0:0:0:0,23 +< zx0 ip6/0 20 0 6 10:3:3:0:0:0:0:3,12345 > 10:1:0:0:0:0:0:0,23 +< zx0 ip6/0 8 0 17 10:0:0:0:0:2:2:2,12345 > 10:1:1:0:0:0:0:0,53 +< zx0 ip6/0 8 0 17 10:3:3:0:0:0:0:3,12345 > 10:1:1:0:0:0:0:0,53 +< zx0 ip6/0 20 0 6 10:0:0:0:0:2:2:2,12345 > 10:1:1:0:0:0:0:0,53 +< zx0 ip6/0 20 0 6 10:3:3:0:0:0:0:3,12345 > 10:1:1:0:0:0:0:0,53 +List of active MAP/Redirect filters: +rdr zx0 inet6 from 10::/32 to 10:1:1::/112 port = 23 -> 10::2:2:1/128 port 10023 tcp + +List of active sessions: +RDR 10::2:2:1 10023 <- -> 10:1:1::1 23 [10::2:2:2 12345] + +Hostmap table: +List of active state sessions: +List of configured pools +List of configured hash tables +List of groups configured (set 0) +List of groups configured (set 1) +Rules configured (set 0, in) +Rules configured (set 0, out) +Rules configured (set 1, in) +Rules configured (set 1, out) +Accounting rules configured (set 0, in) +Accounting rules configured (set 0, out) +Accounting rules configured (set 1, in) +Accounting rules configured (set 1, out) +------------------------------- +< zx0 ip6/0 20 0 6 10:0:0:0:0:2:2:2,12345 > 10:1:1:0:0:0:0:1,23 +< zx0 ip6/0 20 0 6 10:0:0:0:0:2:2:2,12345 > 10:1:1:0:0:0:0:2,23 +< zx0 ip6/0 20 0 6 10:3:0:0:0:0:0:1,12345 > 10:0:0:0:0:2:2:1,10023 +< zx0 ip6/0 20 0 6 10:3:0:0:0:0:0:1,12345 > 10:0:0:0:0:2:2:2,23 +< zx0 ip6/0 20 0 6 10:3:3:0:0:0:0:3,12345 > 10:0:0:0:0:2:2:1,10023 +< zx0 ip6/0 20 0 6 10:0:0:0:0:2:2:2,12345 > 10:1:1:0:0:0:0:1,53 +< zx0 ip6/0 20 0 6 10:3:3:0:0:0:0:3,12345 > 10:1:1:0:0:0:0:1,53 +< zx0 ip6/0 20 0 6 10:0:0:0:0:2:2:2,12345 > 10:1:0:0:0:0:0:0,23 +16 +< zx0 ip6/0 8 0 17 10:0:0:0:0:2:2:2,12345 > 10:1:1:0:0:0:0:0,53 +< zx0 ip6/0 8 0 17 10:3:3:0:0:0:0:3,12345 > 10:1:1:0:0:0:0:0,53 +< zx0 ip6/0 20 0 6 10:0:0:0:0:2:2:2,12345 > 10:1:1:0:0:0:0:0,53 +< zx0 ip6/0 20 0 6 10:3:3:0:0:0:0:3,12345 > 10:1:1:0:0:0:0:0,53 +List of active MAP/Redirect filters: +rdr zx0 inet6 from 10:3::/32 to 10:1::/32 port = 23 -> 10::2:2:1/128 port 10023 tcp + +List of active sessions: +RDR 10::2:2:1 10023 <- -> 10:1:1::1 23 [10:3:3::3 12345] +RDR 10::2:2:1 10023 <- -> 10:1:2::2 23 [10:3::1 12345] + +Hostmap table: +List of active state sessions: +List of configured pools +List of configured hash tables +List of groups configured (set 0) +List of groups configured (set 1) +Rules configured (set 0, in) +Rules configured (set 0, out) +Rules configured (set 1, in) +Rules configured (set 1, out) +Accounting rules configured (set 0, in) +Accounting rules configured (set 0, out) +Accounting rules configured (set 1, in) +Accounting rules configured (set 1, out) +------------------------------- +< zx0 ip6/0 20 0 6 10:0:0:0:0:2:2:2,12345 > 10:1:1:0:0:0:0:1,23 +< zx0 ip6/0 20 0 6 10:0:0:0:0:2:2:2,12345 > 10:1:1:0:0:0:0:2,23 +< zx0 ip6/0 20 0 6 10:3:0:0:0:0:0:1,12345 > 10:1:2:0:0:0:0:2,23 +< zx0 ip6/0 20 0 6 10:3:0:0:0:0:0:1,12345 > 10:0:0:0:0:2:2:2,23 +< zx0 ip6/0 20 0 6 10:3:3:0:0:0:0:3,12345 > 10:1:1:0:0:0:0:1,23 +< zx0 ip6/0 20 0 6 10:0:0:0:0:2:2:2,12345 > 10:1:1:0:0:0:0:1,53 +< zx0 ip6/0 20 0 6 10:3:3:0:0:0:0:3,12345 > 10:1:1:0:0:0:0:1,53 +< zx0 ip6/0 20 0 6 10:0:0:0:0:2:2:2,12345 > 10:1:0:0:0:0:0:0,23 +< zx0 ip6/0 20 0 6 10:3:3:0:0:0:0:3,12345 > 10:1:0:0:0:0:0:0,23 +< zx0 ip6/0 8 0 17 10:0:0:0:0:2:2:2,12345 > 10:1:1:0:0:0:0:0,53 +< zx0 ip6/0 8 0 17 10:3:3:0:0:0:0:3,12345 > 10:0:0:0:0:2:2:1,10053 +< zx0 ip6/0 20 0 6 10:0:0:0:0:2:2:2,12345 > 10:1:1:0:0:0:0:0,53 +< zx0 ip6/0 20 0 6 10:3:3:0:0:0:0:3,12345 > 10:1:1:0:0:0:0:0,53 +List of active MAP/Redirect filters: +rdr zx0 inet6 ! from 10::/32 to 10:1:1::/112 port = 53 -> 10::2:2:1/128 port 10053 udp + +List of active sessions: +RDR 10::2:2:1 10053 <- -> 10:1:1:: 53 [10:3:3::3 12345] + +Hostmap table: +List of active state sessions: +List of configured pools +List of configured hash tables +List of groups configured (set 0) +List of groups configured (set 1) +Rules configured (set 0, in) +Rules configured (set 0, out) +Rules configured (set 1, in) +Rules configured (set 1, out) +Accounting rules configured (set 0, in) +Accounting rules configured (set 0, out) +Accounting rules configured (set 1, in) +Accounting rules configured (set 1, out) +------------------------------- diff --git a/contrib/ipfilter/test/expected/n7 b/contrib/ipfilter/test/expected/n7 index eb23534d0b30..11b811538ba9 100644 --- a/contrib/ipfilter/test/expected/n7 +++ b/contrib/ipfilter/test/expected/n7 @@ -1,30 +1,98 @@ -ip #0 40(20) 6 10.2.3.1,1230 > 10.1.1.1,22 -ip #0 40(20) 6 10.2.3.1,1231 > 10.2.2.1,10023 -ip #0 40(20) 6 10.2.3.1,1232 > 10.2.2.1,10050 -ip #0 40(20) 6 10.2.3.1,1233 > 10.2.2.1,10079 -ip #0 40(20) 6 10.2.3.1,1234 > 10.1.1.1,80 -ip #0 40(20) 6 10.2.3.1,1235 > 10.1.1.2,80 -ip #0 40(20) 6 10.2.3.1,1236 > 10.1.1.3,80 -ip #0 40(20) 6 10.2.3.1,1237 > 10.1.1.4,80 -ip #0 40(20) 6 10.2.3.1,1238 > 10.1.1.4,80 +< zx0 ip #0 40(20) 6 10.2.3.1,1230 > 10.1.1.1,22 +< zx0 ip #0 40(20) 6 10.2.3.1,1231 > 10.2.2.1,10023 +< zx0 ip #0 40(20) 6 10.2.3.1,1232 > 10.2.2.1,10050 +< zx0 ip #0 40(20) 6 10.2.3.1,1233 > 10.2.2.1,10079 +< zx0 ip #0 40(20) 6 10.2.3.1,1234 > 10.1.1.1,80 +< zx0 ip #0 40(20) 6 10.2.3.1,1235 > 10.1.1.2,80 +< zx0 ip #0 40(20) 6 10.2.3.1,1236 > 10.1.1.3,80 +< zx0 ip #0 40(20) 6 10.2.3.1,1237 > 10.1.1.4,80 +< zx0 ip #0 40(20) 6 10.2.3.1,1238 > 10.1.1.4,80 +List of active MAP/Redirect filters: +rdr zx0 10.1.1.1/32 port 23-79 -> 10.2.2.1/32 port 10023 tcp + +List of active sessions: +RDR 10.2.2.1 10079 <- -> 10.1.1.1 79 [10.2.3.1 1233] +RDR 10.2.2.1 10050 <- -> 10.1.1.1 50 [10.2.3.1 1232] +RDR 10.2.2.1 10023 <- -> 10.1.1.1 23 [10.2.3.1 1231] + +Hostmap table: +List of active state sessions: +List of configured pools +List of configured hash tables +List of groups configured (set 0) +List of groups configured (set 1) +Rules configured (set 0, in) +Rules configured (set 0, out) +Rules configured (set 1, in) +Rules configured (set 1, out) +Accounting rules configured (set 0, in) +Accounting rules configured (set 0, out) +Accounting rules configured (set 1, in) +Accounting rules configured (set 1, out) ------------------------------- -ip #0 40(20) 6 10.2.3.1,1230 > 10.1.1.1,22 -ip #0 40(20) 6 10.2.3.1,1231 > 10.2.2.1,10023 -ip #0 40(20) 6 10.2.3.1,1232 > 10.2.2.1,10023 -ip #0 40(20) 6 10.2.3.1,1233 > 10.2.2.1,10023 -ip #0 40(20) 6 10.2.3.1,1234 > 10.1.1.1,80 -ip #0 40(20) 6 10.2.3.1,1235 > 10.1.1.2,80 -ip #0 40(20) 6 10.2.3.1,1236 > 10.1.1.3,80 -ip #0 40(20) 6 10.2.3.1,1237 > 10.1.1.4,80 -ip #0 40(20) 6 10.2.3.1,1238 > 10.1.1.4,80 +< zx0 ip #0 40(20) 6 10.2.3.1,1230 > 10.1.1.1,22 +< zx0 ip #0 40(20) 6 10.2.3.1,1231 > 10.2.2.1,10023 +< zx0 ip #0 40(20) 6 10.2.3.1,1232 > 10.2.2.1,10023 +< zx0 ip #0 40(20) 6 10.2.3.1,1233 > 10.2.2.1,10023 +< zx0 ip #0 40(20) 6 10.2.3.1,1234 > 10.1.1.1,80 +< zx0 ip #0 40(20) 6 10.2.3.1,1235 > 10.1.1.2,80 +< zx0 ip #0 40(20) 6 10.2.3.1,1236 > 10.1.1.3,80 +< zx0 ip #0 40(20) 6 10.2.3.1,1237 > 10.1.1.4,80 +< zx0 ip #0 40(20) 6 10.2.3.1,1238 > 10.1.1.4,80 +List of active MAP/Redirect filters: +rdr zx0 10.1.1.1/32 port 23-79 -> 10.2.2.1/32 port = 10023 tcp + +List of active sessions: +RDR 10.2.2.1 10023 <- -> 10.1.1.1 79 [10.2.3.1 1233] +RDR 10.2.2.1 10023 <- -> 10.1.1.1 50 [10.2.3.1 1232] +RDR 10.2.2.1 10023 <- -> 10.1.1.1 23 [10.2.3.1 1231] + +Hostmap table: +List of active state sessions: +List of configured pools +List of configured hash tables +List of groups configured (set 0) +List of groups configured (set 1) +Rules configured (set 0, in) +Rules configured (set 0, out) +Rules configured (set 1, in) +Rules configured (set 1, out) +Accounting rules configured (set 0, in) +Accounting rules configured (set 0, out) +Accounting rules configured (set 1, in) +Accounting rules configured (set 1, out) ------------------------------- -ip #0 40(20) 6 10.2.3.1,1230 > 10.1.1.1,22 -ip #0 40(20) 6 10.2.3.1,1231 > 10.1.1.1,23 -ip #0 40(20) 6 10.2.3.1,1232 > 10.1.1.1,50 -ip #0 40(20) 6 10.2.3.1,1233 > 10.1.1.1,79 -ip #0 40(20) 6 10.2.3.1,1234 > 10.2.2.1,3128 -ip #0 40(20) 6 10.2.3.1,1235 > 1.2.2.129,3128 -ip #0 40(20) 6 10.2.3.1,1236 > 10.2.2.1,3128 -ip #0 40(20) 6 10.2.3.1,1237 > 1.2.2.129,3128 -ip #0 40(20) 6 10.2.3.1,1238 > 10.2.2.1,3128 +< zx0 ip #0 40(20) 6 10.2.3.1,1230 > 10.1.1.1,22 +< zx0 ip #0 40(20) 6 10.2.3.1,1231 > 10.1.1.1,23 +< zx0 ip #0 40(20) 6 10.2.3.1,1232 > 10.1.1.1,50 +< zx0 ip #0 40(20) 6 10.2.3.1,1233 > 10.1.1.1,79 +< zx0 ip #0 40(20) 6 10.2.3.1,1234 > 10.2.2.1,3128 +< zx0 ip #0 40(20) 6 10.2.3.1,1235 > 1.2.2.129,3128 +< zx0 ip #0 40(20) 6 10.2.3.1,1236 > 10.2.2.1,3128 +< zx0 ip #0 40(20) 6 10.2.3.1,1237 > 1.2.2.129,3128 +< zx0 ip #0 40(20) 6 10.2.3.1,1238 > 10.2.2.1,3128 +List of active MAP/Redirect filters: +rdr zx0 10.1.1.0/24 port 80 -> 10.2.2.1,1.2.2.129 port 3128 tcp + +List of active sessions: +RDR 10.2.2.1 3128 <- -> 10.1.1.4 80 [10.2.3.1 1238] +RDR 1.2.2.129 3128 <- -> 10.1.1.4 80 [10.2.3.1 1237] +RDR 10.2.2.1 3128 <- -> 10.1.1.3 80 [10.2.3.1 1236] +RDR 1.2.2.129 3128 <- -> 10.1.1.2 80 [10.2.3.1 1235] +RDR 10.2.2.1 3128 <- -> 10.1.1.1 80 [10.2.3.1 1234] + +Hostmap table: +List of active state sessions: +List of configured pools +List of configured hash tables +List of groups configured (set 0) +List of groups configured (set 1) +Rules configured (set 0, in) +Rules configured (set 0, out) +Rules configured (set 1, in) +Rules configured (set 1, out) +Accounting rules configured (set 0, in) +Accounting rules configured (set 0, out) +Accounting rules configured (set 1, in) +Accounting rules configured (set 1, out) ------------------------------- diff --git a/contrib/ipfilter/test/expected/n7_6 b/contrib/ipfilter/test/expected/n7_6 new file mode 100644 index 000000000000..25630334147f --- /dev/null +++ b/contrib/ipfilter/test/expected/n7_6 @@ -0,0 +1,98 @@ +< zx0 ip6/0 20 0 6 10:0:0:0:0:2:3:1,1230 > 10:1:1:0:0:0:0:1,22 +< zx0 ip6/0 20 0 6 10:0:0:0:0:2:3:1,1231 > 10:0:0:0:0:2:2:1,10023 +< zx0 ip6/0 20 0 6 10:0:0:0:0:2:3:1,1232 > 10:0:0:0:0:2:2:1,10050 +< zx0 ip6/0 20 0 6 10:0:0:0:0:2:3:1,1233 > 10:0:0:0:0:2:2:1,10079 +< zx0 ip6/0 20 0 6 10:0:0:0:0:2:3:1,1234 > 10:1:1:0:0:0:0:1,80 +< zx0 ip6/0 20 0 6 10:0:0:0:0:2:3:1,1235 > 10:1:1:0:0:0:0:2,80 +< zx0 ip6/0 20 0 6 10:0:0:0:0:2:3:1,1236 > 10:1:1:0:0:0:0:3,80 +< zx0 ip6/0 20 0 6 10:0:0:0:0:2:3:1,1237 > 10:1:1:0:0:0:0:4,80 +< zx0 ip6/0 20 0 6 10:0:0:0:0:2:3:1,1238 > 10:1:1:0:0:0:0:4,80 +List of active MAP/Redirect filters: +rdr zx0 inet6 10:1:1::1/128 port 23-79 -> 10::2:2:1/128 port 10023 tcp + +List of active sessions: +RDR 10::2:2:1 10079 <- -> 10:1:1::1 79 [10::2:3:1 1233] +RDR 10::2:2:1 10050 <- -> 10:1:1::1 50 [10::2:3:1 1232] +RDR 10::2:2:1 10023 <- -> 10:1:1::1 23 [10::2:3:1 1231] + +Hostmap table: +List of active state sessions: +List of configured pools +List of configured hash tables +List of groups configured (set 0) +List of groups configured (set 1) +Rules configured (set 0, in) +Rules configured (set 0, out) +Rules configured (set 1, in) +Rules configured (set 1, out) +Accounting rules configured (set 0, in) +Accounting rules configured (set 0, out) +Accounting rules configured (set 1, in) +Accounting rules configured (set 1, out) +------------------------------- +< zx0 ip6/0 20 0 6 10:0:0:0:0:2:3:1,1230 > 10:1:1:0:0:0:0:1,22 +< zx0 ip6/0 20 0 6 10:0:0:0:0:2:3:1,1231 > 10:0:0:0:0:2:2:1,10023 +< zx0 ip6/0 20 0 6 10:0:0:0:0:2:3:1,1232 > 10:0:0:0:0:2:2:1,10023 +< zx0 ip6/0 20 0 6 10:0:0:0:0:2:3:1,1233 > 10:0:0:0:0:2:2:1,10023 +< zx0 ip6/0 20 0 6 10:0:0:0:0:2:3:1,1234 > 10:1:1:0:0:0:0:1,80 +< zx0 ip6/0 20 0 6 10:0:0:0:0:2:3:1,1235 > 10:1:1:0:0:0:0:2,80 +< zx0 ip6/0 20 0 6 10:0:0:0:0:2:3:1,1236 > 10:1:1:0:0:0:0:3,80 +< zx0 ip6/0 20 0 6 10:0:0:0:0:2:3:1,1237 > 10:1:1:0:0:0:0:4,80 +< zx0 ip6/0 20 0 6 10:0:0:0:0:2:3:1,1238 > 10:1:1:0:0:0:0:4,80 +List of active MAP/Redirect filters: +rdr zx0 inet6 10:1:1::1/128 port 23-79 -> 10::2:2:1/128 port = 10023 tcp + +List of active sessions: +RDR 10::2:2:1 10023 <- -> 10:1:1::1 79 [10::2:3:1 1233] +RDR 10::2:2:1 10023 <- -> 10:1:1::1 50 [10::2:3:1 1232] +RDR 10::2:2:1 10023 <- -> 10:1:1::1 23 [10::2:3:1 1231] + +Hostmap table: +List of active state sessions: +List of configured pools +List of configured hash tables +List of groups configured (set 0) +List of groups configured (set 1) +Rules configured (set 0, in) +Rules configured (set 0, out) +Rules configured (set 1, in) +Rules configured (set 1, out) +Accounting rules configured (set 0, in) +Accounting rules configured (set 0, out) +Accounting rules configured (set 1, in) +Accounting rules configured (set 1, out) +------------------------------- +< zx0 ip6/0 20 0 6 10:0:0:0:0:2:3:1,1230 > 10:1:1:0:0:0:0:1,22 +< zx0 ip6/0 20 0 6 10:0:0:0:0:2:3:1,1231 > 10:1:1:0:0:0:0:1,23 +< zx0 ip6/0 20 0 6 10:0:0:0:0:2:3:1,1232 > 10:1:1:0:0:0:0:1,50 +< zx0 ip6/0 20 0 6 10:0:0:0:0:2:3:1,1233 > 10:1:1:0:0:0:0:1,79 +< zx0 ip6/0 20 0 6 10:0:0:0:0:2:3:1,1234 > 10:0:0:0:0:2:2:1,3128 +< zx0 ip6/0 20 0 6 10:0:0:0:0:2:3:1,1235 > 1:0:0:0:0:2:2:129,3128 +< zx0 ip6/0 20 0 6 10:0:0:0:0:2:3:1,1236 > 10:0:0:0:0:2:2:1,3128 +< zx0 ip6/0 20 0 6 10:0:0:0:0:2:3:1,1237 > 1:0:0:0:0:2:2:129,3128 +< zx0 ip6/0 20 0 6 10:0:0:0:0:2:3:1,1238 > 10:0:0:0:0:2:2:1,3128 +List of active MAP/Redirect filters: +rdr zx0 inet6 10:1:1::/112 port 80 -> 10::2:2:1,1::2:2:129 port 3128 tcp + +List of active sessions: +RDR 10::2:2:1 3128 <- -> 10:1:1::4 80 [10::2:3:1 1238] +RDR 1::2:2:129 3128 <- -> 10:1:1::4 80 [10::2:3:1 1237] +RDR 10::2:2:1 3128 <- -> 10:1:1::3 80 [10::2:3:1 1236] +RDR 1::2:2:129 3128 <- -> 10:1:1::2 80 [10::2:3:1 1235] +RDR 10::2:2:1 3128 <- -> 10:1:1::1 80 [10::2:3:1 1234] + +Hostmap table: +List of active state sessions: +List of configured pools +List of configured hash tables +List of groups configured (set 0) +List of groups configured (set 1) +Rules configured (set 0, in) +Rules configured (set 0, out) +Rules configured (set 1, in) +Rules configured (set 1, out) +Accounting rules configured (set 0, in) +Accounting rules configured (set 0, out) +Accounting rules configured (set 1, in) +Accounting rules configured (set 1, out) +------------------------------- diff --git a/contrib/ipfilter/test/expected/n8 b/contrib/ipfilter/test/expected/n8 index d3e061da974a..a5e938f16ef4 100644 --- a/contrib/ipfilter/test/expected/n8 +++ b/contrib/ipfilter/test/expected/n8 @@ -6,4 +6,25 @@ 4500 0054 3fd5 4000 ff01 2fc8 0404 0404 0202 0202 0000 f7de 6220 0001 3f6f 6e80 000b 0d02 0809 0a0b 0c0d 0e0f 1011 1213 1415 1617 1819 1a1b 1c1d 1e1f 2021 2223 2425 2627 2829 2a2b 2c2d 2e2f 3031 3233 3435 3637 +List of active MAP/Redirect filters: +map icmp0 2.2.2.0/24 -> 10.10.10.0/24 + +List of active sessions: +MAP 2.2.2.2 <- -> 10.10.10.1 [4.4.4.4] + +Hostmap table: +2.2.2.2,4.4.4.4 -> 10.10.10.1,0.0.0.0 (use = 1) +List of active state sessions: +List of configured pools +List of configured hash tables +List of groups configured (set 0) +List of groups configured (set 1) +Rules configured (set 0, in) +Rules configured (set 0, out) +Rules configured (set 1, in) +Rules configured (set 1, out) +Accounting rules configured (set 0, in) +Accounting rules configured (set 0, out) +Accounting rules configured (set 1, in) +Accounting rules configured (set 1, out) ------------------------------- diff --git a/contrib/ipfilter/test/expected/n8_6 b/contrib/ipfilter/test/expected/n8_6 new file mode 100644 index 000000000000..4d08efe37e2b --- /dev/null +++ b/contrib/ipfilter/test/expected/n8_6 @@ -0,0 +1,30 @@ +6000 0000 0040 3aff 0010 0010 0010 0000 0000 0000 0000 0001 0004 0004 0004 0000 0000 0000 0000 0004 8000 7724 6220 0000 3f6f 6e80 000b 0d02 0809 0a0b 0c0d 0e0f 1011 1213 1415 1617 1819 1a1b 1c1d 1e1f 2021 2223 2425 2627 2829 2a2b 2c2d 2e2f 3031 3233 3435 3637 + +6000 0000 0040 3aff 0004 0004 0004 0000 0000 0000 0000 0004 0002 0000 0000 0000 0000 0002 0002 0002 8100 764d 6220 0000 3f6f 6e80 000b 0d02 0809 0a0b 0c0d 0e0f 1011 1213 1415 1617 1819 1a1b 1c1d 1e1f 2021 2223 2425 2627 2829 2a2b 2c2d 2e2f 3031 3233 3435 3637 + +6000 0000 0040 3aff 0010 0010 0010 0000 0000 0000 0000 0001 0004 0004 0004 0000 0000 0000 0000 0004 8000 7723 6220 0001 3f6f 6e80 000b 0d02 0809 0a0b 0c0d 0e0f 1011 1213 1415 1617 1819 1a1b 1c1d 1e1f 2021 2223 2425 2627 2829 2a2b 2c2d 2e2f 3031 3233 3435 3637 + +6000 0000 0040 3aff 0004 0004 0004 0000 0000 0000 0000 0004 0002 0000 0000 0000 0000 0002 0002 0002 8100 764c 6220 0001 3f6f 6e80 000b 0d02 0809 0a0b 0c0d 0e0f 1011 1213 1415 1617 1819 1a1b 1c1d 1e1f 2021 2223 2425 2627 2829 2a2b 2c2d 2e2f 3031 3233 3435 3637 + +List of active MAP/Redirect filters: +map icmp0 inet6 2::2:2:0/112 -> 10:10:10::/112 + +List of active sessions: +MAP 2::2:2:2 <- -> 10:10:10::1 [4:4:4::4] + +Hostmap table: +2::2:2:2,4:4:4::4 -> 10:10:10::1,any (use = 1) +List of active state sessions: +List of configured pools +List of configured hash tables +List of groups configured (set 0) +List of groups configured (set 1) +Rules configured (set 0, in) +Rules configured (set 0, out) +Rules configured (set 1, in) +Rules configured (set 1, out) +Accounting rules configured (set 0, in) +Accounting rules configured (set 0, out) +Accounting rules configured (set 1, in) +Accounting rules configured (set 1, out) +------------------------------- diff --git a/contrib/ipfilter/test/expected/n9 b/contrib/ipfilter/test/expected/n9 index 917105f74ed4..2c762be6af6a 100644 --- a/contrib/ipfilter/test/expected/n9 +++ b/contrib/ipfilter/test/expected/n9 @@ -6,4 +6,24 @@ 4500 0054 3fd5 4000 ff01 2fc8 0404 0404 0202 0202 0000 f7de 6220 0001 3f6f 6e80 000b 0d02 0809 0a0b 0c0d 0e0f 1011 1213 1415 1617 1819 1a1b 1c1d 1e1f 2021 2223 2425 2627 2829 2a2b 2c2d 2e2f 3031 3233 3435 3637 +List of active MAP/Redirect filters: +rdr icmp0 4.4.4.0/24 -> 10.10.10.1/32 ip + +List of active sessions: +RDR 10.10.10.1 <- -> 4.4.4.4 [2.2.2.2] + +Hostmap table: +List of active state sessions: +List of configured pools +List of configured hash tables +List of groups configured (set 0) +List of groups configured (set 1) +Rules configured (set 0, in) +Rules configured (set 0, out) +Rules configured (set 1, in) +Rules configured (set 1, out) +Accounting rules configured (set 0, in) +Accounting rules configured (set 0, out) +Accounting rules configured (set 1, in) +Accounting rules configured (set 1, out) ------------------------------- diff --git a/contrib/ipfilter/test/expected/n9_6 b/contrib/ipfilter/test/expected/n9_6 new file mode 100644 index 000000000000..134d74c9fa45 --- /dev/null +++ b/contrib/ipfilter/test/expected/n9_6 @@ -0,0 +1,29 @@ +6000 0000 0040 3aff 0002 0000 0000 0000 0000 0002 0002 0002 0010 0010 0010 0000 0000 0000 0000 0001 8000 772c 6220 0000 3f6f 6e80 000b 0d02 0809 0a0b 0c0d 0e0f 1011 1213 1415 1617 1819 1a1b 1c1d 1e1f 2021 2223 2425 2627 2829 2a2b 2c2d 2e2f 3031 3233 3435 3637 + +6000 0000 0040 3aff 0004 0004 0004 0000 0000 0000 0000 0004 0002 0000 0000 0000 0000 0002 0002 0002 8100 764d 6220 0000 3f6f 6e80 000b 0d02 0809 0a0b 0c0d 0e0f 1011 1213 1415 1617 1819 1a1b 1c1d 1e1f 2021 2223 2425 2627 2829 2a2b 2c2d 2e2f 3031 3233 3435 3637 + +6000 0000 0040 3aff 0002 0000 0000 0000 0000 0002 0002 0002 0010 0010 0010 0000 0000 0000 0000 0001 8000 772b 6220 0001 3f6f 6e80 000b 0d02 0809 0a0b 0c0d 0e0f 1011 1213 1415 1617 1819 1a1b 1c1d 1e1f 2021 2223 2425 2627 2829 2a2b 2c2d 2e2f 3031 3233 3435 3637 + +6000 0000 0040 3aff 0004 0004 0004 0000 0000 0000 0000 0004 0002 0000 0000 0000 0000 0002 0002 0002 8100 764c 6220 0001 3f6f 6e80 000b 0d02 0809 0a0b 0c0d 0e0f 1011 1213 1415 1617 1819 1a1b 1c1d 1e1f 2021 2223 2425 2627 2829 2a2b 2c2d 2e2f 3031 3233 3435 3637 + +List of active MAP/Redirect filters: +rdr icmp0 inet6 4:4:4::/112 -> 10:10:10::1/128 ip + +List of active sessions: +RDR 10:10:10::1 <- -> 4:4:4::4 [2::2:2:2] + +Hostmap table: +List of active state sessions: +List of configured pools +List of configured hash tables +List of groups configured (set 0) +List of groups configured (set 1) +Rules configured (set 0, in) +Rules configured (set 0, out) +Rules configured (set 1, in) +Rules configured (set 1, out) +Accounting rules configured (set 0, in) +Accounting rules configured (set 0, out) +Accounting rules configured (set 1, in) +Accounting rules configured (set 1, out) +------------------------------- diff --git a/contrib/ipfilter/test/expected/ni10 b/contrib/ipfilter/test/expected/ni10 index 3ee63fb8ddd0..050fb40725ea 100644 --- a/contrib/ipfilter/test/expected/ni10 +++ b/contrib/ipfilter/test/expected/ni10 @@ -4,6 +4,5 @@ 4500 0058 0001 0000 ff01 af98 0202 0202 0404 0404 0303 0937 0000 0000 4500 003c 4706 4000 ff06 28aa 0404 0404 0202 0202 5000 0050 0000 0001 0000 0000 a002 16d0 d8e2 0000 0204 05b4 0402 080a 0047 fbb0 0000 0000 0103 0300 -4500 0038 809a 0000 ff01 2b1b 0303 0303 0505 0505 0303 acab 0000 0000 4500 003c 4706 4000 ff06 28ab 0404 0404 0202 0201 5000 0050 0000 0001 - +0 ------------------------------- diff --git a/contrib/ipfilter/test/expected/ni11 b/contrib/ipfilter/test/expected/ni11 index 88d6406e6ee7..6ed8ecc80634 100644 --- a/contrib/ipfilter/test/expected/ni11 +++ b/contrib/ipfilter/test/expected/ni11 @@ -1,9 +1,8 @@ 4500 003c 4706 4000 ff06 2aac 0404 0404 0101 0101 5000 9d58 0000 0001 0000 0000 a002 16d0 3ddc 0000 0204 05b4 0402 080a 0047 fbb0 0000 0000 0103 0300 -4500 0038 0000 0000 ff01 a7b9 0a02 0202 0404 0404 0303 a7fb 0000 0000 4500 003c 4706 4000 ff06 20aa 0404 0404 0a02 0202 5000 0500 0000 0001 +4500 0038 0000 0000 ff01 a7b9 0a02 0202 0404 0404 0303 a7fc 0000 0000 4500 003c 4706 4000 ff06 20aa 0404 0404 0a02 0202 5000 0500 0000 0001 4500 0058 0001 0000 ff01 a798 0a02 0202 0404 0404 0303 1137 0000 0000 4500 003c 4706 4000 ff06 20aa 0404 0404 0a02 0202 5000 0500 0000 0001 0000 0000 a002 16d0 cc32 0000 0204 05b4 0402 080a 0047 fbb0 0000 0000 0103 0300 -4500 0038 809a 0000 ff01 2b1b 0303 0303 0505 0505 0303 0fa3 0000 0000 4500 003c 4706 4000 ff06 2aab 0404 0404 0101 0102 5000 9d58 0000 0001 - +0 ------------------------------- diff --git a/contrib/ipfilter/test/expected/ni12 b/contrib/ipfilter/test/expected/ni12 index 7d24a493fd32..590ec23087e8 100644 --- a/contrib/ipfilter/test/expected/ni12 +++ b/contrib/ipfilter/test/expected/ni12 @@ -1,9 +1,8 @@ 4500 003c 4706 4000 ff06 2aac 0404 0404 0101 0101 5000 9c40 0000 0001 0000 0000 a002 16d0 3ef4 0000 0204 05b4 0402 080a 0047 fbb0 0000 0000 0103 0300 -4500 0038 809a 0000 ff01 2d1d 0303 0303 0404 0404 0303 0fa3 0000 0000 4500 003c 4706 4000 ff06 2aac 0404 0404 0101 0101 5000 9d58 0000 0001 +4500 0038 0000 0000 ff01 a7b9 0a02 0202 0404 0404 0303 a7fc 0000 0000 4500 003c 4706 4000 ff06 20aa 0404 0404 0a02 0202 5000 0500 0000 0001 -4500 0058 809a 0000 ff01 2cfd 0303 0303 0404 0404 0303 0735 0000 0000 4500 003c 4706 4000 ff06 2aac 0404 0404 0101 0101 5000 9d58 0000 0001 0000 0000 a002 16d0 3ddc 0000 0204 05b4 0402 080a 0047 fbb0 0000 0000 0103 0300 - -4500 0038 809a 0000 ff01 2b1b 0303 0303 0505 0505 0303 0fa3 0000 0000 4500 003c 4706 4000 ff06 2aab 0404 0404 0101 0102 5000 9d58 0000 0001 +4500 0058 0001 0000 ff01 a798 0a02 0202 0404 0404 0303 1137 0000 0000 4500 003c 4706 4000 ff06 20aa 0404 0404 0a02 0202 5000 0500 0000 0001 0000 0000 a002 16d0 cc32 0000 0204 05b4 0402 080a 0047 fbb0 0000 0000 0103 0300 +0 ------------------------------- diff --git a/contrib/ipfilter/test/expected/ni17 b/contrib/ipfilter/test/expected/ni17 new file mode 100644 index 000000000000..74eb4ddc5f9c --- /dev/null +++ b/contrib/ipfilter/test/expected/ni17 @@ -0,0 +1,7 @@ +< le0 ip #0 40(20) 6 10.2.2.5,2000 > 10.1.1.252,3128 +< le0 ip #0 40(20) 6 10.2.2.6,2000 > 10.1.2.252,3128 +< le0 ip #0 40(20) 6 10.2.2.7,2000 > 10.1.3.252,3128 +< le0 ip #0 40(20) 6 10.2.2.7,2001 > 10.1.3.252,3128 +< le0 ip #0 40(20) 6 10.2.2.8,2000 > 10.1.1.253,3128 +< le0 ip #0 40(20) 6 10.2.2.9,2000 > 10.1.2.253,3128 +------------------------------- diff --git a/contrib/ipfilter/test/expected/ni18 b/contrib/ipfilter/test/expected/ni18 new file mode 100644 index 000000000000..defc59cca97b --- /dev/null +++ b/contrib/ipfilter/test/expected/ni18 @@ -0,0 +1,5 @@ +< hme0 ip #0 40(20) 6 2.2.2.2,3000 > 1.1.1.1,80 +< hme0 ip #0 40(20) 6 2.2.2.2,3000 > 192.168.1.1,80 +> hme1 ip #0 40(20) 6 203.1.1.1,10000 > 4.5.6.7,80 +> hme1 ip #0 40(20) 6 10.1.1.2,5050 > 4.5.6.7,80 +------------------------------- diff --git a/contrib/ipfilter/test/expected/ni19 b/contrib/ipfilter/test/expected/ni19 index fa40771a0f13..e55c75dc3837 100644 --- a/contrib/ipfilter/test/expected/ni19 +++ b/contrib/ipfilter/test/expected/ni19 @@ -34,16 +34,10 @@ 4500 0034 118c 4000 4006 ec87 0a01 0104 c0a8 7103 03ff 03f0 91d4 c8a7 66e5 b811 8011 05b4 d54e 0000 0101 080a 0039 dd6d 0000 0000 -4500 0028 e404 4000 4006 1a1b c0a8 7103 0a01 0104 03f1 0202 6523 90eb 915a a5cb 5010 8328 bcd3 0000 - -4500 0034 e405 4000 4006 1a0e c0a8 7103 0a01 0104 03f0 03ff 66e5 b811 91d4 c8a8 8010 8328 57d7 0000 0101 080a 0000 0004 0039 dd6c - -4500 0028 e40a 4000 4006 1a15 c0a8 7103 0a01 0104 03f1 0202 6523 90eb 915a a5cb 5011 832c bcce 0000 - -4500 0034 e40b 4000 4006 1a08 c0a8 7103 0a01 0104 03f0 03ff 66e5 b811 91d4 c8a8 8011 832c 57d2 0000 0101 080a 0000 0004 0039 dd6c - -4500 0028 0004 4000 4006 fe1b 0a01 0104 c0a8 7103 0202 03f1 915a a5cb 6523 90ec 5010 05b4 3a47 0000 - -4500 0034 118e 4000 4006 ec85 0a01 0104 c0a8 7103 03ff 03f0 91d4 c8a8 66e5 b812 8010 05b4 d548 0000 0101 080a 0039 dd6e 0000 0004 - +0 +0 +0 +0 +0 +0 ------------------------------- diff --git a/contrib/ipfilter/test/expected/ni2 b/contrib/ipfilter/test/expected/ni2 index e2a7eb89ffaf..69a52724f0c1 100644 --- a/contrib/ipfilter/test/expected/ni2 +++ b/contrib/ipfilter/test/expected/ni2 @@ -14,6 +14,6 @@ 4500 05dc e483 4000 7e06 44bb c0a8 0133 0a01 0201 0077 05f6 fbdf 1a75 a664 248c 5010 2232 9f2d 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 1111 2222 3333 0000 0000 0000 0000 0000 0000 1111 2222 3333 0000 0000 0000 0000 0000 0000 1111 2222 3333 0000 0000 0000 0000 0000 0000 1111 2222 3333 0000 0000 0000 0000 0000 0000 1111 2222 3333 0000 0000 0000 0000 0000 0000 1111 2222 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 1111 2222 3333 0000 0000 0000 0000 0000 0000 1111 2222 3333 0000 0000 0000 0000 0000 0000 1111 2222 3333 0000 0000 0000 0000 0000 0000 1111 2222 3333 0000 0000 0000 0000 0000 0000 1111 2222 3333 0000 0000 0000 0000 0000 0000 1111 2222 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 1111 2222 3333 0000 0000 0000 0000 0000 0000 1111 2222 3333 0000 0000 0000 0000 0000 0000 1111 2222 3333 0000 0000 0000 0000 0000 0000 1111 2222 3333 0000 0000 0000 0000 0000 0000 1111 2222 3333 0000 0000 0000 0000 0000 0000 1111 2222 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 1111 2222 3333 0000 0000 0000 0000 0000 0000 1111 2222 3333 0000 0000 0000 0000 0000 0000 1111 2222 3333 0000 0000 0000 0000 0000 0000 1111 2222 3333 0000 0000 0000 0000 0000 0000 1111 2222 3333 0000 0000 0000 0000 0000 0000 1111 2222 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 1111 2222 3333 0000 0000 0000 0000 0000 0000 1111 2222 3333 0000 0000 0000 0000 0000 0000 1111 2222 3333 0000 0000 0000 0000 0000 0000 1111 2222 3333 0000 0000 0000 0000 0000 0000 1111 2222 3333 0000 0000 0000 0000 0000 0000 1111 2222 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 1111 2222 3333 0000 0000 0000 0000 0000 0000 1111 2222 3333 0000 0000 0000 0000 0000 0000 1111 2222 3333 0000 0000 0000 0000 0000 0000 1111 2222 3333 0000 0000 0000 0000 0000 0000 1111 2222 3333 0000 0000 0000 0000 0000 0000 1111 2222 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 1111 2222 3331 0000 0000 0000 0000 0000 0000 1111 2222 3333 0000 0000 0000 0000 0000 0000 1111 2222 3333 0000 0000 0000 0000 0000 0000 1111 2222 3333 0000 0000 0000 0000 0000 0000 1111 2222 3333 0000 0000 0000 0000 0000 0000 1111 2222 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 1111 2222 3333 0000 0000 0000 0000 0000 0000 1111 2222 3333 0000 0000 0000 0000 0000 0000 1111 2222 3333 0000 0000 0000 0000 0000 0000 1111 2222 3333 0000 0000 0000 0000 0000 0000 1111 2222 3333 0000 0000 0000 0000 0000 0000 1111 2222 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 1111 2222 3333 0000 0000 0000 0000 0000 0000 1111 2222 3333 0000 0000 0000 0000 0000 0000 1111 2222 3333 0000 0000 0000 0000 0000 0000 1111 2222 3333 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 -4500 0038 0004 4000 4001 76e4 0101 0101 c0a8 0133 0304 9dea 0000 05a0 4500 05dc e483 4000 7e06 4ebb c0a8 0133 0101 0101 0077 9c40 fbdf 1a75 +4500 0038 0004 4000 4001 76e4 0101 0101 c0a8 0133 0304 444f 0000 05a0 4500 05dc e483 4000 7e06 4ebb c0a8 0133 0101 0101 0077 9c40 fbdf 1a75 ------------------------------- diff --git a/contrib/ipfilter/test/expected/ni20 b/contrib/ipfilter/test/expected/ni20 index 6001a5af9eb8..913ef0b1e461 100644 --- a/contrib/ipfilter/test/expected/ni20 +++ b/contrib/ipfilter/test/expected/ni20 @@ -34,16 +34,36 @@ 4500 0034 118c 4000 4006 ec87 0a01 0104 c0a8 7103 03ff 03f0 91d4 c8a7 66e5 b811 8011 05b4 d54e 0000 0101 080a 0039 dd6d 0000 0000 -4500 0028 e404 4000 4006 f372 c0a8 7103 c0a8 7104 03f1 0202 6523 90eb 915a a5cb 5010 8328 962b 0000 +0 +0 +0 +0 +0 +0 +List of active MAP/Redirect filters: +rdr bge0 10.1.1.4/32 port 514 -> 192.168.113.4/32 port 514 tcp proxy rcmd -4500 0034 e405 4000 4006 f365 c0a8 7103 c0a8 7104 03f0 03ff 66e5 b811 91d4 c8a8 8010 8328 312f 0000 0101 080a 0000 0004 0039 dd6c - -4500 0028 e40a 4000 4006 f36c c0a8 7103 c0a8 7104 03f1 0202 6523 90eb 915a a5cb 5011 832c 9626 0000 - -4500 0034 e40b 4000 4006 f35f c0a8 7103 c0a8 7104 03f0 03ff 66e5 b811 91d4 c8a8 8011 832c 312a 0000 0101 080a 0000 0004 0039 dd6c - -4500 0028 0004 4000 4006 d773 c0a8 7104 c0a8 7103 0202 03f1 915a a5cb 6523 90ec 5010 05b4 139f 0000 - -4500 0034 118e 4000 4006 c5dd c0a8 7104 c0a8 7103 03ff 03f0 91d4 c8a8 66e5 b812 8010 05b4 aea0 0000 0101 080a 0039 dd6e 0000 0004 +List of active sessions: +MAP 192.168.113.4 1023 <- -> 10.1.1.4 1023 [192.168.113.3 1008] +RDR 192.168.113.4 514 <- -> 10.1.1.4 514 [192.168.113.3 1009] + proxy active +Hostmap table: +192.168.113.4,192.168.113.3 -> 10.1.1.4,0.0.0.0 (use = 1) +List of active state sessions: +List of configured pools +List of configured hash tables +List of groups configured (set 0) +List of groups configured (set 1) +Rules configured (set 0, in) +5 block in all +1 pass in quick on bge0 proto tcp from any to any port = 514 flags S/FSRPAU keep state +Rules configured (set 0, out) +2 block out all +Rules configured (set 1, in) +Rules configured (set 1, out) +Accounting rules configured (set 0, in) +Accounting rules configured (set 0, out) +Accounting rules configured (set 1, in) +Accounting rules configured (set 1, out) ------------------------------- diff --git a/contrib/ipfilter/test/expected/ni21 b/contrib/ipfilter/test/expected/ni21 index 349ae2391cc0..53e64a5a1f97 100644 --- a/contrib/ipfilter/test/expected/ni21 +++ b/contrib/ipfilter/test/expected/ni21 @@ -1,4 +1,6 @@ -ip #0 20(20) 0 4.4.4.4 > 3.3.3.3 -ip #0 20(20) 0 3.3.3.3 > 2.2.2.2 -ip #0 20(20) 0 4.4.4.4 > 3.3.3.3 +> eri0 ip #0 20(20) 0 4.4.4.4 > 3.3.3.3 +0 +< lan0 ip #0 20(20) 0 3.3.3.3 > 2.2.2.2 +> eri0 ip #0 20(20) 0 4.4.4.4 > 3.3.3.3 +0 ------------------------------- diff --git a/contrib/ipfilter/test/expected/ni23 b/contrib/ipfilter/test/expected/ni23 index 24909b07f059..586373c070ca 100644 --- a/contrib/ipfilter/test/expected/ni23 +++ b/contrib/ipfilter/test/expected/ni23 @@ -1,8 +1,9 @@ -ip #0 28(20) 17 4.4.4.4,6700 > 2.2.2.2,4500 -ip #0 28(20) 17 2.2.2.2,4500 > 3.3.3.1,6700 -ip #0 28(20) 17 1.1.2.3,4500 > 3.3.3.1,6700 +> ppp0 ip #0 28(20) 17 4.4.4.4,6700 > 2.2.2.2,4500 +0 +< hme0 ip #0 28(20) 17 2.2.2.2,4500 > 3.3.3.1,6700 +> bge0 ip #0 28(20) 17 1.1.2.3,4500 > 3.3.3.1,6700 List of active MAP/Redirect filters: -rdr le0,bge0 1.1.0.0/16 -> 2.2.2.2 ip +rdr le0,bge0 1.1.0.0/16 -> 2.2.2.2/32 ip map hme0,ppp0 3.3.3.0/24 -> 4.4.4.4/32 List of active sessions: @@ -10,20 +11,27 @@ MAP 3.3.3.1 6700 <- -> 4.4.4.4 6700 [2.2.2.2 4500] RDR 2.2.2.2 4500 <- -> 1.1.2.3 4500 [3.3.3.1 6700] Hostmap table: -3.3.3.1,2.2.2.2 -> 4.4.4.4 (use = 1 hv = 0) +3.3.3.1,2.2.2.2 -> 4.4.4.4,0.0.0.0 (use = 1) List of active state sessions: -3.3.3.1 -> 2.2.2.2 pass 0x40008402 pr 17 state 0/0 - tag 0 ttl 24 6700 -> 4500 - forward: pkts in 1 bytes in 28 pkts out 1 bytes out 28 - backward: pkts in 1 bytes in 28 pkts out 1 bytes out 28 - pass in keep state IPv4 - pkt_flags & 0(0) = 0, pkt_options & ffffffff = 0, ffffffff = 0 - pkt_security & ffff = 0, pkt_auth & ffff = 0 - is_flx 0x8001 0x8001 0x8001 0x1 +4:udp src:3.3.3.1,6700 dst:2.2.2.2,4500 24 + FWD: IN pkts 1 bytes 28 OUT pkts 1 bytes 28 + REV: IN pkts 1 bytes 28 OUT pkts 1 bytes 28 + tag 0 pass 0x2008402 = pass in keep state interfaces: in X[le0],X[hme0] out X[ppp0],X[bge0] Sync status: not synchronized List of configured pools List of configured hash tables List of groups configured (set 0) List of groups configured (set 1) +Rules configured (set 0, in) +1 block in all +1 pass in on le0,hme0 to ppp0:3.3.3.254 out-via ppp0,bge0 inet proto udp from any to any keep state +Rules configured (set 0, out) +0 block out all +Rules configured (set 1, in) +Rules configured (set 1, out) +Accounting rules configured (set 0, in) +Accounting rules configured (set 0, out) +Accounting rules configured (set 1, in) +Accounting rules configured (set 1, out) ------------------------------- diff --git a/contrib/ipfilter/test/expected/ni4 b/contrib/ipfilter/test/expected/ni4 index c9f7504d7ac1..627aa1909da7 100644 --- a/contrib/ipfilter/test/expected/ni4 +++ b/contrib/ipfilter/test/expected/ni4 @@ -1,6 +1,6 @@ 4500 003c 0000 4000 ff06 67a8 0606 0606 0404 0404 9c40 0050 0000 0001 0000 0000 a002 16d0 849a 0000 0204 05b4 0402 080a 0047 fbb0 0000 0000 0103 0300 -4500 0038 809a 0000 ff01 3121 0303 0303 0202 0202 0303 acab 0000 0000 4500 003c 4706 4000 ff06 28aa 0202 0202 0404 0404 5000 0050 0000 0001 +4500 0038 809a 0000 ff01 3121 0303 0303 0202 0202 0303 acac 0000 0000 4500 003c 4706 4000 ff06 28aa 0202 0202 0404 0404 5000 0050 0000 0001 4500 0058 809a 0000 ff01 3101 0303 0303 0202 0202 0303 0937 0000 0000 4500 003c 4706 4000 ff06 28aa 0202 0202 0404 0404 5000 0050 0000 0001 0000 0000 a002 16d0 d8e2 0000 0204 05b4 0402 080a 0047 fbb0 0000 0000 0103 0300 diff --git a/contrib/ipfilter/test/expected/ni5 b/contrib/ipfilter/test/expected/ni5 index e713cf285101..14d983759f6c 100644 --- a/contrib/ipfilter/test/expected/ni5 +++ b/contrib/ipfilter/test/expected/ni5 @@ -4,6 +4,7 @@ 4500 0028 0001 4000 ff06 02ff 0101 0101 96cb e002 8032 0015 bd6b c9c9 3786 76c5 5010 269c 5aa0 0000 +ipf_p_ftp_servert_valid:i(0) < 5 4500 006f ffde 4000 ef06 5330 96cb e002 c0a8 0103 0015 8032 3786 76c5 bd6b c9c9 5018 269c 967e 0000 3232 302d 636f 6f6d 6273 2e61 6e75 2e65 6475 2e61 7520 4e63 4654 5064 2053 6572 7665 7220 2866 7265 6520 6564 7563 6174 696f 6e61 6c20 6c69 6365 6e73 6529 2072 6561 6479 2e0d 0a 4500 0028 0002 4000 ff06 02fe 0101 0101 96cb e002 8032 0015 bd6b c9c9 3786 770c 5010 269c 5a59 0000 @@ -22,6 +23,7 @@ 4500 0036 0006 4000 ff06 02ec 0101 0101 96cb e002 8032 0015 bd6b c9d9 3786 77ef 5018 269c 373f 0000 5041 5353 2061 7661 6c6f 6e40 0d0a +ipf_p_ftp_servert_valid:i(0) < 5 4500 005f ffe2 4000 ef06 533c 96cb e002 c0a8 0103 0015 8032 3786 77ef bd6b c9e7 5018 269c 895e 0000 3233 302d 596f 7520 6172 6520 7573 6572 2023 3420 6f66 2035 3020 7369 6d75 6c74 616e 656f 7573 2075 7365 7273 2061 6c6c 6f77 6564 2e0d 0a 4500 0028 0007 4000 ff06 02f9 0101 0101 96cb e002 8032 0015 bd6b c9e7 3786 7826 5010 269c 5921 0000 @@ -72,32 +74,23 @@ 4500 0028 ffec 4000 ef06 5369 96cb e002 c0a8 0103 0014 8034 d9f8 11d4 0000 0000 5010 2238 e90d 0000 -4500 0063 ffed 4000 ef06 532d 96cb e002 c0a8 0103 0014 8033 d9f8 11d5 bd78 5c13 5018 269c a315 0000 636f 6f6d 6273 7061 7065 7273 0d0a 6465 7074 730d 0a66 6f75 6e64 2d66 696c 6573 0d0a 696e 636f 6d69 6e67 0d0a 6e6c 632d 7465 7374 0d0a 7075 620d 0a - -4500 0028 0014 4000 ff06 02ec 0101 0101 96cb e002 8033 0014 bd78 5c13 d9f8 1210 5010 6348 4de0 0000 - -4500 0028 ffee 4000 ef06 5367 96cb e002 c0a8 0103 0014 8033 d9f8 1210 bd78 5c13 5011 269c cae1 0000 - -4500 0028 10dd 4000 ff06 3279 c0a8 0103 96cb e002 8033 0014 bd78 5c13 d9f8 1211 5010 6348 8e35 0000 - -4500 0028 10dd 4000 ff06 3279 c0a8 0103 96cb e002 8033 0014 bd78 5c13 d9f8 1211 5011 6348 8e34 0000 - -4500 0028 ffef 4000 ef06 5366 96cb e002 c0a8 0103 0014 8033 d9f8 1211 bd78 5c14 5010 269c cae0 0000 - +0 +0 +0 +0 +0 +0 4500 0040 fff0 4000 ef06 534d 96cb e002 c0a8 0103 0015 8032 3786 7903 bd6b ca3f 5018 269c 7c80 0000 3232 3620 4c69 7374 696e 6720 636f 6d70 6c65 7465 642e 0d0a -4500 0028 0015 4000 ff06 02eb 0101 0101 96cb e002 8032 0015 bd6b ca2f 3786 791b 5010 269c 57e4 0000 +4500 0028 0014 4000 ff06 02ec 0101 0101 96cb e002 8032 0015 bd6b ca2f 3786 791b 5010 269c 57e4 0000 -4500 002e 0016 4000 ff06 02e4 0101 0101 96cb e002 8032 0015 bd6b ca2f 3786 791b 5018 269c b022 0000 5155 4954 0d0a +4500 002e 0015 4000 ff06 02e5 0101 0101 96cb e002 8032 0015 bd6b ca2f 3786 791b 5018 269c b022 0000 5155 4954 0d0a 4500 0036 fff2 4000 ef06 5355 96cb e002 c0a8 0103 0015 8032 3786 791b bd6b ca45 5018 269c a936 0000 3232 3120 476f 6f64 6279 652e 0d0a -4500 0028 0017 4000 ff06 02e9 0101 0101 96cb e002 8032 0015 bd6b ca35 3786 7929 5011 269c 57cf 0000 - -4500 0028 fff3 4000 ef06 5362 96cb e002 c0a8 0103 0015 8032 3786 7929 bd6b ca45 5011 269c 9815 0000 - -4500 0028 10e3 4000 ff06 3273 c0a8 0103 96cb e002 8032 0015 bd6b ca3d 3786 792a 5010 269c 981d 0000 - -4500 0028 fff4 4000 ef06 5361 96cb e002 c0a8 0103 0015 8032 3786 792a bd6b ca46 5010 269c 9814 0000 +4500 0028 0016 4000 ff06 02ea 0101 0101 96cb e002 8032 0015 bd6b ca35 3786 7929 5011 269c 57cf 0000 +0 +0 +0 ------------------------------- diff --git a/contrib/ipfilter/test/expected/ni6 b/contrib/ipfilter/test/expected/ni6 index 0da034a781b3..e70412b7f471 100644 --- a/contrib/ipfilter/test/expected/ni6 +++ b/contrib/ipfilter/test/expected/ni6 @@ -1,17 +1,63 @@ -4500 0054 cd8a 4000 ff11 1fbb c0a8 0601 c0a8 0701 8075 006f 0040 d26e 3e1d d249 0000 0000 0000 0002 0001 86a0 0000 0002 0000 0003 0000 0000 0000 0000 0000 0000 0000 0000 0001 86a3 0000 0003 0000 0011 0000 0000 +< nf0 ip #52618 84(20) 17 192.168.6.1,32885 > 192.168.7.1,111 +> qfe0 ip #0 84(20) 17 192.168.7.2,32885 > 192.168.7.1,111 +< qfe0 ip #52611 56(20) 17 192.168.7.1,111 > 192.168.6.1,32885 +> nf0 ip #1 56(20) 17 192.168.6.2,111 > 192.168.6.1,32885 +< nf0 ip #54694 68(20) 17 192.168.6.1,32991 > 192.168.7.1,2049 +> qfe0 ip #2 68(20) 17 192.168.7.2,32991 > 192.168.7.1,2049 +< qfe0 ip #0 52(20) 17 192.168.7.1,2049 > 192.168.6.1,32991 +> nf0 ip #3 52(20) 17 192.168.6.2,2049 > 192.168.6.1,32991 +List of active MAP/Redirect filters: +rdr nf0 192.168.6.2/32 port 111 -> 192.168.7.1/32 port 111 udp proxy rpcbu +rdr nf0 192.168.6.2/32 port 111 -> 192.168.7.1/32 port 111 tcp proxy rpcbt +map qfe0 192.168.6.0/24 -> 192.168.7.2/32 -4500 0054 0000 4000 ff11 ec44 c0a8 0702 c0a8 0701 8075 006f 0040 d16d 3e1d d249 0000 0000 0000 0002 0001 86a0 0000 0002 0000 0003 0000 0000 0000 0000 0000 0000 0000 0000 0001 86a3 0000 0003 0000 0011 0000 0000 - -4500 0038 cd83 4000 ff11 1fde c0a8 0701 c0a8 0601 006f 8075 0024 d805 3e1d d249 0000 0001 0000 0000 0000 0000 0000 0000 0000 0000 0000 0801 - -4500 0038 0001 4000 ff11 ee5f c0a8 0602 c0a8 0601 006f 8075 0024 d904 3e1d d249 0000 0001 0000 0000 0000 0000 0000 0000 0000 0000 0000 0801 - -4500 0044 d5a6 4000 ff11 17af c0a8 0601 c0a8 0701 80df 0801 0030 03f1 3e10 1fb1 0000 0000 0000 0002 0001 86a3 0000 0002 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 - -4500 0044 0002 4000 ff11 ec52 c0a8 0702 c0a8 0701 80df 0801 0030 02f0 3e10 1fb1 0000 0000 0000 0002 0001 86a3 0000 0002 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 - -4500 0034 0000 4000 fe11 ee65 c0a8 0701 c0a8 0601 0801 80df 0020 8ab8 3e10 1fb1 0000 0001 0000 0000 0000 0000 0000 0000 0000 0000 - -4500 0034 0003 4000 fe11 ef61 c0a8 0602 c0a8 0601 0801 80df 0020 0000 3e10 1fb1 0000 0001 0000 0000 0000 0000 0000 0000 0000 0000 +List of active sessions: +MAP 192.168.6.1 32991 <- -> 192.168.7.2 32991 [192.168.7.1 2049] +RDR 192.168.7.1 2049 <- -> 192.168.6.2 2049 [192.168.6.1 32991] +RDR CLONE 192.168.7.1 2049 <- -> 192.168.6.2 2049 [192.168.6.1 0] +MAP 192.168.6.1 32885 <- -> 192.168.7.2 32885 [192.168.7.1 111] +RDR 192.168.7.1 111 <- -> 192.168.6.2 111 [192.168.6.1 32885] + proxy active +Hostmap table: +192.168.6.1,192.168.7.1 -> 192.168.7.2,0.0.0.0 (use = 2) +List of active state sessions: +4:udp src:192.168.6.1,32991 dst:192.168.7.1,2049 24 + FWD: IN pkts 2 bytes 96 OUT pkts 1 bytes 68 + REV: IN pkts 1 bytes 52 OUT pkts 1 bytes 52 + tag 0 pass 0x502 = pass in quick keep state + interfaces: in X[nf0],X[qfe0] out X[qfe0],X[nf0] + Sync status: not synchronized +4:udp src:192.168.6.1,* dst:192.168.7.1,2049 240 CLONE + FWD: IN pkts 1 bytes 28 OUT pkts 0 bytes 0 + REV: IN pkts 0 bytes 0 OUT pkts 0 bytes 0 + tag 0 pass 0x502 = pass in quick keep state + interfaces: in X[nf0],X[] out X[],X[] + Sync status: not synchronized +4:udp src:192.168.6.1,32885 dst:192.168.7.1,111 24 + FWD: IN pkts 1 bytes 84 OUT pkts 1 bytes 84 + REV: IN pkts 1 bytes 56 OUT pkts 1 bytes 56 + tag 0 pass 0x2008502 = pass in quick keep state + interfaces: in X[nf0],X[qfe0] out X[qfe0],X[nf0] + Sync status: not synchronized +List of configured pools +List of configured hash tables +List of groups configured (set 0) +List of groups configured (set 1) +Rules configured (set 0, in) +0 pass in quick on nf0 proto tcp from any to any port = 111 flags S/FSRPAU keep state +1 pass in quick on nf0 proto udp from any to any port = 111 keep state +0 block return-rst in log quick on nf0 proto tcp from any to any +0 block in log quick on nf0 inet from 192.168.7.0/24 to any +0 block return-rst in log quick on qfe0 proto tcp from any to any +0 block in log quick on qfe0 inet from 192.168.6.0/24 to any +Rules configured (set 0, out) +0 block out log quick on qfe0 inet from 192.168.7.0/24 to any +0 block out log quick on nf0 inet from 192.168.6.0/24 to any +Rules configured (set 1, in) +Rules configured (set 1, out) +Accounting rules configured (set 0, in) +Accounting rules configured (set 0, out) +Accounting rules configured (set 1, in) +Accounting rules configured (set 1, out) ------------------------------- diff --git a/contrib/ipfilter/test/expected/ni8 b/contrib/ipfilter/test/expected/ni8 index 689ccaa87ead..e0d518270a1f 100644 --- a/contrib/ipfilter/test/expected/ni8 +++ b/contrib/ipfilter/test/expected/ni8 @@ -1,6 +1,6 @@ 4500 003c 4706 4000 ff06 2aac 0404 0404 0101 0101 5000 9d58 0000 0001 0000 0000 a002 16d0 3ddc 0000 0204 05b4 0402 080a 0047 fbb0 0000 0000 0103 0300 -4500 0038 0000 0000 ff01 a7b9 0a02 0202 0404 0404 0303 a7fb 0000 0000 4500 003c 4706 4000 ff06 20aa 0404 0404 0a02 0202 5000 0500 0000 0001 +4500 0038 0000 0000 ff01 a7b9 0a02 0202 0404 0404 0303 a7fc 0000 0000 4500 003c 4706 4000 ff06 20aa 0404 0404 0a02 0202 5000 0500 0000 0001 4500 0058 0001 0000 ff01 a798 0a02 0202 0404 0404 0303 1137 0000 0000 4500 003c 4706 4000 ff06 20aa 0404 0404 0a02 0202 5000 0500 0000 0001 0000 0000 a002 16d0 cc32 0000 0204 05b4 0402 080a 0047 fbb0 0000 0000 0103 0300 diff --git a/contrib/ipfilter/test/expected/p1 b/contrib/ipfilter/test/expected/p1 index 9f02804439e8..58dc6813f329 100644 --- a/contrib/ipfilter/test/expected/p1 +++ b/contrib/ipfilter/test/expected/p1 @@ -13,9 +13,18 @@ List of active sessions: Hostmap table: List of active state sessions: List of configured pools -table role = ipf type = tree number = 100 - { 1.1.1.1/32; ! 2.2.0.0/16; 2.2.2.0/24; }; +table role=ipf type=tree number=100 + { 1.1.1.1/32; ! 2.2.0.0/16; 2.2.2.0/24; ef00::5/128; }; List of configured hash tables List of groups configured (set 0) List of groups configured (set 1) +Rules configured (set 0, in) +2 pass in from pool/100 to any +Rules configured (set 0, out) +Rules configured (set 1, in) +Rules configured (set 1, out) +Accounting rules configured (set 0, in) +Accounting rules configured (set 0, out) +Accounting rules configured (set 1, in) +Accounting rules configured (set 1, out) ------------------------------- diff --git a/contrib/ipfilter/test/expected/p10 b/contrib/ipfilter/test/expected/p10 new file mode 100644 index 000000000000..9f09502d2499 --- /dev/null +++ b/contrib/ipfilter/test/expected/p10 @@ -0,0 +1,40 @@ +< bge0 ip #0 40(20) 6 5.5.5.5,10000 > 1.1.1.2,80 +< bge0 ip #0 40(20) 6 5.5.5.6,10000 > 1.1.1.9,80 +< bge0 ip #0 40(20) 6 5.5.5.7,10000 > 1.1.1.2,80 +< bge0 ip #0 40(20) 6 5.5.5.8,10000 > 1.1.1.9,80 +< bge0 ip #0 40(20) 6 5.5.5.9,10000 > 1.1.1.4,80 +< bge0 ip #0 40(20) 6 5.5.6.5,10000 > 1.1.1.4,80 +< bge0 ip #0 40(20) 6 5.5.6.6,10000 > 1.1.1.9,80 +< bge0 ip #0 40(20) 6 5.5.6.7,10000 > 1.1.1.5,80 +< bge0 ip #0 40(20) 6 5.5.6.8,10000 > 1.1.1.5,80 +< bge0 ip #0 40(20) 6 5.5.6.9,10000 > 1.1.1.9,80 +List of active MAP/Redirect filters: +rewrite in on bge0 proto tcp from 0/0 to 0/0 port = 80 -> src 0/0 dst dstlist/servers; + +List of active sessions: +RWR-RDR 5.5.6.9 10000 9.9.9.9 80 <- -> 5.5.6.9 10000 1.1.1.9 80 +RWR-RDR 5.5.6.8 10000 9.9.9.9 80 <- -> 5.5.6.8 10000 1.1.1.5 80 +RWR-RDR 5.5.6.7 10000 9.9.9.9 80 <- -> 5.5.6.7 10000 1.1.1.5 80 +RWR-RDR 5.5.6.6 10000 9.9.9.9 80 <- -> 5.5.6.6 10000 1.1.1.9 80 +RWR-RDR 5.5.6.5 10000 9.9.9.9 80 <- -> 5.5.6.5 10000 1.1.1.4 80 +RWR-RDR 5.5.5.9 10000 9.9.9.9 80 <- -> 5.5.5.9 10000 1.1.1.4 80 +RWR-RDR 5.5.5.8 10000 9.9.9.9 80 <- -> 5.5.5.8 10000 1.1.1.9 80 +RWR-RDR 5.5.5.7 10000 9.9.9.9 80 <- -> 5.5.5.7 10000 1.1.1.2 80 +RWR-RDR 5.5.5.6 10000 9.9.9.9 80 <- -> 5.5.5.6 10000 1.1.1.9 80 +RWR-RDR 5.5.5.5 10000 9.9.9.9 80 <- -> 5.5.5.5 10000 1.1.1.2 80 + +Hostmap table: +List of active state sessions: +List of configured pools +List of configured hash tables +List of groups configured (set 0) +List of groups configured (set 1) +Rules configured (set 0, in) +Rules configured (set 0, out) +Rules configured (set 1, in) +Rules configured (set 1, out) +Accounting rules configured (set 0, in) +Accounting rules configured (set 0, out) +Accounting rules configured (set 1, in) +Accounting rules configured (set 1, out) +------------------------------- diff --git a/contrib/ipfilter/test/expected/p11 b/contrib/ipfilter/test/expected/p11 new file mode 100644 index 000000000000..e907fbb16ab1 --- /dev/null +++ b/contrib/ipfilter/test/expected/p11 @@ -0,0 +1,40 @@ +< bge0 ip #0 40(20) 6 5.5.5.5,10000 > 1.1.1.5,80 +< bge0 ip #0 40(20) 6 5.5.5.6,10000 > 1.1.1.5,80 +< bge0 ip #0 40(20) 6 5.5.5.7,10000 > 1.1.1.5,80 +< bge0 ip #0 40(20) 6 5.5.5.8,10000 > 1.1.1.5,80 +< bge0 ip #0 40(20) 6 5.5.5.9,10000 > 1.1.1.5,80 +< bge0 ip #0 40(20) 6 5.5.6.5,10000 > 1.1.1.5,80 +< bge0 ip #0 40(20) 6 5.5.6.6,10000 > 1.1.1.5,80 +< bge0 ip #0 40(20) 6 5.5.6.7,10000 > 1.1.1.5,80 +< bge0 ip #0 40(20) 6 5.5.6.8,10000 > 1.1.1.5,80 +< bge0 ip #0 40(20) 6 5.5.6.9,10000 > 1.1.1.5,80 +List of active MAP/Redirect filters: +rewrite in on bge0 proto tcp from 0/0 to 0/0 port = 80 -> src 0/0 dst dstlist/servers; + +List of active sessions: +RWR-RDR 5.5.6.9 10000 9.9.9.9 80 <- -> 5.5.6.9 10000 1.1.1.5 80 +RWR-RDR 5.5.6.8 10000 9.9.9.9 80 <- -> 5.5.6.8 10000 1.1.1.5 80 +RWR-RDR 5.5.6.7 10000 9.9.9.9 80 <- -> 5.5.6.7 10000 1.1.1.5 80 +RWR-RDR 5.5.6.6 10000 9.9.9.9 80 <- -> 5.5.6.6 10000 1.1.1.5 80 +RWR-RDR 5.5.6.5 10000 9.9.9.9 80 <- -> 5.5.6.5 10000 1.1.1.5 80 +RWR-RDR 5.5.5.9 10000 9.9.9.9 80 <- -> 5.5.5.9 10000 1.1.1.5 80 +RWR-RDR 5.5.5.8 10000 9.9.9.9 80 <- -> 5.5.5.8 10000 1.1.1.5 80 +RWR-RDR 5.5.5.7 10000 9.9.9.9 80 <- -> 5.5.5.7 10000 1.1.1.5 80 +RWR-RDR 5.5.5.6 10000 9.9.9.9 80 <- -> 5.5.5.6 10000 1.1.1.5 80 +RWR-RDR 5.5.5.5 10000 9.9.9.9 80 <- -> 5.5.5.5 10000 1.1.1.5 80 + +Hostmap table: +List of active state sessions: +List of configured pools +List of configured hash tables +List of groups configured (set 0) +List of groups configured (set 1) +Rules configured (set 0, in) +Rules configured (set 0, out) +Rules configured (set 1, in) +Rules configured (set 1, out) +Accounting rules configured (set 0, in) +Accounting rules configured (set 0, out) +Accounting rules configured (set 1, in) +Accounting rules configured (set 1, out) +------------------------------- diff --git a/contrib/ipfilter/test/expected/p12 b/contrib/ipfilter/test/expected/p12 new file mode 100644 index 000000000000..d097d5117b65 --- /dev/null +++ b/contrib/ipfilter/test/expected/p12 @@ -0,0 +1,40 @@ +< bge0 ip #0 40(20) 6 5.5.5.5,10000 > 1.1.1.2,80 +< bge0 ip #0 40(20) 6 5.5.5.6,10000 > 1.1.1.5,80 +< bge0 ip #0 40(20) 6 5.5.5.7,10000 > 1.1.1.4,80 +< bge0 ip #0 40(20) 6 5.5.5.8,10000 > 1.1.1.4,80 +< bge0 ip #0 40(20) 6 5.5.5.9,10000 > 1.1.1.9,80 +< bge0 ip #0 40(20) 6 5.5.6.5,10000 > 1.1.1.4,80 +< bge0 ip #0 40(20) 6 5.5.6.6,10000 > 1.1.1.4,80 +< bge0 ip #0 40(20) 6 5.5.6.7,10000 > 1.1.1.9,80 +< bge0 ip #0 40(20) 6 5.5.6.8,10000 > 1.1.1.9,80 +< bge0 ip #0 40(20) 6 5.5.6.9,10000 > 1.1.1.5,80 +List of active MAP/Redirect filters: +rewrite in on bge0 proto tcp from 0/0 to 0/0 port = 80 -> src 0/0 dst dstlist/servers; + +List of active sessions: +RWR-RDR 5.5.6.9 10000 9.9.9.9 80 <- -> 5.5.6.9 10000 1.1.1.5 80 +RWR-RDR 5.5.6.8 10000 9.9.9.9 80 <- -> 5.5.6.8 10000 1.1.1.9 80 +RWR-RDR 5.5.6.7 10000 9.9.9.9 80 <- -> 5.5.6.7 10000 1.1.1.9 80 +RWR-RDR 5.5.6.6 10000 9.9.9.9 80 <- -> 5.5.6.6 10000 1.1.1.4 80 +RWR-RDR 5.5.6.5 10000 9.9.9.9 80 <- -> 5.5.6.5 10000 1.1.1.4 80 +RWR-RDR 5.5.5.9 10000 9.9.9.9 80 <- -> 5.5.5.9 10000 1.1.1.9 80 +RWR-RDR 5.5.5.8 10000 9.9.9.9 80 <- -> 5.5.5.8 10000 1.1.1.4 80 +RWR-RDR 5.5.5.7 10000 9.9.9.9 80 <- -> 5.5.5.7 10000 1.1.1.4 80 +RWR-RDR 5.5.5.6 10000 9.9.9.9 80 <- -> 5.5.5.6 10000 1.1.1.5 80 +RWR-RDR 5.5.5.5 10000 9.9.9.9 80 <- -> 5.5.5.5 10000 1.1.1.2 80 + +Hostmap table: +List of active state sessions: +List of configured pools +List of configured hash tables +List of groups configured (set 0) +List of groups configured (set 1) +Rules configured (set 0, in) +Rules configured (set 0, out) +Rules configured (set 1, in) +Rules configured (set 1, out) +Accounting rules configured (set 0, in) +Accounting rules configured (set 0, out) +Accounting rules configured (set 1, in) +Accounting rules configured (set 1, out) +------------------------------- diff --git a/contrib/ipfilter/test/expected/p13 b/contrib/ipfilter/test/expected/p13 new file mode 100644 index 000000000000..aa529eada030 --- /dev/null +++ b/contrib/ipfilter/test/expected/p13 @@ -0,0 +1,30 @@ +nomatch +pass +nomatch +nomatch +nomatch +pass +nomatch +nomatch +List of active MAP/Redirect filters: + +List of active sessions: + +Hostmap table: +List of active state sessions: +List of configured pools +table role=all type=tree number=100 + { 1.1.1.1/32; ! 2.2.0.0/16; 2.2.2.0/24; ef00::5/128; }; +List of configured hash tables +List of groups configured (set 0) +List of groups configured (set 1) +Rules configured (set 0, in) +2 pass in from pool/100 to any +Rules configured (set 0, out) +Rules configured (set 1, in) +Rules configured (set 1, out) +Accounting rules configured (set 0, in) +Accounting rules configured (set 0, out) +Accounting rules configured (set 1, in) +Accounting rules configured (set 1, out) +------------------------------- diff --git a/contrib/ipfilter/test/expected/p2 b/contrib/ipfilter/test/expected/p2 index 67a7c3ea26f3..53887422b217 100644 --- a/contrib/ipfilter/test/expected/p2 +++ b/contrib/ipfilter/test/expected/p2 @@ -14,12 +14,22 @@ Hostmap table: List of active state sessions: List of configured pools List of configured hash tables -# 'anonymous' table -table role = ipf type = hash number = 2147483650 size = 3 +# 'anonymous' table refs 2 +table role=ipf type=hash number=2147483650 size=3 { 127.0.0.1/32; 4.4.0.0/16; }; -# 'anonymous' table -table role = ipf type = hash number = 2147483649 size = 3 +# 'anonymous' table refs 2 +table role=ipf type=hash number=2147483649 size=3 { 127.0.0.1/32; 4.4.0.0/16; }; List of groups configured (set 0) List of groups configured (set 1) +Rules configured (set 0, in) +1 block in from hash/2147483650 to any +Rules configured (set 0, out) +2 pass out from hash/2147483649 to any +Rules configured (set 1, in) +Rules configured (set 1, out) +Accounting rules configured (set 0, in) +Accounting rules configured (set 0, out) +Accounting rules configured (set 1, in) +Accounting rules configured (set 1, out) ------------------------------- diff --git a/contrib/ipfilter/test/expected/p3 b/contrib/ipfilter/test/expected/p3 index 94fde9e701af..c1e034325384 100644 --- a/contrib/ipfilter/test/expected/p3 +++ b/contrib/ipfilter/test/expected/p3 @@ -18,18 +18,28 @@ Hostmap table: List of active state sessions: List of configured pools List of configured hash tables -group-map out role = ipf number = 2010 size = 5 - { 5.0.0.0/8, group = 2040; 4.4.0.0/16, group = 2020; 2.2.2.2/32, group = 2020; }; -group-map in role = ipf number = 1010 size = 3 - { 3.3.0.0/16, group = 1030; 1.1.1.1/32, group = 1020; }; +group-map out role=ipf number=2010 size=5 + { 2.2.2.2/32, group=2020; 4.4.0.0/16, group=2020; 5.0.0.0/8, group=2040; }; +group-map in role=ipf number=1010 size=3 + { 1.1.1.1/32, group=1020; 3.3.0.0/16, group=1030; }; List of groups configured (set 0) -Dev.0. Group 1020 Ref 1 Flags 0x8000 +Dev.0. Group 1020 Ref 2 Flags 0x8000 2 pass in all group 1020 -Dev.0. Group 1030 Ref 1 Flags 0x8000 +Dev.0. Group 1030 Ref 2 Flags 0x8000 2 block in all group 1030 -Dev.0. Group 2020 Ref 2 Flags 0x4000 +Dev.0. Group 2020 Ref 3 Flags 0x4000 4 pass out all group 2020 -Dev.0. Group 2040 Ref 1 Flags 0x4000 +Dev.0. Group 2040 Ref 2 Flags 0x4000 2 block out all group 2040 List of groups configured (set 1) +Rules configured (set 0, in) +6 call now srcgrpmap/1010 in all +Rules configured (set 0, out) +6 call now dstgrpmap/2010 out all +Rules configured (set 1, in) +Rules configured (set 1, out) +Accounting rules configured (set 0, in) +Accounting rules configured (set 0, out) +Accounting rules configured (set 1, in) +Accounting rules configured (set 1, out) ------------------------------- diff --git a/contrib/ipfilter/test/expected/p4 b/contrib/ipfilter/test/expected/p4 new file mode 100644 index 000000000000..e7aa73fda3d6 --- /dev/null +++ b/contrib/ipfilter/test/expected/p4 @@ -0,0 +1,38 @@ +< anon0 ip #0 20(20) 0 127.0.0.1 > 127.0.0.1 +< anon0 ip #0 20(20) 0 1.1.1.1 > 1.2.1.1 +> anon0 ip #0 20(20) 0 127.0.0.1 > 127.0.0.1 +> anon0 ip #0 20(20) 0 1.2.3.4 > 1.2.1.1 +< anon0 ip #0 20(20) 0 2.3.0.1 > 1.2.1.1 +< anon0 ip #0 20(20) 0 2.2.2.1 > 1.2.1.1 +< anon0 ip #0 20(20) 0 2.2.0.1 > 1.2.1.1 +15 +> anon0 ip #0 20(20) 0 1.2.3.4 > 1.2.1.2 +> anon0 ip #0 20(20) 0 2.2.0.1 > 1.2.1.1 +> anon0 ip #0 20(20) 0 2.2.0.1 > 1.2.1.3 +> anon0 ip #0 20(20) 0 4.4.1.1 > 1.2.1.1 +List of active MAP/Redirect filters: +map * from pool/100 to 0/0 -> 1.2.3.4/32 + +List of active sessions: +MAP 2.2.2.1 <- -> 1.2.3.4 [1.2.1.2] +MAP 1.1.1.1 <- -> 1.2.3.4 [1.2.1.1] + +Hostmap table: +2.2.2.1,1.2.1.2 -> 1.2.3.4,0.0.0.0 (use = 1) +1.1.1.1,1.2.1.1 -> 1.2.3.4,0.0.0.0 (use = 1) +List of active state sessions: +List of configured pools +table role=nat type=tree number=100 + { 1.1.1.1/32; ! 2.2.0.0/16; 2.2.2.0/24; }; +List of configured hash tables +List of groups configured (set 0) +List of groups configured (set 1) +Rules configured (set 0, in) +Rules configured (set 0, out) +Rules configured (set 1, in) +Rules configured (set 1, out) +Accounting rules configured (set 0, in) +Accounting rules configured (set 0, out) +Accounting rules configured (set 1, in) +Accounting rules configured (set 1, out) +------------------------------- diff --git a/contrib/ipfilter/test/expected/p5 b/contrib/ipfilter/test/expected/p5 index d8ea95c066a9..b56c3bcb4e9b 100644 --- a/contrib/ipfilter/test/expected/p5 +++ b/contrib/ipfilter/test/expected/p5 @@ -13,7 +13,7 @@ List of active sessions: Hostmap table: List of active state sessions: List of configured pools -table role = ipf type = tree name = letters +table role=ipf type=tree name=letters { 1.1.1.1/32; ! 2.2.0.0/16; 2.2.2.0/24; }; List of configured hash tables List of groups configured (set 0) diff --git a/contrib/ipfilter/test/expected/p6 b/contrib/ipfilter/test/expected/p6 new file mode 100644 index 000000000000..413f94ba74b9 --- /dev/null +++ b/contrib/ipfilter/test/expected/p6 @@ -0,0 +1,24 @@ +block +nomatch +List of active MAP/Redirect filters: + +List of active sessions: + +Hostmap table: +List of active state sessions: +List of configured pools +table role=ipf type=tree name=microsoft + { 131.107.0.0/16; 192.92.90.0/24; 198.105.232.0/22; 204.231.58.0/24; 204.140.77.0/24; 204.140.80.0/22; 199.60.28.0/24; 199.103.90.0/23; 199.103.122.0/24; 204.79.101.0/24; 192.237.67.0/24; 198.137.97.0/24; 204.79.135.0/24; 204.79.179.0/24; 204.79.180.0/23; 204.79.188.0/24; 204.79.7.0/24; 204.79.27.0/24; 198.180.74.0/23; 204.231.236.0/24; 205.163.63.0/24; 205.163.62.0/24; 205.163.144.0/20; 205.248.50.0/23; 205.248.72.0/24; 205.248.212.0/22; 205.248.228.0/24; 205.248.235.0/24; 204.231.76.0/24; 204.231.192.0/24; 207.78.80.0/24; 207.78.81.0/24; 207.78.82.0/24; 207.117.3.0/24; 207.18.117.0/24; 208.139.27.0/24; 209.28.213.0/24; 207.209.68.0/24; 204.95.96.0/20; 207.158.93.192/27; 207.240.123.192/27; 208.26.205.0/24; 192.197.157.0/24; 204.133.231.0/24; 216.72.96.0/22; 207.229.166.152/29; 204.95.149.0/24; 209.192.213.72/29; 206.73.203.0/24; 206.73.118.0/24; 208.45.54.16/29; 208.45.54.8/29; 206.73.31.0/24; 63.161.50.128/25; 63.161.50.0/25; 207.240.8.224/28; 208.45.89.248/29; 206.182.69.0/24; 206.182.240.0/24; 206.182.241.0/24; 206.73.67.0/24; 206.182.251.0/24; 206.182.247.0/24; 206.182.236.0/24; 63.236.198.64/29; 63.236.198.152/29; 165.121.253.232/29; 63.236.170.64/29; 63.236.186.64/29; 63.236.187.104/29; 63.236.187.128/29; 63.236.187.160/29; 199.2.137.0/24; 216.222.104.224/28; 63.151.87.64/29; 64.77.82.96/29; 64.77.93.80/28; 65.52.0.0/14; 207.46.0.0/16; 204.182.144.0/20; 206.107.34.0/24; 205.240.158.0/23; 204.79.252.0/24; 64.200.211.16/28; 12.178.163.0/27; 69.44.126.80/28; 63.173.42.128/25; 12.28.108.0/25; 65.170.29.0/29; 67.132.133.96/29; 8.6.176.0/24; 63.148.123.240/29; 64.41.193.0/24; 64.85.70.32/28; 64.85.81.96/29; 64.85.81.104/29; 216.32.168.224/27; 206.79.74.32/28; 216.32.175.224/27; 216.32.180.0/22; 216.33.229.224/27; 216.33.236.0/22; 216.33.240.0/22; 216.32.240.0/22; 216.34.51.0/24; 209.1.112.0/24; 209.1.113.0/24; 209.1.15.0/24; 216.34.53.176/28; 216.35.8.224/28; 209.185.128.0/22; 65.114.175.128/27; 64.15.229.96/27; 64.15.177.0/24; 64.15.170.192/29; 209.143.238.0/24; 64.15.178.0/24; 66.35.209.120/29; 66.35.211.128/26; 66.35.208.48/28; 216.33.148.0/22; 216.35.66.88/29; 12.230.32.160/29; 12.53.124.0/27; 12.232.18.96/27; 12.190.158.0/24; 12.71.196.32/28; 209.240.192.0/19; 70.37.128.0/23; 70.37.135.0/24; 12.49.87.192/26; 74.93.205.144/29; 74.93.205.152/29; 74.93.206.64/29; 70.89.139.120/29; 206.71.119.0/24; 206.71.117.0/24; 206.71.118.0/24; 209.154.155.112/29; 65.68.62.152/29; 67.39.208.168/29; 65.242.67.0/24; 204.71.191.0/24; 63.194.155.144/29; 66.136.85.192/29; 64.124.184.72/29; 216.200.206.0/24; 63.80.93.0/25; 67.192.225.208/28; 69.74.162.0/24; 65.221.5.0/24; 65.248.85.0/24; 199.243.157.192/27; 199.243.157.112/29; 65.194.210.224/27; 208.194.139.0/24; 208.204.49.128/25; 208.205.26.0/24; 208.217.184.0/22; 208.222.172.0/24; 208.224.200.64/27; 208.229.100.0/23; 208.241.19.0/28; 208.241.19.16/28; 208.241.9.224/28; 208.244.108.0/28; 208.245.16.0/27; 208.249.17.160/28; 63.104.216.0/25; 63.69.245.0/24; 68.90.141.72/29; 63.198.123.160/29; 68.248.48.64/29; 68.248.48.72/29; 99.49.8.248/29; 65.38.172.72/29; 65.38.172.96/28; 75.149.174.16/29; 75.151.100.240/28; 64.81.8.96/27; 67.112.255.144/29; 63.240.201.176/28; 206.16.209.208/28; 63.240.195.208/28; 206.16.204.64/28; 206.16.223.0/24; 63.240.216.0/22; 63.240.220.0/22; 206.16.246.24/29; 63.240.195.192/28; 206.16.224.160/27; 67.192.39.48/28; 72.32.240.160/28; 72.32.201.152/29; 67.39.81.152/29; 69.20.127.32/29; 216.52.28.0/24; 70.42.230.0/23; 63.251.97.0/24; 67.120.132.128/29; 67.120.132.152/29; 67.120.132.192/28; }; +List of configured hash tables +List of groups configured (set 0) +List of groups configured (set 1) +Rules configured (set 0, in) +1 block in from pool/microsoft to any +Rules configured (set 0, out) +Rules configured (set 1, in) +Rules configured (set 1, out) +Accounting rules configured (set 0, in) +Accounting rules configured (set 0, out) +Accounting rules configured (set 1, in) +Accounting rules configured (set 1, out) +------------------------------- diff --git a/contrib/ipfilter/test/expected/p7 b/contrib/ipfilter/test/expected/p7 new file mode 100644 index 000000000000..89bfc11301c7 --- /dev/null +++ b/contrib/ipfilter/test/expected/p7 @@ -0,0 +1,40 @@ +< bge0 ip #0 40(20) 6 5.5.5.5,10000 > 1.1.1.2,80 +< bge0 ip #0 40(20) 6 5.5.5.6,10000 > 1.1.1.4,80 +< bge0 ip #0 40(20) 6 5.5.5.7,10000 > 1.1.1.5,80 +< bge0 ip #0 40(20) 6 5.5.5.8,10000 > 1.1.1.9,80 +< bge0 ip #0 40(20) 6 5.5.5.9,10000 > 1.1.1.2,80 +< bge0 ip #0 40(20) 6 5.5.6.5,10000 > 1.1.1.4,80 +< bge0 ip #0 40(20) 6 5.5.6.6,10000 > 1.1.1.5,80 +< bge0 ip #0 40(20) 6 5.5.6.7,10000 > 1.1.1.9,80 +< bge0 ip #0 40(20) 6 5.5.6.8,10000 > 1.1.1.2,80 +< bge0 ip #0 40(20) 6 5.5.6.9,10000 > 1.1.1.4,80 +List of active MAP/Redirect filters: +rewrite in on bge0 proto tcp from 0/0 to 0/0 port = 80 -> src 0/0 dst dstlist/servers; + +List of active sessions: +RWR-RDR 5.5.6.9 10000 9.9.9.9 80 <- -> 5.5.6.9 10000 1.1.1.4 80 +RWR-RDR 5.5.6.8 10000 9.9.9.9 80 <- -> 5.5.6.8 10000 1.1.1.2 80 +RWR-RDR 5.5.6.7 10000 9.9.9.9 80 <- -> 5.5.6.7 10000 1.1.1.9 80 +RWR-RDR 5.5.6.6 10000 9.9.9.9 80 <- -> 5.5.6.6 10000 1.1.1.5 80 +RWR-RDR 5.5.6.5 10000 9.9.9.9 80 <- -> 5.5.6.5 10000 1.1.1.4 80 +RWR-RDR 5.5.5.9 10000 9.9.9.9 80 <- -> 5.5.5.9 10000 1.1.1.2 80 +RWR-RDR 5.5.5.8 10000 9.9.9.9 80 <- -> 5.5.5.8 10000 1.1.1.9 80 +RWR-RDR 5.5.5.7 10000 9.9.9.9 80 <- -> 5.5.5.7 10000 1.1.1.5 80 +RWR-RDR 5.5.5.6 10000 9.9.9.9 80 <- -> 5.5.5.6 10000 1.1.1.4 80 +RWR-RDR 5.5.5.5 10000 9.9.9.9 80 <- -> 5.5.5.5 10000 1.1.1.2 80 + +Hostmap table: +List of active state sessions: +List of configured pools +List of configured hash tables +List of groups configured (set 0) +List of groups configured (set 1) +Rules configured (set 0, in) +Rules configured (set 0, out) +Rules configured (set 1, in) +Rules configured (set 1, out) +Accounting rules configured (set 0, in) +Accounting rules configured (set 0, out) +Accounting rules configured (set 1, in) +Accounting rules configured (set 1, out) +------------------------------- diff --git a/contrib/ipfilter/test/expected/p9 b/contrib/ipfilter/test/expected/p9 new file mode 100644 index 000000000000..89bfc11301c7 --- /dev/null +++ b/contrib/ipfilter/test/expected/p9 @@ -0,0 +1,40 @@ +< bge0 ip #0 40(20) 6 5.5.5.5,10000 > 1.1.1.2,80 +< bge0 ip #0 40(20) 6 5.5.5.6,10000 > 1.1.1.4,80 +< bge0 ip #0 40(20) 6 5.5.5.7,10000 > 1.1.1.5,80 +< bge0 ip #0 40(20) 6 5.5.5.8,10000 > 1.1.1.9,80 +< bge0 ip #0 40(20) 6 5.5.5.9,10000 > 1.1.1.2,80 +< bge0 ip #0 40(20) 6 5.5.6.5,10000 > 1.1.1.4,80 +< bge0 ip #0 40(20) 6 5.5.6.6,10000 > 1.1.1.5,80 +< bge0 ip #0 40(20) 6 5.5.6.7,10000 > 1.1.1.9,80 +< bge0 ip #0 40(20) 6 5.5.6.8,10000 > 1.1.1.2,80 +< bge0 ip #0 40(20) 6 5.5.6.9,10000 > 1.1.1.4,80 +List of active MAP/Redirect filters: +rewrite in on bge0 proto tcp from 0/0 to 0/0 port = 80 -> src 0/0 dst dstlist/servers; + +List of active sessions: +RWR-RDR 5.5.6.9 10000 9.9.9.9 80 <- -> 5.5.6.9 10000 1.1.1.4 80 +RWR-RDR 5.5.6.8 10000 9.9.9.9 80 <- -> 5.5.6.8 10000 1.1.1.2 80 +RWR-RDR 5.5.6.7 10000 9.9.9.9 80 <- -> 5.5.6.7 10000 1.1.1.9 80 +RWR-RDR 5.5.6.6 10000 9.9.9.9 80 <- -> 5.5.6.6 10000 1.1.1.5 80 +RWR-RDR 5.5.6.5 10000 9.9.9.9 80 <- -> 5.5.6.5 10000 1.1.1.4 80 +RWR-RDR 5.5.5.9 10000 9.9.9.9 80 <- -> 5.5.5.9 10000 1.1.1.2 80 +RWR-RDR 5.5.5.8 10000 9.9.9.9 80 <- -> 5.5.5.8 10000 1.1.1.9 80 +RWR-RDR 5.5.5.7 10000 9.9.9.9 80 <- -> 5.5.5.7 10000 1.1.1.5 80 +RWR-RDR 5.5.5.6 10000 9.9.9.9 80 <- -> 5.5.5.6 10000 1.1.1.4 80 +RWR-RDR 5.5.5.5 10000 9.9.9.9 80 <- -> 5.5.5.5 10000 1.1.1.2 80 + +Hostmap table: +List of active state sessions: +List of configured pools +List of configured hash tables +List of groups configured (set 0) +List of groups configured (set 1) +Rules configured (set 0, in) +Rules configured (set 0, out) +Rules configured (set 1, in) +Rules configured (set 1, out) +Accounting rules configured (set 0, in) +Accounting rules configured (set 0, out) +Accounting rules configured (set 1, in) +Accounting rules configured (set 1, out) +------------------------------- diff --git a/contrib/ipfilter/test/h4to6 b/contrib/ipfilter/test/h4to6 new file mode 100644 index 000000000000..e31f7c4224b6 --- /dev/null +++ b/contrib/ipfilter/test/h4to6 @@ -0,0 +1,135 @@ +@P=(); +$line = 0; +while (<>) { + s/\=192.168.1.188/\=c0a8:0100::bc/g; + s/\=192.168.1.188/\=c0a8:0100::bc/g; + @F = split; + if (/^#/) { + @P[$nline++] = join(" ",@F); + next; + } + $line = 0 if (/^\[/); + if ($line == 1) { + $len = hex($F[1]) - 20; + $pr = hex($F[4]) & 0xff; + $pr = 58 if ($pr == 1); + $ttl = hex($F[4]) >> 8; + &replaceip($_, $len, $pr, $ttl); + $ipline = $nline; + $err = 0; + } elsif ($line == 2) { + if ($pr == 58) { + # + # Map the ICMP type codes from IPv4 to IPv6 + # and update the checksum to compensate. + # + if ($F[0] =~ /^0800/) { + $F[0] =~ s/^0800/8000/; + $d = 0x7800; + } + if ($F[0] =~ /^0000/) { + $F[0] =~ s/^0000/8100/; + $d = 0x8100; + } + if ($F[0] =~ /^0304/) { + $F[0] =~ s/^0304/0200/; + $d = 0xfefc; + $err = 1; + } + if ($F[0] =~ /^03/) { + $F[0] =~ s/^03/01/; + $d = 0xfe00; + $err = 1; + } + if ($F[0] =~ /^0b/) { + $F[0] =~ s/^0b/03/; + $d = 0xf800; + $err = 1; + } + if ($F[0] =~ /^0c/) { + $F[0] =~ s/^0c/04/; + $d = 0xf800; + $err = 1; + } + $F[1] = sprintf "%04x", hex($F[1]) - $d; + } + @P[$nline++] = join(" ",@F); + } elsif ($line == 3) { + if ($pr == 58 && $err == 1 && $F[0] =~ /^45/) { + local($l) = hex($F[1]) - 20; + local($p) = hex($F[4]) & 0xff; + $p = 58 if ($p == 1); + local($t) = hex($F[4]) >> 8; + &replaceip(join(" ", @F), $l, $p, $t); + @H = split(/ /, $P[$ipline]); + $H[2] += 20; + $P[$ipline] = join(" ",@H); + } else { + @P[$nline++] = join(" ",@F); + } + } else { + @P[$nline++] = join(" ",@F); + } + $line++; +} + +for ($li = 0; $li < $nline; $li++) { + print "$P[$li]\n"; +} + +exit(0); + +sub replaceip { + local(@G) = split(/\s/,$_[0]); + local($p) = ""; + + $p = sprintf "6000 0000 %04x %02x%02x", $_[1], $_[2], $_[3]; + if ($G[6] =~ /^c0a8/) { + $fmt = " %02x%02x %02x00 0000 0000 0000 0000 0000 00%02x"; + } else { + if ($G[6] =~ /^0[4a]../) { + $fmt = " 00%02x 00%02x 00%02x 0000 0000 0000 0000 00%02x"; + } else { + $fmt = " 00%02x 0000 0000 0000 0000 00%02x 00%02x 00%02x"; + } + if ($G[6] =~ /^0a/) { + $G[6] =~ s/^0a/10/; + } + if ($G[6] =~ /0a$/) { + $G[6] =~ s/0a$/10/; + } + if ($G[7] =~ /^0a/) { + $G[7] =~ s/^0a/10/; + } + if ($G[7] =~ /0a$/) { + $G[7] =~ s/0a$/10/; + } + } + $p = $p.sprintf $fmt, hex($G[6]) >> 8, hex($G[6]) & 0xff, + hex($G[7]) >> 8, hex($G[7]) & 0xff; + + if ($G[6] =~ /^c0a8/) { + $fmt = " %02x%02x %02x00 0000 0000 0000 0000 0000 00%02x"; + } else { + if ($G[8] =~ /^0[4a]../) { + $fmt = " 00%02x 00%02x 00%02x 0000 0000 0000 0000 00%02x"; + } else { + $fmt = " 00%02x 0000 0000 0000 0000 00%02x 00%02x 00%02x"; + } + if ($G[8] =~ /^0a/) { + $G[8] =~ s/^0a/10/; + } + if ($G[8] =~ /0a$/) { + $G[8] =~ s/0a$/10/; + } + if ($G[9] =~ /^0a/) { + $G[9] =~ s/^0a/10/; + } + if ($G[9] =~ /0a$/) { + $G[9] =~ s/0a$/10/; + } + } + $p = $p.sprintf $fmt, hex($G[8]) >> 8, hex($G[8]) & 0xff, + hex($G[9]) >> 8, hex($G[9]) & 0xff; + $P[$nline++] = $p; +} diff --git a/contrib/ipfilter/test/hextest b/contrib/ipfilter/test/hextest deleted file mode 100644 index b7b0b2c75e42..000000000000 --- a/contrib/ipfilter/test/hextest +++ /dev/null @@ -1,27 +0,0 @@ -#!/bin/sh -if [ -f /usr/ucb/touch ] ; then - TOUCH=/usr/ucb/touch -else - if [ -f /usr/bin/touch ] ; then - TOUCH=/usr/bin/touch - else - if [ -f /bin/touch ] ; then - TOUCH=/bin/touch - fi - fi -fi -echo "$1..."; -/bin/cp /dev/null results/$1 -( while read rule; do - echo "$rule" | ../ipftest -br - -F hex -i input/$1 >> results/$1; - if [ $? -ne 0 ] ; then - exit 1; - fi - echo "--------" >> results/$1 -done ) < regress/$1 -cmp expected/$1 results/$1 -status=$? -if [ $status = 0 ] ; then - $TOUCH $1 -fi -exit $status diff --git a/contrib/ipfilter/test/i4to6 b/contrib/ipfilter/test/i4to6 new file mode 100644 index 000000000000..b1208fd923dd --- /dev/null +++ b/contrib/ipfilter/test/i4to6 @@ -0,0 +1,12 @@ +sed \ +-e 's/in /in6 /g' \ +-e 's/icmp/58/g' \ +-e 's/out /out6 /g' \ +-e 's/10\.4\.\([0-9]\)\.\([0-9]\)/10:4:\1::\2/g' \ +-e 's/10\.3\.4\.\([0-9]\)/10::3:4:\1/g' \ +-e 's/10\.3\.\([0-9]\)\.\([0-9]\)/10:3:\1::\2/g' \ +-e 's/10\.1\.\([0-9]\)\.\([0-9]\)/10:1:\1::\2/g' \ +-e 's/10\.2\.\([0-9]\)\.\([0-9]\)/10::2:\1:\2/g' \ +-e 's/9\.\([0-9]\)\.\([0-9]\)\.\([0-9]\)/9:\1:\2::\3/g' \ +-e 's/5\.\([0-9]\)\.\([0-9]\)\.\([0-9]\)/5:\1::\2:\3/g' \ +-e 's/2\.\([0-9]\)\.\([0-9]\)\.\([0-9]\)/2::\1:\2:\3/g' diff --git a/contrib/ipfilter/test/input/f13 b/contrib/ipfilter/test/input/f13 index 77e537e2b638..ccd370a7230c 100644 --- a/contrib/ipfilter/test/input/f13 +++ b/contrib/ipfilter/test/input/f13 @@ -83,7 +83,7 @@ 4500 0028 0003 4000 3f06 36ca 0101 0101 0201 0101 0400 0019 0040 0000 0000 0000 5010 2000 8678 0000 -# 1.1.1.1,1024 -> 2.1.1.1,25 TTL=63 TCP DF ACK +# 1.1.1.1,1024 -> 2.1.1.1,25 TTL=63 TCP DF ACK (out-of-order) [in] 4500 0028 0003 4000 3f06 36ca 0101 0101 0201 0101 0400 0019 7000 0004 0000 0002 5010 2000 16b2 0000 diff --git a/contrib/ipfilter/test/input/f21 b/contrib/ipfilter/test/input/f21 new file mode 100644 index 000000000000..1135cbd01c48 --- /dev/null +++ b/contrib/ipfilter/test/input/f21 @@ -0,0 +1,31 @@ +# ICMP dest unreachable with 64 bits in payload (in reply to a TCP packet +# going out) +# IP 4.4.4.4 2.2.2.2 TCP(20480,80) +[out,df0] +4500 003c 4706 4000 ff06 28aa 0404 0404 +0202 0202 5000 0050 0000 0001 0000 0000 +a002 16d0 d8e2 0000 0204 05b4 0402 080a +0047 fbb0 0000 0000 0103 0300 + +# IP 3.3.3.3 -> 4.4.4.4 ICMP (IP(4.4.4.4,6.6.6.6) TCP(20480,80)) UNREACH +[in,df0] +4500 0038 809a 0000 ff01 2d1d 0303 0303 +0404 0404 0303 acab 0000 0000 4500 003c +4706 4000 ff06 28aa 0404 0404 0202 0202 +5000 0050 0000 0001 + +# IP 3.3.3.3 -> 4.4.4.4 ICMP (IP(4.4.4.4,6.6.6.6) TCP(20480,80)) REDIRECT +# ICMP dest unreachable with whole packet in payload (40 bytes = 320 bits) +[in,df0] +4500 0038 809a 0000 ff01 2d1d 0303 0303 +0404 0404 0501 9a9d 0808 0808 4500 003c +4706 4000 ff06 28aa 0404 0404 0202 0202 +5000 0050 0000 0001 + +# IP 3.3.3.3 -> 5.5.5.5 ICMP (IP(4.4.4.4,6.6.6.6) TCP(20480,80)) UNREACH +[in,df0] +4500 0038 809a 0000 ff01 2b1b 0303 0303 +0505 0505 0303 acab 0000 0000 4500 003c +4706 4000 ff06 28aa 0404 0404 0202 0202 +5000 0050 0000 0001 + diff --git a/contrib/ipfilter/test/input/f22 b/contrib/ipfilter/test/input/f22 new file mode 100644 index 000000000000..a5221c1abdb2 --- /dev/null +++ b/contrib/ipfilter/test/input/f22 @@ -0,0 +1,31 @@ +# ICMP dest unreachable with 64 bits in payload (in reply to a TCP packet +# going out) +# IP 4.4.4.4 2.2.2.2 TCP(20480,80) +[in,df0] +4500 003c 4706 4000 ff06 28aa 0404 0404 +0202 0202 5000 0050 0000 0001 0000 0000 +a002 16d0 d8e2 0000 0204 05b4 0402 080a +0047 fbb0 0000 0000 0103 0300 + +# IP 3.3.3.3 -> 4.4.4.4 ICMP (IP(4.4.4.4,6.6.6.6) TCP(20480,80)) UNREACH +[out,df0] +4500 0038 809a 0000 ff01 2d1d 0303 0303 +0404 0404 0303 acab 0000 0000 4500 003c +4706 4000 ff06 28aa 0404 0404 0202 0202 +5000 0050 0000 0001 + +# IP 3.3.3.3 -> 4.4.4.4 ICMP (IP(4.4.4.4,6.6.6.6) TCP(20480,80)) REDIRECT +# ICMP dest unreachable with whole packet in payload (40 bytes = 320 bits) +[out,df0] +4500 0038 809a 0000 ff01 2d1d 0303 0303 +0404 0404 0501 9a9d 0808 0808 4500 003c +4706 4000 ff06 28aa 0404 0404 0202 0202 +5000 0050 0000 0001 + +# IP 3.3.3.3 -> 5.5.5.5 ICMP (IP(4.4.4.4,6.6.6.6) TCP(20480,80)) UNREACH +[out,df0] +4500 0038 809a 0000 ff01 2b1b 0303 0303 +0505 0505 0303 acab 0000 0000 4500 003c +4706 4000 ff06 28aa 0404 0404 0202 0202 +5000 0050 0000 0001 + diff --git a/contrib/ipfilter/test/input/f24 b/contrib/ipfilter/test/input/f24 index 1d066822561f..030772b427f7 100644 --- a/contrib/ipfilter/test/input/f24 +++ b/contrib/ipfilter/test/input/f24 @@ -12,7 +12,7 @@ c0a8 0101 0035 eb22 00a9 d7b9 4a82 8180 0c00 0100 0100 0000 3c00 0496 [in,hme0] -4500 004c fc96 2006 4011 d9b4 c0a8 01fe +4500 004c fc96 2007 4011 d9b3 c0a8 01fe c0a8 0101 cbe7 50c0 1300 0200 0100 0078 8c00 0603 6e73 31c0 13c0 1300 0200 0100 0078 8c00 0e02 6e73 0861 6465 6c61 6964 diff --git a/contrib/ipfilter/test/input/f25 b/contrib/ipfilter/test/input/f25 new file mode 100644 index 000000000000..a4e31398e012 --- /dev/null +++ b/contrib/ipfilter/test/input/f25 @@ -0,0 +1,41 @@ +[in,hme0]+mcast +4500 0081 b02d 0000 0411 53b1 c0a8 01eb +efff fffa 1f48 076c 006d 1bd2 0000 0000 +0000 0000 0000 0000 0000 0000 0000 0000 +0000 0000 0000 0000 0000 0000 0000 0000 +0000 0000 0000 0000 0000 0000 0000 0000 +0000 0000 0000 0000 0000 0000 0000 0000 +0000 0000 0000 0000 0000 0000 0000 0000 +0000 0000 0000 0000 0000 0000 0000 0000 +0a + +[out,hme0] +4500 0108 7aca 0000 4011 79e1 c0a8 01fe +c0a8 01eb 076c 1f48 00f4 5218 0000 0000 +0000 0000 0000 0000 0000 0000 0000 0000 +0000 0000 0000 0000 0000 0000 0000 0000 +0000 0000 0000 0000 0000 0000 0000 0000 +0000 0000 0000 0000 0000 0000 0000 0000 +0000 0000 0000 0000 0000 0000 0000 0000 +0000 0000 0000 0000 0000 0000 0000 0000 +0000 0000 0000 0000 0000 0000 0000 0000 +0000 0000 0000 0000 0000 0000 0000 0000 +0000 0000 0000 0000 0000 0000 0000 0000 +0000 0000 0000 0000 0000 0000 0000 0000 +0000 0000 0000 0000 0000 0000 0000 0000 +0000 0000 0000 0000 0000 0000 0000 0000 +0000 0000 0000 0000 0000 0000 0000 0000 +0000 0000 0000 0000 0000 0000 0000 0000 +0000 0000 0000 0000 + +[in,hme0]+mcast +4500 0081 b02d 0000 0411 53b1 c0a8 01eb +efff fffa 1f48 076c 006d 1bd2 0000 0000 +0000 0000 0000 0000 0000 0000 0000 0000 +0000 0000 0000 0000 0000 0000 0000 0000 +0000 0000 0000 0000 0000 0000 0000 0000 +0000 0000 0000 0000 0000 0000 0000 0000 +0000 0000 0000 0000 0000 0000 0000 0000 +0000 0000 0000 0000 0000 0000 0000 0000 +0a + diff --git a/contrib/ipfilter/test/input/f26 b/contrib/ipfilter/test/input/f26 new file mode 100644 index 000000000000..2151f72e7cb2 --- /dev/null +++ b/contrib/ipfilter/test/input/f26 @@ -0,0 +1,13 @@ +in tcp 1.1.1.1,1001 2.2.2.2,22 S +in tcp 1.1.1.1,1002 2.2.2.2,22 S +in tcp 1.1.1.1,1003 2.2.2.2,22 S +in tcp 1.1.1.1,1004 2.2.2.2,22 S +in tcp 1.1.1.2,1002 2.2.2.2,22 S +in tcp 1.1.1.3,1003 2.2.2.2,22 S +in tcp 1.1.1.4,1004 2.2.2.2,22 S +in tcp 1.1.1.2,1005 2.2.2.2,22 S +in tcp 1.1.1.3,1006 2.2.2.2,22 S +in tcp 1.1.1.4,1007 2.2.2.2,22 S +in tcp 1.1.1.2,1008 2.2.2.2,22 S +in tcp 1.1.1.3,1009 2.2.2.2,22 S +in tcp 1.1.1.4,1010 2.2.2.2,22 S diff --git a/contrib/ipfilter/test/input/f27 b/contrib/ipfilter/test/input/f27 new file mode 100644 index 000000000000..f01bf7e6ee73 --- /dev/null +++ b/contrib/ipfilter/test/input/f27 @@ -0,0 +1,84 @@ +[in,hme0] +45000028 0000 0000 FF06 b5ca +01010101 02020202 +03e9 0016 00000000 00000000 5002 0000 +a5de 0000 + +[in,hme0] +45000028 0000 0000 FF06 b5ca +01010101 02020202 +03ea 0016 00000000 00000000 5002 0000 +a5dd 0000 + +[in,hme0] +45000028 0000 0000 FF06 b5ca +01010101 02020202 +03eb 0016 00000000 00000000 5002 0000 +a5dc 0000 + +[in,hme0] +45000028 0000 0000 FF06 b5ca +01010101 02020202 +03ec 0016 00000000 00000000 5002 0000 +a5db 0000 + +[in,hme0] +45000028 0000 0000 FF06 b5c9 +01010102 02020202 +03ed 0016 00000000 00000000 5002 0000 +a5d9 0000 + +[in,hme0] +45000028 0000 0000 FF06 b5c8 +01010103 02020202 +03ee 0016 00000000 00000000 5002 0000 +a5d7 0000 + +[in,hme0] +45000028 0000 0000 FF06 b5c7 +01010104 02020202 +03ef 0016 00000000 00000000 5002 0000 +a5d5 0000 + +[in,hme0] +45000028 0000 0000 FF06 b5c9 +01010102 02020202 +03f0 0016 00000000 00000000 5002 0000 +a5d6 0000 + +[in,hme0] +45000028 0000 0000 FF06 b5c8 +01010103 02020202 +03f1 0016 00000000 00000000 5002 0000 +a5d4 0000 + +[in,hme0] +45000028 0000 0000 FF06 b5c7 +01010104 02020202 +03f2 0016 00000000 00000000 5002 0000 +a5d2 0000 + +[in,hme0] +45000028 0000 0000 FF06 b5c9 +01010102 02020202 +03f3 0016 00000000 00000000 5002 0000 +a5d3 0000 + +[in,hme0] +45000028 0000 0000 FF06 b5c8 +01010103 02020202 +03f4 0016 00000000 00000000 5002 0000 +a5d1 0000 + +[in,hme0] +45000028 0000 0000 FF06 b5c7 +01010104 02020202 +03f5 0016 00000000 00000000 5002 0000 +a5cf 0000 + +[in,hme0] +6000 0000 0014 06FF +ef00 1001 2002 0001 0000 0000 0000 0070 +2001 1002 3333 0001 0000 0000 0000 0001 +03f6 0016 0000 0000 0000 0000 5002 0000 292a 0000 + diff --git a/contrib/ipfilter/test/input/f28 b/contrib/ipfilter/test/input/f28 new file mode 100644 index 000000000000..8849c140f1fa --- /dev/null +++ b/contrib/ipfilter/test/input/f28 @@ -0,0 +1,7 @@ +in on nic1 4.4.0.1 4.2.0.2 +in on nic2 4.4.1.1 4.2.1.2 +in on nic3 4.4.2.1 4.2.2.2 +in on nic0 4.4.3.1 4.2.3.2 +in on nic0 4.4.1.1 4.2.1.2 +in on nic0 4.4.2.1 4.2.2.2 +in on nic0 4.4.3.1 4.2.3.2 diff --git a/contrib/ipfilter/test/input/f29 b/contrib/ipfilter/test/input/f29 new file mode 100644 index 000000000000..2e717af635b8 --- /dev/null +++ b/contrib/ipfilter/test/input/f29 @@ -0,0 +1,11 @@ +in on nic1 4.4.0.1 4.2.0.2 +in on nic2 4.4.1.1 4.2.1.2 +in on nic3 4.4.2.1 4.2.2.2 +in on nic0 udp 4.4.3.1,1000 4.2.3.2,2000 +in on nic0 udp 4.4.3.1,1000 4.2.3.2,2000 +in on nic0 udp 4.4.1.1,1001 4.2.1.2,2001 +in on nic0 udp 4.4.1.1,1001 4.2.1.2,2001 +in on nic0 udp 4.4.2.1,1002 4.2.2.2,2002 +in on nic0 udp 4.4.2.1,1002 4.2.2.2,2002 +in on nic0 udp 4.4.3.1,1003 4.2.3.2,2003 +in on nic0 udp 4.4.3.1,1003 4.2.3.2,2003 diff --git a/contrib/ipfilter/test/input/f30 b/contrib/ipfilter/test/input/f30 new file mode 100644 index 000000000000..ebf7dc061809 --- /dev/null +++ b/contrib/ipfilter/test/input/f30 @@ -0,0 +1,16 @@ +in on hme0 udp 1.1.1.1,53 2.1.1.1,53 opt lsrr +in on hme1 udp 2.1.1.1,53 1.1.1.1,53 opt ts,lsrr +in on hme1 udp 2.1.1.1,53 1.1.1.1,53 opt lsrr +in on hme0 udp 1.1.1.1,53 2.1.1.1,53 +in on hme1 udp 2.1.1.1,53 1.1.1.1,53 +in on hme0 tcp 1.1.1.1,12345 2.1.1.1,22 S opt rr +in on hme0 tcp 1.1.1.1,12345 2.1.1.1,22 S +in on hme1 tcp 2.1.1.1,22 1.1.1.1,12345 SA opt rr,ts +in on hme1 tcp 2.1.1.1,22 1.1.1.1,12345 SA opt rr +in on hme1 tcp 2.1.1.1,22 1.1.1.1,12345 SA +in on hme0 tcp 1.1.1.1,12346 2.1.1.1,22 S opt sec-class=secret +in on hme0 tcp 1.1.1.1,12346 2.1.1.1,22 S +in on hme1 tcp 2.1.1.1,22 1.1.1.1,12346 SA opt sec-class=topsecret +in on hme1 tcp 2.1.1.1,22 1.1.1.1,12346 SA opt ts,sec-class=secret +in on hme1 tcp 2.1.1.1,22 1.1.1.1,12346 SA opt sec-class=secret +in on hme1 tcp 2.1.1.1,22 1.1.1.1,12346 SA diff --git a/contrib/ipfilter/test/input/ipf6-1 b/contrib/ipfilter/test/input/ipf6-1 deleted file mode 100644 index 8cc2d175dc24..000000000000 --- a/contrib/ipfilter/test/input/ipf6-1 +++ /dev/null @@ -1,26 +0,0 @@ -[out,de0] -6000 0000 0020 3aff ef00 0000 0000 0000 -0000 0000 0001 0013 ff02 0000 0000 0000 -0000 0001 ff01 000b 8700 ea32 0000 0000 -ef00 0000 0000 0000 0000 0000 0001 000b -0101 0048 5487 5c6f - -[in,de0] -6000 0000 0020 3aff ef00 0000 0000 0000 -0000 0000 0001 000b ef00 0000 0000 0000 -0000 0000 0001 0013 8800 5322 6000 0000 -ef00 0000 0000 0000 0000 0000 0001 000b -0201 0800 2071 cce1 - -[out,de0] -6000 0000 0010 3a40 ef00 0000 0000 0000 -0000 0000 0001 0013 ef00 0000 0000 0000 -0000 0000 0001 000b 8000 3210 06ff 0002 -9ec3 3c3c 8a82 0300 - -[in,de0] -6000 0000 0010 3aff ef00 0000 0000 0000 -0000 0000 0001 000b ef00 0000 0000 0000 -0000 0000 0001 0013 8100 3110 06ff 0002 -9ec3 3c3c 8a82 0300 - diff --git a/contrib/ipfilter/test/input/ipv6.1 b/contrib/ipfilter/test/input/ipv6.1 index 3f0fd308102f..6da8da0e4bbc 100644 --- a/contrib/ipfilter/test/input/ipv6.1 +++ b/contrib/ipfilter/test/input/ipv6.1 @@ -1,3 +1,8 @@ +# +# traceroute simulation +# +# UDP +# [out,gif0] 6000 0000 0018 1101 ef00 1001 2002 0001 0000 0000 0000 0070 2001 1002 3333 0001 0000 0000 0000 0001 @@ -6,10 +11,14 @@ ef00 1001 2002 0001 0000 0000 0000 0070 f4c1 0000 0344 0000 0004 f8f1 9d3c ddba 0e00 +# +# ICMPV6 +# - Time exceeded +# [in,gif0] 6000 0000 0048 3a40 ef00 1001 0880 6cbf 0000 0000 0000 0001 ef00 1001 2002 0001 0000 0000 0000 0070 -0300 7d44 0000 0000 +0300 f86f 0000 0000 6000 0000 0018 1101 ef00 1001 2002 0001 0000 0000 0000 0070 2001 1002 3333 0001 0000 0000 0000 0001 @@ -18,14 +27,18 @@ ef00 1001 2002 0001 0000 0000 0000 0070 f427 0000 0344 0000 0004 f8f1 9d3c ddba 0e00 +# +# ICMPV6 +# - Time exceeded +# [in,gif0] 6000 0000 0048 3a40 ef00 1001 0880 6cbf 0000 0000 0000 0001 ef00 1001 2002 0001 0000 0000 0000 0070 -0300 7d44 0000 0000 +0300 7266 0000 0000 6000 0000 0018 1101 ef00 1001 2002 1001 0000 0000 0000 0070 2001 1002 3333 0001 0000 0000 0000 0001 -8083 829a +8083 f8a3 0018 f427 0000 0344 0000 0004 f8f1 9d3c ddba 0e00 diff --git a/contrib/ipfilter/test/input/ipv6.3 b/contrib/ipfilter/test/input/ipv6.3 index e8ad9f2f22d3..3b2ef4d325b3 100644 --- a/contrib/ipfilter/test/input/ipv6.3 +++ b/contrib/ipfilter/test/input/ipv6.3 @@ -7,19 +7,19 @@ [in,gif0] 6000 0000 0010 3a40 3ffe 8280 0000 2001 0000 0000 0000 4393 3ffe 8280 0000 2001 -0000 0000 0000 4395 8100 3e77 085c 0038 +0000 0000 0000 4395 8100 3e78 085c 0038 0c06 b73d 1b3d 0d00 [in,gif0] 6000 0000 0010 3a40 3ffe 8280 0000 2001 0000 0000 0000 4394 3ffe 8280 0000 2001 -0000 0000 0000 4395 8300 3e77 085c 0038 +0000 0000 0000 4395 8300 3c77 085c 0038 0c06 b73d 1b3d 0d00 [in,gif0] 6000 0000 0010 3a40 3ffe 8280 0000 2001 0000 0000 0000 4394 3ffe 8280 0000 2001 -0000 0000 0000 4395 8000 3e77 085c 0038 +0000 0000 0000 4395 8000 3f77 085c 0038 0c06 b73d 1b3d 0d00 [in,gif0] diff --git a/contrib/ipfilter/test/input/ipv6.4 b/contrib/ipfilter/test/input/ipv6.4 new file mode 100644 index 000000000000..eb986ae9e36c --- /dev/null +++ b/contrib/ipfilter/test/input/ipv6.4 @@ -0,0 +1,522 @@ +# fe80::20c:29ff:fe13:6899 > fe80::20c:29ff:fe21:5742: frag (0|1448) icmp6: echo request +[in,eth0] +6000 0000 05b0 2c40 fe80 0000 0000 0000 +020c 29ff fe13 6899 fe80 0000 0000 0000 +020c 29ff fe21 5742 3a00 0001 0000 0008 +8000 f400 2c0a 0001 fd38 4a42 9e59 0900 +0809 0a0b 0c0d 0e0f 1011 1213 1415 1617 +1819 1a1b 1c1d 1e1f 2021 2223 2425 2627 +2829 2a2b 2c2d 2e2f 3031 3233 3435 3637 +3839 3a3b 3c3d 3e3f 4041 4243 4445 4647 +4849 4a4b 4c4d 4e4f 5051 5253 5455 5657 +5859 5a5b 5c5d 5e5f 6061 6263 6465 6667 +6869 6a6b 6c6d 6e6f 7071 7273 7475 7677 +7879 7a7b 7c7d 7e7f 8081 8283 8485 8687 +8889 8a8b 8c8d 8e8f 9091 9293 9495 9697 +9899 9a9b 9c9d 9e9f a0a1 a2a3 a4a5 a6a7 +a8a9 aaab acad aeaf b0b1 b2b3 b4b5 b6b7 +b8b9 babb bcbd bebf c0c1 c2c3 c4c5 c6c7 +c8c9 cacb cccd cecf d0d1 d2d3 d4d5 d6d7 +d8d9 dadb dcdd dedf e0e1 e2e3 e4e5 e6e7 +e8e9 eaeb eced eeef f0f1 f2f3 f4f5 f6f7 +f8f9 fafb fcfd feff 0001 0203 0405 0607 +0809 0a0b 0c0d 0e0f 1011 1213 1415 1617 +1819 1a1b 1c1d 1e1f 2021 2223 2425 2627 +2829 2a2b 2c2d 2e2f 3031 3233 3435 3637 +3839 3a3b 3c3d 3e3f 4041 4243 4445 4647 +4849 4a4b 4c4d 4e4f 5051 5253 5455 5657 +5859 5a5b 5c5d 5e5f 6061 6263 6465 6667 +6869 6a6b 6c6d 6e6f 7071 7273 7475 7677 +7879 7a7b 7c7d 7e7f 8081 8283 8485 8687 +8889 8a8b 8c8d 8e8f 9091 9293 9495 9697 +9899 9a9b 9c9d 9e9f a0a1 a2a3 a4a5 a6a7 +a8a9 aaab acad aeaf b0b1 b2b3 b4b5 b6b7 +b8b9 babb bcbd bebf c0c1 c2c3 c4c5 c6c7 +c8c9 cacb cccd cecf d0d1 d2d3 d4d5 d6d7 +d8d9 dadb dcdd dedf e0e1 e2e3 e4e5 e6e7 +e8e9 eaeb eced eeef f0f1 f2f3 f4f5 f6f7 +f8f9 fafb fcfd feff 0001 0203 0405 0607 +0809 0a0b 0c0d 0e0f 1011 1213 1415 1617 +1819 1a1b 1c1d 1e1f 2021 2223 2425 2627 +2829 2a2b 2c2d 2e2f 3031 3233 3435 3637 +3839 3a3b 3c3d 3e3f 4041 4243 4445 4647 +4849 4a4b 4c4d 4e4f 5051 5253 5455 5657 +5859 5a5b 5c5d 5e5f 6061 6263 6465 6667 +6869 6a6b 6c6d 6e6f 7071 7273 7475 7677 +7879 7a7b 7c7d 7e7f 8081 8283 8485 8687 +8889 8a8b 8c8d 8e8f 9091 9293 9495 9697 +9899 9a9b 9c9d 9e9f a0a1 a2a3 a4a5 a6a7 +a8a9 aaab acad aeaf b0b1 b2b3 b4b5 b6b7 +b8b9 babb bcbd bebf c0c1 c2c3 c4c5 c6c7 +c8c9 cacb cccd cecf d0d1 d2d3 d4d5 d6d7 +d8d9 dadb dcdd dedf e0e1 e2e3 e4e5 e6e7 +e8e9 eaeb eced eeef f0f1 f2f3 f4f5 f6f7 +f8f9 fafb fcfd feff 0001 0203 0405 0607 +0809 0a0b 0c0d 0e0f 1011 1213 1415 1617 +1819 1a1b 1c1d 1e1f 2021 2223 2425 2627 +2829 2a2b 2c2d 2e2f 3031 3233 3435 3637 +3839 3a3b 3c3d 3e3f 4041 4243 4445 4647 +4849 4a4b 4c4d 4e4f 5051 5253 5455 5657 +5859 5a5b 5c5d 5e5f 6061 6263 6465 6667 +6869 6a6b 6c6d 6e6f 7071 7273 7475 7677 +7879 7a7b 7c7d 7e7f 8081 8283 8485 8687 +8889 8a8b 8c8d 8e8f 9091 9293 9495 9697 +9899 9a9b 9c9d 9e9f a0a1 a2a3 a4a5 a6a7 +a8a9 aaab acad aeaf b0b1 b2b3 b4b5 b6b7 +b8b9 babb bcbd bebf c0c1 c2c3 c4c5 c6c7 +c8c9 cacb cccd cecf d0d1 d2d3 d4d5 d6d7 +d8d9 dadb dcdd dedf e0e1 e2e3 e4e5 e6e7 +e8e9 eaeb eced eeef f0f1 f2f3 f4f5 f6f7 +f8f9 fafb fcfd feff 0001 0203 0405 0607 +0809 0a0b 0c0d 0e0f 1011 1213 1415 1617 +1819 1a1b 1c1d 1e1f 2021 2223 2425 2627 +2829 2a2b 2c2d 2e2f 3031 3233 3435 3637 +3839 3a3b 3c3d 3e3f 4041 4243 4445 4647 +4849 4a4b 4c4d 4e4f 5051 5253 5455 5657 +5859 5a5b 5c5d 5e5f 6061 6263 6465 6667 +6869 6a6b 6c6d 6e6f 7071 7273 7475 7677 +7879 7a7b 7c7d 7e7f 8081 8283 8485 8687 +8889 8a8b 8c8d 8e8f 9091 9293 9495 9697 +9899 9a9b 9c9d 9e9f a0a1 a2a3 a4a5 a6a7 +a8a9 aaab acad aeaf b0b1 b2b3 b4b5 b6b7 +b8b9 babb bcbd bebf c0c1 c2c3 c4c5 c6c7 +c8c9 cacb cccd cecf d0d1 d2d3 d4d5 d6d7 +d8d9 dadb dcdd dedf e0e1 e2e3 e4e5 e6e7 +e8e9 eaeb eced eeef f0f1 f2f3 f4f5 f6f7 +f8f9 fafb fcfd feff 0001 0203 0405 0607 +0809 0a0b 0c0d 0e0f 1011 1213 1415 1617 +1819 1a1b 1c1d 1e1f 2021 2223 2425 2627 +2829 2a2b 2c2d 2e2f 3031 3233 3435 3637 +3839 3a3b 3c3d 3e3f 4041 4243 4445 4647 +4849 4a4b 4c4d 4e4f 5051 5253 5455 5657 +5859 5a5b 5c5d 5e5f 6061 6263 6465 6667 +6869 6a6b 6c6d 6e6f 7071 7273 7475 7677 +7879 7a7b 7c7d 7e7f 8081 8283 8485 8687 +8889 8a8b 8c8d 8e8f 9091 9293 9495 9697 +9899 9a9b 9c9d 9e9f + +# fe80::20c:29ff:fe13:6899 > fe80::20c:29ff:fe21:5742: frag (1448|160) +[in,eth0] +6000 0000 00a8 2c40 fe80 0000 0000 0000 +020c 29ff fe13 6899 fe80 0000 0000 0000 +020c 29ff fe21 5742 3a00 05a8 0000 0008 +a0a1 a2a3 a4a5 a6a7 a8a9 aaab acad aeaf +b0b1 b2b3 b4b5 b6b7 b8b9 babb bcbd bebf +c0c1 c2c3 c4c5 c6c7 c8c9 cacb cccd cecf +d0d1 d2d3 d4d5 d6d7 d8d9 dadb dcdd dedf +e0e1 e2e3 e4e5 e6e7 e8e9 eaeb eced eeef +f0f1 f2f3 f4f5 f6f7 f8f9 fafb fcfd feff +0001 0203 0405 0607 0809 0a0b 0c0d 0e0f +1011 1213 1415 1617 1819 1a1b 1c1d 1e1f +2021 2223 2425 2627 2829 2a2b 2c2d 2e2f +3031 3233 3435 3637 3839 3a3b 3c3d 3e3f + +# fe80::20c:29ff:fe21:5742 > fe80::20c:29ff:fe13:6899: frag (0|1232) icmp6: echo reply +[out,eth0] +6000 0000 04d8 2c40 fe80 0000 0000 0000 +020c 29ff fe21 5742 fe80 0000 0000 0000 +020c 29ff fe13 6899 3a00 0001 9c56 86dd +8100 f300 2c0a 0001 fd38 4a42 9e59 0900 +0809 0a0b 0c0d 0e0f 1011 1213 1415 1617 +1819 1a1b 1c1d 1e1f 2021 2223 2425 2627 +2829 2a2b 2c2d 2e2f 3031 3233 3435 3637 +3839 3a3b 3c3d 3e3f 4041 4243 4445 4647 +4849 4a4b 4c4d 4e4f 5051 5253 5455 5657 +5859 5a5b 5c5d 5e5f 6061 6263 6465 6667 +6869 6a6b 6c6d 6e6f 7071 7273 7475 7677 +7879 7a7b 7c7d 7e7f 8081 8283 8485 8687 +8889 8a8b 8c8d 8e8f 9091 9293 9495 9697 +9899 9a9b 9c9d 9e9f a0a1 a2a3 a4a5 a6a7 +a8a9 aaab acad aeaf b0b1 b2b3 b4b5 b6b7 +b8b9 babb bcbd bebf c0c1 c2c3 c4c5 c6c7 +c8c9 cacb cccd cecf d0d1 d2d3 d4d5 d6d7 +d8d9 dadb dcdd dedf e0e1 e2e3 e4e5 e6e7 +e8e9 eaeb eced eeef f0f1 f2f3 f4f5 f6f7 +f8f9 fafb fcfd feff 0001 0203 0405 0607 +0809 0a0b 0c0d 0e0f 1011 1213 1415 1617 +1819 1a1b 1c1d 1e1f 2021 2223 2425 2627 +2829 2a2b 2c2d 2e2f 3031 3233 3435 3637 +3839 3a3b 3c3d 3e3f 4041 4243 4445 4647 +4849 4a4b 4c4d 4e4f 5051 5253 5455 5657 +5859 5a5b 5c5d 5e5f 6061 6263 6465 6667 +6869 6a6b 6c6d 6e6f 7071 7273 7475 7677 +7879 7a7b 7c7d 7e7f 8081 8283 8485 8687 +8889 8a8b 8c8d 8e8f 9091 9293 9495 9697 +9899 9a9b 9c9d 9e9f a0a1 a2a3 a4a5 a6a7 +a8a9 aaab acad aeaf b0b1 b2b3 b4b5 b6b7 +b8b9 babb bcbd bebf c0c1 c2c3 c4c5 c6c7 +c8c9 cacb cccd cecf d0d1 d2d3 d4d5 d6d7 +d8d9 dadb dcdd dedf e0e1 e2e3 e4e5 e6e7 +e8e9 eaeb eced eeef f0f1 f2f3 f4f5 f6f7 +f8f9 fafb fcfd feff 0001 0203 0405 0607 +0809 0a0b 0c0d 0e0f 1011 1213 1415 1617 +1819 1a1b 1c1d 1e1f 2021 2223 2425 2627 +2829 2a2b 2c2d 2e2f 3031 3233 3435 3637 +3839 3a3b 3c3d 3e3f 4041 4243 4445 4647 +4849 4a4b 4c4d 4e4f 5051 5253 5455 5657 +5859 5a5b 5c5d 5e5f 6061 6263 6465 6667 +6869 6a6b 6c6d 6e6f 7071 7273 7475 7677 +7879 7a7b 7c7d 7e7f 8081 8283 8485 8687 +8889 8a8b 8c8d 8e8f 9091 9293 9495 9697 +9899 9a9b 9c9d 9e9f a0a1 a2a3 a4a5 a6a7 +a8a9 aaab acad aeaf b0b1 b2b3 b4b5 b6b7 +b8b9 babb bcbd bebf c0c1 c2c3 c4c5 c6c7 +c8c9 cacb cccd cecf d0d1 d2d3 d4d5 d6d7 +d8d9 dadb dcdd dedf e0e1 e2e3 e4e5 e6e7 +e8e9 eaeb eced eeef f0f1 f2f3 f4f5 f6f7 +f8f9 fafb fcfd feff 0001 0203 0405 0607 +0809 0a0b 0c0d 0e0f 1011 1213 1415 1617 +1819 1a1b 1c1d 1e1f 2021 2223 2425 2627 +2829 2a2b 2c2d 2e2f 3031 3233 3435 3637 +3839 3a3b 3c3d 3e3f 4041 4243 4445 4647 +4849 4a4b 4c4d 4e4f 5051 5253 5455 5657 +5859 5a5b 5c5d 5e5f 6061 6263 6465 6667 +6869 6a6b 6c6d 6e6f 7071 7273 7475 7677 +7879 7a7b 7c7d 7e7f 8081 8283 8485 8687 +8889 8a8b 8c8d 8e8f 9091 9293 9495 9697 +9899 9a9b 9c9d 9e9f a0a1 a2a3 a4a5 a6a7 +a8a9 aaab acad aeaf b0b1 b2b3 b4b5 b6b7 +b8b9 babb bcbd bebf c0c1 c2c3 c4c5 c6c7 +c8c9 cacb cccd cecf d0d1 d2d3 d4d5 d6d7 +d8d9 dadb dcdd dedf e0e1 e2e3 e4e5 e6e7 +e8e9 eaeb eced eeef f0f1 f2f3 f4f5 f6f7 +f8f9 fafb fcfd feff 0001 0203 0405 0607 +0809 0a0b 0c0d 0e0f 1011 1213 1415 1617 +1819 1a1b 1c1d 1e1f 2021 2223 2425 2627 +2829 2a2b 2c2d 2e2f 3031 3233 3435 3637 +3839 3a3b 3c3d 3e3f 4041 4243 4445 4647 +4849 4a4b 4c4d 4e4f 5051 5253 5455 5657 +5859 5a5b 5c5d 5e5f 6061 6263 6465 6667 +6869 6a6b 6c6d 6e6f 7071 7273 7475 7677 +7879 7a7b 7c7d 7e7f 8081 8283 8485 8687 +8889 8a8b 8c8d 8e8f 9091 9293 9495 9697 +9899 9a9b 9c9d 9e9f a0a1 a2a3 a4a5 a6a7 +a8a9 aaab acad aeaf b0b1 b2b3 b4b5 b6b7 +b8b9 babb bcbd bebf c0c1 c2c3 c4c5 c6c7 + +# fe80::20c:29ff:fe21:5742 > fe80::20c:29ff:fe13:6899: frag (1232|376) +[out,eth0] +6000 0000 0180 2c40 fe80 0000 0000 0000 +020c 29ff fe21 5742 fe80 0000 0000 0000 +020c 29ff fe13 6899 3a00 04d0 9c56 86dd +c8c9 cacb cccd cecf d0d1 d2d3 d4d5 d6d7 +d8d9 dadb dcdd dedf e0e1 e2e3 e4e5 e6e7 +e8e9 eaeb eced eeef f0f1 f2f3 f4f5 f6f7 +f8f9 fafb fcfd feff 0001 0203 0405 0607 +0809 0a0b 0c0d 0e0f 1011 1213 1415 1617 +1819 1a1b 1c1d 1e1f 2021 2223 2425 2627 +2829 2a2b 2c2d 2e2f 3031 3233 3435 3637 +3839 3a3b 3c3d 3e3f 4041 4243 4445 4647 +4849 4a4b 4c4d 4e4f 5051 5253 5455 5657 +5859 5a5b 5c5d 5e5f 6061 6263 6465 6667 +6869 6a6b 6c6d 6e6f 7071 7273 7475 7677 +7879 7a7b 7c7d 7e7f 8081 8283 8485 8687 +8889 8a8b 8c8d 8e8f 9091 9293 9495 9697 +9899 9a9b 9c9d 9e9f a0a1 a2a3 a4a5 a6a7 +a8a9 aaab acad aeaf b0b1 b2b3 b4b5 b6b7 +b8b9 babb bcbd bebf c0c1 c2c3 c4c5 c6c7 +c8c9 cacb cccd cecf d0d1 d2d3 d4d5 d6d7 +d8d9 dadb dcdd dedf e0e1 e2e3 e4e5 e6e7 +e8e9 eaeb eced eeef f0f1 f2f3 f4f5 f6f7 +f8f9 fafb fcfd feff 0001 0203 0405 0607 +0809 0a0b 0c0d 0e0f 1011 1213 1415 1617 +1819 1a1b 1c1d 1e1f 2021 2223 2425 2627 +2829 2a2b 2c2d 2e2f 3031 3233 3435 3637 +3839 3a3b 3c3d 3e3f + +# fe80::20c:29ff:fe13:6899 > fe80::20c:29ff:fe21:5742: frag (0|1448) icmp6: echo request +[in,eth0] +6000 0000 05b0 2c40 fe80 0000 0000 0000 +020c 29ff fe13 6899 fe80 0000 0000 0000 +020c 29ff fe21 5742 3a00 0001 0000 0009 +8000 80fb 2c0a 0002 fe38 4a42 105e 0900 +0809 0a0b 0c0d 0e0f 1011 1213 1415 1617 +1819 1a1b 1c1d 1e1f 2021 2223 2425 2627 +2829 2a2b 2c2d 2e2f 3031 3233 3435 3637 +3839 3a3b 3c3d 3e3f 4041 4243 4445 4647 +4849 4a4b 4c4d 4e4f 5051 5253 5455 5657 +5859 5a5b 5c5d 5e5f 6061 6263 6465 6667 +6869 6a6b 6c6d 6e6f 7071 7273 7475 7677 +7879 7a7b 7c7d 7e7f 8081 8283 8485 8687 +8889 8a8b 8c8d 8e8f 9091 9293 9495 9697 +9899 9a9b 9c9d 9e9f a0a1 a2a3 a4a5 a6a7 +a8a9 aaab acad aeaf b0b1 b2b3 b4b5 b6b7 +b8b9 babb bcbd bebf c0c1 c2c3 c4c5 c6c7 +c8c9 cacb cccd cecf d0d1 d2d3 d4d5 d6d7 +d8d9 dadb dcdd dedf e0e1 e2e3 e4e5 e6e7 +e8e9 eaeb eced eeef f0f1 f2f3 f4f5 f6f7 +f8f9 fafb fcfd feff 0001 0203 0405 0607 +0809 0a0b 0c0d 0e0f 1011 1213 1415 1617 +1819 1a1b 1c1d 1e1f 2021 2223 2425 2627 +2829 2a2b 2c2d 2e2f 3031 3233 3435 3637 +3839 3a3b 3c3d 3e3f 4041 4243 4445 4647 +4849 4a4b 4c4d 4e4f 5051 5253 5455 5657 +5859 5a5b 5c5d 5e5f 6061 6263 6465 6667 +6869 6a6b 6c6d 6e6f 7071 7273 7475 7677 +7879 7a7b 7c7d 7e7f 8081 8283 8485 8687 +8889 8a8b 8c8d 8e8f 9091 9293 9495 9697 +9899 9a9b 9c9d 9e9f a0a1 a2a3 a4a5 a6a7 +a8a9 aaab acad aeaf b0b1 b2b3 b4b5 b6b7 +b8b9 babb bcbd bebf c0c1 c2c3 c4c5 c6c7 +c8c9 cacb cccd cecf d0d1 d2d3 d4d5 d6d7 +d8d9 dadb dcdd dedf e0e1 e2e3 e4e5 e6e7 +e8e9 eaeb eced eeef f0f1 f2f3 f4f5 f6f7 +f8f9 fafb fcfd feff 0001 0203 0405 0607 +0809 0a0b 0c0d 0e0f 1011 1213 1415 1617 +1819 1a1b 1c1d 1e1f 2021 2223 2425 2627 +2829 2a2b 2c2d 2e2f 3031 3233 3435 3637 +3839 3a3b 3c3d 3e3f 4041 4243 4445 4647 +4849 4a4b 4c4d 4e4f 5051 5253 5455 5657 +5859 5a5b 5c5d 5e5f 6061 6263 6465 6667 +6869 6a6b 6c6d 6e6f 7071 7273 7475 7677 +7879 7a7b 7c7d 7e7f 8081 8283 8485 8687 +8889 8a8b 8c8d 8e8f 9091 9293 9495 9697 +9899 9a9b 9c9d 9e9f a0a1 a2a3 a4a5 a6a7 +a8a9 aaab acad aeaf b0b1 b2b3 b4b5 b6b7 +b8b9 babb bcbd bebf c0c1 c2c3 c4c5 c6c7 +c8c9 cacb cccd cecf d0d1 d2d3 d4d5 d6d7 +d8d9 dadb dcdd dedf e0e1 e2e3 e4e5 e6e7 +e8e9 eaeb eced eeef f0f1 f2f3 f4f5 f6f7 +f8f9 fafb fcfd feff 0001 0203 0405 0607 +0809 0a0b 0c0d 0e0f 1011 1213 1415 1617 +1819 1a1b 1c1d 1e1f 2021 2223 2425 2627 +2829 2a2b 2c2d 2e2f 3031 3233 3435 3637 +3839 3a3b 3c3d 3e3f 4041 4243 4445 4647 +4849 4a4b 4c4d 4e4f 5051 5253 5455 5657 +5859 5a5b 5c5d 5e5f 6061 6263 6465 6667 +6869 6a6b 6c6d 6e6f 7071 7273 7475 7677 +7879 7a7b 7c7d 7e7f 8081 8283 8485 8687 +8889 8a8b 8c8d 8e8f 9091 9293 9495 9697 +9899 9a9b 9c9d 9e9f a0a1 a2a3 a4a5 a6a7 +a8a9 aaab acad aeaf b0b1 b2b3 b4b5 b6b7 +b8b9 babb bcbd bebf c0c1 c2c3 c4c5 c6c7 +c8c9 cacb cccd cecf d0d1 d2d3 d4d5 d6d7 +d8d9 dadb dcdd dedf e0e1 e2e3 e4e5 e6e7 +e8e9 eaeb eced eeef f0f1 f2f3 f4f5 f6f7 +f8f9 fafb fcfd feff 0001 0203 0405 0607 +0809 0a0b 0c0d 0e0f 1011 1213 1415 1617 +1819 1a1b 1c1d 1e1f 2021 2223 2425 2627 +2829 2a2b 2c2d 2e2f 3031 3233 3435 3637 +3839 3a3b 3c3d 3e3f 4041 4243 4445 4647 +4849 4a4b 4c4d 4e4f 5051 5253 5455 5657 +5859 5a5b 5c5d 5e5f 6061 6263 6465 6667 +6869 6a6b 6c6d 6e6f 7071 7273 7475 7677 +7879 7a7b 7c7d 7e7f 8081 8283 8485 8687 +8889 8a8b 8c8d 8e8f 9091 9293 9495 9697 +9899 9a9b 9c9d 9e9f a0a1 a2a3 a4a5 a6a7 +a8a9 aaab acad aeaf b0b1 b2b3 b4b5 b6b7 +b8b9 babb bcbd bebf c0c1 c2c3 c4c5 c6c7 +c8c9 cacb cccd cecf d0d1 d2d3 d4d5 d6d7 +d8d9 dadb dcdd dedf e0e1 e2e3 e4e5 e6e7 +e8e9 eaeb eced eeef f0f1 f2f3 f4f5 f6f7 +f8f9 fafb fcfd feff 0001 0203 0405 0607 +0809 0a0b 0c0d 0e0f 1011 1213 1415 1617 +1819 1a1b 1c1d 1e1f 2021 2223 2425 2627 +2829 2a2b 2c2d 2e2f 3031 3233 3435 3637 +3839 3a3b 3c3d 3e3f 4041 4243 4445 4647 +4849 4a4b 4c4d 4e4f 5051 5253 5455 5657 +5859 5a5b 5c5d 5e5f 6061 6263 6465 6667 +6869 6a6b 6c6d 6e6f 7071 7273 7475 7677 +7879 7a7b 7c7d 7e7f 8081 8283 8485 8687 +8889 8a8b 8c8d 8e8f 9091 9293 9495 9697 +9899 9a9b 9c9d 9e9f + +# fe80::20c:29ff:fe13:6899 > fe80::20c:29ff:fe21:5742: frag (1448|160) +[in,eth0] +6000 0000 00a8 2c40 fe80 0000 0000 0000 +020c 29ff fe13 6899 fe80 0000 0000 0000 +020c 29ff fe21 5742 3a00 05a8 0000 0009 +a0a1 a2a3 a4a5 a6a7 a8a9 aaab acad aeaf +b0b1 b2b3 b4b5 b6b7 b8b9 babb bcbd bebf +c0c1 c2c3 c4c5 c6c7 c8c9 cacb cccd cecf +d0d1 d2d3 d4d5 d6d7 d8d9 dadb dcdd dedf +e0e1 e2e3 e4e5 e6e7 e8e9 eaeb eced eeef +f0f1 f2f3 f4f5 f6f7 f8f9 fafb fcfd feff +0001 0203 0405 0607 0809 0a0b 0c0d 0e0f +1011 1213 1415 1617 1819 1a1b 1c1d 1e1f +2021 2223 2425 2627 2829 2a2b 2c2d 2e2f +3031 3233 3435 3637 3839 3a3b 3c3d 3e3f + +# fe80::20c:29ff:fe21:5742 > fe80::20c:29ff:fe13:6899: frag (0|1232) icmp6: echo reply +[out,eth0] +6000 0000 04d8 2c40 fe80 0000 0000 0000 +020c 29ff fe21 5742 fe80 0000 0000 0000 +020c 29ff fe13 6899 3a00 0001 9889 f4c1 +8100 7ffb 2c0a 0002 fe38 4a42 105e 0900 +0809 0a0b 0c0d 0e0f 1011 1213 1415 1617 +1819 1a1b 1c1d 1e1f 2021 2223 2425 2627 +2829 2a2b 2c2d 2e2f 3031 3233 3435 3637 +3839 3a3b 3c3d 3e3f 4041 4243 4445 4647 +4849 4a4b 4c4d 4e4f 5051 5253 5455 5657 +5859 5a5b 5c5d 5e5f 6061 6263 6465 6667 +6869 6a6b 6c6d 6e6f 7071 7273 7475 7677 +7879 7a7b 7c7d 7e7f 8081 8283 8485 8687 +8889 8a8b 8c8d 8e8f 9091 9293 9495 9697 +9899 9a9b 9c9d 9e9f a0a1 a2a3 a4a5 a6a7 +a8a9 aaab acad aeaf b0b1 b2b3 b4b5 b6b7 +b8b9 babb bcbd bebf c0c1 c2c3 c4c5 c6c7 +c8c9 cacb cccd cecf d0d1 d2d3 d4d5 d6d7 +d8d9 dadb dcdd dedf e0e1 e2e3 e4e5 e6e7 +e8e9 eaeb eced eeef f0f1 f2f3 f4f5 f6f7 +f8f9 fafb fcfd feff 0001 0203 0405 0607 +0809 0a0b 0c0d 0e0f 1011 1213 1415 1617 +1819 1a1b 1c1d 1e1f 2021 2223 2425 2627 +2829 2a2b 2c2d 2e2f 3031 3233 3435 3637 +3839 3a3b 3c3d 3e3f 4041 4243 4445 4647 +4849 4a4b 4c4d 4e4f 5051 5253 5455 5657 +5859 5a5b 5c5d 5e5f 6061 6263 6465 6667 +6869 6a6b 6c6d 6e6f 7071 7273 7475 7677 +7879 7a7b 7c7d 7e7f 8081 8283 8485 8687 +8889 8a8b 8c8d 8e8f 9091 9293 9495 9697 +9899 9a9b 9c9d 9e9f a0a1 a2a3 a4a5 a6a7 +a8a9 aaab acad aeaf b0b1 b2b3 b4b5 b6b7 +b8b9 babb bcbd bebf c0c1 c2c3 c4c5 c6c7 +c8c9 cacb cccd cecf d0d1 d2d3 d4d5 d6d7 +d8d9 dadb dcdd dedf e0e1 e2e3 e4e5 e6e7 +e8e9 eaeb eced eeef f0f1 f2f3 f4f5 f6f7 +f8f9 fafb fcfd feff 0001 0203 0405 0607 +0809 0a0b 0c0d 0e0f 1011 1213 1415 1617 +1819 1a1b 1c1d 1e1f 2021 2223 2425 2627 +2829 2a2b 2c2d 2e2f 3031 3233 3435 3637 +3839 3a3b 3c3d 3e3f 4041 4243 4445 4647 +4849 4a4b 4c4d 4e4f 5051 5253 5455 5657 +5859 5a5b 5c5d 5e5f 6061 6263 6465 6667 +6869 6a6b 6c6d 6e6f 7071 7273 7475 7677 +7879 7a7b 7c7d 7e7f 8081 8283 8485 8687 +8889 8a8b 8c8d 8e8f 9091 9293 9495 9697 +9899 9a9b 9c9d 9e9f a0a1 a2a3 a4a5 a6a7 +a8a9 aaab acad aeaf b0b1 b2b3 b4b5 b6b7 +b8b9 babb bcbd bebf c0c1 c2c3 c4c5 c6c7 +c8c9 cacb cccd cecf d0d1 d2d3 d4d5 d6d7 +d8d9 dadb dcdd dedf e0e1 e2e3 e4e5 e6e7 +e8e9 eaeb eced eeef f0f1 f2f3 f4f5 f6f7 +f8f9 fafb fcfd feff 0001 0203 0405 0607 +0809 0a0b 0c0d 0e0f 1011 1213 1415 1617 +1819 1a1b 1c1d 1e1f 2021 2223 2425 2627 +2829 2a2b 2c2d 2e2f 3031 3233 3435 3637 +3839 3a3b 3c3d 3e3f 4041 4243 4445 4647 +4849 4a4b 4c4d 4e4f 5051 5253 5455 5657 +5859 5a5b 5c5d 5e5f 6061 6263 6465 6667 +6869 6a6b 6c6d 6e6f 7071 7273 7475 7677 +7879 7a7b 7c7d 7e7f 8081 8283 8485 8687 +8889 8a8b 8c8d 8e8f 9091 9293 9495 9697 +9899 9a9b 9c9d 9e9f a0a1 a2a3 a4a5 a6a7 +a8a9 aaab acad aeaf b0b1 b2b3 b4b5 b6b7 +b8b9 babb bcbd bebf c0c1 c2c3 c4c5 c6c7 +c8c9 cacb cccd cecf d0d1 d2d3 d4d5 d6d7 +d8d9 dadb dcdd dedf e0e1 e2e3 e4e5 e6e7 +e8e9 eaeb eced eeef f0f1 f2f3 f4f5 f6f7 +f8f9 fafb fcfd feff 0001 0203 0405 0607 +0809 0a0b 0c0d 0e0f 1011 1213 1415 1617 +1819 1a1b 1c1d 1e1f 2021 2223 2425 2627 +2829 2a2b 2c2d 2e2f 3031 3233 3435 3637 +3839 3a3b 3c3d 3e3f 4041 4243 4445 4647 +4849 4a4b 4c4d 4e4f 5051 5253 5455 5657 +5859 5a5b 5c5d 5e5f 6061 6263 6465 6667 +6869 6a6b 6c6d 6e6f 7071 7273 7475 7677 +7879 7a7b 7c7d 7e7f 8081 8283 8485 8687 +8889 8a8b 8c8d 8e8f 9091 9293 9495 9697 +9899 9a9b 9c9d 9e9f a0a1 a2a3 a4a5 a6a7 +a8a9 aaab acad aeaf b0b1 b2b3 b4b5 b6b7 +b8b9 babb bcbd bebf c0c1 c2c3 c4c5 c6c7 + +# fe80::20c:29ff:fe21:5742 > fe80::20c:29ff:fe13:6899: frag (1232|376) +[out,eth0] +6000 0000 0180 2c40 fe80 0000 0000 0000 +020c 29ff fe21 5742 fe80 0000 0000 0000 +020c 29ff fe13 6899 3a00 04d0 9889 f4c1 +c8c9 cacb cccd cecf d0d1 d2d3 d4d5 d6d7 +d8d9 dadb dcdd dedf e0e1 e2e3 e4e5 e6e7 +e8e9 eaeb eced eeef f0f1 f2f3 f4f5 f6f7 +f8f9 fafb fcfd feff 0001 0203 0405 0607 +0809 0a0b 0c0d 0e0f 1011 1213 1415 1617 +1819 1a1b 1c1d 1e1f 2021 2223 2425 2627 +2829 2a2b 2c2d 2e2f 3031 3233 3435 3637 +3839 3a3b 3c3d 3e3f 4041 4243 4445 4647 +4849 4a4b 4c4d 4e4f 5051 5253 5455 5657 +5859 5a5b 5c5d 5e5f 6061 6263 6465 6667 +6869 6a6b 6c6d 6e6f 7071 7273 7475 7677 +7879 7a7b 7c7d 7e7f 8081 8283 8485 8687 +8889 8a8b 8c8d 8e8f 9091 9293 9495 9697 +9899 9a9b 9c9d 9e9f a0a1 a2a3 a4a5 a6a7 +a8a9 aaab acad aeaf b0b1 b2b3 b4b5 b6b7 +b8b9 babb bcbd bebf c0c1 c2c3 c4c5 c6c7 +c8c9 cacb cccd cecf d0d1 d2d3 d4d5 d6d7 +d8d9 dadb dcdd dedf e0e1 e2e3 e4e5 e6e7 +e8e9 eaeb eced eeef f0f1 f2f3 f4f5 f6f7 +f8f9 fafb fcfd feff 0001 0203 0405 0607 +0809 0a0b 0c0d 0e0f 1011 1213 1415 1617 +1819 1a1b 1c1d 1e1f 2021 2223 2425 2627 +2829 2a2b 2c2d 2e2f 3031 3233 3435 3637 +3839 3a3b 3c3d 3e3f + +# frag: [0-7:nh][8-15:res][16-31:off][32-64:id] +# Case 4: ipv6,fragment[id=10,off=0,m=1],tcp +[in,eth0] +600a af74 0038 2c40 +fe80 0000 0000 0000 020c 29ff fe21 5742 +fe80 0000 0000 0000 020c 29ff fe6e eb5a +0600 0001 0000 0010 +fff3 0017 52ac fbab 0000 0000 c002 8000 d36b 0000 +0204 05a0 0103 0300 0402 0101 0101 080a 0000 0000 0000 0000 0000 0000 + +# Case 5: ipv6,fragment[id=10,off=5,m=1],data +[in,eth0] +600a af74 0010 2c40 +fe80 0000 0000 0000 020c 29ff fe21 5742 +fe80 0000 0000 0000 020c 29ff fe6e eb5a +0600 0030 0000 0010 +0000 0000 0000 0000 + +# Case 3: ipv6,fragment[id=10,off=1,m=0],tcp +[in,eth0] +600a af74 0034 2c40 +fe80 0000 0000 0000 020c 29ff fe21 5742 +fe80 0000 0000 0000 020c 29ff fe6e eb5a +0600 0008 0000 0010 +0000 0000 b002 8000 d36b 0000 +0204 05a0 0103 0300 0402 0101 0101 080a 0000 0000 0000 0000 + +# Case 1: ipv6,fragment[id=11,off=0,m=1],hopopts,ah[next=dstopts] +[in,eth0] +600a af74 0020 2c40 +fe80 0000 0000 0000 020c 29ff fe21 5742 +fe80 0000 0000 0000 020c 29ff fe6e eb5a +0000 0001 0000 0011 +3300 0000 0000 0000 +3c01 0000 0000 0000 0000 0000 0000 0000 + +# Case 2: ipv6,fragment[id=11,off=3,m=0],dstopts,hop,tcp +[in,eth0] +600a af74 002c 2c40 +fe80 0000 0000 0000 020c 29ff fe21 5742 +fe80 0000 0000 0000 020c 29ff fe6e eb5a +3c00 0008 0000 0011 +0000 0000 0000 0000 +0600 0000 0000 0000 +fff3 0017 52ac fbab 0000 0000 5002 8000 d36b 0000 + +# Case 4: ipv6,fragment[id=10,off=0,m=1],tcp +[out,eth0] +6000 0000 001c 2c40 +fe80 0000 0000 0000 020c 29ff fe6e eb5a +fe80 0000 0000 0000 020c 29ff fe21 5742 +0600 0001 0000 0010 +0017 fff3 0000 0000 52ac fbac 5014 0000 cd26 0000 + +# Normal TCP Reset +[out,eth0] +6000 0000 0014 0640 +fe80 0000 0000 0000 020c 29ff fe6e eb5a +fe80 0000 0000 0000 020c 29ff fe21 5742 +0017 fff3 0000 0000 52ac fbac 5014 0000 cd26 0000 + +# Case 4: ipv6,fragment[id=12,off=0,m=1],tcp +[in,eth0] +600a af74 0038 2c40 +fe80 0000 0000 0000 020c 29ff fe21 5742 +fe80 0000 0000 0000 020c 29ff fe6e eb5a +0600 0001 0000 0012 +fff3 0017 52ac fbab 0000 0000 c002 8000 d36b 0000 +0204 05a0 0103 0300 0402 0101 0101 080a 0000 0000 0000 0000 0000 0000 + diff --git a/contrib/ipfilter/test/input/ipv6.6 b/contrib/ipfilter/test/input/ipv6.6 index 82efeac624da..fffbad28ccda 100644 --- a/contrib/ipfilter/test/input/ipv6.6 +++ b/contrib/ipfilter/test/input/ipv6.6 @@ -15,3 +15,17 @@ ef00 1001 2002 0001 0000 0000 0000 0070 1100 0008 0000 0001 0000 0000 0000 0000 0000 0000 0000 0000 +[out,gif0] +6000 0000 001e 2c01 +ef00 1001 2002 0001 0000 0000 0000 0070 +2001 1002 3333 0001 0000 0000 0000 0001 +1100 0001 0000 0001 +0000 0000 0000 0000 0000 0000 0000 + +[out,gif0] +6000 0000 0020 2c01 +ef00 1001 2002 0001 0000 0000 0000 0070 +2001 1002 3333 0001 0000 0000 0000 0001 +1100 001c 0000 0001 +0000 0000 0000 0000 0000 0000 0000 0000 + diff --git a/contrib/ipfilter/test/input/n10 b/contrib/ipfilter/test/input/n10 index 321ed0bf9443..1e919cc4b34d 100644 --- a/contrib/ipfilter/test/input/n10 +++ b/contrib/ipfilter/test/input/n10 @@ -1,6 +1,6 @@ # TCP SYN packet with an MSS option [out,ppp0] -4500 002c 10c9 4000 ff06 3289 c0a8 0103 -96cb e002 8032 0015 bd6b c9c8 0000 0000 +4500 002c 10c9 4000 ff06 3289 c0a8 0103 96cb e002 +8032 0015 bd6b c9c8 0000 0000 6002 2238 35f9 0000 0204 05b4 diff --git a/contrib/ipfilter/test/input/n100 b/contrib/ipfilter/test/input/n100 new file mode 100644 index 000000000000..94ff8c4be6e5 --- /dev/null +++ b/contrib/ipfilter/test/input/n100 @@ -0,0 +1,8 @@ +out on zx0 255 1.1.1.1 2.3.2.3 +out on zx0 255 1.1.1.1 2.2.2.3 +out on zx0 255 1.1.1.2 2.2.2.3 +out on zx0 255 1.2.1.2 2.2.2.3 +out on zx0 255 1.1.1.1 2.2.2.4 +out on zx0 255 1.1.1.1 2.2.2.3 +out on zx0 tcp 1.1.1.1,101 2.3.2.3,203 +out on zx0 tcp 1.1.1.1,101 2.2.2.3,203 diff --git a/contrib/ipfilter/test/input/n101 b/contrib/ipfilter/test/input/n101 new file mode 100644 index 000000000000..94ff8c4be6e5 --- /dev/null +++ b/contrib/ipfilter/test/input/n101 @@ -0,0 +1,8 @@ +out on zx0 255 1.1.1.1 2.3.2.3 +out on zx0 255 1.1.1.1 2.2.2.3 +out on zx0 255 1.1.1.2 2.2.2.3 +out on zx0 255 1.2.1.2 2.2.2.3 +out on zx0 255 1.1.1.1 2.2.2.4 +out on zx0 255 1.1.1.1 2.2.2.3 +out on zx0 tcp 1.1.1.1,101 2.3.2.3,203 +out on zx0 tcp 1.1.1.1,101 2.2.2.3,203 diff --git a/contrib/ipfilter/test/input/n102 b/contrib/ipfilter/test/input/n102 new file mode 100644 index 000000000000..94ff8c4be6e5 --- /dev/null +++ b/contrib/ipfilter/test/input/n102 @@ -0,0 +1,8 @@ +out on zx0 255 1.1.1.1 2.3.2.3 +out on zx0 255 1.1.1.1 2.2.2.3 +out on zx0 255 1.1.1.2 2.2.2.3 +out on zx0 255 1.2.1.2 2.2.2.3 +out on zx0 255 1.1.1.1 2.2.2.4 +out on zx0 255 1.1.1.1 2.2.2.3 +out on zx0 tcp 1.1.1.1,101 2.3.2.3,203 +out on zx0 tcp 1.1.1.1,101 2.2.2.3,203 diff --git a/contrib/ipfilter/test/input/n103 b/contrib/ipfilter/test/input/n103 new file mode 100644 index 000000000000..7957799d071f --- /dev/null +++ b/contrib/ipfilter/test/input/n103 @@ -0,0 +1,8 @@ +out on zx0 tcp 1.1.1.1,101 2.3.2.3,203 +out on zx0 tcp 1.1.1.1,101 2.2.2.3,203 +out on zx0 tcp 1.1.1.1,101 2.2.2.3,203 +out on zx0 tcp 1.1.1.2,101 2.2.2.3,203 +out on zx0 tcp 10.10.10.10,101 2.2.2.3,203 +out on zx0 tcp 5.5.5.5,101 2.2.2.3,203 +in on zx0 tcp 2.2.2.3,4000 4.4.4.4,1000 +out on zx0 tcp 7.7.7.7,101 2.2.2.3,203 diff --git a/contrib/ipfilter/test/input/n104 b/contrib/ipfilter/test/input/n104 new file mode 100644 index 000000000000..bb46b285608f --- /dev/null +++ b/contrib/ipfilter/test/input/n104 @@ -0,0 +1,48 @@ +[out,zx0] +4500 0028 0001 0000 ff06 b5c9 0101 0101 0202 0202 +0065 00cb 0000 0001 1000 0001 5010 2000 789d 0000 + +[in,zx0] +4500 0028 0002 0000 ff06 b1c2 0606 0001 0404 0001 +0fa0 03e8 0000 0001 1000 0001 5010 2000 623f 0000 + +[out,zx0] +4500 0028 0003 0000 ff06 b5c7 0101 0101 0202 0202 +0066 00cb 0000 0001 1000 0001 5010 2000 789c 0000 + +[in,zx0] +4500 0028 0004 0000 ff06 b1bf 0606 0001 0404 0002 +0fa0 03e8 0000 0001 1000 0001 5010 2000 623e 0000 + +[out,zx0] +4500 0028 0005 0000 ff06 b5c5 0101 0101 0202 0202 +0067 00cb 0000 0001 1000 0001 5010 2000 789b 0000 + +[in,zx0] +4500 0028 0006 0000 ff06 b1bd 0606 0001 0404 0002 +0fa0 03e9 0000 0001 1000 0001 5010 2000 623d 0000 + +[out,zx0] +4500 0028 0007 0000 ff06 b5c3 0101 0101 0202 0202 +0068 00cb 0000 0001 1000 0001 5010 2000 789a 0000 + +[in,zx0] +4500 0028 0008 0000 ff06 b1ba 0606 0002 0404 0002 +0fa0 03e9 0000 0001 1000 0001 5010 2000 623c 0000 + +[out,zx0] +4500 0028 0009 0000 ff06 b5c1 0101 0101 0202 0202 +0069 00cb 0000 0001 1000 0001 5010 2000 7899 0000 + +[in,zx0] +4500 0028 000a 0000 ff06 b1b8 0606 0002 0404 0002 +0fa1 03e9 0000 0001 1000 0001 5010 2000 623b 0000 + +[out,zx0] +4500 0028 000b 0000 ff06 b5bf 0101 0101 0202 0202 +006a 00cb 0000 0001 1000 0001 5010 2000 7898 0000 + +[in,zx0] +4500 0028 000c 0000 ff06 b1b5 0606 0002 0404 0003 +0fa1 03e9 0000 0001 1000 0001 5010 2000 623a 0000 + diff --git a/contrib/ipfilter/test/input/n105 b/contrib/ipfilter/test/input/n105 new file mode 100644 index 000000000000..63b68f0301cb --- /dev/null +++ b/contrib/ipfilter/test/input/n105 @@ -0,0 +1,8 @@ +[in,zx0] +4500 0028 0001 0000 ff06 b5c9 0101 0101 0202 0202 +0065 0050 0000 0001 1000 0001 5010 2000 7918 0000 + +[out,zx0] +4500 0028 0001 0000 ff06 adc0 0606 0001 0404 0404 +0c38 03e8 0000 0001 1000 0001 5010 2000 61a4 0000 + diff --git a/contrib/ipfilter/test/input/n106 b/contrib/ipfilter/test/input/n106 new file mode 100644 index 000000000000..4e933785606e --- /dev/null +++ b/contrib/ipfilter/test/input/n106 @@ -0,0 +1,8 @@ +[out,zx0] +4500 0028 0001 0000 ff06 b5c9 0101 0101 0202 0202 +0065 0050 0000 0001 1000 0001 5010 2000 7918 0000 + +[in,zx0] +4500 0028 0001 0000 ff06 adc0 0606 0001 0404 0404 +0c38 03e8 0000 0001 1000 0001 5010 2000 61a4 0000 + diff --git a/contrib/ipfilter/test/input/n10_6 b/contrib/ipfilter/test/input/n10_6 new file mode 100644 index 000000000000..5c1f5af85968 --- /dev/null +++ b/contrib/ipfilter/test/input/n10_6 @@ -0,0 +1,6 @@ +# TCP SYN packet with an MSS option +[out,ppp0] +6000 0000 0018 06ff c0a8 0100 0000 0000 0000 0000 0000 0003 96cb e000 0000 0000 0000 0000 0000 0002 +8032 0015 bd6b c9c8 0000 0000 +6002 2238 35f9 0000 0204 05b4 + diff --git a/contrib/ipfilter/test/input/n11_6 b/contrib/ipfilter/test/input/n11_6 new file mode 100644 index 000000000000..128e45ae5c5b --- /dev/null +++ b/contrib/ipfilter/test/input/n11_6 @@ -0,0 +1,16 @@ +out6 on zx0 255 10:1:1::0 10:1:1::2 +out6 on zx0 255 10:1:1::1 10:1:1::2 +out6 on zx0 255 10:1:1::2 10:1:1::1 +out6 on zx0 255 10::2:2:1 10:1:2::1 +out6 on zx0 255 10::2:2:2 10:1:2::1 +in6 on zx0 255 10:1:1::1 10:1:1::2 +in6 on zx0 255 10:1:1::2 10:1:1::1 +in6 on zx0 255 10::2:2:1 10::2:1:1 +in6 on zx0 255 10::2:2:2 10::2:1:1 +in6 on zx0 255 10::2:2:3 10:1:1::1 +in6 on zx0 255 10::2:3:4 10::2:2:2 +in6 on zx0 255 10:1:1::1 10::2:2:2 +in6 on zx0 255 10:1:1::2 10::2:2:2 +in6 on zx0 255 10:1:1::0 10::3:4:5 +in6 on zx0 255 10:1:1::1 10::3:4:5 +in6 on zx0 255 10:1:1::2 10::3:4:5 diff --git a/contrib/ipfilter/test/input/n12 b/contrib/ipfilter/test/input/n12 index fb4d76de4755..16e479ed1964 100644 --- a/contrib/ipfilter/test/input/n12 +++ b/contrib/ipfilter/test/input/n12 @@ -1,18 +1,18 @@ [out,le0=192.168.1.188] -4510 0040 2020 4000 4006 17e1 c0a8 7e53 -c0a8 0303 12c2 0017 4e33 298e 0000 0000 +4510 0040 2020 4000 4006 17e1 c0a8 7e53 c0a8 0303 +12c2 0017 4e33 298e 0000 0000 b002 4000 07af 0000 0204 05b4 0101 0402 0103 0300 0101 080a 0c72 549e 0000 0000 [in,le0] -4500 003c 00b0 4000 fe06 f5fb c0a8 0303 -c0a8 01bc 0017 2710 f674 e02c 4e33 298f +4500 003c 00b0 4000 fe06 f5fb c0a8 0303 c0a8 01bc +0017 2710 f674 e02c 4e33 298f a012 2798 e317 0000 0101 080a 2c05 b797 0c72 549e 0103 0300 0204 05b4 [out,le0] -4510 0034 493b 4000 4006 eed1 c0a8 7e53 -c0a8 0303 12c2 0017 4e33 298f f674 e02d +4510 0034 493b 4000 4006 eed1 c0a8 7e53 c0a8 0303 +12c2 0017 4e33 298f f674 e02d 8010 4000 8e2a 0000 0101 080a 0c72 549e 2c05 b797 diff --git a/contrib/ipfilter/test/input/n12_6 b/contrib/ipfilter/test/input/n12_6 new file mode 100644 index 000000000000..8583acbd7196 --- /dev/null +++ b/contrib/ipfilter/test/input/n12_6 @@ -0,0 +1,18 @@ +[out,le0=c0a8:0100::bc] +6000 0000 002c 0640 c0a8 7e00 0000 0000 0000 0000 0000 0053 c0a8 0300 0000 0000 0000 0000 0000 0003 +12c2 0017 4e33 298e 0000 0000 +b002 4000 07af 0000 0204 05b4 0101 0402 +0103 0300 0101 080a 0c72 549e 0000 0000 + +[in,le0] +6000 0000 0028 06fe c0a8 0300 0000 0000 0000 0000 0000 0003 c0a8 0100 0000 0000 0000 0000 0000 00bc +0017 2710 f674 e02c 4e33 298f +a012 2798 e317 0000 0101 080a 2c05 b797 +0c72 549e 0103 0300 0204 05b4 + +[out,le0] +6000 0000 0020 0640 c0a8 7e00 0000 0000 0000 0000 0000 0053 c0a8 0300 0000 0000 0000 0000 0000 0003 +12c2 0017 4e33 298f f674 e02d +8010 4000 8e2a 0000 0101 080a 0c72 549e +2c05 b797 + diff --git a/contrib/ipfilter/test/input/n13_6 b/contrib/ipfilter/test/input/n13_6 new file mode 100644 index 000000000000..54b262dc8ea1 --- /dev/null +++ b/contrib/ipfilter/test/input/n13_6 @@ -0,0 +1,4 @@ +out6 on le0 192:168:1::1 150:1:1::1 +out6 on le0 192:168:1::1 150:1:1::2 +out6 on le0 192:168:1::2 150:1:1::2 +out6 on le0 192:168:1::3 150:1:1::1 diff --git a/contrib/ipfilter/test/input/n14_6 b/contrib/ipfilter/test/input/n14_6 new file mode 100644 index 000000000000..f5dd5d359f64 --- /dev/null +++ b/contrib/ipfilter/test/input/n14_6 @@ -0,0 +1,4 @@ +in6 on gre0 tcp 10::2:2:5,2000 203:1:1::1,80 +in6 on gre0 tcp 10::2:2:6,2000 203:1:1::1,80 +in6 on gre0 tcp 10::2:2:7,2000 203:1:1::1,80 +in6 on gre0 tcp 10::2:2:5,2001 203:1:1::1,80 diff --git a/contrib/ipfilter/test/input/n15 b/contrib/ipfilter/test/input/n15 new file mode 100644 index 000000000000..715848e764d5 --- /dev/null +++ b/contrib/ipfilter/test/input/n15 @@ -0,0 +1,2 @@ +in on le0 tcp 9.9.9.9,10011 5.5.5.5,80 +in on le0 tcp 9.9.9.9,10011 2.2.2.2,80 diff --git a/contrib/ipfilter/test/input/n15_6 b/contrib/ipfilter/test/input/n15_6 new file mode 100644 index 000000000000..4a56138724b0 --- /dev/null +++ b/contrib/ipfilter/test/input/n15_6 @@ -0,0 +1,2 @@ +in6 on le0 tcp 9:9:9::9,10011 5:5::5:5,80 +in6 on le0 tcp 9:9:9::9,10011 2::2:2:2,80 diff --git a/contrib/ipfilter/test/input/n16 b/contrib/ipfilter/test/input/n16 index 2e77e40d7671..ad09a45f6735 100644 --- a/contrib/ipfilter/test/input/n16 +++ b/contrib/ipfilter/test/input/n16 @@ -8,33 +8,33 @@ a5a5 a5a5 a5a5 a5a5 a5a5 a5a5 a5a5 a5a5 a5a5 a5a5 a5a5 a5a5 a5a5 a5a5 [out,vlan2] -4520 0068 17e4 0000 6a11 ccba c05b ac33 -ac1f 5318 1194 07dd 0054 0000 a5a5 a5a5 +4520 0068 17e4 0000 6a11 ccba c05b ac33 ac1f 5318 +1194 07dd 0054 0000 a5a5 a5a5 a5a5 a5a5 a5a5 a5a5 a5a5 a5a5 a5a5 a5a5 a5a5 a5a5 a5a5 a5a5 a5a5 a5a5 a5a5 a5a5 a5a5 a5a5 a5a5 a5a5 a5a5 a5a5 a5a5 a5a5 a5a5 a5a5 a5a5 a5a5 a5a5 a5a5 -a5a5 a5a5 a5a5 a5a5 +a5a5 a5a5 a5a5 a5a5 a5a5 a5a5 [in,vlan2] -4500 0084 ee0f 0000 8001 e0a2 ac1f 5318 -c05b ac33 0303 4ca1 0000 0000 4520 0068 -17e4 0000 6a11 ccba c05b ac33 ac1f 5318 -1194 07dd 0054 0000 a5a5 a5a5 a5a5 a5a5 +4500 0084 ee0f 0000 8001 e0a2 ac1f 5318 c05b ac33 +0303 4ca1 0000 0000 +4520 0068 17e4 0000 6a11 ccba c05b ac33 ac1f 5318 +1194 07dd 0054 0000 a5a5 a5a5 a5a5 a5a5 a5a5 a5a5 a5a5 a5a5 a5a5 a5a5 a5a5 a5a5 a5a5 a5a5 a5a5 a5a5 a5a5 a5a5 a5a5 a5a5 a5a5 a5a5 a5a5 a5a5 a5a5 a5a5 a5a5 a5a5 a5a5 a5a5 a5a5 a5a5 -a5a5 a5a5 +a5a5 a5a5 a5a5 a5a5 a5a5 a5a5 [out,vlan0] -4500 0084 ee0f 0000 8001 e0a2 ac1f 5318 -c05b ac33 0303 4ca1 0000 0000 4520 0068 -17e4 0000 6a11 ccba c05b ac33 ac1f 5318 -1194 07dd 0054 0000 a5a5 a5a5 a5a5 a5a5 +4500 0084 ee0f 0000 8001 e0a2 ac1f 5318 c05b ac33 +0303 4ca1 0000 0000 +4520 0068 17e4 0000 6a11 ccba c05b ac33 ac1f 5318 +1194 07dd 0054 0000 a5a5 a5a5 a5a5 a5a5 a5a5 a5a5 a5a5 a5a5 a5a5 a5a5 a5a5 a5a5 a5a5 a5a5 a5a5 a5a5 a5a5 a5a5 a5a5 a5a5 a5a5 a5a5 a5a5 a5a5 a5a5 a5a5 a5a5 a5a5 a5a5 a5a5 a5a5 a5a5 -a5a5 a5a5 +a5a5 a5a5 a5a5 a5a5 a5a5 a5a5 diff --git a/contrib/ipfilter/test/input/n17 b/contrib/ipfilter/test/input/n17 new file mode 100644 index 000000000000..29709de53f62 --- /dev/null +++ b/contrib/ipfilter/test/input/n17 @@ -0,0 +1,24 @@ +[out,zx0] +4500 00a0 0000 0100 3f06 7555 0101 0101 0201 0101 +0401 0019 0000 0000 0000 0000 5010 2000 86b7 0000 +0000 0000 0000 0000 0000 0000 0000 0000 +0000 0000 0000 0000 0000 0000 0000 0000 +0000 0000 0000 0000 0000 0000 0000 0000 +0000 0000 0000 0000 0000 0000 0000 0000 +0000 0000 0000 0000 0000 0000 0000 0000 +0000 0000 0000 0000 0000 0000 0000 0000 +0000 0000 0000 0000 0000 0000 0000 0000 +0000 0000 0000 0000 + +[in,zx0] +4500 00a0 0000 0100 3f06 7553 0201 0101 0101 0103 +0401 0019 0000 0000 0000 0000 5010 2000 86b7 0000 +0000 0000 0000 0000 0000 0000 0000 0000 +0000 0000 0000 0000 0000 0000 0000 0000 +0000 0000 0000 0000 0000 0000 0000 0000 +0000 0000 0000 0000 0000 0000 0000 0000 +0000 0000 0000 0000 0000 0000 0000 0000 +0000 0000 0000 0000 0000 0000 0000 0000 +0000 0000 0000 0000 0000 0000 0000 0000 +0000 0000 0000 0000 + diff --git a/contrib/ipfilter/test/input/n17_6 b/contrib/ipfilter/test/input/n17_6 new file mode 100644 index 000000000000..a176c158ccc1 --- /dev/null +++ b/contrib/ipfilter/test/input/n17_6 @@ -0,0 +1,24 @@ +[out,zx0] +6000 0000 008c 063f 0001 0000 0000 0000 0000 0001 0001 0001 0002 0000 0000 0000 0000 0001 0001 0001 +0401 0019 0000 0000 0000 0000 5010 2000 86b7 0000 +0000 0000 0000 0000 0000 0000 0000 0000 +0000 0000 0000 0000 0000 0000 0000 0000 +0000 0000 0000 0000 0000 0000 0000 0000 +0000 0000 0000 0000 0000 0000 0000 0000 +0000 0000 0000 0000 0000 0000 0000 0000 +0000 0000 0000 0000 0000 0000 0000 0000 +0000 0000 0000 0000 0000 0000 0000 0000 +0000 0000 0000 0000 + +[in,zx0] +6000 0000 008c 063f 0002 0000 0000 0000 0000 0001 0001 0001 0001 0000 0000 0000 0000 0001 0001 0003 +0401 0019 0000 0000 0000 0000 5010 2000 86b7 0000 +0000 0000 0000 0000 0000 0000 0000 0000 +0000 0000 0000 0000 0000 0000 0000 0000 +0000 0000 0000 0000 0000 0000 0000 0000 +0000 0000 0000 0000 0000 0000 0000 0000 +0000 0000 0000 0000 0000 0000 0000 0000 +0000 0000 0000 0000 0000 0000 0000 0000 +0000 0000 0000 0000 0000 0000 0000 0000 +0000 0000 0000 0000 + diff --git a/contrib/ipfilter/test/input/n18 b/contrib/ipfilter/test/input/n18 new file mode 100644 index 000000000000..a7a610cf8fb8 --- /dev/null +++ b/contrib/ipfilter/test/input/n18 @@ -0,0 +1,8 @@ +out on z0 tcp 2.2.2.2,22 3.3.3.3,30 +out on z0 tcp 2.2.2.2,23 3.3.3.3,31 +out on z0 tcp 2.2.2.2,24 3.3.3.3,32 +out on z0 tcp 2.2.2.2,25 3.3.3.3,33 +out on z0 tcp 2.2.2.2,26 3.3.3.3,34 +out on z0 tcp 2.2.2.2,27 3.3.3.3,35 +out on z0 tcp 2.2.2.2,28 3.3.3.3,36 +out on z0 tcp 2.2.2.2,29 3.3.3.3,37 diff --git a/contrib/ipfilter/test/input/n1_6 b/contrib/ipfilter/test/input/n1_6 new file mode 100644 index 000000000000..c1badab9a9cb --- /dev/null +++ b/contrib/ipfilter/test/input/n1_6 @@ -0,0 +1,34 @@ +out6 on zx0 255 10:1:1::0 10:1:1::2 +out6 on zx0 255 10:1:1::1 10:1:1::2 +out6 on zx0 255 10:1:1::2 10:1:1::1 +out6 on zx0 tcp 10:1:1::2,1025 10:1:1::1,1025 +out6 on zx0 tcp 10:1:1::2,1026 10:1:1::1,1025 +out6 on zx0 255 10::2:2:1 10:1:2::1 +out6 on zx0 255 10::2:2:2 10:1:2::1 +in6 on zx0 255 10:1:1::1 10:1:1::2 +in6 on zx0 255 10:1:1::2 10:1:1::1 +in6 on zx0 255 10::2:2:1 10::2:1:1 +in6 on zx0 255 10::2:2:2 10::2:1:1 +in6 on zx0 255 10::2:2:3 10:1:1::1 +in6 on zx0 255 10::2:3:4 10::2:2:2 +in6 on zx0 255 10:1:1::1 10::2:2:2 +in6 on zx0 255 10:1:1::2 10::2:2:2 +in6 on zx0 255 10:1:1::0 10::3:4:5 +in6 on zx0 255 10:1:1::1 10::3:4:5 +in6 on zx0 255 10:1:1::2 10::3:4:5 +in6 on zx0 tcp 10:1:1::1,1025 10::3:4:5,1025 +out6 on zx0 58 10:1:1::1 10:4:3::2 +in6 on zx0 58 10:4:3::2 10::2:2:2 +in6 on zx0 58 10:4:3::2 10::3:4:1 +in6 on zx0 58 10:4:3::2 10::3:4:2 +in6 on zx0 58 10:4:3::2 10::3:4:3 +in6 on zx0 58 10:4:3::2 10::3:4:4 +in6 on zx0 58 10:4:3::2 10::3:4:5 +out6 on zx0 34 10:1:1::2 10:4:3::2 +in6 on zx0 34 10:4:3::2 10::3:4:4 +out6 on zx0 34 10:1:1::2 10:4:3::4 +in6 on zx0 34 10:4:3::4 10::3:4:5 +out6 on zx0 34 10:1:1::3 10:4:3::4 +in6 on zx0 34 10:4:3::4 10::3:4:6 +out6 on zx0 35 10:1:1::3 10:4:3::4 +in6 on zx0 35 10:4:3::4 10::3:4:7 diff --git a/contrib/ipfilter/test/input/n200 b/contrib/ipfilter/test/input/n200 new file mode 100644 index 000000000000..9b021581e131 --- /dev/null +++ b/contrib/ipfilter/test/input/n200 @@ -0,0 +1,6 @@ +[in,bar0] +4500 0028 0000 0000 0006 435a 6363 6363 5858 5858 038d 0050 0000 0000 0000 0000 5000 1000 2491 0000 + +[out,bar0] +4500 0044 0000 0000 ff11 bda6 7f00 0001 7f00 0001 2775 2775 0030 0000 4500 0028 0000 0000 0006 435a 6363 6363 5858 5858 038d 0050 0000 0000 0000 0000 5000 1000 2491 0000 + diff --git a/contrib/ipfilter/test/input/n2_6 b/contrib/ipfilter/test/input/n2_6 new file mode 100644 index 000000000000..3ea74ff377ab --- /dev/null +++ b/contrib/ipfilter/test/input/n2_6 @@ -0,0 +1,19 @@ +out6 on zx0 tcp 10:1:1::1,1025 10:1:1::1,1025 +out6 on zx0 tcp 10:1:1::1,1025 10:1:1::2,1025 +out6 on zx0 10:1:1::0 10:1:1::2 +out6 on zx0 10:1:1::1 10:1:2::1 +out6 on zx0 tcp 10:1:1::2,1025 10:1:1::1,1025 +out6 on zx0 tcp 10:1:1::2,1025 10:1:1::1,1025 +out6 on zx0 tcp 10:1:1::2,1026 10:1:1::1,1025 +out6 on zx0 udp 10:1:1::2,1025 10:1:1::1,1025 +out6 on zx0 tcp 10:1:1::3,2000 10:1:2::1,80 +out6 on zx0 tcp 10:1:1::3,2001 10:1:3::1,80 +out6 on zx0 tcp 10:1:1::3,2002 10:1:4::1,80 +out6 on zx0 tcp 10:1:1::3,2003 10:1:4::1,80 +in6 on zx0 10:1:1::1 10:1:1::2 +in6 on zx0 tcp 10:1:1::1,1025 10:1:1::2,1025 +in6 on zx0 10:1:1::2 10:1:1::1 +in6 on zx0 tcp 10:1:1::1,1026 10::3:4:5,40000 +in6 on zx0 tcp 10:1:1::1,1025 10::3:4:5,40000 +in6 on zx0 udp 10:1:1::2,1025 10::3:4:5,40001 +in6 on zx0 tcp 10:1:2::1,80 10::3:4:5,40001 diff --git a/contrib/ipfilter/test/input/n4_6 b/contrib/ipfilter/test/input/n4_6 new file mode 100644 index 000000000000..8f0f423bc27b --- /dev/null +++ b/contrib/ipfilter/test/input/n4_6 @@ -0,0 +1,10 @@ +in6 on zx0 tcp 10:3:3::3,12345 10:1:1::1,23 +out6 on zx0 tcp 10::2:2:1,10023 10:3:3::3,12345 +in6 on zx0 tcp 10:3:3::3,12345 10:1:1::1,53 +out6 on zx0 tcp 10::2:2:1,10053 10:3:3::3,12345 +in6 on zx0 tcp 10:3:3::3,12346 10:1:0::0,23 +out6 on zx0 tcp 10::2:2:1,10023 10:3:3::3,12346 +in6 on zx0 udp 10:3:3::3,12345 10:1:1::0,53 +out6 on zx0 udp 10::2:2:1,10053 10:3:3::3,12345 +in6 on zx0 tcp 10:3:3::3,12345 10:1:1::0,53 +out6 on zx0 tcp 10::2:2:1,53 10:3:3::3,12345 diff --git a/contrib/ipfilter/test/input/n5_6 b/contrib/ipfilter/test/input/n5_6 new file mode 100644 index 000000000000..9ac0c29c4a39 --- /dev/null +++ b/contrib/ipfilter/test/input/n5_6 @@ -0,0 +1,54 @@ +out6 on zx0 255 10:1:1::0 10:1:1::2 +out6 on zx0 255 10:1:1::1 10:1:1::2 +out6 on zx0 255 10:1:1::2 10:1:1::1 +out6 on zx0 tcp 10:1:1::2,1025 10:1:1::1,1025 +out6 on zx0 tcp 10:1:1::2,1026 10:1:1::1,1025 +out6 on zx0 255 10::2:2:1 10:1:2::1 +out6 on zx0 255 10::2:2:2 10:1:2::1 +in6 on zx0 255 10:1:1::1 10:1:1::2 +in6 on zx0 255 10:1:1::2 10:1:1::1 +in6 on zx0 255 10::2:2:1 10::2:1:1 +in6 on zx0 255 10::2:2:2 10::2:1:1 +in6 on zx0 255 10::2:2:3 10:1:1::1 +in6 on zx0 255 10::2:3:4 10::2:2:2 +in6 on zx0 255 10:1:1::1 10::2:2:2 +in6 on zx0 255 10:1:1::2 10::2:2:2 +in6 on zx0 255 10:1:1::0 10::3:4:5 +in6 on zx0 255 10:1:1::1 10::3:4:5 +in6 on zx0 255 10:1:1::2 10::3:4:5 +in6 on zx0 tcp 10:1:1::1,1025 10::3:4:5,1025 +out6 on zx0 58 10:1:1::1 10:4:3::2 +in6 on zx0 58 10:4:3::2 10::2:2:2 +in6 on zx0 58 10:4:3::2 10::3:4:3 +in6 on zx0 58 10:4:3::2 10::3:4:5 +out6 on zx0 34 10:1:1::2 10:4:3::2 +in6 on zx0 34 10:4:3::2 10::3:4:4 +out6 on zx0 34 10:1:1::2 10:4:3::4 +in6 on zx0 34 10:4:3::4 10::3:4:5 +out6 on zx0 34 10:1:1::3 10:4:3::4 +in6 on zx0 34 10:4:3::4 10::3:4:6 +out6 on zx0 35 10:1:1::3 10:4:3::4 +in6 on zx0 35 10:4:3::4 10::3:4:7 +out6 on zx0 tcp 10:1:1::1,1025 10:1:1::1,1025 +out6 on zx0 tcp 10:1:1::1,1025 10:1:1::2,1025 +out6 on zx0 10:1:1::0 10:1:1::2 +out6 on zx0 10:1:1::1 10:1:2::1 +out6 on zx0 tcp 10:1:1::2,1025 10:1:1::1,1025 +out6 on zx0 tcp 10:1:1::2,1025 10:1:1::1,1025 +out6 on zx0 tcp 10:1:1::2,1026 10:1:1::1,1025 +out6 on zx0 udp 10:1:1::2,1025 10:1:1::1,1025 +out6 on zx0 tcp 10:1:1::3,2000 10:1:2::1,80 +out6 on zx0 tcp 10:1:1::3,2001 10:1:3::1,80 +out6 on zx0 tcp 10:1:1::3,2002 10:1:4::1,80 +out6 on zx0 tcp 10:1:1::3,2003 10:1:4::1,80 +in6 on zx0 10:1:1::1 10:1:1::2 +in6 on zx0 tcp 10:1:1::1,1025 10:1:1::2,1025 +in6 on zx0 10:1:1::2 10:1:1::1 +out6 on zx0 tcp 10:1:1::1,1026 10::3:4:5,40000 +in6 on zx0 tcp 10:1:1::1,1026 10::3:4:5,40000 +out6 on zx0 tcp 10:1:1::1,1025 10::3:4:5,40000 +in6 on zx0 tcp 10:1:1::1,1025 10::3:4:5,40000 +out6 on zx0 udp 10:1:1::2,1025 10::3:4:5,40001 +in6 on zx0 udp 10:1:1::2,1025 10::3:4:5,40001 +out6 on zx0 tcp 10:1:2::1,80 10::3:4:5,40001 +in6 on zx0 tcp 10:1:2::1,80 10::3:4:5,40001 diff --git a/contrib/ipfilter/test/input/n6_6 b/contrib/ipfilter/test/input/n6_6 new file mode 100644 index 000000000000..18300cd14552 --- /dev/null +++ b/contrib/ipfilter/test/input/n6_6 @@ -0,0 +1,13 @@ +in6 on zx0 tcp 10::2:2:2,12345 10:1:1::1,23 +in6 on zx0 tcp 10::2:2:2,12345 10:1:1::2,23 +in6 on zx0 tcp 10:3:0::1,12345 10:1:2::2,23 +in6 on zx0 tcp 10:3:0::1,12345 10::2:2:2,23 +in6 on zx0 tcp 10:3:3::3,12345 10:1:1::1,23 +in6 on zx0 tcp 10::2:2:2,12345 10:1:1::1,53 +in6 on zx0 tcp 10:3:3::3,12345 10:1:1::1,53 +in6 on zx0 tcp 10::2:2:2,12345 10:1:0::0,23 +in6 on zx0 tcp 10:3:3::3,12345 10:1:0::0,23 +in6 on zx0 udp 10::2:2:2,12345 10:1:1::0,53 +in6 on zx0 udp 10:3:3::3,12345 10:1:1::0,53 +in6 on zx0 tcp 10::2:2:2,12345 10:1:1::0,53 +in6 on zx0 tcp 10:3:3::3,12345 10:1:1::0,53 diff --git a/contrib/ipfilter/test/input/n7_6 b/contrib/ipfilter/test/input/n7_6 new file mode 100644 index 000000000000..b31a1def4f48 --- /dev/null +++ b/contrib/ipfilter/test/input/n7_6 @@ -0,0 +1,9 @@ +in6 on zx0 tcp 10::2:3:1,1230 10:1:1::1,22 +in6 on zx0 tcp 10::2:3:1,1231 10:1:1::1,23 +in6 on zx0 tcp 10::2:3:1,1232 10:1:1::1,50 +in6 on zx0 tcp 10::2:3:1,1233 10:1:1::1,79 +in6 on zx0 tcp 10::2:3:1,1234 10:1:1::1,80 +in6 on zx0 tcp 10::2:3:1,1235 10:1:1::2,80 +in6 on zx0 tcp 10::2:3:1,1236 10:1:1::3,80 +in6 on zx0 tcp 10::2:3:1,1237 10:1:1::4,80 +in6 on zx0 tcp 10::2:3:1,1238 10:1:1::4,80 diff --git a/contrib/ipfilter/test/input/n8 b/contrib/ipfilter/test/input/n8 index 1f5b2130ba28..c0a5b3fd7dd0 100644 --- a/contrib/ipfilter/test/input/n8 +++ b/contrib/ipfilter/test/input/n8 @@ -1,27 +1,31 @@ #v tos len id off ttl p sum src dst # ICMP ECHO (ping) exchange -[out,icmp0] 4500 0054 8bc1 0000 ff01 23dc 0202 0202 0404 0404 +[out,icmp0] +4500 0054 8bc1 0000 ff01 23dc 0202 0202 0404 0404 0800 efdf 6220 0000 3f6f 6e80 000b 0d02 0809 0a0b 0c0d 0e0f 1011 1213 1415 1617 1819 1a1b 1c1d 1e1f 2021 2223 2425 2627 2829 2a2b 2c2d 2e2f 3031 3233 3435 3637 -[in,icmp0] 4500 0054 3fd5 4000 ff01 1fc1 0404 0404 0a0a 0a01 +[in,icmp0] +4500 0054 3fd5 4000 ff01 1fc1 0404 0404 0a0a 0a01 0000 f7df 6220 0000 3f6f 6e80 000b 0d02 0809 0a0b 0c0d 0e0f 1011 1213 1415 1617 1819 1a1b 1c1d 1e1f 2021 2223 2425 2627 2829 2a2b 2c2d 2e2f 3031 3233 3435 3637 -[out,icmp0] 4500 0054 8bc1 0000 ff01 23dc 0202 0202 0404 0404 +[out,icmp0] +4500 0054 8bc1 0000 ff01 23dc 0202 0202 0404 0404 0800 efde 6220 0001 3f6f 6e80 000b 0d02 0809 0a0b 0c0d 0e0f 1011 1213 1415 1617 1819 1a1b 1c1d 1e1f 2021 2223 2425 2627 2829 2a2b 2c2d 2e2f 3031 3233 3435 3637 -[in,icmp0] 4500 0054 3fd5 4000 ff01 1fc1 0404 0404 0a0a 0a01 +[in,icmp0] +4500 0054 3fd5 4000 ff01 1fc1 0404 0404 0a0a 0a01 0000 f7de 6220 0001 3f6f 6e80 000b 0d02 0809 0a0b 0c0d 0e0f 1011 1213 1415 1617 1819 1a1b 1c1d 1e1f 2021 2223 2425 diff --git a/contrib/ipfilter/test/input/n8_6 b/contrib/ipfilter/test/input/n8_6 new file mode 100644 index 000000000000..8039f78df638 --- /dev/null +++ b/contrib/ipfilter/test/input/n8_6 @@ -0,0 +1,37 @@ +#v tos len id off ttl p sum src dst +# ICMP ECHO (ping) exchange +[out,icmp0] +6000 0000 0040 3aff 0002 0000 0000 0000 0000 0002 0002 0002 0004 0004 0004 0000 0000 0000 0000 0004 +8000 774d 6220 0000 3f6f 6e80 000b +0d02 0809 0a0b 0c0d 0e0f 1011 1213 1415 +1617 1819 1a1b 1c1d 1e1f 2021 2223 2425 +2627 2829 2a2b 2c2d 2e2f 3031 3233 3435 +3637 + +# ECHO reply +[in,icmp0] +6000 0000 0040 3aff 0004 0004 0004 0000 0000 0000 0000 0004 0010 0010 0010 0000 0000 0000 0000 0001 +8100 7624 6220 0000 3f6f 6e80 000b +0d02 0809 0a0b 0c0d 0e0f 1011 1213 1415 +1617 1819 1a1b 1c1d 1e1f 2021 2223 2425 +2627 2829 2a2b 2c2d 2e2f 3031 3233 3435 +3637 + +# ECHO request +[out,icmp0] +6000 0000 0040 3aff 0002 0000 0000 0000 0000 0002 0002 0002 0004 0004 0004 0000 0000 0000 0000 0004 +8000 774c 6220 0001 3f6f 6e80 000b +0d02 0809 0a0b 0c0d 0e0f 1011 1213 1415 +1617 1819 1a1b 1c1d 1e1f 2021 2223 2425 +2627 2829 2a2b 2c2d 2e2f 3031 3233 3435 +3637 + +# ECHO reply +[in,icmp0] +6000 0000 0040 3aff 0004 0004 0004 0000 0000 0000 0000 0004 0010 0010 0010 0000 0000 0000 0000 0001 +8100 7623 6220 0001 3f6f 6e80 000b +0d02 0809 0a0b 0c0d 0e0f 1011 1213 1415 +1617 1819 1a1b 1c1d 1e1f 2021 2223 2425 +2627 2829 2a2b 2c2d 2e2f 3031 3233 3435 +3637 + diff --git a/contrib/ipfilter/test/input/n9 b/contrib/ipfilter/test/input/n9 index c4aada8f2c70..5c2d3c7dfebd 100644 --- a/contrib/ipfilter/test/input/n9 +++ b/contrib/ipfilter/test/input/n9 @@ -1,27 +1,31 @@ #v tos len id off ttl p sum src dst # ICMP ECHO (ping) exchange -[in,icmp0] 4500 0054 8bc1 0000 ff01 23dc 0202 0202 0404 0404 +[in,icmp0] +4500 0054 8bc1 0000 ff01 23dc 0202 0202 0404 0404 0800 efdf 6220 0000 3f6f 6e80 000b 0d02 0809 0a0b 0c0d 0e0f 1011 1213 1415 1617 1819 1a1b 1c1d 1e1f 2021 2223 2425 2627 2829 2a2b 2c2d 2e2f 3031 3233 3435 3637 -[out,icmp0] 4500 0054 3fd5 4000 ff01 23c5 0a0a 0a01 0202 0202 +[out,icmp0] +4500 0054 3fd5 4000 ff01 23c5 0a0a 0a01 0202 0202 0000 f7df 6220 0000 3f6f 6e80 000b 0d02 0809 0a0b 0c0d 0e0f 1011 1213 1415 1617 1819 1a1b 1c1d 1e1f 2021 2223 2425 2627 2829 2a2b 2c2d 2e2f 3031 3233 3435 3637 -[in,icmp0] 4500 0054 8bc1 0000 ff01 23dc 0202 0202 0404 0404 +[in,icmp0] +4500 0054 8bc1 0000 ff01 23dc 0202 0202 0404 0404 0800 efde 6220 0001 3f6f 6e80 000b 0d02 0809 0a0b 0c0d 0e0f 1011 1213 1415 1617 1819 1a1b 1c1d 1e1f 2021 2223 2425 2627 2829 2a2b 2c2d 2e2f 3031 3233 3435 3637 -[out,icmp0] 4500 0054 3fd5 4000 ff01 23c5 0a0a 0a01 0202 0202 +[out,icmp0] +4500 0054 3fd5 4000 ff01 23c5 0a0a 0a01 0202 0202 0000 f7de 6220 0001 3f6f 6e80 000b 0d02 0809 0a0b 0c0d 0e0f 1011 1213 1415 1617 1819 1a1b 1c1d 1e1f 2021 2223 2425 diff --git a/contrib/ipfilter/test/input/n9_6 b/contrib/ipfilter/test/input/n9_6 new file mode 100644 index 000000000000..42db09dd3653 --- /dev/null +++ b/contrib/ipfilter/test/input/n9_6 @@ -0,0 +1,34 @@ +#v tos len id off ttl p sum src dst +# ICMP ECHO (ping) exchange +[in,icmp0] +6000 0000 0040 3aff 0002 0000 0000 0000 0000 0002 0002 0002 0004 0004 0004 0000 0000 0000 0000 0004 +8000 774d 6220 0000 3f6f 6e80 000b +0d02 0809 0a0b 0c0d 0e0f 1011 1213 1415 +1617 1819 1a1b 1c1d 1e1f 2021 2223 2425 +2627 2829 2a2b 2c2d 2e2f 3031 3233 3435 +3637 + +[out,icmp0] +6000 0000 0040 3aff 0010 0010 0010 0000 0000 0000 0000 0001 0002 0000 0000 0000 0000 0002 0002 0002 +8100 762c 6220 0000 3f6f 6e80 000b +0d02 0809 0a0b 0c0d 0e0f 1011 1213 1415 +1617 1819 1a1b 1c1d 1e1f 2021 2223 2425 +2627 2829 2a2b 2c2d 2e2f 3031 3233 3435 +3637 + +[in,icmp0] +6000 0000 0040 3aff 0002 0000 0000 0000 0000 0002 0002 0002 0004 0004 0004 0000 0000 0000 0000 0004 +8000 774c 6220 0001 3f6f 6e80 000b +0d02 0809 0a0b 0c0d 0e0f 1011 1213 1415 +1617 1819 1a1b 1c1d 1e1f 2021 2223 2425 +2627 2829 2a2b 2c2d 2e2f 3031 3233 3435 +3637 + +[out,icmp0] +6000 0000 0040 3aff 0010 0010 0010 0000 0000 0000 0000 0001 0002 0000 0000 0000 0000 0002 0002 0002 +8100 762b 6220 0001 3f6f 6e80 000b +0d02 0809 0a0b 0c0d 0e0f 1011 1213 1415 +1617 1819 1a1b 1c1d 1e1f 2021 2223 2425 +2627 2829 2a2b 2c2d 2e2f 3031 3233 3435 +3637 + diff --git a/contrib/ipfilter/test/input/ni1 b/contrib/ipfilter/test/input/ni1 index fb6b0b63e5f9..519325fc56b4 100644 --- a/contrib/ipfilter/test/input/ni1 +++ b/contrib/ipfilter/test/input/ni1 @@ -1,55 +1,58 @@ #v tos len id off ttl p sum src dst # ICMP timeout exceeded in reply to a ICMP packet going out. +# 2.2.2.2,44489 -> 4.4.4.4,33438 [out,df0] -4500 0028 4706 4000 0111 26b4 0202 0202 -0404 0404 afc9 829e 0014 6b10 0402 0000 -3be5 468d 000a cfc3 +4500 0028 4706 4000 0111 26b4 0202 0202 0404 0404 +afc9 829e 0014 6b10 +0402 0000 3be5 468d 000a cfc3 [in,df0] -4500 0038 809a 0000 ff01 2919 0303 0303 -0606 0606 0b00 5f7b 0000 0000 +4500 0038 809a 0000 ff01 2919 0303 0303 0606 0606 +0b00 5f7b 0000 0000 4500 0028 0000 4000 0111 65b2 0606 0606 0404 0404 afc9 829e 0014 6308 [in,df0] -4500 0044 809a 0000 ff01 290d 0303 0303 -0606 0606 0b00 0939 0000 0000 +4500 0044 809a 0000 ff01 290d 0303 0303 0606 0606 +0b00 0939 0000 0000 4500 0028 0000 4000 0111 65b2 0606 0606 0404 0404 afc9 829e 0014 6308 0402 0000 3be5 468d 000a cfc3 +# 2.2.2.2,2048 -> 4.4.4.4,33438 [out,df0] -4500 0028 4706 4000 0111 26b4 0202 0202 -0404 0404 0800 829e 0014 12da 0402 0000 -3be5 468d 000a cfc3 +4500 0028 4706 4000 0111 26b4 0202 0202 0404 0404 +0800 829e 0014 12da +0402 0000 3be5 468d 000a cfc3 [in,df0] -4500 0038 809a 0000 ff01 2918 0303 0303 -0606 0607 0b00 5f7c 0000 0000 +4500 0038 809a 0000 ff01 2918 0303 0303 0606 0607 +0b00 5f7c 0000 0000 4500 0028 0000 4000 0111 65b1 0606 0607 0404 0404 4e20 829e 0014 c4b0 [in,df0] -4500 0044 809a 0000 ff01 290c 0303 0303 -0606 0607 0b00 093a 0000 0000 +4500 0044 809a 0000 ff01 290c 0303 0303 0606 0607 +0b00 093a 0000 0000 4500 0028 0000 4000 0111 65b1 0606 0607 0404 0404 4e20 829e 0014 c4b0 0402 0000 3be5 468d 000a cfc3 +# 2.2.2.2,20480 -> 4.4.4.4,33438 [out,df0] -4500 0028 4706 4000 0111 26b4 0202 0202 -0404 0404 5000 829e 0014 cad9 0402 0000 -3be5 468d 000a cfc3 +4500 0028 4706 4000 0111 26b4 0202 0202 0404 0404 +5000 829e 0014 cad9 +0402 0000 3be5 468d 000a cfc3 [in,df0] -4500 0038 809a 0000 ff01 2917 0303 0303 -0606 0608 0b00 0775 0000 0000 +4500 0038 809a 0000 ff01 2917 0303 0303 0606 0608 +0b00 0775 0000 0000 4500 0028 0000 4000 0111 65b0 0606 0608 0404 0404 07d0 829e 0014 6308 [in,df0] -4500 0044 809a 0000 ff01 290b 0303 0303 -0606 0608 0b00 093b 0000 0000 +4500 0044 809a 0000 ff01 290b 0303 0303 0606 0608 +0b00 093b 0000 0000 4500 0028 0000 4000 0111 65b0 0606 0608 0404 0404 07d0 829e 0014 0b00 0402 0000 3be5 468d 000a cfc3 diff --git a/contrib/ipfilter/test/input/ni10 b/contrib/ipfilter/test/input/ni10 index 48ac22570283..636c4f1b2d6a 100644 --- a/contrib/ipfilter/test/input/ni10 +++ b/contrib/ipfilter/test/input/ni10 @@ -2,7 +2,9 @@ # ICMP dest unreachable with 64 bits in payload (in reply to a TCP packet # going out) # IP 4.4.4.4 2.2.2.2 TCP(20480,80) -[in,df0] 45 00 00 3c 47 06 40 00 ff 06 28 aa 04 04 04 04 02 02 02 02 50 00 00 50 00 00 00 01 00 00 00 00 a0 02 16 d0 d8 e2 00 00 02 04 05 b4 04 02 08 0a 00 47 fb b0 00 00 00 00 01 03 03 00 +[in,df0] +4500 003c 4706 4000 ff06 28aa 0404 0404 0202 0202 +5000 0050 0000 0001 0000 0000 a002 16d0 d8e2 0000 0204 05b4 0402 080a 0047 fbb0 0000 0000 0103 0300 # IP 3.3.3.3 -> 4.4.4.4 ICMP (IP(4.4.4.4,6.6.6.6) TCP(20480,80)) [out,df0] @@ -13,7 +15,11 @@ # IP 3.3.3.3 -> 4.4.4.4 ICMP (IP(4.4.4.4,6.6.6.6) TCP(20480,80)) # ICMP dest unreachable with whole packet in payload (40 bytes = 320 bits) -[out,df0] 45 00 00 58 80 9a 00 00 ff 01 2c fd 03 03 03 03 04 04 04 04 03 03 11 3f 00 00 00 00 45 00 00 3c 47 06 40 00 ff 06 20 a2 04 04 04 04 06 06 06 06 50 00 00 50 00 00 00 01 00 00 00 00 a0 02 16 d0 d0 da 00 00 02 04 05 b4 04 02 08 0a 00 47 fb b0 00 00 00 00 01 03 03 00 +[out,df0] +4500 0058 809a 0000 ff01 2cfd 0303 0303 0404 0404 +0303 113f 0000 0000 +4500 003c 4706 4000 ff06 20a2 0404 0404 0606 0606 +5000 0050 0000 0001 0000 0000 a002 16d0 d0da 0000 0204 05b4 0402 080a 0047 fbb0 0000 0000 0103 0300 # IP 3.3.3.3 -> 4.4.4.4 ICMP (IP(4.4.4.4,6.6.6.6) TCP(20480,80)) [out,df0] diff --git a/contrib/ipfilter/test/input/ni11 b/contrib/ipfilter/test/input/ni11 index 788e6036c407..0650abb70342 100644 --- a/contrib/ipfilter/test/input/ni11 +++ b/contrib/ipfilter/test/input/ni11 @@ -1,7 +1,9 @@ #v tos len id off ttl p sum src dst # ICMP dest unreachable with 64 bits in payload (in reply to a TCP packet # going out) -[in,df0] 45 00 00 3c 47 06 40 00 ff 06 20 aa 04 04 04 04 0a 02 02 02 50 00 05 00 00 00 00 01 00 00 00 00 a0 02 16 d0 cc 32 00 00 02 04 05 b4 04 02 08 0a 00 47 fb b0 00 00 00 00 01 03 03 00 +[in,df0] +4500 003c 4706 4000 ff06 20aa 0404 0404 0a02 0202 +5000 0500 0000 0001 0000 0000 a002 16d0 cc32 0000 0204 05b4 0402 080a 0047 fbb0 0000 0000 0103 0300 [out,df0] 4500 0038 809a 0000 ff01 2d1d 0303 0303 0404 0404 diff --git a/contrib/ipfilter/test/input/ni12 b/contrib/ipfilter/test/input/ni12 index 788e6036c407..c44aacce6da5 100644 --- a/contrib/ipfilter/test/input/ni12 +++ b/contrib/ipfilter/test/input/ni12 @@ -1,24 +1,26 @@ #v tos len id off ttl p sum src dst # ICMP dest unreachable with 64 bits in payload (in reply to a TCP packet # going out) -[in,df0] 45 00 00 3c 47 06 40 00 ff 06 20 aa 04 04 04 04 0a 02 02 02 50 00 05 00 00 00 00 01 00 00 00 00 a0 02 16 d0 cc 32 00 00 02 04 05 b4 04 02 08 0a 00 47 fb b0 00 00 00 00 01 03 03 00 +[in,df0] +4500 003c 4706 4000 ff06 20aa 0404 0404 0a02 0202 +5000 0500 0000 0001 0000 0000 a002 16d0 cc32 0000 0204 05b4 0402 080a 0047 fbb0 0000 0000 0103 0300 [out,df0] 4500 0038 809a 0000 ff01 2d1d 0303 0303 0404 0404 -0303 0fa3 0000 0000 +0303 10bb 0000 0000 4500 003c 4706 4000 ff06 2aac 0404 0404 0101 0101 -5000 9d58 0000 0001 +5000 9c40 0000 0001 # ICMP dest unreachable with whole packet in payload (40 bytes = 320 bits) [out,df0] 4500 0058 809a 0000 ff01 2cfd 0303 0303 0404 0404 0303 0735 0000 0000 4500 003c 4706 4000 ff06 2aac 0404 0404 0101 0101 -5000 9d58 0000 0001 0000 0000 a002 16d0 3ddc 0000 +5000 9c40 0000 0001 0000 0000 a002 16d0 3ef4 0000 0204 05b4 0402 080a 0047 fbb0 0000 0000 0103 0300 [out,df0] 4500 0038 809a 0000 ff01 2b1b 0303 0303 0505 0505 -0303 0fa3 0000 0000 -4500 003c 4706 4000 ff06 2aab 0404 0404 0101 0102 5000 9d58 0000 0001 +0303 10bb 0000 0000 +4500 003c 4706 4000 ff06 2aab 0404 0404 0101 0102 5000 9c40 0000 0001 diff --git a/contrib/ipfilter/test/input/ni13 b/contrib/ipfilter/test/input/ni13 index 77569eead702..70c19526ba90 100644 --- a/contrib/ipfilter/test/input/ni13 +++ b/contrib/ipfilter/test/input/ni13 @@ -1,19 +1,17 @@ # 23:18:36.130424 192.168.113.1.1511 > 192.168.113.3.1723: S 2884651685:2884651685(0) win 64240 (DF) [in,pcn1=192.168.113.3] -4500 0030 5e11 4000 8006 3961 c0a8 7101 -c0a8 7103 05e7 06bb abf0 4aa5 0000 0000 -7002 faf0 21a1 0000 0204 05b4 0101 0402 +4500 0030 5e11 4000 8006 3961 c0a8 7101 c0a8 7103 +05e7 06bb abf0 4aa5 0000 0000 7002 faf0 21a1 0000 0204 05b4 0101 0402 # 23:18:36.130778 192.168.113.3.1723 > 192.168.113.1.1511: S 2774821082:2774821082(0) ack 2884651686 win 32768 (DF) [out,pcn1] -4500 002c 69a6 4000 4006 6dd0 c0a8 7103 -c0a8 7101 06bb 05e7 a564 68da abf0 4aa6 -6012 8000 a348 0000 0204 05b4 +4500 002c 69a6 4000 4006 6dd0 c0a8 7103 c0a8 7101 +06bb 05e7 a564 68da abf0 4aa6 6012 8000 a348 0000 0204 05b4 # 23:18:36.130784 192.168.113.1.1511 > 192.168.113.3.1723: P 1:157(156) ack 1 win 64240: pptp CTRL_MSGTYPE=SCCRQ PROTO_VER(1.0) FRAME_CAP(A) BEARER_CAP(A) MAX_CHAN(0) FIRM_REV(2600) HOSTNAME() VENDOR(Microsoft Windows NT) (DF) [in,pcn1] -4500 00c4 5e12 4000 8006 38cc c0a8 7101 -c0a8 7103 05e7 06bb abf0 4aa6 a564 68db +4500 00c4 5e12 4000 8006 38cc c0a8 7101 c0a8 7103 +05e7 06bb abf0 4aa6 a564 68db 5018 faf0 e2a0 0000 009c 0001 1a2b 3c4d 0001 0000 0100 0000 0000 0001 0000 0001 0000 0a28 0000 0000 0000 0000 0000 0000 @@ -28,8 +26,8 @@ c0a8 7103 05e7 06bb abf0 4aa6 a564 68db # 23:18:36.260235 192.168.113.3.1723 > 192.168.113.1.1511: P 1:157(156) ack 157 win 33580: pptp CTRL_MSGTYPE=SCCRP PROTO_VER(1.0) RESULT_CODE(1) ERR_CODE(0) FRAME_CAP() BEARER_CAP() MAX_CHAN(1) FIRM_REV(1) HOSTNAME(local) VENDOR(linux) (DF) [out,pcn1] -4500 00c4 69a7 4000 4006 6d37 c0a8 7103 -c0a8 7101 06bb 05e7 a564 68db abf0 4b42 +4500 00c4 69a7 4000 4006 6d37 c0a8 7103 c0a8 7101 +06bb 05e7 a564 68db abf0 4b42 5018 832c cecf 0000 009c 0001 1a2b 3c4d 0002 0000 0100 0100 0000 0000 0000 0000 0001 0001 6c6f 6361 6c00 0000 0000 0000 @@ -44,8 +42,8 @@ c0a8 7101 06bb 05e7 a564 68db abf0 4b42 # 23:18:36.260252 192.168.113.1.1511 > 192.168.113.3.1723: P 157:325(168) ack 157 win 64084: pptp CTRL_MSGTYPE=OCRQ CALL_ID(16384) CALL_SER_NUM(4913) MIN_BPS(300) MAX_BPS(100000000) BEARER_TYPE(Any) FRAME_TYPE(E) RECV_WIN(64) PROC_DELAY(0) PHONE_NO_LEN(0) PHONE_NO() SUB_ADDR() (DF) [in,pcn1] -4500 00d0 5e13 4000 8006 38bf c0a8 7101 -c0a8 7103 05e7 06bb abf0 4b42 a564 6977 +4500 00d0 5e13 4000 8006 38bf c0a8 7101 c0a8 7103 +05e7 06bb abf0 4b42 a564 6977 5018 fa54 ac07 0000 00a8 0001 1a2b 3c4d 0007 0000 4000 1331 0000 012c 05f5 e100 0000 0003 0000 0003 0040 0000 0000 0000 @@ -60,176 +58,174 @@ c0a8 7103 05e7 06bb abf0 4b42 a564 6977 # 23:18:36.272856 192.168.113.3.1723 > 192.168.113.1.1511: P 157:189(32) ack 325 win 33580: pptp CTRL_MSGTYPE=OCRP CALL_ID(0) PEER_CALL_ID(16384) RESULT_CODE(1) ERR_CODE(0) CAUSE_CODE(0) CONN_SPEED(100000000) RECV_WIN(64) PROC_DELAY(0) PHY_CHAN_ID(0) (DF) [out,pcn1] -4500 0048 69a8 4000 4006 6db2 c0a8 7103 -c0a8 7101 06bb 05e7 a564 6977 abf0 4bea +4500 0048 69a8 4000 4006 6db2 c0a8 7103 c0a8 7101 +06bb 05e7 a564 6977 abf0 4bea 5018 832c 36fa 0000 0020 0001 1a2b 3c4d 0008 0000 0000 4000 0100 0000 05f5 e100 0040 0000 0000 0000 # 23:18:36.321819 192.168.113.1.1511 > 192.168.113.3.1723: P 325:349(24) ack 189 win 64052: pptp CTRL_MSGTYPE=SLI PEER_CALL_ID(0) SEND_ACCM(0xffffffff) RECV_ACCM(0xffffffff) (DF) [in,pcn1] -4500 0040 5e14 4000 8006 394e c0a8 7101 -c0a8 7103 05e7 06bb abf0 4bea a564 6997 +4500 0040 5e14 4000 8006 394e c0a8 7101 c0a8 7103 +05e7 06bb abf0 4bea a564 6997 5018 fa34 e810 0000 0018 0001 1a2b 3c4d 000f 0000 0000 0000 ffff ffff ffff ffff # 23:18:36.349759 192.168.113.1 > 192.168.113.3: gre [KSv1] ID:0000 S:0 ppp: LCP 25: Conf-Req(0), MRU=1400, Magic-Num=577f7c5b, PFC, ACFC, Call-Back CBCP [in,pcn1] -4500 0039 5e15 0000 802f 792b c0a8 7101 -c0a8 7103 3001 880b 0019 0000 0000 0000 +4500 0039 5e15 0000 802f 792b c0a8 7101 c0a8 7103 +3001 880b 0019 0000 0000 0000 ff03 c021 0100 0015 0104 0578 0506 577f 7c5b 0702 0802 0d03 06 # 23:18:36.389970 192.168.113.3 > 192.168.113.1: gre [KAv1] ID:4000 A:4294967295 [|gre] [out,pcn1] -4500 0020 69a9 0000 ff2f eeaf c0a8 7103 -c0a8 7101 2081 880b 0000 4000 ffff ffff +4500 0020 69a9 0000 ff2f eeaf c0a8 7103 c0a8 7101 +2081 880b 0000 4000 ffff ffff # 23:18:36.518426 192.168.113.3.1723 > 192.168.113.1.1511: . ack 349 win 33580 (DF) [out,pcn1] -4500 0028 69aa 4000 4006 6dd0 c0a8 7103 -c0a8 7101 06bb 05e7 a564 6997 abf0 4c02 -5010 832c b5c1 0000 +4500 0028 69aa 4000 4006 6dd0 c0a8 7103 c0a8 7101 +06bb 05e7 a564 6997 abf0 4c02 5010 832c b5c1 0000 # 23:18:36.555363 192.168.113.3 > 192.168.113.1: gre [KSv1] ID:4000 S:0 ppp: LCP 24: Conf-Req(1), ACCM=00000000, Magic-Num=22d90cfa, PFC, ACFC [out,pcn1] -4500 0038 69ab 0000 ff2f ee95 c0a8 7103 -c0a8 7101 3001 880b 0018 4000 0000 0000 +4500 0038 69ab 0000 ff2f ee95 c0a8 7103 c0a8 7101 +3001 880b 0018 4000 0000 0000 ff03 c021 0101 0014 0206 0000 0000 0506 22d9 0cfa 0702 0802 # 23:18:36.556030 192.168.113.3 > 192.168.113.1: gre [KSAv1] ID:4000 S:1 A:0 ppp: LCP 11: Conf-Rej(0), Call-Back CBCP [out,pcn1] -4500 002f 69ac 0000 ff2f ee9d c0a8 7103 -c0a8 7101 3081 880b 000b 4000 0000 0001 -0000 0000 ff03 c021 0400 0007 0d03 06 +4500 002f 69ac 0000 ff2f ee9d c0a8 7103 c0a8 7101 +3081 880b 000b 4000 0000 0001 0000 0000 ff03 c021 0400 0007 0d03 06 # 23:18:36.557166 192.168.113.1 > 192.168.113.3: gre [KSAv1] ID:0000 S:1 A:1 ppp: LCP 24: Conf-Ack(1), ACCM=00000000, Magic-Num=22d90cfa, PFC, ACFC [in,pcn1] -4500 003c 5e16 0000 802f 7927 c0a8 7101 -c0a8 7103 3081 880b 0018 0000 0000 0001 +4500 003c 5e16 0000 802f 7927 c0a8 7101 c0a8 7103 +3081 880b 0018 0000 0000 0001 0000 0001 ff03 c021 0201 0014 0206 0000 0000 0506 22d9 0cfa 0702 0802 # 23:18:36.557764 192.168.113.1 > 192.168.113.3: gre [KSv1] ID:0000 S:2 ppp: LCP 22: Conf-Req(1), MRU=1400, Magic-Num=577f7c5b, PFC, ACFC [in,pcn1] -4500 0036 5e17 0000 802f 792c c0a8 7101 -c0a8 7103 3001 880b 0016 0000 0000 0002 +4500 0036 5e17 0000 802f 792c c0a8 7101 c0a8 7103 +3001 880b 0016 0000 0000 0002 ff03 c021 0101 0012 0104 0578 0506 577f 7c5b 0702 0802 # 23:18:36.564658 192.168.113.3 > 192.168.113.1: gre [KSAv1] ID:4000 S:2 A:2 ppp: LCP 22: Conf-Ack(1), MRU=1400, Magic-Num=577f7c5b, PFC, ACFC [out,pcn1] -4500 003a 69ad 0000 ff2f ee91 c0a8 7103 -c0a8 7101 3081 880b 0016 4000 0000 0002 +4500 003a 69ad 0000 ff2f ee91 c0a8 7103 c0a8 7101 +3081 880b 0016 4000 0000 0002 0000 0002 ff03 c021 0201 0012 0104 0578 0506 577f 7c5b 0702 0802 # 23:18:36.564803 192.168.113.3 > 192.168.113.1: gre [KSv1] ID:4000 S:3 ppp: IPCP 18: Conf-Req(1), IP-Addr=192.168.0.1, IP-Comp VJ-Comp [out,pcn1] -4500 0032 69ae 0000 ff2f ee98 c0a8 7103 -c0a8 7101 3001 880b 0012 4000 0000 0003 +4500 0032 69ae 0000 ff2f ee98 c0a8 7103 c0a8 7101 +3001 880b 0012 4000 0000 0003 8021 0101 0010 0306 c0a8 0001 0206 002d 0f01 # 23:18:36.570395 192.168.113.1.1511 > 192.168.113.3.1723: P 349:373(24) ack 189 win 64052: pptp CTRL_MSGTYPE=SLI PEER_CALL_ID(0) SEND_ACCM(0x00000000) RECV_ACCM(0xffffffff) (DF) [in,pcn1] -4500 0040 5e18 4000 8006 394a c0a8 7101 -c0a8 7103 05e7 06bb abf0 4c02 a564 6997 +4500 0040 5e18 4000 8006 394a c0a8 7101 c0a8 7103 +05e7 06bb abf0 4c02 a564 6997 5018 fa34 e7f8 0000 0018 0001 1a2b 3c4d 000f 0000 0000 0000 0000 0000 ffff ffff # 23:18:36.573307 192.168.113.1 > 192.168.113.3: gre [KSAv1] ID:0000 S:3 A:3 ppp: LCP 20: Ident(2), Magic-Num=577f7c5b [in,pcn1] -4500 0038 5e19 0000 802f 7928 c0a8 7101 -c0a8 7103 3081 880b 0014 0000 0000 0003 +4500 0038 5e19 0000 802f 7928 c0a8 7101 c0a8 7103 +3081 880b 0014 0000 0000 0003 0000 0003 c021 0c02 0012 577f 7c5b 4d53 5241 5356 352e 3130 # 23:18:36.573856 192.168.113.3 > 192.168.113.1: gre [KSAv1] ID:4000 S:4 A:3 ppp: LCP 26: Code-Rej(2) [out,pcn1] -4500 003e 69af 0000 ff2f ee8b c0a8 7103 -c0a8 7101 3081 880b 001a 4000 0000 0004 +4500 003e 69af 0000 ff2f ee8b c0a8 7103 c0a8 7101 +3081 880b 001a 4000 0000 0004 0000 0003 ff03 c021 0702 0016 0c02 0012 577f 7c5b 4d53 5241 5356 352e 3130 # 23:18:36.584936 192.168.113.1 > 192.168.113.3: gre [KSAv1] ID:0000 S:4 A:4 ppp: LCP 26: Ident(3), Magic-Num=577f7c5b [in,pcn1] -4500 003e 5e1a 0000 802f 7921 c0a8 7101 -c0a8 7103 3081 880b 001a 0000 0000 0004 +4500 003e 5e1a 0000 802f 7921 c0a8 7101 c0a8 7103 +3081 880b 001a 0000 0000 0004 0000 0004 c021 0c03 0018 577f 7c5b 4d53 5241 532d 302d 434c 4159 4d4f 4f52 # 23:18:36.585562 192.168.113.3 > 192.168.113.1: gre [KSAv1] ID:4000 S:5 A:4 ppp: LCP 32: Code-Rej(3) [out,pcn1] -4500 0044 69b0 0000 ff2f ee84 c0a8 7103 -c0a8 7101 3081 880b 0020 4000 0000 0005 +4500 0044 69b0 0000 ff2f ee84 c0a8 7103 c0a8 7101 +3081 880b 0020 4000 0000 0005 0000 0004 ff03 c021 0703 001c 0c03 0018 577f 7c5b 4d53 5241 532d 302d 434c 4159 4d4f 4f52 # 23:18:36.588721 192.168.113.1 > 192.168.113.3: gre [KSAv1] ID:0000 S:5 A:5 ppp: CCP 12: Conf-Req(4), MPPC [in,pcn1] -4500 0030 5e1b 0000 802f 792e c0a8 7101 -c0a8 7103 3081 880b 000c 0000 0000 0005 +4500 0030 5e1b 0000 802f 792e c0a8 7101 c0a8 7103 +3081 880b 000c 0000 0000 0005 0000 0005 80fd 0104 000a 1206 0100 0001 # 23:18:36.589445 192.168.113.3 > 192.168.113.1: gre [KSAv1] ID:4000 S:6 A:5 ppp: CCP 6: Conf-Req(1) [out,pcn1] -4500 002a 69b1 0000 ff2f ee9d c0a8 7103 -c0a8 7101 3081 880b 0006 4000 0000 0006 +4500 002a 69b1 0000 ff2f ee9d c0a8 7103 c0a8 7101 +3081 880b 0006 4000 0000 0006 0000 0005 80fd 0101 0004 # 23:18:36.589540 192.168.113.3 > 192.168.113.1: gre [KSv1] ID:4000 S:7 ppp: CCP 12: Conf-Rej(4), MPPC [out,pcn1] -4500 002c 69b2 0000 ff2f ee9a c0a8 7103 -c0a8 7101 3001 880b 000c 4000 0000 0007 +4500 002c 69b2 0000 ff2f ee9a c0a8 7103 c0a8 7101 +3001 880b 000c 4000 0000 0007 80fd 0404 000a 1206 0100 0001 # 23:18:36.590023 192.168.113.1 > 192.168.113.3: gre [KSAv1] ID:0000 S:6 A:7 ppp: IPCP 36: Conf-Req(5), IP-Addr=0.0.0.0, Pri-DNS=0.0.0.0, Pri-NBNS=0.0.0.0, Sec-DNS=0.0.0.0, Sec-NBNS=0.0.0.0 [in,pcn1] -4500 0048 5e1c 0000 802f 7915 c0a8 7101 -c0a8 7103 3081 880b 0024 0000 0000 0006 +4500 0048 5e1c 0000 802f 7915 c0a8 7101 c0a8 7103 +3081 880b 0024 0000 0000 0006 0000 0007 8021 0105 0022 0306 0000 0000 8106 0000 0000 8206 0000 0000 8306 0000 0000 8406 0000 0000 # 23:18:36.590489 192.168.113.3 > 192.168.113.1: gre [KSAv1] ID:4000 S:8 A:6 ppp: IPCP 30: Conf-Rej(5), Pri-DNS=0.0.0.0, Pri-NBNS=0.0.0.0, Sec-DNS=0.0.0.0, Sec-NBNS=0.0.0.0 [out,pcn1] -4500 0042 69b3 0000 ff2f ee83 c0a8 7103 -c0a8 7101 3081 880b 001e 4000 0000 0008 +4500 0042 69b3 0000 ff2f ee83 c0a8 7103 c0a8 7101 +3081 880b 001e 4000 0000 0008 0000 0006 8021 0405 001c 8106 0000 0000 8206 0000 0000 8306 0000 0000 8406 0000 0000 # 23:18:36.591003 192.168.113.1 > 192.168.113.3: gre [KSAv1] ID:0000 S:7 A:8 ppp: IPCP 12: Conf-Rej(1), IP-Comp VJ-Comp [in,pcn1] -4500 0030 5e1d 0000 802f 792c c0a8 7101 -c0a8 7103 3081 880b 000c 0000 0000 0007 +4500 0030 5e1d 0000 802f 792c c0a8 7101 c0a8 7103 +3081 880b 000c 0000 0000 0007 0000 0008 8021 0401 000a 0206 002d 0f01 # 23:18:36.593819 192.168.113.3 > 192.168.113.1: gre [KSAv1] ID:4000 S:9 A:7 ppp: IPCP 12: Conf-Req(2), IP-Addr=192.168.0.1 [out,pcn1] -4500 0030 69b4 0000 ff2f ee94 c0a8 7103 -c0a8 7101 3081 880b 000c 4000 0000 0009 +4500 0030 69b4 0000 ff2f ee94 c0a8 7103 c0a8 7101 +3081 880b 000c 4000 0000 0009 0000 0007 8021 0102 000a 0306 c0a8 0001 # 23:18:36.594840 192.168.113.1 > 192.168.113.3: gre [KSAv1] ID:0000 S:8 A:9 ppp: CCP 6: Conf-Ack(1) [in,pcn1] -4500 002a 5e1e 0000 802f 7931 c0a8 7101 -c0a8 7103 3081 880b 0006 0000 0000 0008 -0000 0009 80fd 0201 0004 0000 0000 +4500 002a 5e1e 0000 802f 7931 c0a8 7101 c0a8 7103 +3081 880b 0006 0000 0000 0008 +0000 0009 80fd 0201 0004 # 23:18:36.595525 192.168.113.1 > 192.168.113.3: gre [KSv1] ID:0000 S:9 ppp: CCP 18: Term-Req(6) [in,pcn1] -4500 0032 5e1f 0000 802f 7928 c0a8 7101 -c0a8 7103 3001 880b 0012 0000 0000 0009 +4500 0032 5e1f 0000 802f 7928 c0a8 7101 c0a8 7103 +3001 880b 0012 0000 0000 0009 80fd 0506 0010 577f 7c5b 003c cd74 0000 02dc # 23:18:36.595937 192.168.113.3 > 192.168.113.1: gre [KSAv1] ID:4000 S:10 A:9 ppp: CCP 6: Term-Ack(6) [out,pcn1] -4500 002a 69b5 0000 ff2f ee99 c0a8 7103 -c0a8 7101 3081 880b 0006 4000 0000 000a +4500 002a 69b5 0000 ff2f ee99 c0a8 7103 c0a8 7101 +3081 880b 0006 4000 0000 000a 0000 0009 80fd 0606 0004 diff --git a/contrib/ipfilter/test/input/ni14 b/contrib/ipfilter/test/input/ni14 index 681132120e23..6bc127610f2b 100644 --- a/contrib/ipfilter/test/input/ni14 +++ b/contrib/ipfilter/test/input/ni14 @@ -1,19 +1,19 @@ # 23:18:36.130424 192.168.113.1.1511 > 192.168.113.3.1723: S 2884651685:2884651685(0) win 64240 (DF) [in,pcn1=192.168.113.3] -4500 0030 5e11 4000 8006 3961 c0a8 7101 -c0a8 7103 05e7 06bb abf0 4aa5 0000 0000 +4500 0030 5e11 4000 8006 3961 c0a8 7101 c0a8 7103 +05e7 06bb abf0 4aa5 0000 0000 7002 faf0 21a1 0000 0204 05b4 0101 0402 # 23:18:36.130778 192.168.113.3.1723 > 192.168.113.1.1511: S 2774821082:2774821082(0) ack 2884651686 win 32768 (DF) [out,pcn1] -4500 002c 69a6 4000 4006 207b 7f00 0001 -c0a8 7101 06bb 05e7 a564 68da abf0 4aa6 +4500 002c 69a6 4000 4006 207b 7f00 0001 c0a8 7101 +06bb 05e7 a564 68da abf0 4aa6 6012 8000 55f3 0000 0204 05b4 # 23:18:36.130784 192.168.113.1.1511 > 192.168.113.3.1723: P 1:157(156) ack 1 win 64240: pptp CTRL_MSGTYPE=SCCRQ PROTO_VER(1.0) FRAME_CAP(A) BEARER_CAP(A) MAX_CHAN(0) FIRM_REV(2600) HOSTNAME() VENDOR(Microsoft Windows NT) (DF) [in,pcn1] -4500 00c4 5e12 4000 8006 38cc c0a8 7101 -c0a8 7103 05e7 06bb abf0 4aa6 a564 68db +4500 00c4 5e12 4000 8006 38cc c0a8 7101 c0a8 7103 +05e7 06bb abf0 4aa6 a564 68db 5018 faf0 e2a0 0000 009c 0001 1a2b 3c4d 0001 0000 0100 0000 0000 0001 0000 0001 0000 0a28 0000 0000 0000 0000 0000 0000 @@ -28,8 +28,8 @@ c0a8 7103 05e7 06bb abf0 4aa6 a564 68db # 23:18:36.260235 192.168.113.3.1723 > 192.168.113.1.1511: P 1:157(156) ack 157 win 33580: pptp CTRL_MSGTYPE=SCCRP PROTO_VER(1.0) RESULT_CODE(1) ERR_CODE(0) FRAME_CAP() BEARER_CAP() MAX_CHAN(1) FIRM_REV(1) HOSTNAME(local) VENDOR(linux) (DF) [out,pcn1] -4500 00c4 69a7 4000 4006 1fe2 7f00 0001 -c0a8 7101 06bb 05e7 a564 68db abf0 4b42 +4500 00c4 69a7 4000 4006 1fe2 7f00 0001 c0a8 7101 +06bb 05e7 a564 68db abf0 4b42 5018 832c 817a 0000 009c 0001 1a2b 3c4d 0002 0000 0100 0100 0000 0000 0000 0000 0001 0001 6c6f 6361 6c00 0000 0000 0000 @@ -44,8 +44,8 @@ c0a8 7101 06bb 05e7 a564 68db abf0 4b42 # 23:18:36.260252 192.168.113.1.1511 > 192.168.113.3.1723: P 157:325(168) ack 157 win 64084: pptp CTRL_MSGTYPE=OCRQ CALL_ID(16384) CALL_SER_NUM(4913) MIN_BPS(300) MAX_BPS(100000000) BEARER_TYPE(Any) FRAME_TYPE(E) RECV_WIN(64) PROC_DELAY(0) PHONE_NO_LEN(0) PHONE_NO() SUB_ADDR() (DF) [in,pcn1] -4500 00d0 5e13 4000 8006 38bf c0a8 7101 -c0a8 7103 05e7 06bb abf0 4b42 a564 6977 +4500 00d0 5e13 4000 8006 38bf c0a8 7101 c0a8 7103 +05e7 06bb abf0 4b42 a564 6977 5018 fa54 ac07 0000 00a8 0001 1a2b 3c4d 0007 0000 4000 1331 0000 012c 05f5 e100 0000 0003 0000 0003 0040 0000 0000 0000 @@ -60,176 +60,176 @@ c0a8 7103 05e7 06bb abf0 4b42 a564 6977 # 23:18:36.272856 192.168.113.3.1723 > 192.168.113.1.1511: P 157:189(32) ack 325 win 33580: pptp CTRL_MSGTYPE=OCRP CALL_ID(0) PEER_CALL_ID(16384) RESULT_CODE(1) ERR_CODE(0) CAUSE_CODE(0) CONN_SPEED(100000000) RECV_WIN(64) PROC_DELAY(0) PHY_CHAN_ID(0) (DF) [out,pcn1] -4500 0048 69a8 4000 4006 205d 7f00 0001 -c0a8 7101 06bb 05e7 a564 6977 abf0 4bea +4500 0048 69a8 4000 4006 205d 7f00 0001 c0a8 7101 +06bb 05e7 a564 6977 abf0 4bea 5018 832c e9a4 0000 0020 0001 1a2b 3c4d 0008 0000 0000 4000 0100 0000 05f5 e100 0040 0000 0000 0000 # 23:18:36.321819 192.168.113.1.1511 > 192.168.113.3.1723: P 325:349(24) ack 189 win 64052: pptp CTRL_MSGTYPE=SLI PEER_CALL_ID(0) SEND_ACCM(0xffffffff) RECV_ACCM(0xffffffff) (DF) [in,pcn1] -4500 0040 5e14 4000 8006 394e c0a8 7101 -c0a8 7103 05e7 06bb abf0 4bea a564 6997 +4500 0040 5e14 4000 8006 394e c0a8 7101 c0a8 7103 +05e7 06bb abf0 4bea a564 6997 5018 fa34 e810 0000 0018 0001 1a2b 3c4d 000f 0000 0000 0000 ffff ffff ffff ffff # 23:18:36.349759 192.168.113.1 > 192.168.113.3: gre [KSv1] ID:0000 S:0 ppp: LCP 25: Conf-Req(0), MRU=1400, Magic-Num=577f7c5b, PFC, ACFC, Call-Back CBCP [in,pcn1] -4500 0039 5e15 0000 802f 792b c0a8 7101 -c0a8 7103 3001 880b 0019 0000 0000 0000 +4500 0039 5e15 0000 802f 792b c0a8 7101 c0a8 7103 +3001 880b 0019 0000 0000 0000 ff03 c021 0100 0015 0104 0578 0506 577f 7c5b 0702 0802 0d03 06 # 23:18:36.389970 192.168.113.3 > 192.168.113.1: gre [KAv1] ID:4000 A:4294967295 [|gre] [out,pcn1] -4500 0020 69a9 0000 ff2f a15a 7f00 0001 -c0a8 7101 2081 880b 0000 4000 ffff ffff +4500 0020 69a9 0000 ff2f a15a 7f00 0001 c0a8 7101 +2081 880b 0000 4000 ffff ffff # 23:18:36.518426 192.168.113.3.1723 > 192.168.113.1.1511: . ack 349 win 33580 (DF) [out,pcn1] -4500 0028 69aa 4000 4006 207b 7f00 0001 -c0a8 7101 06bb 05e7 a564 6997 abf0 4c02 +4500 0028 69aa 4000 4006 207b 7f00 0001 c0a8 7101 +06bb 05e7 a564 6997 abf0 4c02 5010 832c 686c 0000 # 23:18:36.555363 192.168.113.3 > 192.168.113.1: gre [KSv1] ID:4000 S:0 ppp: LCP 24: Conf-Req(1), ACCM=00000000, Magic-Num=22d90cfa, PFC, ACFC [out,pcn1] -4500 0038 69ab 0000 ff2f a140 7f00 0001 -c0a8 7101 3001 880b 0018 4000 0000 0000 +4500 0038 69ab 0000 ff2f a140 7f00 0001 c0a8 7101 +3001 880b 0018 4000 0000 0000 ff03 c021 0101 0014 0206 0000 0000 0506 22d9 0cfa 0702 0802 # 23:18:36.556030 192.168.113.3 > 192.168.113.1: gre [KSAv1] ID:4000 S:1 A:0 ppp: LCP 11: Conf-Rej(0), Call-Back CBCP [out,pcn1] -4500 002f 69ac 0000 ff2f a148 7f00 0001 -c0a8 7101 3081 880b 000b 4000 0000 0001 +4500 002f 69ac 0000 ff2f a148 7f00 0001 c0a8 7101 +3081 880b 000b 4000 0000 0001 0000 0000 ff03 c021 0400 0007 0d03 06 # 23:18:36.557166 192.168.113.1 > 192.168.113.3: gre [KSAv1] ID:0000 S:1 A:1 ppp: LCP 24: Conf-Ack(1), ACCM=00000000, Magic-Num=22d90cfa, PFC, ACFC [in,pcn1] -4500 003c 5e16 0000 802f 7927 c0a8 7101 -c0a8 7103 3081 880b 0018 0000 0000 0001 +4500 003c 5e16 0000 802f 7927 c0a8 7101 c0a8 7103 +3081 880b 0018 0000 0000 0001 0000 0001 ff03 c021 0201 0014 0206 0000 0000 0506 22d9 0cfa 0702 0802 # 23:18:36.557764 192.168.113.1 > 192.168.113.3: gre [KSv1] ID:0000 S:2 ppp: LCP 22: Conf-Req(1), MRU=1400, Magic-Num=577f7c5b, PFC, ACFC [in,pcn1] -4500 0036 5e17 0000 802f 792c c0a8 7101 -c0a8 7103 3001 880b 0016 0000 0000 0002 +4500 0036 5e17 0000 802f 792c c0a8 7101 c0a8 7103 +3001 880b 0016 0000 0000 0002 ff03 c021 0101 0012 0104 0578 0506 577f 7c5b 0702 0802 # 23:18:36.564658 192.168.113.3 > 192.168.113.1: gre [KSAv1] ID:4000 S:2 A:2 ppp: LCP 22: Conf-Ack(1), MRU=1400, Magic-Num=577f7c5b, PFC, ACFC [out,pcn1] -4500 003a 69ad 0000 ff2f a13c 7f00 0001 -c0a8 7101 3081 880b 0016 4000 0000 0002 +4500 003a 69ad 0000 ff2f a13c 7f00 0001 c0a8 7101 +3081 880b 0016 4000 0000 0002 0000 0002 ff03 c021 0201 0012 0104 0578 0506 577f 7c5b 0702 0802 # 23:18:36.564803 192.168.113.3 > 192.168.113.1: gre [KSv1] ID:4000 S:3 ppp: IPCP 18: Conf-Req(1), IP-Addr=192.168.0.1, IP-Comp VJ-Comp [out,pcn1] -4500 0032 69ae 0000 ff2f a143 7f00 0001 -c0a8 7101 3001 880b 0012 4000 0000 0003 +4500 0032 69ae 0000 ff2f a143 7f00 0001 c0a8 7101 +3001 880b 0012 4000 0000 0003 8021 0101 0010 0306 c0a8 0001 0206 002d 0f01 # 23:18:36.570395 192.168.113.1.1511 > 192.168.113.3.1723: P 349:373(24) ack 189 win 64052: pptp CTRL_MSGTYPE=SLI PEER_CALL_ID(0) SEND_ACCM(0x00000000) RECV_ACCM(0xffffffff) (DF) [in,pcn1] -4500 0040 5e18 4000 8006 394a c0a8 7101 -c0a8 7103 05e7 06bb abf0 4c02 a564 6997 +4500 0040 5e18 4000 8006 394a c0a8 7101 c0a8 7103 +05e7 06bb abf0 4c02 a564 6997 5018 fa34 e7f8 0000 0018 0001 1a2b 3c4d 000f 0000 0000 0000 0000 0000 ffff ffff # 23:18:36.573307 192.168.113.1 > 192.168.113.3: gre [KSAv1] ID:0000 S:3 A:3 ppp: LCP 20: Ident(2), Magic-Num=577f7c5b [in,pcn1] -4500 0038 5e19 0000 802f 7928 c0a8 7101 -c0a8 7103 3081 880b 0014 0000 0000 0003 +4500 0038 5e19 0000 802f 7928 c0a8 7101 c0a8 7103 +3081 880b 0014 0000 0000 0003 0000 0003 c021 0c02 0012 577f 7c5b 4d53 5241 5356 352e 3130 # 23:18:36.573856 192.168.113.3 > 192.168.113.1: gre [KSAv1] ID:4000 S:4 A:3 ppp: LCP 26: Code-Rej(2) [out,pcn1] -4500 003e 69af 0000 ff2f a136 7f00 0001 -c0a8 7101 3081 880b 001a 4000 0000 0004 +4500 003e 69af 0000 ff2f a136 7f00 0001 c0a8 7101 +3081 880b 001a 4000 0000 0004 0000 0003 ff03 c021 0702 0016 0c02 0012 577f 7c5b 4d53 5241 5356 352e 3130 # 23:18:36.584936 192.168.113.1 > 192.168.113.3: gre [KSAv1] ID:0000 S:4 A:4 ppp: LCP 26: Ident(3), Magic-Num=577f7c5b [in,pcn1] -4500 003e 5e1a 0000 802f 7921 c0a8 7101 -c0a8 7103 3081 880b 001a 0000 0000 0004 +4500 003e 5e1a 0000 802f 7921 c0a8 7101 c0a8 7103 +3081 880b 001a 0000 0000 0004 0000 0004 c021 0c03 0018 577f 7c5b 4d53 5241 532d 302d 434c 4159 4d4f 4f52 # 23:18:36.585562 192.168.113.3 > 192.168.113.1: gre [KSAv1] ID:4000 S:5 A:4 ppp: LCP 32: Code-Rej(3) [out,pcn1] -4500 0044 69b0 0000 ff2f a12f 7f00 0001 -c0a8 7101 3081 880b 0020 4000 0000 0005 +4500 0044 69b0 0000 ff2f a12f 7f00 0001 c0a8 7101 +3081 880b 0020 4000 0000 0005 0000 0004 ff03 c021 0703 001c 0c03 0018 577f 7c5b 4d53 5241 532d 302d 434c 4159 4d4f 4f52 # 23:18:36.588721 192.168.113.1 > 192.168.113.3: gre [KSAv1] ID:0000 S:5 A:5 ppp: CCP 12: Conf-Req(4), MPPC [in,pcn1] -4500 0030 5e1b 0000 802f 792e c0a8 7101 -c0a8 7103 3081 880b 000c 0000 0000 0005 +4500 0030 5e1b 0000 802f 792e c0a8 7101 c0a8 7103 +3081 880b 000c 0000 0000 0005 0000 0005 80fd 0104 000a 1206 0100 0001 # 23:18:36.589445 192.168.113.3 > 192.168.113.1: gre [KSAv1] ID:4000 S:6 A:5 ppp: CCP 6: Conf-Req(1) [out,pcn1] -4500 002a 69b1 0000 ff2f a148 7f00 0001 -c0a8 7101 3081 880b 0006 4000 0000 0006 +4500 002a 69b1 0000 ff2f a148 7f00 0001 c0a8 7101 +3081 880b 0006 4000 0000 0006 0000 0005 80fd 0101 0004 # 23:18:36.589540 192.168.113.3 > 192.168.113.1: gre [KSv1] ID:4000 S:7 ppp: CCP 12: Conf-Rej(4), MPPC [out,pcn1] -4500 002c 69b2 0000 ff2f a145 7f00 0001 -c0a8 7101 3001 880b 000c 4000 0000 0007 +4500 002c 69b2 0000 ff2f a145 7f00 0001 c0a8 7101 +3001 880b 000c 4000 0000 0007 80fd 0404 000a 1206 0100 0001 # 23:18:36.590023 192.168.113.1 > 192.168.113.3: gre [KSAv1] ID:0000 S:6 A:7 ppp: IPCP 36: Conf-Req(5), IP-Addr=0.0.0.0, Pri-DNS=0.0.0.0, Pri-NBNS=0.0.0.0, Sec-DNS=0.0.0.0, Sec-NBNS=0.0.0.0 [in,pcn1] -4500 0048 5e1c 0000 802f 7915 c0a8 7101 -c0a8 7103 3081 880b 0024 0000 0000 0006 +4500 0048 5e1c 0000 802f 7915 c0a8 7101 c0a8 7103 +3081 880b 0024 0000 0000 0006 0000 0007 8021 0105 0022 0306 0000 0000 8106 0000 0000 8206 0000 0000 8306 0000 0000 8406 0000 0000 # 23:18:36.590489 192.168.113.3 > 192.168.113.1: gre [KSAv1] ID:4000 S:8 A:6 ppp: IPCP 30: Conf-Rej(5), Pri-DNS=0.0.0.0, Pri-NBNS=0.0.0.0, Sec-DNS=0.0.0.0, Sec-NBNS=0.0.0.0 [out,pcn1] -4500 0042 69b3 0000 ff2f a12e 7f00 0001 -c0a8 7101 3081 880b 001e 4000 0000 0008 +4500 0042 69b3 0000 ff2f a12e 7f00 0001 c0a8 7101 +3081 880b 001e 4000 0000 0008 0000 0006 8021 0405 001c 8106 0000 0000 8206 0000 0000 8306 0000 0000 8406 0000 0000 # 23:18:36.591003 192.168.113.1 > 192.168.113.3: gre [KSAv1] ID:0000 S:7 A:8 ppp: IPCP 12: Conf-Rej(1), IP-Comp VJ-Comp [in,pcn1] -4500 0030 5e1d 0000 802f 792c c0a8 7101 -c0a8 7103 3081 880b 000c 0000 0000 0007 +4500 0030 5e1d 0000 802f 792c c0a8 7101 c0a8 7103 +3081 880b 000c 0000 0000 0007 0000 0008 8021 0401 000a 0206 002d 0f01 # 23:18:36.593819 192.168.113.3 > 192.168.113.1: gre [KSAv1] ID:4000 S:9 A:7 ppp: IPCP 12: Conf-Req(2), IP-Addr=192.168.0.1 [out,pcn1] -4500 0030 69b4 0000 ff2f a13f 7f00 0001 -c0a8 7101 3081 880b 000c 4000 0000 0009 +4500 0030 69b4 0000 ff2f a13f 7f00 0001 c0a8 7101 +3081 880b 000c 4000 0000 0009 0000 0007 8021 0102 000a 0306 c0a8 0001 # 23:18:36.594840 192.168.113.1 > 192.168.113.3: gre [KSAv1] ID:0000 S:8 A:9 ppp: CCP 6: Conf-Ack(1) [in,pcn1] -4500 002a 5e1e 0000 802f 7931 c0a8 7101 -c0a8 7103 3081 880b 0006 0000 0000 0008 -0000 0009 80fd 0201 0004 0000 0000 +4500 002a 5e1e 0000 802f 7931 c0a8 7101 c0a8 7103 +3081 880b 0006 0000 0000 0008 +0000 0009 80fd 0201 0004 # 23:18:36.595525 192.168.113.1 > 192.168.113.3: gre [KSv1] ID:0000 S:9 ppp: CCP 18: Term-Req(6) [in,pcn1] -4500 0032 5e1f 0000 802f 7928 c0a8 7101 -c0a8 7103 3001 880b 0012 0000 0000 0009 +4500 0032 5e1f 0000 802f 7928 c0a8 7101 c0a8 7103 +3001 880b 0012 0000 0000 0009 80fd 0506 0010 577f 7c5b 003c cd74 0000 02dc # 23:18:36.595937 192.168.113.3 > 192.168.113.1: gre [KSAv1] ID:4000 S:10 A:9 ppp: CCP 6: Term-Ack(6) [out,pcn1] -4500 002a 69b5 0000 ff2f a144 7f00 0001 -c0a8 7101 3081 880b 0006 4000 0000 000a +4500 002a 69b5 0000 ff2f a144 7f00 0001 c0a8 7101 +3081 880b 0006 4000 0000 000a 0000 0009 80fd 0606 0004 diff --git a/contrib/ipfilter/test/input/ni15 b/contrib/ipfilter/test/input/ni15 index fb445bb93c6f..7e7aabde1580 100644 --- a/contrib/ipfilter/test/input/ni15 +++ b/contrib/ipfilter/test/input/ni15 @@ -218,7 +218,7 @@ c0a8 7101 3081 880b 000c 4000 0000 0009 [out,pcn1] 4500 002a 5e1e 0000 802f 7931 c0a8 7101 c0a8 7103 3081 880b 0006 0000 0000 0008 -0000 0009 80fd 0201 0004 0000 0000 +0000 0009 80fd 0201 0004 # 23:18:36.595525 192.168.113.1 > 192.168.113.3: gre [KSv1] ID:0000 S:9 ppp: CCP 18: Term-Req(6) [out,pcn1] diff --git a/contrib/ipfilter/test/input/ni16 b/contrib/ipfilter/test/input/ni16 index 24bfcfc3835f..362b98d09c47 100644 --- a/contrib/ipfilter/test/input/ni16 +++ b/contrib/ipfilter/test/input/ni16 @@ -218,7 +218,7 @@ c0a8 7101 3081 880b 000c 4000 0000 0009 [out,pcn1] 4500 002a 5e1e 0000 802f 9ed7 0a02 0202 c0a8 7103 3081 880b 0006 0000 0000 0008 -0000 0009 80fd 0201 0004 0000 0000 +0000 0009 80fd 0201 0004 # 23:18:36.595525 192.168.113.1 > 192.168.113.3: gre [KSv1] ID:0000 S:9 ppp: CCP 18: Term-Req(6) [out,pcn1] diff --git a/contrib/ipfilter/test/input/ni18 b/contrib/ipfilter/test/input/ni18 new file mode 100644 index 000000000000..4e06f7908442 --- /dev/null +++ b/contrib/ipfilter/test/input/ni18 @@ -0,0 +1,4 @@ +in on hme0 tcp 2.2.2.2,3000 192.168.1.2,80 +in on hme0 tcp 2.2.2.2,3000 192.168.1.1,80 +out on hme1 tcp 10.1.2.2,5050 4.5.6.7,80; +out on hme1 tcp 10.1.1.2,5050 4.5.6.7,80; diff --git a/contrib/ipfilter/test/input/ni19 b/contrib/ipfilter/test/input/ni19 index d95e68afc7b1..3ea706fcbcd2 100644 --- a/contrib/ipfilter/test/input/ni19 +++ b/contrib/ipfilter/test/input/ni19 @@ -28,7 +28,7 @@ b002 8000 7d87 0000 0204 05b4 0103 0300 [in,bge0] 4500 0028 7ce5 4000 4006 a7e4 0a01 0104 0a01 0101 0202 03f1 915a a5c5 6523 90b8 -5010 05b4 612b 0000 0000 0000 0000 +5010 05b4 612b 0000 # 10.1.1.4.1023 > 10.1.1.1.1008: SYN win 5840 [in,bge0] @@ -61,7 +61,7 @@ b012 8000 1e85 0000 0204 05b4 0103 0300 [in,bge0] 4500 0028 7ce7 4000 4006 a7e2 0a01 0104 0a01 0101 0202 03f1 915a a5c5 6523 90c0 -5010 05b4 6123 0000 0000 0000 0000 +5010 05b4 6123 0000 # 192.168.113.3.1009 > 10.1.1.4.shell [out,bge0] @@ -76,13 +76,13 @@ b012 8000 1e85 0000 0204 05b4 0103 0300 [in,bge0] 4500 0028 7ce9 4000 4006 a7e0 0a01 0104 0a01 0101 0202 03f1 915a a5c5 6523 90eb -5010 05b4 60f8 0000 0000 0000 0000 +5010 05b4 60f8 0000 # 10.1.1.4.shell > 10.1.1.1.1009 [in,bge0] 4500 0029 7ceb 4000 4006 a7dd 0a01 0104 0a01 0101 0202 03f1 915a a5c5 6523 90eb -5018 05b4 60ef 0000 0000 0000 0000 +5018 05b4 60ef 0000 00 # 192.168.113.3.1009 > 10.1.1.4.shell [out,bge0] @@ -94,7 +94,7 @@ b012 8000 1e85 0000 0204 05b4 0103 0300 [in,bge0] 4500 002c 7ced 4000 4006 a7d8 0a01 0104 0a01 0101 0202 03f1 915a a5c6 6523 90eb -5018 05b4 8b71 0000 666f 6f0a 0000 +5018 05b4 8b71 0000 666f 6f0a # 10.1.1.4.1023 > 10.1.1.1.1008 [in,bge0] @@ -107,7 +107,7 @@ b012 8000 1e85 0000 0204 05b4 0103 0300 [in,bge0] 4500 0028 7cef 4000 4006 a7da 0a01 0104 0a01 0101 0202 03f1 915a a5ca 6523 90eb -5011 05b4 60f2 0000 0000 0000 0000 +5011 05b4 60f2 0000 # 10.1.1.4.1023 > 10.1.1.1.1008 [in,bge0] @@ -146,7 +146,7 @@ b012 8000 1e85 0000 0204 05b4 0103 0300 [in,bge0] 4500 0028 0004 4000 4006 24c6 0a01 0104 0a01 0101 0202 03f1 915a a5cb 6523 90ec -5010 05b4 60f1 0000 0000 0000 0000 +5010 05b4 60f1 0000 # 10.1.1.4.1023 > 10.1.1.1.1008 [in,bge0] diff --git a/contrib/ipfilter/test/input/ni2 b/contrib/ipfilter/test/input/ni2 index 30458212bb03..6dcedb7f0ffe 100644 --- a/contrib/ipfilter/test/input/ni2 +++ b/contrib/ipfilter/test/input/ni2 @@ -1,29 +1,21 @@ # Test of fragmentation required coming from the inside. [out,xl0] -4510 002c bd0d 4000 3e06 b1d1 -0a01 0201 -c0a8 0133 +4510 002c bd0d 4000 3e06 b1d1 0a01 0201 c0a8 0133 05f6 0077 a664 2485 0000 0000 6002 4000 b8f2 0000 0204 05b4 [in,xl0] -4500 002c ce83 4000 7e06 606b -c0a8 0133 -0a01 0201 +4500 002c ce83 4000 7e06 606b c0a8 0133 0a01 0201 0077 05f6 fbdf 1a21 a664 2486 -6012 2238 c0a8 0000 0204 05b4 0000 +6012 2238 c0a8 0000 0204 05b4 [out,xl0] -4510 0028 bd0e 4000 3e06 b1d4 -0a01 0201 -c0a8 0133 +4510 0028 bd0e 4000 3e06 b1d4 0a01 0201 c0a8 0133 05f6 0077 a664 2486 fbdf 1a22 5010 4470 b62d 0000 [in,xl0] -4500 005b cf83 4000 7e06 5f3c -c0a8 0133 -0a01 0201 +4500 005b cf83 4000 7e06 5f3c c0a8 0133 0a01 0201 0077 05f6 fbdf 1a22 a664 2486 5018 2238 ce2a 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 @@ -31,32 +23,24 @@ c0a8 0133 0000 0000 0000 0000 0000 0a [out,xl0] -4510 0028 bd18 4000 3e06 b1ca -0a01 0201 -c0a8 0133 +4510 0028 bd18 4000 3e06 b1ca 0a01 0201 c0a8 0133 05f6 0077 a664 2486 fbdf 1a55 5010 4470 b5fa 0000 [out,xl0] -4510 002e bd1e 4000 3e06 b1be -0a01 0201 -c0a8 0133 +4510 002e bd1e 4000 3e06 b1be 0a01 0201 c0a8 0133 05f6 0077 a664 2486 fbdf 1a55 5018 4470 a8e2 0000 0000 0000 0d0a [in,xl0] -4500 0048 e383 4000 7e06 4b4f -c0a8 0133 -0a01 0201 +4500 0048 e383 4000 7e06 4b4f c0a8 0133 0a01 0201 0077 05f6 fbdf 1a55 a664 248c 5018 2232 d80a 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 [in,xl0] -4500 05dc e483 4000 7e06 44bb -c0a8 0133 -0a01 0201 +4500 05dc e483 4000 7e06 44bb c0a8 0133 0a01 0201 0077 05f6 fbdf 1a75 a664 248c 5010 2232 9f2d 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 @@ -152,10 +136,8 @@ c0a8 0133 0000 0000 0000 0000 0000 0000 [out,xl0] -4500 0038 d71d 4000 4001 7d22 -c0a8 6401 -c0a8 0133 -0304 3435 0000 05a0 +4500 0038 d71d 4000 4001 7d22 c0a8 6401 c0a8 0133 +0304 da99 0000 05a0 4500 05dc e483 4000 7e06 44bb c0a8 0133 0a01 0201 -0077 05f6 fbdf 1a75 a664 +0077 05f6 fbdf 1a75 diff --git a/contrib/ipfilter/test/input/ni20 b/contrib/ipfilter/test/input/ni20 index 4c2b87e4de34..065ed27ba79a 100644 --- a/contrib/ipfilter/test/input/ni20 +++ b/contrib/ipfilter/test/input/ni20 @@ -28,7 +28,7 @@ c0a8 7103 0202 03f1 915a a5c4 6523 90b3 [out,bge0] 4500 0028 7ce5 4000 4006 5a92 c0a8 7104 c0a8 7103 0202 03f1 915a a5c5 6523 90b8 -5010 05b4 13d9 0000 0000 0000 0000 +5010 05b4 13d9 0000 # 192.168.113.4.1023 > 192.168.113.3.1008: SYN win 5840 [out,bge0] @@ -44,26 +44,26 @@ a002 16d0 9218 0000 0204 05b4 0402 080a b012 8000 1e85 0000 0204 05b4 0103 0300 0101 080a 0000 0000 0039 d924 0402 0101 -# 192.168.113.4.1023 > 192.168.113.3.1008 +# 192.168.113.4.1023 > 192.168.113.3.1008 ACK [out,bge0] 4500 0034 1188 4000 4006 c5e3 c0a8 7104 c0a8 7103 03ff 03f0 91d4 c8a3 66e5 b811 8010 05b4 b2f3 0000 0101 080a 0039 d925 0000 0000 -# 192.168.113.3.1009 > 10.1.1.4.shell +# 192.168.113.3.1009 > 10.1.1.4.shell PUSH+ACK [in,bge0] 4500 0030 e400 4000 4006 1a17 c0a8 7103 0a01 0104 03f1 0202 6523 90b8 915a a5c5 5018 832c 0eb6 0000 6461 7272 656e 7200 -# 192.168.113.4.shell > 192.168.113.3.1009 +# 192.168.113.4.shell > 192.168.113.3.1009 ACK [out,bge0] 4500 0028 7ce7 4000 4006 5a90 c0a8 7104 c0a8 7103 0202 03f1 915a a5c5 6523 90c0 -5010 05b4 13d1 0000 0000 0000 0000 +5010 05b4 13d1 0000 -# 192.168.113.3.1009 > 10.1.1.4.shell +# 192.168.113.3.1009 > 10.1.1.4.shell PUSH+ACK [in,bge0] 4500 0053 e401 4000 4006 19f3 c0a8 7103 0a01 0104 03f1 0202 6523 90c0 915a a5c5 @@ -72,83 +72,83 @@ c0a8 7103 0202 03f1 915a a5c5 6523 90c0 3e26 313b 2065 6368 6f20 6261 7220 3e26 3222 00 -# 192.168.113.4.shell > 192.168.113.3.1009 +# 192.168.113.4.shell > 192.168.113.3.1009 ACK [out,bge0] 4500 0028 7ce9 4000 4006 5a8e c0a8 7104 c0a8 7103 0202 03f1 915a a5c5 6523 90eb -5010 05b4 13a6 0000 0000 0000 0000 +5010 05b4 13a6 0000 -# 192.168.113.4.shell > 192.168.113.3.1009 +# 192.168.113.4.shell > 192.168.113.3.1009 PUSH+ACK [out,bge0] 4500 0029 7ceb 4000 4006 5a8b c0a8 7104 c0a8 7103 0202 03f1 915a a5c5 6523 90eb -5018 05b4 139d 0000 0000 0000 0000 +5018 05b4 139d 0000 00 -# 192.168.113.3.1009 > 10.1.1.4.shell +# 192.168.113.3.1009 > 10.1.1.4.shell ACK [in,bge0] 4500 0028 e403 4000 4006 1a1c c0a8 7103 0a01 0104 03f1 0202 6523 90eb 915a a5c6 5010 832c bcd4 0000 -# 192.168.113.4.shell > 192.168.113.3.1009 +# 192.168.113.4.shell > 192.168.113.3.1009 PUSH+ACK [out,bge0] 4500 002c 7ced 4000 4006 5a86 c0a8 7104 c0a8 7103 0202 03f1 915a a5c6 6523 90eb -5018 05b4 3e1f 0000 666f 6f0a 0000 +5018 05b4 3e1f 0000 666f 6f0a -# 192.168.113.4.1023 > 192.168.113.3.1008 +# 192.168.113.4.1023 > 192.168.113.3.1008 PUSH+ACK [out,bge0] 4500 0038 118a 4000 4006 c5dd c0a8 7104 c0a8 7103 03ff 03f0 91d4 c8a3 66e5 b811 8018 05b4 da34 0000 0101 080a 0039 dd6c 0000 0000 6261 720a -# 192.168.113.4.shell > 192.168.113.3.1009 +# 192.168.113.4.shell > 192.168.113.3.1009 FIN+ACK [out,bge0] 4500 0028 7cef 4000 4006 5a88 c0a8 7104 c0a8 7103 0202 03f1 915a a5ca 6523 90eb -5011 05b4 13a0 0000 0000 0000 0000 +5011 05b4 13a0 0000 -# 192.168.113.4.1023 > 192.168.113.3.1008 +# 192.168.113.4.1023 > 192.168.113.3.1008 FIN+ACK [out,bge0] 4500 0034 118c 4000 4006 c5df c0a8 7104 c0a8 7103 03ff 03f0 91d4 c8a7 66e5 b811 8011 05b4 aea6 0000 0101 080a 0039 dd6d 0000 0000 -# 192.168.113.3.1009 > 10.1.1.4.shell +# 192.168.113.3.1009 > 10.1.1.4.shell ACK [in,bge0] 4500 0028 e404 4000 4006 1a1b c0a8 7103 0a01 0104 03f1 0202 6523 90eb 915a a5cb 5010 8328 bcd3 0000 -# 192.168.113.3.1008 > 10.1.1.4.1023 +# 192.168.113.3.1008 > 10.1.1.4.1023 ACK [in,bge0] 4500 0034 e405 4000 4006 1a0e c0a8 7103 0a01 0104 03f0 03ff 66e5 b811 91d4 c8a8 8010 8328 57d7 0000 0101 080a 0000 0004 0039 dd6c -# 192.168.113.3.1009 > 10.1.1.4.shell +# 192.168.113.3.1009 > 10.1.1.4.shell FIN+ACK [in,bge0] 4500 0028 e40a 4000 4006 1a15 c0a8 7103 0a01 0104 03f1 0202 6523 90eb 915a a5cb 5011 832c bcce 0000 -# 192.168.113.3.1008 > 10.1.1.4.1023 +# 192.168.113.3.1008 > 10.1.1.4.1023 FIN+ACK [in,bge0] 4500 0034 e40b 4000 4006 1a08 c0a8 7103 0a01 0104 03f0 03ff 66e5 b811 91d4 c8a8 8011 832c 57d2 0000 0101 080a 0000 0004 0039 dd6c -# 192.168.113.4.shell > 192.168.113.3.1009 +# 192.168.113.4.shell > 192.168.113.3.1009 ACK [out,bge0] 4500 0028 0004 4000 4006 d773 c0a8 7104 c0a8 7103 0202 03f1 915a a5cb 6523 90ec -5010 05b4 139f 0000 0000 0000 0000 +5010 05b4 139f 0000 -# 192.168.113.4.1023 > 192.168.113.3.1008 +# 192.168.113.4.1023 > 192.168.113.3.1008 ACK [out,bge0] 4500 0034 118e 4000 4006 c5dd c0a8 7104 c0a8 7103 03ff 03f0 91d4 c8a8 66e5 b812 diff --git a/contrib/ipfilter/test/input/ni3 b/contrib/ipfilter/test/input/ni3 index 66b22a6d4293..e4d12fe1dee5 100644 --- a/contrib/ipfilter/test/input/ni3 +++ b/contrib/ipfilter/test/input/ni3 @@ -1,10 +1,20 @@ #v tos len id off ttl p sum src dst # ICMP dest unreachable with 64 bits in payload (in reply to a TCP packet # going out) -[out,df0] 45 00 00 3c 47 06 40 00 ff 06 28 aa 02 02 02 02 04 04 04 04 50 00 00 50 00 00 00 01 00 00 00 00 a0 02 16 d0 d8 e2 00 00 02 04 05 b4 04 02 08 0a 00 47 fb b0 00 00 00 00 01 03 03 00 +[out,df0] +4500 003c 4706 4000 ff06 28aa 0202 0202 0404 0404 +5000 0050 0000 0001 0000 0000 a002 16d0 d8e2 0000 0204 05b4 0402 080a 0047 fbb0 0000 0000 0103 0300 -[in,df0] 45 00 00 38 80 9a 00 00 ff 01 29 19 03 03 03 03 06 06 06 06 03 03 ac ab 00 00 00 00 45 00 00 3c 47 06 40 00 ff 06 20 a2 06 06 06 06 04 04 04 04 50 00 00 50 00 00 00 01 +[in,df0] +4500 0038 809a 0000 ff01 2919 0303 0303 0606 0606 +0303 acab 0000 0000 +4500 003c 4706 4000 ff06 20a2 0606 0606 0404 0404 +5000 0050 0000 0001 # ICMP dest unreachable with whole packet in payload (40 bytes = 320 bits) -[in,df0] 45 00 00 58 80 9a 00 00 ff 01 28 f9 03 03 03 03 06 06 06 06 03 03 11 3f 00 00 00 00 45 00 00 3c 47 06 40 00 ff 06 20 a2 06 06 06 06 04 04 04 04 50 00 00 50 00 00 00 01 00 00 00 00 a0 02 16 d0 d0 da 00 00 02 04 05 b4 04 02 08 0a 00 47 fb b0 00 00 00 00 01 03 03 00 +[in,df0] +4500 0058 809a 0000 ff01 28f9 0303 0303 0606 0606 +0303 113f 0000 0000 +4500 003c 4706 4000 ff06 20a2 0606 0606 0404 0404 +5000 0050 0000 0001 0000 0000 a002 16d0 d0da 0000 0204 05b4 0402 080a 0047 fbb0 0000 0000 0103 0300 diff --git a/contrib/ipfilter/test/input/ni4 b/contrib/ipfilter/test/input/ni4 index ad5575f95317..dac9f53b8e6a 100644 --- a/contrib/ipfilter/test/input/ni4 +++ b/contrib/ipfilter/test/input/ni4 @@ -1,10 +1,18 @@ #v tos len id off ttl p sum src dst # ICMP dest unreachable with 64 bits in payload (in reply to a TCP packet # going out) -[out,df0] 45 00 00 3c 47 06 40 00 ff 06 28 aa 02 02 02 02 04 04 04 04 50 00 00 50 00 00 00 01 00 00 00 00 a0 02 16 d0 d8 e2 00 00 02 04 05 b4 04 02 08 0a 00 47 fb b0 00 00 00 00 01 03 03 00 +[out,df0] +4500 003c 4706 4000 ff06 28aa 0202 0202 0404 0404 +5000 0050 0000 0001 0000 0000 a002 16d0 d8e2 0000 0204 05b4 0402 080a 0047 fbb0 0000 0000 0103 0300 -[in,df0] 45 00 00 38 80 9a 00 00 ff 01 29 19 03 03 03 03 06 06 06 06 03 03 60 6b 00 00 00 00 45 00 00 3c 47 06 40 00 ff 06 20 a2 06 06 06 06 04 04 04 04 9c 40 00 50 00 00 00 01 +[in,df0] +4500 0038 809a 0000 ff01 2919 0303 0303 0606 0606 +0303 606b 0000 0000 4500 003c 4706 4000 ff06 20a2 0606 0606 0404 0404 9c40 0050 0000 0001 # ICMP dest unreachable with whole packet in payload (40 bytes = 320 bits) -[in,df0] 45 00 00 58 80 9a 00 00 ff 01 28 f9 03 03 03 03 06 06 06 06 03 03 11 3f 00 00 00 00 45 00 00 3c 47 06 40 00 ff 06 20 a2 06 06 06 06 04 04 04 04 9c 40 00 50 00 00 00 01 00 00 00 00 a0 02 16 d0 84 9a 00 00 02 04 05 b4 04 02 08 0a 00 47 fb b0 00 00 00 00 01 03 03 00 +[in,df0] +4500 0058 809a 0000 ff01 28f9 0303 0303 0606 0606 +0303 113f 0000 0000 +4500 003c 4706 4000 ff06 20a2 0606 0606 0404 0404 +9c40 0050 0000 0001 0000 0000 a002 16d0 849a 0000 0204 05b4 0402 080a 0047 fbb0 0000 0000 0103 0300 diff --git a/contrib/ipfilter/test/input/ni5 b/contrib/ipfilter/test/input/ni5 index c45be54266ff..4b32e49d0913 100644 --- a/contrib/ipfilter/test/input/ni5 +++ b/contrib/ipfilter/test/input/ni5 @@ -203,7 +203,7 @@ 0101 0101 0014 8033 d9f8 11d5 bd78 5c13 5010 269c 8ac7 0000 -# 21,32819 ACK "150 Opening ASCII mode data connection for /bin/ls.\r\n" +# 21,32818 ACK "150 Opening ASCII mode data connection for /bin/ls.\r\n" [in,ppp0] 4500 005d ffe9 4000 ef06 12e1 96cb e002 0101 0101 0015 8032 3786 78d5 bd6b ca16 diff --git a/contrib/ipfilter/test/input/ni7 b/contrib/ipfilter/test/input/ni7 index 30f247d39ca9..8d07937c1266 100644 --- a/contrib/ipfilter/test/input/ni7 +++ b/contrib/ipfilter/test/input/ni7 @@ -1,13 +1,13 @@ #v tos len id off ttl p sum src dst # ICMP timeout exceeded in reply to a ICMP packet coming in. [in,df0] -4500 0028 4706 4000 0111 26b4 0404 0404 -0202 0202 afc9 829e 0014 6b10 0402 0000 +4500 0028 4706 4000 0111 26b4 0404 0404 0202 0202 +afc9 829e 0014 6b10 0402 0000 3be5 468d 000a cfc3 [out,df0] -4500 0038 809a 0000 ff01 2d1d 0303 0303 -0404 0404 0b00 0125 0000 0000 4500 0028 -4706 4000 0111 1eac 0404 0404 0606 0606 +4500 0038 809a 0000 ff01 2d1d 0303 0303 0404 0404 +0b00 0125 0000 0000 +4500 0028 4706 4000 0111 1eac 0404 0404 0606 0606 afc9 829e 0014 c15e diff --git a/contrib/ipfilter/test/input/ni8 b/contrib/ipfilter/test/input/ni8 index 788e6036c407..72205ee9a79e 100644 --- a/contrib/ipfilter/test/input/ni8 +++ b/contrib/ipfilter/test/input/ni8 @@ -1,7 +1,7 @@ #v tos len id off ttl p sum src dst -# ICMP dest unreachable with 64 bits in payload (in reply to a TCP packet -# going out) -[in,df0] 45 00 00 3c 47 06 40 00 ff 06 20 aa 04 04 04 04 0a 02 02 02 50 00 05 00 00 00 00 01 00 00 00 00 a0 02 16 d0 cc 32 00 00 02 04 05 b4 04 02 08 0a 00 47 fb b0 00 00 00 00 01 03 03 00 +[in,df0] +4500 003c 4706 4000 ff06 20aa 0404 0404 0a02 0202 +5000 0500 0000 0001 0000 0000 a002 16d0 cc32 0000 0204 05b4 0402 080a 0047 fbb0 0000 0000 0103 0300 [out,df0] 4500 0038 809a 0000 ff01 2d1d 0303 0303 0404 0404 @@ -17,8 +17,11 @@ 5000 9d58 0000 0001 0000 0000 a002 16d0 3ddc 0000 0204 05b4 0402 080a 0047 fbb0 0000 0000 0103 0300 +# ICMP dest unreachable with 64 bits in payload (in reply to a TCP packet +# going in) [out,df0] 4500 0038 809a 0000 ff01 2b1b 0303 0303 0505 0505 0303 0fa3 0000 0000 -4500 003c 4706 4000 ff06 2aab 0404 0404 0101 0102 5000 9d58 0000 0001 +4500 003c 4706 4000 ff06 2aab 0404 0404 0101 0102 +5000 9d58 0000 0001 diff --git a/contrib/ipfilter/test/input/ni9 b/contrib/ipfilter/test/input/ni9 index 788e6036c407..b8f45991f08d 100644 --- a/contrib/ipfilter/test/input/ni9 +++ b/contrib/ipfilter/test/input/ni9 @@ -1,7 +1,9 @@ #v tos len id off ttl p sum src dst # ICMP dest unreachable with 64 bits in payload (in reply to a TCP packet # going out) -[in,df0] 45 00 00 3c 47 06 40 00 ff 06 20 aa 04 04 04 04 0a 02 02 02 50 00 05 00 00 00 00 01 00 00 00 00 a0 02 16 d0 cc 32 00 00 02 04 05 b4 04 02 08 0a 00 47 fb b0 00 00 00 00 01 03 03 00 +[in,df0] +4500 003c 4706 4000 ff06 20aa 0404 0404 0a02 0202 +5000 0500 0000 0001 0000 0000 a002 16d0 cc32 0000 0204 05b4 0402 080a 0047 fbb0 0000 0000 0103 0300 [out,df0] 4500 0038 809a 0000 ff01 2d1d 0303 0303 0404 0404 @@ -20,5 +22,6 @@ [out,df0] 4500 0038 809a 0000 ff01 2b1b 0303 0303 0505 0505 0303 0fa3 0000 0000 -4500 003c 4706 4000 ff06 2aab 0404 0404 0101 0102 5000 9d58 0000 0001 +4500 003c 4706 4000 ff06 2aab 0404 0404 0101 0102 +5000 9d58 0000 0001 diff --git a/contrib/ipfilter/test/input/p10 b/contrib/ipfilter/test/input/p10 new file mode 100644 index 000000000000..f8162e807b04 --- /dev/null +++ b/contrib/ipfilter/test/input/p10 @@ -0,0 +1,10 @@ +in on bge0 tcp 5.5.5.5,10000 9.9.9.9,80 +in on bge0 tcp 5.5.5.6,10000 9.9.9.9,80 +in on bge0 tcp 5.5.5.7,10000 9.9.9.9,80 +in on bge0 tcp 5.5.5.8,10000 9.9.9.9,80 +in on bge0 tcp 5.5.5.9,10000 9.9.9.9,80 +in on bge0 tcp 5.5.6.5,10000 9.9.9.9,80 +in on bge0 tcp 5.5.6.6,10000 9.9.9.9,80 +in on bge0 tcp 5.5.6.7,10000 9.9.9.9,80 +in on bge0 tcp 5.5.6.8,10000 9.9.9.9,80 +in on bge0 tcp 5.5.6.9,10000 9.9.9.9,80 diff --git a/contrib/ipfilter/test/input/p11 b/contrib/ipfilter/test/input/p11 new file mode 100644 index 000000000000..f8162e807b04 --- /dev/null +++ b/contrib/ipfilter/test/input/p11 @@ -0,0 +1,10 @@ +in on bge0 tcp 5.5.5.5,10000 9.9.9.9,80 +in on bge0 tcp 5.5.5.6,10000 9.9.9.9,80 +in on bge0 tcp 5.5.5.7,10000 9.9.9.9,80 +in on bge0 tcp 5.5.5.8,10000 9.9.9.9,80 +in on bge0 tcp 5.5.5.9,10000 9.9.9.9,80 +in on bge0 tcp 5.5.6.5,10000 9.9.9.9,80 +in on bge0 tcp 5.5.6.6,10000 9.9.9.9,80 +in on bge0 tcp 5.5.6.7,10000 9.9.9.9,80 +in on bge0 tcp 5.5.6.8,10000 9.9.9.9,80 +in on bge0 tcp 5.5.6.9,10000 9.9.9.9,80 diff --git a/contrib/ipfilter/test/input/p12 b/contrib/ipfilter/test/input/p12 new file mode 100644 index 000000000000..f8162e807b04 --- /dev/null +++ b/contrib/ipfilter/test/input/p12 @@ -0,0 +1,10 @@ +in on bge0 tcp 5.5.5.5,10000 9.9.9.9,80 +in on bge0 tcp 5.5.5.6,10000 9.9.9.9,80 +in on bge0 tcp 5.5.5.7,10000 9.9.9.9,80 +in on bge0 tcp 5.5.5.8,10000 9.9.9.9,80 +in on bge0 tcp 5.5.5.9,10000 9.9.9.9,80 +in on bge0 tcp 5.5.6.5,10000 9.9.9.9,80 +in on bge0 tcp 5.5.6.6,10000 9.9.9.9,80 +in on bge0 tcp 5.5.6.7,10000 9.9.9.9,80 +in on bge0 tcp 5.5.6.8,10000 9.9.9.9,80 +in on bge0 tcp 5.5.6.9,10000 9.9.9.9,80 diff --git a/contrib/ipfilter/test/input/p13 b/contrib/ipfilter/test/input/p13 new file mode 100644 index 000000000000..f6753fac4264 --- /dev/null +++ b/contrib/ipfilter/test/input/p13 @@ -0,0 +1,8 @@ +in 127.0.0.1 127.0.0.1 +in 1.1.1.1 1.2.1.1 +out 127.0.0.1 127.0.0.1 +out 1.1.1.1 1.2.1.1 +in 2.3.0.1 1.2.1.1 +in 2.2.2.1 1.2.1.1 +in 2.2.0.1 1.2.1.1 +out 4.4.1.1 1.2.1.1 diff --git a/contrib/ipfilter/test/input/p4 b/contrib/ipfilter/test/input/p4 new file mode 100644 index 000000000000..46c0998cb4ed --- /dev/null +++ b/contrib/ipfilter/test/input/p4 @@ -0,0 +1,12 @@ +in 127.0.0.1 127.0.0.1 +in 1.1.1.1 1.2.1.1 +out 127.0.0.1 127.0.0.1 +out 1.1.1.1 1.2.1.1 +in 2.3.0.1 1.2.1.1 +in 2.2.2.1 1.2.1.1 +in 2.2.0.1 1.2.1.1 +out 2.2.2.1 1.2.1.1 +out 2.2.2.1 1.2.1.2 +out 2.2.0.1 1.2.1.1 +out 2.2.0.1 1.2.1.3 +out 4.4.1.1 1.2.1.1 diff --git a/contrib/ipfilter/test/input/p6 b/contrib/ipfilter/test/input/p6 new file mode 100644 index 000000000000..37c26ce3442f --- /dev/null +++ b/contrib/ipfilter/test/input/p6 @@ -0,0 +1,2 @@ +in 131.107.1.1 10.1.1.1 +out 10.1.1.1 131.107.1.1 diff --git a/contrib/ipfilter/test/input/p7 b/contrib/ipfilter/test/input/p7 new file mode 100644 index 000000000000..f8162e807b04 --- /dev/null +++ b/contrib/ipfilter/test/input/p7 @@ -0,0 +1,10 @@ +in on bge0 tcp 5.5.5.5,10000 9.9.9.9,80 +in on bge0 tcp 5.5.5.6,10000 9.9.9.9,80 +in on bge0 tcp 5.5.5.7,10000 9.9.9.9,80 +in on bge0 tcp 5.5.5.8,10000 9.9.9.9,80 +in on bge0 tcp 5.5.5.9,10000 9.9.9.9,80 +in on bge0 tcp 5.5.6.5,10000 9.9.9.9,80 +in on bge0 tcp 5.5.6.6,10000 9.9.9.9,80 +in on bge0 tcp 5.5.6.7,10000 9.9.9.9,80 +in on bge0 tcp 5.5.6.8,10000 9.9.9.9,80 +in on bge0 tcp 5.5.6.9,10000 9.9.9.9,80 diff --git a/contrib/ipfilter/test/input/p9 b/contrib/ipfilter/test/input/p9 new file mode 100644 index 000000000000..f8162e807b04 --- /dev/null +++ b/contrib/ipfilter/test/input/p9 @@ -0,0 +1,10 @@ +in on bge0 tcp 5.5.5.5,10000 9.9.9.9,80 +in on bge0 tcp 5.5.5.6,10000 9.9.9.9,80 +in on bge0 tcp 5.5.5.7,10000 9.9.9.9,80 +in on bge0 tcp 5.5.5.8,10000 9.9.9.9,80 +in on bge0 tcp 5.5.5.9,10000 9.9.9.9,80 +in on bge0 tcp 5.5.6.5,10000 9.9.9.9,80 +in on bge0 tcp 5.5.6.6,10000 9.9.9.9,80 +in on bge0 tcp 5.5.6.7,10000 9.9.9.9,80 +in on bge0 tcp 5.5.6.8,10000 9.9.9.9,80 +in on bge0 tcp 5.5.6.9,10000 9.9.9.9,80 diff --git a/contrib/ipfilter/test/intest b/contrib/ipfilter/test/intest index e94ca0894e57..bcafe76d0dcd 100755 --- a/contrib/ipfilter/test/intest +++ b/contrib/ipfilter/test/intest @@ -1,22 +1,12 @@ #!/bin/sh -mkdir -p results -if [ -f /usr/ucb/touch ] ; then - TOUCH=/usr/ucb/touch -else - if [ -f /usr/bin/touch ] ; then - TOUCH=/usr/bin/touch - else - if [ -f /bin/touch ] ; then - TOUCH=/bin/touch - fi - fi -fi -echo "$1..."; -/bin/cp /dev/null results/$1 -../ipnat -Rnvf regress/$1 2>/dev/null > results/$1 -cmp expected/$1 results/$1 -status=$? -if [ $status = 0 ] ; then - $TOUCH $1 -fi +name=$1 + +. ./ipflib.sh + +test_init + +echo "$name..."; +/bin/cp /dev/null results/$name +../ipnat -Rnvf regress/$name 2>/dev/null > results/$name +check_results $name exit $status diff --git a/contrib/ipfilter/test/ipflib.sh b/contrib/ipfilter/test/ipflib.sh new file mode 100644 index 000000000000..82d473d0d36b --- /dev/null +++ b/contrib/ipfilter/test/ipflib.sh @@ -0,0 +1,59 @@ +#!/bin/sh +# +# (C)opyright 2012 by Darren Reed. +# +# See the IPFILTER.LICENCE file for details on licencing. +# +test_init() { + mkdir -p results + find_touch + set_core $name 1 +} + +set_core() { + if [ -n "${FINDLEAKS}" -a -x /bin/mdb ] ; then + _findleaks=1 + else + _findleaks=0 + fi + if [ -x /bin/coreadm ] ; then + _cn="$1.$2.core" + coreadm -p "${PWD}/$_cn" + else + _cn= + fi +} + +test_end_leak() { + if [ $1 -ne 0 ] ; then + if [ ${_findleaks} = 1 -a -f $_cn ] ; then + echo "==== ${name}:${n} ====" >> leaktest + echo '::findleaks' | mdb ../i86/ipftest $_cn >> leaktest + rm $_cn + else + exit 2; + fi + fi +} + +check_results() { + cmp expected/$1 results/$1 + status=$? + if [ $status = 0 ] ; then + $TOUCH $1 + fi +} + +find_touch() { + if [ -f /bin/touch ] ; then + TOUCH=/bin/touch + else + if [ -f /usr/bin/touch ] ; then + TOUCH=/usr/bin/touch + else + if [ -f /usr/ucb/touch ] ; then + TOUCH=/usr/ucb/touch + fi + fi + fi +} diff --git a/contrib/ipfilter/test/iptest b/contrib/ipfilter/test/iptest index bb3ab5ea86fc..70fd9d89c722 100644 --- a/contrib/ipfilter/test/iptest +++ b/contrib/ipfilter/test/iptest @@ -1,22 +1,12 @@ #!/bin/sh -mkdir -p results -if [ -f /usr/ucb/touch ] ; then - TOUCH=/usr/ucb/touch -else - if [ -f /usr/bin/touch ] ; then - TOUCH=/usr/bin/touch - else - if [ -f /bin/touch ] ; then - TOUCH=/bin/touch - fi - fi -fi -echo "$1..."; -/bin/cp /dev/null results/$1 -../ippool -f regress/$1 -nRv 2>/dev/null > results/$1 -cmp expected/$1 results/$1 -status=$? -if [ $status = 0 ] ; then - $TOUCH $1 -fi +name=$1 + +. ./ipflib.sh + +test_init + +echo "$name..."; +/bin/cp /dev/null results/$name +../ippool -f regress/$name -nRv 2>/dev/null > results/$name +check_results $name exit $status diff --git a/contrib/ipfilter/test/itest b/contrib/ipfilter/test/itest index 8fefc634bfb9..84b045454ff3 100644 --- a/contrib/ipfilter/test/itest +++ b/contrib/ipfilter/test/itest @@ -1,29 +1,30 @@ #!/bin/sh -mkdir -p results -if [ -f /usr/ucb/touch ] ; then - TOUCH=/usr/ucb/touch -else - if [ -f /usr/bin/touch ] ; then - TOUCH=/usr/bin/touch - else - if [ -f /bin/touch ] ; then - TOUCH=/bin/touch - fi - fi -fi -echo "$1..."; -/bin/cp /dev/null results/$1 +name=$1 + +. ./ipflib.sh + +test_init + +echo "$name..."; +/bin/cp /dev/null results/$name case $3 in ipf) - ../ipf -Rnvf regress/$1 2>/dev/null > results/$1 + ../ipf -Rnvf regress/$name 2>/dev/null > results/$name + status=$? + if [ $status -ne 0 ] ; then + echo "ERROR: ../ipf -Rnvf regress/$name" + fi ;; ipftest) - ../ipftest -D -r regress/$1 -i /dev/null > results/$1 + unset FINDLEAKS + ../ipftest -D -r regress/$name -i /dev/null > results/$name + status=$? + if [ $status -ne 0 ] ; then + echo "ERROR: ../ipftest -D -r regress/$name" + fi ;; esac -cmp expected/$1 results/$1 -status=$? -if [ $status = 0 ] ; then - $TOUCH $1 +if [ $status -eq 0 ] ; then + check_results $name fi exit $status diff --git a/contrib/ipfilter/test/logtest b/contrib/ipfilter/test/logtest index 1c8ac5bca2c3..a3a967160790 100755 --- a/contrib/ipfilter/test/logtest +++ b/contrib/ipfilter/test/logtest @@ -1,19 +1,13 @@ #!/bin/sh # $FreeBSD$ +name=$1 format=$2 -mkdir -p results -if [ -f /usr/ucb/touch ] ; then - TOUCH=/usr/ucb/touch -else - if [ -f /usr/bin/touch ] ; then - TOUCH=/usr/bin/touch - else - if [ -f /bin/touch ] ; then - TOUCH=/bin/touch - fi - fi -fi -echo "$1..."; + +. ./ipflib.sh + +test_init + +echo "$name..."; case `uname -s` in OSF1) @@ -24,16 +18,20 @@ OSF1) ;; esac -/bin/cp /dev/null results/$1 -/bin/cp /dev/null results/$1.b +n=1 +/bin/cp /dev/null results/$name +/bin/cp /dev/null results/$name.b ( while read rule; do - echo $rule >> results/$1 - echo $rule | ../ipftest -br - -F $format -i input/$1 -l logout > /dev/null - if [ $? -ne 0 ] ; then - /bin/rm -f logout - exit 1 - fi + /bin/rm -f logout + set_core $name $n + echo $rule >> results/$name + echo $rule | ../ipftest -br - -F $format -i input/$name -l logout > /dev/null & + back=$! + wait $back + test_end_leak $? + n=`expr $n + 1` + TZ=$GMT ../ipmon -P /dev/null -f logout >> results/$1 echo "--------" >> results/$1 TZ=$GMT ../ipmon -P /dev/null -bf logout >> results/$1.b diff --git a/contrib/ipfilter/test/mhtest b/contrib/ipfilter/test/mhtest deleted file mode 100755 index a4d48d693476..000000000000 --- a/contrib/ipfilter/test/mhtest +++ /dev/null @@ -1,36 +0,0 @@ -#!/bin/sh -# multiple rules at the same time - -if [ -f /usr/ucb/touch ] ; then - TOUCH=/usr/ucb/touch -else - if [ -f /usr/bin/touch ] ; then - TOUCH=/usr/bin/touch - else - if [ -f /bin/touch ] ; then - TOUCH=/bin/touch - fi - fi -fi -echo "$1..."; - -/bin/cp /dev/null results/$1 - -../ipftest -br regress/$1 -F hex -i input/$1 > results/$1 -if [ $? -ne 0 ] ; then - exit 1 -fi -echo "--------" >> results/$1 - -cmp expected/$1 results/$1 -status=$? -if [ $status -ne 0 ] ; then - exit $status -fi -cmp expected/$1 results/$1 -status=$? -if [ $status -ne 0 ] ; then - exit $status -fi -$TOUCH $1 -exit 0 diff --git a/contrib/ipfilter/test/mtest b/contrib/ipfilter/test/mtest index 2a3ed38b34f7..aed9fb984243 100755 --- a/contrib/ipfilter/test/mtest +++ b/contrib/ipfilter/test/mtest @@ -1,38 +1,20 @@ #!/bin/sh +name=$1 format=$2 -mkdir -p results -# multiple rules at the same time -if [ -f /usr/ucb/touch ] ; then - TOUCH=/usr/ucb/touch -else - if [ -f /usr/bin/touch ] ; then - TOUCH=/usr/bin/touch - else - if [ -f /bin/touch ] ; then - TOUCH=/bin/touch - fi - fi -fi -echo "$1..."; +. ./ipflib.sh + +test_init + +echo "$name..."; /bin/cp /dev/null results/$1 -../ipftest -F $format -Rbr regress/$1 -i input/$1 > results/$1 -if [ $? -ne 0 ] ; then - exit 1 -fi -echo "--------" >> results/$1 +../ipftest -F $format $4 -Rbr regress/$name -i input/$name > results/$name & +back=$! +wait $back +test_end_leak $? +echo "--------" >> results/$name -cmp expected/$1 results/$1 -status=$? -if [ $status -ne 0 ] ; then - exit $status -fi -cmp expected/$1 results/$1 -status=$? -if [ $status -ne 0 ] ; then - exit $status -fi -$TOUCH $1 -exit 0 +check_results $name +exit $status diff --git a/contrib/ipfilter/test/natipftest b/contrib/ipfilter/test/natipftest index 5776b4202c95..493f18b43a83 100755 --- a/contrib/ipfilter/test/natipftest +++ b/contrib/ipfilter/test/natipftest @@ -3,6 +3,12 @@ mode=$1 name=$2 input=$3 output=$4 +n=1 + +. ./ipflib.sh + +test_init + shift if [ $output = hex ] ; then format="-xF $input" @@ -21,51 +27,33 @@ while [ $# -ge 1 ] ; do fi shift done -mkdir -p results -if [ -f /usr/ucb/touch ] ; then - TOUCH=/usr/ucb/touch -else - if [ -f /usr/bin/touch ] ; then - TOUCH=/usr/bin/touch - else - if [ -f /bin/touch ] ; then - TOUCH=/bin/touch - fi - fi -fi case $mode in single) echo "$name..."; /bin/cp /dev/null results/$name ( while read rule; do + set_core $name $n echo "$rule" | ../ipftest -R $format -b -r regress/$name.ipf -N - -i input/$name >> \ - results/$name; - if [ $? -ne 0 ] ; then - exit 1; - fi + results/$name & + back=$! + wait $back + test_end_leak $? + n=`expr $n + 1` echo "-------------------------------" >> results/$name done ) < regress/$name.nat - cmp expected/$name results/$name - status=$? - if [ $status = 0 ] ; then - $TOUCH $name - fi + check_results $name ;; multi) echo "$name..."; /bin/cp /dev/null results/$name ../ipftest -R $format -b -r regress/$name.ipf -N regress/$name.nat \ - -i input/$name >> results/$name; - if [ $? -ne 0 ] ; then - exit 2; - fi + -i input/$name >> results/$name & + back=$! + wait $back + test_end_leak $? echo "-------------------------------" >> results/$name - cmp expected/$name results/$name - status=$? - if [ $status = 0 ] ; then - $TOUCH $name - fi + check_results $name ;; esac exit $status diff --git a/contrib/ipfilter/test/nattest b/contrib/ipfilter/test/nattest index fece276a6a76..c97087717190 100755 --- a/contrib/ipfilter/test/nattest +++ b/contrib/ipfilter/test/nattest @@ -1,4 +1,10 @@ #!/bin/sh +name=$1 + +. ./ipflib.sh + +test_init + if [ $3 = hex ] ; then format="-xF $2" else @@ -14,29 +20,18 @@ if [ "$4" != "" ] ; then ;; esac fi -if [ -f /usr/ucb/touch ] ; then - TOUCH=/usr/ucb/touch -else - if [ -f /usr/bin/touch ] ; then - TOUCH=/usr/bin/touch - else - if [ -f /bin/touch ] ; then - TOUCH=/bin/touch - fi - fi -fi -echo "$1..."; -/bin/cp /dev/null results/$1 + +echo "$name..."; +n=1 +/bin/cp /dev/null results/$name ( while read rule; do - echo "$rule" | ../ipftest $format -RbN - -i input/$1 >> results/$1; - if [ $? -ne 0 ] ; then - exit 1; - fi - echo "-------------------------------" >> results/$1 -done ) < regress/$1 -cmp expected/$1 results/$1 -status=$? -if [ $status = 0 ] ; then - $TOUCH $1 -fi + set_core $name $n + echo "$rule" | ../ipftest $format -DRbN - -i input/$name >>results/$name & + back=$! + wait $back + test_end_leak $? + n=`expr $n + 1` + echo "-------------------------------" >> results/$name +done ) < regress/$name +check_results $name exit $status diff --git a/contrib/ipfilter/test/ptest b/contrib/ipfilter/test/ptest index 7deccd3354f4..87daacc8072a 100644 --- a/contrib/ipfilter/test/ptest +++ b/contrib/ipfilter/test/ptest @@ -1,31 +1,24 @@ #!/bin/sh -mkdir -p results -if [ -f /usr/ucb/touch ] ; then - TOUCH=/usr/ucb/touch +name=$1 + +. ./ipflib.sh + +test_init + +echo "$name..."; +/bin/cp /dev/null results/$name +if [ -f regress/$name.pool -a -f regress/$name.ipf ] ; then + ../ipftest -RD -b -P regress/$name.pool -r regress/$name.ipf -i input/$name >> \ + results/$name & +elif [ -f regress/$name.pool -a -f regress/$name.nat ] ; then + ../ipftest -RD -b -P regress/$name.pool -N regress/$name.nat -i input/$name >> \ + results/$name & else - if [ -f /usr/bin/touch ] ; then - TOUCH=/usr/bin/touch - else - if [ -f /bin/touch ] ; then - TOUCH=/bin/touch - fi - fi -fi -echo "$1..."; -/bin/cp /dev/null results/$1 -if [ -f regress/$1.pool ] ; then - ../ipftest -RD -b -P regress/$1.pool -r regress/$1.ipf -i input/$1 >> \ - results/$1 -else - ../ipftest -RD -b -r regress/$1.ipf -i input/$1 >> results/$1 -fi -if [ $? -ne 0 ] ; then - exit 1; -fi -echo "-------------------------------" >> results/$1 -cmp expected/$1 results/$1 -status=$? -if [ $status = 0 ] ; then - $TOUCH $1 + ../ipftest -RD -b -r regress/$name.ipf -i input/$name >> results/$name & fi +back=$! +wait $back +test_end_leak $? +echo "-------------------------------" >> results/$name +check_results $name exit $status diff --git a/contrib/ipfilter/test/regress/f13 b/contrib/ipfilter/test/regress/f13 index 8106419f3e08..393a65e9eff0 100644 --- a/contrib/ipfilter/test/regress/f13 +++ b/contrib/ipfilter/test/regress/f13 @@ -6,3 +6,4 @@ pass in proto tcp from any to any port = 25 flags S/SA keep state keep frags block in proto tcp from any to any port = 25 flags S/SA keep state keep frags pass in proto udp from any to any port = 53 keep frags(strict) pass in proto tcp from any to any port = 25 keep state(strict) +pass in proto tcp from any to any port = 25 keep state(loose) diff --git a/contrib/ipfilter/test/regress/f21 b/contrib/ipfilter/test/regress/f21 new file mode 100644 index 000000000000..26ffa87f2386 --- /dev/null +++ b/contrib/ipfilter/test/regress/f21 @@ -0,0 +1,2 @@ +pass out proto tcp all flags S keep state(icmp-head icmpredir) +block in proto icmp all icmp-type redir group icmpredir diff --git a/contrib/ipfilter/test/regress/f22 b/contrib/ipfilter/test/regress/f22 new file mode 100644 index 000000000000..10765db18f06 --- /dev/null +++ b/contrib/ipfilter/test/regress/f22 @@ -0,0 +1,2 @@ +pass in proto tcp all flags S keep state(icmp-head icmpredir) +block out proto icmp all icmp-type redir group icmpredir diff --git a/contrib/ipfilter/test/regress/f25 b/contrib/ipfilter/test/regress/f25 new file mode 100644 index 000000000000..c018b498dd3a --- /dev/null +++ b/contrib/ipfilter/test/regress/f25 @@ -0,0 +1 @@ +pass in on hme0 proto udp all with mcast keep state diff --git a/contrib/ipfilter/test/regress/f26 b/contrib/ipfilter/test/regress/f26 new file mode 100644 index 000000000000..22357a475cae --- /dev/null +++ b/contrib/ipfilter/test/regress/f26 @@ -0,0 +1,6 @@ +pass in quick proto tcp from 1.1.1.0/24 to any port = 22 flags S keep state(max-srcs 3) +pass in quick proto tcp from 1.1.1.0/24 to any port = 22 flags S keep state(max-srcs 3, max-per-src 1/32) +pass in quick proto tcp from 1.1.1.0/24 to any port = 22 flags S keep state(max-srcs 3, max-per-src 1/16) +pass in quick proto tcp all flags S keep state(max-srcs 3) +pass in quick proto tcp all flags S keep state(max-srcs 3, max-per-src 1/32) +pass in quick proto tcp all flags S keep state(max-srcs 3, max-per-src 1/16) diff --git a/contrib/ipfilter/test/regress/f27 b/contrib/ipfilter/test/regress/f27 new file mode 100644 index 000000000000..22357a475cae --- /dev/null +++ b/contrib/ipfilter/test/regress/f27 @@ -0,0 +1,6 @@ +pass in quick proto tcp from 1.1.1.0/24 to any port = 22 flags S keep state(max-srcs 3) +pass in quick proto tcp from 1.1.1.0/24 to any port = 22 flags S keep state(max-srcs 3, max-per-src 1/32) +pass in quick proto tcp from 1.1.1.0/24 to any port = 22 flags S keep state(max-srcs 3, max-per-src 1/16) +pass in quick proto tcp all flags S keep state(max-srcs 3) +pass in quick proto tcp all flags S keep state(max-srcs 3, max-per-src 1/32) +pass in quick proto tcp all flags S keep state(max-srcs 3, max-per-src 1/16) diff --git a/contrib/ipfilter/test/regress/f28.ipf b/contrib/ipfilter/test/regress/f28.ipf new file mode 100644 index 000000000000..ca427715ac10 --- /dev/null +++ b/contrib/ipfilter/test/regress/f28.ipf @@ -0,0 +1,2 @@ +block in all +pass in on nic0 to dstlist/spread from 4.4.0.0/16 to any diff --git a/contrib/ipfilter/test/regress/f28.pool b/contrib/ipfilter/test/regress/f28.pool new file mode 100644 index 000000000000..499b60344662 --- /dev/null +++ b/contrib/ipfilter/test/regress/f28.pool @@ -0,0 +1,2 @@ +pool ipf/dstlist (name spread; policy round-robin;) + { nic0:1.1.0.2; nic1:1.1.1.2; nic2:1.1.2.2; nic3:1.1.3.2; }; diff --git a/contrib/ipfilter/test/regress/f29.ipf b/contrib/ipfilter/test/regress/f29.ipf new file mode 100644 index 000000000000..e4634cc1fa4d --- /dev/null +++ b/contrib/ipfilter/test/regress/f29.ipf @@ -0,0 +1,2 @@ +block in all +pass in on nic0 to dstlist/spread from 4.4.0.0/16 to any keep state diff --git a/contrib/ipfilter/test/regress/f29.pool b/contrib/ipfilter/test/regress/f29.pool new file mode 100644 index 000000000000..499b60344662 --- /dev/null +++ b/contrib/ipfilter/test/regress/f29.pool @@ -0,0 +1,2 @@ +pool ipf/dstlist (name spread; policy round-robin;) + { nic0:1.1.0.2; nic1:1.1.1.2; nic2:1.1.2.2; nic3:1.1.3.2; }; diff --git a/contrib/ipfilter/test/regress/f30 b/contrib/ipfilter/test/regress/f30 new file mode 100644 index 000000000000..84a8970eb860 --- /dev/null +++ b/contrib/ipfilter/test/regress/f30 @@ -0,0 +1,4 @@ +pass in on hme0 proto udp all with not ipopts keep state +pass in on hme0 proto udp all with ipopts keep state +pass in on hme0 proto tcp all flags S with opt rr keep state +pass in on hme0 proto tcp all flags S with opt sec-class secret keep state diff --git a/contrib/ipfilter/test/regress/i11 b/contrib/ipfilter/test/regress/i11 index cb7d68389993..ca65da313b0b 100644 --- a/contrib/ipfilter/test/regress/i11 +++ b/contrib/ipfilter/test/regress/i11 @@ -8,4 +8,5 @@ pass out on ppp0 in-via le0 proto tcp from any to any keep state pass in on ed0,vx0 out-via vx0,ed0 proto udp from any to any keep state pass in proto tcp from any port gt 1024 to localhost port eq 1024 keep state pass in proto tcp all flags S keep state(strict,newisn,no-icmp-err,limit 101,age 600) +pass in proto tcp all flags S keep state(loose,newisn,no-icmp-err,limit 101,age 600) pass in proto udp all keep state(age 10/20,sync) diff --git a/contrib/ipfilter/test/regress/i12 b/contrib/ipfilter/test/regress/i12 index 5342702353e4..f42c2d522b5d 100644 --- a/contrib/ipfilter/test/regress/i12 +++ b/contrib/ipfilter/test/regress/i12 @@ -1,9 +1,9 @@ pass in from 1.1.1.1/32 to 2.2.2.2/32 -pass in from (2.2.2.2/24,3.3.3.3/32) to 4.4.4.4/32 -pass in from (2.2.2.2/24,3.3.3.3/32) to (5.5.5.5/32,6.6.6.6/32) -pass in from (2.2.2.2/24,3.3.3.3/32) to (5.5.5.5/32,6.6.6.6/32) port = (22,25) -pass in proto tcp from (2.2.2.2/24,3.3.3.3/32) port = (53,9) to (5.5.5.5/32,6.6.6.6/32) -pass in proto udp from (2.2.2.2/24,3.3.3.3/32) to (5.5.5.5/32,6.6.6.6/32) port = (53,9) +pass in from {2.2.2.2/24,3.3.3.3/32} to 4.4.4.4/32 +pass in from {2.2.2.2/24,3.3.3.3/32} to {5.5.5.5/32,6.6.6.6/32} +pass in from {2.2.2.2/24,3.3.3.3/32} to {5.5.5.5/32,6.6.6.6/32} port = {22,25} +pass in proto tcp from {2.2.2.2/24,3.3.3.3/32} port = {53,9} to {5.5.5.5/32,6.6.6.6/32} +pass in proto udp from {2.2.2.2/24,3.3.3.3/32} to {5.5.5.5/32,6.6.6.6/32} port = {53,9} pass in from 10.10.10.10 to 11.11.11.11 pass in from pool/101 to hash/202 pass in from hash/303 to pool/404 diff --git a/contrib/ipfilter/test/regress/i14 b/contrib/ipfilter/test/regress/i14 index 2cd26130640a..54613a516706 100644 --- a/contrib/ipfilter/test/regress/i14 +++ b/contrib/ipfilter/test/regress/i14 @@ -8,3 +8,5 @@ pass in proto tcp from 1.0.0.1 to 2.0.0.2 group 101 pass in proto udp from 2.0.0.2 to 3.0.0.3 group 101 block in on vm0 proto tcp/udp all head vm0-group pass in from 1.1.1.1 to 2.2.2.2 group vm0-group +block in on vm0 proto tcp/udp all head vm0-group +pass in from 1.1.1.1 to 2.2.2.2 group vm0-group diff --git a/contrib/ipfilter/test/regress/i17 b/contrib/ipfilter/test/regress/i17 index e399248222a6..139b86a8d84a 100644 --- a/contrib/ipfilter/test/regress/i17 +++ b/contrib/ipfilter/test/regress/i17 @@ -9,5 +9,5 @@ pass in from localhost to any @0 pass in from 1.1.1.1 to any @1 110 pass in from 2.2.2.2 to any @2 pass in from 3.3.3.3 to any -call fr_srcgrpmap/100 out from 10.1.0.0/16 to any -call now fr_dstgrpmap/200 in from 10.2.0.0/16 to any +call srcgrpmap/100 out from 10.1.0.0/16 to any +call now dstgrpmap/200 in from 10.2.0.0/16 to any diff --git a/contrib/ipfilter/test/regress/i18 b/contrib/ipfilter/test/regress/i18 index 03ce713b4a54..b55b11a01fe8 100644 --- a/contrib/ipfilter/test/regress/i18 +++ b/contrib/ipfilter/test/regress/i18 @@ -1,3 +1,3 @@ -pass in tos (80,0x80) all -pass in tos (0x80,80) all -block in ttl (0,1,2,3,4,5,6) all +pass in tos {80,0x80} all +pass out tos {0x80,80} all +block in ttl {0,1,2,3,4,5,6} all diff --git a/contrib/ipfilter/test/regress/i2 b/contrib/ipfilter/test/regress/i2 index 50f610750bc2..f69e28edb13d 100644 --- a/contrib/ipfilter/test/regress/i2 +++ b/contrib/ipfilter/test/regress/i2 @@ -6,3 +6,4 @@ block in proto 17 from any to any block in proto 250 from any to any pass in proto tcp/udp from any to any block in proto tcp-udp from any to any +block in proto tcp-udp from any to any diff --git a/contrib/ipfilter/test/regress/i21 b/contrib/ipfilter/test/regress/i21 index 9d583ab0894f..237f8fadb648 100644 --- a/contrib/ipfilter/test/regress/i21 +++ b/contrib/ipfilter/test/regress/i21 @@ -2,6 +2,6 @@ pass in from port = 10101 pass out from any to port != 22 block in from port 20:21 block out from any to port 10 <> 100 -pass out from any to port = (3,5,7,9) -block in from port = (20,25) -pass in from any port = (11:12, 21:22) to any port = (1:2, 4:5, 8:9) +pass out from any to port = {3,5,7,9} +block in from port = {20,25} +pass in from any port = {11:12, 21:22} to any port = {1:2, 4:5, 8:9} diff --git a/contrib/ipfilter/test/regress/i22 b/contrib/ipfilter/test/regress/i22 new file mode 100644 index 000000000000..1ac8d12ba35f --- /dev/null +++ b/contrib/ipfilter/test/regress/i22 @@ -0,0 +1,5 @@ +pass in exp { "ip.src != 1.1.1.0/24; tcp.dport = 80;" } +pass in exp { "ip.addr = 1.2.3.4,5.6.7.8;" } +block out exp { "ip.dst= 127.0.0.0/8;" } +block in exp { "udp.sport=53;udp.dport=53;" } +pass out exp { "tcp.sport=22; tcp.port=25;" } diff --git a/contrib/ipfilter/test/regress/i23 b/contrib/ipfilter/test/regress/i23 new file mode 100644 index 000000000000..792d6005489e --- /dev/null +++ b/contrib/ipfilter/test/regress/i23 @@ -0,0 +1 @@ +# diff --git a/contrib/ipfilter/test/regress/i7 b/contrib/ipfilter/test/regress/i7 index 1a82940c6c86..15b88a56dc51 100644 --- a/contrib/ipfilter/test/regress/i7 +++ b/contrib/ipfilter/test/regress/i7 @@ -7,3 +7,8 @@ block in on lo0 proto tcp from any to any flags 2/18 pass in on lo0 proto tcp from any to any flags 2 block in on lo0 proto tcp from any to any flags /16 pass in on lo0 proto tcp from any to any flags 2/SA +pass in on lo0 proto tcp from any to any flags S/18 +block in on lo0 proto tcp from any to any flags 2/18 +pass in on lo0 proto tcp from any to any flags 2 +block in on lo0 proto tcp from any to any flags /16 +pass in on lo0 proto tcp from any to any flags 2/SA diff --git a/contrib/ipfilter/test/regress/i8 b/contrib/ipfilter/test/regress/i8 index c30f8bdbd90e..abf69d9d30bd 100644 --- a/contrib/ipfilter/test/regress/i8 +++ b/contrib/ipfilter/test/regress/i8 @@ -11,11 +11,11 @@ pass in proto icmp all icmp-type unreach code host-prohib pass in proto icmp all icmp-type unreach code host-tos pass in proto icmp all icmp-type unreach code host-unk pass in proto icmp all icmp-type unreach code host-unr -pass in proto icmp all icmp-type unreach code (net-unk,net-unr) +pass in proto icmp all icmp-type unreach code {net-unk,net-unr} pass in proto icmp all icmp-type unreach code port-unr pass in proto icmp all icmp-type unreach code proto-unr pass in proto icmp all icmp-type unreach code srcfail -pass in proto icmp all icmp-type (echo,echorep) +pass in proto icmp all icmp-type {echo,echorep} pass in proto icmp all icmp-type inforeq pass in proto icmp all icmp-type inforep pass in proto icmp all icmp-type maskrep @@ -31,3 +31,32 @@ pass in proto icmp all icmp-type timestrep pass in proto icmp all icmp-type timex pass in proto icmp all icmp-type 254 pass in proto icmp all icmp-type 253 code 254 +pass in proto icmp all icmp-type unreach code cutoff-preced +pass in proto icmp all icmp-type unreach code filter-prohib +pass in proto icmp all icmp-type unreach code isolate +pass in proto icmp all icmp-type unreach code needfrag +pass in proto icmp all icmp-type unreach code net-prohib +pass in proto icmp all icmp-type unreach code net-tos +pass in proto icmp all icmp-type unreach code host-preced +pass in proto icmp all icmp-type unreach code host-prohib +pass in proto icmp all icmp-type unreach code host-tos +pass in proto icmp all icmp-type unreach code host-unk +pass in proto icmp all icmp-type unreach code host-unr +pass in proto icmp all icmp-type unreach code {net-unk,net-unr} +pass in proto icmp all icmp-type unreach code port-unr +pass in proto icmp all icmp-type unreach code proto-unr +pass in proto icmp all icmp-type unreach code srcfail +pass in proto icmp all icmp-type {echo,echorep} +pass in proto icmp all icmp-type inforeq +pass in proto icmp all icmp-type inforep +pass in proto icmp all icmp-type maskrep +pass in proto icmp all icmp-type maskreq +pass in proto icmp all icmp-type paramprob +pass in proto icmp all icmp-type redir +pass in proto icmp all icmp-type unreach +pass in proto icmp all icmp-type routerad +pass in proto icmp all icmp-type routersol +pass in proto icmp all icmp-type squench +pass in proto icmp all icmp-type timest +pass in proto icmp all icmp-type timestrep +pass in proto icmp all icmp-type timex diff --git a/contrib/ipfilter/test/regress/in100 b/contrib/ipfilter/test/regress/in100 new file mode 100644 index 000000000000..5e2ab6c91730 --- /dev/null +++ b/contrib/ipfilter/test/regress/in100 @@ -0,0 +1,3 @@ +rewrite in on bge0 from 1.1.1.1 to 2.2.2.2 -> src 3.3.3.3 dst 4.4.4.4; +rewrite out on bge0 from 1.1.1.1/32 to 2.2.2.2 -> src 3.3.3.0/24 dst 4.4.4.4; +rewrite in on bge0 from 1.1.1.1/32 to 2.2.2.2/32 -> src 3.3.3.0/24 dst 4.4.4.0/24; diff --git a/contrib/ipfilter/test/regress/in101 b/contrib/ipfilter/test/regress/in101 new file mode 100644 index 000000000000..afef53bc9ab4 --- /dev/null +++ b/contrib/ipfilter/test/regress/in101 @@ -0,0 +1,4 @@ +rewrite in on bge0 proto icmp from 1.1.1.1 to 2.2.2.2 -> src 3.3.3.3 dst 4.4.4.4; +rewrite in on bge0 proto udp from 1.1.1.1 to 2.2.2.2 -> src 3.3.3.3 dst 4.4.4.4; +rewrite out on bge0 proto tcp from 1.1.1.1/32 to 2.2.2.2 -> src 3.3.3.0/24 dst 4.4.4.4; +rewrite in on bge0 proto tcp/udp from 1.1.1.1/32 to 2.2.2.2/32 -> src 3.3.3.0/24,20202 dst 4.4.4.0/24,10101; diff --git a/contrib/ipfilter/test/regress/in102 b/contrib/ipfilter/test/regress/in102 new file mode 100644 index 000000000000..57f364566f08 --- /dev/null +++ b/contrib/ipfilter/test/regress/in102 @@ -0,0 +1,5 @@ +rewrite in on bge0 proto tcp from any to any -> src 0/0 dst dstlist/a; +rewrite in on bge0 proto tcp from 1.1.1.1 to any -> src 0/0 dst dstlist/bee; +rewrite in on bge0 proto tcp from 1.1.1.1 to 2.2.2.2 -> src 0/0 dst dstlist/cat; +rewrite in on bge0 proto tcp from pool/a to 2.2.2.2 -> src 0/0 dst dstlist/bat; +rewrite in on bge0 proto tcp from pool/a to pool/1 -> src 0/0 dst dstlist/ant; diff --git a/contrib/ipfilter/test/regress/in2 b/contrib/ipfilter/test/regress/in2 index 83a2ca5acc3c..58556c048543 100644 --- a/contrib/ipfilter/test/regress/in2 +++ b/contrib/ipfilter/test/regress/in2 @@ -67,5 +67,5 @@ rdr ge0 9.8.7.6/32 port 21 -> 1.1.1.1 port 21 tcp proxy ftp rdr le0 9.8.7.6/32 port 1000-2000 -> 1.1.1.1 port 5555 tcp rdr le0 9.8.7.6/32 port 1000-2000 -> 1.1.1.1 port = 5555 tcp rdr le0 0/0 -> test.host.dots -rdr le0 0/0 -> test.host.dots,test.host.dots -rdr adsl0,ppp0 0/0 port 25 -> 127.0.0.1 port 25 +rdr le0 any -> test.host.dots,test.host.dots +rdr adsl0,ppp0 9.8.7.6/32 port 1000-2000 -> 1.1.1.1 port 5555-7777 tcp diff --git a/contrib/ipfilter/test/regress/in7 b/contrib/ipfilter/test/regress/in7 new file mode 100644 index 000000000000..792d6005489e --- /dev/null +++ b/contrib/ipfilter/test/regress/in7 @@ -0,0 +1 @@ +# diff --git a/contrib/ipfilter/test/regress/ip3 b/contrib/ipfilter/test/regress/ip3 new file mode 100644 index 000000000000..98d2b0b94555 --- /dev/null +++ b/contrib/ipfilter/test/regress/ip3 @@ -0,0 +1,14 @@ +pool ipf/dstlist (name fred; policy round-robin;) + { 3.3.3.3; }; +pool ipf/dstlist (name jack; policy weighted connection;) + { 4.4.4.4; bge0:5.5.5.5;}; +pool ipf/dstlist (name jill; policy random;) + { 1.1.1.1; bge0:2.2.2.2;}; +pool nat/hash (name noproxy; size 17;) + { 1.1.1.1; 2.2.2.2;}; +pool nat/tree (name raw;) + { 1.1.1.1; 2.2.2.2;}; +pool all/dstlist (name jill; policy random;) + { 1.1.1.1; bge0:2.2.2.2;}; +pool all/hash (name noproxy; size 17;) + { 1.1.1.1; 2.2.2.2;}; diff --git a/contrib/ipfilter/test/regress/ipv6.4 b/contrib/ipfilter/test/regress/ipv6.4 new file mode 100644 index 000000000000..b2217446d39e --- /dev/null +++ b/contrib/ipfilter/test/regress/ipv6.4 @@ -0,0 +1,3 @@ +pass in proto ipv6-icmp all icmp-type echo keep frags +pass in proto ipv6-icmp all icmp-type echo keep frags keep state +pass in proto tcp all keep frags keep state diff --git a/contrib/ipfilter/test/regress/ipv6.5 b/contrib/ipfilter/test/regress/ipv6.5 index ba8cabb501e0..d9ae23b2fbd7 100644 --- a/contrib/ipfilter/test/regress/ipv6.5 +++ b/contrib/ipfilter/test/regress/ipv6.5 @@ -1,2 +1,2 @@ -pass out all with v6hdrs routing -block out proto tcp all with v6hdrs routing +pass out family inet6 all with v6hdr routing +block out family inet6 proto tcp all with v6hdr routing diff --git a/contrib/ipfilter/test/regress/ipv6.6 b/contrib/ipfilter/test/regress/ipv6.6 index f1f904b4eb61..19a4df972334 100644 --- a/contrib/ipfilter/test/regress/ipv6.6 +++ b/contrib/ipfilter/test/regress/ipv6.6 @@ -1 +1,2 @@ pass out on gif0 proto udp all keep frag +block out all with bad diff --git a/contrib/ipfilter/test/regress/n100 b/contrib/ipfilter/test/regress/n100 new file mode 100644 index 000000000000..a8b6deeb52e3 --- /dev/null +++ b/contrib/ipfilter/test/regress/n100 @@ -0,0 +1 @@ +rewrite out on zx0 from 0/0 to 2.2.0.0/16 -> src 4.4.4.4/32 dst 6.6.0.0/16; diff --git a/contrib/ipfilter/test/regress/n101 b/contrib/ipfilter/test/regress/n101 new file mode 100644 index 000000000000..2f5fcd98c9ce --- /dev/null +++ b/contrib/ipfilter/test/regress/n101 @@ -0,0 +1 @@ +rewrite out on zx0 proto tcp from 0/0 to 2.2.0.0/16 -> src 4.4.4.4/32 dst 6.6.0.0/16; diff --git a/contrib/ipfilter/test/regress/n102 b/contrib/ipfilter/test/regress/n102 new file mode 100644 index 000000000000..f056633dd23b --- /dev/null +++ b/contrib/ipfilter/test/regress/n102 @@ -0,0 +1 @@ +rewrite out on zx0 proto tcp from 0/0 to 2.2.0.0/16 -> src 4.4.4.4/32,1000:2000 dst 6.6.0.0/16; diff --git a/contrib/ipfilter/test/regress/n103 b/contrib/ipfilter/test/regress/n103 new file mode 100644 index 000000000000..c3c27d60dd8f --- /dev/null +++ b/contrib/ipfilter/test/regress/n103 @@ -0,0 +1 @@ +rewrite out on zx0 proto tcp from 0/0 to 2.2.0.0/16 -> src 4.4.4.4/32,1000-1001 dst 6.6.0.0/16,4000:4001; diff --git a/contrib/ipfilter/test/regress/n104 b/contrib/ipfilter/test/regress/n104 new file mode 100644 index 000000000000..785f0ada244b --- /dev/null +++ b/contrib/ipfilter/test/regress/n104 @@ -0,0 +1 @@ +rewrite out on zx0 proto tcp from 0/0 to 2.2.0.0/16 -> src 4.4.0.0/24,1000-1001 dst 6.6.0.0/16,4000:4001; diff --git a/contrib/ipfilter/test/regress/n105 b/contrib/ipfilter/test/regress/n105 new file mode 100644 index 000000000000..afe89660a728 --- /dev/null +++ b/contrib/ipfilter/test/regress/n105 @@ -0,0 +1 @@ +rewrite in on zx0 proto tcp from 0/0 to 2.2.0.0/16 port = 80 -> src 4.4.4.4/32,1000-1001 dst 6.6.0.0/16 port = 3128; diff --git a/contrib/ipfilter/test/regress/n106 b/contrib/ipfilter/test/regress/n106 new file mode 100644 index 000000000000..6074ab0b4cc4 --- /dev/null +++ b/contrib/ipfilter/test/regress/n106 @@ -0,0 +1 @@ +rewrite out on zx0 proto tcp from 0/0 to 2.2.0.0/16 port = 80 -> src 4.4.4.4/32,1000-1001 dst 6.6.0.0/16 port = 3128; diff --git a/contrib/ipfilter/test/regress/n10_6 b/contrib/ipfilter/test/regress/n10_6 new file mode 100644 index 000000000000..738152df62ab --- /dev/null +++ b/contrib/ipfilter/test/regress/n10_6 @@ -0,0 +1,3 @@ +map ppp0 any -> 203.203.203.203/128 mssclamp 100 +map ppp0 any -> 203.203.203.203/128 mssclamp 1000 +map ppp0 any -> 203.203.203.203/128 mssclamp 10000 diff --git a/contrib/ipfilter/test/regress/n11_6 b/contrib/ipfilter/test/regress/n11_6 new file mode 100644 index 000000000000..7b428cc23925 --- /dev/null +++ b/contrib/ipfilter/test/regress/n11_6 @@ -0,0 +1,3 @@ +bimap zx0 10:1:1::1/128 -> 1::6:7:8/128 +bimap zx0 10:1:1::/112 -> 10::2:2:2/128 +bimap zx0 10:1:1::/112 -> 10::3:4:5/112 diff --git a/contrib/ipfilter/test/regress/n12_6 b/contrib/ipfilter/test/regress/n12_6 new file mode 100644 index 000000000000..bf218489d051 --- /dev/null +++ b/contrib/ipfilter/test/regress/n12_6 @@ -0,0 +1 @@ +map le0 c0a8:7e00::/112 -> 0/128 portmap tcp/udp 10000:20000 diff --git a/contrib/ipfilter/test/regress/n13_6 b/contrib/ipfilter/test/regress/n13_6 new file mode 100644 index 000000000000..c1d1646d2ddb --- /dev/null +++ b/contrib/ipfilter/test/regress/n13_6 @@ -0,0 +1 @@ +map le0 192:168:1::0/48 -> range 203:0:1::1:23-203:0:1::3:45 diff --git a/contrib/ipfilter/test/regress/n14_6 b/contrib/ipfilter/test/regress/n14_6 new file mode 100644 index 000000000000..64e88ee4c7fe --- /dev/null +++ b/contrib/ipfilter/test/regress/n14_6 @@ -0,0 +1 @@ +rdr gre0 any port 80 -> 10:1:1::254,10:1:1::253 port 80 tcp sticky diff --git a/contrib/ipfilter/test/regress/n15 b/contrib/ipfilter/test/regress/n15 new file mode 100644 index 000000000000..062b766c9aba --- /dev/null +++ b/contrib/ipfilter/test/regress/n15 @@ -0,0 +1,2 @@ +rdr le0 0/0 port 80 -> 3.3.3.3 port 80 tcp +rdr le0 0/0 port 80 -> 3.3.3.3 port 80-88 tcp diff --git a/contrib/ipfilter/test/regress/n15_6 b/contrib/ipfilter/test/regress/n15_6 new file mode 100644 index 000000000000..e82dd8232760 --- /dev/null +++ b/contrib/ipfilter/test/regress/n15_6 @@ -0,0 +1,2 @@ +rdr le0 any port 80 -> 3:0:3::3:3 port 80 tcp +rdr le0 any port 80 -> 3:0:3::3:3 port 80-88 tcp diff --git a/contrib/ipfilter/test/regress/n16_6 b/contrib/ipfilter/test/regress/n16_6 new file mode 100644 index 000000000000..ff8958cad869 --- /dev/null +++ b/contrib/ipfilter/test/regress/n16_6 @@ -0,0 +1 @@ +rdr vlan0 from any to 69.248.79.193 port = 38136 -> 172.31.83.24 port 2013 udp diff --git a/contrib/ipfilter/test/regress/n17 b/contrib/ipfilter/test/regress/n17 new file mode 100644 index 000000000000..213f51f079b5 --- /dev/null +++ b/contrib/ipfilter/test/regress/n17 @@ -0,0 +1 @@ +bimap zx0 0/0 -> 1.1.1.3 diff --git a/contrib/ipfilter/test/regress/n17_6 b/contrib/ipfilter/test/regress/n17_6 new file mode 100644 index 000000000000..08ef77a48845 --- /dev/null +++ b/contrib/ipfilter/test/regress/n17_6 @@ -0,0 +1 @@ +bimap zx0 any -> 1::1:1:3 diff --git a/contrib/ipfilter/test/regress/n18 b/contrib/ipfilter/test/regress/n18 new file mode 100644 index 000000000000..792f136b76c1 --- /dev/null +++ b/contrib/ipfilter/test/regress/n18 @@ -0,0 +1,3 @@ +map z0 0/0 -> 1.1.1.1/32 portmap tcp/udp 1:4 sequential +map z0 0/0 -> 1.1.1.1/32 portmap tcp/udp 1000:5000 sequential +map z0 0/0 -> 1.1.1.1/32 portmap tcp/udp 1000:50000 sequential diff --git a/contrib/ipfilter/test/regress/n1_6 b/contrib/ipfilter/test/regress/n1_6 new file mode 100644 index 000000000000..341f13651b98 --- /dev/null +++ b/contrib/ipfilter/test/regress/n1_6 @@ -0,0 +1,3 @@ +map zx0 10:1:1::1/128 -> 10::2:2:2/128 +map zx0 10:1:1::/112 -> 10::3:4:5/128 +map zx0 10:1:1::/112 -> 10::3:4:0/112 diff --git a/contrib/ipfilter/test/regress/n200 b/contrib/ipfilter/test/regress/n200 new file mode 100644 index 000000000000..c792e5406754 --- /dev/null +++ b/contrib/ipfilter/test/regress/n200 @@ -0,0 +1 @@ +divert in on bar0 from any to any -> src 127.0.0.1,10101 dst 127.0.0.1,10101 udp; diff --git a/contrib/ipfilter/test/regress/n2_6 b/contrib/ipfilter/test/regress/n2_6 new file mode 100644 index 000000000000..3a04f33ae740 --- /dev/null +++ b/contrib/ipfilter/test/regress/n2_6 @@ -0,0 +1,4 @@ +map zx0 10:1:1::1/128 -> 10::2:2:2/128 portmap tcp 10000:20000 sequential +map zx0 10:1:1::/112 -> 10::3:4:5/128 portmap udp 10000:20000 sequential +map zx0 10:1::/32 -> 10::3:4:0/112 portmap tcp/udp 10000:20000 sequential +map zx0 10:1:1::/112 -> 10::3:4:5/128 portmap tcp/udp 40000:40001 sequential diff --git a/contrib/ipfilter/test/regress/n4_6 b/contrib/ipfilter/test/regress/n4_6 new file mode 100644 index 000000000000..72dad4c11217 --- /dev/null +++ b/contrib/ipfilter/test/regress/n4_6 @@ -0,0 +1,6 @@ +rdr zx0 10:1:1::1/128 port 23 -> 10::2:2:1 port 10023 tcp +rdr zx0 10:1:1::/112 port 23 -> 10::2:2:1 port 10023 tcp +rdr zx0 any port 23 -> 10::2:2:1 port 10023 tcp +rdr zx0 10:1:1::/112 port 53 -> 10::2:2:1 port 10053 udp +rdr zx0 10:1:1::/112 port 0 -> 10::2:2:1 port 0 tcp +rdr zx0 10:1:1::/112 port 0 -> 10::2:2:1 port 0 ip diff --git a/contrib/ipfilter/test/regress/n5_6 b/contrib/ipfilter/test/regress/n5_6 new file mode 100644 index 000000000000..acefd7b18a73 --- /dev/null +++ b/contrib/ipfilter/test/regress/n5_6 @@ -0,0 +1,6 @@ +map zx0 10:1:1::1/128 -> 10::2:2:2/128 +map zx0 from 10:1:1::/112 to 10:1::/32 -> 10::3:4:5/128 +map zx0 from 10:1:1::/112 ! to 10:1::/32 -> 10::3:4:0/112 +map zx0 10:1:1::/112 -> 10::3:4:5/128 portmap udp 10000:20000 sequential +map zx0 10:1::/32 -> 10::3:4:0/112 portmap tcp/udp 10000:20000 sequential +map zx0 10:1:1::/112 -> 10::3:4:5/128 portmap tcp/udp 40000:40001 sequential diff --git a/contrib/ipfilter/test/regress/n6_6 b/contrib/ipfilter/test/regress/n6_6 new file mode 100644 index 000000000000..3491c6b3e039 --- /dev/null +++ b/contrib/ipfilter/test/regress/n6_6 @@ -0,0 +1,5 @@ +rdr zx0 10:1:1::1/128 port 23 -> 10::2:2:1 port 10023 tcp +rdr zx0 from any to 10:1:1::/112 port = 23 -> 10::2:2:1 port 10023 tcp +rdr zx0 from 10::/32 to 10:1:1::/112 port = 23 -> 10::2:2:1 port 10023 tcp +rdr zx0 from 10:3::/32 to 10:1::/32 port = 23 -> 10::2:2:1 port 10023 tcp +rdr zx0 ! from 10::/32 to 10:1:1::/112 port = 53 -> 10::2:2:1 port 10053 udp diff --git a/contrib/ipfilter/test/regress/n7_6 b/contrib/ipfilter/test/regress/n7_6 new file mode 100644 index 000000000000..88055f69ab30 --- /dev/null +++ b/contrib/ipfilter/test/regress/n7_6 @@ -0,0 +1,3 @@ +rdr zx0 10:1:1::1/128 port 23-79 -> 10::2:2:1 port 10023 tcp +rdr zx0 10:1:1::1/128 port 23-79 -> 10::2:2:1 port = 10023 tcp +rdr zx0 10:1:1::/112 port 80 -> 10::2:2:1,1::2:2:129 port 3128 tcp diff --git a/contrib/ipfilter/test/regress/n8_6 b/contrib/ipfilter/test/regress/n8_6 new file mode 100644 index 000000000000..2f96be05d003 --- /dev/null +++ b/contrib/ipfilter/test/regress/n8_6 @@ -0,0 +1 @@ +map icmp0 2::2:2:0/112 -> 10:10:10::/112 diff --git a/contrib/ipfilter/test/regress/n9_6 b/contrib/ipfilter/test/regress/n9_6 new file mode 100644 index 000000000000..31e4615f1327 --- /dev/null +++ b/contrib/ipfilter/test/regress/n9_6 @@ -0,0 +1 @@ +rdr icmp0 4:4:4::/112 port 0 -> 10:10:10::1 port 0 ip diff --git a/contrib/ipfilter/test/regress/ni13.nat b/contrib/ipfilter/test/regress/ni13.nat index 7a879d8cd85a..ac2be49d61f8 100644 --- a/contrib/ipfilter/test/regress/ni13.nat +++ b/contrib/ipfilter/test/regress/ni13.nat @@ -1 +1 @@ -rdr pcn1 192.168.113.3/32 port 1723 -> 0.0.0.0 port 1723 proxy pptp +rdr pcn1 192.168.113.3/32 port 1723 -> 0.0.0.0 port 1723 tcp proxy pptp diff --git a/contrib/ipfilter/test/regress/ni14.nat b/contrib/ipfilter/test/regress/ni14.nat index c546e99029de..72a8a4a2759e 100644 --- a/contrib/ipfilter/test/regress/ni14.nat +++ b/contrib/ipfilter/test/regress/ni14.nat @@ -1 +1 @@ -rdr pcn1 192.168.113.3/32 port 1723 -> 127.0.0.1 port 1723 proxy pptp +rdr pcn1 192.168.113.3/32 port 1723 -> 127.0.0.1 port 1723 tcp proxy pptp diff --git a/contrib/ipfilter/test/regress/ni17.ipf b/contrib/ipfilter/test/regress/ni17.ipf new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/contrib/ipfilter/test/regress/ni18.ipf b/contrib/ipfilter/test/regress/ni18.ipf new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/contrib/ipfilter/test/regress/ni18.nat b/contrib/ipfilter/test/regress/ni18.nat new file mode 100644 index 000000000000..40113c1c32c2 --- /dev/null +++ b/contrib/ipfilter/test/regress/ni18.nat @@ -0,0 +1,4 @@ +rdr hme0 192.168.1.0/24 port 80 -> 1.1.1.1 port 80 tcp; +no rdr hme0 192.168.1.1 port 80 tcp; +map hme1 10.1.0.0/16 -> 203.1.1.1/32 portmap tcp/udp 10000:20000 +no map hme1 10.1.1.0/24 tcp; diff --git a/contrib/ipfilter/test/regress/p1.pool b/contrib/ipfilter/test/regress/p1.pool index 14ae3a3d40dd..aa262a7704ce 100644 --- a/contrib/ipfilter/test/regress/p1.pool +++ b/contrib/ipfilter/test/regress/p1.pool @@ -1,2 +1,2 @@ table role = ipf type = tree number = 100 - { 1.1.1.1/32; !2.2.0.0/16; 2.2.2.0/24; }; + { 1.1.1.1/32; !2.2.0.0/16; 2.2.2.0/24; ef00::5/128; }; diff --git a/contrib/ipfilter/test/regress/p10.nat b/contrib/ipfilter/test/regress/p10.nat new file mode 100644 index 000000000000..3c3fa7c1874f --- /dev/null +++ b/contrib/ipfilter/test/regress/p10.nat @@ -0,0 +1 @@ +rewrite in on bge0 proto tcp from any to any port = 80 -> src 0/0 dst dstlist/servers; diff --git a/contrib/ipfilter/test/regress/p10.pool b/contrib/ipfilter/test/regress/p10.pool new file mode 100644 index 000000000000..2be554aadc82 --- /dev/null +++ b/contrib/ipfilter/test/regress/p10.pool @@ -0,0 +1,2 @@ +pool nat/dstlist (name servers; policy hash;) + { 1.1.1.2; 1.1.1.4; 1.1.1.5; 1.1.1.9; }; diff --git a/contrib/ipfilter/test/regress/p11.nat b/contrib/ipfilter/test/regress/p11.nat new file mode 100644 index 000000000000..3c3fa7c1874f --- /dev/null +++ b/contrib/ipfilter/test/regress/p11.nat @@ -0,0 +1 @@ +rewrite in on bge0 proto tcp from any to any port = 80 -> src 0/0 dst dstlist/servers; diff --git a/contrib/ipfilter/test/regress/p11.pool b/contrib/ipfilter/test/regress/p11.pool new file mode 100644 index 000000000000..a79d9ea58098 --- /dev/null +++ b/contrib/ipfilter/test/regress/p11.pool @@ -0,0 +1,2 @@ +pool nat/dstlist (name servers; policy dst-hash;) + { 1.1.1.2; 1.1.1.4; 1.1.1.5; 1.1.1.9; }; diff --git a/contrib/ipfilter/test/regress/p12.nat b/contrib/ipfilter/test/regress/p12.nat new file mode 100644 index 000000000000..3c3fa7c1874f --- /dev/null +++ b/contrib/ipfilter/test/regress/p12.nat @@ -0,0 +1 @@ +rewrite in on bge0 proto tcp from any to any port = 80 -> src 0/0 dst dstlist/servers; diff --git a/contrib/ipfilter/test/regress/p12.pool b/contrib/ipfilter/test/regress/p12.pool new file mode 100644 index 000000000000..c9afcda840cd --- /dev/null +++ b/contrib/ipfilter/test/regress/p12.pool @@ -0,0 +1,2 @@ +pool nat/dstlist (name servers; policy src-hash;) + { 1.1.1.2; 1.1.1.4; 1.1.1.5; 1.1.1.9; }; diff --git a/contrib/ipfilter/test/regress/p13.ipf b/contrib/ipfilter/test/regress/p13.ipf new file mode 100644 index 000000000000..acaf639ac1fb --- /dev/null +++ b/contrib/ipfilter/test/regress/p13.ipf @@ -0,0 +1 @@ +pass in from pool/100 to any diff --git a/contrib/ipfilter/test/regress/p13.pool b/contrib/ipfilter/test/regress/p13.pool new file mode 100644 index 000000000000..de80f72d5b8b --- /dev/null +++ b/contrib/ipfilter/test/regress/p13.pool @@ -0,0 +1,2 @@ +table role = all type = tree number = 100 + { 1.1.1.1/32; !2.2.0.0/16; 2.2.2.0/24; ef00::5/128; }; diff --git a/contrib/ipfilter/test/regress/p3.ipf b/contrib/ipfilter/test/regress/p3.ipf index aad7cb358b5c..a598d88168c9 100644 --- a/contrib/ipfilter/test/regress/p3.ipf +++ b/contrib/ipfilter/test/regress/p3.ipf @@ -1,5 +1,5 @@ -call now fr_srcgrpmap/1010 in all -call now fr_dstgrpmap/2010 out all +call now srcgrpmap/1010 in all +call now dstgrpmap/2010 out all pass in all group 1020 block in all group 1030 pass out all group 2020 diff --git a/contrib/ipfilter/test/regress/p4.nat b/contrib/ipfilter/test/regress/p4.nat new file mode 100644 index 000000000000..d504ac90c467 --- /dev/null +++ b/contrib/ipfilter/test/regress/p4.nat @@ -0,0 +1 @@ +map * from pool/100 to any -> 1.2.3.4/32 diff --git a/contrib/ipfilter/test/regress/p4.pool b/contrib/ipfilter/test/regress/p4.pool new file mode 100644 index 000000000000..6ed0e499ac5a --- /dev/null +++ b/contrib/ipfilter/test/regress/p4.pool @@ -0,0 +1,2 @@ +table role = nat type = tree number = 100 + { 1.1.1.1/32; !2.2.0.0/16; 2.2.2.0/24; }; diff --git a/contrib/ipfilter/test/regress/p6.ipf b/contrib/ipfilter/test/regress/p6.ipf new file mode 100644 index 000000000000..b9b89374eede --- /dev/null +++ b/contrib/ipfilter/test/regress/p6.ipf @@ -0,0 +1 @@ +block in from pool/microsoft to any diff --git a/contrib/ipfilter/test/regress/p6.pool b/contrib/ipfilter/test/regress/p6.pool new file mode 100644 index 000000000000..83e818ced5b0 --- /dev/null +++ b/contrib/ipfilter/test/regress/p6.pool @@ -0,0 +1 @@ +pool ipf/tree (name microsoft;) { whois file "regress/p6.whois"; }; diff --git a/contrib/ipfilter/test/regress/p6.whois b/contrib/ipfilter/test/regress/p6.whois new file mode 100644 index 000000000000..284244e11b8f --- /dev/null +++ b/contrib/ipfilter/test/regress/p6.whois @@ -0,0 +1,241 @@ +# This query resulted in more than 256 records. Remaining results +# have been truncated. For more specific results, go to +# http://ws.arin.net/whois for help in refining your query. +Microsoft Corp (MSFT) +Microsoft Corp., MSN Operations (MCMO) +MICROSOFT CORPORATION (MICRO-101) +MICROSOFT CORPORATION (MICRO-97) +MICROSOFT CORPORATION (MICRO-100) +Microsoft Corporation (MICRO-111) +MICROSOFT CORPORATION (MICRO-117) +Microsoft Corporation (ZM23-ARIN) noc@microsoft.com +1-425-882-8080 +Microsoft (ZM39-ARIN) noc@microsoft.com +1-425-882-8080 +Microsoft Corp (AS8068) MICROSOFT-CORP---MSN-AS-BLOCK 8068 - 8075 +Microsoft Corp (AS13811) MSLI 13811 +Microsoft Corp (AS14719) MICROSOFT-CORP-BCENTRAL 14719 +Microsoft Corp (AS3598) MICROSOFT-CORP-AS 3598 +Microsoft Corp (AS5761) MICROSOFT-CORP---MSN-AS---SATURN 5761 +Microsoft Corp (AS6182) MICROSOFT-CORP--MSN-AS-4 6182 +Microsoft Corp (AS6194) MICROSOFT-CORP--MSN-AS-3 6194 +Microsoft Corp (AS6291) MICROSOFT-CORP---MSN-AS 6291 +Microsoft Corp (AS13399) MICROSOFT-CORP---MSN-AS-2 13399 +Microsoft Corp (AS23468) MICROSOFT-CORP-XBOX-ONLINE 23468 +Microsoft Corp MICROSOFT (NET-131-107-0-0-1) 131.107.0.0 - 131.107.255.255 +Microsoft Corp MICROSOFT-VEXCEL (NET-192-92-90-0-1) 192.92.90.0 - 192.92.90.255 +Microsoft Corp NETBLK-MSOFT-NET (NET-198-105-232-0-1) 198.105.232.0 - 198.105.235.255 +Microsoft Corp MICROSOFT19-NET58 (NET-204-231-58-0-1) 204.231.58.0 - 204.231.58.255 +Microsoft Corp MICROSOFT15 (NET-204-140-77-0-1) 204.140.77.0 - 204.140.77.255 +Microsoft Corp MICROSOFT16 (NET-204-140-80-0-1) 204.140.80.0 - 204.140.83.255 +Microsoft Corp MICROSOFT-CORP-MSN-1 (NET-199-60-28-0-1) 199.60.28.0 - 199.60.28.255 +Microsoft Corp MICROSOFT-1 (NET-199-103-90-0-1) 199.103.90.0 - 199.103.91.255 +Microsoft Corp MICROSOFT-CORP-MSN-3 (NET-199-103-122-0-1) 199.103.122.0 - 199.103.122.255 +Microsoft Corp MICROSOFT8 (NET-204-79-101-0-1) 204.79.101.0 - 204.79.101.255 +Microsoft Corp MICROSOFT18 (NET-192-237-67-0-1) 192.237.67.0 - 192.237.67.255 +Microsoft Corp MICROSOFT19 (NET-198-137-97-0-1) 198.137.97.0 - 198.137.97.255 +Microsoft Corp MICROSOFT-HK (NET-204-79-135-0-1) 204.79.135.0 - 204.79.135.255 +Microsoft Corp MICROSOFT-PLACEWARE-1 (NET-204-79-179-0-1) 204.79.179.0 - 204.79.179.255 +Microsoft Corp MICROSOFT11 (NET-204-79-180-0-1) 204.79.180.0 - 204.79.181.255 +Microsoft Corp MICROSOFT-PLACEWARE-2 (NET-204-79-188-0-1) 204.79.188.0 - 204.79.188.255 +Microsoft Corp MICROSOFT13 (NET-204-79-195-0-1) 204.79.195.0 - 204.79.197.255 +Microsoft Corp MICROSOFT17 (NET-199-6-92-0-1) 199.6.92.0 - 199.6.94.255 +Microsoft Corp MICROSOFT-2 (NET-204-79-7-0-1) 204.79.7.0 - 204.79.7.255 +Microsoft Corp MICROSOFT-NET1 (NET-204-79-27-0-1) 204.79.27.0 - 204.79.27.255 +Microsoft Corp MICROSOFT2 (NET-198-180-74-0-1) 198.180.74.0 - 198.180.75.255 +Microsoft Corp MICROSOFT3 (NET-198-180-95-0-1) 198.180.95.0 - 198.180.97.255 +Microsoft Corp MICROSOFT28 (NET-204-231-236-0-1) 204.231.236.0 - 204.231.236.255 +Microsoft Corp MICROSOFT29 (NET-205-248-10-0-1) 205.248.10.0 - 205.248.15.255 +Microsoft Corp SPRINT-CDA33F (NET-205-163-63-0-1) 205.163.63.0 - 205.163.63.255 +Microsoft Corp SPRINT-CDA33E (NET-205-163-62-0-1) 205.163.62.0 - 205.163.62.255 +Microsoft Corp SPRINT-CDA39F (NET-205-163-144-0-1) 205.163.144.0 - 205.163.159.255 +Microsoft Corp MICROSOFT30 (NET-205-248-41-0-1) 205.248.41.0 - 205.248.43.255 +Microsoft Corp MICROSOFT31 (NET-205-248-50-0-1) 205.248.50.0 - 205.248.51.255 +Microsoft Corp MICROSOFT32 (NET-205-248-61-0-1) 205.248.61.0 - 205.248.63.255 +Microsoft Corp MICROSOFT34 (NET-205-248-72-0-1) 205.248.72.0 - 205.248.72.255 +Microsoft Corp MICROSOFT35 (NET-205-248-212-0-1) 205.248.212.0 - 205.248.215.255 +Microsoft Corp MICROSOFT36 (NET-205-248-228-0-1) 205.248.228.0 - 205.248.228.255 +Microsoft Corp MICROSOFT37 (NET-205-248-235-0-1) 205.248.235.0 - 205.248.235.255 +Microsoft Corp MICROSOFT20 (NET-204-231-76-0-1) 204.231.76.0 - 204.231.76.255 +Microsoft Corp MICROSOFT26 (NET-204-231-192-0-1) 204.231.192.0 - 204.231.192.255 +Microsoft Corp MICROSOFT27 (NET-204-231-194-0-1) 204.231.194.0 - 204.231.223.255 +Microsoft Corp SOCRATIC (NET-207-78-80-0-1) 207.78.80.0 - 207.78.80.255 +Microsoft Corp DAVELADD (NET-207-78-81-0-1) 207.78.81.0 - 207.78.81.255 +Microsoft Corp RSEGAL (NET-207-78-82-0-1) 207.78.82.0 - 207.78.82.255 +Microsoft Corp MICROSOFT44 (NET-205-248-243-0-1) 205.248.243.0 - 205.248.244.255 +Microsoft Corp MICROSOFT48 (NET-207-117-3-0-1) 207.117.3.0 - 207.117.3.255 +Microsoft Corp UU-207-18-117 (NET-207-18-117-0-1) 207.18.117.0 - 207.18.117.255 +Microsoft Corp CW-208-139-27-B (NET-208-139-27-0-1) 208.139.27.0 - 208.139.27.255 +Microsoft Corp MICROSOFT55 (NET-209-28-213-0-1) 209.28.213.0 - 209.28.213.255 +Microsoft Corp MICROSOFT50 (NET-207-209-68-0-1) 207.209.68.0 - 207.209.68.255 +Microsoft Corp SPRINT-CC5F6F (NET-204-95-96-0-1) 204.95.96.0 - 204.95.111.255 +Microsoft Corp CYBR-LCCLAB (NET-207-158-93-192-1) 207.158.93.192 - 207.158.93.223 +Microsoft Corp MSBPN-2 (NET-207-240-123-192-1) 207.240.123.192 - 207.240.123.223 +Microsoft Corp SPRINT-D01ACD (NET-208-26-205-0-1) 208.26.205.0 - 208.26.205.255 +Microsoft Corp MICROSOFT-CORP-MSN-2 (NET-192-197-157-0-1) 192.197.157.0 - 192.197.157.255 +Microsoft Corp MICROSOFTDENVER (NET-204-133-231-0-1) 204.133.231.0 - 204.133.231.255 +Microsoft Corp MICROSOFTG1-COM (NET-216-72-96-0-1) 216.72.96.0 - 216.72.99.255 +Microsoft Corp EACT-CUST-JLEZNEK (NET-207-229-166-152-1) 207.229.166.152 - 207.229.166.159 +Microsoft Corp SPRINT-CC5F95-8 (NET-204-95-149-0-1) 204.95.149.0 - 204.95.149.255 +Microsoft Corp NET-CSAMSI (NET-209-192-213-72-1) 209.192.213.72 - 209.192.213.79 +Microsoft Corp MICROSOFT57 (NET-206-73-203-0-1) 206.73.203.0 - 206.73.203.255 +Microsoft Corp MICROSOFT56 (NET-206-73-118-0-1) 206.73.118.0 - 206.73.118.255 +Microsoft Corp QWEST-208-45-54-16 (NET-208-45-54-16-1) 208.45.54.16 - 208.45.54.23 +Microsoft Corp QWEST-208-45-54-8 (NET-208-45-54-8-1) 208.45.54.8 - 208.45.54.15 +Microsoft Corp MICROSOFT58 (NET-206-73-31-0-1) 206.73.31.0 - 206.73.31.255 +Microsoft Corp SPRINT-3FA132 (NET-63-161-50-128-1) 63.161.50.128 - 63.161.50.255 +Microsoft Corp SPRINT-3FA132-6 (NET-63-161-50-0-1) 63.161.50.0 - 63.161.50.127 +Microsoft Corp MICROSOFT-8-18 (NET-207-240-8-224-1) 207.240.8.224 - 207.240.8.239 +Microsoft Corp MICROSOFT-BBLK (NET-157-54-0-0-1) 157.54.0.0 - 157.60.255.255 +Microsoft Corp QWEST-208-45-89-248A (NET-208-45-89-248-1) 208.45.89.248 - 208.45.89.255 +Microsoft Corp MICROSOFT61 (NET-206-182-69-0-1) 206.182.69.0 - 206.182.69.255 +Microsoft Corp MICROSOFT63 (NET-206-182-240-0-1) 206.182.240.0 - 206.182.240.255 +Microsoft Corp MICROSOFT64 (NET-206-182-241-0-1) 206.182.241.0 - 206.182.241.255 +Microsoft Corp MICROSOFT59 (NET-206-73-67-0-1) 206.73.67.0 - 206.73.67.255 +Microsoft Corp MICROSOFT66 (NET-206-182-251-0-1) 206.182.251.0 - 206.182.251.255 +Microsoft Corp MICROSOFT65 (NET-206-182-247-0-1) 206.182.247.0 - 206.182.247.255 +Microsoft Corp MICROSOFT62 (NET-206-182-236-0-1) 206.182.236.0 - 206.182.236.255 +Microsoft Corp QWEST-63-236-198-64 (NET-63-236-198-64-1) 63.236.198.64 - 63.236.198.71 +Microsoft Corp QWEST-63-236-198-152 (NET-63-236-198-152-1) 63.236.198.152 - 63.236.198.159 +Microsoft Corp ERMS-6799349 (NET-165-121-253-232-1) 165.121.253.232 - 165.121.253.239 +Microsoft Corp QWEST-63-236-170-64 (NET-63-236-170-64-1) 63.236.170.64 - 63.236.170.71 +Microsoft Corp QWEST-63-236-186-64 (NET-63-236-186-64-1) 63.236.186.64 - 63.236.186.71 +Microsoft Corp QWEST-63-236-187-104 (NET-63-236-187-104-1) 63.236.187.104 - 63.236.187.111 +Microsoft Corp QWEST-63-236-187-128 (NET-63-236-187-128-1) 63.236.187.128 - 63.236.187.135 +Microsoft Corp QWEST-63-236-187-160 (NET-63-236-187-160-1) 63.236.187.160 - 63.236.187.167 +Microsoft Corp FON-3338832128690 (NET-199-2-137-0-1) 199.2.137.0 - 199.2.137.255 +Microsoft Corp CUST-86-24614 (NET-216-222-104-224-1) 216.222.104.224 - 216.222.104.239 +Microsoft Corp QWEST-63-151-87-64 (NET-63-151-87-64-1) 63.151.87.64 - 63.151.87.71 +Microsoft Corp HP-64-77-82-96 (NET-64-77-82-96-1) 64.77.82.96 - 64.77.82.103 +Microsoft Corp HP-64-77-93-80 (NET-64-77-93-80-1) 64.77.93.80 - 64.77.93.95 +Microsoft Corp MICROSOFT-1BLK (NET-65-52-0-0-1) 65.52.0.0 - 65.55.255.255 +Microsoft Corp MICROSOFT-GLOBAL-NET (NET-207-46-0-0-1) 207.46.0.0 - 207.46.255.255 +Microsoft Corp MICROSOFT-CORP-MSN-BLK (NET-207-68-128-0-1) 207.68.128.0 - 207.68.207.255 +Microsoft Corp FON-343451648081865 (NET-204-182-144-0-1) 204.182.144.0 - 204.182.159.255 +Microsoft Corp FON-346312755281299 (NET-206-107-34-0-1) 206.107.34.0 - 206.107.34.255 +Microsoft Corp FON-34550983681918 (NET-205-240-158-0-1) 205.240.158.0 - 205.240.159.255 +Microsoft Corp MICROSOFT-PLACEWARE-2 (NET-204-79-252-0-1) 204.79.252.0 - 204.79.252.255 +Microsoft Corp WLCO-TWC1057147-MICROSOFT (NET-64-200-211-16-1) 64.200.211.16 - 64.200.211.31 +Microsoft Corp MICROSOF81-163-0 (NET-12-178-163-0-1) 12.178.163.0 - 12.178.163.31 +Microsoft Corp WLCO-TWC1057147-MICROSOFT-1 (NET-69-44-126-80-1) 69.44.126.80 - 69.44.126.95 +Microsoft Corp SPRINTLINK (NET-63-173-42-128-1) 63.173.42.128 - 63.173.42.255 +Microsoft Corp MICROSOF33-108-0 (NET-12-28-108-0-1) 12.28.108.0 - 12.28.108.127 +Microsoft Corp SPRINTLINK (NET-65-170-29-0-1) 65.170.29.0 - 65.170.29.7 +Microsoft Corp Q0903-67-132-133-96 (NET-67-132-133-96-1) 67.132.133.96 - 67.132.133.103 +Microsoft Corp MICROSOFT-IPV6-BLK (NET6-2001-4898-1) 2001:4898:0000:0000:0000:0000:0000:0000 - 2001:4898:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF +Microsoft Corp LVLT-MSFT-8-6-176 (NET-8-6-176-0-1) 8.6.176.0 - 8.6.176.255 +Microsoft Corp MICROSOFT33 (NET-205-248-80-0-1) 205.248.80.0 - 205.248.129.255 +Microsoft Corp Q0523-63-148-123-240 (NET-63-148-123-240-1) 63.148.123.240 - 63.148.123.247 +Microsoft Corp SAVV-S233608-1 (NET-64-41-193-0-1) 64.41.193.0 - 64.41.193.255 +Microsoft Corp SAVV-S233053-1 (NET-64-85-70-32-1) 64.85.70.32 - 64.85.70.47 +Microsoft Corp SAVV-S233053-2 (NET-64-85-81-96-1) 64.85.81.96 - 64.85.81.103 +Microsoft Corp SAVV-S233053-3 (NET-64-85-81-104-1) 64.85.81.104 - 64.85.81.111 +Microsoft Corp SAVV-S233053-7 (NET-216-32-168-224-1) 216.32.168.224 - 216.32.168.255 +Microsoft Corp SAVV-S233053-6 (NET-206-79-74-32-1) 206.79.74.32 - 206.79.74.47 +Microsoft Corp SAVV-S233053-8 (NET-216-32-175-224-1) 216.32.175.224 - 216.32.175.255 +Microsoft Corp SAVV-S233053-9 (NET-216-32-180-0-1) 216.32.180.0 - 216.32.183.255 +Microsoft Corp SAVV-S233053-11 (NET-216-33-229-224-1) 216.33.229.224 - 216.33.229.255 +Microsoft Corp SAVV-S233053-12 (NET-216-33-236-0-1) 216.33.236.0 - 216.33.239.255 +Microsoft Corp SAVV-S233053-13 (NET-216-33-240-0-1) 216.33.240.0 - 216.33.243.255 +Microsoft Corp SAVV-S233053-10 (NET-216-32-240-0-1) 216.32.240.0 - 216.32.243.255 +Microsoft Corp SAVV-S233608-3 (NET-216-34-51-0-1) 216.34.51.0 - 216.34.51.255 +Microsoft Corp SAVV-S233053-4 (NET-209-1-112-0-1) 209.1.112.0 - 209.1.112.255 +Microsoft Corp SAVV-S233053-5 (NET-209-1-113-0-1) 209.1.113.0 - 209.1.113.255 +Microsoft Corp SAVV-S233608-2 (NET-209-1-15-0-1) 209.1.15.0 - 209.1.15.255 +Microsoft Corp SAVV-S233608-4 (NET-216-34-53-176-1) 216.34.53.176 - 216.34.53.191 +Microsoft Corp SAVV-S233608-5 (NET-216-35-8-224-1) 216.35.8.224 - 216.35.8.239 +Microsoft Corp SAVV-S233053-14 (NET-209-185-128-0-1) 209.185.128.0 - 209.185.131.255 +Microsoft Corp Q0112-65-114-175-128 (NET-65-114-175-128-1) 65.114.175.128 - 65.114.175.159 +Microsoft Corp SAVV-S233053-15 (NET-64-15-229-96-1) 64.15.229.96 - 64.15.229.127 +Microsoft Corp SAVV-S233050-5 (NET-64-15-177-0-1) 64.15.177.0 - 64.15.177.255 +Microsoft Corp SAVV-S233050-4 (NET-64-15-170-192-1) 64.15.170.192 - 64.15.170.199 +Microsoft Corp SAVV-S233050-2 (NET-209-143-238-0-1) 209.143.238.0 - 209.143.238.255 +Microsoft Corp SAVV-S233050-6 (NET-64-15-178-0-1) 64.15.178.0 - 64.15.178.255 +Microsoft Corp SAVV-S232995-2 (NET-66-35-209-120-1) 66.35.209.120 - 66.35.209.127 +Microsoft Corp SAVV-S232995-3 (NET-66-35-211-128-1) 66.35.211.128 - 66.35.211.191 +Microsoft Corp SAVV-S232995-1 (NET-66-35-208-48-1) 66.35.208.48 - 66.35.208.63 +Microsoft Corp SAVV-S233053-16 (NET-216-33-148-0-1) 216.33.148.0 - 216.33.151.255 +Microsoft Corp., MSN Operations SAVV-S233052-4 (NET-216-35-66-88-1) 216.35.66.88 - 216.35.66.95 +MICROSOFT CORPORATION MICROSOF32-32-160 (NET-12-230-32-160-1) 12.230.32.160 - 12.230.32.167 +MICROSOFT CORPORATION MICROSOF43-124-0 (NET-12-53-124-0-1) 12.53.124.0 - 12.53.124.31 +MICROSOFT CORPORATION MICROSOF82-18-96 (NET-12-232-18-96-1) 12.232.18.96 - 12.232.18.127 +MICROSOFT CORPORATION MICROSOF25-158 (NET-12-190-158-0-1) 12.190.158.0 - 12.190.158.255 +MICROSOFT CORPORATION MICROSOF61-196-32 (NET-12-71-196-32-1) 12.71.196.32 - 12.71.196.47 +Microsoft Corporation MICROSOFT-ONLINE-SERVICES (NET-209-240-192-0-1) 209.240.192.0 - 209.240.223.255 +Microsoft Corporation MICROSOFT-DYNAMIC-HOSTING (NET-70-37-0-0-1) 70.37.0.0 - 70.37.191.255 +Microsoft Corporation MS-ONLINE-SERVICES-NJ (NET-70-37-128-0-1) 70.37.128.0 - 70.37.129.255 +Microsoft Corporation MS-GLOBAL-ONLINE-SERVICES (NET-70-37-135-0-1) 70.37.135.0 - 70.37.135.255 +MICROSOFT CORPORATION MICROSOF82-87-192 (NET-12-49-87-192-1) 12.49.87.192 - 12.49.87.255 +Microsoft MICROSOFT (NET-74-93-205-144-1) 74.93.205.144 - 74.93.205.151 +Microsoft MICROSOFT (NET-74-93-205-152-1) 74.93.205.152 - 74.93.205.159 +Microsoft MICROSOFT (NET-74-93-206-64-1) 74.93.206.64 - 74.93.206.71 +Microsoft MICROSOFT (NET-70-89-139-120-1) 70.89.139.120 - 70.89.139.127 +Microsoft DIRECP-NET1-206-71-11 (NET-206-71-119-0-1) 206.71.119.0 - 206.71.119.255 +Microsoft DIRECP-NET1-117 (NET-206-71-117-0-1) 206.71.117.0 - 206.71.117.255 +Microsoft DIRECP-NET1-118 (NET-206-71-118-0-1) 206.71.118.0 - 206.71.118.255 +Microsoft UUHIL-BLK1-C155-112 (NET-209-154-155-112-1) 209.154.155.112 - 209.154.155.119 +Microsoft SBCIS-101411-164355 (NET-65-68-62-152-1) 65.68.62.152 - 65.68.62.159 +MICROSOFT SBC067039208168020503 (NET-67-39-208-168-1) 67.39.208.168 - 67.39.208.175 +Microsoft UU-65-242-67 (NET-65-242-67-0-1) 65.242.67.0 - 65.242.67.255 +Microsoft CW-204-71-191-0 (NET-204-71-191-0-1) 204.71.191.0 - 204.71.191.255 +Microsoft SBC063194155144021023 (NET-63-194-155-144-1) 63.194.155.144 - 63.194.155.151 +Microsoft SBC066136085192030113 (NET-66-136-85-192-1) 66.136.85.192 - 66.136.85.199 +MICROSOFT MFN-T280-64-124-184-72-29 (NET-64-124-184-72-1) 64.124.184.72 - 64.124.184.79 +MICROSOFT MFN-T133-216-200-206-0-24 (NET-216-200-206-0-1) 216.200.206.0 - 216.200.206.255 +Microsoft UU-63-80-93-D4 (NET-63-80-93-0-1) 63.80.93.0 - 63.80.93.127 +Microsoft RSPC-1218167167199384 (NET-67-192-225-208-1) 67.192.225.208 - 67.192.225.223 +Microsoft CVNET-454AA20 (NET-69-74-162-0-1) 69.74.162.0 - 69.74.162.255 +Microsoft UU-65-221-5 (NET-65-221-5-0-1) 65.221.5.0 - 65.221.5.255 +Microsoft - Partner Campaign Builder (PCB) MICROSOFT-PARTNER-CAMPAIGN-BUILDER-PCB (NET-216-182-89-192-1) 216.182.89.192 - 216.182.89.207 +Microsoft - Partner Campaign Builder (PCB) MICROSOFT-PARTNER-CAMPAIGN-BUILDER-PCB (NET-216-182-89-48-1) 216.182.89.48 - 216.182.89.63 +MICROSOFT AUSTIN-STO UU-65-248-85-D4 (NET-65-248-85-0-1) 65.248.85.0 - 65.248.85.255 +Microsoft Canada MIC0923-CA (NET-199-243-157-192-1) 199.243.157.192 - 199.243.157.223 +Microsoft Canada MIC0702-CA (NET-199-243-157-112-1) 199.243.157.112 - 199.243.157.119 +Microsoft Corp UU-65-194-210-224 (NET-65-194-210-224-1) 65.194.210.224 - 65.194.210.255 +Microsoft Corp UU-208-194-139 (NET-208-194-139-0-1) 208.194.139.0 - 208.194.139.255 +Microsoft Corp UU-208-204-49-128-B (NET-208-204-49-128-1) 208.204.49.128 - 208.204.49.255 +Microsoft Corp UU-208-205-26 (NET-208-205-26-0-1) 208.205.26.0 - 208.205.26.255 +Microsoft Corp UU-208-217-184-D1 (NET-208-217-184-0-1) 208.217.184.0 - 208.217.187.255 +Microsoft Corp UU-208-222-172 (NET-208-222-172-0-1) 208.222.172.0 - 208.222.172.255 +Microsoft Corp UU-208-224-200-64 (NET-208-224-200-64-1) 208.224.200.64 - 208.224.200.95 +Microsoft Corp UU-208-229-100-D1 (NET-208-229-100-0-1) 208.229.100.0 - 208.229.101.255 +Microsoft Corp UU-208-241-19 (NET-208-241-19-0-1) 208.241.19.0 - 208.241.19.15 +Microsoft Corp UU-208-241-19-16 (NET-208-241-19-16-1) 208.241.19.16 - 208.241.19.31 +Microsoft Corp UU-208-241-9-224 (NET-208-241-9-224-1) 208.241.9.224 - 208.241.9.239 +Microsoft Corp UU-208-244-108-D2 (NET-208-244-108-0-1) 208.244.108.0 - 208.244.108.15 +Microsoft Corp UU-208-245-16 (NET-208-245-16-0-1) 208.245.16.0 - 208.245.16.31 +Microsoft Corp UU-208-249-17-160 (NET-208-249-17-160-1) 208.249.17.160 - 208.249.17.175 +Microsoft Corp UU-63-104-216-D2 (NET-63-104-216-0-1) 63.104.216.0 - 63.104.216.127 +Microsoft Corp UU-63-69-245 (NET-63-69-245-0-1) 63.69.245.0 - 63.69.245.255 +Microsoft Corp SBC068090141072031030 (NET-68-90-141-72-1) 68.90.141.72 - 68.90.141.79 +Microsoft Corp 10825385 SBC06319812316029040317151513 (NET-63-198-123-160-1) 63.198.123.160 - 63.198.123.167 +MICROSOFT CORP-040821020257 SBC06824804806429040821020303 (NET-68-248-48-64-1) 68.248.48.64 - 68.248.48.71 +MICROSOFT CORP-040821020338 SBC06824804807229040821020347 (NET-68-248-48-72-1) 68.248.48.72 - 68.248.48.79 +MICROSOFT CORP-081024181821 SBC-99-49-8-248-29-0810241850 (NET-99-49-8-248-1) 99.49.8.248 - 99.49.8.255 +Microsoft Corp. HUGE-65-38-172-72-29 (NET-65-38-172-72-1) 65.38.172.72 - 65.38.172.79 +Microsoft Corp. HUGE-65-38-172-96-28 (NET-65-38-172-96-1) 65.38.172.96 - 65.38.172.111 +Microsoft Corporation MICROSOFT-CORPORATION (NET-75-149-174-16-1) 75.149.174.16 - 75.149.174.23 +Microsoft Corporation MICROSOFT-CORPORATION (NET-75-151-100-240-1) 75.151.100.240 - 75.151.100.255 +Microsoft Corporation SPEK-647057-0 (NET-64-81-8-96-1) 64.81.8.96 - 64.81.8.127 +Microsoft Corporation SBC067112255144030130 (NET-67-112-255-144-1) 67.112.255.144 - 67.112.255.151 +Microsoft Corporation ATTENS-010075-004522 (NET-63-240-201-176-1) 63.240.201.176 - 63.240.201.191 +Microsoft Corporation ATTENS-010075-004523 (NET-206-16-209-208-1) 206.16.209.208 - 206.16.209.223 +Microsoft Corporation ATTENS-010075-004525 (NET-63-240-195-208-1) 63.240.195.208 - 63.240.195.223 +Microsoft Corporation ATTENS-010075-004526 (NET-206-16-204-64-1) 206.16.204.64 - 206.16.204.79 +Microsoft Corporation ATTENS-010075-004450 (NET-206-16-223-0-1) 206.16.223.0 - 206.16.223.255 +Microsoft Corporation ATTENS-010075-005028 (NET-63-240-216-0-1) 63.240.216.0 - 63.240.219.255 +Microsoft Corporation ATTENS-010075-005057 (NET-63-240-220-0-1) 63.240.220.0 - 63.240.223.255 +Microsoft Corporation ATTENS-010075-005135 (NET-206-16-246-24-1) 206.16.246.24 - 206.16.246.31 +Microsoft Corporation ATTENS-010075-004524 (NET-63-240-195-192-1) 63.240.195.192 - 63.240.195.207 +Microsoft Corporation ATTENS-010075-005880 (NET-206-16-224-160-1) 206.16.224.160 - 206.16.224.191 +Microsoft Corporation (managed segment) RSPC-1229444888833780 (NET-98-129-187-144-1) 98.129.187.144 - 98.129.187.151 +Microsoft Corporation - Secure Dimensions ( RSPC-33955-12072007 (NET-67-192-39-48-1) 67.192.39.48 - 67.192.39.63 +Microsoft Corporation - Whale RSPC-108457-1170047010 (NET-72-32-240-160-1) 72.32.240.160 - 72.32.240.175 +Microsoft Corporation - Whale RSPC-108456-1173386392 (NET-72-32-201-152-1) 72.32.201.152 - 72.32.201.159 +MICROSOFT CROP SBC067039081152020503 (NET-67-39-81-152-1) 67.39.81.152 - 67.39.81.159 +Microsoft Education Programs RSPC-48725-1096578571 (NET-69-20-127-32-1) 69.20.127.32 - 69.20.127.39 +Microsoft License PNAP-SFJ-MSLI-RM-01 (NET-216-52-28-0-1) 216.52.28.0 - 216.52.28.255 +Microsoft License INAP-PHX003-MSLICENSE-25271 (NET-70-42-230-0-1) 70.42.230.0 - 70.42.231.255 +Microsoft License INAP-SFJ-MSLICENSE-13982 (NET-63-251-97-0-1) 63.251.97.0 - 63.251.97.255 +Microsoft Licensing SBC067120132128020815 (NET-67-120-132-128-1) 67.120.132.128 - 67.120.132.135 +Microsoft Licensing SBC067120132152020815 (NET-67-120-132-152-1) 67.120.132.152 - 67.120.132.159 +Microsoft Licensing SBC067120132192020816 (NET-67-120-132-192-1) 67.120.132.192 - 67.120.132.207 +Microsoft Licensing SBC0671201322080208 diff --git a/contrib/ipfilter/test/regress/p7.nat b/contrib/ipfilter/test/regress/p7.nat new file mode 100644 index 000000000000..3c3fa7c1874f --- /dev/null +++ b/contrib/ipfilter/test/regress/p7.nat @@ -0,0 +1 @@ +rewrite in on bge0 proto tcp from any to any port = 80 -> src 0/0 dst dstlist/servers; diff --git a/contrib/ipfilter/test/regress/p7.pool b/contrib/ipfilter/test/regress/p7.pool new file mode 100644 index 000000000000..451b374dfd1f --- /dev/null +++ b/contrib/ipfilter/test/regress/p7.pool @@ -0,0 +1,2 @@ +pool nat/dstlist (name servers; policy weighted connection;) + { 1.1.1.2; 1.1.1.4; 1.1.1.5; 1.1.1.9; }; diff --git a/contrib/ipfilter/test/regress/p9.nat b/contrib/ipfilter/test/regress/p9.nat new file mode 100644 index 000000000000..3c3fa7c1874f --- /dev/null +++ b/contrib/ipfilter/test/regress/p9.nat @@ -0,0 +1 @@ +rewrite in on bge0 proto tcp from any to any port = 80 -> src 0/0 dst dstlist/servers; diff --git a/contrib/ipfilter/test/regress/p9.pool b/contrib/ipfilter/test/regress/p9.pool new file mode 100644 index 000000000000..c452ffc681b6 --- /dev/null +++ b/contrib/ipfilter/test/regress/p9.pool @@ -0,0 +1,2 @@ +pool nat/dstlist (name servers; policy round-robin;) + { 1.1.1.2; 1.1.1.4; 1.1.1.5; 1.1.1.9; }; diff --git a/contrib/ipfilter/test/test.format b/contrib/ipfilter/test/test.format index dfc3f35b619a..64f7d9b3202c 100644 --- a/contrib/ipfilter/test/test.format +++ b/contrib/ipfilter/test/test.format @@ -1,6 +1,6 @@ -#test input-format output-format +#test input-format output-format options bpf-f1 text text -bpf1 text ipf +bpf1 text text f1 text text f2 text text f3 text text @@ -18,9 +18,11 @@ f14 text text f15 text text f16 text text f17 hex hex -f18 text text -f19 text text fr_statemax=3 +f18 text text -D +f19 text text state_max=3 f20 text text +f21 hex text +f22 hex text i1 text ipf i2 text ipf i3 text ipf @@ -42,17 +44,26 @@ i18 text ipf i19 text ipf i20 text ipf i21 text ipf +i22 text ipf +i23 text ipf in1 text text in2 text text in3 text text in4 text text in5 text text in6 text text +in7 text text +in8 text text +in100 text text +in101 text text +in102 text text ip1 text text ip2 text text +ip3 text text ipv6.1 hex hex ipv6.2 hex hex ipv6.3 hex hex +ipv6.4 hex hex ipv6.5 hex hex l1 hex hex n1 text text @@ -62,31 +73,40 @@ n4 text text n5 text text n6 text text n7 text text -n8 hex hex fr_update_ipid=0 -n9 hex hex fr_update_ipid=0 -n10 hex hex fr_update_ipid=0 +n8 hex hex update_ipid=0 +n9 hex hex update_ipid=0 +n10 hex hex update_ipid=0 n11 text text -n12 hex hex fr_update_ipid=0 -n13 text text -n14 text text -ni1 hex hex fr_update_ipid=1 -ni2 hex hex fr_update_ipid=1 -ni3 hex hex fr_update_ipid=1 -ni4 hex hex fr_update_ipid=1 -ni5 hex hex fr_update_ipid=1 -ni6 hex hex fr_update_ipid=1 -ni7 hex hex fr_update_ipid=1 -ni8 hex hex fr_update_ipid=1 -ni9 hex hex fr_update_ipid=1 -ni10 hex hex fr_update_ipid=1 -ni11 hex hex fr_update_ipid=1 -ni12 hex hex fr_update_ipid=1 -ni13 hex hex fr_update_ipid=1 -ni14 hex hex fr_update_ipid=1 -ni15 hex hex fr_update_ipid=1 -ni16 hex hex fr_update_ipid=1 -ni19 hex hex fr_update_ipid=0 -ni20 hex hex fr_update_ipid=0 +n12 hex hex update_ipid=0 -v +n15 text text update_ipid=0 +n100 text text +n101 text text +n102 text text +n103 text text +n104 hex hex update_ipid=0 +n105 hex hex update_ipid=0 +n106 hex hex update_ipid=0 +n200 hex hex update_ipid=0 +ni1 hex hex update_ipid=1 +ni2 hex hex update_ipid=1 +ni3 hex hex update_ipid=1 +ni4 hex hex update_ipid=1 +ni5 hex hex update_ipid=1 +ni6 hex text update_ipid=1 -D +ni7 hex hex update_ipid=1 +ni8 hex hex update_ipid=1 +ni9 hex hex update_ipid=1 +ni10 hex hex update_ipid=1 +ni11 hex hex update_ipid=1 +ni12 hex hex update_ipid=1 +ni13 hex hex update_ipid=1 +ni14 hex hex update_ipid=1 +ni15 hex hex update_ipid=1 +ni16 hex hex update_ipid=1 +ni17 text text +ni18 text text +ni19 hex hex update_ipid=0 +ni20 hex hex update_ipid=0 -D ni21 text text ni23 text text -D p1 text text @@ -94,6 +114,35 @@ p2 text text p3 text text p4 text text p5 text text +p6 text text +p7 text text +p9 text text +p10 text text +p11 text text +p12 text text +p13 text text n16 hex hex -D +n17 hex hex -D f24 hex text ipv6.6 hex text +f25 hex text -D +f26 text text +f27 hex text +n1_6 text text -6 +n2_6 text text -6 +n4_6 text text -6 +n5_6 text text -6 +n6_6 text text -6 +n7_6 text text -6 +n8_6 hex hex -6D +n9_6 hex hex -6D +n11_6 text text -6 +n12_6 hex hex -D6 +n15_6 text text -6 +n17_6 hex hex -6 +n13 text text +n14 text text +n18 text text -D +f28 text text +f29 text text +f30 text text diff --git a/contrib/ipfilter/test/vfycksum.pl b/contrib/ipfilter/test/vfycksum.pl index b3a20be0cf24..0272e4b867ce 100755 --- a/contrib/ipfilter/test/vfycksum.pl +++ b/contrib/ipfilter/test/vfycksum.pl @@ -19,82 +19,71 @@ sub dosum { local($lsum) = $seed; for ($idx = $start, $lsum = $seed; $idx < $max; $idx++) { +#printf "%#x += %#x\n", $lsum, $bytes[$idx]; $lsum += $bytes[$idx]; } - $lsum = ($lsum & 0xffff) + ($lsum >> 16); + while ($lsum > 0xffff) { + $lsum = ($lsum & 0xffff) + ($lsum >> 16); + } $lsum = ~$lsum & 0xffff; return $lsum; } -sub ipv4check { - local($base) = $_[0]; - $hl = $bytes[$base] / 256; - return if (($hl >> 4) != 4); # IPv4 ? - $hl &= 0xf; - $hl <<= 1; # get the header length in 16bit words - $hs = &dosum(0, $base, $base + $hl); - $osum = $bytes[$base + 5]; +sub ipv4addrsum { + local($b) = $_[0]; + local($as) = 0; - if ($hs != 0) { - $bytes[$base + 5] = 0; - $hs2 = &dosum(0, $base, $base + $hl); - $bytes[$base + 5] = $osum; - printf " IP: ($hl,%x) %x != %x", $hs, $osum, $hs2; - } else { - print " IP($base): ok "; - } - - # - # Recognise TCP & UDP and calculate checksums for each of these. - # - if (($bytes[$base + 4] & 0xff) == 6) { - &tcpcheck($base); - } - - if (($bytes[$base + 4] & 0xff) == 17) { - &udpcheck($base); - } - - if (($bytes[$base + 4] & 0xff) == 1) { - &icmpcheck($base); - } - if ($base == 0) { - print "\n"; - } + $as += $bytes[$b + 6]; # source address + $as += $bytes[$b + 7]; + $as += $bytes[$b + 8]; # destination address + $as += $bytes[$b + 9]; + return ($as); } -sub tcpcheck { +sub ipv6addrsum { + local($b) = $_[0]; + local($as) = 0; + + $as += $bytes[$b + 4]; # source address + $as += $bytes[$b + 5]; + $as += $bytes[$b + 6]; + $as += $bytes[$b + 7]; + $as += $bytes[$b + 8]; + $as += $bytes[$b + 9]; + $as += $bytes[$b + 10]; + $as += $bytes[$b + 11]; + $as += $bytes[$b + 12]; # destination address + $as += $bytes[$b + 13]; + $as += $bytes[$b + 14]; + $as += $bytes[$b + 15]; + $as += $bytes[$b + 16]; + $as += $bytes[$b + 17]; + $as += $bytes[$b + 18]; + $as += $bytes[$b + 19]; + return ($as); +} + +sub tcpcommon { local($base) = $_[0]; - local($hl) = $bytes[$base] / 256; - return if (($hl >> 4) != 4); - return if ($bytes[$base + 3] & 0x1fff); - $hl &= 0xf; - $hl <<= 1; + local($hl) = $_[1]; + local($hs) = $_[2]; + local($lenoffset) = $_[3]; - local($hs2); - local($hs) = 6; # TCP - local($len) = $bytes[$base + 1] - ($hl << 1); - $hs += $len; - $hs += $bytes[$base + 6]; # source address - $hs += $bytes[$base + 7]; - $hs += $bytes[$base + 8]; # destination address - $hs += $bytes[$base + 9]; - local($tcpsum) = $hs; - - local($thl) = $bytes[$base + $hl + 6] >> 8; + local($thl) = $bytes[$base + $hl + 6]; $thl &= 0xf0; $thl >>= 2; - $x = $bytes[$base + 1]; - $y = ($cnt - $base) * 2; - $z = 0; - if ($bytes[$base + 1] > ($cnt - $base) * 2) { + local($x) = $bytes[$base + $lenoffset]; + local($y) = ($cnt - $base) * 2; + local($z) = 0; + + if ($bytes[$base + $lenoffset] > ($cnt - $base) * 2) { print "[cnt=$cnt base=$base]"; - $x = $bytes[$base + 1]; + $x = $bytes[$base + $lenoffset]; $y = ($cnt - $base) * 2; $z = 1; - } elsif (($cnt - $base) * 2 < $hl + 20) { + } elsif (($cnt - $base) * 2 < $hl + $hl) { $x = ($cnt - $base) * 2; $y = $hl + 20; $z = 2; @@ -106,6 +95,10 @@ sub tcpcheck { $x = ($cnt - $base) * 2; $y = $len; $z = 4; + } elsif (($cnt - $base) * 2 < 20) { + $x = ($cnt - $base) * 2; + $y = $len; + $z = 5; } if ($z) { @@ -115,11 +108,11 @@ sub tcpcheck { } local($tcpat) = $base + $hl; - $hs = &dosum($tcpsum, $tcpat, $cnt); + $hs = &dosum($_[2], $tcpat, $cnt); if ($hs != 0) { local($osum) = $bytes[$tcpat + 8]; $bytes[$base + $hl + 8] = 0; - $hs2 = &dosum($tcpsum, $tcpat, $cnt); + local($hs2) = &dosum($_[2], $tcpat, $cnt); $bytes[$tcpat + 8] = $osum; printf " TCP: (%x) %x != %x", $hs, $osum, $hs2; } else { @@ -127,23 +120,10 @@ sub tcpcheck { } } -sub udpcheck { +sub udpcommon { local($base) = $_[0]; - local($hl) = $bytes[0] / 256; - return if (($hl >> 4) != 4); - return if ($bytes[3] & 0x1fff); - $hl &= 0xf; - $hl <<= 1; - - local($hs2); - local($hs) = 17; # UDP - local($len) = $bytes[$base + 1] - ($hl << 1); - $hs += $len; - $hs += $bytes[$base + 6]; # source address - $hs += $bytes[$base + 7]; - $hs += $bytes[$base + 8]; # destination address - $hs += $bytes[$base + 9]; - local($udpsum) = $hs; + local($hl) = $_[1]; + local($hs) = $_[2]; if ($bytes[$base + 1] > ($cnt - $base) * 2) { print " UDP: missing data(1)"; @@ -168,7 +148,7 @@ sub udpcheck { printf " UDP: => %x", $hs; } elsif ($hs != 0) { $bytes[$udpat + 3] = 0; - $hs2 = &dosum($udpsum, $udpat, $cnt); + local($hs2) = &dosum($udpsum, $udpat, $cnt); $bytes[$udpat + 3] = $osum; printf " UDP: (%x) %x != %x", $hs, $osum, $hs2; } else { @@ -176,6 +156,156 @@ sub udpcheck { } } +sub ipv6check { + local($base) = $_[0]; + $hl = $bytes[$base] / 256; + return if (($hl >> 4) != 6); # IPv4 ? + $hl = 40; + + print " IPv6($base): ok "; + + if (($bytes[$base + 3] >> 8) == 6) { + &tcpcheck6($base); + } elsif (($bytes[$base + 3] >> 8) == 58) { + &icmpcheck6($base); + } + print "\n"; +} + +sub tcpcheck6 { + local($base) = $_[0]; + local($hl) = $bytes[$base] / 256; + return if (($hl >> 4) != 6); + $hl = 20; + + local($hs) = 6; # TCP + local($len) = $bytes[$base + 2]; + $hs += $len; + $hs += &ipv6addrsum($base); + + &tcpcommon($base, $hl, $hs, 2); +} + +sub icmpcheck6 { + local($base) = $_[0]; + local($hl) = 20; + + local($hs) = 58; # ICMP6 + local($len) = $bytes[$base + 2]; + $hs += $len; + $hs += &ipv6addrsum($base); + + local($len) = $bytes[$base + 1] - ($hl << 1); + + if ($bytes[$base + 2] > ($cnt - $base) * 2) { + print " ICMPv6: missing data(1)"; + return; + } elsif ($bytes[$base + 2] < 8) { + print " ICMPv6: missing data(2)"; + return; + } + + local($osum) = $bytes[$base + $hl + 1]; + $bytes[$base + $hl + 1] = 0; + local($hs2) = &dosum($hs, $base + $hl, $cnt); + $bytes[$base + $hl + 1] = $osum; + + if ($osum != $hs2) { + printf " ICMPv6: (%x) %x != %x", $hs, $osum, $hs2; + } else { + print " ICMPv6: ok"; + } +# if ($base == 0) { +# $type = $bytes[$hl] >> 8; +# if ($type == 3 || $type == 4 || $type == 5 || +# $type == 11 || $type == 12) { +# &ipv4check($hl + 4); +# } +# } +} + +sub ipv4check { + local($base) = $_[0]; + $hl = $bytes[$base] / 256; + if (($hl >> 4) == 6) { + &ipv6check($_[0]); + } + return if (($hl >> 4) != 4); # IPv4 ? + $hl &= 0xf; + $hl <<= 1; # get the header length in 16bit words + + $hs = &dosum(0, $base, $base + $hl); + $osum = $bytes[$base + 5]; + + if ($hs != 0) { + $bytes[$base + 5] = 0; + $hs2 = &dosum(0, $base, $base + $hl); + $bytes[$base + 5] = $osum; + printf " IPv4: ($hl,%x) %x != %x", $hs, $osum, $hs2; + } else { + print " IPv4($base): ok "; + } + + # + # Recognise TCP & UDP and calculate checksums for each of these. + # + if (($bytes[$base + 4] & 0xff) == 4) { + &ipv4check($hl); + } + if (($bytes[$base + 4] & 0xff) == 6) { + &tcpcheck($base); + } + + if (($bytes[$base + 4] & 0xff) == 17) { + &udpcheck($base); + } + + if (($bytes[$base + 4] & 0xff) == 1) { + &icmpcheck($base); + } + if ($base == 0) { + print "\n"; + } +} + +sub tcpcheck { + local($base) = $_[0]; + local($hl) = $bytes[$base] / 256; + return if (($hl >> 4) != 4); + if ($bytes[$base + 3] & 0x3fff) { + print " TCP: fragment"; + return; + } + $hl &= 0xf; + $hl <<= 1; + + local($hs) = 6; # TCP + local($len) = $bytes[$base + 1] - ($hl << 1); + $hs += $len; + $hs += &ipv4addrsum($base); + + &tcpcommon($base, $hl, $hs, 1); +} + +sub udpcheck { + local($base) = $_[0]; + local($hl) = $bytes[0] / 256; + return if (($hl >> 4) != 4); + if ($bytes[$base + 3] & 0x3fff) { + print " UDP: fragment"; + return; + } + $hl &= 0xf; + $hl <<= 1; + + local($hs) = 17; # UDP + local($len) = $bytes[$base + 1] - ($hl << 1); + $hs += $len; + $hs += &ipv4addrsum($base); + local($udpsum) = $hs; + &udpcommon($base, $hl, $hs); +} + sub icmpcheck { local($base) = $_[0]; local($hl) = $bytes[$base + 0] / 256; diff --git a/contrib/ipfilter/todo b/contrib/ipfilter/todo index 5b2c05905214..3f558d1f603f 100644 --- a/contrib/ipfilter/todo +++ b/contrib/ipfilter/todo @@ -21,14 +21,6 @@ time permitting: * record buffering for TCP/UDP -* modular application proxying --done - -* allow multiple ip addresses in a source route list for ipsend - -* port IP Filter to Linux -Not in this century. - * document bimap * document NAT rule order processing @@ -56,14 +48,14 @@ I would also love to see a more extensive NAT. It can choose to do rdr and map based on saddr, daddr, sport and dport. (Does the kernel module already have functionality for that and it just needs support in the userland ipnat?) --sort of done +-done - * intrusion detection - detection of port scans + * intrusion detection + detection of port scans detection of multiple connection attempts - + * support for multiple log files - i.e. all connections to ftp and telnet logged to + i.e. all connections to ftp and telnet logged to a seperate log file * multiple levels of log severity with E-mail notification diff --git a/contrib/ipfilter/tools/BNF.ipf b/contrib/ipfilter/tools/BNF.ipf index 0e8433291d1c..0740c5855af9 100644 --- a/contrib/ipfilter/tools/BNF.ipf +++ b/contrib/ipfilter/tools/BNF.ipf @@ -66,7 +66,7 @@ facility = "kern" | "user" | "mail" | "daemon" | "auth" | "syslog" | "audit" | "logalert" | "local0" | "local1" | "local2" | "local3" | "local4" | "local5" | "local6" | "local7" . priority = "emerg" | "alert" | "crit" | "err" | "warn" | "notice" | - "info" | "debug" . + "info" | "debug" . hexnumber = "0" "x" hexstring . hexstring = hexdigit [ hexstring ] . diff --git a/contrib/ipfilter/tools/Makefile b/contrib/ipfilter/tools/Makefile index 43ec1a897b83..ce1ab0e6fc22 100644 --- a/contrib/ipfilter/tools/Makefile +++ b/contrib/ipfilter/tools/Makefile @@ -1,8 +1,5 @@ -# -# Copyright (C) 1993-2001 by Darren Reed. -# -# See the IPFILTER.LICENCE file for details on licencing. -# +YACC=yacc -v + DEST=. all: $(DEST)/ipf_y.c $(DEST)/ipf_y.h $(DEST)/ipf_l.c \ @@ -16,7 +13,7 @@ all: $(DEST)/ipf_y.c $(DEST)/ipf_y.h $(DEST)/ipf_l.c \ $(DEST)/ipf_y.h: $(DEST)/ipf_y.c $(DEST)/ipf_y.c: ipf_y.y - yacc -d ipf_y.y + $(YACC) -d ipf_y.y sed -e 's/yy/ipf_yy/g' -e 's/y.tab.h/ipf_y.c/' \ -e 's/"ipf_y.y"/"..\/tools\/ipf_y.y"/' \ y.tab.c > $(DEST)/ipf_y.c @@ -30,7 +27,7 @@ $(DEST)/ipf_l.c: lexer.c $(DEST)/ipmon_y.n: $(DEST)/ipmon_y.c $(DEST)/ipmon_y.c $(DEST)/ipmon_y.h: ipmon_y.y - yacc -d ipmon_y.y + $(YACC) -d ipmon_y.y sed -e 's/yy/ipmon_yy/g' -e 's/"ipmon_y.y"/"..\/tools\/ipmon_y.y"/' \ y.tab.c > $(DEST)/ipmon_y.c sed -e 's/yy/ipmon_yy/g' y.tab.h > $(DEST)/ipmon_y.h @@ -43,7 +40,7 @@ $(DEST)/ipmon_l.c: lexer.c $(DEST)/ipscan_y.h: $(DEST)/ipscan_y.c $(DEST)/ipscan_y.c $(DEST)/ipscan_y.h: ipscan_y.y - yacc -d ipscan_y.y + $(YACC) -d ipscan_y.y sed -e 's/yy/ipscan_yy/g' \ -e 's/"ipscan_y.y"/"..\/tools\/ipscan_y.y"/' \ y.tab.c > $(DEST)/ipscan_y.c @@ -57,7 +54,7 @@ $(DEST)/ipscan_l.c: lexer.c $(DEST)/ippool_y.h: $(DEST)/ippool_y.c $(DEST)/ippool_y.c $(DEST)/ippool_y.h: ippool_y.y - yacc -d ippool_y.y + $(YACC) -d ippool_y.y sed -e 's/yy/ippool_yy/g' -e 's/"ippool_y.y"/"..\/tools\/ippool_y.y"/' \ y.tab.c > $(DEST)/ippool_y.c sed -e 's/yy/ippool_yy/g' y.tab.h > $(DEST)/ippool_y.h @@ -70,7 +67,7 @@ $(DEST)/ippool_l.c: lexer.c $(DEST)/ipnat_y.h: $(DEST)/ipnat_y.c $(DEST)/ipnat_y.c $(DEST)/ipnat_y.h: ipnat_y.y - yacc -d ipnat_y.y + $(YACC) -d ipnat_y.y sed -e 's/yy/ipnat_yy/g' -e 's/y.tab.c/ipnat_y.c/' \ -e s/\"ipnat_y.y\"/\"..\\/tools\\/ipnat_y.y\"/ \ y.tab.c > $(DEST)/ipnat_y.c diff --git a/contrib/ipfilter/tools/ipf.c b/contrib/ipfilter/tools/ipf.c index fe9fec2581ec..dd601426debd 100644 --- a/contrib/ipfilter/tools/ipf.c +++ b/contrib/ipfilter/tools/ipf.c @@ -1,7 +1,7 @@ /* $FreeBSD$ */ /* - * Copyright (C) 2001-2006 by Darren Reed. + * Copyright (C) 2012 by Darren Reed. * * See the IPFILTER.LICENCE file for details on licencing. */ @@ -16,12 +16,13 @@ #endif #include "ipf.h" #include +#include #include #include "netinet/ipl.h" #if !defined(lint) static const char sccsid[] = "@(#)ipf.c 1.23 6/5/96 (C) 1993-2000 Darren Reed"; -static const char rcsid[] = "@(#)$Id: ipf.c,v 1.35.2.8 2007/05/10 06:12:01 darrenr Exp $"; +static const char rcsid[] = "@(#)$Id$"; #endif #if !defined(__SVR4) && defined(__GNUC__) @@ -40,23 +41,30 @@ int main __P((int, char *[])); int opts = 0; int outputc = 0; int use_inet6 = 0; +int exitstatus = 0; -static void procfile __P((char *, char *)), flushfilter __P((char *)); -static void set_state __P((u_int)), showstats __P((friostat_t *)); -static void packetlogon __P((char *)), swapactive __P((void)); +static void procfile __P((char *)); +static void flushfilter __P((char *, int *)); +static void set_state __P((u_int)); +static void showstats __P((friostat_t *)); +static void packetlogon __P((char *)); +static void swapactive __P((void)); static int opendevice __P((char *, int)); static void closedevice __P((void)); static char *ipfname = IPL_NAME; static void usage __P((void)); static int showversion __P((void)); static int get_flags __P((void)); -static void ipf_interceptadd __P((int, ioctlfunc_t, void *)); +static int ipf_interceptadd __P((int, ioctlfunc_t, void *)); static int fd = -1; static ioctlfunc_t iocfunctions[IPL_LOGSIZE] = { ioctl, ioctl, ioctl, ioctl, ioctl, ioctl, ioctl, ioctl }; +/* XXX The following was added to satisfy a rescue/rescue/ build + XXX requirement. */ +int nohdrfields; static void usage() { @@ -68,25 +76,28 @@ static void usage() int main(argc,argv) -int argc; -char *argv[]; + int argc; + char *argv[]; { - int c; + int c, *filter = NULL; if (argc < 2) usage(); - while ((c = getopt(argc, argv, "6Ac:dDEf:F:Il:noPrRsT:vVyzZ")) != -1) { + assigndefined(getenv("IPF_PREDEFINED")); + + while ((c = getopt(argc, argv, "46Ac:dDEf:F:Il:m:noPrRsT:vVyzZ")) != -1) { switch (c) { case '?' : usage(); break; -#ifdef USE_INET6 + case '4' : + use_inet6 = -1; + break; case '6' : use_inet6 = 1; break; -#endif case 'A' : opts &= ~OPT_INACTIVE; break; @@ -104,10 +115,10 @@ char *argv[]; opts ^= OPT_DEBUG; break; case 'f' : - procfile(argv[0], optarg); + procfile(optarg); break; case 'F' : - flushfilter(optarg); + flushfilter(optarg, filter); break; case 'I' : opts ^= OPT_INACTIVE; @@ -115,8 +126,11 @@ char *argv[]; case 'l' : packetlogon(optarg); break; + case 'm' : + filter = parseipfexpr(optarg, NULL); + break; case 'n' : - opts ^= OPT_DONOTHING; + opts ^= OPT_DONOTHING|OPT_DONTOPEN; break; case 'o' : break; @@ -161,14 +175,14 @@ char *argv[]; if (fd != -1) (void) close(fd); - return(0); + return(exitstatus); /* NOTREACHED */ } static int opendevice(ipfdev, check) -char *ipfdev; -int check; + char *ipfdev; + int check; { if (opts & OPT_DONOTHING) return -2; @@ -184,7 +198,7 @@ int check; if (fd == -1) if ((fd = open(ipfdev, O_RDWR)) == -1) if ((fd = open(ipfdev, O_RDONLY)) == -1) - perror("open device"); + ipferror(fd, "open device"); return fd; } @@ -202,7 +216,7 @@ static int get_flags() if ((opendevice(ipfname, 1) != -2) && (ioctl(fd, SIOCGETFF, &i) == -1)) { - perror("SIOCGETFF"); + ipferror(fd, "SIOCGETFF"); return 0; } return i; @@ -210,22 +224,24 @@ static int get_flags() static void set_state(enable) -u_int enable; + u_int enable; { - if (opendevice(ipfname, 0) != -2) + if (opendevice(ipfname, 0) != -2) { if (ioctl(fd, SIOCFRENB, &enable) == -1) { - if (errno == EBUSY) + if (errno == EBUSY) { fprintf(stderr, "IP FIlter: already initialized\n"); - else - perror("SIOCFRENB"); + } else { + ipferror(fd, "SIOCFRENB"); + } } + } return; } -static void procfile(name, file) -char *name, *file; +static void procfile(file) + char *file; { (void) opendevice(ipfname, 1); @@ -241,20 +257,22 @@ char *name, *file; } -static void ipf_interceptadd(fd, ioctlfunc, ptr) -int fd; -ioctlfunc_t ioctlfunc; -void *ptr; +static int ipf_interceptadd(fd, ioctlfunc, ptr) + int fd; + ioctlfunc_t ioctlfunc; + void *ptr; { if (outputc) printc(ptr); - ipf_addrule(fd, ioctlfunc, ptr); + if (ipf_addrule(fd, ioctlfunc, ptr) != 0) + exitstatus = 1; + return 0; } static void packetlogon(opt) -char *opt; + char *opt; { int flag, xfd, logopt, change = 0; @@ -293,7 +311,7 @@ char *opt; if (change == 1) { if (opendevice(ipfname, 1) != -2 && (ioctl(fd, SIOCSETFF, &flag) != 0)) - perror("ioctl(SIOCSETFF)"); + ipferror(fd, "ioctl(SIOCSETFF)"); } if ((opts & (OPT_DONOTHING|OPT_VERBOSE)) == OPT_VERBOSE) { @@ -308,11 +326,11 @@ char *opt; if (xfd >= 0) { logopt = 0; if (ioctl(xfd, SIOCGETLG, &logopt)) - perror("ioctl(SIOCGETLG)"); + ipferror(fd, "ioctl(SIOCGETLG)"); else { logopt = 1 - logopt; if (ioctl(xfd, SIOCSETLG, &logopt)) - perror("ioctl(SIOCSETLG)"); + ipferror(xfd, "ioctl(SIOCSETLG)"); } close(xfd); } @@ -325,11 +343,11 @@ char *opt; if (xfd >= 0) { logopt = 0; if (ioctl(xfd, SIOCGETLG, &logopt)) - perror("ioctl(SIOCGETLG)"); + ipferror(xfd, "ioctl(SIOCGETLG)"); else { logopt = 1 - logopt; if (ioctl(xfd, SIOCSETLG, &logopt)) - perror("ioctl(SIOCSETLG)"); + ipferror(xfd, "ioctl(SIOCSETLG)"); } close(xfd); } @@ -337,8 +355,9 @@ char *opt; } -static void flushfilter(arg) -char *arg; +static void flushfilter(arg, filter) + char *arg; + int *filter; { int fl = 0, rem; @@ -359,20 +378,33 @@ char *arg; if (!(opts & OPT_DONOTHING)) { if (use_inet6) { - if (ioctl(fd, SIOCIPFL6, &fl) == -1) { - perror("ioctl(SIOCIPFL6)"); - exit(1); + fprintf(stderr, + "IPv6 rules are no longer seperate\n"); + } else if (filter != NULL) { + ipfobj_t obj; + + obj.ipfo_rev = IPFILTER_VERSION; + obj.ipfo_size = filter[0] * sizeof(int); + obj.ipfo_type = IPFOBJ_IPFEXPR; + obj.ipfo_ptr = filter; + if (ioctl(fd, SIOCMATCHFLUSH, &obj) == -1) { + ipferror(fd, "ioctl(SIOCMATCHFLUSH)"); + fl = -1; + } else { + fl = obj.ipfo_retval; } } else { if (ioctl(fd, SIOCIPFFL, &fl) == -1) { - perror("ioctl(SIOCIPFFL)"); + ipferror(fd, "ioctl(SIOCIPFFL)"); exit(1); } } } - if ((opts & (OPT_DONOTHING|OPT_VERBOSE)) == OPT_VERBOSE) { + if ((opts & (OPT_DONOTHING|OPT_DEBUG)) == OPT_DEBUG) { printf("remove flags %s (%d)\n", arg, rem); - printf("removed %d entries\n", fl); + } + if ((opts & (OPT_DONOTHING|OPT_VERBOSE)) == OPT_VERBOSE) { + printf("%d state entries removed\n", fl); } closedevice(); return; @@ -388,7 +420,7 @@ char *arg; perror("open(IPL_AUTH)"); else { if (ioctl(fd, SIOCIPFFA, &fl) == -1) - perror("ioctl(SIOCIPFFA)"); + ipferror(fd, "ioctl(SIOCIPFFA)"); } closedevice(); return; @@ -411,21 +443,23 @@ char *arg; if (!(opts & OPT_DONOTHING)) { if (use_inet6) { if (ioctl(fd, SIOCIPFL6, &fl) == -1) { - perror("ioctl(SIOCIPFL6)"); + ipferror(fd, "ioctl(SIOCIPFL6)"); exit(1); } } else { if (ioctl(fd, SIOCIPFFL, &fl) == -1) { - perror("ioctl(SIOCIPFFL)"); + ipferror(fd, "ioctl(SIOCIPFFL)"); exit(1); } } } - if ((opts & (OPT_DONOTHING|OPT_VERBOSE)) == OPT_VERBOSE) { + if ((opts & (OPT_DONOTHING|OPT_DEBUG)) == OPT_DEBUG) { printf("remove flags %s%s (%d)\n", (rem & FR_INQUE) ? "I" : "", (rem & FR_OUTQUE) ? "O" : "", rem); - printf("removed %d filter rules\n", fl); + } + if ((opts & (OPT_DONOTHING|OPT_VERBOSE)) == OPT_VERBOSE) { + printf("%d filter rules removed\n", fl); } return; } @@ -436,7 +470,7 @@ static void swapactive() int in = 2; if (opendevice(ipfname, 1) != -2 && ioctl(fd, SIOCSWAPA, &in) == -1) - perror("ioctl(SIOCSWAPA)"); + ipferror(fd, "ioctl(SIOCSWAPA)"); else printf("Set %d now inactive\n", in); } @@ -447,7 +481,7 @@ void ipf_frsync() int frsyn = 0; if (opendevice(ipfname, 1) != -2 && ioctl(fd, SIOCFRSYN, &frsyn) == -1) - perror("SIOCFRSYN"); + ipferror(fd, "SIOCFRSYN"); else printf("filter sync'd\n"); } @@ -466,7 +500,7 @@ void zerostats() if (opendevice(ipfname, 1) != -2) { if (ioctl(fd, SIOCFRZST, &obj) == -1) { - perror("ioctl(SIOCFRZST)"); + ipferror(fd, "ioctl(SIOCFRZST)"); exit(-1); } showstats(&fio); @@ -479,7 +513,7 @@ void zerostats() * read the kernel stats for packets blocked and passed */ static void showstats(fp) -friostat_t *fp; + friostat_t *fp; { printf("bad packets:\t\tin %lu\tout %lu\n", fp->f_st[0].fr_bad, fp->f_st[1].fr_bad); @@ -495,9 +529,6 @@ friostat_t *fp; fp->f_st[0].fr_bpkl, fp->f_st[0].fr_ppkl); 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-%lu output %lu-%lu\n", - fp->f_st[0].fr_pkl, fp->f_st[0].fr_skip, - fp->f_st[1].fr_pkl, fp->f_st[1].fr_skip); } @@ -523,7 +554,7 @@ static int showversion() } if (ioctl(vfd, SIOCGETFS, &ipfo)) { - perror("ioctl(SIOCGETFS)"); + ipferror(vfd, "ioctl(SIOCGETFS)"); close(vfd); return 1; } diff --git a/contrib/ipfilter/tools/ipf_y.y b/contrib/ipfilter/tools/ipf_y.y index 82307dec0328..822e9a5ab0ca 100644 --- a/contrib/ipfilter/tools/ipf_y.y +++ b/contrib/ipfilter/tools/ipf_y.y @@ -1,7 +1,7 @@ /* $FreeBSD$ */ /* - * Copyright (C) 2001-2006 by Darren Reed. + * Copyright (C) 2012 by Darren Reed. * * See the IPFILTER.LICENCE file for details on licencing. */ @@ -28,18 +28,29 @@ extern int yydebug; extern FILE *yyin; extern int yylineNum; -static void newrule __P((void)); -static void setipftype __P((void)); -static u_32_t lookuphost __P((char *)); +static int addname __P((frentry_t **, char *)); +static frentry_t *addrule __P((void)); +static frentry_t *allocfr __P((void)); +static void build_dstaddr_af __P((frentry_t *, void *)); +static void build_srcaddr_af __P((frentry_t *, void *)); static void dobpf __P((int, char *)); -static void resetaddr __P((void)); -static struct alist_s *newalist __P((struct alist_s *)); +static void doipfexpr __P((char *)); +static void do_tuneint __P((char *, int)); +static void do_tunestr __P((char *, char *)); +static void fillgroup __P((frentry_t *)); +static int lookuphost __P((char *, i6addr_t *)); static u_int makehash __P((struct alist_s *)); static int makepool __P((struct alist_s *)); -static frentry_t *addrule __P((void)); +static struct alist_s *newalist __P((struct alist_s *)); +static void newrule __P((void)); +static void resetaddr __P((void)); +static void setgroup __P((frentry_t **, char *)); +static void setgrhead __P((frentry_t **, char *)); +static void seticmphead __P((frentry_t **, char *)); +static void setifname __P((frentry_t **, int, char *)); +static void setipftype __P((void)); static void setsyslog __P((void)); static void unsetsyslog __P((void)); -static void fillgroup __P((frentry_t *)); frentry_t *fr = NULL, *frc = NULL, *frtop = NULL, *frold = NULL; @@ -52,52 +63,54 @@ static int nrules = 0; static int newlist = 0; static int added = 0; static int ipffd = -1; -static int *yycont = 0; -static ioctlfunc_t ipfioctl[IPL_LOGSIZE]; +static int *yycont = NULL; +static ioctlfunc_t ipfioctls[IPL_LOGSIZE]; static addfunc_t ipfaddfunc = NULL; -static struct wordtab ipfwords[95]; -static struct wordtab addrwords[4]; -static struct wordtab maskwords[5]; -static struct wordtab icmpcodewords[17]; -static struct wordtab icmptypewords[16]; -static struct wordtab ipv4optwords[25]; -static struct wordtab ipv4secwords[9]; -static struct wordtab ipv6optwords[9]; -static struct wordtab logwords[33]; %} %union { char *str; u_32_t num; - struct in_addr ipa; frentry_t fr; frtuc_t *frt; struct alist_s *alist; u_short port; + struct in_addr ip4; struct { u_short p1; u_short p2; int pc; } pc; - struct { + struct ipp_s { + int type; + int ifpos; + int f; + int v; + int lif; union i6addr a; union i6addr m; + char *name; } ipp; - union i6addr ip6; + struct { + i6addr_t adr; + int f; + } adr; + i6addr_t ip6; struct { char *if1; char *if2; } ifs; + char gname[FR_GROUPLEN]; }; %type portnum %type facility priority icmpcode seclevel secname icmptype %type opt compare range opttype flagset optlist ipv6hdrlist ipv6hdr -%type portc porteq -%type hostname ipv4 ipv4mask ipv4_16 ipv4_24 -%type ipv6mask +%type portc porteq ipmask maskopts +%type ipv4 ipv4_16 ipv4_24 +%type hostname %type addr ipaddr -%type servicename name interfacename +%type servicename name interfacename groupname %type portrange portcomp %type addrlist poollist %type onname @@ -109,30 +122,32 @@ static struct wordtab logwords[33]; %token YY_RANGE_OUT YY_RANGE_IN %token YY_IPV6 +%token IPFY_SET %token IPFY_PASS IPFY_BLOCK IPFY_COUNT IPFY_CALL IPFY_NOMATCH %token IPFY_RETICMP IPFY_RETRST IPFY_RETICMPASDST %token IPFY_IN IPFY_OUT %token IPFY_QUICK IPFY_ON IPFY_OUTVIA IPFY_INVIA %token IPFY_DUPTO IPFY_TO IPFY_FROUTE IPFY_REPLY_TO IPFY_ROUTETO -%token IPFY_TOS IPFY_TTL IPFY_PROTO +%token IPFY_TOS IPFY_TTL IPFY_PROTO IPFY_INET IPFY_INET6 %token IPFY_HEAD IPFY_GROUP %token IPFY_AUTH IPFY_PREAUTH -%token IPFY_LOG IPFY_BODY IPFY_FIRST IPFY_LEVEL IPFY_ORBLOCK -%token IPFY_LOGTAG IPFY_MATCHTAG IPFY_SETTAG IPFY_SKIP +%token IPFY_LOG IPFY_BODY IPFY_FIRST IPFY_LEVEL IPFY_ORBLOCK IPFY_L5AS +%token IPFY_LOGTAG IPFY_MATCHTAG IPFY_SETTAG IPFY_SKIP IPFY_DECAPS %token IPFY_FROM IPFY_ALL IPFY_ANY IPFY_BPFV4 IPFY_BPFV6 IPFY_POOL IPFY_HASH -%token IPFY_PPS +%token IPFY_IPFEXPR IPFY_PPS IPFY_FAMILY IPFY_DSTLIST %token IPFY_ESP IPFY_AH %token IPFY_WITH IPFY_AND IPFY_NOT IPFY_NO IPFY_OPT %token IPFY_TCPUDP IPFY_TCP IPFY_UDP %token IPFY_FLAGS IPFY_MULTICAST %token IPFY_MASK IPFY_BROADCAST IPFY_NETWORK IPFY_NETMASKED IPFY_PEER -%token IPFY_PORT -%token IPFY_NOW +%token IPFY_RPC IPFY_PORT +%token IPFY_NOW IPFY_COMMENT IPFY_RULETTL %token IPFY_ICMP IPFY_ICMPTYPE IPFY_ICMPCODE %token IPFY_IPOPTS IPFY_SHORT IPFY_NAT IPFY_BADSRC IPFY_LOWTTL IPFY_FRAG %token IPFY_MBCAST IPFY_BAD IPFY_BADNAT IPFY_OOW IPFY_NEWISN IPFY_NOICMPERR %token IPFY_KEEP IPFY_STATE IPFY_FRAGS IPFY_LIMIT IPFY_STRICT IPFY_AGE -%token IPFY_SYNC IPFY_FRAGBODY +%token IPFY_SYNC IPFY_FRAGBODY IPFY_ICMPHEAD IPFY_NOLOG IPFY_LOOSE +%token IPFY_MAX_SRCS IPFY_MAX_PER_SRC %token IPFY_IPOPT_NOP IPFY_IPOPT_RR IPFY_IPOPT_ZSU IPFY_IPOPT_MTUP %token IPFY_IPOPT_MTUR IPFY_IPOPT_ENCODE IPFY_IPOPT_TS IPFY_IPOPT_TR %token IPFY_IPOPT_SEC IPFY_IPOPT_LSRR IPFY_IPOPT_ESEC IPFY_IPOPT_CIPSO @@ -140,10 +155,10 @@ static struct wordtab logwords[33]; %token IPFY_IPOPT_IMITD IPFY_IPOPT_EIP IPFY_IPOPT_FINN IPFY_IPOPT_DPS %token IPFY_IPOPT_SDB IPFY_IPOPT_NSAPA IPFY_IPOPT_RTRALRT IPFY_IPOPT_UMP %token IPFY_SECCLASS IPFY_SEC_UNC IPFY_SEC_CONF IPFY_SEC_RSV1 IPFY_SEC_RSV2 -%token IPFY_SEC_RSV4 IPFY_SEC_SEC IPFY_SEC_TS IPFY_SEC_RSV3 +%token IPFY_SEC_RSV4 IPFY_SEC_SEC IPFY_SEC_TS IPFY_SEC_RSV3 IPFY_DOI -%token IPF6_V6HDRS IPFY_IPV6OPT IPFY_IPV6OPT_DSTOPTS IPFY_IPV6OPT_HOPOPTS -%token IPFY_IPV6OPT_IPV6 IPFY_IPV6OPT_NONE IPFY_IPV6OPT_ROUTING +%token IPFY_V6HDRS IPFY_IPV6OPT IPFY_IPV6OPT_DSTOPTS IPFY_IPV6OPT_HOPOPTS +%token IPFY_IPV6OPT_IPV6 IPFY_IPV6OPT_NONE IPFY_IPV6OPT_ROUTING IPFY_V6HDR %token IPFY_IPV6OPT_MOBILITY IPFY_IPV6OPT_ESP IPFY_IPV6OPT_FRAG %token IPFY_ICMPT_UNR IPFY_ICMPT_ECHO IPFY_ICMPT_ECHOR IPFY_ICMPT_SQUENCH @@ -168,16 +183,36 @@ static struct wordtab logwords[33]; %token IPFY_PRI_EMERG IPFY_PRI_ALERT IPFY_PRI_CRIT IPFY_PRI_ERR IPFY_PRI_WARN %token IPFY_PRI_NOTICE IPFY_PRI_INFO IPFY_PRI_DEBUG %% -file: line +file: settings rules + | rules + ; + +settings: + YY_COMMENT + | setting + | settings setting + ; + +rules: line | assign - | file line - | file assign + | rules line + | rules assign + ; + +setting: + IPFY_SET YY_STR YY_NUMBER ';' { do_tuneint($2, $3); } + | IPFY_SET YY_STR YY_HEX ';' { do_tuneint($2, $3); } + | IPFY_SET YY_STR YY_STR ';' { do_tunestr($2, $3); } ; line: rule { while ((fr = frtop) != NULL) { frtop = fr->fr_next; fr->fr_next = NULL; - (*ipfaddfunc)(ipffd, ipfioctl[IPL_LOGIPF], fr); + if ((fr->fr_type == FR_T_IPF) && + (fr->fr_ip.fi_v == 0)) + fr->fr_mip.fi_v = 0; + /* XXX validate ? */ + (*ipfaddfunc)(ipffd, ipfioctls[IPL_LOGIPF], fr); fr->fr_next = frold; frold = fr; } @@ -231,10 +266,37 @@ markout: rulemain: ipfrule | bpfrule + | exprrule ; ipfrule: - tos ttl proto ip + family tos ttl proto ip + ; + +family: | IPFY_FAMILY IPFY_INET { if (use_inet6 == 1) { + YYERROR; + } else { + frc->fr_family = AF_INET; + } + } + | IPFY_INET { if (use_inet6 == 1) { + YYERROR; + } else { + frc->fr_family = AF_INET; + } + } + | IPFY_FAMILY IPFY_INET6 { if (use_inet6 == -1) { + YYERROR; + } else { + frc->fr_family = AF_INET6; + } + } + | IPFY_INET6 { if (use_inet6 == -1) { + YYERROR; + } else { + frc->fr_family = AF_INET6; + } + } ; bpfrule: @@ -242,12 +304,16 @@ bpfrule: | IPFY_BPFV6 '{' YY_STR '}' { dobpf(6, $3); free($3); } ; +exprrule: + IPFY_IPFEXPR '{' YY_STR '}' { doipfexpr($3); } + ; + ruletail: with keep head group ; ruletail2: - pps age new + pps age new rulettl comment ; intag: settagin matchtagin @@ -269,6 +335,7 @@ action: block | IPFY_NOMATCH { fr->fr_flags |= FR_NOMATCH; } | log | IPFY_COUNT { fr->fr_flags |= FR_ACCOUNT; } + | decaps { fr->fr_flags |= FR_DECAPSULATE; } | auth | IPFY_SKIP YY_NUMBER { fr->fr_flags |= FR_SKIP; fr->fr_arg = $2; } @@ -291,6 +358,11 @@ blockreturn: | IPFY_RETRST { fr->fr_flags |= FR_RETRST; } ; +decaps: IPFY_DECAPS + | IPFY_DECAPS IPFY_L5AS '(' YY_STR ')' + { fr->fr_icode = atoi($4); } + ; + log: IPFY_LOG { fr->fr_flags |= FR_LOG; } | IPFY_LOG logoptions { fr->fr_flags |= FR_LOG; } ; @@ -300,10 +372,11 @@ auth: IPFY_AUTH { fr->fr_flags |= FR_AUTH; } | IPFY_PREAUTH { fr->fr_flags |= FR_PREAUTH; } ; -func: YY_STR '/' YY_NUMBER { fr->fr_func = nametokva($1, - ipfioctl[IPL_LOGIPF]); - fr->fr_arg = $3; - free($1); } +func: YY_STR '/' YY_NUMBER + { fr->fr_func = nametokva($1, ipfioctls[IPL_LOGIPF]); + fr->fr_arg = $3; + free($1); + } ; inopts: @@ -330,6 +403,7 @@ outopt: | on | dup | proute + | froute | replyto ; @@ -346,7 +420,7 @@ toslist: | YY_HEX { DOREM(fr->fr_tos = $1; fr->fr_mtos = 0xff;) } | toslist lmore YY_NUMBER { DOREM(fr->fr_tos = $3; fr->fr_mtos = 0xff;) } - | toslist lmore YY_HEX + | toslist lmore YY_HEX { DOREM(fr->fr_tos = $3; fr->fr_mtos = 0xff;) } ; @@ -355,10 +429,10 @@ ttl: | setttl YY_NUMBER | setttl lstart ttllist lend ; -lstart: '(' { newlist = 1; fr = frc; added = 0; } +lstart: '{' { newlist = 1; fr = frc; added = 0; } ; -lend: ')' { nrules += added; } +lend: '}' { nrules += added; } ; lmore: lanother { if (newlist == 1) { @@ -394,20 +468,25 @@ protox: IPFY_PROTO { setipftype(); ip: srcdst flags icmp ; -group: | IPFY_GROUP YY_STR { DOALL(strncpy(fr->fr_group, $2, \ - FR_GROUPLEN); \ - fillgroup(fr);); - free($2); } - | IPFY_GROUP YY_NUMBER { DOALL(sprintf(fr->fr_group, "%d", \ - $2); \ - fillgroup(fr);) } +group: | IPFY_GROUP groupname { DOALL(setgroup(&fr, $2); \ + fillgroup(fr);); + free($2); + } ; -head: | IPFY_HEAD YY_STR { DOALL(strncpy(fr->fr_grhead, $2, \ - FR_GROUPLEN);); - free($2); } - | IPFY_HEAD YY_NUMBER { DOALL(sprintf(fr->fr_grhead, "%d", \ - $2);) } +head: | IPFY_HEAD groupname { DOALL(setgrhead(&fr, $2);); + free($2); + } + ; + +groupname: + YY_STR { $$ = $1; + if (strlen($$) >= FR_GROUPLEN) + $$[FR_GROUPLEN - 1] = '\0'; + } + | YY_NUMBER { $$ = malloc(16); + sprintf($$, "%d", $1); + } ; settagin: @@ -461,6 +540,15 @@ pps: | IPFY_PPS YY_NUMBER { DOALL(fr->fr_pps = $2;) } new: | savegroup file restoregroup ; +rulettl: + | IPFY_RULETTL YY_NUMBER { DOALL(fr->fr_die = $2;) } + ; + +comment: + | IPFY_COMMENT YY_STR { DOALL(fr->fr_comment = addname(&fr, \ + $2);) } + ; + savegroup: '{' ; @@ -472,76 +560,92 @@ restoregroup: logopt: log ; -quick: - IPFY_QUICK { fr->fr_flags |= FR_QUICK; } +quick: IPFY_QUICK { fr->fr_flags |= FR_QUICK; } ; -on: IPFY_ON onname +on: IPFY_ON onname { setifname(&fr, 0, $2.if1); + free($2.if1); + if ($2.if2 != NULL) { + setifname(&fr, 1, + $2.if2); + free($2.if2); + } + } | IPFY_ON lstart onlist lend - | IPFY_ON onname IPFY_INVIA vianame - | IPFY_ON onname IPFY_OUTVIA vianame + | IPFY_ON onname IPFY_INVIA vianame { setifname(&fr, 0, $2.if1); + free($2.if1); + if ($2.if2 != NULL) { + setifname(&fr, 1, + $2.if2); + free($2.if2); + } + } + | IPFY_ON onname IPFY_OUTVIA vianame { setifname(&fr, 0, $2.if1); + free($2.if1); + if ($2.if2 != NULL) { + setifname(&fr, 1, + $2.if2); + free($2.if2); + } + } ; -onlist: onname { DOREM(strncpy(fr->fr_ifnames[0], $1.if1, \ - sizeof(fr->fr_ifnames[0])); \ - if ($1.if2 != NULL) { \ - strncpy(fr->fr_ifnames[1], \ - $1.if2, \ - sizeof(fr->fr_ifnames[1]));\ - } \ - ) } - | onlist lmore onname { DOREM(strncpy(fr->fr_ifnames[0], $3.if1, \ - sizeof(fr->fr_ifnames[0])); \ - if ($3.if2 != NULL) { \ - strncpy(fr->fr_ifnames[1], \ - $3.if2, \ - sizeof(fr->fr_ifnames[1]));\ - } \ - ) } +onlist: onname { DOREM(setifname(&fr, 0, $1.if1); \ + if ($1.if2 != NULL) \ + setifname(&fr, 1, $1.if2); \ + ) + free($1.if1); + if ($1.if2 != NULL) + free($1.if2); + } + | onlist lmore onname { DOREM(setifname(&fr, 0, $3.if1); \ + if ($3.if2 != NULL) \ + setifname(&fr, 1, $3.if2); \ + ) + free($3.if1); + if ($3.if2 != NULL) + free($3.if2); + } ; -onname: interfacename - { strncpy(fr->fr_ifnames[0], $1, sizeof(fr->fr_ifnames[0])); - $$.if1 = fr->fr_ifnames[0]; - $$.if2 = NULL; - free($1); - } +onname: interfacename { $$.if1 = $1; + $$.if2 = NULL; + } | interfacename ',' interfacename - { strncpy(fr->fr_ifnames[0], $1, sizeof(fr->fr_ifnames[0])); - $$.if1 = fr->fr_ifnames[0]; - free($1); - strncpy(fr->fr_ifnames[1], $3, sizeof(fr->fr_ifnames[1])); - $$.if1 = fr->fr_ifnames[1]; - free($3); - } + { $$.if1 = $1; + $$.if2 = $3; + } ; vianame: - name - { strncpy(fr->fr_ifnames[2], $1, sizeof(fr->fr_ifnames[2])); - free($1); - } - | name ',' name - { strncpy(fr->fr_ifnames[2], $1, sizeof(fr->fr_ifnames[2])); - free($1); - strncpy(fr->fr_ifnames[3], $3, sizeof(fr->fr_ifnames[3])); - free($3); - } + name { setifname(&fr, 2, $1); + free($1); + } + | name ',' name { setifname(&fr, 2, $1); + free($1); + setifname(&fr, 3, $3); + free($3); + } ; dup: IPFY_DUPTO name - { strncpy(fr->fr_dif.fd_ifname, $2, sizeof(fr->fr_dif.fd_ifname)); + { int idx = addname(&fr, $2); + fr->fr_dif.fd_name = idx; free($2); } + | IPFY_DUPTO IPFY_DSTLIST '/' name + { int idx = addname(&fr, $4); + fr->fr_dif.fd_name = idx; + fr->fr_dif.fd_type = FRD_DSTLIST; + free($4); + } | IPFY_DUPTO name duptoseparator hostname - { strncpy(fr->fr_dif.fd_ifname, $2, sizeof(fr->fr_dif.fd_ifname)); - fr->fr_dif.fd_ip = $4; - yyexpectaddr = 0; - free($2); - } - | IPFY_DUPTO name duptoseparator YY_IPV6 - { strncpy(fr->fr_dif.fd_ifname, $2, sizeof(fr->fr_dif.fd_ifname)); - bcopy(&$4, &fr->fr_dif.fd_ip6, sizeof(fr->fr_dif.fd_ip6)); + { int idx = addname(&fr, $2); + fr->fr_dif.fd_name = idx; + fr->fr_dif.fd_ptr = (void *)-1; + fr->fr_dif.fd_ip6 = $4.adr; + if (fr->fr_family == AF_UNSPEC && $4.f != AF_UNSPEC) + fr->fr_family = $4.f; yyexpectaddr = 0; free($2); } @@ -555,18 +659,23 @@ froute: IPFY_FROUTE { fr->fr_flags |= FR_FASTROUTE; } ; proute: routeto name - { strncpy(fr->fr_tif.fd_ifname, $2, sizeof(fr->fr_tif.fd_ifname)); + { int idx = addname(&fr, $2); + fr->fr_tif.fd_name = idx; free($2); } + | routeto IPFY_DSTLIST '/' name + { int idx = addname(&fr, $4); + fr->fr_tif.fd_name = idx; + fr->fr_tif.fd_type = FRD_DSTLIST; + free($4); + } | routeto name duptoseparator hostname - { strncpy(fr->fr_tif.fd_ifname, $2, sizeof(fr->fr_tif.fd_ifname)); - fr->fr_tif.fd_ip = $4; - yyexpectaddr = 0; - free($2); - } - | routeto name duptoseparator YY_IPV6 - { strncpy(fr->fr_tif.fd_ifname, $2, sizeof(fr->fr_tif.fd_ifname)); - bcopy(&$4, &fr->fr_tif.fd_ip6, sizeof(fr->fr_tif.fd_ip6)); + { int idx = addname(&fr, $2); + fr->fr_tif.fd_name = idx; + fr->fr_tif.fd_ptr = (void *)-1; + fr->fr_tif.fd_ip6 = $4.adr; + if (fr->fr_family == AF_UNSPEC && $4.f != AF_UNSPEC) + fr->fr_family = $4.f; yyexpectaddr = 0; free($2); } @@ -579,12 +688,22 @@ routeto: replyto: IPFY_REPLY_TO name - { strncpy(fr->fr_rif.fd_ifname, $2, sizeof(fr->fr_rif.fd_ifname)); + { int idx = addname(&fr, $2); + fr->fr_rif.fd_name = idx; free($2); } + | IPFY_REPLY_TO IPFY_DSTLIST '/' name + { fr->fr_rif.fd_name = addname(&fr, $4); + fr->fr_rif.fd_type = FRD_DSTLIST; + free($4); + } | IPFY_REPLY_TO name duptoseparator hostname - { strncpy(fr->fr_rif.fd_ifname, $2, sizeof(fr->fr_rif.fd_ifname)); - fr->fr_rif.fd_ip = $4; + { int idx = addname(&fr, $2); + fr->fr_rif.fd_name = idx; + fr->fr_rif.fd_ptr = (void *)-1; + fr->fr_rif.fd_ip6 = $4.adr; + if (fr->fr_family == AF_UNSPEC && $4.f != AF_UNSPEC) + fr->fr_family = $4.f; free($2); } ; @@ -614,27 +733,29 @@ srcdst: | IPFY_ALL ; protocol: - YY_NUMBER { DOREM(fr->fr_proto = $1; \ - fr->fr_mproto = 0xff;) } + YY_NUMBER { DOALL(fr->fr_proto = $1; \ + fr->fr_mproto = 0xff;) + } | YY_STR { if (!strcmp($1, "tcp-udp")) { - DOREM(fr->fr_flx |= FI_TCPUDP; \ + DOALL(fr->fr_flx |= FI_TCPUDP; \ fr->fr_mflx |= FI_TCPUDP;) } else { int p = getproto($1); if (p == -1) yyerror("protocol unknown"); - DOREM(fr->fr_proto = p; \ + DOALL(fr->fr_proto = p; \ fr->fr_mproto = 0xff;) } free($1); - } + } | YY_STR nextstring YY_STR { if (!strcmp($1, "tcp") && !strcmp($3, "udp")) { DOREM(fr->fr_flx |= FI_TCPUDP; \ fr->fr_mflx |= FI_TCPUDP;) - } else + } else { YYERROR; + } free($1); free($3); } @@ -667,7 +788,8 @@ to: IPFY_TO { if (fr == NULL) printf("set yyexpectaddr\n"); yycont = &yyexpectaddr; yysetdict(addrwords); - resetaddr(); } + resetaddr(); + } ; with: | andwith withlist @@ -678,7 +800,7 @@ andwith: | IPFY_AND { nowith = 0; setipftype(); } ; -flags: | startflags flagset +flags: | startflags flagset { DOALL(fr->fr_tcpf = $2; fr->fr_tcpfm = FR_TCPFMAX;) } | startflags flagset '/' flagset { DOALL(fr->fr_tcpf = $2; fr->fr_tcpfm = $4;) } @@ -717,35 +839,14 @@ srcobject: ; srcaddr: - addr { DOREM(bcopy(&($1.a), &fr->fr_ip.fi_src, sizeof($1.a)); \ - bcopy(&($1.m), &fr->fr_mip.fi_src, sizeof($1.m)); \ - if (dynamic != -1) { \ - fr->fr_satype = ifpflag; \ - fr->fr_ipf->fri_sifpidx = dynamic; \ - } else if (pooled || hashed) \ - fr->fr_satype = FRI_LOOKUP;) - } + addr { build_srcaddr_af(fr, &$1); } | lstart srcaddrlist lend ; srcaddrlist: - addr { DOREM(bcopy(&($1.a), &fr->fr_ip.fi_src, sizeof($1.a)); \ - bcopy(&($1.m), &fr->fr_mip.fi_src, sizeof($1.m)); \ - if (dynamic != -1) { \ - fr->fr_satype = ifpflag; \ - fr->fr_ipf->fri_sifpidx = dynamic; \ - } else if (pooled || hashed) \ - fr->fr_satype = FRI_LOOKUP;) - } + addr { build_srcaddr_af(fr, &$1); } | srcaddrlist lmore addr - { DOREM(bcopy(&($3.a), &fr->fr_ip.fi_src, sizeof($3.a)); \ - bcopy(&($3.m), &fr->fr_mip.fi_src, sizeof($3.m)); \ - if (dynamic != -1) { \ - fr->fr_satype = ifpflag; \ - fr->fr_ipf->fri_sifpidx = dynamic; \ - } else if (pooled || hashed) \ - fr->fr_satype = FRI_LOOKUP;) - } + { build_srcaddr_af(fr, &$3); } ; srcport: @@ -770,10 +871,10 @@ fromport: srcportlist: portnum { DOREM(fr->fr_scmp = FR_EQUAL; fr->fr_sport = $1;) } - | portnum ':' portnum + | portnum ':' portnum { DOREM(fr->fr_scmp = FR_INCRANGE; fr->fr_sport = $1; \ fr->fr_stop = $3;) } - | portnum YY_RANGE_IN portnum + | portnum YY_RANGE_IN portnum { DOREM(fr->fr_scmp = FR_INRANGE; fr->fr_sport = $1; \ fr->fr_stop = $3;) } | srcportlist lmore portnum @@ -794,34 +895,25 @@ dstobject: ; dstaddr: - addr { DOREM(bcopy(&($1.a), &fr->fr_ip.fi_dst, sizeof($1.a)); \ - bcopy(&($1.m), &fr->fr_mip.fi_dst, sizeof($1.m)); \ - if (dynamic != -1) { \ - fr->fr_datype = ifpflag; \ - fr->fr_ipf->fri_difpidx = dynamic; \ - } else if (pooled || hashed) \ - fr->fr_datype = FRI_LOOKUP;) + addr { if (($1.f != AF_UNSPEC) && (frc->fr_family != AF_UNSPEC) && + ($1.f != frc->fr_family)) + yyerror("1.src/dst address family mismatch"); + build_dstaddr_af(fr, &$1); } | lstart dstaddrlist lend ; dstaddrlist: - addr { DOREM(bcopy(&($1.a), &fr->fr_ip.fi_dst, sizeof($1.a)); \ - bcopy(&($1.m), &fr->fr_mip.fi_dst, sizeof($1.m)); \ - if (dynamic != -1) { \ - fr->fr_datype = ifpflag; \ - fr->fr_ipf->fri_difpidx = dynamic; \ - } else if (pooled || hashed) \ - fr->fr_datype = FRI_LOOKUP;) + addr { if (($1.f != AF_UNSPEC) && (frc->fr_family != AF_UNSPEC) && + ($1.f != frc->fr_family)) + yyerror("2.src/dst address family mismatch"); + build_dstaddr_af(fr, &$1); } | dstaddrlist lmore addr - { DOREM(bcopy(&($3.a), &fr->fr_ip.fi_dst, sizeof($3.a)); \ - bcopy(&($3.m), &fr->fr_mip.fi_dst, sizeof($3.m)); \ - if (dynamic != -1) { \ - fr->fr_datype = ifpflag; \ - fr->fr_ipf->fri_difpidx = dynamic; \ - } else if (pooled || hashed) \ - fr->fr_datype = FRI_LOOKUP;) + { if (($3.f != AF_UNSPEC) && (frc->fr_family != AF_UNSPEC) && + ($3.f != frc->fr_family)) + yyerror("3.src/dst address family mismatch"); + build_dstaddr_af(fr, &$3); } ; @@ -848,10 +940,10 @@ toport: dstportlist: portnum { DOREM(fr->fr_dcmp = FR_EQUAL; fr->fr_dport = $1;) } - | portnum ':' portnum + | portnum ':' portnum { DOREM(fr->fr_dcmp = FR_INCRANGE; fr->fr_dport = $1; \ fr->fr_dtop = $3;) } - | portnum YY_RANGE_IN portnum + | portnum YY_RANGE_IN portnum { DOREM(fr->fr_dcmp = FR_INRANGE; fr->fr_dport = $1; \ fr->fr_dtop = $3;) } | dstportlist lmore portnum @@ -865,141 +957,234 @@ dstportlist: ; addr: pool '/' YY_NUMBER { pooled = 1; + yyexpectaddr = 0; + $$.type = FRI_LOOKUP; + $$.v = 0; + $$.ifpos = -1; + $$.f = AF_UNSPEC; $$.a.iplookuptype = IPLT_POOL; $$.a.iplookupsubtype = 0; $$.a.iplookupnum = $3; } | pool '/' YY_STR { pooled = 1; + $$.ifpos = -1; + $$.f = AF_UNSPEC; + $$.type = FRI_LOOKUP; $$.a.iplookuptype = IPLT_POOL; $$.a.iplookupsubtype = 1; - strncpy($$.a.iplookupname, $3, - sizeof($$.a.iplookupname)); + $$.a.iplookupname = addname(&fr, $3); } - | pool '=' '(' poollist ')' { pooled = 1; + | pool '=' '(' { yyexpectaddr = 1; + pooled = 1; + } + poollist ')' { yyexpectaddr = 0; + $$.v = 0; + $$.ifpos = -1; + $$.f = AF_UNSPEC; + $$.type = FRI_LOOKUP; $$.a.iplookuptype = IPLT_POOL; $$.a.iplookupsubtype = 0; - $$.a.iplookupnum = makepool($4); } + $$.a.iplookupnum = makepool($5); + } | hash '/' YY_NUMBER { hashed = 1; + yyexpectaddr = 0; + $$.v = 0; + $$.ifpos = -1; + $$.f = AF_UNSPEC; + $$.type = FRI_LOOKUP; $$.a.iplookuptype = IPLT_HASH; $$.a.iplookupsubtype = 0; - $$.a.iplookupnum = $3; } - | hash '/' YY_STR { pooled = 1; + $$.a.iplookupnum = $3; + } + | hash '/' YY_STR { hashed = 1; + $$.type = FRI_LOOKUP; + $$.v = 0; + $$.ifpos = -1; + $$.f = AF_UNSPEC; $$.a.iplookuptype = IPLT_HASH; $$.a.iplookupsubtype = 1; - strncpy($$.a.iplookupname, $3, - sizeof($$.a.iplookupname)); + $$.a.iplookupname = addname(&fr, $3); } - | hash '=' '(' addrlist ')' { hashed = 1; + | hash '=' '(' { hashed = 1; + yyexpectaddr = 1; + } + addrlist ')' { yyexpectaddr = 0; + $$.v = 0; + $$.ifpos = -1; + $$.f = AF_UNSPEC; + $$.type = FRI_LOOKUP; $$.a.iplookuptype = IPLT_HASH; $$.a.iplookupsubtype = 0; - $$.a.iplookupnum = makehash($4); } - | ipaddr { bcopy(&$1, &$$, sizeof($$)); + $$.a.iplookupnum = makehash($5); + } + | ipaddr { $$ = $1; yyexpectaddr = 0; } ; ipaddr: IPFY_ANY { bzero(&($$), sizeof($$)); + $$.type = FRI_NORMAL; + $$.ifpos = -1; + yyexpectaddr = 0; + } + | hostname { $$.a = $1.adr; + $$.f = $1.f; + if ($1.f == AF_INET6) + fill6bits(128, $$.m.i6); + else if ($1.f == AF_INET) + fill6bits(32, $$.m.i6); + $$.v = ftov($1.f); + $$.ifpos = dynamic; + $$.type = FRI_NORMAL; + } + | hostname { yyresetdict(); } + maskspace { yysetdict(maskwords); + yyexpectaddr = 2; } + ipmask { ntomask($1.f, $5, $$.m.i6); + $$.a = $1.adr; + $$.a.i6[0] &= $$.m.i6[0]; + $$.a.i6[1] &= $$.m.i6[1]; + $$.a.i6[2] &= $$.m.i6[2]; + $$.a.i6[3] &= $$.m.i6[3]; + $$.f = $1.f; + $$.v = ftov($1.f); + $$.type = ifpflag; + $$.ifpos = dynamic; + if (ifpflag != 0 && $$.v == 0) { + if (frc->fr_family == AF_INET6){ + $$.v = 6; + $$.f = AF_INET6; + } else { + $$.v = 4; + $$.f = AF_INET; + } + } yyresetdict(); - yyexpectaddr = 0; } - | hostname { $$.a.in4 = $1; - $$.m.in4_addr = 0xffffffff; - yyexpectaddr = 0; } - | hostname { yyresetdict(); - $$.a.in4_addr = $1.s_addr; } - maskspace { yysetdict(maskwords); } - ipv4mask { $$.m.in4_addr = $5.s_addr; - $$.a.in4_addr &= $5.s_addr; + yyexpectaddr = 0; + } + | '(' YY_STR ')' { $$.type = FRI_DYNAMIC; + ifpflag = FRI_DYNAMIC; + $$.ifpos = addname(&fr, $2); + $$.lif = 0; + } + | '(' YY_STR ')' '/' + { ifpflag = FRI_DYNAMIC; yysetdict(maskwords); } + maskopts + { $$.type = ifpflag; + $$.ifpos = addname(&fr, $2); + $$.lif = 0; + if (frc->fr_family == AF_UNSPEC) + frc->fr_family = AF_INET; + if (ifpflag == FRI_DYNAMIC) { + ntomask(frc->fr_family, + $6, $$.m.i6); + } yyresetdict(); - yyexpectaddr = 0; } - | YY_IPV6 { bcopy(&$1, &$$.a, sizeof($$.a)); - fill6bits(128, (u_32_t *)&$$.m); + yyexpectaddr = 0; + } + | '(' YY_STR ':' YY_NUMBER ')' '/' + { ifpflag = FRI_DYNAMIC; yysetdict(maskwords); } + maskopts + { $$.type = ifpflag; + $$.ifpos = addname(&fr, $2); + $$.lif = $4; + if (frc->fr_family == AF_UNSPEC) + frc->fr_family = AF_INET; + if (ifpflag == FRI_DYNAMIC) { + ntomask(frc->fr_family, + $8, $$.m.i6); + } yyresetdict(); - yyexpectaddr = 0; } - | YY_IPV6 { yyresetdict(); - bcopy(&$1, &$$.a, sizeof($$.a)); } - maskspace { yysetdict(maskwords); } - ipv6mask { bcopy(&$5, &$$.m, sizeof($$.m)); - yyresetdict(); - yyexpectaddr = 0; } + yyexpectaddr = 0; + } ; + maskspace: '/' | IPFY_MASK ; -ipv4mask: - ipv4 { $$ = $1; } - | YY_HEX { $$.s_addr = htonl($1); } - | YY_NUMBER { ntomask(4, $1, (u_32_t *)&$$); } - | IPFY_BROADCAST { if (ifpflag == FRI_DYNAMIC) { - $$.s_addr = 0; - ifpflag = FRI_BROADCAST; - } else - YYERROR; - } - | IPFY_NETWORK { if (ifpflag == FRI_DYNAMIC) { - $$.s_addr = 0; - ifpflag = FRI_NETWORK; - } else - YYERROR; - } - | IPFY_NETMASKED { if (ifpflag == FRI_DYNAMIC) { - $$.s_addr = 0; - ifpflag = FRI_NETMASKED; - } else - YYERROR; - } - | IPFY_PEER { if (ifpflag == FRI_DYNAMIC) { - $$.s_addr = 0; - ifpflag = FRI_PEERADDR; - } else - YYERROR; - } +ipmask: ipv4 { $$ = count4bits($1.s_addr); } + | YY_HEX { $$ = count4bits(htonl($1)); } + | YY_NUMBER { $$ = $1; } + | YY_IPV6 { $$ = count6bits($1.i6); } + | maskopts { $$ = $1; } ; -ipv6mask: - YY_NUMBER { ntomask(6, $1, $$.i6); } - | IPFY_BROADCAST { if (ifpflag == FRI_DYNAMIC) { - bzero(&$$, sizeof($$)); +maskopts: + IPFY_BROADCAST { if (ifpflag == FRI_DYNAMIC) { ifpflag = FRI_BROADCAST; - } else + } else { YYERROR; + } + $$ = 0; } | IPFY_NETWORK { if (ifpflag == FRI_DYNAMIC) { - bzero(&$$, sizeof($$)); - ifpflag = FRI_BROADCAST; - } else + ifpflag = FRI_NETWORK; + } else { YYERROR; + } + $$ = 0; } | IPFY_NETMASKED { if (ifpflag == FRI_DYNAMIC) { - bzero(&$$, sizeof($$)); - ifpflag = FRI_BROADCAST; - } else + ifpflag = FRI_NETMASKED; + } else { YYERROR; + } + $$ = 0; } | IPFY_PEER { if (ifpflag == FRI_DYNAMIC) { - bzero(&$$, sizeof($$)); - ifpflag = FRI_BROADCAST; - } else + ifpflag = FRI_PEERADDR; + } else { YYERROR; + } + $$ = 0; } + | YY_NUMBER { $$ = $1; } ; hostname: - ipv4 { $$ = $1; } - | YY_NUMBER { $$.s_addr = $1; } - | YY_HEX { $$.s_addr = $1; } - | YY_STR { $$.s_addr = lookuphost($1); + ipv4 { $$.adr.in4 = $1; + if (frc->fr_family == AF_INET6) + YYERROR; + $$.f = AF_INET; + yyexpectaddr = 2; + } + | YY_NUMBER { if (frc->fr_family == AF_INET6) + YYERROR; + $$.adr.in4_addr = $1; + $$.f = AF_INET; + yyexpectaddr = 2; + } + | YY_HEX { if (frc->fr_family == AF_INET6) + YYERROR; + $$.adr.in4_addr = $1; + $$.f = AF_INET; + yyexpectaddr = 2; + } + | YY_STR { if (lookuphost($1, &$$.adr) == 0) + $$.f = AF_INET; free($1); + yyexpectaddr = 2; + } + | YY_IPV6 { if (frc->fr_family == AF_INET) + YYERROR; + $$.adr = $1; + $$.f = AF_INET6; + yyexpectaddr = 2; } ; addrlist: ipaddr { $$ = newalist(NULL); - bcopy(&($1.a), &($$->al_i6addr), sizeof($1.a)); - bcopy(&($1.m), &($$->al_i6mask), sizeof($1.m)); } - | addrlist ',' ipaddr - { $$ = newalist($1); - bcopy(&($3.a), &($$->al_i6addr), sizeof($3.a)); - bcopy(&($3.m), &($$->al_i6mask), sizeof($3.m)); } + $$->al_family = $1.f; + $$->al_i6addr = $1.a; + $$->al_i6mask = $1.m; + } + | ipaddr ',' { yyexpectaddr = 1; } addrlist + { $$ = newalist($4); + $$->al_family = $1.f; + $$->al_i6addr = $1.a; + $$->al_i6mask = $1.m; + } ; pool: IPFY_POOL { yyexpectaddr = 0; yycont = NULL; yyresetdict(); } @@ -1010,53 +1195,70 @@ hash: IPFY_HASH { yyexpectaddr = 0; yycont = NULL; yyresetdict(); } poollist: ipaddr { $$ = newalist(NULL); - bcopy(&($1.a), &($$->al_i6addr), sizeof($1.a)); - bcopy(&($1.m), &($$->al_i6mask), sizeof($1.m)); } + $$->al_family = $1.f; + $$->al_i6addr = $1.a; + $$->al_i6mask = $1.m; + } | '!' ipaddr { $$ = newalist(NULL); $$->al_not = 1; - bcopy(&($2.a), &($$->al_i6addr), sizeof($2.a)); - bcopy(&($2.m), &($$->al_i6mask), sizeof($2.m)); } + $$->al_family = $2.f; + $$->al_i6addr = $2.a; + $$->al_i6mask = $2.m; + } | poollist ',' ipaddr { $$ = newalist($1); - bcopy(&($3.a), &($$->al_i6addr), sizeof($3.a)); - bcopy(&($3.m), &($$->al_i6mask), sizeof($3.m)); } + $$->al_family = $3.f; + $$->al_i6addr = $3.a; + $$->al_i6mask = $3.m; + } | poollist ',' '!' ipaddr { $$ = newalist($1); $$->al_not = 1; - bcopy(&($4.a), &($$->al_i6addr), sizeof($4.a)); - bcopy(&($4.m), &($$->al_i6mask), sizeof($4.m)); } + $$->al_family = $4.f; + $$->al_i6addr = $4.a; + $$->al_i6mask = $4.m; + } ; port: IPFY_PORT { yyexpectaddr = 0; yycont = NULL; + if (frc->fr_proto != 0 && + frc->fr_proto != IPPROTO_UDP && + frc->fr_proto != IPPROTO_TCP) + yyerror("port use incorrect"); } ; portc: port compare { $$ = $2; - yysetdict(NULL); } + yysetdict(NULL); + } | porteq { $$ = $1; } ; porteq: port '=' { $$ = FR_EQUAL; - yysetdict(NULL); } + yysetdict(NULL); + } ; portr: IPFY_PORT { yyexpectaddr = 0; yycont = NULL; - yysetdict(NULL); } + yysetdict(NULL); + } ; portcomp: portc portnum { $$.pc = $1; $$.p1 = $2; - yyresetdict(); } + yyresetdict(); + } ; portrange: portr portnum range portnum { $$.p1 = $2; $$.pc = $3; $$.p2 = $4; - yyresetdict(); } + yyresetdict(); + } ; icmp: | itype icode @@ -1070,8 +1272,30 @@ itype: seticmptype icmptype ; seticmptype: - IPFY_ICMPTYPE { setipftype(); - yysetdict(icmptypewords); } + IPFY_ICMPTYPE { if (frc->fr_family == AF_UNSPEC) + frc->fr_family = AF_INET; + if (frc->fr_family == AF_INET && + frc->fr_type == FR_T_IPF && + frc->fr_proto != IPPROTO_ICMP) { + yyerror("proto not icmp"); + } + if (frc->fr_family == AF_INET6 && + frc->fr_type == FR_T_IPF && + frc->fr_proto != IPPROTO_ICMPV6) { + yyerror("proto not ipv6-icmp"); + } + setipftype(); + DOALL(if (fr->fr_family == AF_INET) { \ + fr->fr_ip.fi_v = 4; \ + fr->fr_mip.fi_v = 0xf; \ + } + if (fr->fr_family == AF_INET6) { \ + fr->fr_ip.fi_v = 6; \ + fr->fr_mip.fi_v = 0xf; \ + } + ) + yysetdict(NULL); + } ; icode: | seticmpcode icmpcode @@ -1146,9 +1370,18 @@ stateopt: IPFY_LIMIT YY_NUMBER { DOALL(fr->fr_statemax = $2;) } | IPFY_STRICT { DOALL(if (fr->fr_proto != IPPROTO_TCP) { \ YYERROR; \ - } else \ + } else if (fr->fr_flags & FR_STLOOSE) {\ + YYERROR; \ + } else \ fr->fr_flags |= FR_STSTRICT;) } + | IPFY_LOOSE { DOALL(if (fr->fr_proto != IPPROTO_TCP) { \ + YYERROR; \ + } else if (fr->fr_flags & FR_STSTRICT){\ + YYERROR; \ + } else \ + fr->fr_flags |= FR_STLOOSE;) + } | IPFY_NEWISN { DOALL(if (fr->fr_proto != IPPROTO_TCP) { \ YYERROR; \ } else \ @@ -1162,10 +1395,32 @@ stateopt: | IPFY_AGE YY_NUMBER '/' YY_NUMBER { DOALL(fr->fr_age[0] = $2; \ fr->fr_age[1] = $4;) } + | IPFY_ICMPHEAD groupname + { DOALL(seticmphead(&fr, $2);) + free($2); + } + | IPFY_NOLOG + { DOALL(fr->fr_nostatelog = 1;) } + | IPFY_RPC + { DOALL(fr->fr_rpc = 1;) } + | IPFY_RPC IPFY_IN YY_STR + { DOALL(fr->fr_rpc = 1;) } + | IPFY_MAX_SRCS YY_NUMBER + { DOALL(fr->fr_srctrack.ht_max_nodes = $2;) } + | IPFY_MAX_PER_SRC YY_NUMBER + { DOALL(fr->fr_srctrack.ht_max_per_node = $2; \ + fr->fr_srctrack.ht_netmask = \ + fr->fr_family == AF_INET ? 32: 128;) + } + | IPFY_MAX_PER_SRC YY_NUMBER '/' YY_NUMBER + { DOALL(fr->fr_srctrack.ht_max_per_node = $2; \ + fr->fr_srctrack.ht_netmask = $4;) + } ; portnum: - servicename { if (getport(frc, $1, &($$)) == -1) + servicename { if (getport(frc, $1, + &($$), NULL) == -1) yyerror("service unknown"); $$ = ntohs($$); free($1); @@ -1188,14 +1443,14 @@ withopt: | notwith opttype { DOALL(fr->fr_mflx |= $2;) } | ipopt ipopts { yyresetdict(); } | notwith ipopt ipopts { yyresetdict(); } - | startv6hdrs ipv6hdrs { yyresetdict(); } + | startv6hdr ipv6hdrs { yyresetdict(); } ; ipopt: IPFY_OPT { yysetdict(ipv4optwords); } ; -startv6hdrs: - IPF6_V6HDRS { if (use_inet6 == 0) +startv6hdr: + IPFY_V6HDR { if (frc->fr_family != AF_INET6) yyerror("only available with IPv6"); yysetdict(ipv6optwords); } @@ -1222,9 +1477,18 @@ opttype: | IPFY_BROADCAST { $$ = FI_BROADCAST; } | IPFY_STATE { $$ = FI_STATE; } | IPFY_OOW { $$ = FI_OOW; } + | IPFY_AH { $$ = FI_AH; } + | IPFY_V6HDRS { $$ = FI_V6EXTHDR; } ; ipopts: optlist { DOALL(fr->fr_mip.fi_optmsk |= $1; + if (fr->fr_family == AF_UNSPEC) { + fr->fr_family = AF_INET; + fr->fr_ip.fi_v = 4; + fr->fr_mip.fi_v = 0xf; + } else if (fr->fr_family != AF_INET) { + YYERROR; + } if (!nowith) fr->fr_ip.fi_optmsk |= $1;) } @@ -1264,22 +1528,11 @@ seclevel: ; icmptype: - YY_NUMBER { $$ = $1; } - | IPFY_ICMPT_UNR { $$ = ICMP_UNREACH; } - | IPFY_ICMPT_ECHO { $$ = ICMP_ECHO; } - | IPFY_ICMPT_ECHOR { $$ = ICMP_ECHOREPLY; } - | IPFY_ICMPT_SQUENCH { $$ = ICMP_SOURCEQUENCH; } - | IPFY_ICMPT_REDIR { $$ = ICMP_REDIRECT; } - | IPFY_ICMPT_TIMEX { $$ = ICMP_TIMXCEED; } - | IPFY_ICMPT_PARAMP { $$ = ICMP_PARAMPROB; } - | IPFY_ICMPT_TIMEST { $$ = ICMP_TSTAMP; } - | IPFY_ICMPT_TIMESTREP { $$ = ICMP_TSTAMPREPLY; } - | IPFY_ICMPT_INFOREQ { $$ = ICMP_IREQ; } - | IPFY_ICMPT_INFOREP { $$ = ICMP_IREQREPLY; } - | IPFY_ICMPT_MASKREQ { $$ = ICMP_MASKREQ; } - | IPFY_ICMPT_MASKREP { $$ = ICMP_MASKREPLY; } - | IPFY_ICMPT_ROUTERAD { $$ = ICMP_ROUTERADVERT; } - | IPFY_ICMPT_ROUTERSOL { $$ = ICMP_ROUTERSOLICIT; } + YY_NUMBER { $$ = $1; } + | YY_STR { $$ = geticmptype(frc->fr_family, $1); + if ($$ == -1) + yyerror("unrecognised icmp type"); + } ; icmpcode: @@ -1314,7 +1567,8 @@ opt: | IPFY_IPOPT_SEC { $$ = getoptbyvalue(IPOPT_SECURITY); } | IPFY_IPOPT_LSRR { $$ = getoptbyvalue(IPOPT_LSRR); } | IPFY_IPOPT_ESEC { $$ = getoptbyvalue(IPOPT_E_SEC); } - | IPFY_IPOPT_CIPSO { $$ = getoptbyvalue(IPOPT_CIPSO); } + | IPFY_IPOPT_CIPSO { $$ = getoptbyvalue(IPOPT_CIPSO); } + | IPFY_IPOPT_CIPSO doi { $$ = getoptbyvalue(IPOPT_CIPSO); } | IPFY_IPOPT_SATID { $$ = getoptbyvalue(IPOPT_SATID); } | IPFY_IPOPT_SSRR { $$ = getoptbyvalue(IPOPT_SSRR); } | IPFY_IPOPT_ADDEXT { $$ = getoptbyvalue(IPOPT_ADDEXT); } @@ -1329,6 +1583,13 @@ opt: | IPFY_IPOPT_UMP { $$ = getoptbyvalue(IPOPT_UMP); } | setsecclass secname { DOALL(fr->fr_mip.fi_secmsk |= $2; + if (fr->fr_family == AF_UNSPEC) { + fr->fr_family = AF_INET; + fr->fr_ip.fi_v = 4; + fr->fr_mip.fi_v = 0xf; + } else if (fr->fr_family != AF_INET) { + YYERROR; + } if (!nowith) fr->fr_ip.fi_secmsk |= $2;) $$ = 0; @@ -1337,7 +1598,15 @@ opt: ; setsecclass: - IPFY_SECCLASS { yysetdict(ipv4secwords); } + IPFY_SECCLASS { yysetdict(ipv4secwords); } + ; + +doi: IPFY_DOI YY_NUMBER { DOALL(fr->fr_doimask = 0xffffffff; \ + if (!nowith) \ + fr->fr_doi = $2;) } + | IPFY_DOI YY_HEX { DOALL(fr->fr_doimask = 0xffffffff; \ + if (!nowith) \ + fr->fr_doi = $2;) } ; ipv6hdr: @@ -1463,7 +1732,7 @@ ipv4: ipv4_24 '.' YY_NUMBER %% -static struct wordtab ipfwords[95] = { +static struct wordtab ipfwords[] = { { "age", IPFY_AGE }, { "ah", IPFY_AH }, { "all", IPFY_ALL }, @@ -1481,10 +1750,16 @@ static struct wordtab ipfwords[95] = { #endif { "call", IPFY_CALL }, { "code", IPFY_ICMPCODE }, + { "comment", IPFY_COMMENT }, { "count", IPFY_COUNT }, + { "decapsulate", IPFY_DECAPS }, + { "dstlist", IPFY_DSTLIST }, + { "doi", IPFY_DOI }, { "dup-to", IPFY_DUPTO }, { "eq", YY_CMP_EQ }, { "esp", IPFY_ESP }, + { "exp", IPFY_IPFEXPR }, + { "family", IPFY_FAMILY }, { "fastroute", IPFY_FROUTE }, { "first", IPFY_FIRST }, { "flags", IPFY_FLAGS }, @@ -1497,20 +1772,27 @@ static struct wordtab ipfwords[95] = { { "gt", YY_CMP_GT }, { "head", IPFY_HEAD }, { "icmp", IPFY_ICMP }, + { "icmp-head", IPFY_ICMPHEAD }, { "icmp-type", IPFY_ICMPTYPE }, { "in", IPFY_IN }, { "in-via", IPFY_INVIA }, + { "inet", IPFY_INET }, + { "inet6", IPFY_INET6 }, { "ipopt", IPFY_IPOPTS }, { "ipopts", IPFY_IPOPTS }, { "keep", IPFY_KEEP }, + { "l5-as", IPFY_L5AS }, { "le", YY_CMP_LE }, { "level", IPFY_LEVEL }, { "limit", IPFY_LIMIT }, { "log", IPFY_LOG }, + { "loose", IPFY_LOOSE }, { "lowttl", IPFY_LOWTTL }, { "lt", YY_CMP_LT }, { "mask", IPFY_MASK }, { "match-tag", IPFY_MATCHTAG }, + { "max-per-src", IPFY_MAX_PER_SRC }, + { "max-srcs", IPFY_MAX_SRCS }, { "mbcast", IPFY_MBCAST }, { "mcast", IPFY_MULTICAST }, { "multicast", IPFY_MULTICAST }, @@ -1520,6 +1802,7 @@ static struct wordtab ipfwords[95] = { { "newisn", IPFY_NEWISN }, { "no", IPFY_NO }, { "no-icmp-err", IPFY_NOICMPERR }, + { "nolog", IPFY_NOLOG }, { "nomatch", IPFY_NOMATCH }, { "now", IPFY_NOW }, { "not", IPFY_NOT }, @@ -1540,7 +1823,10 @@ static struct wordtab ipfwords[95] = { { "return-icmp-as-dest", IPFY_RETICMPASDST }, { "return-rst", IPFY_RETRST }, { "route-to", IPFY_ROUTETO }, + { "rule-ttl", IPFY_RULETTL }, + { "rpc", IPFY_RPC }, { "sec-class", IPFY_SECCLASS }, + { "set", IPFY_SET }, { "set-tag", IPFY_SETTAG }, { "skip", IPFY_SKIP }, { "short", IPFY_SHORT }, @@ -1554,19 +1840,20 @@ static struct wordtab ipfwords[95] = { { "to", IPFY_TO }, { "ttl", IPFY_TTL }, { "udp", IPFY_UDP }, - { "v6hdrs", IPF6_V6HDRS }, + { "v6hdr", IPFY_V6HDR }, + { "v6hdrs", IPFY_V6HDRS }, { "with", IPFY_WITH }, { NULL, 0 } }; -static struct wordtab addrwords[4] = { +static struct wordtab addrwords[] = { { "any", IPFY_ANY }, { "hash", IPFY_HASH }, { "pool", IPFY_POOL }, { NULL, 0 } }; -static struct wordtab maskwords[5] = { +static struct wordtab maskwords[] = { { "broadcast", IPFY_BROADCAST }, { "netmasked", IPFY_NETMASKED }, { "network", IPFY_NETWORK }, @@ -1574,26 +1861,7 @@ static struct wordtab maskwords[5] = { { NULL, 0 } }; -static struct wordtab icmptypewords[16] = { - { "echo", IPFY_ICMPT_ECHO }, - { "echorep", IPFY_ICMPT_ECHOR }, - { "inforeq", IPFY_ICMPT_INFOREQ }, - { "inforep", IPFY_ICMPT_INFOREP }, - { "maskrep", IPFY_ICMPT_MASKREP }, - { "maskreq", IPFY_ICMPT_MASKREQ }, - { "paramprob", IPFY_ICMPT_PARAMP }, - { "redir", IPFY_ICMPT_REDIR }, - { "unreach", IPFY_ICMPT_UNR }, - { "routerad", IPFY_ICMPT_ROUTERAD }, - { "routersol", IPFY_ICMPT_ROUTERSOL }, - { "squench", IPFY_ICMPT_SQUENCH }, - { "timest", IPFY_ICMPT_TIMEST }, - { "timestrep", IPFY_ICMPT_TIMESTREP }, - { "timex", IPFY_ICMPT_TIMEX }, - { NULL, 0 }, -}; - -static struct wordtab icmpcodewords[17] = { +static struct wordtab icmpcodewords[] = { { "cutoff-preced", IPFY_ICMPC_CUTPRE }, { "filter-prohib", IPFY_ICMPC_FLTPRO }, { "isolate", IPFY_ICMPC_ISOLATE }, @@ -1613,7 +1881,7 @@ static struct wordtab icmpcodewords[17] = { { NULL, 0 }, }; -static struct wordtab ipv4optwords[25] = { +static struct wordtab ipv4optwords[] = { { "addext", IPFY_IPOPT_ADDEXT }, { "cipso", IPFY_IPOPT_CIPSO }, { "dps", IPFY_IPOPT_DPS }, @@ -1641,7 +1909,7 @@ static struct wordtab ipv4optwords[25] = { { NULL, 0 }, }; -static struct wordtab ipv4secwords[9] = { +static struct wordtab ipv4secwords[] = { { "confid", IPFY_SEC_CONF }, { "reserv-1", IPFY_SEC_RSV1 }, { "reserv-2", IPFY_SEC_RSV2 }, @@ -1653,7 +1921,7 @@ static struct wordtab ipv4secwords[9] = { { NULL, 0 }, }; -static struct wordtab ipv6optwords[9] = { +static struct wordtab ipv6optwords[] = { { "dstopts", IPFY_IPV6OPT_DSTOPTS }, { "esp", IPFY_IPV6OPT_ESP }, { "frag", IPFY_IPV6OPT_FRAG }, @@ -1665,7 +1933,7 @@ static struct wordtab ipv6optwords[9] = { { NULL, 0 }, }; -static struct wordtab logwords[33] = { +static struct wordtab logwords[] = { { "kern", IPFY_FAC_KERN }, { "user", IPFY_FAC_USER }, { "mail", IPFY_FAC_MAIL }, @@ -1751,7 +2019,7 @@ FILE *fp; ipffd = fd; for (i = 0; i <= IPL_LOGMAX; i++) - ipfioctl[i] = iocfuncs[i]; + ipfioctls[i] = iocfuncs[i]; ipfaddfunc = addfunc; if (feof(fp)) @@ -1779,23 +2047,29 @@ static void newrule() { frentry_t *frn; - frn = (frentry_t *)calloc(1, sizeof(frentry_t)); + frn = allocfr(); for (fr = frtop; fr != NULL && fr->fr_next != NULL; fr = fr->fr_next) ; - if (fr != NULL) + if (fr != NULL) { fr->fr_next = frn; - if (frtop == NULL) + frn->fr_pnext = &fr->fr_next; + } + if (frtop == NULL) { frtop = frn; + frn->fr_pnext = &frtop; + } fr = frn; frc = frn; fr->fr_loglevel = 0xffff; fr->fr_isc = (void *)-1; fr->fr_logtag = FR_NOLOGTAG; fr->fr_type = FR_T_NONE; - if (use_inet6 != 0) - fr->fr_v = 6; - else - fr->fr_v = 4; + fr->fr_flineno = yylineNum; + + if (use_inet6 == 1) + fr->fr_family = AF_INET6; + else if (use_inet6 == -1) + fr->fr_family = AF_INET; nrules = 1; } @@ -1808,7 +2082,13 @@ static void setipftype() fr->fr_type = FR_T_IPF; fr->fr_data = (void *)calloc(sizeof(fripf_t), 1); fr->fr_dsize = sizeof(fripf_t); - fr->fr_ip.fi_v = frc->fr_v; + fr->fr_family = frc->fr_family; + if (fr->fr_family == AF_INET) { + fr->fr_ip.fi_v = 4; + } + else if (fr->fr_family == AF_INET6) { + fr->fr_ip.fi_v = 6; + } fr->fr_mip.fi_v = 0xf; fr->fr_ipf->fri_sifpidx = -1; fr->fr_ipf->fri_difpidx = -1; @@ -1831,10 +2111,13 @@ static frentry_t *addrule() count = nrules; f = f2; for (f1 = frc; count > 0; count--, f1 = f1->fr_next) { - f->fr_next = (frentry_t *)calloc(sizeof(*f), 1); + f->fr_next = allocfr(); + if (f->fr_next == NULL) + return NULL; + f->fr_next->fr_pnext = &f->fr_next; added++; f = f->fr_next; - bcopy(f1, f, sizeof(*f)); + *f = *f1; f->fr_next = NULL; if (f->fr_caddr != NULL) { f->fr_caddr = malloc(f->fr_dsize); @@ -1846,10 +2129,11 @@ static frentry_t *addrule() } -static u_32_t lookuphost(name) -char *name; +static int +lookuphost(name, addrp) + char *name; + i6addr_t *addrp; { - u_32_t addr; int i; hashed = 0; @@ -1857,19 +2141,20 @@ char *name; dynamic = -1; for (i = 0; i < 4; i++) { - if (strncmp(name, frc->fr_ifnames[i], - sizeof(frc->fr_ifnames[i])) == 0) { + if (fr->fr_ifnames[i] == -1) + continue; + if (strcmp(name, fr->fr_names + fr->fr_ifnames[i]) == 0) { ifpflag = FRI_DYNAMIC; - dynamic = i; - return 0; + dynamic = addname(&fr, name); + return 1; } } - if (gethost(name, &addr) == -1) { + if (gethost(AF_INET, name, addrp) == -1) { fprintf(stderr, "unknown name \"%s\"\n", name); - return 0; + return -1; } - return addr; + return 0; } @@ -1891,7 +2176,7 @@ char *phrase; fprintf(stderr, "cannot mix IPF and BPF matching\n"); return; } - fr->fr_v = v; + fr->fr_family = vtof(v); fr->fr_type = FR_T_BPFOPC; if (!strncmp(phrase, "0x", 2)) { @@ -1986,8 +2271,9 @@ alist_t *ptr; } -static int makepool(list) -alist_t *list; +static int +makepool(list) + alist_t *list; { ip_pool_node_t *n, *top; ip_pool_t pool; @@ -1999,10 +2285,30 @@ alist_t *list; top = calloc(1, sizeof(*top)); if (top == NULL) return 0; - + for (n = top, a = list; (n != NULL) && (a != NULL); a = a->al_next) { - n->ipn_addr.adf_addr.in4.s_addr = a->al_1; - n->ipn_mask.adf_addr.in4.s_addr = a->al_2; + if (use_inet6 == 1) { +#ifdef AF_INET6 + n->ipn_addr.adf_family = AF_INET6; + n->ipn_addr.adf_addr = a->al_i6addr; + n->ipn_addr.adf_len = offsetof(addrfamily_t, + adf_addr) + 16; + n->ipn_mask.adf_family = AF_INET6; + n->ipn_mask.adf_addr = a->al_i6mask; + n->ipn_mask.adf_len = offsetof(addrfamily_t, + adf_addr) + 16; + +#endif + } else { + n->ipn_addr.adf_family = AF_INET; + n->ipn_addr.adf_addr.in4.s_addr = a->al_1; + n->ipn_addr.adf_len = offsetof(addrfamily_t, + adf_addr) + 4; + n->ipn_mask.adf_family = AF_INET; + n->ipn_mask.adf_addr.in4.s_addr = a->al_2; + n->ipn_mask.adf_len = offsetof(addrfamily_t, + adf_addr) + 4; + } n->ipn_info = a->al_not; if (a->al_next != NULL) { n->ipn_next = calloc(1, sizeof(*n)); @@ -2013,7 +2319,7 @@ alist_t *list; bzero((char *)&pool, sizeof(pool)); pool.ipo_unit = IPL_LOGIPF; pool.ipo_list = top; - num = load_pool(&pool, ipfioctl[IPL_LOGLOOKUP]); + num = load_pool(&pool, ipfioctls[IPL_LOGLOOKUP]); while ((n = top) != NULL) { top = n->ipn_next; @@ -2036,10 +2342,17 @@ alist_t *list; top = calloc(1, sizeof(*top)); if (top == NULL) return 0; - + for (n = top, a = list; (n != NULL) && (a != NULL); a = a->al_next) { - n->ipe_addr.in4_addr = a->al_1; - n->ipe_mask.in4_addr = a->al_2; + if (a->al_family == AF_INET6) { + n->ipe_family = AF_INET6; + n->ipe_addr = a->al_i6addr; + n->ipe_mask = a->al_i6mask; + } else { + n->ipe_family = AF_INET; + n->ipe_addr.in4_addr = a->al_1; + n->ipe_mask.in4_addr = a->al_2; + } n->ipe_value = 0; if (a->al_next != NULL) { n->ipe_next = calloc(1, sizeof(*n)); @@ -2052,7 +2365,7 @@ alist_t *list; iph.iph_type = IPHASH_LOOKUP; *iph.iph_name = '\0'; - if (load_hash(&iph, top, ipfioctl[IPL_LOGLOOKUP]) == 0) + if (load_hash(&iph, top, ipfioctls[IPL_LOGLOOKUP]) == 0) sscanf(iph.iph_name, "%u", &num); else num = 0; @@ -2065,7 +2378,7 @@ alist_t *list; } -void ipf_addrule(fd, ioctlfunc, ptr) +int ipf_addrule(fd, ioctlfunc, ptr) int fd; ioctlfunc_t ioctlfunc; void *ptr; @@ -2075,7 +2388,7 @@ void *ptr; ipfobj_t obj; if (ptr == NULL) - return; + return 0; fr = ptr; add = 0; @@ -2083,7 +2396,7 @@ void *ptr; bzero((char *)&obj, sizeof(obj)); obj.ipfo_rev = IPFILTER_VERSION; - obj.ipfo_size = sizeof(*fr); + obj.ipfo_size = fr->fr_size; obj.ipfo_type = IPFOBJ_FRENTRY; obj.ipfo_ptr = ptr; @@ -2118,8 +2431,11 @@ void *ptr; if ((opts & OPT_ZERORULEST) != 0) { if ((*ioctlfunc)(fd, add, (void *)&obj) == -1) { if ((opts & OPT_DONOTHING) == 0) { - fprintf(stderr, "%d:", yylineNum); - perror("ioctl(SIOCZRLST)"); + char msg[80]; + + sprintf(msg, "%d:ioctl(zero rule)", + fr->fr_flineno); + return ipf_perror_fd(fd, ioctlfunc, msg); } } else { #ifdef USE_QUAD_T @@ -2134,19 +2450,26 @@ void *ptr; } } else if ((opts & OPT_REMOVE) != 0) { if ((*ioctlfunc)(fd, del, (void *)&obj) == -1) { - if ((opts & OPT_DONOTHING) != 0) { - fprintf(stderr, "%d:", yylineNum); - perror("ioctl(delete rule)"); + if ((opts & OPT_DONOTHING) == 0) { + char msg[80]; + + sprintf(msg, "%d:ioctl(delete rule)", + fr->fr_flineno); + return ipf_perror_fd(fd, ioctlfunc, msg); } } } else { if ((*ioctlfunc)(fd, add, (void *)&obj) == -1) { - if (!(opts & OPT_DONOTHING)) { - fprintf(stderr, "%d:", yylineNum); - perror("ioctl(add/insert rule)"); + if ((opts & OPT_DONOTHING) == 0) { + char msg[80]; + + sprintf(msg, "%d:ioctl(add/insert rule)", + fr->fr_flineno); + return ipf_perror_fd(fd, ioctlfunc, msg); } } } + return 0; } static void setsyslog() @@ -2168,9 +2491,16 @@ frentry_t *fr; { frentry_t *f; - for (f = frold; f != NULL; f = f->fr_next) - if (strncmp(f->fr_grhead, fr->fr_group, FR_GROUPLEN) == 0) + for (f = frold; f != NULL; f = f->fr_next) { + if (f->fr_grhead == -1 && fr->fr_group == -1) break; + if (f->fr_grhead == -1 || fr->fr_group == -1) + continue; + if (strcmp(f->fr_names + f->fr_grhead, + fr->fr_names + fr->fr_group) == 0) + break; + } + if (f == NULL) return; @@ -2183,8 +2513,8 @@ frentry_t *fr; if (f->fr_type != fr->fr_type || f->fr_type != FR_T_IPF) return; - if (fr->fr_v == 0 && f->fr_v != 0) - fr->fr_v = f->fr_v; + if (fr->fr_family == 0 && f->fr_family != 0) + fr->fr_family = f->fr_family; if (fr->fr_mproto == 0 && f->fr_mproto != 0) fr->fr_mproto = f->fr_mproto; @@ -2192,6 +2522,218 @@ frentry_t *fr; fr->fr_proto = f->fr_proto; if ((fr->fr_mproto == 0) && ((fr->fr_flx & FI_TCPUDP) == 0) && - ((f->fr_flx & FI_TCPUDP) != 0)) + ((f->fr_flx & FI_TCPUDP) != 0)) { fr->fr_flx |= FI_TCPUDP; + fr->fr_mflx |= FI_TCPUDP; + } +} + + +static void doipfexpr(line) +char *line; +{ + int *array; + char *error; + + array = parseipfexpr(line, &error); + if (array == NULL) { + fprintf(stderr, "%s:", error); + yyerror("error parsing ipf matching expression"); + return; + } + + fr->fr_type = FR_T_IPFEXPR; + fr->fr_data = array; + fr->fr_dsize = array[0] * sizeof(*array); +} + + +static void do_tuneint(varname, value) +char *varname; +int value; +{ + char buffer[80]; + + strncpy(buffer, varname, 60); + buffer[59] = '\0'; + strcat(buffer, "="); + sprintf(buffer, "%u", value); + ipf_dotuning(ipffd, buffer, ioctl); +} + + +static void do_tunestr(varname, value) +char *varname, *value; +{ + + if (!strcasecmp(value, "true")) { + do_tuneint(varname, 1); + } else if (!strcasecmp(value, "false")) { + do_tuneint(varname, 0); + } else { + yyerror("did not find true/false where expected"); + } +} + + +static void setifname(frp, idx, name) +frentry_t **frp; +int idx; +char *name; +{ + int pos; + + pos = addname(frp, name); + if (pos == -1) + return; + (*frp)->fr_ifnames[idx] = pos; +} + + +static int addname(frp, name) +frentry_t **frp; +char *name; +{ + frentry_t *f; + int nlen; + int pos; + + nlen = strlen(name) + 1; + f = realloc(*frp, (*frp)->fr_size + nlen); + if (*frp == frc) + frc = f; + *frp = f; + if (f == NULL) + return -1; + if (f->fr_pnext != NULL) + *f->fr_pnext = f; + f->fr_size += nlen; + pos = f->fr_namelen; + f->fr_namelen += nlen; + strcpy(f->fr_names + pos, name); + f->fr_names[f->fr_namelen] = '\0'; + return pos; +} + + +static frentry_t *allocfr() +{ + frentry_t *fr; + + fr = calloc(1, sizeof(*fr)); + if (fr != NULL) { + fr->fr_size = sizeof(*fr); + fr->fr_comment = -1; + fr->fr_group = -1; + fr->fr_grhead = -1; + fr->fr_icmphead = -1; + fr->fr_ifnames[0] = -1; + fr->fr_ifnames[1] = -1; + fr->fr_ifnames[2] = -1; + fr->fr_ifnames[3] = -1; + fr->fr_tif.fd_name = -1; + fr->fr_rif.fd_name = -1; + fr->fr_dif.fd_name = -1; + } + return fr; +} + + +static void setgroup(frp, name) +frentry_t **frp; +char *name; +{ + int pos; + + pos = addname(frp, name); + if (pos == -1) + return; + (*frp)->fr_group = pos; +} + + +static void setgrhead(frp, name) +frentry_t **frp; +char *name; +{ + int pos; + + pos = addname(frp, name); + if (pos == -1) + return; + (*frp)->fr_grhead = pos; +} + + +static void seticmphead(frp, name) +frentry_t **frp; +char *name; +{ + int pos; + + pos = addname(frp, name); + if (pos == -1) + return; + (*frp)->fr_icmphead = pos; +} + + +static void +build_dstaddr_af(fp, ptr) + frentry_t *fp; + void *ptr; +{ + struct ipp_s *ipp = ptr; + frentry_t *f = fp; + + if (f->fr_family != AF_UNSPEC && ipp->f == AF_UNSPEC) { + ipp->f = f->fr_family; + ipp->v = f->fr_ip.fi_v; + } + if (ipp->f == AF_INET) + ipp->v = 4; + else if (ipp->f == AF_INET6) + ipp->v = 6; + + for (; f != NULL; f = f->fr_next) { + f->fr_ip.fi_dst = ipp->a; + f->fr_mip.fi_dst = ipp->m; + f->fr_family = ipp->f; + f->fr_ip.fi_v = ipp->v; + f->fr_mip.fi_v = 0xf; + f->fr_datype = ipp->type; + if (ipp->ifpos != -1) + f->fr_ipf->fri_difpidx = ipp->ifpos; + } + fr = NULL; +} + + +static void +build_srcaddr_af(fp, ptr) + frentry_t *fp; + void *ptr; +{ + struct ipp_s *ipp = ptr; + frentry_t *f = fp; + + if (f->fr_family != AF_UNSPEC && ipp->f == AF_UNSPEC) { + ipp->f = f->fr_family; + ipp->v = f->fr_ip.fi_v; + } + if (ipp->f == AF_INET) + ipp->v = 4; + else if (ipp->f == AF_INET6) + ipp->v = 6; + + for (; f != NULL; f = f->fr_next) { + f->fr_ip.fi_src = ipp->a; + f->fr_mip.fi_src = ipp->m; + f->fr_family = ipp->f; + f->fr_ip.fi_v = ipp->v; + f->fr_mip.fi_v = 0xf; + f->fr_satype = ipp->type; + f->fr_ipf->fri_sifpidx = ipp->ifpos; + } + fr = NULL; } diff --git a/contrib/ipfilter/tools/ipfcomp.c b/contrib/ipfilter/tools/ipfcomp.c index e00fe84a9af3..eba28ceb1d51 100644 --- a/contrib/ipfilter/tools/ipfcomp.c +++ b/contrib/ipfilter/tools/ipfcomp.c @@ -1,13 +1,13 @@ /* $FreeBSD$ */ /* - * Copyright (C) 2001-2005 by Darren Reed. + * Copyright (C) 2012 by Darren Reed. * * See the IPFILTER.LICENCE file for details on licencing. */ #if !defined(lint) static const char sccsid[] = "@(#)ip_fil.c 2.41 6/5/96 (C) 1993-2000 Darren Reed"; -static const char rcsid[] = "@(#)$Id: ipfcomp.c,v 1.24.2.7 2007/05/01 22:15:00 darrenr Exp $"; +static const char rcsid[] = "@(#)$Id$"; #endif #include "ipf.h" @@ -63,7 +63,7 @@ static FILE *cfile = NULL; * required. */ void printc(fr) -frentry_t *fr; + frentry_t *fr; { fripf_t *ipf; u_long *ulp; @@ -71,7 +71,7 @@ frentry_t *fr; FILE *fp; int i; - if (fr->fr_v != 4) + if (fr->fr_family == 6) return; if ((fr->fr_type != FR_T_IPF) && (fr->fr_type != FR_T_NONE)) return; @@ -87,7 +87,7 @@ frentry_t *fr; fp = cfile; if (count == 0) { fprintf(fp, "/*\n"); - fprintf(fp, "* Copyright (C) 1993-2000 by Darren Reed.\n"); + fprintf(fp, "* Copyright (C) 2012 by Darren Reed.\n"); fprintf(fp, "*\n"); fprintf(fp, "* Redistribution and use in source and binary forms are permitted\n"); fprintf(fp, "* provided that this notice is preserved and due credit is given\n"); @@ -136,6 +136,9 @@ frentry_t *fr; fprintf(fp, "#endif /* _KERNEL */\n"); fprintf(fp, "\n"); fprintf(fp, "#ifdef IPFILTER_COMPILED\n"); + fprintf(fp, "\n"); + fprintf(fp, "extern ipf_main_softc_t ipfmain;\n"); + fprintf(fp, "\n"); } addrule(fp, fr); @@ -162,12 +165,14 @@ static frgroup_t *groups = NULL; static void addrule(fp, fr) -FILE *fp; -frentry_t *fr; + FILE *fp; + frentry_t *fr; { frentry_t *f, **fpp; frgroup_t *g; u_long *ulp; + char *ghead; + char *gname; char *and; int i; @@ -180,8 +185,10 @@ frentry_t *fr; } f->fr_next = NULL; + gname = FR_NAME(fr, fr_group); + for (g = groups; g != NULL; g = g->fg_next) - if ((strncmp(g->fg_name, f->fr_group, FR_GROUPLEN) == 0) && + if ((strncmp(g->fg_name, gname, FR_GROUPLEN) == 0) && (g->fg_flags == (f->fr_flags & FR_INOUT))) break; @@ -190,7 +197,7 @@ frentry_t *fr; g->fg_next = groups; groups = g; g->fg_head = f; - bcopy(f->fr_group, g->fg_name, FR_GROUPLEN); + strncpy(g->fg_name, gname, FR_GROUPLEN); g->fg_ref = 0; g->fg_flags = f->fr_flags & FR_INOUT; } @@ -219,10 +226,10 @@ static u_long ipf%s_rule_data_%s_%u[] = {\n", g->fg_ref++; - if (f->fr_grhead != 0) { + if (f->fr_grhead != -1) { + ghead = FR_NAME(f, fr_grhead); for (g = groups; g != NULL; g = g->fg_next) - if ((strncmp(g->fg_name, f->fr_grhead, - FR_GROUPLEN) == 0) && + if ((strncmp(g->fg_name, ghead, FR_GROUPLEN) == 0) && g->fg_flags == (f->fr_flags & FR_INOUT)) break; if (g == NULL) { @@ -230,7 +237,7 @@ static u_long ipf%s_rule_data_%s_%u[] = {\n", g->fg_next = groups; groups = g; g->fg_head = f; - bcopy(f->fr_grhead, g->fg_name, FR_GROUPLEN); + strncpy(g->fg_name, ghead, FR_GROUPLEN); g->fg_ref = 0; g->fg_flags = f->fr_flags & FR_INOUT; } @@ -239,7 +246,7 @@ static u_long ipf%s_rule_data_%s_%u[] = {\n", int intcmp(c1, c2) -const void *c1, *c2; + const void *c1, *c2; { const mc_t *i1 = (const mc_t *)c1, *i2 = (const mc_t *)c2; @@ -251,17 +258,17 @@ const void *c1, *c2; static void indent(fp, in) -FILE *fp; -int in; + FILE *fp; + int in; { for (; in; in--) fputc('\t', fp); } static void printeq(fp, var, m, max, v) -FILE *fp; -char *var; -int m, max, v; + FILE *fp; + char *var; + int m, max, v; { if (m == max) fprintf(fp, "%s == %#x) {\n", var, v); @@ -276,9 +283,9 @@ int m, max, v; * v - required address */ static void printipeq(fp, var, fl, m, v) -FILE *fp; -char *var; -int fl, m, v; + FILE *fp; + char *var; + int fl, m, v; { if (m == 0xffffffff) fprintf(fp, "%s ", var); @@ -290,9 +297,9 @@ int fl, m, v; void emit(num, dir, v, fr) -int num, dir; -void *v; -frentry_t *fr; + int num, dir; + void *v; + frentry_t *fr; { u_int incnt, outcnt; frgroup_t *g; @@ -342,8 +349,8 @@ frentry_t *fr; static void emitheader(grp, incount, outcount) -frgroup_t *grp; -u_int incount, outcount; + frgroup_t *grp; + u_int incount, outcount; { static FILE *fph = NULL; frgroup_t *g; @@ -434,11 +441,11 @@ int ipfrule_remove()\n\ static void emitGroup(num, dir, v, fr, group, incount, outcount) -int num, dir; -void *v; -frentry_t *fr; -char *group; -u_int incount, outcount; + int num, dir; + void *v; + frentry_t *fr; + char *group; + u_int incount, outcount; { static FILE *fp = NULL; static int header[2] = { 0, 0 }; @@ -514,9 +521,8 @@ u_int incount, outcount; if ((i & 1) == 0) { fprintf(fp, "\n\t"); } - fprintf(fp, - "(frentry_t *)&in_rule_%s_%d", - f->fr_group, i); + fprintf(fp, "(frentry_t *)&in_rule_%s_%d", + FR_NAME(f, fr_group), i); if (i + 1 < incount) fprintf(fp, ", "); i++; @@ -534,9 +540,8 @@ u_int incount, outcount; if ((i & 1) == 0) { fprintf(fp, "\n\t"); } - fprintf(fp, - "(frentry_t *)&out_rule_%s_%d", - f->fr_group, i); + fprintf(fp, "(frentry_t *)&out_rule_%s_%d", + FR_NAME(f, fr_group), i); if (i + 1 < outcount) fprintf(fp, ", "); i++; @@ -586,7 +591,7 @@ u_int incount, outcount; switch(m[i].c) { case FRC_IFN : - if (*fr->fr_ifname) + if (fr->fr_ifnames[0] != -1) m[i].s = 1; break; case FRC_V : @@ -940,11 +945,11 @@ u_int incount, outcount; if (fr->fr_flags & FR_QUICK) { fprintf(fp, "return (frentry_t *)&%s_rule_%s_%d;\n", fr->fr_flags & FR_INQUE ? "in" : "out", - fr->fr_group, num); + FR_NAME(fr, fr_group), num); } else { fprintf(fp, "fr = (frentry_t *)&%s_rule_%s_%d;\n", fr->fr_flags & FR_INQUE ? "in" : "out", - fr->fr_group, num); + FR_NAME(fr, fr_group), num); } if (n == NULL) n = (mc_t *)malloc(sizeof(*n) * FRC_MAX); @@ -954,7 +959,7 @@ u_int incount, outcount; void printC(dir) -int dir; + int dir; { static mc_t *m = NULL; frgroup_t *g; @@ -977,10 +982,10 @@ int dir; * Now print out code to implement all of the rules. */ static void printCgroup(dir, top, m, group) -int dir; -frentry_t *top; -mc_t *m; -char *group; + int dir; + frentry_t *top; + mc_t *m; + char *group; { frentry_t *fr, *fr1; int i, n, rn; @@ -1027,13 +1032,14 @@ char *group; continue; if ((n & 0x0001) && - !strcmp(fr1->fr_ifname, fr->fr_ifname)) { + !strcmp(fr1->fr_names + fr1->fr_ifnames[0], + fr->fr_names + fr->fr_ifnames[0])) { m[FRC_IFN].e++; m[FRC_IFN].n++; } else n &= ~0x0001; - if ((n & 0x0002) && (fr1->fr_v == fr->fr_v)) { + if ((n & 0x0002) && (fr1->fr_family == fr->fr_family)) { m[FRC_V].e++; m[FRC_V].n++; } else @@ -1226,10 +1232,10 @@ char *group; } static void printhooks(fp, in, out, grp) -FILE *fp; -int in; -int out; -frgroup_t *grp; + FILE *fp; + int in; + int out; + frgroup_t *grp; { frentry_t *fr; char *group; @@ -1237,7 +1243,7 @@ frgroup_t *grp; char *instr; group = grp->fg_name; - dogrp = *group ? 1 : 0; + dogrp = 0; if (in && out) { fprintf(stderr, @@ -1283,18 +1289,24 @@ int ipfrule_add_%s_%s()\n", instr, group); fprintf(fp, "\ for (j = i + 1; j < max; j++)\n\ - if (strncmp(fp->fr_group,\n\ + if (strncmp(fp->fr_names + fp->fr_group,\n\ + ipf_rules_%s_%s[j]->fr_names +\n\ ipf_rules_%s_%s[j]->fr_group,\n\ FR_GROUPLEN) == 0) {\n\ + if (ipf_rules_%s_%s[j] != NULL)\n\ + ipf_rules_%s_%s[j]->fr_pnext =\n\ + &fp->fr_next;\n\ + fp->fr_pnext = &ipf_rules_%s_%s[j];\n\ fp->fr_next = ipf_rules_%s_%s[j];\n\ break;\n\ - }\n", instr, group, instr, group); + }\n", instr, group, instr, group, instr, group, + instr, group, instr, group, instr, group); if (dogrp) fprintf(fp, "\ \n\ - if (fp->fr_grhead != 0) {\n\ - fg = fr_addgroup(fp->fr_grhead, fp, FR_INQUE,\n\ - IPL_LOGIPF, 0);\n\ + if (fp->fr_grhead != -1) {\n\ + fg = fr_addgroup(fp->fr_names + fp->fr_grhead,\n\ + fp, FR_INQUE, IPL_LOGIPF, 0);\n\ if (fg != NULL)\n\ fp->fr_grp = &fg->fg_start;\n\ }\n"); @@ -1304,7 +1316,7 @@ int ipfrule_add_%s_%s()\n", instr, group); fp = &ipfrule_%s_%s;\n", instr, group); fprintf(fp, "\ bzero((char *)fp, sizeof(*fp));\n\ - fp->fr_type = FR_T_CALLFUNC|FR_T_BUILTIN;\n\ + fp->fr_type = FR_T_CALLFUNC_BUILTIN;\n\ fp->fr_flags = FR_%sQUE|FR_NOMATCH;\n\ fp->fr_data = (void *)ipf_rules_%s_%s[0];\n", (in != 0) ? "IN" : "OUT", instr, group); @@ -1313,9 +1325,10 @@ int ipfrule_add_%s_%s()\n", instr, group); instr, group); fprintf(fp, "\ - fp->fr_v = 4;\n\ + fp->fr_family = AF_INET;\n\ fp->fr_func = (ipfunc_t)ipfrule_match_%s_%s;\n\ - err = frrequest(IPL_LOGIPF, SIOCADDFR, (caddr_t)fp, fr_active, 0);\n", + err = frrequest(&ipfmain, IPL_LOGIPF, SIOCADDFR, (caddr_t)fp,\n\ + ipfmain.ipf_active, 0);\n", instr, group); fprintf(fp, "\treturn err;\n}\n"); @@ -1348,8 +1361,9 @@ int ipfrule_remove_%s_%s()\n", instr, group); }\n\ }\n\ if (err == 0)\n\ - err = frrequest(IPL_LOGIPF, SIOCDELFR,\n\ - (caddr_t)&ipfrule_%s_%s, fr_active, 0);\n", + err = frrequest(&ipfmain, IPL_LOGIPF, SIOCDELFR,\n\ + (caddr_t)&ipfrule_%s_%s,\n\ + ipfmain.ipf_active, 0);\n", instr, group, instr, group, instr, group); fprintf(fp, "\ if (err)\n\ diff --git a/contrib/ipfilter/tools/ipfs.c b/contrib/ipfilter/tools/ipfs.c index eab650a7ee36..b5484be2193c 100644 --- a/contrib/ipfilter/tools/ipfs.c +++ b/contrib/ipfilter/tools/ipfs.c @@ -1,7 +1,7 @@ /* $FreeBSD$ */ /* - * Copyright (C) 2001-2006 by Darren Reed. + * Copyright (C) 2012 by Darren Reed. * * See the IPFILTER.LICENCE file for details on licencing. */ @@ -44,7 +44,7 @@ #include "netinet/ipl.h" #if !defined(lint) -static const char rcsid[] = "@(#)Id: ipfs.c,v 1.12 2003/12/01 01:56:53 darrenr Exp"; +static const char rcsid[] = "@(#)$Id$"; #endif #ifndef IPF_SAVEDIR @@ -100,7 +100,7 @@ void usage() * Change interface names in state information saved out to disk. */ int changestateif(ifs, fname) -char *ifs, *fname; + char *ifs, *fname; { int fd, olen, nlen, rw; ipstate_save_t ips; @@ -163,7 +163,7 @@ char *ifs, *fname; * Change interface names in NAT information saved out to disk. */ int changenatif(ifs, fname) -char *ifs, *fname; + char *ifs, *fname; { int fd, olen, nlen, rw; nat_save_t ipn; @@ -198,14 +198,6 @@ char *ifs, *fname; strcpy(nat->nat_ifnames[1], s); rw = 1; } - if (!strncmp(nat->nat_ifnames[2], ifs, olen + 1)) { - strcpy(nat->nat_ifnames[2], s); - rw = 1; - } - if (!strncmp(nat->nat_ifnames[3], ifs, olen + 1)) { - strcpy(nat->nat_ifnames[3], s); - rw = 1; - } if (rw == 1) { if (lseek(fd, pos, SEEK_SET) != pos) { perror("lseek"); @@ -225,8 +217,8 @@ char *ifs, *fname; int main(argc,argv) -int argc; -char *argv[]; + int argc; + char *argv[]; { int c, lock = -1, devfd = -1, err = 0, rw = -1, ns = -1, set = 0; char *dirname = NULL, *filename = NULL, *ifs = NULL; @@ -356,7 +348,7 @@ char *argv[]; int opendevice(ipfdev) -char *ipfdev; + char *ipfdev; { int fd = -1; @@ -374,14 +366,14 @@ char *ipfdev; void closedevice(fd) -int fd; + int fd; { close(fd); } int setlock(fd, lock) -int fd, lock; + int fd, lock; { if (opts & OPT_VERBOSE) printf("Turn lock %s\n", lock ? "on" : "off"); @@ -398,8 +390,8 @@ int fd, lock; int writestate(fd, file) -int fd; -char *file; + int fd; + char *file; { ipstate_save_t ips, *ipsp; ipfobj_t obj; @@ -450,8 +442,8 @@ char *file; int readstate(fd, file) -int fd; -char *file; + int fd; + char *file; { ipstate_save_t ips, *is, *ipshead = NULL, *is1, *ipstail = NULL; int sfd = -1, i; @@ -567,8 +559,8 @@ char *file; int readnat(fd, file) -int fd; -char *file; + int fd; + char *file; { nat_save_t ipn, *in, *ipnhead = NULL, *in1, *ipntail = NULL; ipfobj_t obj; @@ -714,8 +706,8 @@ char *file; int writenat(fd, file) -int fd; -char *file; + int fd; + char *file; { nat_save_t *ipnp = NULL, *next = NULL; ipfobj_t obj; @@ -798,7 +790,7 @@ char *file; int writeall(dirname) -char *dirname; + char *dirname; { int fd, devfd; @@ -849,7 +841,7 @@ char *dirname; int readall(dirname) -char *dirname; + char *dirname; { int fd, devfd; diff --git a/contrib/ipfilter/tools/ipfstat.c b/contrib/ipfilter/tools/ipfstat.c index 3c5bfdd50ac4..3261cef8e4d2 100644 --- a/contrib/ipfilter/tools/ipfstat.c +++ b/contrib/ipfilter/tools/ipfstat.c @@ -1,7 +1,7 @@ /* $FreeBSD$ */ /* - * Copyright (C) 2002-2006 by Darren Reed. + * Copyright (C) 2012 by Darren Reed. * * See the IPFILTER.LICENCE file for details on licencing. */ @@ -15,6 +15,7 @@ # endif #endif #include +#include #include #ifdef linux # include @@ -71,7 +72,7 @@ #if !defined(lint) static const char sccsid[] = "@(#)fils.c 1.21 4/20/96 (C) 1993-2000 Darren Reed"; -static const char rcsid[] = "@(#)$Id: ipfstat.c,v 1.44.2.25 2007/06/30 09:48:50 darrenr Exp $"; +static const char rcsid[] = "@(#)$Id$"; #endif #ifdef __hpux @@ -87,7 +88,9 @@ extern int opterr; static char *filters[4] = { "ipfilter(in)", "ipfilter(out)", "ipacct(in)", "ipacct(out)" }; static int state_logging = -1; +static wordtab_t *state_fields = NULL; +int nohdrfields = 0; int opts = 0; int use_inet6 = 0; int live_kernel = 1; @@ -98,6 +101,26 @@ int nat_fd = -1; frgroup_t *grtop = NULL; frgroup_t *grtail = NULL; +char *blockreasons[FRB_MAX_VALUE + 1] = { + "packet blocked", + "log rule failure", + "pps rate exceeded", + "jumbogram", + "makefrip failed", + "cannot add state", + "IP ID update failed", + "log-or-block failed", + "decapsulate failure", + "cannot create new auth entry", + "packet queued for auth", + "buffer coalesce failure", + "buffer pullup failure", + "auth feedback", + "bad fragment", + "IPv4 NAT failure", + "IPv6 NAT failure" +}; + #ifdef STATETOP #define STSTRSIZE 80 #define STGROWSIZE 16 @@ -135,22 +158,27 @@ static int fetchfrag __P((int, int, ipfr_t *)); static void showstats __P((friostat_t *, u_32_t)); static void showfrstates __P((ipfrstat_t *, u_long)); static void showlist __P((friostat_t *)); -static void showipstates __P((ips_stat_t *)); -static void showauthstates __P((fr_authstat_t *)); +static void showstatestats __P((ips_stat_t *)); +static void showipstates __P((ips_stat_t *, int *)); +static void showauthstates __P((ipf_authstat_t *)); +static void showtqtable_live __P((int)); static void showgroups __P((friostat_t *)); static void usage __P((char *)); -static void showtqtable_live __P((int)); -static void printlivelist __P((int, int, frentry_t *, char *, char *)); -static void printdeadlist __P((int, int, frentry_t *, char *, char *)); +static int state_matcharray __P((ipstate_t *, int *)); +static int printlivelist __P((friostat_t *, int, int, frentry_t *, + char *, char *)); +static void printdeadlist __P((friostat_t *, int, int, frentry_t *, + char *, char *)); +static void printside __P((char *, ipf_statistics_t *)); static void parse_ipportstr __P((const char *, i6addr_t *, int *)); static void ipfstate_live __P((char *, friostat_t **, ips_stat_t **, - ipfrstat_t **, fr_authstat_t **, u_32_t *)); + ipfrstat_t **, ipf_authstat_t **, u_32_t *)); static void ipfstate_dead __P((char *, friostat_t **, ips_stat_t **, - ipfrstat_t **, fr_authstat_t **, u_32_t *)); + ipfrstat_t **, ipf_authstat_t **, u_32_t *)); static ipstate_t *fetchstate __P((ipstate_t *, ipstate_t *)); #ifdef STATETOP static void topipstates __P((i6addr_t, i6addr_t, int, int, int, - int, int, int)); + int, int, int, int *)); static void sig_break __P((int)); static void sig_resize __P((int)); static char *getip __P((int, i6addr_t *)); @@ -167,7 +195,7 @@ static int sort_dstpt __P((const void *, const void *)); static void usage(name) -char *name; + char *name; { #ifdef USE_INET6 fprintf(stderr, "Usage: %s [-6aAdfghIilnoRsv]\n", name); @@ -186,20 +214,23 @@ char *name; int main(argc,argv) -int argc; -char *argv[]; + int argc; + char *argv[]; { - fr_authstat_t frauthst; - fr_authstat_t *frauthstp = &frauthst; + ipf_authstat_t frauthst; + ipf_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 *memf = NULL; - char *options, *kern = NULL; - int c, myoptind; + char *options; + char *kern = NULL; + char *memf = NULL; + int c; + int myoptind; + int *filter = NULL; int protocol = -1; /* -1 = wild card for any protocol */ int refreshtime = 1; /* default update time */ @@ -210,9 +241,9 @@ char *argv[]; u_32_t frf; #ifdef USE_INET6 - options = "6aACdfghIilnostvD:M:N:P:RS:T:"; + options = "6aACdfghIilnostvD:m:M:N:O:P:RS:T:"; #else - options = "aACdfghIilnostvD:M:N:P:RS:T:"; + options = "aACdfghIilnostvD:m:M:N:O:P:RS:T:"; #endif saddr.in4.s_addr = INADDR_ANY; /* default any v4 source addr */ @@ -324,6 +355,14 @@ char *argv[]; case 'l' : opts |= OPT_SHOWLIST; break; + case 'm' : + filter = parseipfexpr(optarg, NULL); + if (filter == NULL) { + fprintf(stderr, "Error parseing '%s'\n", + optarg); + exit(1); + } + break; case 'M' : break; case 'N' : @@ -334,6 +373,9 @@ char *argv[]; case 'o' : opts |= OPT_OUTQUE|OPT_SHOWLIST; break; + case 'O' : + state_fields = parsefields(statefields, optarg); + break; case 'P' : protocol = getproto(optarg); if (protocol == -1) { @@ -386,11 +428,12 @@ char *argv[]; ipfstate_live(IPL_NAME, &fiop, &ipsstp, &ifrstp, &frauthstp, &frf); - } else + } else { ipfstate_dead(kern, &fiop, &ipsstp, &ifrstp, &frauthstp, &frf); + } if (opts & OPT_IPSTATES) { - showipstates(ipsstp); + showipstates(ipsstp, filter); } else if (opts & OPT_SHOWLIST) { showlist(fiop); if ((opts & OPT_OUTQUE) && (opts & OPT_INQUE)){ @@ -402,7 +445,7 @@ char *argv[]; #ifdef STATETOP else if (opts & OPT_STATETOP) topipstates(saddr, daddr, sport, dport, protocol, - use_inet6 ? 6 : 4, refreshtime, topclosed); + use_inet6 ? 6 : 4, refreshtime, topclosed, filter); #endif else if (opts & OPT_AUTHSTATS) showauthstates(frauthstp); @@ -420,12 +463,12 @@ char *argv[]; * of ioctl's and copying directly from kernel memory. */ static void ipfstate_live(device, fiopp, ipsstpp, ifrstpp, frauthstpp, frfp) -char *device; -friostat_t **fiopp; -ips_stat_t **ipsstpp; -ipfrstat_t **ifrstpp; -fr_authstat_t **frauthstpp; -u_32_t *frfp; + char *device; + friostat_t **fiopp; + ips_stat_t **ipsstpp; + ipfrstat_t **ifrstpp; + ipf_authstat_t **frauthstpp; + u_32_t *frfp; { ipfobj_t ipfo; @@ -442,12 +485,12 @@ u_32_t *frfp; ipfo.ipfo_ptr = (void *)*fiopp; if (ioctl(ipf_fd, SIOCGETFS, &ipfo) == -1) { - perror("ioctl(ipf:SIOCGETFS)"); + ipferror(ipf_fd, "ioctl(ipf:SIOCGETFS)"); exit(-1); } if (ioctl(ipf_fd, SIOCGETFF, frfp) == -1) - perror("ioctl(SIOCGETFF)"); + ipferror(ipf_fd, "ioctl(SIOCGETFF)"); } if ((opts & OPT_IPSTATES) != 0) { @@ -459,11 +502,11 @@ u_32_t *frfp; ipfo.ipfo_ptr = (void *)*ipsstpp; if ((ioctl(state_fd, SIOCGETFS, &ipfo) == -1)) { - perror("ioctl(state:SIOCGETFS)"); + ipferror(state_fd, "ioctl(state:SIOCGETFS)"); exit(-1); } if (ioctl(state_fd, SIOCGETLG, &state_logging) == -1) { - perror("ioctl(state:SIOCGETLG)"); + ipferror(state_fd, "ioctl(state:SIOCGETLG)"); exit(-1); } } @@ -474,9 +517,9 @@ u_32_t *frfp; ipfo.ipfo_type = IPFOBJ_FRAGSTAT; ipfo.ipfo_size = sizeof(ipfrstat_t); ipfo.ipfo_ptr = (void *)*ifrstpp; - + if (ioctl(ipf_fd, SIOCGFRST, &ipfo) == -1) { - perror("ioctl(SIOCGFRST)"); + ipferror(ipf_fd, "ioctl(SIOCGFRST)"); exit(-1); } } @@ -488,11 +531,11 @@ u_32_t *frfp; bzero((caddr_t)&ipfo, sizeof(ipfo)); ipfo.ipfo_rev = IPFILTER_VERSION; ipfo.ipfo_type = IPFOBJ_AUTHSTAT; - ipfo.ipfo_size = sizeof(fr_authstat_t); + ipfo.ipfo_size = sizeof(ipf_authstat_t); ipfo.ipfo_ptr = (void *)*frauthstpp; if (ioctl(auth_fd, SIOCATHST, &ipfo) == -1) { - perror("ioctl(SIOCATHST)"); + ipferror(auth_fd, "ioctl(SIOCATHST)"); exit(-1); } } @@ -505,66 +548,64 @@ u_32_t *frfp; * just won't work any more. */ static void ipfstate_dead(kernel, fiopp, ipsstpp, ifrstpp, frauthstpp, frfp) -char *kernel; -friostat_t **fiopp; -ips_stat_t **ipsstpp; -ipfrstat_t **ifrstpp; -fr_authstat_t **frauthstpp; -u_32_t *frfp; + char *kernel; + friostat_t **fiopp; + ips_stat_t **ipsstpp; + ipfrstat_t **ifrstpp; + ipf_authstat_t **frauthstpp; + u_32_t *frfp; { - static fr_authstat_t frauthst, *frauthstp; + static ipf_authstat_t frauthst, *frauthstp; + static ipftq_t ipstcptab[IPF_TCP_NSTATES]; static ips_stat_t ipsst, *ipsstp; static ipfrstat_t ifrst, *ifrstp; static friostat_t fio, *fiop; - static ipftq_t ipssttab[IPF_TCP_NSTATES]; int temp; void *rules[2][2]; struct nlist deadlist[44] = { - { "fr_authstats" }, /* 0 */ - { "fae_list" }, - { "ipauth" }, - { "fr_authlist" }, - { "fr_authstart" }, - { "fr_authend" }, /* 5 */ - { "fr_authnext" }, - { "fr_auth" }, - { "fr_authused" }, - { "fr_authsize" }, - { "fr_defaultauthage" }, /* 10 */ - { "fr_authpkts" }, - { "fr_auth_lock" }, - { "frstats" }, - { "ips_stats" }, - { "ips_num" }, /* 15 */ - { "ips_wild" }, - { "ips_list" }, - { "ips_table" }, - { "fr_statemax" }, - { "fr_statesize" }, /* 20 */ - { "fr_state_doflush" }, - { "fr_state_lock" }, - { "ipfr_heads" }, - { "ipfr_nattab" }, - { "ipfr_stats" }, /* 25 */ - { "ipfr_inuse" }, - { "fr_ipfrttl" }, - { "fr_frag_lock" }, - { "ipfr_timer_id" }, - { "fr_nat_lock" }, /* 30 */ - { "ipfilter" }, - { "ipfilter6" }, - { "ipacct" }, - { "ipacct6" }, - { "ipl_frouteok" }, /* 35 */ - { "fr_running" }, - { "ipfgroups" }, - { "fr_active" }, - { "fr_pass" }, - { "fr_flags" }, /* 40 */ - { "ipstate_logging" }, - { "ips_tqtqb" }, - { NULL } + { "ipf_auth_stats", 0, 0, 0, 0 }, /* 0 */ + { "fae_list", 0, 0, 0, 0 }, + { "ipauth", 0, 0, 0, 0 }, + { "ipf_auth_list", 0, 0, 0, 0 }, + { "ipf_auth_start", 0, 0, 0, 0 }, + { "ipf_auth_end", 0, 0, 0, 0 }, /* 5 */ + { "ipf_auth_next", 0, 0, 0, 0 }, + { "ipf_auth", 0, 0, 0, 0 }, + { "ipf_auth_used", 0, 0, 0, 0 }, + { "ipf_auth_size", 0, 0, 0, 0 }, + { "ipf_auth_defaultage", 0, 0, 0, 0 }, /* 10 */ + { "ipf_auth_pkts", 0, 0, 0, 0 }, + { "ipf_auth_lock", 0, 0, 0, 0 }, + { "frstats", 0, 0, 0, 0 }, + { "ips_stats", 0, 0, 0, 0 }, + { "ips_num", 0, 0, 0, 0 }, /* 15 */ + { "ips_wild", 0, 0, 0, 0 }, + { "ips_list", 0, 0, 0, 0 }, + { "ips_table", 0, 0, 0, 0 }, + { "ipf_state_max", 0, 0, 0, 0 }, + { "ipf_state_size", 0, 0, 0, 0 }, /* 20 */ + { "ipf_state_doflush", 0, 0, 0, 0 }, + { "ipf_state_lock", 0, 0, 0, 0 }, + { "ipfr_heads", 0, 0, 0, 0 }, + { "ipfr_nattab", 0, 0, 0, 0 }, + { "ipfr_stats", 0, 0, 0, 0 }, /* 25 */ + { "ipfr_inuse", 0, 0, 0, 0 }, + { "ipf_ipfrttl", 0, 0, 0, 0 }, + { "ipf_frag_lock", 0, 0, 0, 0 }, + { "ipfr_timer_id", 0, 0, 0, 0 }, + { "ipf_nat_lock", 0, 0, 0, 0 }, /* 30 */ + { "ipf_rules", 0, 0, 0, 0 }, + { "ipf_acct", 0, 0, 0, 0 }, + { "ipl_frouteok", 0, 0, 0, 0 }, + { "ipf_running", 0, 0, 0, 0 }, + { "ipf_groups", 0, 0, 0, 0 }, /* 35 */ + { "ipf_active", 0, 0, 0, 0 }, + { "ipf_pass", 0, 0, 0, 0 }, + { "ipf_flags", 0, 0, 0, 0 }, + { "ipf_state_logging", 0, 0, 0, 0 }, + { "ips_tqtqb", 0, 0, 0, 0 }, /* 40 */ + { NULL, 0, 0, 0, 0 } }; @@ -617,23 +658,6 @@ u_32_t *frfp; fiop->f_fout[0] = rules[1][0]; fiop->f_fout[1] = rules[1][1]; - /* - * Same for IPv6, except make them null if support for it is not - * being compiled in. - */ -#ifdef USE_INET6 - kmemcpy((char *)&rules, (u_long)deadlist[32].n_value, sizeof(rules)); - fiop->f_fin6[0] = rules[0][0]; - fiop->f_fin6[1] = rules[0][1]; - fiop->f_fout6[0] = rules[1][0]; - fiop->f_fout6[1] = rules[1][1]; -#else - fiop->f_fin6[0] = NULL; - fiop->f_fin6[1] = NULL; - fiop->f_fout6[0] = NULL; - fiop->f_fout6[1] = NULL; -#endif - /* * Now get accounting rules pointers. */ @@ -643,32 +667,19 @@ u_32_t *frfp; fiop->f_acctout[0] = rules[1][0]; fiop->f_acctout[1] = rules[1][1]; -#ifdef USE_INET6 - kmemcpy((char *)&rules, (u_long)deadlist[34].n_value, sizeof(rules)); - fiop->f_acctin6[0] = rules[0][0]; - fiop->f_acctin6[1] = rules[0][1]; - fiop->f_acctout6[0] = rules[1][0]; - fiop->f_acctout6[1] = rules[1][1]; -#else - fiop->f_acctin6[0] = NULL; - fiop->f_acctin6[1] = NULL; - fiop->f_acctout6[0] = NULL; - fiop->f_acctout6[1] = NULL; -#endif - /* * A collection of "global" variables used inside the kernel which * are all collected in friostat_t via ioctl. */ - kmemcpy((char *)&fiop->f_froute, (u_long)deadlist[35].n_value, + kmemcpy((char *)&fiop->f_froute, (u_long)deadlist[33].n_value, sizeof(fiop->f_froute)); - kmemcpy((char *)&fiop->f_running, (u_long)deadlist[36].n_value, + kmemcpy((char *)&fiop->f_running, (u_long)deadlist[34].n_value, sizeof(fiop->f_running)); - kmemcpy((char *)&fiop->f_groups, (u_long)deadlist[37].n_value, + kmemcpy((char *)&fiop->f_groups, (u_long)deadlist[35].n_value, sizeof(fiop->f_groups)); - kmemcpy((char *)&fiop->f_active, (u_long)deadlist[38].n_value, + kmemcpy((char *)&fiop->f_active, (u_long)deadlist[36].n_value, sizeof(fiop->f_active)); - kmemcpy((char *)&fiop->f_defpass, (u_long)deadlist[39].n_value, + kmemcpy((char *)&fiop->f_defpass, (u_long)deadlist[37].n_value, sizeof(fiop->f_defpass)); /* @@ -676,12 +687,12 @@ u_32_t *frfp; */ kmemcpy((char *)ipsstp, (u_long)deadlist[14].n_value, sizeof(*ipsstp)); kmemcpy((char *)&temp, (u_long)deadlist[15].n_value, sizeof(temp)); - kmemcpy((char *)ipssttab, (u_long)deadlist[42].n_value, - sizeof(ipssttab)); + kmemcpy((char *)ipstcptab, (u_long)deadlist[40].n_value, + sizeof(ipstcptab)); ipsstp->iss_active = temp; ipsstp->iss_table = (void *)deadlist[18].n_value; ipsstp->iss_list = (void *)deadlist[17].n_value; - ipsstp->iss_tcptab = ipssttab; + ipsstp->iss_tcptab = ipstcptab; /* * Build up the authentiation information stats structure. @@ -708,65 +719,62 @@ u_32_t *frfp; } +static void printside(side, frs) + char *side; + ipf_statistics_t *frs; +{ + int i; + + PRINTF("%lu\t%s bad packets\n", frs->fr_bad, side); +#ifdef USE_INET6 + PRINTF("%lu\t%s IPv6 packets\n", frs->fr_ipv6, side); +#endif + PRINTF("%lu\t%s packets blocked\n", frs->fr_block, side); + PRINTF("%lu\t%s packets passed\n", frs->fr_pass, side); + PRINTF("%lu\t%s packets not matched\n", frs->fr_nom, side); + PRINTF("%lu\t%s packets counted\n", frs->fr_acct, side); + PRINTF("%lu\t%s packets short\n", frs->fr_short, side); + PRINTF("%lu\t%s packets logged and blocked\n", frs->fr_bpkl, side); + PRINTF("%lu\t%s packets logged and passed\n", frs->fr_ppkl, side); + PRINTF("%lu\t%s fragment state kept\n", frs->fr_nfr, side); + PRINTF("%lu\t%s fragment state lost\n", frs->fr_bnfr, side); + PRINTF("%lu\t%s packet state kept\n", frs->fr_ads, side); + PRINTF("%lu\t%s packet state lost\n", frs->fr_bads, side); + PRINTF("%lu\t%s invalid source\n", frs->fr_v4_badsrc, side); + PRINTF("%lu\t%s cache hits\n", frs->fr_chit, side); + PRINTF("%lu\t%s cache misses\n", frs->fr_cmiss, side); + PRINTF("%lu\t%s bad coalesces\n", frs->fr_badcoalesces, side); + PRINTF("%lu\t%s pullups succeeded\n", frs->fr_pull[0], side); + PRINTF("%lu\t%s pullups failed\n", frs->fr_pull[1], side); + PRINTF("%lu\t%s TCP checksum failures\n", frs->fr_tcpbad, side); + for (i = 0; i <= FRB_MAX_VALUE; i++) + PRINTF("%lu\t%s block reason %s\n", + frs->fr_blocked[i], side, blockreasons[i]); +} + + /* * Display the kernel stats for packets blocked and passed and other * associated running totals which are kept. */ static void showstats(fp, frf) -struct friostat *fp; -u_32_t frf; + struct friostat *fp; + u_32_t frf; { + printside("input", &fp->f_st[0]); + printside("output", &fp->f_st[1]); - PRINTF("bad packets:\t\tin %lu\tout %lu\n", - fp->f_st[0].fr_bad, fp->f_st[1].fr_bad); -#ifdef USE_INET6 - PRINTF(" IPv6 packets:\t\tin %lu out %lu\n", - fp->f_st[0].fr_ipv6, fp->f_st[1].fr_ipv6); -#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", - fp->f_st[0].fr_acct, fp->f_st[0].fr_short); - 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", - fp->f_st[1].fr_acct, fp->f_st[1].fr_short); - 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", - fp->f_st[1].fr_bpkl, fp->f_st[1].fr_ppkl); - 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", - fp->f_st[0].fr_skip, fp->f_st[1].fr_skip); - PRINTF("fragment state(in):\tkept %lu\tlost %lu\tnot fragmented %lu\n", - fp->f_st[0].fr_nfr, fp->f_st[0].fr_bnfr, - fp->f_st[0].fr_cfr); - PRINTF("fragment state(out):\tkept %lu\tlost %lu\tnot fragmented %lu\n", - fp->f_st[1].fr_nfr, fp->f_st[1].fr_bnfr, - fp->f_st[0].fr_cfr); - 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", - fp->f_st[1].fr_ads, fp->f_st[1].fr_bads); - PRINTF("ICMP replies:\t%lu\tTCP RSTs sent:\t%lu\n", - fp->f_st[0].fr_ret, fp->f_st[1].fr_ret); - 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", - fp->f_st[0].fr_pull[0], fp->f_st[0].fr_pull[1]); - 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", - fp->f_froute[0], fp->f_froute[1]); - 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("IPF Ticks:\t%lu\n", fp->f_ticks); + PRINTF("%lu\tpackets logged\n", fp->f_log_ok); + PRINTF("%lu\tlog failures\n", fp->f_log_fail); + PRINTF("%lu\tred-black no memory\n", fp->f_rb_no_mem); + PRINTF("%lu\tred-black node maximum\n", fp->f_rb_node_max); + PRINTF("%lu\tICMP replies sent\n", fp->f_st[0].fr_ret); + PRINTF("%lu\tTCP RSTs sent\n", fp->f_st[1].fr_ret); + PRINTF("%lu\tfastroute successes\n", fp->f_froute[0]); + PRINTF("%lu\tfastroute failures\n", fp->f_froute[1]); + PRINTF("%u\tIPF Ticks\n", fp->f_ticks); - PRINTF("Packet log flags set: (%#x)\n", frf); + PRINTF("%x\tPacket log flags set:\n", frf); if (frf & FF_LOGPASS) PRINTF("\tpackets passed through filter\n"); if (frf & FF_LOGBLOCK) @@ -781,30 +789,27 @@ u_32_t frf; /* * Print out a list of rules from the kernel, starting at the one passed. */ -static void printlivelist(out, set, fp, group, comment) -int out, set; -frentry_t *fp; -char *group, *comment; +static int +printlivelist(fiop, out, set, fp, group, comment) + struct friostat *fiop; + int out, set; + frentry_t *fp; + char *group, *comment; { struct frentry fb; ipfruleiter_t rule; frentry_t zero; frgroup_t *g; ipfobj_t obj; - int n; + int rules; + int num; - if (use_inet6 == 1) - fb.fr_v = 6; - else - fb.fr_v = 4; - fb.fr_next = fp; - n = 0; + rules = 0; rule.iri_inout = out; rule.iri_active = set; rule.iri_rule = &fb; rule.iri_nrules = 1; - rule.iri_v = use_inet6 ? 6 : 4; if (group != NULL) strncpy(rule.iri_group, group, FR_GROUPLEN); else @@ -818,49 +823,65 @@ char *group, *comment; obj.ipfo_size = sizeof(rule); obj.ipfo_ptr = &rule; - do { + while (rule.iri_rule != NULL) { u_long array[1000]; memset(array, 0xff, sizeof(array)); fp = (frentry_t *)array; rule.iri_rule = fp; if (ioctl(ipf_fd, SIOCIPFITER, &obj) == -1) { - perror("ioctl(SIOCIPFITER)"); - n = IPFGENITER_IPF; - ioctl(ipf_fd, SIOCIPFDELTOK, &n); - return; + ipferror(ipf_fd, "ioctl(SIOCIPFITER)"); + num = IPFGENITER_IPF; + (void) ioctl(ipf_fd,SIOCIPFDELTOK, &num); + return rules; } if (bcmp(fp, &zero, sizeof(zero)) == 0) break; + if (rule.iri_rule == NULL) + break; +#ifdef USE_INET6 + if (use_inet6 != 0) { + if (fp->fr_family != 0 && fp->fr_family != AF_INET6) + continue; + } else +#endif + { + if (fp->fr_family != 0 && fp->fr_family != AF_INET) + continue; + } if (fp->fr_data != NULL) - fp->fr_data = (char *)fp + sizeof(*fp); + fp->fr_data = (char *)fp + fp->fr_size; - n++; + rules++; - if (opts & (OPT_HITS|OPT_VERBOSE)) + if (opts & (OPT_HITS|OPT_DEBUG)) #ifdef USE_QUAD_T - PRINTF("%qu ", (unsigned long long) fp->fr_hits); + PRINTF("%"PRIu64" ", (unsigned long long) fp->fr_hits); #else PRINTF("%lu ", fp->fr_hits); #endif - if (opts & (OPT_ACCNT|OPT_VERBOSE)) + if (opts & (OPT_ACCNT|OPT_DEBUG)) #ifdef USE_QUAD_T - PRINTF("%qu ", (unsigned long long) fp->fr_bytes); + PRINTF("%"PRIu64" ", (unsigned long long) fp->fr_bytes); #else PRINTF("%lu ", fp->fr_bytes); #endif if (opts & OPT_SHOWLINENO) - PRINTF("@%d ", n); + PRINTF("@%d ", rules); + + if (fp->fr_die != 0) + fp->fr_die -= fiop->f_ticks; printfr(fp, ioctl); if (opts & OPT_DEBUG) { - binprint(fp, sizeof(*fp)); + binprint(fp, fp->fr_size); if (fp->fr_data != NULL && fp->fr_dsize > 0) binprint(fp->fr_data, fp->fr_dsize); } - if (fp->fr_grhead[0] != '\0') { + if (fp->fr_grhead != -1) { for (g = grtop; g != NULL; g = g->fg_next) { - if (!strncmp(fp->fr_grhead, g->fg_name, + if (!strncmp(fp->fr_names + fp->fr_grhead, + g->fg_name, FR_GROUPLEN)) break; } @@ -868,7 +889,8 @@ char *group, *comment; g = calloc(1, sizeof(*g)); if (g != NULL) { - strncpy(g->fg_name, fp->fr_grhead, + strncpy(g->fg_name, + fp->fr_names + fp->fr_grhead, FR_GROUPLEN); if (grtop == NULL) { grtop = g; @@ -881,29 +903,23 @@ char *group, *comment; } } if (fp->fr_type == FR_T_CALLFUNC) { - printlivelist(out, set, fp->fr_data, group, - "# callfunc: "); - } - } while (fp->fr_next != NULL); - - n = IPFGENITER_IPF; - ioctl(ipf_fd, SIOCIPFDELTOK, &n); - - if (group == NULL) { - while ((g = grtop) != NULL) { - printf("# Group %s\n", g->fg_name); - printlivelist(out, set, NULL, g->fg_name, comment); - grtop = g->fg_next; - free(g); + rules += printlivelist(fiop, out, set, fp->fr_data, + group, "# callfunc: "); } } + + num = IPFGENITER_IPF; + (void) ioctl(ipf_fd,SIOCIPFDELTOK, &num); + + return rules; } -static void printdeadlist(out, set, fp, group, comment) -int out, set; -frentry_t *fp; -char *group, *comment; +static void printdeadlist(fiop, out, set, fp, group, comment) + friostat_t *fiop; + int out, set; + frentry_t *fp; + char *group, *comment; { frgroup_t *grtop, *grtail, *g; struct frentry fb; @@ -916,13 +932,20 @@ char *group, *comment; grtop = NULL; grtail = NULL; - do { - fp = fb.fr_next; + for (n = 1; fp; fp = fb.fr_next, n++) { if (kmemcpy((char *)&fb, (u_long)fb.fr_next, - sizeof(fb)) == -1) { + fb.fr_size) == -1) { perror("kmemcpy"); return; } + fp = &fb; + if (use_inet6 != 0) { + if (fp->fr_family != 0 && fp->fr_family != 6) + continue; + } else { + if (fp->fr_family != 0 && fp->fr_family != 4) + continue; + } data = NULL; type = fb.fr_type & ~FR_T_BUILTIN; @@ -939,17 +962,15 @@ char *group, *comment; } } - n++; - - if (opts & (OPT_HITS|OPT_VERBOSE)) + if (opts & OPT_HITS) #ifdef USE_QUAD_T - PRINTF("%qu ", (unsigned long long) fb.fr_hits); + PRINTF("%"PRIu64" ", (unsigned long long) fb.fr_hits); #else PRINTF("%lu ", fb.fr_hits); #endif - if (opts & (OPT_ACCNT|OPT_VERBOSE)) + if (opts & OPT_ACCNT) #ifdef USE_QUAD_T - PRINTF("%qu ", (unsigned long long) fb.fr_bytes); + PRINTF("%"PRIu64" ", (unsigned long long) fb.fr_bytes); #else PRINTF("%lu ", fb.fr_bytes); #endif @@ -958,17 +979,17 @@ char *group, *comment; printfr(fp, ioctl); if (opts & OPT_DEBUG) { - binprint(fp, sizeof(*fp)); + binprint(fp, fp->fr_size); if (fb.fr_data != NULL && fb.fr_dsize > 0) binprint(fb.fr_data, fb.fr_dsize); } if (data != NULL) free(data); - if (fb.fr_grhead[0] != '\0') { + if (fb.fr_grhead != -1) { g = calloc(1, sizeof(*g)); if (g != NULL) { - strncpy(g->fg_name, fb.fr_grhead, + strncpy(g->fg_name, fb.fr_names + fb.fr_grhead, FR_GROUPLEN); if (grtop == NULL) { grtop = g; @@ -980,13 +1001,13 @@ char *group, *comment; } } if (type == FR_T_CALLFUNC) { - printdeadlist(out, set, fb.fr_data, group, + printdeadlist(fiop, out, set, fb.fr_data, group, "# callfunc: "); } - } while (fb.fr_next != NULL); + } while ((g = grtop) != NULL) { - printdeadlist(out, set, NULL, g->fg_name, comment); + printdeadlist(fiop, out, set, NULL, g->fg_name, comment); grtop = g->fg_next; free(g); } @@ -997,7 +1018,7 @@ char *group, *comment; * the base from which to get the pointers. */ static void showlist(fiop) -struct friostat *fiop; + struct friostat *fiop; { struct frentry *fp = NULL; int i, set; @@ -1006,15 +1027,6 @@ struct friostat *fiop; if (opts & OPT_INACTIVE) set = 1 - set; if (opts & OPT_ACCNT) { -#ifdef USE_INET6 - if ((use_inet6) && (opts & OPT_OUTQUE)) { - i = F_ACOUT; - fp = (struct frentry *)fiop->f_acctout6[set]; - } else if ((use_inet6) && (opts & OPT_INQUE)) { - i = F_ACIN; - fp = (struct frentry *)fiop->f_acctin6[set]; - } else -#endif if (opts & OPT_OUTQUE) { i = F_ACOUT; fp = (struct frentry *)fiop->f_acctout[set]; @@ -1026,15 +1038,6 @@ struct friostat *fiop; 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]; @@ -1049,139 +1052,243 @@ struct friostat *fiop; if (opts & OPT_DEBUG) PRINTF("fp %p set %d\n", fp, set); - if (!fp) { - FPRINTF(stderr, "empty list for %s%s\n", - (opts & OPT_INACTIVE) ? "inactive " : "", filters[i]); - return; + + if (live_kernel == 1) { + int printed; + + printed = printlivelist(fiop, i, set, fp, NULL, NULL); + if (printed == 0) { + FPRINTF(stderr, "# empty list for %s%s\n", + (opts & OPT_INACTIVE) ? "inactive " : "", + filters[i]); + } + } else { + if (!fp) { + FPRINTF(stderr, "# empty list for %s%s\n", + (opts & OPT_INACTIVE) ? "inactive " : "", + filters[i]); + } else { + printdeadlist(fiop, i, set, fp, NULL, NULL); + } } - if (live_kernel == 1) - printlivelist(i, set, fp, NULL, NULL); - else - printdeadlist(i, set, fp, NULL, NULL); } /* * Display ipfilter stateful filtering information */ -static void showipstates(ipsp) -ips_stat_t *ipsp; +static void showipstates(ipsp, filter) + ips_stat_t *ipsp; + int *filter; { - u_long minlen, maxlen, totallen, *buckets; + ipstate_t *is; + int i; + + /* + * If a list of states hasn't been asked for, only print out stats + */ + if (!(opts & OPT_SHOWLIST)) { + showstatestats(ipsp); + return; + } + + if ((state_fields != NULL) && (nohdrfields == 0)) { + for (i = 0; state_fields[i].w_value != 0; i++) { + printfieldhdr(statefields, state_fields + i); + if (state_fields[i + 1].w_value != 0) + printf("\t"); + } + printf("\n"); + } + + /* + * Print out all the state information currently held in the kernel. + */ + for (is = ipsp->iss_list; is != NULL; ) { + ipstate_t ips; + + is = fetchstate(is, &ips); + + if (is == NULL) + break; + + is = ips.is_next; + if ((filter != NULL) && + (state_matcharray(&ips, filter) == 0)) { + continue; + } + if (state_fields != NULL) { + for (i = 0; state_fields[i].w_value != 0; i++) { + printstatefield(&ips, state_fields[i].w_value); + if (state_fields[i + 1].w_value != 0) + printf("\t"); + } + printf("\n"); + } else { + printstate(&ips, opts, ipsp->iss_ticks); + } + } +} + + +static void showstatestats(ipsp) + ips_stat_t *ipsp; +{ + int minlen, maxlen, totallen; ipftable_t table; + u_int *buckets; ipfobj_t obj; int i, sz; /* * If a list of states hasn't been asked for, only print out stats */ - if (!(opts & OPT_SHOWLIST)) { - sz = sizeof(*buckets) * ipsp->iss_statesize; - buckets = (u_long *)malloc(sz); + sz = sizeof(*buckets) * ipsp->iss_state_size; + buckets = (u_int *)malloc(sz); - obj.ipfo_rev = IPFILTER_VERSION; - obj.ipfo_type = IPFOBJ_GTABLE; - obj.ipfo_size = sizeof(table); - obj.ipfo_ptr = &table; + obj.ipfo_rev = IPFILTER_VERSION; + obj.ipfo_type = IPFOBJ_GTABLE; + obj.ipfo_size = sizeof(table); + obj.ipfo_ptr = &table; - table.ita_type = IPFTABLE_BUCKETS; - table.ita_table = buckets; + table.ita_type = IPFTABLE_BUCKETS; + table.ita_table = buckets; - if (live_kernel == 1) { - if (ioctl(state_fd, SIOCGTABL, &obj) != 0) { - free(buckets); - return; - } - } else { - if (kmemcpy((char *)buckets, - (u_long)ipsp->iss_bucketlen, sz)) { - free(buckets); - return; - } + if (live_kernel == 1) { + if (ioctl(state_fd, SIOCGTABL, &obj) != 0) { + free(buckets); + return; } - - 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 bucket full\n", ipsp->iss_bucketfull); - PRINTF("\t%lu maximum rule references\n", ipsp->iss_maxref); - 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); - - PRINTF("State logging %sabled\n", - state_logging ? "en" : "dis"); - - PRINTF("\nState table bucket statistics:\n"); - PRINTF("\t%lu in use\t\n", ipsp->iss_inuse); - PRINTF("\t%u%% hash efficiency\n", ipsp->iss_active ? - (u_int)(ipsp->iss_inuse * 100 / ipsp->iss_active) : 0); - - minlen = ipsp->iss_inuse; - totallen = 0; - maxlen = 0; - - for (i = 0; i < ipsp->iss_statesize; i++) { - if (buckets[i] > maxlen) - maxlen = buckets[i]; - if (buckets[i] < minlen) - minlen = buckets[i]; - totallen += buckets[i]; + } else { + if (kmemcpy((char *)buckets, + (u_long)ipsp->iss_bucketlen, sz)) { + free(buckets); + return; } + } - PRINTF("\t%2.2f%% bucket usage\n\t%lu minimal length\n", - ((float)ipsp->iss_inuse / ipsp->iss_statesize) * 100.0, - minlen); - PRINTF("\t%lu maximal length\n\t%.3f average length\n", - maxlen, - ipsp->iss_inuse ? (float) totallen/ ipsp->iss_inuse : - 0.0); + PRINTF("%u\tactive state table entries\n",ipsp->iss_active); + PRINTF("%lu\tadd bad\n", ipsp->iss_add_bad); + PRINTF("%lu\tadd duplicate\n", ipsp->iss_add_dup); + PRINTF("%lu\tadd locked\n", ipsp->iss_add_locked); + PRINTF("%lu\tadd oow\n", ipsp->iss_add_oow); + PRINTF("%lu\tbucket full\n", ipsp->iss_bucket_full); + PRINTF("%lu\tcheck bad\n", ipsp->iss_check_bad); + PRINTF("%lu\tcheck miss\n", ipsp->iss_check_miss); + PRINTF("%lu\tcheck nattag\n", ipsp->iss_check_nattag); + PRINTF("%lu\tclone nomem\n", ipsp->iss_clone_nomem); + PRINTF("%lu\tcheck notag\n", ipsp->iss_check_notag); + PRINTF("%lu\tcheck success\n", ipsp->iss_hits); + PRINTF("%lu\tcloned\n", ipsp->iss_cloned); + PRINTF("%lu\texpired\n", ipsp->iss_expire); + PRINTF("%lu\tflush all\n", ipsp->iss_flush_all); + PRINTF("%lu\tflush closing\n", ipsp->iss_flush_closing); + PRINTF("%lu\tflush queue\n", ipsp->iss_flush_queue); + PRINTF("%lu\tflush state\n", ipsp->iss_flush_state); + PRINTF("%lu\tflush timeout\n", ipsp->iss_flush_timeout); + PRINTF("%u\thash buckets in use\n", ipsp->iss_inuse); + PRINTF("%lu\tICMP bad\n", ipsp->iss_icmp_bad); + PRINTF("%lu\tICMP banned\n", ipsp->iss_icmp_banned); + PRINTF("%lu\tICMP errors\n", ipsp->iss_icmp_icmperr); + PRINTF("%lu\tICMP head block\n", ipsp->iss_icmp_headblock); + PRINTF("%lu\tICMP hits\n", ipsp->iss_icmp_hits); + PRINTF("%lu\tICMP not query\n", ipsp->iss_icmp_notquery); + PRINTF("%lu\tICMP short\n", ipsp->iss_icmp_short); + PRINTF("%lu\tICMP too many\n", ipsp->iss_icmp_toomany); + PRINTF("%lu\tICMPv6 errors\n", ipsp->iss_icmp6_icmperr); + PRINTF("%lu\tICMPv6 miss\n", ipsp->iss_icmp6_miss); + PRINTF("%lu\tICMPv6 not info\n", ipsp->iss_icmp6_notinfo); + PRINTF("%lu\tICMPv6 not query\n", ipsp->iss_icmp6_notquery); + PRINTF("%lu\tlog fail\n", ipsp->iss_log_fail); + PRINTF("%lu\tlog ok\n", ipsp->iss_log_ok); + PRINTF("%lu\tlookup interface mismatch\n", ipsp->iss_lookup_badifp); + PRINTF("%lu\tlookup mask mismatch\n", ipsp->iss_miss_mask); + PRINTF("%lu\tlookup port mismatch\n", ipsp->iss_lookup_badport); + PRINTF("%lu\tlookup miss\n", ipsp->iss_lookup_miss); + PRINTF("%lu\tmaximum rule references\n", ipsp->iss_max_ref); + PRINTF("%lu\tmaximum hosts per rule\n", ipsp->iss_max_track); + PRINTF("%lu\tno memory\n", ipsp->iss_nomem); + PRINTF("%lu\tout of window\n", ipsp->iss_oow); + PRINTF("%lu\torphans\n", ipsp->iss_orphan); + PRINTF("%lu\tscan block\n", ipsp->iss_scan_block); + PRINTF("%lu\tstate table maximum reached\n", ipsp->iss_max); + PRINTF("%lu\tTCP closing\n", ipsp->iss_tcp_closing); + PRINTF("%lu\tTCP OOW\n", ipsp->iss_tcp_oow); + PRINTF("%lu\tTCP RST add\n", ipsp->iss_tcp_rstadd); + PRINTF("%lu\tTCP too small\n", ipsp->iss_tcp_toosmall); + PRINTF("%lu\tTCP bad options\n", ipsp->iss_tcp_badopt); + PRINTF("%lu\tTCP removed\n", ipsp->iss_fin); + PRINTF("%lu\tTCP FSM\n", ipsp->iss_tcp_fsm); + PRINTF("%lu\tTCP strict\n", ipsp->iss_tcp_strict); + PRINTF("%lu\tTCP wild\n", ipsp->iss_wild); + PRINTF("%lu\tMicrosoft Windows SACK\n", ipsp->iss_winsack); + + PRINTF("State logging %sabled\n", state_logging ? "en" : "dis"); + + PRINTF("IP states added:\n"); + for (i = 0; i < 256; i++) { + if (ipsp->iss_proto[i] != 0) { + struct protoent *proto; + + proto = getprotobynumber(i); + PRINTF("%lu", ipsp->iss_proto[i]); + if (proto != NULL) + PRINTF("\t%s\n", proto->p_name); + else + PRINTF("\t%d\n", i); + } + } + + PRINTF("\nState table bucket statistics:\n"); + PRINTF("%u\tin use\n", ipsp->iss_inuse); + + minlen = ipsp->iss_max; + totallen = 0; + maxlen = 0; + + for (i = 0; i < ipsp->iss_state_size; i++) { + if (buckets[i] > maxlen) + maxlen = buckets[i]; + if (buckets[i] < minlen) + minlen = buckets[i]; + totallen += buckets[i]; + } + + PRINTF("%d\thash efficiency\n", + totallen ? ipsp->iss_inuse * 100 / totallen : 0); + PRINTF("%2.2f%%\tbucket usage\n%u\tminimal length\n", + ((float)ipsp->iss_inuse / ipsp->iss_state_size) * 100.0, + minlen); + PRINTF("%u\tmaximal length\n%.3f\taverage length\n", + maxlen, + ipsp->iss_inuse ? (float) totallen/ ipsp->iss_inuse : + 0.0); #define ENTRIES_PER_LINE 5 - if (opts & OPT_VERBOSE) { - PRINTF("\nCurrent bucket sizes :\n"); - for (i = 0; i < ipsp->iss_statesize; i++) { - if ((i % ENTRIES_PER_LINE) == 0) - PRINTF("\t"); - PRINTF("%4d -> %4lu", i, buckets[i]); - if ((i % ENTRIES_PER_LINE) == - (ENTRIES_PER_LINE - 1)) - PRINTF("\n"); - else - PRINTF(" "); - } - PRINTF("\n"); + if (opts & OPT_VERBOSE) { + PRINTF("\nCurrent bucket sizes :\n"); + for (i = 0; i < ipsp->iss_state_size; i++) { + if ((i % ENTRIES_PER_LINE) == 0) + PRINTF("\t"); + PRINTF("%4d -> %4u", i, buckets[i]); + if ((i % ENTRIES_PER_LINE) == + (ENTRIES_PER_LINE - 1)) + PRINTF("\n"); + else + PRINTF(" "); } PRINTF("\n"); - - free(buckets); - - if (live_kernel == 1) { - showtqtable_live(state_fd); - } else { - printtqtable(ipsp->iss_tcptab); - } - - return; - } + PRINTF("\n"); - /* - * Print out all the state information currently held in the kernel. - */ - while (ipsp->iss_list != NULL) { - ipstate_t ips; + free(buckets); - ipsp->iss_list = fetchstate(ipsp->iss_list, &ips); - - if (ipsp->iss_list != NULL) { - ipsp->iss_list = ips.is_next; - printstate(&ips, opts, ipsp->iss_ticks); - } + if (live_kernel == 1) { + showtqtable_live(state_fd); + } else { + printtqtable(ipsp->iss_tcptab); } } @@ -1190,21 +1297,23 @@ ips_stat_t *ipsp; static int handle_resize = 0, handle_break = 0; static void topipstates(saddr, daddr, sport, dport, protocol, ver, - refreshtime, topclosed) -i6addr_t saddr; -i6addr_t daddr; -int sport; -int dport; -int protocol; -int ver; -int refreshtime; -int topclosed; + refreshtime, topclosed, filter) + i6addr_t saddr; + i6addr_t daddr; + int sport; + int dport; + int protocol; + int ver; + int refreshtime; + int topclosed; + int *filter; { char str1[STSTRSIZE], str2[STSTRSIZE], str3[STSTRSIZE], str4[STSTRSIZE]; int maxtsentries = 0, reverse = 0, sorting = STSORT_DEFAULT; int i, j, winy, tsentry, maxx, maxy, redraw = 0, ret = 0; int len, srclen, dstlen, forward = 1, c = 0; ips_stat_t ipsst, *ipsstp = &ipsst; + int token_type = IPFGENITER_STATE; statetop_t *tstable = NULL, *tp; const char *errstr = ""; ipstate_t ips; @@ -1267,6 +1376,10 @@ int topclosed; if (ips.is_v != ver) continue; + if ((filter != NULL) && + (state_matcharray(&ips, filter) == 0)) + continue; + /* check v4 src/dest addresses */ if (ips.is_v == 4) { if ((saddr.in4.s_addr != INADDR_ANY && @@ -1348,6 +1461,7 @@ int topclosed; } } + (void) ioctl(state_fd, SIOCIPFDELTOK, &token_type); /* sort the array */ if (tsentry != -1) { @@ -1485,14 +1599,14 @@ int topclosed; printw("Src: %s, Dest: %s, Proto: %s, Sorted by: %s\n\n", str1, str2, str3, str4); - /* + /* * For an IPv4 IP address we need at most 15 characters, * 4 tuples of 3 digits, separated by 3 dots. Enforce this * length, so the colums do not change positions based * on the size of the IP address. This length makes the - * output fit in a 80 column terminal. + * output fit in a 80 column terminal. * We are lacking a good solution for IPv6 addresses (that - * can be longer that 15 characters), so we do not enforce + * can be longer that 15 characters), so we do not enforce * a maximum on the IP field size. */ if (srclen < 15) @@ -1629,8 +1743,8 @@ int topclosed; * Show fragment cache information that's held in the kernel. */ static void showfrstates(ifsp, ticks) -ipfrstat_t *ifsp; -u_long ticks; + ipfrstat_t *ifsp; + u_long ticks; { struct ipfr *ipfrtab[IPFT_SIZE], ifr; int i; @@ -1638,13 +1752,13 @@ u_long ticks; /* * print out the numeric statistics */ - PRINTF("IP fragment states:\n\t%lu new\n\t%lu expired\n\t%lu hits\n", + PRINTF("IP fragment states:\n%lu\tnew\n%lu\texpired\n%lu\thits\n", ifsp->ifs_new, ifsp->ifs_expire, ifsp->ifs_hits); - PRINTF("\t%lu retrans\n\t%lu too short\n", + PRINTF("%lu\tretrans\n%lu\ttoo short\n", ifsp->ifs_retrans0, ifsp->ifs_short); - PRINTF("\t%lu no memory\n\t%lu already exist\n", + PRINTF("%lu\tno memory\n%lu\talready exist\n", ifsp->ifs_nomem, ifsp->ifs_exists); - PRINTF("\t%lu inuse\n", ifsp->ifs_inuse); + PRINTF("%lu\tinuse\n", ifsp->ifs_inuse); PRINTF("\n"); if (live_kernel == 0) { @@ -1664,7 +1778,7 @@ u_long ticks; break; ifr.ipfr_ttl -= ticks; printfraginfo("", &ifr); - } while (1); + } while (ifr.ipfr_next != NULL); } else { for (i = 0; i < IPFT_SIZE; i++) while (ipfrtab[i] != NULL) { @@ -1693,7 +1807,7 @@ u_long ticks; break; ifr.ipfr_ttl -= ticks; printfraginfo("NAT: ", &ifr); - } while (1); + } while (ifr.ipfr_next != NULL); } else { for (i = 0; i < IPFT_SIZE; i++) while (ipfrtab[i] != NULL) { @@ -1711,7 +1825,7 @@ u_long ticks; * Show stats on how auth within IPFilter has been used */ static void showauthstates(asp) -fr_authstat_t *asp; + ipf_authstat_t *asp; { frauthent_t *frap, fra; ipfgeniter_t auth; @@ -1727,7 +1841,7 @@ fr_authstat_t *asp; auth.igi_data = &fra; #ifdef USE_QUAD_T - printf("Authorisation hits: %qu\tmisses %qu\n", + printf("Authorisation hits: %"PRIu64"\tmisses %"PRIu64"\n", (unsigned long long) asp->fas_hits, (unsigned long long) asp->fas_miss); #else @@ -1762,7 +1876,7 @@ fr_authstat_t *asp; * authentication, separately. */ static void showgroups(fiop) -struct friostat *fiop; + struct friostat *fiop; { static char *gnames[3] = { "Filter", "Accounting", "Authentication" }; static int gnums[3] = { IPL_LOGIPF, IPL_LOGCOUNT, IPL_LOGAUTH }; @@ -1790,10 +1904,11 @@ struct friostat *fiop; } } + static void parse_ipportstr(argument, ip, port) -const char *argument; -i6addr_t *ip; -int *port; + const char *argument; + i6addr_t *ip; + int *port; { char *s, *comma; int ok = 0; @@ -1845,20 +1960,20 @@ int *port; #ifdef STATETOP static void sig_resize(s) -int s; + int s; { handle_resize = 1; } static void sig_break(s) -int s; + int s; { handle_break = 1; } static char *getip(v, addr) -int v; -i6addr_t *addr; + int v; + i6addr_t *addr; { #ifdef USE_INET6 static char hostbuf[MAXHOSTNAMELEN+1]; @@ -1878,7 +1993,7 @@ i6addr_t *addr; static char *ttl_to_string(ttl) -long int ttl; + long int ttl; { static char ttlbuf[STSTRSIZE]; int hours, minutes, seconds; @@ -1900,8 +2015,8 @@ long int ttl; static int sort_pkts(a, b) -const void *a; -const void *b; + const void *a; + const void *b; { register const statetop_t *ap = a; @@ -1916,8 +2031,8 @@ const void *b; static int sort_bytes(a, b) -const void *a; -const void *b; + const void *a; + const void *b; { register const statetop_t *ap = a; register const statetop_t *bp = b; @@ -1931,8 +2046,8 @@ const void *b; static int sort_p(a, b) -const void *a; -const void *b; + const void *a; + const void *b; { register const statetop_t *ap = a; register const statetop_t *bp = b; @@ -1946,8 +2061,8 @@ const void *b; static int sort_ttl(a, b) -const void *a; -const void *b; + const void *a; + const void *b; { register const statetop_t *ap = a; register const statetop_t *bp = b; @@ -1960,8 +2075,8 @@ const void *b; } static int sort_srcip(a, b) -const void *a; -const void *b; + const void *a; + const void *b; { register const statetop_t *ap = a; register const statetop_t *bp = b; @@ -1986,8 +2101,8 @@ const void *b; } static int sort_srcpt(a, b) -const void *a; -const void *b; + const void *a; + const void *b; { register const statetop_t *ap = a; register const statetop_t *bp = b; @@ -2000,8 +2115,8 @@ const void *b; } static int sort_dstip(a, b) -const void *a; -const void *b; + const void *a; + const void *b; { register const statetop_t *ap = a; register const statetop_t *bp = b; @@ -2026,8 +2141,8 @@ const void *b; } static int sort_dstpt(a, b) -const void *a; -const void *b; + const void *a; + const void *b; { register const statetop_t *ap = a; register const statetop_t *bp = b; @@ -2043,9 +2158,8 @@ const void *b; ipstate_t *fetchstate(src, dst) -ipstate_t *src, *dst; + ipstate_t *src, *dst; { - int i; if (live_kernel == 1) { ipfgeniter_t state; @@ -2063,8 +2177,8 @@ ipstate_t *src, *dst; if (ioctl(state_fd, SIOCGENITER, &obj) != 0) return NULL; if (dst->is_next == NULL) { - i = IPFGENITER_STATE; - ioctl(state_fd, SIOCIPFDELTOK, &i); + int n = IPFGENITER_STATE; + (void) ioctl(ipf_fd,SIOCIPFDELTOK, &n); } } else { if (kmemcpy((char *)dst, (u_long)src, sizeof(*dst))) @@ -2075,8 +2189,8 @@ ipstate_t *src, *dst; static int fetchfrag(fd, type, frp) -int fd, type; -ipfr_t *frp; + int fd, type; + ipfr_t *frp; { ipfgeniter_t frag; ipfobj_t obj; @@ -2096,8 +2210,155 @@ ipfr_t *frp; } +static int state_matcharray(stp, array) + ipstate_t *stp; + int *array; +{ + int i, n, *x, rv, p; + ipfexp_t *e; + + rv = 0; + + for (n = array[0], x = array + 1; n > 0; x += e->ipfe_size) { + e = (ipfexp_t *)x; + if (e->ipfe_cmd == IPF_EXP_END) + break; + n -= e->ipfe_size; + + rv = 0; + /* + * The upper 16 bits currently store the protocol value. + * This is currently used with TCP and UDP port compares and + * allows "tcp.port = 80" without requiring an explicit + " "ip.pr = tcp" first. + */ + p = e->ipfe_cmd >> 16; + if ((p != 0) && (p != stp->is_p)) + break; + + switch (e->ipfe_cmd) + { + case IPF_EXP_IP_PR : + for (i = 0; !rv && i < e->ipfe_narg; i++) { + rv |= (stp->is_p == e->ipfe_arg0[i]); + } + break; + + case IPF_EXP_IP_SRCADDR : + if (stp->is_v != 4) + break; + for (i = 0; !rv && i < e->ipfe_narg; i++) { + rv |= ((stp->is_saddr & + e->ipfe_arg0[i * 2 + 1]) == + e->ipfe_arg0[i * 2]); + } + break; + + case IPF_EXP_IP_DSTADDR : + if (stp->is_v != 4) + break; + for (i = 0; !rv && i < e->ipfe_narg; i++) { + rv |= ((stp->is_daddr & + e->ipfe_arg0[i * 2 + 1]) == + e->ipfe_arg0[i * 2]); + } + break; + + case IPF_EXP_IP_ADDR : + if (stp->is_v != 4) + break; + for (i = 0; !rv && i < e->ipfe_narg; i++) { + rv |= ((stp->is_saddr & + e->ipfe_arg0[i * 2 + 1]) == + e->ipfe_arg0[i * 2]) || + ((stp->is_daddr & + e->ipfe_arg0[i * 2 + 1]) == + e->ipfe_arg0[i * 2]); + } + break; + +#ifdef USE_INET6 + case IPF_EXP_IP6_SRCADDR : + if (stp->is_v != 6) + break; + for (i = 0; !rv && i < e->ipfe_narg; i++) { + rv |= IP6_MASKEQ(&stp->is_src, + &e->ipfe_arg0[i * 8 + 4], + &e->ipfe_arg0[i * 8]); + } + break; + + case IPF_EXP_IP6_DSTADDR : + if (stp->is_v != 6) + break; + for (i = 0; !rv && i < e->ipfe_narg; i++) { + rv |= IP6_MASKEQ(&stp->is_dst, + &e->ipfe_arg0[i * 8 + 4], + &e->ipfe_arg0[i * 8]); + } + break; + + case IPF_EXP_IP6_ADDR : + if (stp->is_v != 6) + break; + for (i = 0; !rv && i < e->ipfe_narg; i++) { + rv |= IP6_MASKEQ(&stp->is_src, + &e->ipfe_arg0[i * 8 + 4], + &e->ipfe_arg0[i * 8]) || + IP6_MASKEQ(&stp->is_dst, + &e->ipfe_arg0[i * 8 + 4], + &e->ipfe_arg0[i * 8]); + } + break; +#endif + + case IPF_EXP_UDP_PORT : + case IPF_EXP_TCP_PORT : + for (i = 0; !rv && i < e->ipfe_narg; i++) { + rv |= (stp->is_sport == e->ipfe_arg0[i]) || + (stp->is_dport == e->ipfe_arg0[i]); + } + break; + + case IPF_EXP_UDP_SPORT : + case IPF_EXP_TCP_SPORT : + for (i = 0; !rv && i < e->ipfe_narg; i++) { + rv |= (stp->is_sport == e->ipfe_arg0[i]); + } + break; + + case IPF_EXP_UDP_DPORT : + case IPF_EXP_TCP_DPORT : + for (i = 0; !rv && i < e->ipfe_narg; i++) { + rv |= (stp->is_dport == e->ipfe_arg0[i]); + } + break; + + case IPF_EXP_IDLE_GT : + for (i = 0; !rv && i < e->ipfe_narg; i++) { + rv |= (stp->is_die < e->ipfe_arg0[i]); + } + break; + + case IPF_EXP_TCP_STATE : + for (i = 0; !rv && i < e->ipfe_narg; i++) { + rv |= (stp->is_state[0] == e->ipfe_arg0[i]) || + (stp->is_state[1] == e->ipfe_arg0[i]); + } + break; + } + rv ^= e->ipfe_not; + + if (rv == 0) + break; + } + + return rv; +} + + static void showtqtable_live(fd) -int fd; + int fd; { ipftq_t table[IPF_TCP_NSTATES]; ipfobj_t obj; diff --git a/contrib/ipfilter/tools/ipfsyncd.c b/contrib/ipfilter/tools/ipfsyncd.c new file mode 100644 index 000000000000..d4671e409d63 --- /dev/null +++ b/contrib/ipfilter/tools/ipfsyncd.c @@ -0,0 +1,671 @@ +/* + * Copyright (C) 2012 by Darren Reed. + * + * See the IPFILTER.LICENCE file for details on licencing. + */ +#if !defined(lint) +static const char sccsid[] = "@(#)ip_fil.c 2.41 6/5/96 (C) 1993-2000 Darren Reed"; +static const char rcsid[] = "@(#)$Id: ipfsyncd.c,v 1.1.2.2 2012/07/22 08:04:24 darren_r Exp $"; +#endif +#include +#include +#include +#include +#include +#include + +#include +#include + +#include + +#include +#include +#include +#include +#include +#include +#include + +#include "ipf.h" +#include "opts.h" + + +#define R_IO_ERROR -1 +#define R_OKAY 0 +#define R_MORE 1 +#define R_SKIP 2 +#if defined(sun) && !defined(SOLARIS2) +# define STRERROR(x) sys_errlist[x] +extern char *sys_errlist[]; +#else +# define STRERROR(x) strerror(x) +#endif + + +int main __P((int, char *[])); +void usage __P((char *)); +void printsynchdr __P((synchdr_t *)); +void printtable __P((int)); +void printsmcproto __P((char *)); +void printcommand __P((int)); +int do_kbuff __P((int, char *, int *)); +int do_packet __P((int, char *)); +int buildsocket __P((char *, struct sockaddr_in *)); +void do_io __P((void)); +void handleterm __P((int)); + +int terminate = 0; +int igmpfd = -1; +int nfd = -1; +int lfd = -1; +int opts = 0; + +void +usage(progname) + char *progname; +{ + fprintf(stderr, + "Usage: %s [-d] [-p port] [-i address] -I \n", + progname); +} + +void +handleterm(sig) + int sig; +{ + terminate = sig; +} + + +/* should be large enough to hold header + any datatype */ +#define BUFFERLEN 1400 + +int +main(argc, argv) + int argc; + char *argv[]; +{ + struct sockaddr_in sin; + char *interface; + char *progname; + int opt, tries; + + progname = strrchr(argv[0], '/'); + if (progname) { + progname++; + } else { + progname = argv[0]; + } + + opts = 0; + tries = 0; + interface = NULL; + + bzero((char *)&sin, sizeof(sin)); + sin.sin_family = AF_INET; + sin.sin_port = htons(0xaf6c); + sin.sin_addr.s_addr = htonl(INADDR_UNSPEC_GROUP | 0x697066); + + while ((opt = getopt(argc, argv, "di:I:p:")) != -1) + switch (opt) + { + case 'd' : + debuglevel++; + break; + case 'I' : + interface = optarg; + break; + case 'i' : + sin.sin_addr.s_addr = inet_addr(optarg); + break; + case 'p' : + sin.sin_port = htons(atoi(optarg)); + break; + } + + if (interface == NULL) { + usage(progname); + exit(1); + } + + if (!debuglevel) { + +#if BSD >= 199306 + daemon(0, 0); +#else + int fd = open("/dev/null", O_RDWR); + + switch (fork()) + { + case 0 : + break; + + case -1 : + fprintf(stderr, "%s: fork() failed: %s\n", + argv[0], STRERROR(errno)); + exit(1); + /* NOTREACHED */ + + default : + exit(0); + /* NOTREACHED */ + } + + dup2(fd, 0); + dup2(fd, 1); + dup2(fd, 2); + close(fd); + + setsid(); +#endif + } + + signal(SIGHUP, handleterm); + signal(SIGINT, handleterm); + signal(SIGTERM, handleterm); + + openlog(progname, LOG_PID, LOG_SECURITY); + + while (!terminate) { + if (lfd != -1) { + close(lfd); + lfd = -1; + } + if (nfd != -1) { + close(nfd); + nfd = -1; + } + if (igmpfd != -1) { + close(igmpfd); + igmpfd = -1; + } + + if (buildsocket(interface, &sin) == -1) + goto tryagain; + + lfd = open(IPSYNC_NAME, O_RDWR); + if (lfd == -1) { + syslog(LOG_ERR, "open(%s):%m", IPSYNC_NAME); + debug(1, "open(%s): %s\n", IPSYNC_NAME, + STRERROR(errno)); + goto tryagain; + } + + tries = -1; + do_io(); +tryagain: + tries++; + syslog(LOG_INFO, "retry in %d seconds", 1 << tries); + debug(1, "wait %d seconds\n", 1 << tries); + sleep(1 << tries); + } + + + /* terminate */ + if (lfd != -1) + close(lfd); + if (nfd != -1) + close(nfd); + + syslog(LOG_ERR, "signal %d received, exiting...", terminate); + debug(1, "signal %d received, exiting...", terminate); + + exit(1); +} + + +void +do_io() +{ + char nbuff[BUFFERLEN]; + char buff[BUFFERLEN]; + fd_set mrd, rd; + int maxfd; + int inbuf; + int n1; + int left; + + FD_ZERO(&mrd); + FD_SET(lfd, &mrd); + FD_SET(nfd, &mrd); + maxfd = nfd; + if (lfd > maxfd) + maxfd = lfd; + debug(2, "nfd %d lfd %d maxfd %d\n", nfd, lfd, maxfd); + + inbuf = 0; + /* + * A threaded approach to this loop would have one thread + * work on reading lfd (only) all the time and another thread + * working on reading nfd all the time. + */ + while (!terminate) { + int n; + + rd = mrd; + + n = select(maxfd + 1, &rd, NULL, NULL, NULL); + if (n < 0) { + switch (errno) + { + case EINTR : + continue; + default : + syslog(LOG_ERR, "select error: %m"); + debug(1, "select error: %s\n", STRERROR(errno)); + return; + } + } + + if (FD_ISSET(lfd, &rd)) { + n1 = read(lfd, buff+inbuf, BUFFERLEN-inbuf); + + debug(3, "read(K):%d\n", n1); + + if (n1 <= 0) { + syslog(LOG_ERR, "read error (k-header): %m"); + debug(1, "read error (k-header): %s\n", + STRERROR(errno)); + return; + } + + left = 0; + + switch (do_kbuff(n1, buff, &left)) + { + case R_IO_ERROR : + return; + case R_MORE : + inbuf += left; + break; + default : + inbuf = 0; + break; + } + } + + if (FD_ISSET(nfd, &rd)) { + n1 = recv(nfd, nbuff, sizeof(nbuff), 0); + + debug(3, "read(N):%d\n", n1); + + if (n1 <= 0) { + syslog(LOG_ERR, "read error (n-header): %m"); + debug(1, "read error (n-header): %s\n", + STRERROR(errno)); + return; + } + + switch (do_packet(n1, nbuff)) + { + case R_IO_ERROR : + return; + default : + break; + } + } + } +} + + +int +buildsocket(nicname, sinp) + char *nicname; + struct sockaddr_in *sinp; +{ + struct sockaddr_in *reqip; + struct ifreq req; + char opt; + + debug(2, "binding to %s:%s\n", nicname, inet_ntoa(sinp->sin_addr)); + + if (IN_MULTICAST(ntohl(sinp->sin_addr.s_addr))) { + struct in_addr addr; + struct ip_mreq mreq; + + igmpfd = socket(AF_INET, SOCK_RAW, IPPROTO_IGMP); + if (igmpfd == -1) { + syslog(LOG_ERR, "socket:%m"); + debug(1, "socket:%s\n", STRERROR(errno)); + return -1; + } + + bzero((char *)&req, sizeof(req)); + strncpy(req.ifr_name, nicname, sizeof(req.ifr_name)); + req.ifr_name[sizeof(req.ifr_name) - 1] = '\0'; + if (ioctl(igmpfd, SIOCGIFADDR, &req) == -1) { + syslog(LOG_ERR, "ioctl(SIOCGIFADDR):%m"); + debug(1, "ioctl(SIOCGIFADDR):%s\n", STRERROR(errno)); + close(igmpfd); + igmpfd = -1; + return -1; + } + reqip = (struct sockaddr_in *)&req.ifr_addr; + + addr = reqip->sin_addr; + if (setsockopt(igmpfd, IPPROTO_IP, IP_MULTICAST_IF, + (char *)&addr, sizeof(addr)) == -1) { + syslog(LOG_ERR, "setsockopt(IP_MULTICAST_IF(%s)):%m", + inet_ntoa(addr)); + debug(1, "setsockopt(IP_MULTICAST_IF(%s)):%s\n", + inet_ntoa(addr), STRERROR(errno)); + close(igmpfd); + igmpfd = -1; + return -1; + } + + opt = 0; + if (setsockopt(igmpfd, IPPROTO_IP, IP_MULTICAST_LOOP, + (char *)&opt, sizeof(opt)) == -1) { + syslog(LOG_ERR, "setsockopt(IP_MULTICAST_LOOP=0):%m"); + debug(1, "setsockopt(IP_MULTICAST_LOOP=0):%s\n", + STRERROR(errno)); + close(igmpfd); + igmpfd = -1; + return -1; + } + + opt = 63; + if (setsockopt(igmpfd, IPPROTO_IP, IP_MULTICAST_TTL, + (char *)&opt, sizeof(opt)) == -1) { + syslog(LOG_ERR, "setsockopt(IP_MULTICAST_TTL=%d):%m", + opt); + debug(1, "setsockopt(IP_MULTICAST_TTL=%d):%s\n", opt, + STRERROR(errno)); + close(igmpfd); + igmpfd = -1; + return -1; + } + + mreq.imr_multiaddr.s_addr = sinp->sin_addr.s_addr; + mreq.imr_interface.s_addr = reqip->sin_addr.s_addr; + + if (setsockopt(igmpfd, IPPROTO_IP, IP_ADD_MEMBERSHIP, + (char *)&mreq, sizeof(mreq)) == -1) { + char buffer[80]; + + sprintf(buffer, "%s,", inet_ntoa(sinp->sin_addr)); + strcat(buffer, inet_ntoa(reqip->sin_addr)); + + syslog(LOG_ERR, + "setsockpt(IP_ADD_MEMBERSHIP,%s):%m", buffer); + debug(1, "setsockpt(IP_ADD_MEMBERSHIP,%s):%s\n", + buffer, STRERROR(errno)); + close(igmpfd); + igmpfd = -1; + return -1; + } + } + nfd = socket(AF_INET, SOCK_DGRAM, 0); + if (nfd == -1) { + syslog(LOG_ERR, "socket:%m"); + if (igmpfd != -1) { + close(igmpfd); + igmpfd = -1; + } + return -1; + } + bzero((char *)&req, sizeof(req)); + strncpy(req.ifr_name, nicname, sizeof(req.ifr_name)); + req.ifr_name[sizeof(req.ifr_name) - 1] = '\0'; + if (ioctl(nfd, SIOCGIFADDR, &req) == -1) { + syslog(LOG_ERR, "ioctl(SIOCGIFADDR):%m"); + debug(1, "ioctl(SIOCGIFADDR):%s\n", STRERROR(errno)); + close(igmpfd); + igmpfd = -1; + return -1; + } + + if (bind(nfd, (struct sockaddr *)&req.ifr_addr, + sizeof(req.ifr_addr)) == -1) { + syslog(LOG_ERR, "bind:%m"); + debug(1, "bind:%s\n", STRERROR(errno)); + close(nfd); + if (igmpfd != -1) { + close(igmpfd); + igmpfd = -1; + } + nfd = -1; + return -1; + } + + if (connect(nfd, (struct sockaddr *)sinp, sizeof(*sinp)) == -1) { + syslog(LOG_ERR, "connect:%m"); + debug(1, "connect:%s\n", STRERROR(errno)); + close(nfd); + if (igmpfd != -1) { + close(igmpfd); + igmpfd = -1; + } + nfd = -1; + return -1; + } + syslog(LOG_INFO, "Sending data to %s", inet_ntoa(sinp->sin_addr)); + debug(3, "Sending data to %s\n", inet_ntoa(sinp->sin_addr)); + + return nfd; +} + + +int +do_packet(pklen, buff) + int pklen; + char *buff; +{ + synchdr_t *sh; + u_32_t magic; + int len; + int n2; + int n3; + + while (pklen > 0) { + if (pklen < sizeof(*sh)) { + syslog(LOG_ERR, "packet length too short:%d", pklen); + debug(2, "packet length too short:%d\n", pklen); + return R_SKIP; + } + + sh = (synchdr_t *)buff; + len = ntohl(sh->sm_len); + magic = ntohl(sh->sm_magic); + + if (magic != SYNHDRMAGIC) { + syslog(LOG_ERR, "invalid header magic %x", magic); + debug(2, "invalid header magic %x\n", magic); + return R_SKIP; + } + + if (pklen < len + sizeof(*sh)) { + syslog(LOG_ERR, "packet length too short:%d", pklen); + debug(2, "packet length too short:%d\n", pklen); + return R_SKIP; + } + + if (debuglevel > 3) { + printsynchdr(sh); + printcommand(sh->sm_cmd); + printtable(sh->sm_table); + printsmcproto(buff); + } + + n2 = sizeof(*sh) + len; + + do { + n3 = write(lfd, buff, n2); + if (n3 <= 0) { + syslog(LOG_ERR, "write error: %m"); + debug(1, "write error: %s\n", STRERROR(errno)); + return R_IO_ERROR; + } + + n2 -= n3; + buff += n3; + pklen -= n3; + } while (n3 != 0); + } + + return R_OKAY; +} + + + +int +do_kbuff(inbuf, buf, left) + int inbuf, *left; + char *buf; +{ + synchdr_t *sh; + u_32_t magic; + int complete; + int sendlen; + int error; + int bytes; + int len; + int n2; + int n3; + + sendlen = 0; + bytes = inbuf; + error = R_OKAY; + sh = (synchdr_t *)buf; + + for (complete = 0; bytes > 0; complete++) { + len = ntohl(sh->sm_len); + magic = ntohl(sh->sm_magic); + + if (magic != SYNHDRMAGIC) { + syslog(LOG_ERR, + "read invalid header magic 0x%x, flushing", + magic); + debug(2, "read invalid header magic 0x%x, flushing\n", + magic); + n2 = SMC_RLOG; + (void) ioctl(lfd, SIOCIPFFL, &n2); + break; + } + + if (debuglevel > 3) { + printsynchdr(sh); + printcommand(sh->sm_cmd); + printtable(sh->sm_table); + putchar('\n'); + } + + if (bytes < sizeof(*sh) + len) { + debug(3, "Not enough bytes %d < %d\n", bytes, + sizeof(*sh) + len); + error = R_MORE; + break; + } + + if (debuglevel > 3) { + printsmcproto(buf); + } + + sendlen += len + sizeof(*sh); + sh = (synchdr_t *)(buf + sendlen); + bytes -= sendlen; + } + + if (complete) { + n3 = send(nfd, buf, sendlen, 0); + if (n3 <= 0) { + syslog(LOG_ERR, "write error: %m"); + debug(1, "write error: %s\n", STRERROR(errno)); + return R_IO_ERROR; + } + debug(3, "send on %d len %d = %d\n", nfd, sendlen, n3); + error = R_OKAY; + } + + /* move buffer to the front,we might need to make + * this more efficient, by using a rolling pointer + * over the buffer and only copying it, when + * we are reaching the end + */ + if (bytes > 0) { + bcopy(buf + bytes, buf, bytes); + error = R_MORE; + } + debug(4, "complete %d bytes %d error %d\n", complete, bytes, error); + + *left = bytes; + + return error; +} + + +void +printcommand(cmd) + int cmd; +{ + + switch (cmd) + { + case SMC_CREATE : + printf(" cmd:CREATE"); + break; + case SMC_UPDATE : + printf(" cmd:UPDATE"); + break; + default : + printf(" cmd:Unknown(%d)", cmd); + break; + } +} + + +void +printtable(table) + int table; +{ + switch (table) + { + case SMC_NAT : + printf(" table:NAT"); + break; + case SMC_STATE : + printf(" table:STATE"); + break; + default : + printf(" table:Unknown(%d)", table); + break; + } +} + + +void +printsmcproto(buff) + char *buff; +{ + syncupdent_t *su; + synchdr_t *sh; + + sh = (synchdr_t *)buff; + + if (sh->sm_cmd == SMC_CREATE) { + ; + + } else if (sh->sm_cmd == SMC_UPDATE) { + su = (syncupdent_t *)buff; + if (sh->sm_p == IPPROTO_TCP) { + printf(" TCP Update: age %lu state %d/%d\n", + su->sup_tcp.stu_age, + su->sup_tcp.stu_state[0], + su->sup_tcp.stu_state[1]); + } + } else { + printf("Unknown command\n"); + } +} + + +void +printsynchdr(sh) + synchdr_t *sh; +{ + + printf("v:%d p:%d num:%d len:%d magic:%x", sh->sm_v, sh->sm_p, + ntohl(sh->sm_num), ntohl(sh->sm_len), ntohl(sh->sm_magic)); +} diff --git a/contrib/ipfilter/tools/ipftest.c b/contrib/ipfilter/tools/ipftest.c index 963ed197cb9c..a475828b2e8f 100644 --- a/contrib/ipfilter/tools/ipftest.c +++ b/contrib/ipfilter/tools/ipftest.c @@ -1,7 +1,7 @@ /* $FreeBSD$ */ /* - * Copyright (C) 2002-2006 by Darren Reed. + * Copyright (C) 2012 by Darren Reed. * * See the IPFILTER.LICENCE file for details on licencing. */ @@ -12,24 +12,23 @@ #if !defined(lint) static const char sccsid[] = "@(#)ipt.c 1.19 6/3/96 (C) 1993-2000 Darren Reed"; -static const char rcsid[] = "@(#)$Id: ipftest.c,v 1.44.2.13 2006/12/12 16:13:01 darrenr Exp $"; +static const char rcsid[] = "@(#)$Id$"; #endif extern char *optarg; -extern struct frentry *ipfilter[2][2]; -extern struct ipread snoop, etherf, tcpd, pcap, iptext, iphex; +extern struct ipread pcap, iptext, iphex; extern struct ifnet *get_unit __P((char *, int)); extern void init_ifp __P((void)); extern ipnat_t *natparse __P((char *, int)); -extern int fr_running; extern hostmap_t **ipf_hm_maptable; extern hostmap_t *ipf_hm_maplist; -ipfmutex_t ipl_mutex, ipf_authmx, ipf_rw, ipf_stinsert; +ipfmutex_t ipl_mutex, ipf_auth_mx, ipf_rw, ipf_stinsert; ipfmutex_t ipf_nat_new, ipf_natio, ipf_timeoutlock; ipfrwlock_t ipf_mutex, ipf_global, ipf_ipidfrag, ip_poolrw, ipf_frcache; -ipfrwlock_t ipf_frag, ipf_state, ipf_nat, ipf_natfrag, ipf_auth, ipf_tokens; -int opts = OPT_DONOTHING; +ipfrwlock_t ipf_frag, ipf_state, ipf_nat, ipf_natfrag, ipf_authlk; +ipfrwlock_t ipf_tokens; +int opts = OPT_DONTOPEN; int use_inet6 = 0; int docksum = 0; int pfil_delayed_copy = 0; @@ -37,10 +36,10 @@ int main __P((int, char *[])); int loadrules __P((char *, int)); int kmemcpy __P((char *, long, int)); int kstrncpy __P((char *, long, int n)); -void dumpnat __P((void)); -void dumpstate __P((void)); -void dumplookups __P((void)); -void dumpgroups __P((void)); +int blockreason; +void dumpnat __P((void *)); +void dumpgroups __P((ipf_main_softc_t *)); +void dumprules __P((frentry_t *)); void drain_log __P((char *)); void fixv4sums __P((mb_t *, ip_t *)); @@ -72,18 +71,20 @@ static ioctlfunc_t iocfunctions[IPL_LOGSIZE] = { ipftestioctl, ipscantestioctl, ipooltestioctl, NULL }; +static ipf_main_softc_t *softc = NULL; -int main(argc,argv) -int argc; -char *argv[]; +int +main(argc,argv) + int argc; + char *argv[]; { char *datain, *iface, *ifname, *logout; int fd, i, dir, c, loaded, dump, hlen; struct in_addr sip; struct ifnet *ifp; struct ipread *r; - mb_t mb, *m; + mb_t mb, *m, *n; ip_t *ip; m = &mb; @@ -98,18 +99,20 @@ char *argv[]; sip.s_addr = 0; ifname = "anon0"; - MUTEX_INIT(&ipf_rw, "ipf rw mutex"); - MUTEX_INIT(&ipf_timeoutlock, "ipf timeout lock"); - RWLOCK_INIT(&ipf_global, "ipf filter load/unload mutex"); - RWLOCK_INIT(&ipf_mutex, "ipf filter rwlock"); - RWLOCK_INIT(&ipf_ipidfrag, "ipf IP NAT-Frag rwlock"); - RWLOCK_INIT(&ipf_frcache, "ipf filter cache"); - RWLOCK_INIT(&ipf_tokens, "ipf token rwlock"); - initparse(); - if (fr_initialise() == -1) - abort(); - fr_running = 1; + + ipf_load_all(); + + softc = ipf_create_all(NULL); + if (softc == NULL) + exit(1); + + if (ipf_init_all(softc) == -1) + exit(1); + + i = 1; + if (ipftestioctl(IPL_LOGIPF, SIOCFRENB, &i) != 0) + exit(1); while ((c = getopt(argc, argv, "6bCdDF:i:I:l:N:P:or:RS:T:vxX")) != -1) switch (c) @@ -137,12 +140,6 @@ char *argv[]; case 'F' : if (strcasecmp(optarg, "pcap") == 0) r = &pcap; - else if (strcasecmp(optarg, "etherfind") == 0) - r = ðerf; - else if (strcasecmp(optarg, "snoop") == 0) - r = &snoop; - else if (strcasecmp(optarg, "tcpdump") == 0) - r = &tcpd; else if (strcasecmp(optarg, "hex") == 0) r = &iphex; else if (strcasecmp(optarg, "text") == 0) @@ -208,18 +205,21 @@ char *argv[]; else fd = (*r->r_open)("-"); - if (fd < 0) + if (fd < 0) { + perror("error opening input"); exit(-1); + } + + m->m_data = (char *)m->mb_buf; + while ((i = (*r->r_readip)(m, &iface, &dir)) > 0) { - ip = MTOD(m, ip_t *); - while ((i = (*r->r_readip)(MTOD(m, char *), sizeof(m->mb_buf), - &iface, &dir)) > 0) { if ((iface == NULL) || (*iface == '\0')) iface = ifname; + + ip = MTOD(m, ip_t *); ifp = get_unit(iface, IP_V(ip)); - if (!use_inet6) { - ip->ip_off = ntohs(ip->ip_off); - ip->ip_len = ntohs(ip->ip_len); + + if (IP_V(ip) == 4) { if ((r->r_flags & R_DO_CKSUM) || docksum) fixv4sums(m, ip); hlen = IP_HL(ip) << 2; @@ -231,9 +231,11 @@ char *argv[]; hlen = sizeof(ip6_t); #endif /* ipfr_slowtimer(); */ + blockreason = 0; m = &mb; + m->mb_ifp = ifp; m->mb_len = i; - i = fr_check(ip, hlen, ifp, dir, &m); + i = ipf_check(softc, ip, hlen, ifp, dir, &m); if ((opts & OPT_NAT) == 0) switch (i) { @@ -271,17 +273,24 @@ char *argv[]; (void)printf("recognised return %#x\n", i); break; } - if (!use_inet6) { - ip->ip_off = htons(ip->ip_off); - ip->ip_len = htons(ip->ip_len); - } if (!(opts & OPT_BRIEF)) { putchar(' '); - printpacket(ip); + if (m != NULL) + printpacket(dir, m); + else + printpacket(dir, &mb); printf("--------------"); - } else if ((opts & (OPT_BRIEF|OPT_NAT)) == (OPT_NAT|OPT_BRIEF)) - printpacket(ip); + } else if ((opts & (OPT_BRIEF|OPT_NAT)) == + (OPT_NAT|OPT_BRIEF)) { + if (m != NULL) + printpacket(dir, m); + else + PRINTF("%d\n", blockreason); + } + + ipf_state_flush(softc, 1, 0); + if (dir && (ifp != NULL) && IP_V(ip) && (m != NULL)) #if defined(__sgi) && (IRIX < 60500) (*ifp->if_output)(ifp, (void *)m, NULL); @@ -292,6 +301,13 @@ char *argv[]; (*ifp->if_output)(ifp, (void *)m, NULL, 0); # endif #endif + + while ((m != NULL) && (m != &mb)) { + n = m->mb_next; + freembt(m); + m = n; + } + if ((opts & (OPT_BRIEF|OPT_NAT)) != (OPT_NAT|OPT_BRIEF)) putchar('\n'); dir = 0; @@ -300,6 +316,7 @@ char *argv[]; iface = ifname; } m = &mb; + m->mb_data = (char *)m->mb_buf; } if (i != 0) @@ -311,14 +328,25 @@ char *argv[]; } if (dump == 1) { - dumpnat(); - dumpstate(); - dumplookups(); - dumpgroups(); + dumpnat(softc->ipf_nat_soft); + ipf_state_dump(softc, softc->ipf_state_soft); + ipf_lookup_dump(softc, softc->ipf_state_soft); + dumpgroups(softc); } - fr_deinitialise(); + ipf_fini_all(softc); + ipf_destroy_all(softc); + + ipf_unload_all(); + + ipf_mutex_clean(); + ipf_rwlock_clean(); + + if (getenv("FINDLEAKS")) { + fflush(stdout); + abort(); + } return 0; } @@ -332,14 +360,15 @@ int ipftestioctl(int dev, ioctlcmd_t cmd, ...) va_list ap; int i; + dev = dev; /* gcc -Wextra */ va_start(ap, cmd); data = va_arg(ap, caddr_t); va_end(ap); - i = iplioctl(IPL_LOGIPF, cmd, data, FWRITE|FREAD); + i = ipfioctl(softc, IPL_LOGIPF, cmd, data, FWRITE|FREAD); if (opts & OPT_DEBUG) - fprintf(stderr, "iplioctl(IPF,%#x,%p) = %d\n", - (u_int)cmd, data, i); + fprintf(stderr, "ipfioctl(IPF,%#x,%p) = %d (%d)\n", + (u_int)cmd, data, i, softc->ipf_interror); if (i != 0) { errno = i; return -1; @@ -354,13 +383,14 @@ int ipnattestioctl(int dev, ioctlcmd_t cmd, ...) va_list ap; int i; + dev = dev; /* gcc -Wextra */ va_start(ap, cmd); data = va_arg(ap, caddr_t); va_end(ap); - i = iplioctl(IPL_LOGNAT, cmd, data, FWRITE|FREAD); + i = ipfioctl(softc, IPL_LOGNAT, cmd, data, FWRITE|FREAD); if (opts & OPT_DEBUG) - fprintf(stderr, "iplioctl(NAT,%#x,%p) = %d\n", + fprintf(stderr, "ipfioctl(NAT,%#x,%p) = %d\n", (u_int)cmd, data, i); if (i != 0) { errno = i; @@ -376,13 +406,14 @@ int ipstatetestioctl(int dev, ioctlcmd_t cmd, ...) va_list ap; int i; + dev = dev; /* gcc -Wextra */ va_start(ap, cmd); data = va_arg(ap, caddr_t); va_end(ap); - i = iplioctl(IPL_LOGSTATE, cmd, data, FWRITE|FREAD); + i = ipfioctl(softc, IPL_LOGSTATE, cmd, data, FWRITE|FREAD); if ((opts & OPT_DEBUG) || (i != 0)) - fprintf(stderr, "iplioctl(STATE,%#x,%p) = %d\n", + fprintf(stderr, "ipfioctl(STATE,%#x,%p) = %d\n", (u_int)cmd, data, i); if (i != 0) { errno = i; @@ -398,13 +429,14 @@ int ipauthtestioctl(int dev, ioctlcmd_t cmd, ...) va_list ap; int i; + dev = dev; /* gcc -Wextra */ va_start(ap, cmd); data = va_arg(ap, caddr_t); va_end(ap); - i = iplioctl(IPL_LOGAUTH, cmd, data, FWRITE|FREAD); + i = ipfioctl(softc, IPL_LOGAUTH, cmd, data, FWRITE|FREAD); if ((opts & OPT_DEBUG) || (i != 0)) - fprintf(stderr, "iplioctl(AUTH,%#x,%p) = %d\n", + fprintf(stderr, "ipfioctl(AUTH,%#x,%p) = %d\n", (u_int)cmd, data, i); if (i != 0) { errno = i; @@ -420,13 +452,14 @@ int ipscantestioctl(int dev, ioctlcmd_t cmd, ...) va_list ap; int i; + dev = dev; /* gcc -Wextra */ va_start(ap, cmd); data = va_arg(ap, caddr_t); va_end(ap); - i = iplioctl(IPL_LOGSCAN, cmd, data, FWRITE|FREAD); + i = ipfioctl(softc, IPL_LOGSCAN, cmd, data, FWRITE|FREAD); if ((opts & OPT_DEBUG) || (i != 0)) - fprintf(stderr, "iplioctl(SCAN,%#x,%p) = %d\n", + fprintf(stderr, "ipfioctl(SCAN,%#x,%p) = %d\n", (u_int)cmd, data, i); if (i != 0) { errno = i; @@ -442,13 +475,14 @@ int ipsynctestioctl(int dev, ioctlcmd_t cmd, ...) va_list ap; int i; + dev = dev; /* gcc -Wextra */ va_start(ap, cmd); data = va_arg(ap, caddr_t); va_end(ap); - i = iplioctl(IPL_LOGSYNC, cmd, data, FWRITE|FREAD); + i = ipfioctl(softc, IPL_LOGSYNC, cmd, data, FWRITE|FREAD); if ((opts & OPT_DEBUG) || (i != 0)) - fprintf(stderr, "iplioctl(SYNC,%#x,%p) = %d\n", + fprintf(stderr, "ipfioctl(SYNC,%#x,%p) = %d\n", (u_int)cmd, data, i); if (i != 0) { errno = i; @@ -464,14 +498,15 @@ int ipooltestioctl(int dev, ioctlcmd_t cmd, ...) va_list ap; int i; + dev = dev; /* gcc -Wextra */ va_start(ap, cmd); data = va_arg(ap, caddr_t); va_end(ap); - i = iplioctl(IPL_LOGLOOKUP, cmd, data, FWRITE|FREAD); + i = ipfioctl(softc, IPL_LOGLOOKUP, cmd, data, FWRITE|FREAD); if ((opts & OPT_DEBUG) || (i != 0)) - fprintf(stderr, "iplioctl(POOL,%#x,%p) = %d\n", - (u_int)cmd, data, i); + fprintf(stderr, "ipfioctl(POOL,%#x,%p) = %d (%d)\n", + (u_int)cmd, data, i, softc->ipf_interror); if (i != 0) { errno = i; return -1; @@ -480,15 +515,17 @@ int ipooltestioctl(int dev, ioctlcmd_t cmd, ...) } #else int ipftestioctl(dev, cmd, data) -dev_t dev; -ioctlcmd_t cmd; -void *data; + dev_t dev; + ioctlcmd_t cmd; + void *data; { int i; - i = iplioctl(IPL_LOGIPF, cmd, data, FWRITE|FREAD); + dev = dev; /* gcc -Wextra */ + i = ipfioctl(softc, IPL_LOGIPF, cmd, data, FWRITE|FREAD); if ((opts & OPT_DEBUG) || (i != 0)) - fprintf(stderr, "iplioctl(IPF,%#x,%p) = %d\n", cmd, data, i); + fprintf(stderr, "ipfioctl(IPF,%#x,%p) = %d (%d)\n", + cmd, data, i, softc->ipf_interror); if (i != 0) { errno = i; return -1; @@ -498,15 +535,16 @@ void *data; int ipnattestioctl(dev, cmd, data) -dev_t dev; -ioctlcmd_t cmd; -void *data; + dev_t dev; + ioctlcmd_t cmd; + void *data; { int i; - i = iplioctl(IPL_LOGNAT, cmd, data, FWRITE|FREAD); + dev = dev; /* gcc -Wextra */ + i = ipfioctl(softc, IPL_LOGNAT, cmd, data, FWRITE|FREAD); if ((opts & OPT_DEBUG) || (i != 0)) - fprintf(stderr, "iplioctl(NAT,%#x,%p) = %d\n", cmd, data, i); + fprintf(stderr, "ipfioctl(NAT,%#x,%p) = %d\n", cmd, data, i); if (i != 0) { errno = i; return -1; @@ -516,15 +554,16 @@ void *data; int ipstatetestioctl(dev, cmd, data) -dev_t dev; -ioctlcmd_t cmd; -void *data; + dev_t dev; + ioctlcmd_t cmd; + void *data; { int i; - i = iplioctl(IPL_LOGSTATE, cmd, data, FWRITE|FREAD); + dev = dev; /* gcc -Wextra */ + i = ipfioctl(softc, IPL_LOGSTATE, cmd, data, FWRITE|FREAD); if ((opts & OPT_DEBUG) || (i != 0)) - fprintf(stderr, "iplioctl(STATE,%#x,%p) = %d\n", cmd, data, i); + fprintf(stderr, "ipfioctl(STATE,%#x,%p) = %d\n", cmd, data, i); if (i != 0) { errno = i; return -1; @@ -534,15 +573,16 @@ void *data; int ipauthtestioctl(dev, cmd, data) -dev_t dev; -ioctlcmd_t cmd; -void *data; + dev_t dev; + ioctlcmd_t cmd; + void *data; { int i; - i = iplioctl(IPL_LOGAUTH, cmd, data, FWRITE|FREAD); + dev = dev; /* gcc -Wextra */ + i = ipfioctl(softc, IPL_LOGAUTH, cmd, data, FWRITE|FREAD); if ((opts & OPT_DEBUG) || (i != 0)) - fprintf(stderr, "iplioctl(AUTH,%#x,%p) = %d\n", cmd, data, i); + fprintf(stderr, "ipfioctl(AUTH,%#x,%p) = %d\n", cmd, data, i); if (i != 0) { errno = i; return -1; @@ -552,15 +592,16 @@ void *data; int ipsynctestioctl(dev, cmd, data) -dev_t dev; -ioctlcmd_t cmd; -void *data; + dev_t dev; + ioctlcmd_t cmd; + void *data; { int i; - i = iplioctl(IPL_LOGSYNC, cmd, data, FWRITE|FREAD); + dev = dev; /* gcc -Wextra */ + i = ipfioctl(softc, IPL_LOGSYNC, cmd, data, FWRITE|FREAD); if ((opts & OPT_DEBUG) || (i != 0)) - fprintf(stderr, "iplioctl(SYNC,%#x,%p) = %d\n", cmd, data, i); + fprintf(stderr, "ipfioctl(SYNC,%#x,%p) = %d\n", cmd, data, i); if (i != 0) { errno = i; return -1; @@ -570,15 +611,16 @@ void *data; int ipscantestioctl(dev, cmd, data) -dev_t dev; -ioctlcmd_t cmd; -void *data; + dev_t dev; + ioctlcmd_t cmd; + void *data; { int i; - i = iplioctl(IPL_LOGSCAN, cmd, data, FWRITE|FREAD); + dev = dev; /* gcc -Wextra */ + i = ipfioctl(softc, IPL_LOGSCAN, cmd, data, FWRITE|FREAD); if ((opts & OPT_DEBUG) || (i != 0)) - fprintf(stderr, "iplioctl(SCAN,%#x,%p) = %d\n", cmd, data, i); + fprintf(stderr, "ipfioctl(SCAN,%#x,%p) = %d\n", cmd, data, i); if (i != 0) { errno = i; return -1; @@ -588,15 +630,17 @@ void *data; int ipooltestioctl(dev, cmd, data) -dev_t dev; -ioctlcmd_t cmd; -void *data; + dev_t dev; + ioctlcmd_t cmd; + void *data; { int i; - i = iplioctl(IPL_LOGLOOKUP, cmd, data, FWRITE|FREAD); + dev = dev; /* gcc -Wextra */ + i = ipfioctl(softc, IPL_LOGLOOKUP, cmd, data, FWRITE|FREAD); if (opts & OPT_DEBUG) - fprintf(stderr, "iplioctl(POOL,%#x,%p) = %d\n", cmd, data, i); + fprintf(stderr, "ipfioctl(POOL,%#x,%p) = %d (%d)\n", + cmd, data, i, softc->ipf_interror); if (i != 0) { errno = i; return -1; @@ -607,9 +651,9 @@ void *data; int kmemcpy(addr, offset, size) -char *addr; -long offset; -int size; + char *addr; + long offset; + int size; { bcopy((char *)offset, addr, size); return 0; @@ -617,9 +661,9 @@ int size; int kstrncpy(buf, pos, n) -char *buf; -long pos; -int n; + char *buf; + long pos; + int n; { char *ptr; @@ -634,100 +678,91 @@ int n; /* * Display the built up NAT table rules and mapping entries. */ -void dumpnat() +void dumpnat(arg) + void *arg; { + ipf_nat_softc_t *softn = arg; hostmap_t *hm; ipnat_t *ipn; nat_t *nat; printf("List of active MAP/Redirect filters:\n"); - for (ipn = nat_list; ipn != NULL; ipn = ipn->in_next) + for (ipn = softn->ipf_nat_list; ipn != NULL; ipn = ipn->in_next) printnat(ipn, opts & (OPT_DEBUG|OPT_VERBOSE)); printf("\nList of active sessions:\n"); - for (nat = nat_instances; nat; nat = nat->nat_next) { - printactivenat(nat, opts, 0, 0); + for (nat = softn->ipf_nat_instances; nat; nat = nat->nat_next) { + printactivenat(nat, opts, 0); if (nat->nat_aps) - printaps(nat->nat_aps, opts); + printf("\tproxy active\n"); } printf("\nHostmap table:\n"); - for (hm = ipf_hm_maplist; hm != NULL; hm = hm->hm_next) - printhostmap(hm, 0); + for (hm = softn->ipf_hm_maplist; hm != NULL; hm = hm->hm_next) + printhostmap(hm, hm->hm_hv); } -/* - * Display the built up state table rules and mapping entries. - */ -void dumpstate() -{ - ipstate_t *ips; - - printf("List of active state sessions:\n"); - for (ips = ips_list; ips != NULL; ) - ips = printstate(ips, opts & (OPT_DEBUG|OPT_VERBOSE), - fr_ticks); -} - - -void dumplookups() -{ - iphtable_t *iph; - ip_pool_t *ipl; - int i; - - printf("List of configured pools\n"); - for (i = 0; i < IPL_LOGSIZE; i++) - for (ipl = ip_pool_list[i]; ipl != NULL; ipl = ipl->ipo_next) - printpool(ipl, bcopywrap, NULL, opts); - - printf("List of configured hash tables\n"); - for (i = 0; i < IPL_LOGSIZE; i++) - for (iph = ipf_htables[i]; iph != NULL; iph = iph->iph_next) - printhash(iph, bcopywrap, NULL, opts); -} - - -void dumpgroups() +void dumpgroups(softc) + ipf_main_softc_t *softc; { frgroup_t *fg; - frentry_t *fr; int i; printf("List of groups configured (set 0)\n"); for (i = 0; i < IPL_LOGSIZE; i++) - for (fg = ipfgroups[i][0]; fg != NULL; fg = fg->fg_next) { + for (fg = softc->ipf_groups[i][0]; fg != NULL; + fg = fg->fg_next) { printf("Dev.%d. Group %s Ref %d Flags %#x\n", i, fg->fg_name, fg->fg_ref, fg->fg_flags); - for (fr = fg->fg_start; fr != NULL; fr = fr->fr_next) { -#ifdef USE_QUAD_T - printf("%qu ",(unsigned long long)fr->fr_hits); -#else - printf("%ld ", fr->fr_hits); -#endif - printfr(fr, ipftestioctl); - } + dumprules(fg->fg_start); } printf("List of groups configured (set 1)\n"); for (i = 0; i < IPL_LOGSIZE; i++) - for (fg = ipfgroups[i][1]; fg != NULL; fg = fg->fg_next) { + for (fg = softc->ipf_groups[i][1]; fg != NULL; + fg = fg->fg_next) { printf("Dev.%d. Group %s Ref %d Flags %#x\n", i, fg->fg_name, fg->fg_ref, fg->fg_flags); - for (fr = fg->fg_start; fr != NULL; fr = fr->fr_next) { -#ifdef USE_QUAD_T - printf("%qu ",(unsigned long long)fr->fr_hits); -#else - printf("%ld ", fr->fr_hits); -#endif - printfr(fr, ipftestioctl); - } + dumprules(fg->fg_start); } + + printf("Rules configured (set 0, in)\n"); + dumprules(softc->ipf_rules[0][0]); + printf("Rules configured (set 0, out)\n"); + dumprules(softc->ipf_rules[1][0]); + printf("Rules configured (set 1, in)\n"); + dumprules(softc->ipf_rules[0][1]); + printf("Rules configured (set 1, out)\n"); + dumprules(softc->ipf_rules[1][1]); + + printf("Accounting rules configured (set 0, in)\n"); + dumprules(softc->ipf_acct[0][0]); + printf("Accounting rules configured (set 0, out)\n"); + dumprules(softc->ipf_acct[0][1]); + printf("Accounting rules configured (set 1, in)\n"); + dumprules(softc->ipf_acct[1][0]); + printf("Accounting rules configured (set 1, out)\n"); + dumprules(softc->ipf_acct[1][1]); +} + +void dumprules(rulehead) + frentry_t *rulehead; +{ + frentry_t *fr; + + for (fr = rulehead; fr != NULL; fr = fr->fr_next) { +#ifdef USE_QUAD_T + printf("%"PRIu64" ",(unsigned long long)fr->fr_hits); +#else + printf("%ld ", fr->fr_hits); +#endif + printfr(fr, ipftestioctl); + } } void drain_log(filename) -char *filename; + char *filename; { char buffer[DEFAULT_IPFLOGSIZE]; struct iovec iov; @@ -753,7 +788,7 @@ char *filename; uio.uio_resid = iov.iov_len; resid = uio.uio_resid; - if (ipflog_read(i, &uio) == 0) { + if (ipf_log_read(softc, i, &uio) == 0) { /* * If nothing was read then break out. */ @@ -769,18 +804,38 @@ char *filename; void fixv4sums(m, ip) -mb_t *m; -ip_t *ip; + mb_t *m; + ip_t *ip; { - u_char *csump, *hdr; + u_char *csump, *hdr, p; + fr_info_t tmp; + int len; - ip->ip_sum = 0; - ip->ip_sum = ipf_cksum((u_short *)ip, IP_HL(ip) << 2); + p = 0; + len = 0; + bzero((char *)&tmp, sizeof(tmp)); csump = (u_char *)ip; - csump += IP_HL(ip) << 2; + if (IP_V(ip) == 4) { + ip->ip_sum = 0; + ip->ip_sum = ipf_cksum((u_short *)ip, IP_HL(ip) << 2); + tmp.fin_hlen = IP_HL(ip) << 2; + csump += IP_HL(ip) << 2; + p = ip->ip_p; + len = ntohs(ip->ip_len); +#ifdef USE_INET6 + } else if (IP_V(ip) == 6) { + tmp.fin_hlen = sizeof(ip6_t); + csump += sizeof(ip6_t); + p = ((ip6_t *)ip)->ip6_nxt; + len = ntohs(((ip6_t *)ip)->ip6_plen); + len += sizeof(ip6_t); +#endif + } + tmp.fin_plen = len; + tmp.fin_dlen = len - tmp.fin_hlen; - switch (ip->ip_p) + switch (p) { case IPPROTO_TCP : hdr = csump; @@ -800,7 +855,12 @@ ip_t *ip; break; } if (hdr != NULL) { + tmp.fin_m = m; + tmp.fin_mp = &m; + tmp.fin_dp = hdr; + tmp.fin_ip = ip; + tmp.fin_plen = len; *csump = 0; - *(u_short *)csump = fr_cksum(m, ip, ip->ip_p, hdr, ip->ip_len); + *(u_short *)csump = fr_cksum(&tmp, ip, p, hdr); } } diff --git a/contrib/ipfilter/tools/ipmon.c b/contrib/ipfilter/tools/ipmon.c index ceaed82cb4b3..1c52e7fd87ac 100644 --- a/contrib/ipfilter/tools/ipmon.c +++ b/contrib/ipfilter/tools/ipmon.c @@ -1,84 +1,22 @@ /* $FreeBSD$ */ /* - * Copyright (C) 2001-2006 by Darren Reed. + * Copyright (C) 2012 by Darren Reed. * * See the IPFILTER.LICENCE file for details on licencing. */ -#ifndef SOLARIS -#define SOLARIS (defined(__SVR4) || defined(__svr4__)) && defined(sun) -#endif - -#include -#include -#include -#include -#include -#define _KERNEL -#include -#undef _KERNEL -#include -#include - -#include -#include -#include -#include -#include -#include -#if !defined(__SVR4) && !defined(__svr4__) -# if (__FreeBSD_version >= 300000) -# include -# else -# include -# endif -#else -# include -# include -#endif -#if !defined(__hpux) && (!defined(__SVR4) && !defined(__GNUC__)) -# include -#endif -#include -#include -#include -#include -#include -#include -#include -#if !defined(__hpux) && !defined(linux) -# include -#endif -#include -#include -#include -#ifdef __hpux -# undef NOERROR -#endif -#include - -#if !defined(linux) -# include -# include -#endif - -#include -#include - -#include -#include - -#include "netinet/ip_compat.h" -#include -#include "netinet/ip_fil.h" -#include "netinet/ip_nat.h" -#include "netinet/ip_state.h" -#include "netinet/ip_proxy.h" +#include "ipf.h" #include "ipmon.h" +#include +#include +#include +#include +#include +#include #if !defined(lint) static const char sccsid[] = "@(#)ipmon.c 1.21 6/5/96 (C)1993-2000 Darren Reed"; -static const char rcsid[] = "@(#)$Id: ipmon.c,v 1.33.2.20 2007/09/20 12:51:56 darrenr Exp $"; +static const char rcsid[] = "@(#)$Id$"; #endif @@ -89,12 +27,41 @@ extern char *sys_errlist[]; #define STRERROR(x) strerror(x) #endif +extern int optind; +extern char *optarg; + +extern ipmon_saver_t executesaver; +extern ipmon_saver_t filesaver; +extern ipmon_saver_t nothingsaver; +extern ipmon_saver_t snmpv1saver; +extern ipmon_saver_t snmpv2saver; +extern ipmon_saver_t syslogsaver; + struct flags { int value; char flag; }; +typedef struct logsource { + int fd; + int logtype; + char *file; + int regular; + size_t size; +} logsource_t; + +typedef struct config { + int opts; + int maxfd; + logsource_t logsrc[3]; + fd_set fdmr; + FILE *blog; + char *bfile; + FILE *log; + char *file; + char *cfile; +} config_t; typedef struct icmp_subtype { int ist_val; @@ -124,6 +91,28 @@ struct flags tcpfl[] = { { 0, '\0' } }; +char *reasons[] = { + "filter-rule", + "log-or-block_1", + "pps-rate", + "jumbogram", + "makefrip-fail", + "state_add-fail", + "updateipid-fail", + "log-or-block_2", + "decap-fail", + "auth_new-fail", + "auth_captured", + "coalesce-fail", + "pullup-fail", + "auth-feedback", + "bad-frag", + "natv4_out-fail", + "natv4_in-fail", + "natv6_out-fail", + "natv6_in-fail", +}; + #ifdef MENTAT static char *pidfile = "/etc/opt/ipf/ipmon.pid"; #else @@ -135,18 +124,14 @@ static char *pidfile = "/etc/ipmon.pid"; #endif static char line[2048]; -static int opts = 0; -static char *logfile = NULL; -static FILE *binarylog = NULL; -static char *binarylogfile = NULL; static int donehup = 0; static void usage __P((char *)); static void handlehup __P((int)); static void flushlogs __P((char *, FILE *)); -static void print_log __P((int, FILE *, char *, int)); -static void print_ipflog __P((FILE *, char *, int)); -static void print_natlog __P((FILE *, char *, int)); -static void print_statelog __P((FILE *, char *, int)); +static void print_log __P((config_t *, logsource_t *, char *, int)); +static void print_ipflog __P((config_t *, char *, int)); +static void print_natlog __P((config_t *, char *, int)); +static void print_statelog __P((config_t *, char *, int)); static int read_log __P((int, int *, char *, int)); static void write_pid __P((char *)); static char *icmpname __P((u_int, u_int)); @@ -159,39 +144,30 @@ static struct tm *get_tm __P((u_32_t)); static struct tm *get_tm __P((time_t)); #endif -char *hostname __P((int, int, u_32_t *)); -char *portname __P((int, char *, u_int)); +char *portlocalname __P((int, char *, u_int)); int main __P((int, char *[])); static void logopts __P((int, char *)); static void init_tabs __P((void)); -static char *getproto __P((u_int)); +static char *getlocalproto __P((u_int)); +static void openlogs __P((config_t *conf)); +static int read_loginfo __P((config_t *conf)); +static void initconfig __P((config_t *conf)); static char **protocols = NULL; static char **udp_ports = NULL; static char **tcp_ports = NULL; -static char *conf_file = NULL; -#define OPT_SYSLOG 0x001 -#define OPT_RESOLVE 0x002 -#define OPT_HEXBODY 0x004 -#define OPT_VERBOSE 0x008 -#define OPT_HEXHDR 0x010 -#define OPT_TAIL 0x020 -#define OPT_NAT 0x080 -#define OPT_STATE 0x100 -#define OPT_FILTER 0x200 -#define OPT_PORTNUM 0x400 -#define OPT_LOGALL (OPT_NAT|OPT_STATE|OPT_FILTER) -#define OPT_LOGBODY 0x800 - -#define HOSTNAME_V4(a,b) hostname((a), 4, (u_32_t *)&(b)) +#define HOSTNAMEV4(b) hostname(AF_INET, (u_32_t *)&(b)) #ifndef LOGFAC #define LOGFAC LOG_LOCAL0 #endif int logfac = LOGFAC; +int ipmonopts = 0; +int opts = OPT_NORESOLVE; +int use_inet6 = 0; static icmp_subtype_t icmpunreachnames[] = { @@ -233,7 +209,7 @@ static icmp_subtype_t paramnames[] = { { -2, NULL } }; -static icmp_type_t icmptypes[] = { +static icmp_type_t icmptypes4[] = { { ICMP_ECHOREPLY, NULL, 0, "echoreply" }, { -1, NULL, 0, NULL }, { -1, NULL, 0, NULL }, @@ -338,9 +314,9 @@ static icmp_type_t icmptypes6[] = { }; static icmp_subtype_t *find_icmpsubtype(type, table, tablesz) -int type; -icmp_subtype_t *table; -size_t tablesz; + int type; + icmp_subtype_t *table; + size_t tablesz; { icmp_subtype_t *ist; int i; @@ -363,9 +339,9 @@ size_t tablesz; static icmp_type_t *find_icmptype(type, table, tablesz) -int type; -icmp_type_t *table; -size_t tablesz; + int type; + icmp_type_t *table; + size_t tablesz; { icmp_type_t *it; int i; @@ -388,7 +364,7 @@ size_t tablesz; static void handlehup(sig) -int sig; + int sig; { signal(SIGHUP, handlehup); donehup = 1; @@ -421,12 +397,12 @@ static void init_tabs() p->p_name != NULL && protocols[p->p_proto] == NULL) protocols[p->p_proto] = strdup(p->p_name); endprotoent(); -#if defined(_AIX51) if (protocols[0]) free(protocols[0]); + protocols[0] = strdup("ip"); +#if defined(_AIX51) if (protocols[252]) free(protocols[252]); - protocols[0] = "ip"; protocols[252] = NULL; #endif } @@ -480,8 +456,8 @@ static void init_tabs() } -static char *getproto(p) -u_int p; +static char *getlocalproto(p) + u_int p; { static char pnum[4]; char *s; @@ -497,11 +473,14 @@ u_int p; static int read_log(fd, lenp, buf, bufsize) -int fd, bufsize, *lenp; -char *buf; + int fd, bufsize, *lenp; + char *buf; { int nr; + if (bufsize > IPFILTER_LOGSIZE) + bufsize = IPFILTER_LOGSIZE; + nr = read(fd, buf, bufsize); if (!nr) return 2; @@ -512,51 +491,18 @@ char *buf; } -char *hostname(res, v, ip) -int res, v; -u_32_t *ip; +char *portlocalname(res, proto, port) + int res; + char *proto; + u_int port; { -# define MAX_INETA 16 - static char hname[MAXHOSTNAMELEN + MAX_INETA + 3]; -#ifdef USE_INET6 - static char hostbuf[MAXHOSTNAMELEN+1]; -#endif - struct hostent *hp; - struct in_addr ipa; - - 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); - sprintf(hname, "%.*s[%s]", MAXHOSTNAMELEN, hp->h_name, - inet_ntoa(ipa)); - return hname; - } -#ifdef USE_INET6 - (void) inet_ntop(AF_INET6, ip, hostbuf, sizeof(hostbuf) - 1); - hostbuf[MAXHOSTNAMELEN] = '\0'; - return hostbuf; -#else - return "IPv6"; -#endif -} - - -char *portname(res, proto, port) -int res; -char *proto; -u_int port; -{ - static char pname[8]; - char *s; + static char pname[8]; + char *s; port = ntohs(port); port &= 0xffff; - (void) sprintf(pname, "%u", port); - if (!res || (opts & OPT_PORTNUM)) + sprintf(pname, "%u", port); + if (!res || (ipmonopts & IPMON_PORTNUM)) return pname; s = NULL; if (!strcmp(proto, "tcp")) @@ -569,9 +515,9 @@ u_int port; } -static char *icmpname(type, code) -u_int type; -u_int code; +static char *icmpname(type, code) + u_int type; + u_int code; { static char name[80]; icmp_subtype_t *ist; @@ -579,7 +525,7 @@ u_int code; char *s; s = NULL; - it = find_icmptype(type, icmptypes, sizeof(icmptypes) / sizeof(*it)); + it = find_icmptype(type, icmptypes4, sizeof(icmptypes4) / sizeof(*it)); if (it != NULL) s = it->it_name; @@ -600,9 +546,9 @@ u_int code; return name; } -static char *icmpname6(type, code) -u_int type; -u_int code; +static char *icmpname6(type, code) + u_int type; + u_int code; { static char name[80]; icmp_subtype_t *ist; @@ -632,11 +578,11 @@ u_int code; } -void dumphex(log, dopts, buf, len) -FILE *log; -int dopts; -char *buf; -int len; +void dumphex(log, dopts, buf, len) + FILE *log; + int dopts; + char *buf; + int len; { char hline[80]; int i, j, k; @@ -651,7 +597,7 @@ int len; if (j && !(j & 0xf)) { *t++ = '\n'; *t = '\0'; - if ((dopts & OPT_SYSLOG)) + if ((dopts & IPMON_SYSLOG)) syslog(LOG_INFO, "%s", hline); else if (log != NULL) fputs(hline, log); @@ -665,10 +611,10 @@ int len; sprintf((char *)t, " "); t += 8; for (k = 16; k; k--, s++) - *t++ = (ISPRINT(*s) ? *s : '.'); + *t++ = (isprint(*s) ? *s : '.'); s--; } - + if ((j + 1) & 0xf) *t++ = ' ';; } @@ -683,11 +629,11 @@ int len; t += 7; s -= j & 0xf; for (k = j & 0xf; k; k--, s++) - *t++ = (ISPRINT(*s) ? *s : '.'); + *t++ = (isprint(*s) ? *s : '.'); *t++ = '\n'; *t = '\0'; } - if ((dopts & OPT_SYSLOG) != 0) + if ((dopts & IPMON_SYSLOG) != 0) syslog(LOG_INFO, "%s", hline); else if (log != NULL) { fputs(hline, log); @@ -696,11 +642,11 @@ int len; } -static struct tm *get_tm(sec) +static struct tm *get_tm(sec) #ifdef __hpux -u_32_t sec; + u_32_t sec; #else -time_t sec; + time_t sec; #endif { struct tm *tm; @@ -711,23 +657,44 @@ time_t sec; return tm; } -static void print_natlog(log, buf, blen) -FILE *log; -char *buf; -int blen; +static void print_natlog(conf, buf, blen) + config_t *conf; + char *buf; + int blen; { - struct natlog *nl; - iplog_t *ipl = (iplog_t *)buf; - char *t = line; - struct tm *tm; - int res, i, len; - char *proto; + static u_32_t seqnum = 0; + int res, i, len, family; + struct natlog *nl; + struct tm *tm; + iplog_t *ipl; + char *proto; + int simple; + char *t; + + t = line; + simple = 0; + ipl = (iplog_t *)buf; + if (ipl->ipl_seqnum != seqnum) { + if ((ipmonopts & IPMON_SYSLOG) != 0) { + syslog(LOG_WARNING, + "missed %u NAT log entries: %u %u", + ipl->ipl_seqnum - seqnum, seqnum, + ipl->ipl_seqnum); + } else { + (void) fprintf(conf->log, + "missed %u NAT log entries: %u %u\n", + ipl->ipl_seqnum - seqnum, seqnum, + ipl->ipl_seqnum); + } + } + seqnum = ipl->ipl_seqnum + ipl->ipl_count; nl = (struct natlog *)((char *)ipl + sizeof(*ipl)); - res = (opts & OPT_RESOLVE) ? 1 : 0; + res = (ipmonopts & IPMON_RESOLVE) ? 1 : 0; tm = get_tm(ipl->ipl_sec); len = sizeof(line); - if (!(opts & OPT_SYSLOG)) { + + if (!(ipmonopts & IPMON_SYSLOG)) { (void) strftime(t, len, "%d/%m/%Y ", tm); i = strlen(t); len -= i; @@ -735,81 +702,184 @@ int blen; } (void) strftime(t, len, "%T", tm); t += strlen(t); - (void) sprintf(t, ".%-.6ld @%hd ", ipl->ipl_usec, nl->nl_rule + 1); + sprintf(t, ".%-.6ld @%hd ", (long)ipl->ipl_usec, nl->nl_rule + 1); t += strlen(t); - if (nl->nl_type == NL_NEWMAP) - strcpy(t, "NAT:MAP "); - else if (nl->nl_type == NL_NEWRDR) - strcpy(t, "NAT:RDR "); - else if (nl->nl_type == NL_FLUSH) - strcpy(t, "NAT:FLUSH "); - else if (nl->nl_type == NL_EXPIRE) - strcpy(t, "NAT:EXPIRE "); - else if (nl->nl_type == NL_NEWBIMAP) - strcpy(t, "NAT:BIMAP "); - else if (nl->nl_type == NL_NEWBLOCK) - strcpy(t, "NAT:MAPBLOCK "); - else if (nl->nl_type == NL_CLONE) - strcpy(t, "NAT:CLONE "); - else if (nl->nl_type == NL_DESTROY) - strcpy(t, "NAT:DESTROY "); - else - sprintf(t, "Type: %d ", nl->nl_type); + switch (nl->nl_action) + { + case NL_NEW : + strcpy(t, "NAT:NEW"); + break; + + case NL_FLUSH : + strcpy(t, "NAT:FLUSH"); + break; + + case NL_CLONE : + strcpy(t, "NAT:CLONE"); + break; + + case NL_EXPIRE : + strcpy(t, "NAT:EXPIRE"); + break; + + case NL_DESTROY : + strcpy(t, "NAT:DESTROY"); + break; + + case NL_PURGE : + strcpy(t, "NAT:PURGE"); + break; + + default : + sprintf(t, "NAT:Action(%d)", nl->nl_action); + break; + } t += strlen(t); - proto = getproto(nl->nl_p); - (void) sprintf(t, "%s,%s <- -> ", HOSTNAME_V4(res, nl->nl_inip), - portname(res, proto, (u_int)nl->nl_inport)); + switch (nl->nl_type) + { + case NAT_MAP : + strcpy(t, "-MAP "); + simple = 1; + break; + + case NAT_REDIRECT : + strcpy(t, "-RDR "); + simple = 1; + break; + + case NAT_BIMAP : + strcpy(t, "-BIMAP "); + simple = 1; + break; + + case NAT_MAPBLK : + strcpy(t, "-MAPBLOCK "); + simple = 1; + break; + + case NAT_REWRITE|NAT_MAP : + strcpy(t, "-RWR_MAP "); + break; + + case NAT_REWRITE|NAT_REDIRECT : + strcpy(t, "-RWR_RDR "); + break; + + case NAT_ENCAP|NAT_MAP : + strcpy(t, "-ENC_MAP "); + break; + + case NAT_ENCAP|NAT_REDIRECT : + strcpy(t, "-ENC_RDR "); + break; + + case NAT_DIVERTUDP|NAT_MAP : + strcpy(t, "-DIV_MAP "); + break; + + case NAT_DIVERTUDP|NAT_REDIRECT : + strcpy(t, "-DIV_RDR "); + break; + + default : + sprintf(t, "-Type(%d) ", nl->nl_type); + break; + } t += strlen(t); - (void) sprintf(t, "%s,%s ", HOSTNAME_V4(res, nl->nl_outip), - portname(res, proto, (u_int)nl->nl_outport)); + + proto = getlocalproto(nl->nl_p[0]); + + family = vtof(nl->nl_v[0]); + + if (simple == 1) { + sprintf(t, "%s,%s <- -> ", hostname(family, nl->nl_osrcip.i6), + portlocalname(res, proto, (u_int)nl->nl_osrcport)); + t += strlen(t); + sprintf(t, "%s,%s ", hostname(family, nl->nl_nsrcip.i6), + portlocalname(res, proto, (u_int)nl->nl_nsrcport)); + t += strlen(t); + sprintf(t, "[%s,%s] ", hostname(family, nl->nl_odstip.i6), + portlocalname(res, proto, (u_int)nl->nl_odstport)); + } else { + sprintf(t, "%s,%s ", hostname(family, nl->nl_osrcip.i6), + portlocalname(res, proto, (u_int)nl->nl_osrcport)); + t += strlen(t); + sprintf(t, "%s,%s <- -> ", hostname(family, nl->nl_odstip.i6), + portlocalname(res, proto, (u_int)nl->nl_odstport)); + t += strlen(t); + sprintf(t, "%s,%s ", hostname(family, nl->nl_nsrcip.i6), + portlocalname(res, proto, (u_int)nl->nl_nsrcport)); + t += strlen(t); + sprintf(t, "%s,%s ", hostname(family, nl->nl_ndstip.i6), + portlocalname(res, proto, (u_int)nl->nl_ndstport)); + } t += strlen(t); - (void) sprintf(t, "[%s,%s PR %s]", HOSTNAME_V4(res, nl->nl_origip), - portname(res, proto, (u_int)nl->nl_origport), - getproto(nl->nl_p)); + + strcpy(t, getlocalproto(nl->nl_p[0])); t += strlen(t); - if (nl->nl_type == NL_EXPIRE) { + + if (nl->nl_action == NL_EXPIRE || nl->nl_action == NL_FLUSH) { #ifdef USE_QUAD_T - (void) sprintf(t, " Pkts %qd/%qd Bytes %qd/%qd", - (long long)nl->nl_pkts[0], - (long long)nl->nl_pkts[1], - (long long)nl->nl_bytes[0], - (long long)nl->nl_bytes[1]); +# ifdef PRId64 + sprintf(t, " Pkts %" PRId64 "/%" PRId64 " Bytes %" PRId64 "/%" + PRId64, +# else + sprintf(t, " Pkts %qd/%qd Bytes %qd/%qd", +# endif #else - (void) sprintf(t, " Pkts %ld/%ld Bytes %ld/%ld", + sprintf(t, " Pkts %ld/%ld Bytes %ld/%ld", +#endif nl->nl_pkts[0], nl->nl_pkts[1], nl->nl_bytes[0], nl->nl_bytes[1]); -#endif t += strlen(t); } *t++ = '\n'; *t++ = '\0'; - if (opts & OPT_SYSLOG) + if (ipmonopts & IPMON_SYSLOG) syslog(LOG_INFO, "%s", line); - else if (log != NULL) - (void) fprintf(log, "%s", line); + else if (conf->log != NULL) + (void) fprintf(conf->log, "%s", line); } -static void print_statelog(log, buf, blen) -FILE *log; -char *buf; -int blen; +static void print_statelog(conf, buf, blen) + config_t *conf; + char *buf; + int blen; { - struct ipslog *sl; - iplog_t *ipl = (iplog_t *)buf; - char *t = line, *proto; - struct tm *tm; - int res, i, len; + static u_32_t seqnum = 0; + int res, i, len, family; + struct ipslog *sl; + char *t, *proto; + struct tm *tm; + iplog_t *ipl; + + t = line; + ipl = (iplog_t *)buf; + if (ipl->ipl_seqnum != seqnum) { + if ((ipmonopts & IPMON_SYSLOG) != 0) { + syslog(LOG_WARNING, + "missed %u state log entries: %u %u", + ipl->ipl_seqnum - seqnum, seqnum, + ipl->ipl_seqnum); + } else { + (void) fprintf(conf->log, + "missed %u state log entries: %u %u\n", + ipl->ipl_seqnum - seqnum, seqnum, + ipl->ipl_seqnum); + } + } + seqnum = ipl->ipl_seqnum + ipl->ipl_count; sl = (struct ipslog *)((char *)ipl + sizeof(*ipl)); - res = (opts & OPT_RESOLVE) ? 1 : 0; + res = (ipmonopts & IPMON_RESOLVE) ? 1 : 0; tm = get_tm(ipl->ipl_sec); len = sizeof(line); - if (!(opts & OPT_SYSLOG)) { + if (!(ipmonopts & IPMON_SYSLOG)) { (void) strftime(t, len, "%d/%m/%Y ", tm); i = strlen(t); len -= i; @@ -817,9 +887,11 @@ int blen; } (void) strftime(t, len, "%T", tm); t += strlen(t); - (void) sprintf(t, ".%-.6ld ", ipl->ipl_usec); + sprintf(t, ".%-.6ld ", (long)ipl->ipl_usec); t += strlen(t); + family = vtof(sl->isl_v); + switch (sl->isl_type) { case ISL_NEW : @@ -865,41 +937,37 @@ int blen; } t += strlen(t); - proto = getproto(sl->isl_p); + proto = getlocalproto(sl->isl_p); if (sl->isl_p == IPPROTO_TCP || sl->isl_p == IPPROTO_UDP) { - (void) sprintf(t, "%s,%s -> ", - hostname(res, sl->isl_v, (u_32_t *)&sl->isl_src), - portname(res, proto, (u_int)sl->isl_sport)); + sprintf(t, "%s,%s -> ", + hostname(family, (u_32_t *)&sl->isl_src), + portlocalname(res, proto, (u_int)sl->isl_sport)); t += strlen(t); - (void) sprintf(t, "%s,%s PR %s", - hostname(res, sl->isl_v, (u_32_t *)&sl->isl_dst), - portname(res, proto, (u_int)sl->isl_dport), proto); + sprintf(t, "%s,%s PR %s", + hostname(family, (u_32_t *)&sl->isl_dst), + portlocalname(res, proto, (u_int)sl->isl_dport), proto); } else if (sl->isl_p == IPPROTO_ICMP) { - (void) sprintf(t, "%s -> ", hostname(res, sl->isl_v, - (u_32_t *)&sl->isl_src)); + sprintf(t, "%s -> ", hostname(family, (u_32_t *)&sl->isl_src)); t += strlen(t); - (void) sprintf(t, "%s PR icmp %d", - hostname(res, sl->isl_v, (u_32_t *)&sl->isl_dst), + sprintf(t, "%s PR icmp %d", + hostname(family, (u_32_t *)&sl->isl_dst), sl->isl_itype); } else if (sl->isl_p == IPPROTO_ICMPV6) { - (void) sprintf(t, "%s -> ", hostname(res, sl->isl_v, - (u_32_t *)&sl->isl_src)); + sprintf(t, "%s -> ", hostname(family, (u_32_t *)&sl->isl_src)); t += strlen(t); - (void) sprintf(t, "%s PR icmpv6 %d", - hostname(res, sl->isl_v, (u_32_t *)&sl->isl_dst), + sprintf(t, "%s PR icmpv6 %d", + hostname(family, (u_32_t *)&sl->isl_dst), sl->isl_itype); } else { - (void) sprintf(t, "%s -> ", - hostname(res, sl->isl_v, (u_32_t *)&sl->isl_src)); + sprintf(t, "%s -> ", hostname(family, (u_32_t *)&sl->isl_src)); t += strlen(t); - (void) sprintf(t, "%s PR %s", - hostname(res, sl->isl_v, (u_32_t *)&sl->isl_dst), - proto); + sprintf(t, "%s PR %s", + hostname(family, (u_32_t *)&sl->isl_dst), proto); } t += strlen(t); if (sl->isl_tag != FR_NOLOGTAG) { - (void) sprintf(t, " tag %u", sl->isl_tag); + sprintf(t, " tag %u", sl->isl_tag); t += strlen(t); } if (sl->isl_type != ISL_NEW) { @@ -926,22 +994,26 @@ int blen; *t++ = '\n'; *t++ = '\0'; - if (opts & OPT_SYSLOG) + if (ipmonopts & IPMON_SYSLOG) syslog(LOG_INFO, "%s", line); - else if (log != NULL) - (void) fprintf(log, "%s", line); + else if (conf->log != NULL) + (void) fprintf(conf->log, "%s", line); } -static void print_log(logtype, log, buf, blen) -FILE *log; -char *buf; -int logtype, blen; +static void print_log(conf, log, buf, blen) + config_t *conf; + logsource_t *log; + char *buf; + int blen; { + char *bp, *bpo; iplog_t *ipl; - char *bp = NULL, *bpo = NULL; int psize; + bp = NULL; + bpo = NULL; + while (blen > 0) { ipl = (iplog_t *)buf; if ((u_long)ipl & (sizeof(long)-1)) { @@ -961,22 +1033,22 @@ int logtype, blen; if (psize > blen) break; - if (binarylog) { - fwrite(buf, psize, 1, binarylog); - fflush(binarylog); + if (conf->blog != NULL) { + fwrite(buf, psize, 1, conf->blog); + fflush(conf->blog); } - if (logtype == IPL_LOGIPF) { + if (log->logtype == IPL_LOGIPF) { if (ipl->ipl_magic == IPL_MAGIC) - print_ipflog(log, buf, psize); + print_ipflog(conf, buf, psize); - } else if (logtype == IPL_LOGNAT) { + } else if (log->logtype == IPL_LOGNAT) { if (ipl->ipl_magic == IPL_MAGIC_NAT) - print_natlog(log, buf, psize); + print_natlog(conf, buf, psize); - } else if (logtype == IPL_LOGSTATE) { + } else if (log->logtype == IPL_LOGSTATE) { if (ipl->ipl_magic == IPL_MAGIC_STATE) - print_statelog(log, buf, psize); + print_statelog(conf, buf, psize); } blen -= psize; @@ -988,22 +1060,23 @@ int logtype, blen; } -static void print_ipflog(log, buf, blen) -FILE *log; -char *buf; -int blen; +static void print_ipflog(conf, buf, blen) + config_t *conf; + char *buf; + int blen; { - tcphdr_t *tp; - struct icmp *ic; - struct icmp *icmp; - struct tm *tm; - char *t, *proto; - int i, v, lvl, res, len, off, plen, ipoff, defaction; - ip_t *ipc, *ip; - u_32_t *s, *d; - u_short hl, p; + static u_32_t seqnum = 0; + int i, f, lvl, res, len, off, plen, ipoff, defaction; + struct icmp *icmp; + struct icmp *ic; + char *t, *proto; + ip_t *ipc, *ip; + struct tm *tm; + u_32_t *s, *d; + u_short hl, p; ipflog_t *ipf; - iplog_t *ipl; + iplog_t *ipl; + tcphdr_t *tp; #ifdef USE_INET6 struct ip6_ext *ehp; u_short ehl; @@ -1012,16 +1085,31 @@ int blen; #endif ipl = (iplog_t *)buf; + if (ipl->ipl_seqnum != seqnum) { + if ((ipmonopts & IPMON_SYSLOG) != 0) { + syslog(LOG_WARNING, + "missed %u ipf log entries: %u %u", + ipl->ipl_seqnum - seqnum, seqnum, + ipl->ipl_seqnum); + } else { + (void) fprintf(conf->log, + "missed %u ipf log entries: %u %u\n", + ipl->ipl_seqnum - seqnum, seqnum, + ipl->ipl_seqnum); + } + } + seqnum = ipl->ipl_seqnum + ipl->ipl_count; + ipf = (ipflog_t *)((char *)buf + sizeof(*ipl)); ip = (ip_t *)((char *)ipf + sizeof(*ipf)); - v = IP_V(ip); - res = (opts & OPT_RESOLVE) ? 1 : 0; + f = ipf->fl_family; + res = (ipmonopts & IPMON_RESOLVE) ? 1 : 0; t = line; *t = '\0'; tm = get_tm(ipl->ipl_sec); len = sizeof(line); - if (!(opts & OPT_SYSLOG)) { + if (!(ipmonopts & IPMON_SYSLOG)) { (void) strftime(t, len, "%d/%m/%Y ", tm); i = strlen(t); len -= i; @@ -1029,10 +1117,10 @@ int blen; } (void) strftime(t, len, "%T", tm); t += strlen(t); - (void) sprintf(t, ".%-.6ld ", ipl->ipl_usec); + sprintf(t, ".%-.6ld ", (long)ipl->ipl_usec); t += strlen(t); if (ipl->ipl_count > 1) { - (void) sprintf(t, "%dx ", ipl->ipl_count); + sprintf(t, "%dx ", ipl->ipl_count); t += strlen(t); } #if (defined(MENTAT) || \ @@ -1044,13 +1132,19 @@ int blen; strncpy(ifname, ipf->fl_ifname, sizeof(ipf->fl_ifname)); ifname[sizeof(ipf->fl_ifname)] = '\0'; - (void) sprintf(t, "%s", ifname); + sprintf(t, "%s", ifname); t += strlen(t); # if defined(MENTAT) || defined(linux) - if (ISALPHA(*(t - 1))) { - sprintf(t, "%d", ipf->fl_unit); - t += strlen(t); - } +# if defined(linux) + /* + * On Linux, the loopback interface is just "lo", not "lo0". + */ + if (strcmp(ifname, "lo") != 0) +# endif + if (ISALPHA(*(t - 1))) { + sprintf(t, "%d", ipf->fl_unit); + t += strlen(t); + } # endif } #else @@ -1059,7 +1153,7 @@ int blen; break; if (ipf->fl_ifname[len]) len++; - (void) sprintf(t, "%*.*s%u", len, len, ipf->fl_ifname, ipf->fl_unit); + sprintf(t, "%*.*s%u", len, len, ipf->fl_ifname, ipf->fl_unit); t += strlen(t); #endif if ((ipf->fl_group[0] == (char)~0) && (ipf->fl_group[1] == '\0')) @@ -1067,12 +1161,12 @@ int blen; else if (ipf->fl_group[0] == '\0') (void) strcpy(t, " @0:"); else - (void) sprintf(t, " @%s:", ipf->fl_group); + sprintf(t, " @%s:", ipf->fl_group); t += strlen(t); if (ipf->fl_rule == 0xffffffff) strcat(t, "-1 "); else - (void) sprintf(t, "%u ", ipf->fl_rule + 1); + sprintf(t, "%u ", ipf->fl_rule + 1); t += strlen(t); lvl = LOG_NOTICE; @@ -1107,8 +1201,17 @@ int blen; *t++ = ' '; *t = '\0'; - if (v == 6) { + if (f == AF_INET) { + hl = IP_HL(ip) << 2; + ipoff = ntohs(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 = ntohs(ip->ip_len); + } else #ifdef USE_INET6 + if (f == AF_INET6) { off = 0; ipoff = 0; hl = sizeof(ip6_t); @@ -1140,32 +1243,22 @@ int blen; break; } } -#else - sprintf(t, "ipv6"); - goto printipflog; + } else #endif - } else if (v == 4) { - hl = IP_HL(ip) << 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); + proto = getlocalproto(p); if ((p == IPPROTO_TCP || p == IPPROTO_UDP) && !off) { tp = (tcphdr_t *)((char *)ip + hl); if (!(ipf->fl_lflags & FI_SHORT)) { - (void) sprintf(t, "%s,%s -> ", hostname(res, v, s), - portname(res, proto, (u_int)tp->th_sport)); + sprintf(t, "%s,%s -> ", hostname(f, s), + portlocalname(res, proto, (u_int)tp->th_sport)); t += strlen(t); - (void) sprintf(t, "%s,%s PR %s len %hu %hu", - hostname(res, v, d), - portname(res, proto, (u_int)tp->th_dport), + sprintf(t, "%s,%s PR %s len %hu %hu", + hostname(f, d), + portlocalname(res, proto, (u_int)tp->th_dport), proto, hl, plen); t += strlen(t); @@ -1175,8 +1268,8 @@ int blen; for (i = 0; tcpfl[i].value; i++) if (tp->th_flags & tcpfl[i].value) *t++ = tcpfl[i].flag; - if (opts & OPT_VERBOSE) { - (void) sprintf(t, " %lu %lu %hu", + if (ipmonopts & IPMON_VERBOSE) { + sprintf(t, " %lu %lu %hu", (u_long)(ntohl(tp->th_seq)), (u_long)(ntohl(tp->th_ack)), ntohs(tp->th_win)); @@ -1185,24 +1278,26 @@ int blen; } *t = '\0'; } else { - (void) sprintf(t, "%s -> ", hostname(res, v, s)); + sprintf(t, "%s -> ", hostname(f, s)); t += strlen(t); - (void) sprintf(t, "%s PR %s len %hu %hu", - hostname(res, v, d), proto, hl, plen); + sprintf(t, "%s PR %s len %hu %hu", + hostname(f, d), proto, hl, plen); } - } else if ((p == IPPROTO_ICMPV6) && !off && (v == 6)) { +#if defined(AF_INET6) && defined(IPPROTO_ICMPV6) + } else if ((p == IPPROTO_ICMPV6) && !off && (f == AF_INET6)) { ic = (struct icmp *)((char *)ip + hl); - (void) sprintf(t, "%s -> ", hostname(res, v, s)); + sprintf(t, "%s -> ", hostname(f, s)); t += strlen(t); - (void) sprintf(t, "%s PR icmpv6 len %hu %hu icmpv6 %s", - hostname(res, v, d), hl, plen, + sprintf(t, "%s PR icmpv6 len %hu %hu icmpv6 %s", + hostname(f, d), hl, plen, icmpname6(ic->icmp_type, ic->icmp_code)); - } else if ((p == IPPROTO_ICMP) && !off && (v == 4)) { +#endif + } else if ((p == IPPROTO_ICMP) && !off && (f == AF_INET)) { ic = (struct icmp *)((char *)ip + hl); - (void) sprintf(t, "%s -> ", hostname(res, v, s)); + sprintf(t, "%s -> ", hostname(f, s)); t += strlen(t); - (void) sprintf(t, "%s PR icmp len %hu %hu icmp %s", - hostname(res, v, d), hl, plen, + sprintf(t, "%s PR icmp len %hu %hu icmp %s", + hostname(f, d), hl, plen, icmpname(ic->icmp_type, ic->icmp_code)); if (ic->icmp_type == ICMP_UNREACH || ic->icmp_type == ICMP_SOURCEQUENCH || @@ -1218,21 +1313,21 @@ int blen; if (i > 1500) i = ipc->ip_len; ipoff = ntohs(ipc->ip_off); - proto = getproto(ipc->ip_p); + proto = getlocalproto(ipc->ip_p); if (!(ipoff & IP_OFFMASK) && ((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_V4(res, ipc->ip_src), - portname(res, proto, + sprintf(t, " for %s,%s -", + HOSTNAMEV4(ipc->ip_src), + portlocalname(res, proto, (u_int)tp->th_sport)); t += strlen(t); - (void) sprintf(t, " %s,%s PR %s len %hu %hu", - HOSTNAME_V4(res, ipc->ip_dst), - portname(res, proto, + sprintf(t, " %s,%s PR %s len %hu %hu", + HOSTNAMEV4(ipc->ip_dst), + portlocalname(res, proto, (u_int)tp->th_dport), proto, IP_HL(ipc) << 2, i); } else if (!(ipoff & IP_OFFMASK) && @@ -1240,26 +1335,25 @@ int blen; icmp = (icmphdr_t *)((char *)ipc + hl); t += strlen(t); - (void) sprintf(t, " for %s -", - HOSTNAME_V4(res, ipc->ip_src)); + sprintf(t, " for %s -", + HOSTNAMEV4(ipc->ip_src)); t += strlen(t); - (void) sprintf(t, + sprintf(t, " %s PR icmp len %hu %hu icmp %d/%d", - HOSTNAME_V4(res, ipc->ip_dst), + HOSTNAMEV4(ipc->ip_dst), IP_HL(ipc) << 2, i, icmp->icmp_type, icmp->icmp_code); } else { t += strlen(t); - (void) sprintf(t, " for %s -", - HOSTNAME_V4(res, ipc->ip_src)); + sprintf(t, " for %s -", + HOSTNAMEV4(ipc->ip_src)); t += strlen(t); - (void) sprintf(t, " %s PR %s len %hu (%hu)", - HOSTNAME_V4(res, ipc->ip_dst), proto, + sprintf(t, " %s PR %s len %hu (%hu)", + HOSTNAMEV4(ipc->ip_dst), proto, IP_HL(ipc) << 2, i); t += strlen(t); if (ipoff & IP_OFFMASK) { - (void) sprintf(t, - "(frag %d:%hu@%hu%s%s)", + sprintf(t, "(frag %d:%hu@%hu%s%s)", ntohs(ipc->ip_id), i - (IP_HL(ipc) << 2), (ipoff & IP_OFFMASK) << 3, @@ -1270,13 +1364,13 @@ int blen; } } else { - (void) sprintf(t, "%s -> ", hostname(res, v, s)); + sprintf(t, "%s -> ", hostname(f, s)); t += strlen(t); - (void) sprintf(t, "%s PR %s len %hu (%hu)", - hostname(res, v, d), proto, hl, plen); + sprintf(t, "%s PR %s len %hu (%hu)", + hostname(f, d), proto, hl, plen); t += strlen(t); if (off & IP_OFFMASK) - (void) sprintf(t, " (frag %d:%hu@%hu%s%s)", + sprintf(t, " (frag %d:%hu@%hu%s%s)", ntohs(ip->ip_id), plen - hl, (off & IP_OFFMASK) << 3, ipoff & IP_MF ? "+" : "", @@ -1347,32 +1441,43 @@ int blen; strcpy(t, " mbcast"); t += 7; } + if (ipf->fl_breason != 0) { + strcpy(t, " reason:"); + t += 8; + strcpy(t, reasons[ipf->fl_breason]); + t += strlen(reasons[ipf->fl_breason]); + } *t++ = '\n'; *t++ = '\0'; defaction = 0; - if (conf_file != NULL) - defaction = check_action(buf, line, opts, lvl); - if (defaction == 0) { - if (opts & OPT_SYSLOG) - syslog(lvl, "%s", line); - else if (log != NULL) - (void) fprintf(log, "%s", line); + if (conf->cfile != NULL) + defaction = check_action(buf, line, ipmonopts, lvl); - if (opts & OPT_HEXHDR) - dumphex(log, opts, buf, + if (defaction == 0) { + if (ipmonopts & IPMON_SYSLOG) { + syslog(lvl, "%s", line); + } else if (conf->log != NULL) { + (void) fprintf(conf->log, "%s", line); + } + + if (ipmonopts & IPMON_HEXHDR) { + dumphex(conf->log, ipmonopts, buf, sizeof(iplog_t) + sizeof(*ipf)); - if (opts & OPT_HEXBODY) - dumphex(log, opts, (char *)ip, + } + if (ipmonopts & IPMON_HEXBODY) { + dumphex(conf->log, ipmonopts, (char *)ip, ipf->fl_plen + ipf->fl_hlen); - else if ((opts & OPT_LOGBODY) && (ipf->fl_flags & FR_LOGBODY)) - dumphex(log, opts, (char *)ip + ipf->fl_hlen, + } else if ((ipmonopts & IPMON_LOGBODY) && + (ipf->fl_flags & FR_LOGBODY)) { + dumphex(conf->log, ipmonopts, (char *)ip + ipf->fl_hlen, ipf->fl_plen); + } } } static void usage(prog) -char *prog; + char *prog; { fprintf(stderr, "%s: [-NFhstvxX] [-f ]\n", prog); exit(1); @@ -1380,7 +1485,7 @@ char *prog; static void write_pid(file) -char *file; + char *file; { FILE *fp = NULL; int fd; @@ -1400,8 +1505,8 @@ char *file; static void flushlogs(file, log) -char *file; -FILE *log; + char *file; + FILE *log; { int fd, flushed = 0; @@ -1416,11 +1521,11 @@ FILE *log; flushed); fflush(stdout); } else - perror("SIOCIPFFB"); + ipferror(fd, "SIOCIPFFB"); (void) close(fd); if (flushed) { - if (opts & OPT_SYSLOG) { + if (ipmonopts & IPMON_SYSLOG) { syslog(LOG_INFO, "%d bytes flushed from log\n", flushed); } else if ((log != stdout) && (log != NULL)) { @@ -1431,8 +1536,8 @@ FILE *log; static void logopts(turnon, options) -int turnon; -char *options; + int turnon; + char *options; { int flags = 0; char *s; @@ -1442,13 +1547,13 @@ char *options; switch (*s) { case 'N' : - flags |= OPT_NAT; + flags |= IPMON_NAT; break; case 'S' : - flags |= OPT_STATE; + flags |= IPMON_STATE; break; case 'I' : - flags |= OPT_FILTER; + flags |= IPMON_FILTER; break; default : fprintf(stderr, "Unknown log option %c\n", *s); @@ -1457,64 +1562,87 @@ char *options; } if (turnon) - opts |= flags; + ipmonopts |= flags; else - opts &= ~(flags); + ipmonopts &= ~(flags); +} + +static void initconfig(config_t *conf) +{ + int i; + + memset(conf, 0, sizeof(*conf)); + + conf->log = stdout; + conf->maxfd = -1; + + for (i = 0; i < 3; i++) { + conf->logsrc[i].fd = -1; + conf->logsrc[i].logtype = -1; + conf->logsrc[i].regular = -1; + } + + conf->logsrc[0].file = IPL_NAME; + conf->logsrc[1].file = IPNAT_NAME; + conf->logsrc[2].file = IPSTATE_NAME; + + add_doing(&executesaver); + add_doing(&snmpv1saver); + add_doing(&snmpv2saver); + add_doing(&syslogsaver); + add_doing(&filesaver); + add_doing(¬hingsaver); } int main(argc, argv) -int argc; -char *argv[]; + int argc; + char *argv[]; { - struct stat sb; - FILE *log = stdout; - FILE *fp; - int fd[3], doread, n, i; - int tr, nr, regular[3], c; - int fdt[3], devices = 0, make_daemon = 0; - char buf[DEFAULT_IPFLOGSIZE], *iplfile[3], *s; - extern int optind; - extern char *optarg; + int doread, c, make_daemon = 0; + char *prog; + config_t config; - fd[0] = fd[1] = fd[2] = -1; - fdt[0] = fdt[1] = fdt[2] = -1; - iplfile[0] = IPL_NAME; - iplfile[1] = IPNAT_NAME; - iplfile[2] = IPSTATE_NAME; + prog = strrchr(argv[0], '/'); + if (prog == NULL) + prog = argv[0]; + else + prog++; + + initconfig(&config); while ((c = getopt(argc, argv, "?abB:C:Df:FhL:nN:o:O:pP:sS:tvxX")) != -1) switch (c) { case 'a' : - opts |= OPT_LOGALL; - fdt[0] = IPL_LOGIPF; - fdt[1] = IPL_LOGNAT; - fdt[2] = IPL_LOGSTATE; + ipmonopts |= IPMON_LOGALL; + config.logsrc[0].logtype = IPL_LOGIPF; + config.logsrc[1].logtype = IPL_LOGNAT; + config.logsrc[2].logtype = IPL_LOGSTATE; break; case 'b' : - opts |= OPT_LOGBODY; + ipmonopts |= IPMON_LOGBODY; break; case 'B' : - binarylogfile = optarg; - binarylog = fopen(optarg, "a"); + config.bfile = optarg; + config.blog = fopen(optarg, "a"); break; case 'C' : - conf_file = optarg; + config.cfile = optarg; break; case 'D' : make_daemon = 1; break; case 'f' : case 'I' : - opts |= OPT_FILTER; - fdt[0] = IPL_LOGIPF; - iplfile[0] = optarg; + ipmonopts |= IPMON_FILTER; + config.logsrc[0].logtype = IPL_LOGIPF; + config.logsrc[0].file = optarg; break; case 'F' : - flushlogs(iplfile[0], log); - flushlogs(iplfile[1], log); - flushlogs(iplfile[2], log); + flushlogs(config.logsrc[0].file, config.log); + flushlogs(config.logsrc[1].file, config.log); + flushlogs(config.logsrc[2].file, config.log); break; case 'L' : logfac = fac_findname(optarg); @@ -1526,56 +1654,49 @@ char *argv[]; } break; case 'n' : - opts |= OPT_RESOLVE; + ipmonopts |= IPMON_RESOLVE; + opts &= ~OPT_NORESOLVE; break; case 'N' : - opts |= OPT_NAT; - fdt[1] = IPL_LOGNAT; - iplfile[1] = optarg; + ipmonopts |= IPMON_NAT; + config.logsrc[1].logtype = IPL_LOGNAT; + config.logsrc[1].file = optarg; break; case 'o' : case 'O' : logopts(c == 'o', optarg); - fdt[0] = fdt[1] = fdt[2] = -1; - if (opts & OPT_FILTER) - fdt[0] = IPL_LOGIPF; - if (opts & OPT_NAT) - fdt[1] = IPL_LOGNAT; - if (opts & OPT_STATE) - fdt[2] = IPL_LOGSTATE; + if (ipmonopts & IPMON_FILTER) + config.logsrc[0].logtype = IPL_LOGIPF; + if (ipmonopts & IPMON_NAT) + config.logsrc[1].logtype = IPL_LOGNAT; + if (ipmonopts & IPMON_STATE) + config.logsrc[2].logtype = IPL_LOGSTATE; break; case 'p' : - opts |= OPT_PORTNUM; + ipmonopts |= IPMON_PORTNUM; break; case 'P' : pidfile = optarg; break; case 's' : - s = strrchr(argv[0], '/'); - if (s == NULL) - s = argv[0]; - else - s++; - openlog(s, LOG_NDELAY|LOG_PID, logfac); - s = NULL; - opts |= OPT_SYSLOG; - log = NULL; + ipmonopts |= IPMON_SYSLOG; + config.log = NULL; break; case 'S' : - opts |= OPT_STATE; - fdt[2] = IPL_LOGSTATE; - iplfile[2] = optarg; + ipmonopts |= IPMON_STATE; + config.logsrc[2].logtype = IPL_LOGSTATE; + config.logsrc[2].file = optarg; break; case 't' : - opts |= OPT_TAIL; + ipmonopts |= IPMON_TAIL; break; case 'v' : - opts |= OPT_VERBOSE; + ipmonopts |= IPMON_VERBOSE; break; case 'x' : - opts |= OPT_HEXBODY; + ipmonopts |= IPMON_HEXBODY; break; case 'X' : - opts |= OPT_HEXHDR; + ipmonopts |= IPMON_HEXHDR; break; default : case 'h' : @@ -1583,69 +1704,62 @@ char *argv[]; usage(argv[0]); } + if (ipmonopts & IPMON_SYSLOG) + openlog(prog, LOG_NDELAY|LOG_PID, logfac); + init_tabs(); - if (conf_file) - if (load_config(conf_file) == -1) + if (config.cfile) + if (load_config(config.cfile) == -1) { + unload_config(); exit(1); + } /* * Default action is to only open the filter log file. */ - if ((fdt[0] == -1) && (fdt[1] == -1) && (fdt[2] == -1)) - fdt[0] = IPL_LOGIPF; + if ((config.logsrc[0].logtype == -1) && + (config.logsrc[0].logtype == -1) && + (config.logsrc[0].logtype == -1)) + config.logsrc[0].logtype = IPL_LOGIPF; - for (i = 0; i < 3; i++) { - if (fdt[i] == -1) - continue; - if (!strcmp(iplfile[i], "-")) - fd[i] = 0; - else { - if ((fd[i] = open(iplfile[i], O_RDONLY)) == -1) { - (void) fprintf(stderr, - "%s: open: %s\n", iplfile[i], - STRERROR(errno)); - exit(1); - /* NOTREACHED */ - } - if (fstat(fd[i], &sb) == -1) { - (void) fprintf(stderr, "%d: fstat: %s\n", - fd[i], STRERROR(errno)); - exit(1); - /* NOTREACHED */ - } - if (!(regular[i] = !S_ISCHR(sb.st_mode))) - devices++; - } - } + openlogs(&config); - if (!(opts & OPT_SYSLOG)) { - logfile = argv[optind]; - log = logfile ? fopen(logfile, "a") : stdout; - if (log == NULL) { + if (!(ipmonopts & IPMON_SYSLOG)) { + config.file = argv[optind]; + config.log = config.file ? fopen(config.file, "a") : stdout; + if (config.log == NULL) { (void) fprintf(stderr, "%s: fopen: %s\n", argv[optind], STRERROR(errno)); exit(1); /* NOTREACHED */ } - setvbuf(log, NULL, _IONBF, 0); - } else - log = NULL; + setvbuf(config.log, NULL, _IONBF, 0); + } else { + config.log = NULL; + } - if (make_daemon && ((log != stdout) || (opts & OPT_SYSLOG))) { + if (make_daemon && + ((config.log != stdout) || (ipmonopts & IPMON_SYSLOG))) { #if BSD >= 199306 - daemon(0, !(opts & OPT_SYSLOG)); + daemon(0, !(ipmonopts & IPMON_SYSLOG)); #else int pid; - if ((pid = fork()) > 0) - exit(0); - if (pid < 0) { + + switch (fork()) + { + case -1 : (void) fprintf(stderr, "%s: fork() failed: %s\n", argv[0], STRERROR(errno)); exit(1); /* NOTREACHED */ + case 0 : + break; + default : + exit(0); } + setsid(); - if ((opts & OPT_SYSLOG)) + if ((ipmonopts & IPMON_SYSLOG)) close(2); #endif /* !BSD */ close(0); @@ -1655,80 +1769,142 @@ char *argv[]; signal(SIGHUP, handlehup); - for (doread = 1; doread; ) { - nr = 0; + for (doread = 1; doread; ) + doread = read_loginfo(&config); - for (i = 0; i < 3; i++) { - tr = 0; - if (fdt[i] == -1) - continue; - if (!regular[i]) { - if (ioctl(fd[i], FIONREAD, &tr) == -1) { - if (opts & OPT_SYSLOG) - syslog(LOG_CRIT, - "ioctl(FIONREAD): %m"); - else - perror("ioctl(FIONREAD)"); - exit(1); - /* NOTREACHED */ - } - } else { - tr = (lseek(fd[i], 0, SEEK_CUR) < sb.st_size); - if (!tr && !(opts & OPT_TAIL)) - doread = 0; - } - if (!tr) - continue; - nr += tr; - n = 0; + unload_config(); - tr = read_log(fd[i], &n, buf, sizeof(buf)); - if (donehup) { - if (logfile && (fp = fopen(logfile, "a"))) { - fclose(log); - log = fp; - } - if (binarylogfile && - (fp = fopen(binarylogfile, "a"))) { - fclose(binarylog); - binarylog = fp; - } - init_tabs(); - if (conf_file != NULL) - load_config(conf_file); - donehup = 0; - } - - switch (tr) - { - case -1 : - if (opts & OPT_SYSLOG) - syslog(LOG_CRIT, "read: %m\n"); - else - perror("read"); - doread = 0; - break; - case 1 : - if (opts & OPT_SYSLOG) - syslog(LOG_CRIT, "aborting logging\n"); - else if (log != NULL) - fprintf(log, "aborting logging\n"); - doread = 0; - break; - case 2 : - break; - case 0 : - if (n > 0) { - print_log(fdt[i], log, buf, n); - if (!(opts & OPT_SYSLOG)) - fflush(log); - } - break; - } - } - if (!nr && ((opts & OPT_TAIL) || devices)) - sleep(1); - } return(0); /* NOTREACHED */ } + + +static void openlogs(config_t *conf) +{ + logsource_t *l; + struct stat sb; + int i; + + for (i = 0; i < 3; i++) { + l = &conf->logsrc[i]; + if (l->logtype == -1) + continue; + if (!strcmp(l->file, "-")) + l->fd = 0; + else { + if ((l->fd= open(l->file, O_RDONLY)) == -1) { + (void) fprintf(stderr, + "%s: open: %s\n", l->file, + STRERROR(errno)); + exit(1); + /* NOTREACHED */ + } + + if (fstat(l->fd, &sb) == -1) { + (void) fprintf(stderr, "%d: fstat: %s\n", + l->fd, STRERROR(errno)); + exit(1); + /* NOTREACHED */ + } + + l->regular = !S_ISCHR(sb.st_mode); + if (l->regular) + l->size = sb.st_size; + + FD_SET(l->fd, &conf->fdmr); + if (l->fd > conf->maxfd) + conf->maxfd = l->fd; + } + } +} + + +static int read_loginfo(config_t *conf) +{ + iplog_t buf[DEFAULT_IPFLOGSIZE/sizeof(iplog_t)+1]; + int n, tr, nr, i; + logsource_t *l; + fd_set fdr; + + fdr = conf->fdmr; + + n = select(conf->maxfd + 1, &fdr, NULL, NULL, NULL); + if (n == 0) + return 1; + if (n == -1) { + if (errno == EINTR) + return 1; + return -1; + } + + for (i = 0, nr = 0; i < 3; i++) { + l = &conf->logsrc[i]; + + if ((l->logtype == -1) || !FD_ISSET(l->fd, &fdr)) + continue; + + tr = 0; + if (l->regular) { + tr = (lseek(l->fd, 0, SEEK_CUR) < l->size); + if (!tr && !(ipmonopts & IPMON_TAIL)) + return 0; + } + + n = 0; + tr = read_log(l->fd, &n, (char *)buf, sizeof(buf)); + if (donehup) { + if (conf->file != NULL) { + if (conf->log != NULL) { + fclose(conf->log); + conf->log = NULL; + } + conf->log = fopen(conf->file, "a"); + } + + if (conf->bfile != NULL) { + if (conf->blog != NULL) { + fclose(conf->blog); + conf->blog = NULL; + } + conf->blog = fopen(conf->bfile, "a"); + } + + init_tabs(); + if (conf->cfile != NULL) + load_config(conf->cfile); + donehup = 0; + } + + switch (tr) + { + case -1 : + if (ipmonopts & IPMON_SYSLOG) + syslog(LOG_CRIT, "read: %m\n"); + else { + ipferror(l->fd, "read"); + } + return 0; + case 1 : + if (ipmonopts & IPMON_SYSLOG) + syslog(LOG_CRIT, "aborting logging\n"); + else if (conf->log != NULL) + fprintf(conf->log, "aborting logging\n"); + return 0; + case 2 : + break; + case 0 : + nr += tr; + if (n > 0) { + print_log(conf, l, (char *)buf, n); + if (!(ipmonopts & IPMON_SYSLOG)) + fflush(conf->log); + } + break; + } + } + + if (!nr && (ipmonopts & IPMON_TAIL)) + sleep(1); + + return 1; +} diff --git a/contrib/ipfilter/tools/ipmon_y.y b/contrib/ipfilter/tools/ipmon_y.y index 98042d880222..f14180d6a9e9 100644 --- a/contrib/ipfilter/tools/ipmon_y.y +++ b/contrib/ipfilter/tools/ipmon_y.y @@ -1,7 +1,7 @@ /* $FreeBSD$ */ /* - * Copyright (C) 2001-2004 by Darren Reed. + * Copyright (C) 2012 by Darren Reed. * * See the IPFILTER.LICENCE file for details on licencing. */ @@ -13,6 +13,8 @@ #include "ipmon_l.h" #include "ipmon.h" +#include + #define YYDEBUG 1 extern void yyerror __P((char *)); @@ -21,69 +23,88 @@ extern int yylex __P((void)); extern int yydebug; extern FILE *yyin; extern int yylineNum; +extern int ipmonopts; -typedef struct opt { - struct opt *o_next; +typedef struct opt_s { + struct opt_s *o_next; int o_line; int o_type; int o_num; char *o_str; struct in_addr o_ip; + int o_logfac; + int o_logpri; } opt_t; -static void build_action __P((struct opt *)); +static void build_action __P((opt_t *, ipmon_doing_t *)); static opt_t *new_opt __P((int)); static void free_action __P((ipmon_action_t *)); +static void print_action __P((ipmon_action_t *)); +static int find_doing __P((char *)); +static ipmon_doing_t *build_doing __P((char *, char *)); +static void print_match __P((ipmon_action_t *)); +static int install_saver __P((char *, char *)); static ipmon_action_t *alist = NULL; + +ipmon_saver_int_t *saverlist = NULL; %} %union { char *str; u_32_t num; struct in_addr addr; - struct opt *opt; + struct opt_s *opt; union i6addr ip6; + struct ipmon_doing_s *ipmd; } %token YY_NUMBER YY_HEX %token YY_STR %token YY_IPV6 -%token YY_COMMENT +%token YY_COMMENT %token YY_CMP_EQ YY_CMP_NE YY_CMP_LE YY_CMP_GE YY_CMP_LT YY_CMP_GT %token YY_RANGE_OUT YY_RANGE_IN %token IPM_MATCH IPM_BODY IPM_COMMENT IPM_DIRECTION IPM_DSTIP IPM_DSTPORT -%token IPM_EVERY IPM_EXECUTE IPM_GROUP IPM_INTERFACE IPM_IN IPM_NO IPM_OUT +%token IPM_EVERY IPM_GROUP IPM_INTERFACE IPM_IN IPM_NO IPM_OUT IPM_LOADACTION %token IPM_PACKET IPM_PACKETS IPM_POOL IPM_PROTOCOL IPM_RESULT IPM_RULE %token IPM_SECOND IPM_SECONDS IPM_SRCIP IPM_SRCPORT IPM_LOGTAG IPM_WITH -%token IPM_DO IPM_SAVE IPM_SYSLOG IPM_NOTHING IPM_RAW IPM_TYPE IPM_NAT +%token IPM_DO IPM_DOING IPM_TYPE IPM_NAT %token IPM_STATE IPM_NATTAG IPM_IPF %type ipv4 -%type direction dstip dstport every execute group interface +%type direction dstip dstport every group interface %type protocol result rule srcip srcport logtag matching -%type matchopt nattag type doopt doing save syslog nothing -%type saveopts saveopt typeopt +%type matchopt nattag type +%type typeopt +%type doopt doing %% -file: line - | assign - | file line - | file assign +file: action + | file action ; -line: IPM_MATCH '{' matching '}' IPM_DO '{' doing '}' ';' - { build_action($3); resetlexer(); } +action: line ';' + | assign ';' | IPM_COMMENT | YY_COMMENT ; -assign: YY_STR assigning YY_STR ';' { set_variable($1, $3); +line: IPM_MATCH '{' matching ';' '}' IPM_DO '{' doing ';' '}' + { build_action($3, $8); + resetlexer(); + } + | IPM_LOADACTION YY_STR YY_STR { if (install_saver($2, $3)) + yyerror("install saver"); + } + ; + +assign: YY_STR assigning YY_STR { set_variable($1, $3); resetlexer(); free($1); free($3); yyvarnext = 0; - } + } ; assigning: @@ -114,14 +135,20 @@ matchopt: doing: doopt { $$ = $1; } - | doopt ',' doing { $1->o_next = $3; $$ = $1; } + | doopt ',' doing { $1->ipmd_next = $3; $$ = $1; } ; doopt: - execute { $$ = $1; } - | save { $$ = $1; } - | syslog { $$ = $1; } - | nothing { $$ = $1; } + YY_STR { if (find_doing($1) != IPM_DOING) + yyerror("unknown action"); + } + '(' YY_STR ')' { $$ = build_doing($1, $4); + if ($$ == NULL) + yyerror("action building"); + } + | YY_STR { if (find_doing($1) == IPM_DOING) + $$ = build_doing($1, NULL); + } ; direction: @@ -211,31 +238,7 @@ typeopt: | IPM_STATE { $$ = IPL_MAGIC_STATE; } ; -execute: - IPM_EXECUTE YY_STR { $$ = new_opt(IPM_EXECUTE); - $$->o_str = $2; } - ; -save: IPM_SAVE saveopts YY_STR { $$ = new_opt(IPM_SAVE); - $$->o_num = $2; - $$->o_str = $3; } - ; - -saveopts: { $$ = 0; } - | saveopt { $$ = $1; } - | saveopt ',' saveopts { $$ = $1 | $3; } - ; - -saveopt: - IPM_RAW { $$ = IPMDO_SAVERAW; } - ; - -syslog: IPM_SYSLOG { $$ = new_opt(IPM_SYSLOG); } - ; - -nothing: - IPM_NOTHING { $$ = 0; } - ; ipv4: YY_NUMBER '.' YY_NUMBER '.' YY_NUMBER '.' YY_NUMBER { if ($1 > 255 || $3 > 255 || $5 > 255 || $7 > 255) { @@ -253,30 +256,27 @@ static struct wordtab yywords[] = { { "dstip", IPM_DSTIP }, { "dstport", IPM_DSTPORT }, { "every", IPM_EVERY }, - { "execute", IPM_EXECUTE }, { "group", IPM_GROUP }, { "in", IPM_IN }, { "interface", IPM_INTERFACE }, { "ipf", IPM_IPF }, + { "load_action",IPM_LOADACTION }, { "logtag", IPM_LOGTAG }, { "match", IPM_MATCH }, { "nat", IPM_NAT }, { "nattag", IPM_NATTAG }, { "no", IPM_NO }, - { "nothing", IPM_NOTHING }, { "out", IPM_OUT }, { "packet", IPM_PACKET }, { "packets", IPM_PACKETS }, { "protocol", IPM_PROTOCOL }, { "result", IPM_RESULT }, { "rule", IPM_RULE }, - { "save", IPM_SAVE }, { "second", IPM_SECOND }, { "seconds", IPM_SECONDS }, { "srcip", IPM_SRCIP }, { "srcport", IPM_SRCPORT }, { "state", IPM_STATE }, - { "syslog", IPM_SYSLOG }, { "with", IPM_WITH }, { NULL, 0 } }; @@ -301,31 +301,33 @@ static int macflags[17][2] = { { 0, 0 } }; -static opt_t *new_opt(type) -int type; +static opt_t * +new_opt(type) + int type; { opt_t *o; - o = (opt_t *)malloc(sizeof(*o)); + o = (opt_t *)calloc(1, sizeof(*o)); o->o_type = type; o->o_line = yylineNum; - o->o_num = 0; - o->o_str = (char *)0; - o->o_next = NULL; + o->o_logfac = -1; + o->o_logpri = -1; return o; } -static void build_action(olist) -opt_t *olist; +static void +build_action(olist, todo) + opt_t *olist; + ipmon_doing_t *todo; { ipmon_action_t *a; opt_t *o; - char c; int i; a = (ipmon_action_t *)calloc(1, sizeof(*a)); if (a == NULL) return; + while ((o = olist) != NULL) { /* * Check to see if the same comparator is being used more than @@ -358,24 +360,11 @@ opt_t *olist; case IPM_DSTPORT : a->ac_dport = htons(o->o_num); break; - case IPM_EXECUTE : - a->ac_exec = o->o_str; - c = *o->o_str; - if (c== '"'|| c == '\'') { - if (o->o_str[strlen(o->o_str) - 1] == c) { - a->ac_run = strdup(o->o_str + 1); - a->ac_run[strlen(a->ac_run) - 1] ='\0'; - } else - a->ac_run = o->o_str; - } else - a->ac_run = o->o_str; - o->o_str = NULL; - break; case IPM_INTERFACE : a->ac_iface = o->o_str; o->o_str = NULL; break; - case IPM_GROUP : + case IPM_GROUP : if (o->o_str != NULL) strncpy(a->ac_group, o->o_str, FR_GROUPLEN); else @@ -416,24 +405,6 @@ opt_t *olist; case IPM_SRCPORT : a->ac_sport = htons(o->o_num); break; - case IPM_SAVE : - if (a->ac_savefile != NULL) { - fprintf(stderr, "%s redfined on line %d\n", - yykeytostr(o->o_type), yylineNum); - break; - } - a->ac_savefile = strdup(o->o_str); - a->ac_savefp = fopen(o->o_str, "a"); - a->ac_dflag |= o->o_num & IPMDO_SAVERAW; - break; - case IPM_SYSLOG : - if (a->ac_syslog != 0) { - fprintf(stderr, "%s redfined on line %d\n", - yykeytostr(o->o_type), yylineNum); - break; - } - a->ac_syslog = 1; - break; case IPM_TYPE : a->ac_type = o->o_num; break; @@ -448,17 +419,25 @@ opt_t *olist; free(o->o_str); free(o); } + + a->ac_doing = todo; a->ac_next = alist; alist = a; + + if (ipmonopts & IPMON_VERBOSE) + print_action(a); } -int check_action(buf, log, opts, lvl) -char *buf, *log; -int opts, lvl; +int +check_action(buf, log, opts, lvl) + char *buf, *log; + int opts, lvl; { ipmon_action_t *a; struct timeval tv; + ipmon_doing_t *d; + ipmon_msg_t msg; ipflog_t *ipf; tcphdr_t *tcp; iplog_t *ipl; @@ -472,19 +451,33 @@ int opts, lvl; ip = (ip_t *)(ipf + 1); tcp = (tcphdr_t *)((char *)ip + (IP_HL(ip) << 2)); + msg.imm_data = ipl; + msg.imm_dsize = ipl->ipl_dsize; + msg.imm_when = ipl->ipl_time.tv_sec; + msg.imm_msg = log; + msg.imm_msglen = strlen(log); + msg.imm_loglevel = lvl; + for (a = alist; a != NULL; a = a->ac_next) { + verbose(0, "== checking config rule\n"); if ((a->ac_mflag & IPMAC_DIRECTION) != 0) { if (a->ac_direction == IPM_IN) { - if ((ipf->fl_flags & FR_INQUE) == 0) + if ((ipf->fl_flags & FR_INQUE) == 0) { + verbose(8, "-- direction not in\n"); continue; + } } else if (a->ac_direction == IPM_OUT) { - if ((ipf->fl_flags & FR_OUTQUE) == 0) + if ((ipf->fl_flags & FR_OUTQUE) == 0) { + verbose(8, "-- direction not out\n"); continue; + } } } - if ((a->ac_type != 0) && (a->ac_type != ipl->ipl_magic)) + if ((a->ac_type != 0) && (a->ac_type != ipl->ipl_magic)) { + verbose(8, "-- type mismatch\n"); continue; + } if ((a->ac_mflag & IPMAC_EVERY) != 0) { gettimeofday(&tv, NULL); @@ -492,8 +485,10 @@ int opts, lvl; if (tv.tv_usec <= a->ac_lastusec) t1--; if (a->ac_second != 0) { - if (t1 < a->ac_second) + if (t1 < a->ac_second) { + verbose(8, "-- too soon\n"); continue; + } a->ac_lastsec = tv.tv_sec; a->ac_lastusec = tv.tv_usec; } @@ -503,159 +498,149 @@ int opts, lvl; a->ac_pktcnt++; else if (a->ac_pktcnt == a->ac_packet) { a->ac_pktcnt = 0; + verbose(8, "-- packet count\n"); continue; } else { a->ac_pktcnt++; + verbose(8, "-- packet count\n"); continue; } } } if ((a->ac_mflag & IPMAC_DSTIP) != 0) { - if ((ip->ip_dst.s_addr & a->ac_dmsk) != a->ac_dip) + if ((ip->ip_dst.s_addr & a->ac_dmsk) != a->ac_dip) { + verbose(8, "-- dstip wrong\n"); continue; + } } if ((a->ac_mflag & IPMAC_DSTPORT) != 0) { - if (ip->ip_p != IPPROTO_UDP && ip->ip_p != IPPROTO_TCP) + if (ip->ip_p != IPPROTO_UDP && + ip->ip_p != IPPROTO_TCP) { + verbose(8, "-- not port protocol\n"); continue; - if (tcp->th_dport != a->ac_dport) + } + if (tcp->th_dport != a->ac_dport) { + verbose(8, "-- dport mismatch\n"); continue; + } } if ((a->ac_mflag & IPMAC_GROUP) != 0) { if (strncmp(a->ac_group, ipf->fl_group, - FR_GROUPLEN) != 0) + FR_GROUPLEN) != 0) { + verbose(8, "-- group mismatch\n"); continue; + } } if ((a->ac_mflag & IPMAC_INTERFACE) != 0) { - if (strcmp(a->ac_iface, ipf->fl_ifname)) + if (strcmp(a->ac_iface, ipf->fl_ifname)) { + verbose(8, "-- ifname mismatch\n"); continue; + } } if ((a->ac_mflag & IPMAC_PROTOCOL) != 0) { - if (a->ac_proto != ip->ip_p) + if (a->ac_proto != ip->ip_p) { + verbose(8, "-- protocol mismatch\n"); continue; + } } if ((a->ac_mflag & IPMAC_RESULT) != 0) { if ((ipf->fl_flags & FF_LOGNOMATCH) != 0) { - if (a->ac_result != IPMR_NOMATCH) + if (a->ac_result != IPMR_NOMATCH) { + verbose(8, "-- ff-flags mismatch\n"); continue; + } } else if (FR_ISPASS(ipf->fl_flags)) { - if (a->ac_result != IPMR_PASS) + if (a->ac_result != IPMR_PASS) { + verbose(8, "-- pass mismatch\n"); continue; + } } else if (FR_ISBLOCK(ipf->fl_flags)) { - if (a->ac_result != IPMR_BLOCK) + if (a->ac_result != IPMR_BLOCK) { + verbose(8, "-- block mismatch\n"); continue; + } } else { /* Log only */ - if (a->ac_result != IPMR_LOG) + if (a->ac_result != IPMR_LOG) { + verbose(8, "-- log mismatch\n"); continue; + } } } if ((a->ac_mflag & IPMAC_RULE) != 0) { - if (a->ac_rule != ipf->fl_rule) + if (a->ac_rule != ipf->fl_rule) { + verbose(8, "-- rule mismatch\n"); continue; + } } if ((a->ac_mflag & IPMAC_SRCIP) != 0) { - if ((ip->ip_src.s_addr & a->ac_smsk) != a->ac_sip) + if ((ip->ip_src.s_addr & a->ac_smsk) != a->ac_sip) { + verbose(8, "-- srcip mismatch\n"); continue; + } } if ((a->ac_mflag & IPMAC_SRCPORT) != 0) { - if (ip->ip_p != IPPROTO_UDP && ip->ip_p != IPPROTO_TCP) + if (ip->ip_p != IPPROTO_UDP && + ip->ip_p != IPPROTO_TCP) { + verbose(8, "-- port protocol mismatch\n"); continue; - if (tcp->th_sport != a->ac_sport) + } + if (tcp->th_sport != a->ac_sport) { + verbose(8, "-- sport mismatch\n"); continue; + } } if ((a->ac_mflag & IPMAC_LOGTAG) != 0) { - if (a->ac_logtag != ipf->fl_logtag) + if (a->ac_logtag != ipf->fl_logtag) { + verbose(8, "-- logtag %d != %d\n", + a->ac_logtag, ipf->fl_logtag); continue; + } } if ((a->ac_mflag & IPMAC_NATTAG) != 0) { if (strncmp(a->ac_nattag, ipf->fl_nattag.ipt_tag, - IPFTAG_LEN) != 0) + IPFTAG_LEN) != 0) { + verbose(8, "-- nattag mismatch\n"); continue; + } } matched = 1; + verbose(8, "++ matched\n"); /* - * It matched so now execute the command + * It matched so now perform the saves */ - if (a->ac_syslog != 0) { - syslog(lvl, "%s", log); - } - - if (a->ac_savefp != NULL) { - if (a->ac_dflag & IPMDO_SAVERAW) - fwrite(ipl, 1, ipl->ipl_dsize, a->ac_savefp); - else - fputs(log, a->ac_savefp); - } - - if (a->ac_exec != NULL) { - switch (fork()) - { - case 0 : - { - FILE *pi; - - pi = popen(a->ac_run, "w"); - if (pi != NULL) { - fprintf(pi, "%s\n", log); - if ((opts & OPT_HEXHDR) != 0) { - dumphex(pi, 0, buf, - sizeof(*ipl) + - sizeof(*ipf)); - } - if ((opts & OPT_HEXBODY) != 0) { - dumphex(pi, 0, (char *)ip, - ipf->fl_hlen + - ipf->fl_plen); - } - pclose(pi); - } - exit(1); - } - case -1 : - break; - default : - break; - } - } + for (d = a->ac_doing; d != NULL; d = d->ipmd_next) + (*d->ipmd_store)(d->ipmd_token, &msg); } return matched; } -static void free_action(a) -ipmon_action_t *a; +static void +free_action(a) + ipmon_action_t *a; { - if (a->ac_savefile != NULL) { - free(a->ac_savefile); - a->ac_savefile = NULL; - } - if (a->ac_savefp != NULL) { - fclose(a->ac_savefp); - a->ac_savefp = NULL; - } - if (a->ac_exec != NULL) { - free(a->ac_exec); - if (a->ac_run == a->ac_exec) - a->ac_run = NULL; - a->ac_exec = NULL; - } - if (a->ac_run != NULL) { - free(a->ac_run); - a->ac_run = NULL; + ipmon_doing_t *d; + + while ((d = a->ac_doing) != NULL) { + a->ac_doing = d->ipmd_next; + (*d->ipmd_saver->ims_destroy)(d->ipmd_token); + free(d); } + if (a->ac_iface != NULL) { free(a->ac_iface); a->ac_iface = NULL; @@ -665,24 +650,21 @@ ipmon_action_t *a; } -int load_config(file) -char *file; +int +load_config(file) + char *file; { - ipmon_action_t *a; FILE *fp; char *s; + unload_config(); + s = getenv("YYDEBUG"); if (s != NULL) yydebug = atoi(s); else yydebug = 0; - while ((a = alist) != NULL) { - alist = a->ac_next; - free_action(a); - } - yylineNum = 1; (void) yysettab(yywords); @@ -698,3 +680,373 @@ char *file; fclose(fp); return 0; } + + +void +unload_config() +{ + ipmon_saver_int_t *sav, **imsip; + ipmon_saver_t *is; + ipmon_action_t *a; + + while ((a = alist) != NULL) { + alist = a->ac_next; + free_action(a); + } + + /* + * Look for savers that have been added in dynamically from the + * configuration file. + */ + for (imsip = &saverlist; (sav = *imsip) != NULL; ) { + if (sav->imsi_handle == NULL) + imsip = &sav->imsi_next; + else { + dlclose(sav->imsi_handle); + + *imsip = sav->imsi_next; + is = sav->imsi_stor; + free(sav); + + free(is->ims_name); + free(is); + } + } +} + + +void +dump_config() +{ + ipmon_action_t *a; + + for (a = alist; a != NULL; a = a->ac_next) { + print_action(a); + + printf("#\n"); + } +} + + +static void +print_action(a) + ipmon_action_t *a; +{ + ipmon_doing_t *d; + + printf("match { "); + print_match(a); + printf("; }\n"); + printf("do {"); + for (d = a->ac_doing; d != NULL; d = d->ipmd_next) { + printf("%s", d->ipmd_saver->ims_name); + if (d->ipmd_saver->ims_print != NULL) { + printf("(\""); + (*d->ipmd_saver->ims_print)(d->ipmd_token); + printf("\")"); + } + printf(";"); + } + printf("};\n"); +} + + +void * +add_doing(saver) + ipmon_saver_t *saver; +{ + ipmon_saver_int_t *it; + + if (find_doing(saver->ims_name) == IPM_DOING) + return NULL; + + it = calloc(1, sizeof(*it)); + if (it == NULL) + return NULL; + it->imsi_stor = saver; + it->imsi_next = saverlist; + saverlist = it; + return it; +} + + +static int +find_doing(string) + char *string; +{ + ipmon_saver_int_t *it; + + for (it = saverlist; it != NULL; it = it->imsi_next) { + if (!strcmp(it->imsi_stor->ims_name, string)) + return IPM_DOING; + } + return 0; +} + + +static ipmon_doing_t * +build_doing(target, options) + char *target; + char *options; +{ + ipmon_saver_int_t *it; + char *strarray[2]; + ipmon_doing_t *d, *d1; + ipmon_action_t *a; + ipmon_saver_t *save; + + d = calloc(1, sizeof(*d)); + if (d == NULL) + return NULL; + + for (it = saverlist; it != NULL; it = it->imsi_next) { + if (!strcmp(it->imsi_stor->ims_name, target)) + break; + } + if (it == NULL) { + free(d); + return NULL; + } + + strarray[0] = options; + strarray[1] = NULL; + + d->ipmd_token = (*it->imsi_stor->ims_parse)(strarray); + if (d->ipmd_token == NULL) { + free(d); + return NULL; + } + + save = it->imsi_stor; + d->ipmd_saver = save; + d->ipmd_store = it->imsi_stor->ims_store; + + /* + * Look for duplicate do-things that need to be dup'd + */ + for (a = alist; a != NULL; a = a->ac_next) { + for (d1 = a->ac_doing; d1 != NULL; d1 = d1->ipmd_next) { + if (save != d1->ipmd_saver) + continue; + if (save->ims_match == NULL || save->ims_dup == NULL) + continue; + if ((*save->ims_match)(d->ipmd_token, d1->ipmd_token)) + continue; + + (*d->ipmd_saver->ims_destroy)(d->ipmd_token); + d->ipmd_token = (*save->ims_dup)(d1->ipmd_token); + break; + } + } + + return d; +} + + +static void +print_match(a) + ipmon_action_t *a; +{ + char *coma = ""; + + if ((a->ac_mflag & IPMAC_DIRECTION) != 0) { + printf("direction = "); + if (a->ac_direction == IPM_IN) + printf("in"); + else if (a->ac_direction == IPM_OUT) + printf("out"); + coma = ", "; + } + + if ((a->ac_mflag & IPMAC_DSTIP) != 0) { + printf("%sdstip = ", coma); + printhostmask(AF_INET, &a->ac_dip, &a->ac_dmsk); + coma = ", "; + } + + if ((a->ac_mflag & IPMAC_DSTPORT) != 0) { + printf("%sdstport = %hu", coma, ntohs(a->ac_dport)); + coma = ", "; + } + + if ((a->ac_mflag & IPMAC_GROUP) != 0) { + char group[FR_GROUPLEN+1]; + + strncpy(group, a->ac_group, FR_GROUPLEN); + group[FR_GROUPLEN] = '\0'; + printf("%sgroup = %s", coma, group); + coma = ", "; + } + + if ((a->ac_mflag & IPMAC_INTERFACE) != 0) { + printf("%siface = %s", coma, a->ac_iface); + coma = ", "; + } + + if ((a->ac_mflag & IPMAC_LOGTAG) != 0) { + printf("%slogtag = %u", coma, a->ac_logtag); + coma = ", "; + } + + if ((a->ac_mflag & IPMAC_NATTAG) != 0) { + char tag[17]; + + strncpy(tag, a->ac_nattag, 16); + tag[16] = '\0'; + printf("%snattag = %s", coma, tag); + coma = ", "; + } + + if ((a->ac_mflag & IPMAC_PROTOCOL) != 0) { + printf("%sprotocol = %u", coma, a->ac_proto); + coma = ", "; + } + + if ((a->ac_mflag & IPMAC_RESULT) != 0) { + printf("%sresult = ", coma); + switch (a->ac_result) + { + case IPMR_LOG : + printf("log"); + break; + case IPMR_PASS : + printf("pass"); + break; + case IPMR_BLOCK : + printf("block"); + break; + case IPMR_NOMATCH : + printf("nomatch"); + break; + } + coma = ", "; + } + + if ((a->ac_mflag & IPMAC_RULE) != 0) { + printf("%srule = %u", coma, a->ac_rule); + coma = ", "; + } + + if ((a->ac_mflag & IPMAC_EVERY) != 0) { + if (a->ac_packet > 1) { + printf("%severy %d packets", coma, a->ac_packet); + coma = ", "; + } else if (a->ac_packet == 1) { + printf("%severy packet", coma); + coma = ", "; + } + if (a->ac_second > 1) { + printf("%severy %d seconds", coma, a->ac_second); + coma = ", "; + } else if (a->ac_second == 1) { + printf("%severy second", coma); + coma = ", "; + } + } + + if ((a->ac_mflag & IPMAC_SRCIP) != 0) { + printf("%ssrcip = ", coma); + printhostmask(AF_INET, &a->ac_sip, &a->ac_smsk); + coma = ", "; + } + + if ((a->ac_mflag & IPMAC_SRCPORT) != 0) { + printf("%ssrcport = %hu", coma, ntohs(a->ac_sport)); + coma = ", "; + } + + if ((a->ac_mflag & IPMAC_TYPE) != 0) { + printf("%stype = ", coma); + switch (a->ac_type) + { + case IPL_LOGIPF : + printf("ipf"); + break; + case IPL_LOGSTATE : + printf("state"); + break; + case IPL_LOGNAT : + printf("nat"); + break; + } + coma = ", "; + } + + if ((a->ac_mflag & IPMAC_WITH) != 0) { + printf("%swith ", coma); + coma = ", "; + } +} + + +static int +install_saver(name, path) + char *name, *path; +{ + ipmon_saver_int_t *isi; + ipmon_saver_t *is; + char nbuf[80]; + + if (find_doing(name) == IPM_DOING) + return -1; + + isi = calloc(1, sizeof(*isi)); + if (isi == NULL) + return -1; + + is = calloc(1, sizeof(*is)); + if (is == NULL) + goto loaderror; + + is->ims_name = name; + +#ifdef RTLD_LAZY + isi->imsi_handle = dlopen(path, RTLD_LAZY); +#endif +#ifdef DL_LAZY + isi->imsi_handle = dlopen(path, DL_LAZY); +#endif + + if (isi->imsi_handle == NULL) + goto loaderror; + + snprintf(nbuf, sizeof(nbuf), "%sdup", name); + is->ims_dup = (ims_dup_func_t)dlsym(isi->imsi_handle, nbuf); + + snprintf(nbuf, sizeof(nbuf), "%sdestroy", name); + is->ims_destroy = (ims_destroy_func_t)dlsym(isi->imsi_handle, nbuf); + if (is->ims_destroy == NULL) + goto loaderror; + + snprintf(nbuf, sizeof(nbuf), "%smatch", name); + is->ims_match = (ims_match_func_t)dlsym(isi->imsi_handle, nbuf); + + snprintf(nbuf, sizeof(nbuf), "%sparse", name); + is->ims_parse = (ims_parse_func_t)dlsym(isi->imsi_handle, nbuf); + if (is->ims_parse == NULL) + goto loaderror; + + snprintf(nbuf, sizeof(nbuf), "%sprint", name); + is->ims_print = (ims_print_func_t)dlsym(isi->imsi_handle, nbuf); + if (is->ims_print == NULL) + goto loaderror; + + snprintf(nbuf, sizeof(nbuf), "%sstore", name); + is->ims_store = (ims_store_func_t)dlsym(isi->imsi_handle, nbuf); + if (is->ims_store == NULL) + goto loaderror; + + isi->imsi_stor = is; + isi->imsi_next = saverlist; + saverlist = isi; + + return 0; + +loaderror: + if (isi->imsi_handle != NULL) + dlclose(isi->imsi_handle); + free(isi); + if (is != NULL) + free(is); + return -1; +} diff --git a/contrib/ipfilter/tools/ipnat.c b/contrib/ipfilter/tools/ipnat.c index 28e29ec74199..448c1c0d2d2a 100644 --- a/contrib/ipfilter/tools/ipnat.c +++ b/contrib/ipfilter/tools/ipnat.c @@ -1,7 +1,7 @@ /* $FreeBSD$ */ /* - * Copyright (C) 2001-2006 by Darren Reed. + * Copyright (C) 2012 by Darren Reed. * * See the IPFILTER.LICENCE file for details on licencing. * @@ -67,7 +67,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[] = "@(#)$Id: ipnat.c,v 1.24.2.11 2007/09/25 08:27:34 darrenr Exp $"; +static const char rcsid[] = "@(#)$Id$"; #endif @@ -79,23 +79,25 @@ char thishost[MAXHOSTNAMELEN]; extern char *optarg; -void dostats __P((int, natstat_t *, int, int)); -void dotable __P((natstat_t *, int, int)); -void flushtable __P((int, int)); +void dostats __P((int, natstat_t *, int, int, int *)); +void dotable __P((natstat_t *, int, int, int, char *)); +void flushtable __P((int, int, int *)); void usage __P((char *)); int main __P((int, char*[])); void showhostmap __P((natstat_t *nsp)); void natstat_dead __P((natstat_t *, char *)); -void dostats_live __P((int, natstat_t *, int)); +void dostats_live __P((int, natstat_t *, int, int *)); void showhostmap_dead __P((natstat_t *)); void showhostmap_live __P((int, natstat_t *)); -void dostats_dead __P((natstat_t *, int)); -void showtqtable_live __P((int)); +void dostats_dead __P((natstat_t *, int, int *)); +int nat_matcharray __P((nat_t *, int *)); -int opts; +int opts; +int nohdrfields = 0; +wordtab_t *nat_fields = NULL; void usage(name) -char *name; + char *name; { fprintf(stderr, "Usage: %s [-CFhlnrRsv] [-f filename]\n", name); exit(1); @@ -103,12 +105,12 @@ char *name; int main(argc, argv) -int argc; -char *argv[]; + int argc; + char *argv[]; { + int fd, c, mode, *natfilter; char *file, *core, *kernel; natstat_t ns, *nsp; - int fd, c, mode; ipfobj_t obj; fd = -1; @@ -118,8 +120,11 @@ char *argv[]; core = NULL; kernel = NULL; mode = O_RDWR; + natfilter = NULL; - while ((c = getopt(argc, argv, "CdFf:hlM:N:nrRsv")) != -1) + assigndefined(getenv("IPNAT_PREDEFINED")); + + while ((c = getopt(argc, argv, "CdFf:hlm:M:N:nO:prRsv")) != -1) switch (c) { case 'C' : @@ -141,6 +146,9 @@ char *argv[]; opts |= OPT_LIST; mode = O_RDONLY; break; + case 'm' : + natfilter = parseipfexpr(optarg, NULL); + break; case 'M' : core = optarg; break; @@ -148,9 +156,15 @@ char *argv[]; kernel = optarg; break; case 'n' : - opts |= OPT_DONOTHING; + opts |= OPT_DONOTHING|OPT_DONTOPEN; mode = O_RDONLY; break; + case 'O' : + nat_fields = parsefields(natfields, optarg); + break; + case 'p' : + opts |= OPT_PURGE; + break; case 'R' : opts |= OPT_NORESOLVE; break; @@ -168,6 +182,12 @@ char *argv[]; usage(argv[0]); } + if (((opts & OPT_PURGE) != 0) && ((opts & OPT_REMOVE) == 0)) { + (void) fprintf(stderr, "%s: -p must be used with -r\n", + argv[0]); + exit(1); + } + initparse(); if ((kernel != NULL) || (core != NULL)) { @@ -200,7 +220,7 @@ char *argv[]; obj.ipfo_size = sizeof(*nsp); obj.ipfo_ptr = (void *)nsp; if (ioctl(fd, SIOCGNATS, &obj) == -1) { - perror("ioctl(SIOCGNATS)"); + ipferror(fd, "ioctl(SIOCGNATS)"); exit(1); } (void) setgid(getgid()); @@ -211,17 +231,17 @@ char *argv[]; natstat_dead(nsp, kernel); if (opts & (OPT_LIST|OPT_STAT)) - dostats(fd, nsp, opts, 0); + dostats(fd, nsp, opts, 0, natfilter); exit(0); } if (opts & (OPT_FLUSH|OPT_CLEAR)) - flushtable(fd, opts); + flushtable(fd, opts, natfilter); if (file) { - ipnat_parsefile(fd, ipnat_addrule, ioctl, file); + return ipnat_parsefile(fd, ipnat_addrule, ioctl, file); } if (opts & (OPT_LIST|OPT_STAT)) - dostats(fd, nsp, opts, 1); + dostats(fd, nsp, opts, 1, natfilter); return 0; } @@ -231,8 +251,8 @@ char *argv[]; * rather than doing ioctl's. */ void natstat_dead(nsp, kernel) -natstat_t *nsp; -char *kernel; + natstat_t *nsp; + char *kernel; { struct nlist nat_nlist[10] = { { "nat_table" }, /* 0 */ @@ -243,7 +263,6 @@ char *kernel; { "ipf_rdrrules_sz" }, /* 5 */ { "ipf_hostmap_sz" }, { "nat_instances" }, - { "ap_sess_list" }, { NULL } }; void *tables[2]; @@ -259,8 +278,8 @@ char *kernel; * one in individually. */ kmemcpy((char *)&tables, nat_nlist[0].n_value, sizeof(tables)); - nsp->ns_table[0] = tables[0]; - nsp->ns_table[1] = tables[1]; + nsp->ns_side[0].ns_table = tables[0]; + nsp->ns_side[1].ns_table = tables[1]; kmemcpy((char *)&nsp->ns_list, nat_nlist[1].n_value, sizeof(nsp->ns_list)); @@ -276,8 +295,6 @@ char *kernel; sizeof(nsp->ns_hostmap_sz)); kmemcpy((char *)&nsp->ns_instances, nat_nlist[7].n_value, sizeof(nsp->ns_instances)); - kmemcpy((char *)&nsp->ns_apslist, nat_nlist[8].n_value, - sizeof(nsp->ns_apslist)); } @@ -285,23 +302,40 @@ char *kernel; * Issue an ioctl to flush either the NAT rules table or the active mapping * table or both. */ -void flushtable(fd, opts) -int fd, opts; +void flushtable(fd, opts, match) + int fd, opts, *match; { int n = 0; if (opts & OPT_FLUSH) { n = 0; - if (!(opts & OPT_DONOTHING) && ioctl(fd, SIOCIPFFL, &n) == -1) - perror("ioctl(SIOCFLNAT)"); - else + if (!(opts & OPT_DONOTHING)) { + if (match != NULL) { + ipfobj_t obj; + + obj.ipfo_rev = IPFILTER_VERSION; + obj.ipfo_size = match[0] * sizeof(int); + obj.ipfo_type = IPFOBJ_IPFEXPR; + obj.ipfo_ptr = match; + if (ioctl(fd, SIOCMATCHFLUSH, &obj) == -1) { + ipferror(fd, "ioctl(SIOCMATCHFLUSH)"); + n = -1; + } else { + n = obj.ipfo_retval; + } + } else if (ioctl(fd, SIOCIPFFL, &n) == -1) { + ipferror(fd, "ioctl(SIOCIPFFL)"); + n = -1; + } + } + if (n >= 0) printf("%d entries flushed from NAT table\n", n); } if (opts & OPT_CLEAR) { n = 1; if (!(opts & OPT_DONOTHING) && ioctl(fd, SIOCIPFFL, &n) == -1) - perror("ioctl(SIOCCNATL)"); + ipferror(fd, "ioctl(SIOCCNATL)"); else printf("%d entries flushed from NAT list\n", n); } @@ -311,34 +345,65 @@ int fd, opts; /* * Display NAT statistics. */ -void dostats_dead(nsp, opts) -natstat_t *nsp; -int opts; +void dostats_dead(nsp, opts, filter) + natstat_t *nsp; + int opts, *filter; { nat_t *np, nat; ipnat_t ipn; + int i; - printf("List of active MAP/Redirect filters:\n"); - while (nsp->ns_list) { - if (kmemcpy((char *)&ipn, (long)nsp->ns_list, - sizeof(ipn))) { - perror("kmemcpy"); - break; + if (nat_fields == NULL) { + printf("List of active MAP/Redirect filters:\n"); + while (nsp->ns_list) { + if (kmemcpy((char *)&ipn, (long)nsp->ns_list, + sizeof(ipn))) { + perror("kmemcpy"); + break; + } + if (opts & OPT_HITS) + printf("%lu ", ipn.in_hits); + printnat(&ipn, opts & (OPT_DEBUG|OPT_VERBOSE)); + nsp->ns_list = ipn.in_next; } - if (opts & OPT_HITS) - printf("%lu ", ipn.in_hits); - printnat(&ipn, opts & (OPT_DEBUG|OPT_VERBOSE)); - nsp->ns_list = ipn.in_next; } - printf("\nList of active sessions:\n"); + if (nat_fields == NULL) { + printf("\nList of active sessions:\n"); + + } else if (nohdrfields == 0) { + for (i = 0; nat_fields[i].w_value != 0; i++) { + printfieldhdr(natfields, nat_fields + i); + if (nat_fields[i + 1].w_value != 0) + printf("\t"); + } + printf("\n"); + } for (np = nsp->ns_instances; np; np = nat.nat_next) { if (kmemcpy((char *)&nat, (long)np, sizeof(nat))) break; - printactivenat(&nat, opts, 0, nsp->ns_ticks); - if (nat.nat_aps) - printaps(nat.nat_aps, opts); + if ((filter != NULL) && (nat_matcharray(&nat, filter) == 0)) + continue; + if (nat_fields != NULL) { + for (i = 0; nat_fields[i].w_value != 0; i++) { + printnatfield(&nat, nat_fields[i].w_value); + if (nat_fields[i + 1].w_value != 0) + printf("\t"); + } + printf("\n"); + } else { + printactivenat(&nat, opts, nsp->ns_ticks); + if (nat.nat_aps) { + int proto; + + if (nat.nat_dir & NAT_OUTBOUND) + proto = nat.nat_pr[1]; + else + proto = nat.nat_pr[0]; + printaps(nat.nat_aps, opts, proto); + } + } } if (opts & OPT_VERBOSE) @@ -346,62 +411,39 @@ int opts; } -void dostats(fd, nsp, opts, alive) -natstat_t *nsp; -int fd, opts, alive; +void dotable(nsp, fd, alive, which, side) + natstat_t *nsp; + int fd, alive, which; + char *side; { - /* - * Show statistics ? - */ - if (opts & OPT_STAT) { - printf("mapped\tin\t%lu\tout\t%lu\n", - nsp->ns_mapped[0], nsp->ns_mapped[1]); - printf("added\t%lu\texpired\t%lu\n", - nsp->ns_added, nsp->ns_expire); - printf("no memory\t%lu\tbad nat\t%lu\n", - nsp->ns_memfail, nsp->ns_badnat); - printf("inuse\t%lu\norphans\t%u\nrules\t%lu\n", - nsp->ns_inuse, nsp->ns_orphans, nsp->ns_rules); - printf("wilds\t%u\n", nsp->ns_wilds); - dotable(nsp, fd, alive); - if (opts & OPT_VERBOSE) - printf("table %p list %p\n", - nsp->ns_table, nsp->ns_list); - if (alive) - showtqtable_live(fd); - } - - if (opts & OPT_LIST) { - if (alive) - dostats_live(fd, nsp, opts); - else - dostats_dead(nsp, opts); - } -} - - -void dotable(nsp, fd, alive) -natstat_t *nsp; -int fd, alive; -{ - int sz, i, used, totallen, maxlen, minlen; + int sz, i, used, maxlen, minlen, totallen; ipftable_t table; - u_long *buckets; + u_int *buckets; ipfobj_t obj; sz = sizeof(*buckets) * nsp->ns_nattab_sz; - buckets = (u_long *)malloc(sz); + buckets = (u_int *)malloc(sz); + if (buckets == NULL) { + fprintf(stderr, + "cannot allocate memory (%d) for buckets\n", sz); + return; + } obj.ipfo_rev = IPFILTER_VERSION; obj.ipfo_type = IPFOBJ_GTABLE; obj.ipfo_size = sizeof(table); obj.ipfo_ptr = &table; - table.ita_type = IPFTABLE_BUCKETS_NATIN; + if (which == 0) { + table.ita_type = IPFTABLE_BUCKETS_NATIN; + } else if (which == 1) { + table.ita_type = IPFTABLE_BUCKETS_NATOUT; + } table.ita_table = buckets; if (alive) { if (ioctl(fd, SIOCGTABL, &obj) != 0) { + ipferror(fd, "SIOCFTABL"); free(buckets); return; } @@ -412,9 +454,9 @@ int fd, alive; } } + minlen = nsp->ns_side[which].ns_inuse; totallen = 0; maxlen = 0; - minlen = nsp->ns_inuse; used = 0; for (i = 0; i < nsp->ns_nattab_sz; i++) { @@ -427,27 +469,84 @@ int fd, alive; totallen += buckets[i]; } - printf("hash efficiency\t%2.2f%%\n", - totallen ? ((float)used / totallen) * 100.0 : 0.0); - printf("bucket usage\t%2.2f%%\n", - ((float)used / nsp->ns_nattab_sz) * 100.0); - printf("minimal length\t%d\n", minlen); - printf("maximal length\t%d\n", maxlen); - printf("average length\t%.3f\n", used ? (float)totallen / used : 0.0); + printf("%d%%\thash efficiency %s\n", + totallen ? used * 100 / totallen : 0, side); + printf("%2.2f%%\tbucket usage %s\n", + ((float)used / nsp->ns_nattab_sz) * 100.0, side); + printf("%d\tminimal length %s\n", minlen, side); + printf("%d\tmaximal length %s\n", maxlen, side); + printf("%.3f\taverage length %s\n", + used ? ((float)totallen / used) : 0.0, side); + + free(buckets); +} + + +void dostats(fd, nsp, opts, alive, filter) + natstat_t *nsp; + int fd, opts, alive, *filter; +{ + /* + * Show statistics ? + */ + if (opts & OPT_STAT) { + printnatside("in", &nsp->ns_side[0]); + dotable(nsp, fd, alive, 0, "in"); + + printnatside("out", &nsp->ns_side[1]); + dotable(nsp, fd, alive, 1, "out"); + + printf("%lu\tlog successes\n", nsp->ns_side[0].ns_log); + printf("%lu\tlog failures\n", nsp->ns_side[1].ns_log); + printf("%lu\tadded in\n%lu\tadded out\n", + nsp->ns_side[0].ns_added, + nsp->ns_side[1].ns_added); + printf("%u\tactive\n", nsp->ns_active); + printf("%lu\ttransparent adds\n", nsp->ns_addtrpnt); + printf("%lu\tdivert build\n", nsp->ns_divert_build); + printf("%lu\texpired\n", nsp->ns_expire); + printf("%lu\tflush all\n", nsp->ns_flush_all); + printf("%lu\tflush closing\n", nsp->ns_flush_closing); + printf("%lu\tflush queue\n", nsp->ns_flush_queue); + printf("%lu\tflush state\n", nsp->ns_flush_state); + printf("%lu\tflush timeout\n", nsp->ns_flush_timeout); + printf("%lu\thostmap new\n", nsp->ns_hm_new); + printf("%lu\thostmap fails\n", nsp->ns_hm_newfail); + printf("%lu\thostmap add\n", nsp->ns_hm_addref); + printf("%lu\thostmap NULL rule\n", nsp->ns_hm_nullnp); + printf("%lu\tlog ok\n", nsp->ns_log_ok); + printf("%lu\tlog fail\n", nsp->ns_log_fail); + printf("%u\torphan count\n", nsp->ns_orphans); + printf("%u\trule count\n", nsp->ns_rules); + printf("%u\tmap rules\n", nsp->ns_rules_map); + printf("%u\trdr rules\n", nsp->ns_rules_rdr); + printf("%u\twilds\n", nsp->ns_wilds); + if (opts & OPT_VERBOSE) + printf("list %p\n", nsp->ns_list); + } + + if (opts & OPT_LIST) { + if (alive) + dostats_live(fd, nsp, opts, filter); + else + dostats_dead(nsp, opts, filter); + } } /* * Display NAT statistics. */ -void dostats_live(fd, nsp, opts) -natstat_t *nsp; -int fd, opts; +void dostats_live(fd, nsp, opts, filter) + natstat_t *nsp; + int fd, opts, *filter; { ipfgeniter_t iter; + char buffer[2000]; ipfobj_t obj; - ipnat_t ipn; + ipnat_t *ipn; nat_t nat; + int i; bzero((char *)&obj, sizeof(obj)); obj.ipfo_rev = IPFILTER_VERSION; @@ -457,22 +556,39 @@ int fd, opts; iter.igi_type = IPFGENITER_IPNAT; iter.igi_nitems = 1; - iter.igi_data = &ipn; + iter.igi_data = buffer; + ipn = (ipnat_t *)buffer; /* * Show list of NAT rules and NAT sessions ? */ - printf("List of active MAP/Redirect filters:\n"); - while (nsp->ns_list) { - if (ioctl(fd, SIOCGENITER, &obj) == -1) - break; - if (opts & OPT_HITS) - printf("%lu ", ipn.in_hits); - printnat(&ipn, opts & (OPT_DEBUG|OPT_VERBOSE)); - nsp->ns_list = ipn.in_next; + if (nat_fields == NULL) { + printf("List of active MAP/Redirect filters:\n"); + while (nsp->ns_list) { + if (ioctl(fd, SIOCGENITER, &obj) == -1) + break; + if (opts & OPT_HITS) + printf("%lu ", ipn->in_hits); + printnat(ipn, opts & (OPT_DEBUG|OPT_VERBOSE)); + nsp->ns_list = ipn->in_next; + } } - printf("\nList of active sessions:\n"); + if (nat_fields == NULL) { + printf("\nList of active sessions:\n"); + + } else if (nohdrfields == 0) { + for (i = 0; nat_fields[i].w_value != 0; i++) { + printfieldhdr(natfields, nat_fields + i); + if (nat_fields[i + 1].w_value != 0) + printf("\t"); + } + printf("\n"); + } + + i = IPFGENITER_IPNAT; + (void) ioctl(fd,SIOCIPFDELTOK, &i); + iter.igi_type = IPFGENITER_NAT; iter.igi_nitems = 1; @@ -481,14 +597,35 @@ int fd, opts; while (nsp->ns_instances != NULL) { if (ioctl(fd, SIOCGENITER, &obj) == -1) break; - printactivenat(&nat, opts, 1, nsp->ns_ticks); - if (nat.nat_aps) - printaps(nat.nat_aps, opts); + if ((filter != NULL) && (nat_matcharray(&nat, filter) == 0)) + continue; + if (nat_fields != NULL) { + for (i = 0; nat_fields[i].w_value != 0; i++) { + printnatfield(&nat, nat_fields[i].w_value); + if (nat_fields[i + 1].w_value != 0) + printf("\t"); + } + printf("\n"); + } else { + printactivenat(&nat, opts, nsp->ns_ticks); + if (nat.nat_aps) { + int proto; + + if (nat.nat_dir & NAT_OUTBOUND) + proto = nat.nat_pr[1]; + else + proto = nat.nat_pr[0]; + printaps(nat.nat_aps, opts, proto); + } + } nsp->ns_instances = nat.nat_next; } if (opts & OPT_VERBOSE) showhostmap_live(fd, nsp); + + i = IPFGENITER_NAT; + (void) ioctl(fd,SIOCIPFDELTOK, &i); } @@ -496,7 +633,7 @@ int fd, opts; * Display the active host mapping table. */ void showhostmap_dead(nsp) -natstat_t *nsp; + natstat_t *nsp; { hostmap_t hm, *hmp, **maptable; u_int hv; @@ -532,12 +669,13 @@ natstat_t *nsp; * Display the active host mapping table. */ void showhostmap_live(fd, nsp) -int fd; -natstat_t *nsp; + int fd; + natstat_t *nsp; { ipfgeniter_t iter; hostmap_t hm; ipfobj_t obj; + int i; bzero((char *)&obj, sizeof(obj)); obj.ipfo_rev = IPFILTER_VERSION; @@ -554,25 +692,167 @@ natstat_t *nsp; while (nsp->ns_maplist != NULL) { if (ioctl(fd, SIOCGENITER, &obj) == -1) break; - printhostmap(&hm, 0); + printhostmap(&hm, hm.hm_hv); nsp->ns_maplist = hm.hm_next; } + + i = IPFGENITER_HOSTMAP; + (void) ioctl(fd,SIOCIPFDELTOK, &i); } -void showtqtable_live(fd) -int fd; +int nat_matcharray(nat, array) + nat_t *nat; + int *array; { - ipftq_t table[IPF_TCP_NSTATES]; - ipfobj_t obj; + int i, n, *x, rv, p; + ipfexp_t *e; - bzero((char *)&obj, sizeof(obj)); - obj.ipfo_rev = IPFILTER_VERSION; - obj.ipfo_size = sizeof(table); - obj.ipfo_ptr = (void *)table; - obj.ipfo_type = IPFOBJ_STATETQTAB; + rv = 0; + n = array[0]; + x = array + 1; - if (ioctl(fd, SIOCGTQTAB, &obj) == 0) { - printtqtable(table); + for (; n > 0; x += 3 + x[3], rv = 0) { + e = (ipfexp_t *)x; + if (e->ipfe_cmd == IPF_EXP_END) + break; + n -= e->ipfe_size; + + p = e->ipfe_cmd >> 16; + if ((p != 0) && (p != nat->nat_pr[1])) + break; + + switch (e->ipfe_cmd) + { + case IPF_EXP_IP_PR : + for (i = 0; !rv && i < e->ipfe_narg; i++) { + rv |= (nat->nat_pr[1] == e->ipfe_arg0[i]); + } + break; + + case IPF_EXP_IP_SRCADDR : + if (nat->nat_v[0] != 4) + break; + for (i = 0; !rv && i < e->ipfe_narg; i++) { + rv |= ((nat->nat_osrcaddr & + e->ipfe_arg0[i * 2 + 1]) == + e->ipfe_arg0[i * 2]) || + ((nat->nat_nsrcaddr & + e->ipfe_arg0[i * 2 + 1]) == + e->ipfe_arg0[i * 2]); + } + break; + + case IPF_EXP_IP_DSTADDR : + if (nat->nat_v[0] != 4) + break; + for (i = 0; !rv && i < e->ipfe_narg; i++) { + rv |= ((nat->nat_odstaddr & + e->ipfe_arg0[i * 2 + 1]) == + e->ipfe_arg0[i * 2]) || + ((nat->nat_ndstaddr & + e->ipfe_arg0[i * 2 + 1]) == + e->ipfe_arg0[i * 2]); + } + break; + + case IPF_EXP_IP_ADDR : + if (nat->nat_v[0] != 4) + break; + for (i = 0; !rv && i < e->ipfe_narg; i++) { + rv |= ((nat->nat_osrcaddr & + e->ipfe_arg0[i * 2 + 1]) == + e->ipfe_arg0[i * 2]) || + ((nat->nat_nsrcaddr & + e->ipfe_arg0[i * 2 + 1]) == + e->ipfe_arg0[i * 2]) || + ((nat->nat_odstaddr & + e->ipfe_arg0[i * 2 + 1]) == + e->ipfe_arg0[i * 2]) || + ((nat->nat_ndstaddr & + e->ipfe_arg0[i * 2 + 1]) == + e->ipfe_arg0[i * 2]); + } + break; + +#ifdef USE_INET6 + case IPF_EXP_IP6_SRCADDR : + if (nat->nat_v[0] != 6) + break; + for (i = 0; !rv && i < e->ipfe_narg; i++) { + rv |= IP6_MASKEQ(&nat->nat_osrc6, + &e->ipfe_arg0[i * 8 + 4], + &e->ipfe_arg0[i * 8]) || + IP6_MASKEQ(&nat->nat_nsrc6, + &e->ipfe_arg0[i * 8 + 4], + &e->ipfe_arg0[i * 8]); + } + break; + + case IPF_EXP_IP6_DSTADDR : + if (nat->nat_v[0] != 6) + break; + for (i = 0; !rv && i < e->ipfe_narg; i++) { + rv |= IP6_MASKEQ(&nat->nat_odst6, + &e->ipfe_arg0[i * 8 + 4], + &e->ipfe_arg0[i * 8]) || + IP6_MASKEQ(&nat->nat_ndst6, + &e->ipfe_arg0[i * 8 + 4], + &e->ipfe_arg0[i * 8]); + } + break; + + case IPF_EXP_IP6_ADDR : + if (nat->nat_v[0] != 6) + break; + for (i = 0; !rv && i < e->ipfe_narg; i++) { + rv |= IP6_MASKEQ(&nat->nat_osrc6, + &e->ipfe_arg0[i * 8 + 4], + &e->ipfe_arg0[i * 8]) || + IP6_MASKEQ(&nat->nat_nsrc6, + &e->ipfe_arg0[i * 8 + 4], + &e->ipfe_arg0[i * 8]) || + IP6_MASKEQ(&nat->nat_odst6, + &e->ipfe_arg0[i * 8 + 4], + &e->ipfe_arg0[i * 8]) || + IP6_MASKEQ(&nat->nat_ndst6, + &e->ipfe_arg0[i * 8 + 4], + &e->ipfe_arg0[i * 8]); + } + break; +#endif + + case IPF_EXP_UDP_PORT : + case IPF_EXP_TCP_PORT : + for (i = 0; !rv && i < e->ipfe_narg; i++) { + rv |= (nat->nat_osport == e->ipfe_arg0[i]) || + (nat->nat_nsport == e->ipfe_arg0[i]) || + (nat->nat_odport == e->ipfe_arg0[i]) || + (nat->nat_ndport == e->ipfe_arg0[i]); + } + break; + + case IPF_EXP_UDP_SPORT : + case IPF_EXP_TCP_SPORT : + for (i = 0; !rv && i < e->ipfe_narg; i++) { + rv |= (nat->nat_osport == e->ipfe_arg0[i]) || + (nat->nat_nsport == e->ipfe_arg0[i]); + } + break; + + case IPF_EXP_UDP_DPORT : + case IPF_EXP_TCP_DPORT : + for (i = 0; !rv && i < e->ipfe_narg; i++) { + rv |= (nat->nat_odport == e->ipfe_arg0[i]) || + (nat->nat_ndport == e->ipfe_arg0[i]); + } + break; + } + rv ^= e->ipfe_not; + + if (rv == 0) + break; } + + return rv; } diff --git a/contrib/ipfilter/tools/ipnat_y.y b/contrib/ipfilter/tools/ipnat_y.y index 7109f60ec710..71fb8ee37106 100644 --- a/contrib/ipfilter/tools/ipnat_y.y +++ b/contrib/ipfilter/tools/ipnat_y.y @@ -1,7 +1,7 @@ /* $FreeBSD$ */ /* - * Copyright (C) 2001-2006 by Darren Reed. + * Copyright (C) 2012 by Darren Reed. * * See the IPFILTER.LICENCE file for details on licencing. */ @@ -60,33 +60,58 @@ static int natfd = -1; static ioctlfunc_t natioctlfunc = NULL; static addfunc_t nataddfunc = NULL; static int suggest_port = 0; +static proxyrule_t *prules = NULL; +static int parser_error = 0; static void newnatrule __P((void)); static void setnatproto __P((int)); - +static void setmapifnames __P((void)); +static void setrdrifnames __P((void)); +static void proxy_setconfig __P((int)); +static void proxy_unsetconfig __P((void)); +static namelist_t *proxy_dns_add_pass __P((char *, char *)); +static namelist_t *proxy_dns_add_block __P((char *, char *)); +static void proxy_addconfig __P((char *, int, char *, namelist_t *)); +static void proxy_loadconfig __P((int, ioctlfunc_t, char *, int, + char *, namelist_t *)); +static void proxy_loadrules __P((int, ioctlfunc_t, proxyrule_t *)); +static void setmapifnames __P((void)); +static void setrdrifnames __P((void)); +static void setifname __P((ipnat_t **, int, char *)); +static int addname __P((ipnat_t **, char *)); %} %union { char *str; u_32_t num; - struct in_addr ipa; + struct { + i6addr_t a; + int f; + } ipa; frentry_t fr; frtuc_t *frt; u_short port; struct { - u_short p1; - u_short p2; + int p1; + int p2; int pc; } pc; struct { - struct in_addr a; - struct in_addr m; + i6addr_t a; + i6addr_t m; + int t; /* Address type */ + int u; + int f; /* Family */ + int v; /* IP version */ + int s; /* 0 = number, 1 = text */ + int n; /* number */ } ipp; union i6addr ip6; + namelist_t *names; }; %token YY_NUMBER YY_HEX %token YY_STR -%token YY_COMMENT +%token YY_COMMENT %token YY_CMP_EQ YY_CMP_NE YY_CMP_LE YY_CMP_GE YY_CMP_LT YY_CMP_GT %token YY_RANGE_OUT YY_RANGE_IN %token YY_IPV6 @@ -95,23 +120,42 @@ static void setnatproto __P((int)); %token IPNY_MAP IPNY_BIMAP IPNY_FROM IPNY_TO IPNY_MASK IPNY_PORTMAP IPNY_ANY %token IPNY_ROUNDROBIN IPNY_FRAG IPNY_AGE IPNY_ICMPIDMAP IPNY_PROXY %token IPNY_TCP IPNY_UDP IPNY_TCPUDP IPNY_STICKY IPNY_MSSCLAMP IPNY_TAG -%token IPNY_TLATE IPNY_SEQUENTIAL +%token IPNY_TLATE IPNY_POOL IPNY_HASH IPNY_NO IPNY_REWRITE IPNY_PROTO +%token IPNY_ON IPNY_SRC IPNY_DST IPNY_IN IPNY_OUT IPNY_DIVERT +%token IPNY_CONFIG IPNY_ALLOW IPNY_DENY IPNY_DNS IPNY_INET IPNY_INET6 +%token IPNY_SEQUENTIAL IPNY_DSTLIST IPNY_PURGE %type portspec %type hexnumber compare range proto -%type hostname ipv4 -%type addr nummask rhaddr -%type portstuff +%type saddr daddr sobject dobject mapfrom rdrfrom dip +%type hostname ipv4 ipaddr +%type addr rhsaddr rhdaddr erhdaddr +%type portstuff portpair comaports srcports dstports +%type dnslines dnsline %% file: line | assign | file line | file assign + | file pconf ';' ; -line: xx rule { while ((nat = nattop) != NULL) { +line: xx rule { int err; + while ((nat = nattop) != NULL) { + if (nat->in_v[0] == 0) + nat->in_v[0] = 4; + if (nat->in_v[1] == 0) + nat->in_v[1] = nat->in_v[0]; nattop = nat->in_next; - (*nataddfunc)(natfd, natioctlfunc, nat); + err = (*nataddfunc)(natfd, natioctlfunc, nat); free(nat); + if (err != 0) { + parser_error = err; + break; + } + } + if (parser_error == 0 && prules != NULL) { + proxy_loadrules(natfd, natioctlfunc, prules); + prules = NULL; } resetlexer(); } @@ -136,206 +180,541 @@ xx: { newnatrule(); } rule: map eol | mapblock eol | redir eol + | rewrite ';' + | divert ';' + ; + +no: IPNY_NO { nat->in_flags |= IPN_NO; } ; eol: | ';' ; -map: mapit ifnames addr IPNY_TLATE rhaddr proxy mapoptions - { nat->in_v = 4; - nat->in_inip = $3.a.s_addr; - nat->in_inmsk = $3.m.s_addr; - nat->in_outip = $5.a.s_addr; - nat->in_outmsk = $5.m.s_addr; - if (nat->in_ifnames[1][0] == '\0') - strncpy(nat->in_ifnames[1], - nat->in_ifnames[0], - sizeof(nat->in_ifnames[0])); - if ((nat->in_flags & IPN_TCPUDP) == 0) - setnatproto(nat->in_p); - if (((nat->in_redir & NAT_MAPBLK) != 0) || - ((nat->in_flags & IPN_AUTOPORTMAP) != 0)) - nat_setgroupmap(nat); +map: mapit ifnames addr tlate rhsaddr proxy mapoptions + { if ($3.f != 0 && $3.f != $5.f && $5.f != 0) + yyerror("3.address family mismatch"); + if (nat->in_v[0] == 0 && $5.v != 0) + nat->in_v[0] = $5.v; + else if (nat->in_v[0] == 0 && $3.v != 0) + nat->in_v[0] = $3.v; + if (nat->in_v[1] == 0 && $5.v != 0) + nat->in_v[1] = $5.v; + else if (nat->in_v[1] == 0 && $3.v != 0) + nat->in_v[1] = $3.v; + nat->in_osrcatype = $3.t; + bcopy(&$3.a, &nat->in_osrc.na_addr[0], + sizeof($3.a)); + bcopy(&$3.m, &nat->in_osrc.na_addr[1], + sizeof($3.a)); + nat->in_nsrcatype = $5.t; + nat->in_nsrcafunc = $5.u; + bcopy(&$5.a, &nat->in_nsrc.na_addr[0], + sizeof($5.a)); + bcopy(&$5.m, &nat->in_nsrc.na_addr[1], + sizeof($5.a)); + + setmapifnames(); } - | mapit ifnames addr IPNY_TLATE rhaddr mapport mapoptions - { nat->in_v = 4; - nat->in_inip = $3.a.s_addr; - nat->in_inmsk = $3.m.s_addr; - nat->in_outip = $5.a.s_addr; - nat->in_outmsk = $5.m.s_addr; - if (nat->in_ifnames[1][0] == '\0') - strncpy(nat->in_ifnames[1], - nat->in_ifnames[0], - sizeof(nat->in_ifnames[0])); - if (((nat->in_redir & NAT_MAPBLK) != 0) || - ((nat->in_flags & IPN_AUTOPORTMAP) != 0)) - nat_setgroupmap(nat); + | mapit ifnames addr tlate rhsaddr mapport mapoptions + { if ($3.f != $5.f && $3.f != 0 && $5.f != 0) + yyerror("4.address family mismatch"); + if (nat->in_v[1] == 0 && $5.v != 0) + nat->in_v[1] = $5.v; + else if (nat->in_v[0] == 0 && $3.v != 0) + nat->in_v[0] = $3.v; + if (nat->in_v[0] == 0 && $5.v != 0) + nat->in_v[0] = $5.v; + else if (nat->in_v[1] == 0 && $3.v != 0) + nat->in_v[1] = $3.v; + nat->in_osrcatype = $3.t; + bcopy(&$3.a, &nat->in_osrc.na_addr[0], + sizeof($3.a)); + bcopy(&$3.m, &nat->in_osrc.na_addr[1], + sizeof($3.a)); + nat->in_nsrcatype = $5.t; + nat->in_nsrcafunc = $5.u; + bcopy(&$5.a, &nat->in_nsrc.na_addr[0], + sizeof($5.a)); + bcopy(&$5.m, &nat->in_nsrc.na_addr[1], + sizeof($5.a)); + + setmapifnames(); } - | mapit ifnames mapfrom IPNY_TLATE rhaddr proxy mapoptions - { nat->in_v = 4; - nat->in_outip = $5.a.s_addr; - nat->in_outmsk = $5.m.s_addr; - if (nat->in_ifnames[1][0] == '\0') - strncpy(nat->in_ifnames[1], - nat->in_ifnames[0], - sizeof(nat->in_ifnames[0])); - if ((suggest_port == 1) && - (nat->in_flags & IPN_TCPUDP) == 0) - nat->in_flags |= IPN_TCPUDP; - if ((nat->in_flags & IPN_TCPUDP) == 0) - setnatproto(nat->in_p); - if (((nat->in_redir & NAT_MAPBLK) != 0) || - ((nat->in_flags & IPN_AUTOPORTMAP) != 0)) - nat_setgroupmap(nat); + | no mapit ifnames addr setproto ';' + { if (nat->in_v[0] == 0) + nat->in_v[0] = $4.v; + nat->in_osrcatype = $4.t; + bcopy(&$4.a, &nat->in_osrc.na_addr[0], + sizeof($4.a)); + bcopy(&$4.m, &nat->in_osrc.na_addr[1], + sizeof($4.a)); + + setmapifnames(); } - | mapit ifnames mapfrom IPNY_TLATE rhaddr mapport mapoptions - { nat->in_v = 4; - nat->in_outip = $5.a.s_addr; - nat->in_outmsk = $5.m.s_addr; - if (nat->in_ifnames[1][0] == '\0') - strncpy(nat->in_ifnames[1], - nat->in_ifnames[0], - sizeof(nat->in_ifnames[0])); - if ((suggest_port == 1) && - (nat->in_flags & IPN_TCPUDP) == 0) - nat->in_flags |= IPN_TCPUDP; - if (((nat->in_redir & NAT_MAPBLK) != 0) || - ((nat->in_flags & IPN_AUTOPORTMAP) != 0)) - nat_setgroupmap(nat); + | mapit ifnames mapfrom tlate rhsaddr proxy mapoptions + { if ($3 != 0 && $5.f != 0 && $3 != $5.f) + yyerror("5.address family mismatch"); + if (nat->in_v[0] == 0 && $5.v != 0) + nat->in_v[0] = $5.v; + else if (nat->in_v[0] == 0 && $3 != 0) + nat->in_v[0] = ftov($3); + if (nat->in_v[1] == 0 && $5.v != 0) + nat->in_v[1] = $5.v; + else if (nat->in_v[1] == 0 && $3 != 0) + nat->in_v[1] = ftov($3); + nat->in_nsrcatype = $5.t; + nat->in_nsrcafunc = $5.u; + bcopy(&$5.a, &nat->in_nsrc.na_addr[0], + sizeof($5.a)); + bcopy(&$5.m, &nat->in_nsrc.na_addr[1], + sizeof($5.a)); + + setmapifnames(); + } + | no mapit ifnames mapfrom setproto ';' + { nat->in_v[0] = ftov($4); + setmapifnames(); + } + | mapit ifnames mapfrom tlate rhsaddr mapport mapoptions + { if ($3 != 0 && $5.f != 0 && $3 != $5.f) + yyerror("6.address family mismatch"); + if (nat->in_v[0] == 0 && $5.v != 0) + nat->in_v[0] = $5.v; + else if (nat->in_v[0] == 0 && $3 != 0) + nat->in_v[0] = ftov($3); + if (nat->in_v[1] == 0 && $5.v != 0) + nat->in_v[1] = $5.v; + else if (nat->in_v[1] == 0 && $3 != 0) + nat->in_v[1] = ftov($3); + nat->in_nsrcatype = $5.t; + nat->in_nsrcafunc = $5.u; + bcopy(&$5.a, &nat->in_nsrc.na_addr[0], + sizeof($5.a)); + bcopy(&$5.m, &nat->in_nsrc.na_addr[1], + sizeof($5.a)); + + setmapifnames(); } ; mapblock: - mapblockit ifnames addr IPNY_TLATE addr ports mapoptions - { nat->in_v = 4; - nat->in_inip = $3.a.s_addr; - nat->in_inmsk = $3.m.s_addr; - nat->in_outip = $5.a.s_addr; - nat->in_outmsk = $5.m.s_addr; - if (nat->in_ifnames[1][0] == '\0') - strncpy(nat->in_ifnames[1], - nat->in_ifnames[0], - sizeof(nat->in_ifnames[0])); - if ((nat->in_flags & IPN_TCPUDP) == 0) - setnatproto(nat->in_p); - if (((nat->in_redir & NAT_MAPBLK) != 0) || - ((nat->in_flags & IPN_AUTOPORTMAP) != 0)) - nat_setgroupmap(nat); + mapblockit ifnames addr tlate addr ports mapoptions + { if ($3.f != 0 && $5.f != 0 && $3.f != $5.f) + yyerror("7.address family mismatch"); + if (nat->in_v[0] == 0 && $5.v != 0) + nat->in_v[0] = $5.v; + else if (nat->in_v[0] == 0 && $3.v != 0) + nat->in_v[0] = $3.v; + if (nat->in_v[1] == 0 && $5.v != 0) + nat->in_v[1] = $5.v; + else if (nat->in_v[1] == 0 && $3.v != 0) + nat->in_v[1] = $3.v; + nat->in_osrcatype = $3.t; + bcopy(&$3.a, &nat->in_osrc.na_addr[0], + sizeof($3.a)); + bcopy(&$3.m, &nat->in_osrc.na_addr[1], + sizeof($3.a)); + nat->in_nsrcatype = $5.t; + nat->in_nsrcafunc = $5.u; + bcopy(&$5.a, &nat->in_nsrc.na_addr[0], + sizeof($5.a)); + bcopy(&$5.m, &nat->in_nsrc.na_addr[1], + sizeof($5.a)); + + setmapifnames(); + } + | no mapblockit ifnames { yyexpectaddr = 1; } addr setproto ';' + { if (nat->in_v[0] == 0) + nat->in_v[0] = $5.v; + if (nat->in_v[1] == 0) + nat->in_v[1] = $5.v; + nat->in_osrcatype = $5.t; + bcopy(&$5.a, &nat->in_osrc.na_addr[0], + sizeof($5.a)); + bcopy(&$5.m, &nat->in_osrc.na_addr[1], + sizeof($5.a)); + + setmapifnames(); } ; -redir: rdrit ifnames addr dport IPNY_TLATE dip nport setproto rdroptions - { nat->in_v = 4; - nat->in_outip = $3.a.s_addr; - nat->in_outmsk = $3.m.s_addr; - if (nat->in_ifnames[1][0] == '\0') - strncpy(nat->in_ifnames[1], - nat->in_ifnames[0], - sizeof(nat->in_ifnames[0])); - if ((nat->in_p == 0) && - ((nat->in_flags & IPN_TCPUDP) == 0) && - (nat->in_pmin != 0 || - nat->in_pmax != 0 || - nat->in_pnext != 0)) - setnatproto(IPPROTO_TCP); +redir: rdrit ifnames addr dport tlate dip nport setproto rdroptions + { if ($6 != 0 && $3.f != 0 && $6 != $3.f) + yyerror("21.address family mismatch"); + if (nat->in_v[0] == 0) { + if ($3.v != AF_UNSPEC) + nat->in_v[0] = ftov($3.f); + else + nat->in_v[0] = ftov($6); + } + nat->in_odstatype = $3.t; + bcopy(&$3.a, &nat->in_odst.na_addr[0], + sizeof($3.a)); + bcopy(&$3.m, &nat->in_odst.na_addr[1], + sizeof($3.a)); + + setrdrifnames(); } - | rdrit ifnames rdrfrom IPNY_TLATE dip nport setproto rdroptions - { nat->in_v = 4; - if ((nat->in_p == 0) && - ((nat->in_flags & IPN_TCPUDP) == 0) && - (nat->in_pmin != 0 || - nat->in_pmax != 0 || - nat->in_pnext != 0)) - setnatproto(IPPROTO_TCP); - if ((suggest_port == 1) && - (nat->in_flags & IPN_TCPUDP) == 0) - nat->in_flags |= IPN_TCPUDP; - if (nat->in_ifnames[1][0] == '\0') - strncpy(nat->in_ifnames[1], - nat->in_ifnames[0], - sizeof(nat->in_ifnames[0])); + | no rdrit ifnames addr dport setproto ';' + { if (nat->in_v[0] == 0) + nat->in_v[0] = ftov($4.f); + nat->in_odstatype = $4.t; + bcopy(&$4.a, &nat->in_odst.na_addr[0], + sizeof($4.a)); + bcopy(&$4.m, &nat->in_odst.na_addr[1], + sizeof($4.a)); + + setrdrifnames(); } - | rdrit ifnames addr IPNY_TLATE dip setproto rdroptions - { nat->in_v = 4; - nat->in_outip = $3.a.s_addr; - nat->in_outmsk = $3.m.s_addr; - if (nat->in_ifnames[1][0] == '\0') - strncpy(nat->in_ifnames[1], - nat->in_ifnames[0], - sizeof(nat->in_ifnames[0])); + | rdrit ifnames rdrfrom tlate dip nport setproto rdroptions + { if ($5 != 0 && $3 != 0 && $5 != $3) + yyerror("20.address family mismatch"); + if (nat->in_v[0] == 0) { + if ($3 != AF_UNSPEC) + nat->in_v[0] = ftov($3); + else + nat->in_v[0] = ftov($5); + } + setrdrifnames(); } - | rdrit ifnames rdrfrom IPNY_TLATE dip setproto rdroptions - { nat->in_v = 4; - if ((suggest_port == 1) && - (nat->in_flags & IPN_TCPUDP) == 0) - nat->in_flags |= IPN_TCPUDP; - if (nat->in_ifnames[1][0] == '\0') - strncpy(nat->in_ifnames[1], - nat->in_ifnames[0], - sizeof(nat->in_ifnames[0])); + | no rdrit ifnames rdrfrom setproto ';' + { nat->in_v[0] = ftov($4); + + setrdrifnames(); + } + ; + +rewrite: + IPNY_REWRITE oninout rwrproto mapfrom tlate newdst newopts + { if (nat->in_v[0] == 0) + nat->in_v[0] = ftov($4); + if (nat->in_redir & NAT_MAP) + setmapifnames(); + else + setrdrifnames(); + nat->in_redir |= NAT_REWRITE; + } + ; + +divert: IPNY_DIVERT oninout rwrproto mapfrom tlate divdst newopts + { if (nat->in_v[0] == 0) + nat->in_v[0] = ftov($4); + if (nat->in_redir & NAT_MAP) { + setmapifnames(); + nat->in_pr[0] = IPPROTO_UDP; + } else { + setrdrifnames(); + nat->in_pr[1] = IPPROTO_UDP; + } + nat->in_flags &= ~IPN_TCP; + } + ; + +tlate: IPNY_TLATE { yyexpectaddr = 1; } + ; + +pconf: IPNY_PROXY { yysetdict(proxies); } + IPNY_DNS '/' proto IPNY_CONFIG YY_STR '{' + { proxy_setconfig(IPNY_DNS); } + dnslines ';' '}' + { proxy_addconfig("dns", $5, $7, $10); + proxy_unsetconfig(); + } + ; + +dnslines: + dnsline { $$ = $1; } + | dnslines ';' dnsline { $$ = $1; $1->na_next = $3; } + ; + +dnsline: + IPNY_ALLOW YY_STR { $$ = proxy_dns_add_pass(NULL, $2); } + | IPNY_DENY YY_STR { $$ = proxy_dns_add_block(NULL, $2); } + | IPNY_ALLOW '.' YY_STR { $$ = proxy_dns_add_pass(".", $3); } + | IPNY_DENY '.' YY_STR { $$ = proxy_dns_add_block(".", $3); } + ; + +oninout: + inout IPNY_ON ifnames { ; } + ; + +inout: IPNY_IN { nat->in_redir = NAT_REDIRECT; } + | IPNY_OUT { nat->in_redir = NAT_MAP; } + ; + +rwrproto: + | IPNY_PROTO setproto + ; + +newdst: src rhsaddr srcports dst erhdaddr dstports + { nat->in_nsrc.na_addr[0] = $2.a; + nat->in_nsrc.na_addr[1] = $2.m; + nat->in_nsrc.na_atype = $2.t; + if ($2.t == FRI_LOOKUP) { + nat->in_nsrc.na_type = $2.u; + nat->in_nsrc.na_subtype = $2.s; + nat->in_nsrc.na_num = $2.n; + } + nat->in_nsports[0] = $3.p1; + nat->in_nsports[1] = $3.p2; + nat->in_ndst.na_addr[0] = $5.a; + nat->in_ndst.na_addr[1] = $5.m; + nat->in_ndst.na_atype = $5.t; + if ($5.t == FRI_LOOKUP) { + nat->in_ndst.na_type = $5.u; + nat->in_ndst.na_subtype = $5.s; + nat->in_ndst.na_num = $5.n; + } + nat->in_ndports[0] = $6.p1; + nat->in_ndports[1] = $6.p2; + } + ; + +divdst: src addr ',' portspec dst addr ',' portspec IPNY_UDP + { nat->in_nsrc.na_addr[0] = $2.a; + if ($2.m.in4.s_addr != 0xffffffff) + yyerror("divert must have /32 dest"); + nat->in_nsrc.na_addr[1] = $2.m; + nat->in_nsports[0] = $4; + nat->in_nsports[1] = $4; + + nat->in_ndst.na_addr[0] = $6.a; + nat->in_ndst.na_addr[1] = $6.m; + if ($6.m.in4.s_addr != 0xffffffff) + yyerror("divert must have /32 dest"); + nat->in_ndports[0] = $8; + nat->in_ndports[1] = $8; + + nat->in_redir |= NAT_DIVERTUDP; + } + ; + +src: IPNY_SRC { yyexpectaddr = 1; } + ; + +dst: IPNY_DST { yyexpectaddr = 1; } + ; + +srcports: + comaports { $$.p1 = $1.p1; + $$.p2 = $1.p2; + } + | IPNY_PORT '=' portspec + { $$.p1 = $3; + $$.p2 = $3; + nat->in_flags |= IPN_FIXEDSPORT; + } + ; + +dstports: + comaports { $$.p1 = $1.p1; + $$.p2 = $1.p2; + } + | IPNY_PORT '=' portspec + { $$.p1 = $3; + $$.p2 = $3; + nat->in_flags |= IPN_FIXEDDPORT; + } + ; + +comaports: + { $$.p1 = 0; + $$.p2 = 0; + } + | ',' { if (!(nat->in_flags & IPN_TCPUDP)) + yyerror("must be TCP/UDP for ports"); + } + portpair { $$.p1 = $3.p1; + $$.p2 = $3.p2; } ; proxy: | IPNY_PROXY port portspec YY_STR '/' proto - { strncpy(nat->in_plabel, $4, sizeof(nat->in_plabel)); + { int pos; + pos = addname(&nat, $4); + nat->in_plabel = pos; if (nat->in_dcmp == 0) { - nat->in_dport = htons($3); - } else if ($3 != nat->in_dport) { + nat->in_odport = $3; + } else if ($3 != nat->in_odport) { yyerror("proxy port numbers not consistant"); } + nat->in_ndport = $3; setnatproto($6); free($4); } | IPNY_PROXY port YY_STR YY_STR '/' proto - { int pnum; - strncpy(nat->in_plabel, $4, sizeof(nat->in_plabel)); + { int pnum, pos; + pos = addname(&nat, $4); + nat->in_plabel = pos; pnum = getportproto($3, $6); if (pnum == -1) yyerror("invalid port number"); - nat->in_dport = pnum; + nat->in_odport = ntohs(pnum); + nat->in_ndport = ntohs(pnum); setnatproto($6); free($3); free($4); } + | IPNY_PROXY port portspec YY_STR '/' proto IPNY_CONFIG YY_STR + { int pos; + pos = addname(&nat, $4); + nat->in_plabel = pos; + if (nat->in_dcmp == 0) { + nat->in_odport = $3; + } else if ($3 != nat->in_odport) { + yyerror("proxy port numbers not consistant"); + } + nat->in_ndport = $3; + setnatproto($6); + nat->in_pconfig = addname(&nat, $8); + free($4); + free($8); + } + | IPNY_PROXY port YY_STR YY_STR '/' proto IPNY_CONFIG YY_STR + { int pnum, pos; + pos = addname(&nat, $4); + nat->in_plabel = pos; + pnum = getportproto($3, $6); + if (pnum == -1) + yyerror("invalid port number"); + nat->in_odport = ntohs(pnum); + nat->in_ndport = ntohs(pnum); + setnatproto($6); + pos = addname(&nat, $8); + nat->in_pconfig = pos; + free($3); + free($4); + free($8); + } ; - setproto: - | proto { if (nat->in_p != 0 || + | proto { if (nat->in_pr[0] != 0 || + nat->in_pr[1] != 0 || nat->in_flags & IPN_TCPUDP) yyerror("protocol set twice"); setnatproto($1); } - | IPNY_TCPUDP { if (nat->in_p != 0 || + | IPNY_TCPUDP { if (nat->in_pr[0] != 0 || + nat->in_pr[1] != 0 || nat->in_flags & IPN_TCPUDP) yyerror("protocol set twice"); nat->in_flags |= IPN_TCPUDP; - nat->in_p = 0; + nat->in_pr[0] = 0; + nat->in_pr[1] = 0; } - | IPNY_TCP '/' IPNY_UDP { if (nat->in_p != 0 || + | IPNY_TCP '/' IPNY_UDP { if (nat->in_pr[0] != 0 || + nat->in_pr[1] != 0 || nat->in_flags & IPN_TCPUDP) yyerror("protocol set twice"); nat->in_flags |= IPN_TCPUDP; - nat->in_p = 0; + nat->in_pr[0] = 0; + nat->in_pr[1] = 0; } ; -rhaddr: addr { $$.a = $1.a; $$.m = $1.m; } - | IPNY_RANGE ipv4 '-' ipv4 - { $$.a = $2; $$.m = $4; - nat->in_flags |= IPN_IPRANGE; } +rhsaddr: + addr { $$ = $1; + yyexpectaddr = 0; + } + | hostname '-' { yyexpectaddr = 1; } hostname + { $$.t = FRI_RANGE; + if ($1.f != $4.f) + yyerror("8.address family " + "mismatch"); + $$.f = $1.f; + $$.v = ftov($1.f); + $$.a = $1.a; + $$.m = $4.a; + nat->in_flags |= IPN_SIPRANGE; + yyexpectaddr = 0; + } + | IPNY_RANGE hostname '-' { yyexpectaddr = 1; } hostname + { $$.t = FRI_RANGE; + if ($2.f != $5.f) + yyerror("9.address family " + "mismatch"); + $$.f = $2.f; + $$.v = ftov($2.f); + $$.a = $2.a; + $$.m = $5.a; + nat->in_flags |= IPN_SIPRANGE; + yyexpectaddr = 0; + } ; dip: - hostname { nat->in_inip = $1.s_addr; - nat->in_inmsk = 0xffffffff; } - | hostname '/' YY_NUMBER { if ($3 != 0 || $1.s_addr != 0) - yyerror("Only 0/0 supported"); - nat->in_inip = 0; - nat->in_inmsk = 0; + hostname ',' { yyexpectaddr = 1; } hostname + { nat->in_flags |= IPN_SPLIT; + if ($1.f != $4.f) + yyerror("10.address family " + "mismatch"); + $$ = $1.f; + nat->in_ndstip6 = $1.a; + nat->in_ndstmsk6 = $4.a; + nat->in_ndstatype = FRI_SPLIT; + yyexpectaddr = 0; + } + | rhdaddr { int bits; + nat->in_ndstip6 = $1.a; + nat->in_ndstmsk6 = $1.m; + nat->in_ndst.na_atype = $1.t; + yyexpectaddr = 0; + if ($1.f == AF_INET) + bits = count4bits($1.m.in4.s_addr); + else + bits = count6bits($1.m.i6); + if (($1.f == AF_INET) && (bits != 0) && + (bits != 32)) { + yyerror("dest ip bitmask not /32"); + } else if (($1.f == AF_INET6) && + (bits != 0) && (bits != 128)) { + yyerror("dest ip bitmask not /128"); + } + $$ = $1.f; + } + ; + +rhdaddr: + addr { $$ = $1; + yyexpectaddr = 0; + } + | hostname '-' hostname { bzero(&$$, sizeof($$)); + $$.t = FRI_RANGE; + if ($1.f != 0 && $3.f != 0 && + $1.f != $3.f) + yyerror("11.address family " + "mismatch"); + $$.a = $1.a; + $$.m = $3.a; + nat->in_flags |= IPN_DIPRANGE; + yyexpectaddr = 0; + } + | IPNY_RANGE hostname '-' hostname + { bzero(&$$, sizeof($$)); + $$.t = FRI_RANGE; + if ($2.f != 0 && $4.f != 0 && + $2.f != $4.f) + yyerror("12.address family " + "mismatch"); + $$.a = $2.a; + $$.m = $4.a; + nat->in_flags |= IPN_DIPRANGE; + yyexpectaddr = 0; + } + ; + +erhdaddr: + rhdaddr { $$ = $1; } + | IPNY_DSTLIST '/' YY_NUMBER { $$.t = FRI_LOOKUP; + $$.u = IPLT_DSTLIST; + $$.s = 0; + $$.n = $3; + } + | IPNY_DSTLIST '/' YY_STR { $$.t = FRI_LOOKUP; + $$.u = IPLT_DSTLIST; + $$.s = 1; + $$.n = addname(&nat, $3); } - | hostname ',' hostname { nat->in_flags |= IPN_SPLIT; - nat->in_inip = $1.s_addr; - nat->in_inmsk = $3.s_addr; } ; port: IPNY_PORT { suggest_port = 1; } @@ -347,27 +726,44 @@ portspec: else $$ = $1; } - | YY_STR { if (getport(NULL, $1, &($$)) == -1) + | YY_STR { if (getport(NULL, $1, + &($$), NULL) == -1) yyerror("invalid port number"); $$ = ntohs($$); } ; -dport: | port portspec { nat->in_pmin = htons($2); - nat->in_pmax = htons($2); } - | port portspec '-' portspec { nat->in_pmin = htons($2); - nat->in_pmax = htons($4); } - | port portspec ':' portspec { nat->in_pmin = htons($2); - nat->in_pmax = htons($4); } +portpair: + portspec { $$.p1 = $1; $$.p2 = $1; } + | portspec '-' portspec { $$.p1 = $1; $$.p2 = $3; } + | portspec ':' portspec { $$.p1 = $1; $$.p2 = $3; } ; -nport: port portspec { nat->in_pnext = htons($2); } - | port '=' portspec { nat->in_pnext = htons($3); +dport: | port portpair { nat->in_odport = $2.p1; + if ($2.p2 == 0) + nat->in_dtop = $2.p1; + else + nat->in_dtop = $2.p2; + } + ; + +nport: | port portpair { nat->in_dpmin = $2.p1; + nat->in_dpnext = $2.p1; + nat->in_dpmax = $2.p2; + nat->in_ndport = $2.p1; + if (nat->in_dtop == 0) + nat->in_dtop = $2.p2; + } + | port '=' portspec { nat->in_dpmin = $3; + nat->in_dpnext = $3; + nat->in_ndport = $3; + if (nat->in_dtop == 0) + nat->in_dtop = nat->in_odport; nat->in_flags |= IPN_FIXEDDPORT; } ; -ports: | IPNY_PORTS YY_NUMBER { nat->in_pmin = $2; } +ports: | IPNY_PORTS YY_NUMBER { nat->in_spmin = $2; } | IPNY_PORTS IPNY_AUTO { nat->in_flags |= IPN_AUTOPORTMAP; } ; @@ -383,128 +779,282 @@ mapblockit: ; mapfrom: - from sobject IPNY_TO dobject - | from sobject '!' IPNY_TO dobject - { nat->in_flags |= IPN_NOTDST; } - | from sobject IPNY_TO '!' dobject - { nat->in_flags |= IPN_NOTDST; } + from sobject to dobject { if ($2 != 0 && $4 != 0 && $2 != $4) + yyerror("13.address family " + "mismatch"); + $$ = $2; + } + | from sobject '!' to dobject + { if ($2 != 0 && $5 != 0 && $2 != $5) + yyerror("14.address family " + "mismatch"); + nat->in_flags |= IPN_NOTDST; + $$ = $2; + } + | from sobject to '!' dobject + { if ($2 != 0 && $5 != 0 && $2 != $5) + yyerror("15.address family " + "mismatch"); + nat->in_flags |= IPN_NOTDST; + $$ = $2; + } ; rdrfrom: - from sobject IPNY_TO dobject - | '!' from sobject IPNY_TO dobject - { nat->in_flags |= IPN_NOTSRC; } - | from '!' sobject IPNY_TO dobject - { nat->in_flags |= IPN_NOTSRC; } + from sobject to dobject { if ($2 != 0 && $4 != 0 && $2 != $4) + yyerror("16.address family " + "mismatch"); + $$ = $2; + } + | '!' from sobject to dobject + { if ($3 != 0 && $5 != 0 && $3 != $5) + yyerror("17.address family " + "mismatch"); + nat->in_flags |= IPN_NOTSRC; + $$ = $3; + } + | from '!' sobject to dobject + { if ($3 != 0 && $5 != 0 && $3 != $5) + yyerror("18.address family " + "mismatch"); + nat->in_flags |= IPN_NOTSRC; + $$ = $3; + } ; -from: IPNY_FROM { nat->in_flags |= IPN_FILTER; } +from: IPNY_FROM { nat->in_flags |= IPN_FILTER; + yyexpectaddr = 1; + } + ; + +to: IPNY_TO { yyexpectaddr = 1; } ; ifnames: - ifname - | ifname ',' otherifname + ifname family { yyexpectaddr = 1; } + | ifname ',' otherifname family { yyexpectaddr = 1; } ; -ifname: YY_STR { strncpy(nat->in_ifnames[0], $1, - sizeof(nat->in_ifnames[0])); - nat->in_ifnames[0][LIFNAMSIZ - 1] = '\0'; - free($1); - } +ifname: YY_STR { setifname(&nat, 0, $1); + free($1); + } + ; + +family: | IPNY_INET { nat->in_v[0] = 4; nat->in_v[1] = 4; } + | IPNY_INET6 { nat->in_v[0] = 6; nat->in_v[1] = 6; } ; otherifname: - YY_STR { strncpy(nat->in_ifnames[1], $1, - sizeof(nat->in_ifnames[1])); - nat->in_ifnames[1][LIFNAMSIZ - 1] = '\0'; - free($1); - } + YY_STR { setifname(&nat, 1, $1); + free($1); + } ; mapport: - IPNY_PORTMAP tcpudp portspec ':' portspec randport - { nat->in_pmin = htons($3); - nat->in_pmax = htons($5); - } - | IPNY_PORTMAP tcpudp IPNY_AUTO randport - { nat->in_flags |= IPN_AUTOPORTMAP; - nat->in_pmin = htons(1024); - nat->in_pmax = htons(65535); - } - | IPNY_ICMPIDMAP YY_STR YY_NUMBER ':' YY_NUMBER - { if (strcmp($2, "icmp") != 0) { + IPNY_PORTMAP tcpudp portpair sequential + { nat->in_spmin = $3.p1; + nat->in_spmax = $3.p2; + } + | IPNY_PORTMAP portpair tcpudp sequential + { nat->in_spmin = $2.p1; + nat->in_spmax = $2.p2; + } + | IPNY_PORTMAP tcpudp IPNY_AUTO sequential + { nat->in_flags |= IPN_AUTOPORTMAP; + nat->in_spmin = 1024; + nat->in_spmax = 65535; + } + | IPNY_ICMPIDMAP YY_STR portpair sequential + { if (strcmp($2, "icmp") != 0 && + strcmp($2, "ipv6-icmp") != 0) { yyerror("icmpidmap not followed by icmp"); } free($2); - if ($3 < 0 || $3 > 65535) + if ($3.p1 < 0 || $3.p1 > 65535) yyerror("invalid ICMP Id number"); - if ($5 < 0 || $5 > 65535) + if ($3.p2 < 0 || $3.p2 > 65535) yyerror("invalid ICMP Id number"); + if (strcmp($2, "ipv6-icmp") == 0) { + nat->in_pr[0] = IPPROTO_ICMPV6; + nat->in_pr[1] = IPPROTO_ICMPV6; + } else { + nat->in_pr[0] = IPPROTO_ICMP; + nat->in_pr[1] = IPPROTO_ICMP; + } nat->in_flags = IPN_ICMPQUERY; - nat->in_pmin = htons($3); - nat->in_pmax = htons($5); + nat->in_spmin = $3.p1; + nat->in_spmax = $3.p2; } ; -randport: - | IPNY_SEQUENTIAL { nat->in_flags |= IPN_SEQUENTIAL; } - ; - sobject: - saddr - | saddr port portstuff { nat->in_sport = $3.p1; + saddr { $$ = $1; } + | saddr port portstuff { nat->in_osport = $3.p1; nat->in_stop = $3.p2; - nat->in_scmp = $3.pc; } + nat->in_scmp = $3.pc; + $$ = $1; + } ; -saddr: addr { if (nat->in_redir == NAT_REDIRECT) { - nat->in_srcip = $1.a.s_addr; - nat->in_srcmsk = $1.m.s_addr; - } else { - nat->in_inip = $1.a.s_addr; - nat->in_inmsk = $1.m.s_addr; - } +saddr: addr { nat->in_osrcatype = $1.t; + bcopy(&$1.a, + &nat->in_osrc.na_addr[0], + sizeof($1.a)); + bcopy(&$1.m, + &nat->in_osrc.na_addr[1], + sizeof($1.m)); + $$ = $1.f; } ; dobject: - daddr - | daddr port portstuff { nat->in_dport = $3.p1; + daddr { $$ = $1; } + | daddr port portstuff { nat->in_odport = $3.p1; nat->in_dtop = $3.p2; nat->in_dcmp = $3.pc; - if (nat->in_redir == NAT_REDIRECT) - nat->in_pmin = htons($3.p1); + $$ = $1; } ; -daddr: addr { if (nat->in_redir == NAT_REDIRECT) { - nat->in_outip = $1.a.s_addr; - nat->in_outmsk = $1.m.s_addr; - } else { - nat->in_srcip = $1.a.s_addr; - nat->in_srcmsk = $1.m.s_addr; +daddr: addr { nat->in_odstatype = $1.t; + bcopy(&$1.a, + &nat->in_odst.na_addr[0], + sizeof($1.a)); + bcopy(&$1.m, + &nat->in_odst.na_addr[1], + sizeof($1.m)); + $$ = $1.f; + } + ; + +addr: IPNY_ANY { yyexpectaddr = 0; + bzero(&$$, sizeof($$)); + $$.t = FRI_NORMAL; + } + | hostname { bzero(&$$, sizeof($$)); + $$.a = $1.a; + $$.t = FRI_NORMAL; + $$.v = ftov($1.f); + $$.f = $1.f; + if ($$.f == AF_INET) { + $$.m.in4.s_addr = 0xffffffff; + } else if ($$.f == AF_INET6) { + $$.m.i6[0] = 0xffffffff; + $$.m.i6[1] = 0xffffffff; + $$.m.i6[2] = 0xffffffff; + $$.m.i6[3] = 0xffffffff; } + yyexpectaddr = 0; + } + | hostname slash YY_NUMBER + { bzero(&$$, sizeof($$)); + $$.a = $1.a; + $$.f = $1.f; + $$.v = ftov($1.f); + $$.t = FRI_NORMAL; + ntomask($$.f, $3, (u_32_t *)&$$.m); + $$.a.i6[0] &= $$.m.i6[0]; + $$.a.i6[1] &= $$.m.i6[1]; + $$.a.i6[2] &= $$.m.i6[2]; + $$.a.i6[3] &= $$.m.i6[3]; + yyexpectaddr = 0; + } + | hostname slash ipaddr { bzero(&$$, sizeof($$)); + if ($1.f != $3.f) { + yyerror("1.address family " + "mismatch"); + } + $$.a = $1.a; + $$.m = $3.a; + $$.t = FRI_NORMAL; + $$.a.i6[0] &= $$.m.i6[0]; + $$.a.i6[1] &= $$.m.i6[1]; + $$.a.i6[2] &= $$.m.i6[2]; + $$.a.i6[3] &= $$.m.i6[3]; + $$.f = $1.f; + $$.v = ftov($1.f); + yyexpectaddr = 0; + } + | hostname slash hexnumber { bzero(&$$, sizeof($$)); + $$.a = $1.a; + $$.m.in4.s_addr = htonl($3); + $$.t = FRI_NORMAL; + $$.a.in4.s_addr &= $$.m.in4.s_addr; + $$.f = $1.f; + $$.v = ftov($1.f); + if ($$.f == AF_INET6) + yyerror("incorrect inet6 mask"); + } + | hostname mask ipaddr { bzero(&$$, sizeof($$)); + if ($1.f != $3.f) { + yyerror("2.address family " + "mismatch"); + } + $$.a = $1.a; + $$.m = $3.a; + $$.t = FRI_NORMAL; + $$.a.i6[0] &= $$.m.i6[0]; + $$.a.i6[1] &= $$.m.i6[1]; + $$.a.i6[2] &= $$.m.i6[2]; + $$.a.i6[3] &= $$.m.i6[3]; + $$.f = $1.f; + $$.v = ftov($1.f); + yyexpectaddr = 0; + } + | hostname mask hexnumber { bzero(&$$, sizeof($$)); + $$.a = $1.a; + $$.m.in4.s_addr = htonl($3); + $$.t = FRI_NORMAL; + $$.a.in4.s_addr &= $$.m.in4.s_addr; + $$.f = AF_INET; + $$.v = 4; + } + | pool slash YY_NUMBER { bzero(&$$, sizeof($$)); + $$.a.iplookupnum = $3; + $$.a.iplookuptype = IPLT_POOL; + $$.a.iplookupsubtype = 0; + $$.t = FRI_LOOKUP; + } + | pool slash YY_STR { bzero(&$$, sizeof($$)); + $$.a.iplookupname = addname(&nat,$3); + $$.a.iplookuptype = IPLT_POOL; + $$.a.iplookupsubtype = 1; + $$.t = FRI_LOOKUP; + } + | hash slash YY_NUMBER { bzero(&$$, sizeof($$)); + $$.a.iplookupnum = $3; + $$.a.iplookuptype = IPLT_HASH; + $$.a.iplookupsubtype = 0; + $$.t = FRI_LOOKUP; + } + | hash slash YY_STR { bzero(&$$, sizeof($$)); + $$.a.iplookupname = addname(&nat,$3); + $$.a.iplookuptype = IPLT_HASH; + $$.a.iplookupsubtype = 1; + $$.t = FRI_LOOKUP; } ; -addr: IPNY_ANY { $$.a.s_addr = 0; $$.m.s_addr = 0; } - | nummask { $$.a = $1.a; $$.m = $1.m; - $$.a.s_addr &= $$.m.s_addr; } - | hostname '/' ipv4 { $$.a = $1; $$.m = $3; - $$.a.s_addr &= $$.m.s_addr; } - | hostname '/' hexnumber { $$.a = $1; $$.m.s_addr = htonl($3); - $$.a.s_addr &= $$.m.s_addr; } - | hostname IPNY_MASK ipv4 { $$.a = $1; $$.m = $3; - $$.a.s_addr &= $$.m.s_addr; } - | hostname IPNY_MASK hexnumber { $$.a = $1; $$.m.s_addr = htonl($3); - $$.a.s_addr &= $$.m.s_addr; } +slash: '/' { yyexpectaddr = 0; } ; -nummask: - hostname { $$.a = $1; - $$.m.s_addr = 0xffffffff; } - | hostname '/' YY_NUMBER { $$.a = $1; - ntomask(4, $3, &$$.m.s_addr); } +mask: IPNY_MASK { yyexpectaddr = 0; } + ; + +pool: IPNY_POOL { if (!(nat->in_flags & IPN_FILTER)) { + yyerror("Can only use pool with from/to rules\n"); + } + yyexpectaddr = 0; + yyresetdict(); + } + ; + +hash: IPNY_HASH { if (!(nat->in_flags & IPN_FILTER)) { + yyerror("Can only use hash with from/to rules\n"); + } + yyexpectaddr = 0; + yyresetdict(); + } ; portstuff: @@ -513,17 +1063,16 @@ portstuff: ; mapoptions: - rr frag age mssclamp nattag setproto + rr frag age mssclamp nattag setproto purge ; rdroptions: - rr frag age sticky mssclamp rdrproxy nattag + rr frag age sticky mssclamp rdrproxy nattag purge ; nattag: | IPNY_TAG YY_STR { strncpy(nat->in_tag.ipt_tag, $2, sizeof(nat->in_tag.ipt_tag)); } - rr: | IPNY_ROUNDROBIN { nat->in_flags |= IPN_ROUNDR; } ; @@ -536,9 +1085,9 @@ age: | IPNY_AGE YY_NUMBER { nat->in_age[0] = $2; nat->in_age[1] = $4; } ; -sticky: | IPNY_STICKY { if (!(nat->in_flags & IPN_ROUNDR) && +sticky: | IPNY_STICKY { if (!(nat->in_flags & IPN_ROUNDR) && !(nat->in_flags & IPN_SPLIT)) { - fprintf(stderr, + FPRINTF(stderr, "'sticky' for use with round-robin/IP splitting only\n"); } else nat->in_flags |= IPN_STICKY; @@ -549,30 +1098,47 @@ mssclamp: | IPNY_MSSCLAMP YY_NUMBER { nat->in_mssclamp = $2; } ; -tcpudp: | IPNY_TCP { setnatproto(IPPROTO_TCP); } +tcpudp: IPNY_TCP { setnatproto(IPPROTO_TCP); } | IPNY_UDP { setnatproto(IPPROTO_UDP); } | IPNY_TCPUDP { nat->in_flags |= IPN_TCPUDP; - nat->in_p = 0; + nat->in_pr[0] = 0; + nat->in_pr[1] = 0; } | IPNY_TCP '/' IPNY_UDP { nat->in_flags |= IPN_TCPUDP; - nat->in_p = 0; + nat->in_pr[0] = 0; + nat->in_pr[1] = 0; } ; +sequential: + | IPNY_SEQUENTIAL { nat->in_flags |= IPN_SEQUENTIAL; } + ; + +purge: + | IPNY_PURGE { nat->in_flags |= IPN_PURGE; } + ; + rdrproxy: IPNY_PROXY YY_STR - { strncpy(nat->in_plabel, $2, - sizeof(nat->in_plabel)); - nat->in_dport = nat->in_pnext; - nat->in_dport = htons(nat->in_dport); + { int pos; + pos = addname(&nat, $2); + nat->in_plabel = pos; + nat->in_odport = nat->in_dpnext; + nat->in_dtop = nat->in_odport; free($2); } - | proxy { if (nat->in_plabel[0] != '\0') { - nat->in_pmin = nat->in_dport; - nat->in_pmax = nat->in_pmin; - nat->in_pnext = nat->in_pmin; - } - } + | proxy { if (nat->in_plabel != -1) { + nat->in_ndport = nat->in_odport; + nat->in_dpmin = nat->in_odport; + nat->in_dpmax = nat->in_dpmin; + nat->in_dtop = nat->in_dpmin; + nat->in_dpnext = nat->in_dpmin; + } + } + ; + +newopts: + | IPNY_PURGE { nat->in_flags |= IPN_PURGE; } ; proto: YY_NUMBER { $$ = $1; @@ -582,7 +1148,10 @@ proto: YY_NUMBER { $$ = $1; } | IPNY_TCP { $$ = IPPROTO_TCP; } | IPNY_UDP { $$ = IPPROTO_UDP; } - | YY_STR { $$ = getproto($1); free($1); + | YY_STR { $$ = getproto($1); + free($1); + if ($$ == -1) + yyerror("unknwon protocol"); if ($$ != IPPROTO_TCP && $$ != IPPROTO_UDP) suggest_port = 0; @@ -594,14 +1163,39 @@ hexnumber: ; hostname: - YY_STR { if (gethost($1, &$$.s_addr) == -1) - fprintf(stderr, + YY_STR { i6addr_t addr; + + bzero(&$$, sizeof($$)); + if (gethost(AF_INET, $1, + &addr) == 0) { + $$.a = addr; + $$.f = AF_INET; + } else + if (gethost(AF_INET6, $1, + &addr) == 0) { + $$.a = addr; + $$.f = AF_INET6; + } else { + FPRINTF(stderr, "Unknown host '%s'\n", $1); + } free($1); } - | YY_NUMBER { $$.s_addr = htonl($1); } - | ipv4 { $$.s_addr = $1.s_addr; } + | YY_NUMBER { bzero(&$$, sizeof($$)); + $$.a.in4.s_addr = htonl($1); + if ($$.a.in4.s_addr != 0) + $$.f = AF_INET; + } + | ipv4 { $$ = $1; } + | YY_IPV6 { bzero(&$$, sizeof($$)); + $$.a = $1; + $$.f = AF_INET6; + } + | YY_NUMBER YY_IPV6 { bzero(&$$, sizeof($$)); + $$.a = $2; + $$.f = AF_INET6; + } ; compare: @@ -619,40 +1213,77 @@ range: | ':' { $$ = FR_INCRANGE; } ; +ipaddr: ipv4 { $$ = $1; } + | YY_IPV6 { $$.a = $1; + $$.f = AF_INET6; + } + ; + ipv4: YY_NUMBER '.' YY_NUMBER '.' YY_NUMBER '.' YY_NUMBER { if ($1 > 255 || $3 > 255 || $5 > 255 || $7 > 255) { yyerror("Invalid octet string for IP address"); return 0; } - $$.s_addr = ($1 << 24) | ($3 << 16) | ($5 << 8) | $7; - $$.s_addr = htonl($$.s_addr); + bzero((char *)&$$, sizeof($$)); + $$.a.in4.s_addr = ($1 << 24) | ($3 << 16) | ($5 << 8) | $7; + $$.a.in4.s_addr = htonl($$.a.in4.s_addr); + $$.f = AF_INET; } ; %% +static wordtab_t proxies[] = { + { "dns", IPNY_DNS } +}; + +static wordtab_t dnswords[] = { + { "allow", IPNY_ALLOW }, + { "block", IPNY_DENY }, + { "deny", IPNY_DENY }, + { "drop", IPNY_DENY }, + { "pass", IPNY_ALLOW }, + +}; + static wordtab_t yywords[] = { { "age", IPNY_AGE }, { "any", IPNY_ANY }, { "auto", IPNY_AUTO }, { "bimap", IPNY_BIMAP }, + { "config", IPNY_CONFIG }, + { "divert", IPNY_DIVERT }, + { "dst", IPNY_DST }, + { "dstlist", IPNY_DSTLIST }, { "frag", IPNY_FRAG }, { "from", IPNY_FROM }, + { "hash", IPNY_HASH }, { "icmpidmap", IPNY_ICMPIDMAP }, + { "in", IPNY_IN }, + { "inet", IPNY_INET }, + { "inet6", IPNY_INET6 }, { "mask", IPNY_MASK }, { "map", IPNY_MAP }, { "map-block", IPNY_MAPBLOCK }, { "mssclamp", IPNY_MSSCLAMP }, { "netmask", IPNY_MASK }, + { "no", IPNY_NO }, + { "on", IPNY_ON }, + { "out", IPNY_OUT }, + { "pool", IPNY_POOL }, { "port", IPNY_PORT }, { "portmap", IPNY_PORTMAP }, { "ports", IPNY_PORTS }, + { "proto", IPNY_PROTO }, { "proxy", IPNY_PROXY }, + { "purge", IPNY_PURGE }, { "range", IPNY_RANGE }, + { "rewrite", IPNY_REWRITE }, { "rdr", IPNY_RDR }, { "round-robin",IPNY_ROUNDROBIN }, { "sequential", IPNY_SEQUENTIAL }, + { "src", IPNY_SRC }, { "sticky", IPNY_STICKY }, { "tag", IPNY_TAG }, { "tcp", IPNY_TCP }, @@ -671,15 +1302,19 @@ static wordtab_t yywords[] = { }; -int ipnat_parsefile(fd, addfunc, ioctlfunc, filename) -int fd; -addfunc_t addfunc; -ioctlfunc_t ioctlfunc; -char *filename; +int +ipnat_parsefile(fd, addfunc, ioctlfunc, filename) + int fd; + addfunc_t addfunc; + ioctlfunc_t ioctlfunc; + char *filename; { FILE *fp = NULL; + int rval; char *s; + yylineNum = 1; + (void) yysettab(yywords); s = getenv("YYDEBUG"); @@ -691,45 +1326,49 @@ char *filename; if (strcmp(filename, "-")) { fp = fopen(filename, "r"); if (!fp) { - fprintf(stderr, "fopen(%s) failed: %s\n", filename, + FPRINTF(stderr, "fopen(%s) failed: %s\n", filename, STRERROR(errno)); return -1; } } else fp = stdin; - while (ipnat_parsesome(fd, addfunc, ioctlfunc, fp) == 1) + while ((rval = ipnat_parsesome(fd, addfunc, ioctlfunc, fp)) == 0) ; if (fp != NULL) fclose(fp); - return 0; + if (rval == -1) + rval = 0; + else if (rval != 0) + rval = 1; + return rval; } -int ipnat_parsesome(fd, addfunc, ioctlfunc, fp) -int fd; -addfunc_t addfunc; -ioctlfunc_t ioctlfunc; -FILE *fp; +int +ipnat_parsesome(fd, addfunc, ioctlfunc, fp) + int fd; + addfunc_t addfunc; + ioctlfunc_t ioctlfunc; + FILE *fp; { char *s; int i; - yylineNum = 1; - natfd = fd; + parser_error = 0; nataddfunc = addfunc; natioctlfunc = ioctlfunc; if (feof(fp)) - return 0; + return -1; i = fgetc(fp); if (i == EOF) - return 0; + return -1; if (ungetc(i, fp) == EOF) - return 0; + return -1; if (feof(fp)) - return 0; + return -1; s = getenv("YYDEBUG"); if (s) yydebug = atoi(s); @@ -738,11 +1377,12 @@ FILE *fp; yyin = fp; yyparse(); - return 1; + return parser_error; } -static void newnatrule() +static void +newnatrule() { ipnat_t *n; @@ -750,21 +1390,32 @@ static void newnatrule() if (n == NULL) return; - if (nat == NULL) + if (nat == NULL) { nattop = nat = n; - else { + n->in_pnext = &nattop; + } else { nat->in_next = n; + n->in_pnext = &nat->in_next; nat = n; } + n->in_flineno = yylineNum; + n->in_ifnames[0] = -1; + n->in_ifnames[1] = -1; + n->in_plabel = -1; + n->in_pconfig = -1; + n->in_size = sizeof(*n); + suggest_port = 0; } -static void setnatproto(p) -int p; +static void +setnatproto(p) + int p; { - nat->in_p = p; + nat->in_pr[0] = p; + nat->in_pr[1] = p; switch (p) { @@ -778,12 +1429,16 @@ int p; break; case IPPROTO_ICMP : nat->in_flags &= ~IPN_TCPUDP; - if (!(nat->in_flags & IPN_ICMPQUERY)) { + if (!(nat->in_flags & IPN_ICMPQUERY) && + !(nat->in_redir & NAT_DIVERTUDP)) { nat->in_dcmp = 0; nat->in_scmp = 0; - nat->in_pmin = 0; - nat->in_pmax = 0; - nat->in_pnext = 0; + nat->in_dpmin = 0; + nat->in_dpmax = 0; + nat->in_dpnext = 0; + nat->in_spmin = 0; + nat->in_spmax = 0; + nat->in_spnext = 0; } break; default : @@ -791,22 +1446,36 @@ int p; nat->in_flags &= ~IPN_TCPUDP; nat->in_dcmp = 0; nat->in_scmp = 0; - nat->in_pmin = 0; - nat->in_pmax = 0; - nat->in_pnext = 0; + nat->in_dpmin = 0; + nat->in_dpmax = 0; + nat->in_dpnext = 0; + nat->in_spmin = 0; + nat->in_spmax = 0; + nat->in_spnext = 0; } break; } + if ((nat->in_flags & (IPN_TCP|IPN_UDP)) == 0) { + nat->in_stop = 0; + nat->in_dtop = 0; + nat->in_osport = 0; + nat->in_odport = 0; + nat->in_stop = 0; + nat->in_osport = 0; + nat->in_dtop = 0; + nat->in_odport = 0; + } if ((nat->in_flags & (IPN_TCPUDP|IPN_FIXEDDPORT)) == IPN_FIXEDDPORT) nat->in_flags &= ~IPN_FIXEDDPORT; } -void ipnat_addrule(fd, ioctlfunc, ptr) -int fd; -ioctlfunc_t ioctlfunc; -void *ptr; +int +ipnat_addrule(fd, ioctlfunc, ptr) + int fd; + ioctlfunc_t ioctlfunc; + void *ptr; { ioctlcmd_t add, del; ipfobj_t obj; @@ -815,20 +1484,19 @@ void *ptr; ipn = ptr; bzero((char *)&obj, sizeof(obj)); obj.ipfo_rev = IPFILTER_VERSION; - obj.ipfo_size = sizeof(ipnat_t); + obj.ipfo_size = ipn->in_size; obj.ipfo_type = IPFOBJ_IPNAT; obj.ipfo_ptr = ptr; - add = 0; - del = 0; if ((opts & OPT_DONOTHING) != 0) fd = -1; if (opts & OPT_ZERORULEST) { add = SIOCZRLST; - } else if (opts & OPT_INACTIVE) { - add = SIOCADNAT; - del = SIOCRMNAT; + del = 0; + } else if (opts & OPT_PURGE) { + add = 0; + del = SIOCPURGENAT; } else { add = SIOCADNAT; del = SIOCRMNAT; @@ -843,37 +1511,269 @@ void *ptr; if ((opts & OPT_ZERORULEST) != 0) { if ((*ioctlfunc)(fd, add, (void *)&obj) == -1) { if ((opts & OPT_DONOTHING) == 0) { - fprintf(stderr, "%d:", yylineNum); - perror("ioctl(SIOCZRLST)"); + char msg[80]; + + sprintf(msg, "%d:ioctl(zero nat rule)", + ipn->in_flineno); + return ipf_perror_fd(fd, ioctlfunc, msg); } } else { -#ifdef USE_QUAD_T -/* - printf("hits %qd bytes %qd ", - (long long)fr->fr_hits, - (long long)fr->fr_bytes); -*/ + PRINTF("hits %lu ", ipn->in_hits); +#ifdef USE_QUAD_T + PRINTF("bytes %"PRIu64" ", + ipn->in_bytes[0] + ipn->in_bytes[1]); #else -/* - printf("hits %ld bytes %ld ", - fr->fr_hits, fr->fr_bytes); -*/ + PRINTF("bytes %lu ", + ipn->in_bytes[0] + ipn->in_bytes[1]); #endif printnat(ipn, opts); } } else if ((opts & OPT_REMOVE) != 0) { if ((*ioctlfunc)(fd, del, (void *)&obj) == -1) { if ((opts & OPT_DONOTHING) == 0) { - fprintf(stderr, "%d:", yylineNum); - perror("ioctl(delete nat rule)"); + char msg[80]; + + sprintf(msg, "%d:ioctl(delete nat rule)", + ipn->in_flineno); + return ipf_perror_fd(fd, ioctlfunc, msg); } } } else { if ((*ioctlfunc)(fd, add, (void *)&obj) == -1) { if ((opts & OPT_DONOTHING) == 0) { - fprintf(stderr, "%d:", yylineNum); - perror("ioctl(add/insert nat rule)"); + char msg[80]; + + sprintf(msg, "%d:ioctl(add/insert nat rule)", + ipn->in_flineno); + if (errno == EEXIST) { + sprintf(msg + strlen(msg), "(line %d)", + ipn->in_flineno); + } + return ipf_perror_fd(fd, ioctlfunc, msg); } } } + return 0; +} + + +static void +setmapifnames() +{ + if (nat->in_ifnames[1] == -1) + nat->in_ifnames[1] = nat->in_ifnames[0]; + + if ((suggest_port == 1) && (nat->in_flags & IPN_TCPUDP) == 0) + nat->in_flags |= IPN_TCPUDP; + + if ((nat->in_flags & IPN_TCPUDP) == 0) + setnatproto(nat->in_pr[1]); + + if (((nat->in_redir & NAT_MAPBLK) != 0) || + ((nat->in_flags & IPN_AUTOPORTMAP) != 0)) + nat_setgroupmap(nat); +} + + +static void +setrdrifnames() +{ + if ((suggest_port == 1) && (nat->in_flags & IPN_TCPUDP) == 0) + nat->in_flags |= IPN_TCPUDP; + + if ((nat->in_pr[0] == 0) && ((nat->in_flags & IPN_TCPUDP) == 0) && + (nat->in_dpmin != 0 || nat->in_dpmax != 0 || nat->in_dpnext != 0)) + setnatproto(IPPROTO_TCP); + + if (nat->in_ifnames[1] == -1) + nat->in_ifnames[1] = nat->in_ifnames[0]; +} + + +static void +proxy_setconfig(proxy) + int proxy; +{ + if (proxy == IPNY_DNS) { + yysetfixeddict(dnswords); + } +} + + +static void +proxy_unsetconfig() +{ + yyresetdict(); +} + + +static namelist_t * +proxy_dns_add_pass(prefix, name) + char *prefix, *name; +{ + namelist_t *n; + + n = calloc(1, sizeof(*n)); + if (n != NULL) { + if (prefix == NULL || *prefix == '\0') { + n->na_name = strdup(name); + } else { + n->na_name = malloc(strlen(name) + strlen(prefix) + 1); + strcpy(n->na_name, prefix); + strcat(n->na_name, name); + } + } + return n; +} + + +static namelist_t * +proxy_dns_add_block(prefix, name) + char *prefix, *name; +{ + namelist_t *n; + + n = calloc(1, sizeof(*n)); + if (n != NULL) { + if (prefix == NULL || *prefix == '\0') { + n->na_name = strdup(name); + } else { + n->na_name = malloc(strlen(name) + strlen(prefix) + 1); + strcpy(n->na_name, prefix); + strcat(n->na_name, name); + } + n->na_value = 1; + } + return n; +} + + +static void +proxy_addconfig(proxy, proto, conf, list) + char *proxy, *conf; + int proto; + namelist_t *list; +{ + proxyrule_t *pr; + + pr = calloc(1, sizeof(*pr)); + if (pr != NULL) { + pr->pr_proto = proto; + pr->pr_proxy = proxy; + pr->pr_conf = conf; + pr->pr_names = list; + pr->pr_next = prules; + prules = pr; + } +} + + +static void +proxy_loadrules(fd, ioctlfunc, rules) + int fd; + ioctlfunc_t ioctlfunc; + proxyrule_t *rules; +{ + proxyrule_t *pr; + + while ((pr = rules) != NULL) { + proxy_loadconfig(fd, ioctlfunc, pr->pr_proxy, pr->pr_proto, + pr->pr_conf, pr->pr_names); + rules = pr->pr_next; + free(pr->pr_conf); + free(pr); + } +} + + +static void +proxy_loadconfig(fd, ioctlfunc, proxy, proto, conf, list) + int fd; + ioctlfunc_t ioctlfunc; + char *proxy, *conf; + int proto; + namelist_t *list; +{ + namelist_t *na; + ipfobj_t obj; + ap_ctl_t pcmd; + + obj.ipfo_rev = IPFILTER_VERSION; + obj.ipfo_type = IPFOBJ_PROXYCTL; + obj.ipfo_size = sizeof(pcmd); + obj.ipfo_ptr = &pcmd; + + while ((na = list) != NULL) { + if ((opts & OPT_REMOVE) != 0) + pcmd.apc_cmd = APC_CMD_DEL; + else + pcmd.apc_cmd = APC_CMD_ADD; + pcmd.apc_dsize = strlen(na->na_name) + 1; + pcmd.apc_data = na->na_name; + pcmd.apc_arg = na->na_value; + pcmd.apc_p = proto; + + strncpy(pcmd.apc_label, proxy, APR_LABELLEN); + pcmd.apc_label[APR_LABELLEN - 1] = '\0'; + + strncpy(pcmd.apc_config, conf, APR_LABELLEN); + pcmd.apc_config[APR_LABELLEN - 1] = '\0'; + + if ((*ioctlfunc)(fd, SIOCPROXY, (void *)&obj) == -1) { + if ((opts & OPT_DONOTHING) == 0) { + char msg[80]; + + sprintf(msg, "%d:ioctl(add/remove proxy rule)", + yylineNum); + ipf_perror_fd(fd, ioctlfunc, msg); + return; + } + } + + list = na->na_next; + free(na->na_name); + free(na); + } +} + + +static void +setifname(np, idx, name) + ipnat_t **np; + int idx; + char *name; +{ + int pos; + + pos = addname(np, name); + if (pos == -1) + return; + (*np)->in_ifnames[idx] = pos; +} + + +static int +addname(np, name) + ipnat_t **np; + char *name; +{ + ipnat_t *n; + int nlen; + int pos; + + nlen = strlen(name) + 1; + n = realloc(*np, (*np)->in_size + nlen); + if (*np == nattop) + nattop = n; + *np = n; + if (n == NULL) + return -1; + if (n->in_pnext != NULL) + *n->in_pnext = n; + n->in_size += nlen; + pos = n->in_namelen; + n->in_namelen += nlen; + strcpy(n->in_names + pos, name); + n->in_names[n->in_namelen] = '\0'; + return pos; } diff --git a/contrib/ipfilter/tools/ippool.c b/contrib/ipfilter/tools/ippool.c index 8b7096050736..49cf7dae63d7 100644 --- a/contrib/ipfilter/tools/ippool.c +++ b/contrib/ipfilter/tools/ippool.c @@ -1,7 +1,7 @@ /* $FreeBSD$ */ /* - * Copyright (C) 2002-2006 by Darren Reed. + * Copyright (C) 2012 by Darren Reed. * * See the IPFILTER.LICENCE file for details on licencing. */ @@ -61,41 +61,48 @@ int poolflush __P((int, char *[])); int poolstats __P((int, char *[])); int gettype __P((char *, u_int *)); int getrole __P((char *)); -int setnodeaddr __P((ip_pool_node_t *node, char *arg)); -void showpools_live __P((int, int, ip_pool_stat_t *, char *)); +int setnodeaddr __P((int, int, void *ptr, char *arg)); +void showpools_live __P((int, int, ipf_pool_stat_t *, char *)); void showhashs_live __P((int, int, iphtstat_t *, char *)); +void showdstls_live __P((int, int, ipf_dstl_stat_t *, char *)); int opts = 0; int fd = -1; int use_inet6 = 0; +wordtab_t *pool_fields = NULL; +int nohdrfields = 0; -void usage(prog) -char *prog; +void +usage(prog) + char *prog; { fprintf(stderr, "Usage:\t%s\n", prog); - fprintf(stderr, "\t\t\t-a [-dnv] [-m ] [-o ] -i [/netmask]\n"); - fprintf(stderr, "\t\t\t-A [-dnv] [-m ] [-o ] [-S ] [-t ]\n"); - fprintf(stderr, "\t\t\t-f [-dnuv]\n"); - fprintf(stderr, "\t\t\t-F [-dv] [-o ] [-t ]\n"); - fprintf(stderr, "\t\t\t-l [-dv] [-m ] [-t ]\n"); - fprintf(stderr, "\t\t\t-r [-dnv] [-m ] [-o ] -i [/netmask]\n"); - fprintf(stderr, "\t\t\t-R [-dnv] [-m ] [-o ] [-t ]\n"); - fprintf(stderr, "\t\t\t-s [-dtv] [-M ] [-N ]\n"); + fprintf(stderr, "\t-a [-dnv] [-m ] [-o ] [-t type] [-T ttl] -i [/netmask]\n"); + fprintf(stderr, "\t-A [-dnv] [-m ] [-o ] [-S ] [-t ]\n"); + fprintf(stderr, "\t-f [-dnuv]\n"); + fprintf(stderr, "\t-F [-dv] [-o ] [-t ]\n"); + fprintf(stderr, "\t-l [-dv] [-m ] [-t ] [-O ]\n"); + fprintf(stderr, "\t-r [-dnv] [-m ] [-o ] [-t type] -i [/netmask]\n"); + fprintf(stderr, "\t-R [-dnv] [-m ] [-o ] [-t ]\n"); + fprintf(stderr, "\t-s [-dtv] [-M ] [-N ]\n"); exit(1); } -int main(argc, argv) -int argc; -char *argv[]; +int +main(argc, argv) + int argc; + char *argv[]; { - int err; + int err = 1; if (argc < 2) usage(argv[0]); - switch (getopt(argc, argv, "aAf:FlrRs")) + assigndefined(getenv("IPPOOL_PREDEFINED")); + + switch (getopt(argc, argv, "aAf:FlnrRsv")) { case 'a' : err = poolnodecommand(0, argc, argv); @@ -112,6 +119,9 @@ char *argv[]; case 'l' : err = poollist(argc, argv); break; + case 'n' : + opts |= OPT_DONOTHING|OPT_DONTOPEN; + break; case 'r' : err = poolnodecommand(1, argc, argv); break; @@ -121,6 +131,9 @@ char *argv[]; case 's' : err = poolstats(argc, argv); break; + case 'v' : + opts |= OPT_VERBOSE; + break; default : exit(1); } @@ -131,19 +144,23 @@ char *argv[]; } -int poolnodecommand(remove, argc, argv) -int remove, argc; -char *argv[]; +int +poolnodecommand(remove, argc, argv) + int remove, argc; + char *argv[]; { - int err, c, ipset, role; + int err = 0, c, ipset, role, type = IPLT_POOL, ttl = 0; char *poolname = NULL; - ip_pool_node_t node; + ip_pool_node_t pnode; + iphtent_t hnode; + void *ptr = &pnode; ipset = 0; role = IPL_LOGIPF; - bzero((char *)&node, sizeof(node)); + bzero((char *)&pnode, sizeof(pnode)); + bzero((char *)&hnode, sizeof(hnode)); - while ((c = getopt(argc, argv, "di:m:no:Rv")) != -1) + while ((c = getopt(argc, argv, "di:m:no:Rt:T:v")) != -1) switch (c) { case 'd' : @@ -151,16 +168,21 @@ char *argv[]; ippool_yydebug++; break; case 'i' : - if (setnodeaddr(&node, optarg) == 0) + if (setnodeaddr(type, role, ptr, optarg) == 0) ipset = 1; break; case 'm' : poolname = optarg; break; case 'n' : - opts |= OPT_DONOTHING; + opts |= OPT_DONOTHING|OPT_DONTOPEN; break; case 'o' : + if (ipset == 1) { + fprintf(stderr, + "cannot set role after ip address\n"); + return -1; + } role = getrole(optarg); if (role == IPL_LOGNONE) return -1; @@ -168,13 +190,39 @@ char *argv[]; case 'R' : opts |= OPT_NORESOLVE; break; + case 't' : + if (ipset == 1) { + fprintf(stderr, + "cannot set type after ip address\n"); + return -1; + } + type = gettype(optarg, NULL); + switch (type) { + case IPLT_NONE : + fprintf(stderr, "unknown type '%s'\n", optarg); + return -1; + case IPLT_HASH : + ptr = &hnode; + break; + case IPLT_POOL : + default : + break; + } + break; + case 'T' : + ttl = atoi(optarg); + if (ttl < 0) { + fprintf(stderr, "cannot set negative ttl\n"); + return -1; + } + break; case 'v' : opts |= OPT_VERBOSE; break; } if (argv[optind] != NULL && ipset == 0) { - if (setnodeaddr(&node, argv[optind]) == 0) + if (setnodeaddr(type, role, ptr, argv[optind]) == 0) ipset = 1; } @@ -191,17 +239,30 @@ char *argv[]; return -1; } - if (remove == 0) - err = load_poolnode(0, poolname, &node, ioctl); - else - err = remove_poolnode(0, poolname, &node, ioctl); + switch (type) { + case IPLT_POOL : + if (remove == 0) + err = load_poolnode(role, poolname, &pnode, ttl, ioctl); + else + err = remove_poolnode(role, poolname, &pnode, ioctl); + break; + case IPLT_HASH : + if (remove == 0) + err = load_hashnode(role, poolname, &hnode, ttl, ioctl); + else + err = remove_hashnode(role, poolname, &hnode, ioctl); + break; + default : + break; + } return err; } -int poolcommand(remove, argc, argv) -int remove, argc; -char *argv[]; +int +poolcommand(remove, argc, argv) + int remove, argc; + char *argv[]; { int type, role, c, err; char *poolname; @@ -216,7 +277,7 @@ char *argv[]; bzero((char *)&iph, sizeof(iph)); bzero((char *)&pool, sizeof(pool)); - while ((c = getopt(argc, argv, "dm:no:RSt:v")) != -1) + while ((c = getopt(argc, argv, "dm:no:RSv")) != -1) switch (c) { case 'd' : @@ -227,7 +288,7 @@ char *argv[]; poolname = optarg; break; case 'n' : - opts |= OPT_DONOTHING; + opts |= OPT_DONOTHING|OPT_DONTOPEN; break; case 'o' : role = getrole(optarg); @@ -242,13 +303,6 @@ char *argv[]; case 'S' : iph.iph_seed = atoi(optarg); break; - case 't' : - type = gettype(optarg, &iph.iph_type); - if (type == IPLT_NONE) { - fprintf(stderr, "unknown type '%s'\n", optarg); - return -1; - } - break; case 'v' : opts |= OPT_VERBOSE; break; @@ -262,6 +316,12 @@ char *argv[]; return -1; } + type = gettype(argv[optind], &iph.iph_type); + if (type == IPLT_NONE) { + fprintf(stderr, "unknown type '%s'\n", argv[optind]); + return -1; + } + if (type == IPLT_HASH) { strncpy(iph.iph_name, poolname, sizeof(iph.iph_name)); iph.iph_name[sizeof(iph.iph_name) - 1] = '\0'; @@ -297,9 +357,10 @@ char *argv[]; } -int loadpoolfile(argc, argv, infile) -int argc; -char *argv[], *infile; +int +loadpoolfile(argc, argv, infile) + int argc; + char *argv[], *infile; { int c; @@ -313,7 +374,7 @@ char *argv[], *infile; ippool_yydebug++; break; case 'n' : - opts |= OPT_DONOTHING; + opts |= OPT_DONOTHING|OPT_DONTOPEN; break; case 'R' : opts |= OPT_NORESOLVE; @@ -329,7 +390,7 @@ char *argv[], *infile; if (opts & OPT_DEBUG) fprintf(stderr, "loadpoolfile: opts = %#x\n", opts); - if (!(opts & OPT_DONOTHING) && (fd == -1)) { + if (!(opts & (OPT_DONOTHING|OPT_DONTOPEN)) && (fd == -1)) { fd = open(IPLOOKUP_NAME, O_RDWR); if (fd == -1) { perror("open(IPLOOKUP_NAME)"); @@ -343,12 +404,14 @@ char *argv[], *infile; } -int poolstats(argc, argv) -int argc; -char *argv[]; +int +poolstats(argc, argv) + int argc; + char *argv[]; { int c, type, role, live_kernel; - ip_pool_stat_t plstat; + ipf_pool_stat_t plstat; + ipf_dstl_stat_t dlstat; char *kernel, *core; iphtstat_t htstat; iplookupop_t op; @@ -398,7 +461,7 @@ char *argv[]; if (opts & OPT_DEBUG) fprintf(stderr, "poolstats: opts = %#x\n", opts); - if (!(opts & OPT_DONOTHING) && (fd == -1)) { + if (!(opts & (OPT_DONOTHING|OPT_DONTOPEN)) && (fd == -1)) { fd = open(IPLOOKUP_NAME, O_RDWR); if (fd == -1) { perror("open(IPLOOKUP_NAME)"); @@ -410,14 +473,14 @@ char *argv[]; op.iplo_type = IPLT_POOL; op.iplo_struct = &plstat; op.iplo_size = sizeof(plstat); - if (!(opts & OPT_DONOTHING)) { + if (!(opts & (OPT_DONOTHING|OPT_DONTOPEN))) { c = ioctl(fd, SIOCLOOKUPSTAT, &op); if (c == -1) { - perror("ioctl(SIOCLOOKUPSTAT)"); + ipferror(fd, "ioctl(S0IOCLOOKUPSTAT)"); return -1; } - printf("Pools:\t%lu\n", plstat.ipls_pools); - printf("Nodes:\t%lu\n", plstat.ipls_nodes); + printf("%lu\taddress pools\n", plstat.ipls_pools); + printf("%lu\taddress pool nodes\n", plstat.ipls_nodes); } } @@ -425,24 +488,49 @@ char *argv[]; op.iplo_type = IPLT_HASH; op.iplo_struct = &htstat; op.iplo_size = sizeof(htstat); - if (!(opts & OPT_DONOTHING)) { + if (!(opts & (OPT_DONOTHING|OPT_DONTOPEN))) { c = ioctl(fd, SIOCLOOKUPSTAT, &op); if (c == -1) { - perror("ioctl(SIOCLOOKUPSTAT)"); + ipferror(fd, "ioctl(SIOCLOOKUPSTAT)"); return -1; } - printf("Hash Tables:\t%lu\n", htstat.iphs_numtables); - printf("Nodes:\t%lu\n", htstat.iphs_numnodes); - printf("Out of Memory:\t%lu\n", htstat.iphs_nomem); + printf("%lu\thash tables\n", htstat.iphs_numtables); + printf("%lu\thash table nodes\n", htstat.iphs_numnodes); + printf("%lu\thash table no memory \n", + htstat.iphs_nomem); + } + } + + if (type == IPLT_ALL || type == IPLT_DSTLIST) { + op.iplo_type = IPLT_DSTLIST; + op.iplo_struct = &dlstat; + op.iplo_size = sizeof(dlstat); + if (!(opts & (OPT_DONOTHING|OPT_DONTOPEN))) { + c = ioctl(fd, SIOCLOOKUPSTAT, &op); + if (c == -1) { + ipferror(fd, "ioctl(SIOCLOOKUPSTAT)"); + return -1; + } + printf("%u\tdestination lists\n", + dlstat.ipls_numlists); + printf("%u\tdestination list nodes\n", + dlstat.ipls_numnodes); + printf("%lu\tdestination list no memory\n", + dlstat.ipls_nomem); + printf("%u\tdestination list zombies\n", + dlstat.ipls_numdereflists); + printf("%u\tdesetination list node zombies\n", + dlstat.ipls_numderefnodes); } } return 0; } -int poolflush(argc, argv) -int argc; -char *argv[]; +int +poolflush(argc, argv) + int argc; + char *argv[]; { int c, role, type, arg; iplookupflush_t flush; @@ -479,7 +567,7 @@ char *argv[]; if (opts & OPT_DEBUG) fprintf(stderr, "poolflush: opts = %#x\n", opts); - if (!(opts & OPT_DONOTHING) && (fd == -1)) { + if (!(opts & (OPT_DONOTHING|OPT_DONTOPEN)) && (fd == -1)) { fd = open(IPLOOKUP_NAME, O_RDWR); if (fd == -1) { perror("open(IPLOOKUP_NAME)"); @@ -492,22 +580,23 @@ char *argv[]; flush.iplf_unit = role; flush.iplf_arg = arg; - if (!(opts & OPT_DONOTHING)) { + if (!(opts & (OPT_DONOTHING|OPT_DONTOPEN))) { if (ioctl(fd, SIOCLOOKUPFLUSH, &flush) == -1) { - perror("ioctl(SIOCLOOKUPFLUSH)"); + ipferror(fd, "ioctl(SIOCLOOKUPFLUSH)"); exit(1); } } - printf("%zd object%s flushed\n", flush.iplf_count, + printf("%u object%s flushed\n", flush.iplf_count, (flush.iplf_count == 1) ? "" : "s"); return 0; } -int getrole(rolename) -char *rolename; +int +getrole(rolename) + char *rolename; { int role; @@ -537,19 +626,20 @@ char *rolename; } -int gettype(typename, minor) -char *typename; -u_int *minor; +int +gettype(typename, minor) + char *typename; + u_int *minor; { int type; - if (!strcasecmp(optarg, "tree") || !strcasecmp(optarg, "pool")) { + if (!strcasecmp(typename, "tree") || !strcasecmp(typename, "pool")) { type = IPLT_POOL; - } else if (!strcasecmp(optarg, "hash")) { + } else if (!strcasecmp(typename, "hash")) { type = IPLT_HASH; if (minor != NULL) *minor = IPHASH_LOOKUP; - } else if (!strcasecmp(optarg, "group-map")) { + } else if (!strcasecmp(typename, "group-map")) { type = IPLT_HASH; if (minor != NULL) *minor = IPHASH_GROUPMAP; @@ -560,9 +650,10 @@ u_int *minor; } -int poollist(argc, argv) -int argc; -char *argv[]; +int +poollist(argc, argv) + int argc; + char *argv[]; { char *kernel, *core, *poolname; int c, role, type, live_kernel; @@ -599,6 +690,9 @@ char *argv[]; return -1; } break; + case 'O' : + pool_fields = parsefields(poolfields, optarg); + break; case 'R' : opts |= OPT_NORESOLVE; break; @@ -617,7 +711,7 @@ char *argv[]; if (opts & OPT_DEBUG) fprintf(stderr, "poollist: opts = %#x\n", opts); - if (!(opts & OPT_DONOTHING) && (fd == -1)) { + if (!(opts & (OPT_DONOTHING|OPT_DONTOPEN)) && (fd == -1)) { fd = open(IPLOOKUP_NAME, O_RDWR); if (fd == -1) { perror("open(IPLOOKUP_NAME)"); @@ -640,9 +734,10 @@ char *argv[]; } -void poollist_dead(role, poolname, type, kernel, core) -int role, type; -char *poolname, *kernel, *core; +void +poollist_dead(role, poolname, type, kernel, core) + int role, type; + char *poolname, *kernel, *core; { iphtable_t *hptr; ip_pool_t *ptr; @@ -665,14 +760,15 @@ char *poolname, *kernel, *core; ptr = pools[role]; while (ptr != NULL) { ptr = printpool(ptr, kmemcpywrap, poolname, - opts); + opts, pool_fields); } } else { for (role = 0; role <= IPL_LOGMAX; role++) { ptr = pools[role]; while (ptr != NULL) { ptr = printpool(ptr, kmemcpywrap, - poolname, opts); + poolname, opts, + pool_fields); } } role = IPL_LOGALL; @@ -693,14 +789,15 @@ char *poolname, *kernel, *core; hptr = tables[role]; while (hptr != NULL) { hptr = printhash(hptr, kmemcpywrap, - poolname, opts); + poolname, opts, pool_fields); } } else { for (role = 0; role <= IPL_LOGMAX; role++) { hptr = tables[role]; while (hptr != NULL) { hptr = printhash(hptr, kmemcpywrap, - poolname, opts); + poolname, opts, + pool_fields); } } } @@ -708,12 +805,12 @@ char *poolname, *kernel, *core; } -void poollist_live(role, poolname, type, fd) -int role, type, fd; -char *poolname; +void +poollist_live(role, poolname, type, fd) + int role, type, fd; + char *poolname; { - ip_pool_stat_t plstat; - iphtstat_t htstat; + ipf_pool_stat_t plstat; iplookupop_t op; int c; @@ -729,18 +826,18 @@ char *poolname; c = ioctl(fd, SIOCLOOKUPSTAT, &op); if (c == -1) { - perror("ioctl(SIOCLOOKUPSTAT)"); + ipferror(fd, "ioctl(SIOCLOOKUPSTAT)"); return; } showpools_live(fd, role, &plstat, poolname); } else { - for (role = 0; role <= IPL_LOGMAX; role++) { + for (role = -1; role <= IPL_LOGMAX; role++) { op.iplo_unit = role; c = ioctl(fd, SIOCLOOKUPSTAT, &op); if (c == -1) { - perror("ioctl(SIOCLOOKUPSTAT)"); + ipferror(fd, "ioctl(SIOCLOOKUPSTAT)"); return; } @@ -752,6 +849,8 @@ char *poolname; } if (type == IPLT_ALL || type == IPLT_HASH) { + iphtstat_t htstat; + op.iplo_type = IPLT_HASH; op.iplo_size = sizeof(htstat); op.iplo_struct = &htstat; @@ -763,7 +862,7 @@ char *poolname; c = ioctl(fd, SIOCLOOKUPSTAT, &op); if (c == -1) { - perror("ioctl(SIOCLOOKUPSTAT)"); + ipferror(fd, "ioctl(SIOCLOOKUPSTAT)"); return; } showhashs_live(fd, role, &htstat, poolname); @@ -773,21 +872,57 @@ char *poolname; op.iplo_unit = role; c = ioctl(fd, SIOCLOOKUPSTAT, &op); if (c == -1) { - perror("ioctl(SIOCLOOKUPSTAT)"); + ipferror(fd, "ioctl(SIOCLOOKUPSTAT)"); return; } showhashs_live(fd, role, &htstat, poolname); } + role = IPL_LOGALL; + } + } + + if (type == IPLT_ALL || type == IPLT_DSTLIST) { + ipf_dstl_stat_t dlstat; + + op.iplo_type = IPLT_DSTLIST; + op.iplo_size = sizeof(dlstat); + op.iplo_struct = &dlstat; + op.iplo_name[0] = '\0'; + op.iplo_arg = 0; + + if (role != IPL_LOGALL) { + op.iplo_unit = role; + + c = ioctl(fd, SIOCLOOKUPSTAT, &op); + if (c == -1) { + ipferror(fd, "ioctl(SIOCLOOKUPSTAT)"); + return; + } + showdstls_live(fd, role, &dlstat, poolname); + } else { + for (role = 0; role <= IPL_LOGMAX; role++) { + + op.iplo_unit = role; + c = ioctl(fd, SIOCLOOKUPSTAT, &op); + if (c == -1) { + ipferror(fd, "ioctl(SIOCLOOKUPSTAT)"); + return; + } + + showdstls_live(fd, role, &dlstat, poolname); + } + role = IPL_LOGALL; } } } -void showpools_live(fd, role, plstp, poolname) -int fd, role; -ip_pool_stat_t *plstp; -char *poolname; +void +showpools_live(fd, role, plstp, poolname) + int fd, role; + ipf_pool_stat_t *plstp; + char *poolname; { ipflookupiter_t iter; ip_pool_t pool; @@ -806,22 +941,27 @@ char *poolname; iter.ili_unit = role; *iter.ili_name = '\0'; - while (plstp->ipls_list[role] != NULL) { + bzero((char *)&pool, sizeof(pool)); + + while (plstp->ipls_list[role + 1] != NULL) { if (ioctl(fd, SIOCLOOKUPITER, &obj)) { - perror("ioctl(SIOCLOOKUPITER)"); + ipferror(fd, "ioctl(SIOCLOOKUPITER)"); break; } - printpool_live(&pool, fd, poolname, opts); + if (((pool.ipo_flags & IPOOL_DELETE) == 0) || + ((opts & OPT_DEBUG) != 0)) + printpool_live(&pool, fd, poolname, opts, pool_fields); - plstp->ipls_list[role] = pool.ipo_next; + plstp->ipls_list[role + 1] = pool.ipo_next; } } -void showhashs_live(fd, role, htstp, poolname) -int fd, role; -iphtstat_t *htstp; -char *poolname; +void +showhashs_live(fd, role, htstp, poolname) + int fd, role; + iphtstat_t *htstp; + char *poolname; { ipflookupiter_t iter; iphtable_t table; @@ -842,18 +982,55 @@ char *poolname; while (htstp->iphs_tables != NULL) { if (ioctl(fd, SIOCLOOKUPITER, &obj)) { - perror("ioctl(SIOCLOOKUPITER)"); + ipferror(fd, "ioctl(SIOCLOOKUPITER)"); break; } - printhash_live(&table, fd, poolname, opts); + printhash_live(&table, fd, poolname, opts, pool_fields); htstp->iphs_tables = table.iph_next; } } -int setnodeaddr(ip_pool_node_t *node, char *arg) +void +showdstls_live(fd, role, dlstp, poolname) + int fd, role; + ipf_dstl_stat_t *dlstp; + char *poolname; +{ + ipflookupiter_t iter; + ippool_dst_t table; + ipfobj_t obj; + + obj.ipfo_rev = IPFILTER_VERSION; + obj.ipfo_type = IPFOBJ_LOOKUPITER; + obj.ipfo_size = sizeof(iter); + obj.ipfo_ptr = &iter; + + iter.ili_type = IPLT_DSTLIST; + iter.ili_otype = IPFLOOKUPITER_LIST; + iter.ili_ival = IPFGENITER_LOOKUP; + iter.ili_nitems = 1; + iter.ili_data = &table; + iter.ili_unit = role; + *iter.ili_name = '\0'; + + while (dlstp->ipls_list[role] != NULL) { + if (ioctl(fd, SIOCLOOKUPITER, &obj)) { + ipferror(fd, "ioctl(SIOCLOOKUPITER)"); + break; + } + + printdstl_live(&table, fd, poolname, opts, pool_fields); + + dlstp->ipls_list[role] = table.ipld_next; + } +} + + +int +setnodeaddr(int type, int role, void *ptr, char *arg) { struct in_addr mask; char *s; @@ -862,17 +1039,38 @@ int setnodeaddr(ip_pool_node_t *node, char *arg) if (s == NULL) mask.s_addr = 0xffffffff; else if (strchr(s, '.') == NULL) { - if (ntomask(4, atoi(s + 1), &mask.s_addr) != 0) + if (ntomask(AF_INET, atoi(s + 1), &mask.s_addr) != 0) return -1; } else { mask.s_addr = inet_addr(s + 1); } if (s != NULL) *s = '\0'; - node->ipn_addr.adf_len = sizeof(node->ipn_addr); - node->ipn_addr.adf_addr.in4.s_addr = inet_addr(arg); - node->ipn_mask.adf_len = sizeof(node->ipn_mask); - node->ipn_mask.adf_addr.in4.s_addr = mask.s_addr; + + if (type == IPLT_POOL) { + ip_pool_node_t *node = ptr; + + if (node->ipn_addr.adf_family == AF_INET) + node->ipn_addr.adf_len = offsetof(addrfamily_t, + adf_addr) + + sizeof(struct in_addr); +#ifdef USE_INET6 + else + node->ipn_addr.adf_len = offsetof(addrfamily_t, + adf_addr) + + sizeof(struct in6_addr); +#endif + node->ipn_addr.adf_addr.in4.s_addr = inet_addr(arg); + node->ipn_mask.adf_len = node->ipn_addr.adf_len; + node->ipn_mask.adf_addr.in4.s_addr = mask.s_addr; + } else if (type == IPLT_HASH) { + iphtent_t *node = ptr; + + node->ipe_addr.in4.s_addr = inet_addr(arg); + node->ipe_mask.in4.s_addr = mask.s_addr; + node->ipe_family = AF_INET; + node->ipe_unit = role; + } return 0; } diff --git a/contrib/ipfilter/tools/ippool_y.y b/contrib/ipfilter/tools/ippool_y.y index 24f683bd1c19..34987452c65b 100644 --- a/contrib/ipfilter/tools/ippool_y.y +++ b/contrib/ipfilter/tools/ippool_y.y @@ -1,7 +1,7 @@ /* $FreeBSD$ */ /* - * Copyright (C) 2001-2006 by Darren Reed. + * Copyright (C) 2012 by Darren Reed. * * See the IPFILTER.LICENCE file for details on licencing. */ @@ -35,6 +35,7 @@ #include "netinet/ip_lookup.h" #include "netinet/ip_pool.h" #include "netinet/ip_htable.h" +#include "netinet/ip_dstlist.h" #include "ippool_l.h" #include "kmem.h" @@ -48,43 +49,52 @@ extern FILE *yyin; static iphtable_t ipht; static iphtent_t iphte; static ip_pool_t iplo; +static ippool_dst_t ipld; static ioctlfunc_t poolioctl = NULL; static char poolname[FR_GROUPLEN]; static iphtent_t *add_htablehosts __P((char *)); static ip_pool_node_t *add_poolhosts __P((char *)); +static ip_pool_node_t *read_whoisfile __P((char *)); +static void setadflen __P((addrfamily_t *)); %} %union { char *str; u_32_t num; - struct in_addr addr; + struct in_addr ip4; struct alist_s *alist; - struct in_addr adrmsk[2]; + addrfamily_t adrmsk[2]; iphtent_t *ipe; ip_pool_node_t *ipp; - union i6addr ip6; + ipf_dstnode_t *ipd; + addrfamily_t ipa; + i6addr_t ip6; } -%token YY_NUMBER YY_HEX -%token YY_STR -%token YY_COMMENT -%token YY_CMP_EQ YY_CMP_NE YY_CMP_LE YY_CMP_GE YY_CMP_LT YY_CMP_GT -%token YY_RANGE_OUT YY_RANGE_IN -%token YY_IPV6 - -%token IPT_IPF IPT_NAT IPT_COUNT IPT_AUTH IPT_IN IPT_OUT -%token IPT_TABLE IPT_GROUPMAP IPT_HASH +%token YY_NUMBER YY_HEX +%token YY_STR +%token YY_IPV6 +%token YY_COMMENT +%token YY_CMP_EQ YY_CMP_NE YY_CMP_LE YY_CMP_GE YY_CMP_LT YY_CMP_GT +%token YY_RANGE_OUT YY_RANGE_IN +%token IPT_IPF IPT_NAT IPT_COUNT IPT_AUTH IPT_IN IPT_OUT IPT_ALL +%token IPT_TABLE IPT_GROUPMAP IPT_HASH IPT_SRCHASH IPT_DSTHASH %token IPT_ROLE IPT_TYPE IPT_TREE -%token IPT_GROUP IPT_SIZE IPT_SEED IPT_NUM IPT_NAME -%type role table inout +%token IPT_GROUP IPT_SIZE IPT_SEED IPT_NUM IPT_NAME IPT_POLICY +%token IPT_POOL IPT_DSTLIST IPT_ROUNDROBIN +%token IPT_WEIGHTED IPT_RANDOM IPT_CONNECTION +%token IPT_WHOIS IPT_FILE +%type role table inout unit dstopts weighting %type ipftree range addrlist %type addrmask %type ipfgroup ipfhash hashlist hashentry %type groupentry setgrouplist grouplist -%type ipaddr mask ipv4 -%type number setgroup +%type ipaddr mask +%type ipv4 +%type number setgroup name +%type dstentry dstentries dstlist %% file: line @@ -93,25 +103,44 @@ file: line | file assign ; -line: table role ipftree eol { iplo.ipo_unit = $2; +line: table role ipftree eol { ip_pool_node_t *n; + iplo.ipo_unit = $2; iplo.ipo_list = $3; load_pool(&iplo, poolioctl); + while ((n = $3) != NULL) { + $3 = n->ipn_next; + free(n); + } resetlexer(); + use_inet6 = 0; } - | table role ipfhash eol { ipht.iph_unit = $2; + | table role ipfhash eol { iphtent_t *h; + ipht.iph_unit = $2; ipht.iph_type = IPHASH_LOOKUP; load_hash(&ipht, $3, poolioctl); + while ((h = $3) != NULL) { + $3 = h->ipe_next; + free(h); + } resetlexer(); + use_inet6 = 0; } | groupmap role number ipfgroup eol - { ipht.iph_unit = $2; + { iphtent_t *h; + ipht.iph_unit = $2; strncpy(ipht.iph_name, $3, sizeof(ipht.iph_name)); ipht.iph_type = IPHASH_GROUPMAP; load_hash(&ipht, $4, poolioctl); + while ((h = $4) != NULL) { + $4 = h->ipe_next; + free(h); + } resetlexer(); + use_inet6 = 0; } | YY_COMMENT + | poolline eol ; eol: ';' @@ -132,6 +161,7 @@ assigning: table: IPT_TABLE { bzero((char *)&ipht, sizeof(ipht)); bzero((char *)&iphte, sizeof(iphte)); bzero((char *)&iplo, sizeof(iplo)); + bzero((char *)&ipld, sizeof(ipld)); *ipht.iph_name = '\0'; iplo.ipo_flags = IPHASH_ANON; iplo.ipo_name[0] = '\0'; @@ -150,11 +180,15 @@ groupmap: inout: IPT_IN { $$ = FR_INQUE; } | IPT_OUT { $$ = FR_OUTQUE; } ; -role: - IPT_ROLE '=' IPT_IPF { $$ = IPL_LOGIPF; } - | IPT_ROLE '=' IPT_NAT { $$ = IPL_LOGNAT; } - | IPT_ROLE '=' IPT_AUTH { $$ = IPL_LOGAUTH; } - | IPT_ROLE '=' IPT_COUNT { $$ = IPL_LOGCOUNT; } + +role: IPT_ROLE '=' unit { $$ = $3; } + ; + +unit: IPT_IPF { $$ = IPL_LOGIPF; } + | IPT_NAT { $$ = IPL_LOGNAT; } + | IPT_AUTH { $$ = IPL_LOGAUTH; } + | IPT_COUNT { $$ = IPL_LOGCOUNT; } + | IPT_ALL { $$ = IPL_LOGALL; } ; ipftree: @@ -183,14 +217,21 @@ ipfgroup: $1, FR_GROUPLEN); $$ = $4; + free($1); } - | hashopts start setgrouplist end { $$ = $3; } + | hashopts start setgrouplist end + { $$ = $3; } ; number: IPT_NUM '=' YY_NUMBER { sprintf(poolname, "%u", $3); $$ = poolname; } - | IPT_NAME '=' YY_STR { $$ = $3; } + | IPT_NAME '=' YY_STR { strncpy(poolname, $3, + FR_GROUPLEN); + poolname[FR_GROUPLEN-1]='\0'; + free($3); + $$ = poolname; + } | { $$ = ""; } ; @@ -198,6 +239,7 @@ setgroup: IPT_GROUP '=' YY_STR { char tmp[FR_GROUPLEN+1]; strncpy(tmp, $3, FR_GROUPLEN); $$ = strdup(tmp); + free($3); } | IPT_GROUP '=' YY_NUMBER { char tmp[FR_GROUPLEN+1]; sprintf(tmp, "%u", $3); @@ -212,119 +254,162 @@ hashopts: ; addrlist: - next { $$ = NULL; } - | range next addrlist { $1->ipn_next = $3; $$ = $1; } + ';' { $$ = NULL; } + | range next addrlist { $$ = $1; + while ($1->ipn_next != NULL) + $1 = $1->ipn_next; + $1->ipn_next = $3; + } | range next { $$ = $1; } ; grouplist: - next { $$ = NULL; } + ';' { $$ = NULL; } | groupentry next grouplist { $$ = $1; $1->ipe_next = $3; } | addrmask next grouplist { $$ = calloc(1, sizeof(iphtent_t)); - bcopy((char *)&($1[0]), - (char *)&($$->ipe_addr), - sizeof($$->ipe_addr)); - bcopy((char *)&($1[1]), - (char *)&($$->ipe_mask), - sizeof($$->ipe_mask)); + $$->ipe_addr = $1[0].adf_addr; + $$->ipe_mask = $1[1].adf_addr; + $$->ipe_family = $1[0].adf_family; $$->ipe_next = $3; } | groupentry next { $$ = $1; } | addrmask next { $$ = calloc(1, sizeof(iphtent_t)); - bcopy((char *)&($1[0]), - (char *)&($$->ipe_addr), - sizeof($$->ipe_addr)); - bcopy((char *)&($1[1]), - (char *)&($$->ipe_mask), - sizeof($$->ipe_mask)); + $$->ipe_addr = $1[0].adf_addr; + $$->ipe_mask = $1[1].adf_addr; +#ifdef AF_INET6 + if (use_inet6) + $$->ipe_family = AF_INET6; + else +#endif + $$->ipe_family = AF_INET; + } + | YY_STR { $$ = add_htablehosts($1); + free($1); } ; setgrouplist: - next { $$ = NULL; } + ';' { $$ = NULL; } | groupentry next { $$ = $1; } | groupentry next setgrouplist { $1->ipe_next = $3; $$ = $1; } ; groupentry: addrmask ',' setgroup { $$ = calloc(1, sizeof(iphtent_t)); - bcopy((char *)&($1[0]), - (char *)&($$->ipe_addr), - sizeof($$->ipe_addr)); - bcopy((char *)&($1[1]), - (char *)&($$->ipe_mask), - sizeof($$->ipe_mask)); + $$->ipe_addr = $1[0].adf_addr; + $$->ipe_mask = $1[1].adf_addr; strncpy($$->ipe_group, $3, FR_GROUPLEN); +#ifdef AF_INET6 + if (use_inet6) + $$->ipe_family = AF_INET6; + else +#endif + $$->ipe_family = AF_INET; free($3); } - | YY_STR { $$ = add_htablehosts($1); } ; -range: addrmask { $$ = calloc(1, sizeof(*$$)); - $$->ipn_info = 0; - $$->ipn_addr.adf_len = sizeof($$->ipn_addr); - $$->ipn_addr.adf_addr.in4.s_addr = $1[0].s_addr; - $$->ipn_mask.adf_len = sizeof($$->ipn_mask); - $$->ipn_mask.adf_addr.in4.s_addr = $1[1].s_addr; - } - | '!' addrmask { $$ = calloc(1, sizeof(*$$)); - $$->ipn_info = 1; - $$->ipn_addr.adf_len = sizeof($$->ipn_addr); - $$->ipn_addr.adf_addr.in4.s_addr = $2[0].s_addr; - $$->ipn_mask.adf_len = sizeof($$->ipn_mask); - $$->ipn_mask.adf_addr.in4.s_addr = $2[1].s_addr; - } - | YY_STR { $$ = add_poolhosts($1); } +range: addrmask { $$ = calloc(1, sizeof(*$$)); + $$->ipn_info = 0; + $$->ipn_addr = $1[0]; + $$->ipn_mask = $1[1]; + } + | '!' addrmask { $$ = calloc(1, sizeof(*$$)); + $$->ipn_info = 1; + $$->ipn_addr = $2[0]; + $$->ipn_mask = $2[1]; + } + | YY_STR { $$ = add_poolhosts($1); + free($1); + } + | IPT_WHOIS IPT_FILE YY_STR { $$ = read_whoisfile($3); + free($3); + } + ; hashlist: - next { $$ = NULL; } + ';' { $$ = NULL; } | hashentry next { $$ = $1; } | hashentry next hashlist { $1->ipe_next = $3; $$ = $1; } ; hashentry: - addrmask { $$ = calloc(1, sizeof(iphtent_t)); - bcopy((char *)&($1[0]), - (char *)&($$->ipe_addr), - sizeof($$->ipe_addr)); - bcopy((char *)&($1[1]), - (char *)&($$->ipe_mask), - sizeof($$->ipe_mask)); - } - | YY_STR { $$ = add_htablehosts($1); } + addrmask { $$ = calloc(1, sizeof(iphtent_t)); + $$->ipe_addr = $1[0].adf_addr; + $$->ipe_mask = $1[1].adf_addr; +#ifdef USE_INET6 + if (use_inet6) + $$->ipe_family = AF_INET6; + else +#endif + $$->ipe_family = AF_INET; + } + | YY_STR { $$ = add_htablehosts($1); + free($1); + } ; addrmask: - ipaddr '/' mask { $$[0] = $1; $$[1].s_addr = $3.s_addr; - yyexpectaddr = 0; + ipaddr '/' mask { $$[0] = $1; + setadflen(&$$[0]); + $$[1] = $3; + $$[1].adf_len = $$[0].adf_len; } - | ipaddr { $$[0] = $1; $$[1].s_addr = 0xffffffff; - yyexpectaddr = 0; + | ipaddr { $$[0] = $1; + setadflen(&$$[1]); + $$[1].adf_len = $$[0].adf_len; +#ifdef USE_INET6 + if (use_inet6) + memset(&$$[1].adf_addr, 0xff, + sizeof($$[1].adf_addr.in6)); + else +#endif + memset(&$$[1].adf_addr, 0xff, + sizeof($$[1].adf_addr.in4)); } ; -ipaddr: ipv4 { $$ = $1; } - | YY_NUMBER { $$.s_addr = htonl($1); } +ipaddr: ipv4 { $$.adf_addr.in4 = $1; + $$.adf_family = AF_INET; + setadflen(&$$); + use_inet6 = 0; + } + | YY_NUMBER { $$.adf_addr.in4.s_addr = htonl($1); + $$.adf_family = AF_INET; + setadflen(&$$); + use_inet6 = 0; + } + | YY_IPV6 { $$.adf_addr = $1; + $$.adf_family = AF_INET6; + setadflen(&$$); + use_inet6 = 1; + } ; -mask: YY_NUMBER { ntomask(4, $1, (u_32_t *)&$$.s_addr); } - | ipv4 { $$ = $1; } +mask: YY_NUMBER { bzero(&$$, sizeof($$)); + if (use_inet6) { + if (ntomask(AF_INET6, $1, + (u_32_t *)&$$.adf_addr) == -1) + yyerror("bad bitmask"); + } else { + if (ntomask(AF_INET, $1, + (u_32_t *)&$$.adf_addr.in4) == -1) + yyerror("bad bitmask"); + } + } + | ipv4 { bzero(&$$, sizeof($$)); + $$.adf_addr.in4 = $1; + } + | YY_IPV6 { bzero(&$$, sizeof($$)); + $$.adf_addr = $1; + } ; -start: '{' { yyexpectaddr = 1; } +size: IPT_SIZE '=' YY_NUMBER { ipht.iph_size = $3; } ; -end: '}' { yyexpectaddr = 0; } - ; - -next: ';' { yyexpectaddr = 1; } - ; - -size: IPT_SIZE '=' YY_NUMBER { ipht.iph_size = $3; } - ; - -seed: IPT_SEED '=' YY_NUMBER { ipht.iph_seed = $3; } +seed: IPT_SEED '=' YY_NUMBER { ipht.iph_seed = $3; } ; ipv4: YY_NUMBER '.' YY_NUMBER '.' YY_NUMBER '.' YY_NUMBER @@ -336,26 +421,180 @@ ipv4: YY_NUMBER '.' YY_NUMBER '.' YY_NUMBER '.' YY_NUMBER $$.s_addr = htonl($$.s_addr); } ; + +next: ';' { yyexpectaddr = 1; } + ; + +start: '{' { yyexpectaddr = 1; } + ; + +end: '}' { yyexpectaddr = 0; } + ; + +poolline: + IPT_POOL unit '/' IPT_DSTLIST '(' name ';' dstopts ')' + start dstlist end + { bzero((char *)&ipld, sizeof(ipld)); + strncpy(ipld.ipld_name, $6, + sizeof(ipld.ipld_name)); + ipld.ipld_unit = $2; + ipld.ipld_policy = $8; + load_dstlist(&ipld, poolioctl, $11); + resetlexer(); + use_inet6 = 0; + free($6); + } + | IPT_POOL unit '/' IPT_TREE '(' name ';' ')' + start addrlist end + { bzero((char *)&iplo, sizeof(iplo)); + strncpy(iplo.ipo_name, $6, + sizeof(iplo.ipo_name)); + iplo.ipo_list = $10; + iplo.ipo_unit = $2; + load_pool(&iplo, poolioctl); + resetlexer(); + use_inet6 = 0; + free($6); + } + | IPT_POOL '(' name ';' ')' start addrlist end + { bzero((char *)&iplo, sizeof(iplo)); + strncpy(iplo.ipo_name, $3, + sizeof(iplo.ipo_name)); + iplo.ipo_list = $7; + iplo.ipo_unit = IPL_LOGALL; + load_pool(&iplo, poolioctl); + resetlexer(); + use_inet6 = 0; + free($3); + } + | IPT_POOL unit '/' IPT_HASH '(' name ';' hashoptlist ')' + start hashlist end + { iphtent_t *h; + bzero((char *)&ipht, sizeof(ipht)); + strncpy(ipht.iph_name, $6, + sizeof(ipht.iph_name)); + ipht.iph_unit = $2; + load_hash(&ipht, $11, poolioctl); + while ((h = ipht.iph_list) != NULL) { + ipht.iph_list = h->ipe_next; + free(h); + } + resetlexer(); + use_inet6 = 0; + free($6); + } + | IPT_GROUPMAP '(' name ';' inout ';' ')' + start setgrouplist end + { iphtent_t *h; + bzero((char *)&ipht, sizeof(ipht)); + strncpy(ipht.iph_name, $3, + sizeof(ipht.iph_name)); + ipht.iph_type = IPHASH_GROUPMAP; + ipht.iph_unit = IPL_LOGIPF; + ipht.iph_flags = $5; + load_hash(&ipht, $9, poolioctl); + while ((h = ipht.iph_list) != NULL) { + ipht.iph_list = h->ipe_next; + free(h); + } + resetlexer(); + use_inet6 = 0; + free($3); + } + ; + +name: IPT_NAME YY_STR { $$ = $2; } + | IPT_NUM YY_NUMBER { char name[80]; + sprintf(name, "%d", $2); + $$ = strdup(name); + } + ; + +hashoptlist: + | hashopt ';' + | hashoptlist ';' hashopt ';' + ; +hashopt: + IPT_SIZE YY_NUMBER + | IPT_SEED YY_NUMBER + ; + +dstlist: + dstentries { $$ = $1; } + | ';' { $$ = NULL; } + ; + +dstentries: + dstentry next { $$ = $1; } + | dstentry next dstentries { $1->ipfd_next = $3; $$ = $1; } + ; + +dstentry: + YY_STR ':' ipaddr { int size = sizeof(*$$) + strlen($1) + 1; + $$ = calloc(1, size); + if ($$ != NULL) { + $$->ipfd_dest.fd_name = strlen($1) + 1; + bcopy($1, $$->ipfd_names, + $$->ipfd_dest.fd_name); + $$->ipfd_dest.fd_addr = $3; + $$->ipfd_size = size; + } + free($1); + } + | ipaddr { $$ = calloc(1, sizeof(*$$)); + if ($$ != NULL) { + $$->ipfd_dest.fd_name = -1; + $$->ipfd_dest.fd_addr = $1; + $$->ipfd_size = sizeof(*$$); + } + } + ; + +dstopts: + { $$ = IPLDP_NONE; } + | IPT_POLICY IPT_ROUNDROBIN ';' { $$ = IPLDP_ROUNDROBIN; } + | IPT_POLICY IPT_WEIGHTED weighting ';' { $$ = $3; } + | IPT_POLICY IPT_RANDOM ';' { $$ = IPLDP_RANDOM; } + | IPT_POLICY IPT_HASH ';' { $$ = IPLDP_HASHED; } + | IPT_POLICY IPT_SRCHASH ';' { $$ = IPLDP_SRCHASH; } + | IPT_POLICY IPT_DSTHASH ';' { $$ = IPLDP_DSTHASH; } + ; + +weighting: + IPT_CONNECTION { $$ = IPLDP_CONNECTION; } + ; %% static wordtab_t yywords[] = { - { "auth", IPT_AUTH }, - { "count", IPT_COUNT }, - { "group", IPT_GROUP }, - { "group-map", IPT_GROUPMAP }, - { "hash", IPT_HASH }, - { "in", IPT_IN }, - { "ipf", IPT_IPF }, - { "name", IPT_NAME }, - { "nat", IPT_NAT }, - { "number", IPT_NUM }, - { "out", IPT_OUT }, - { "role", IPT_ROLE }, - { "seed", IPT_SEED }, - { "size", IPT_SIZE }, - { "table", IPT_TABLE }, - { "tree", IPT_TREE }, - { "type", IPT_TYPE }, - { NULL, 0 } + { "all", IPT_ALL }, + { "auth", IPT_AUTH }, + { "connection", IPT_CONNECTION }, + { "count", IPT_COUNT }, + { "dst-hash", IPT_DSTHASH }, + { "dstlist", IPT_DSTLIST }, + { "file", IPT_FILE }, + { "group", IPT_GROUP }, + { "group-map", IPT_GROUPMAP }, + { "hash", IPT_HASH }, + { "in", IPT_IN }, + { "ipf", IPT_IPF }, + { "name", IPT_NAME }, + { "nat", IPT_NAT }, + { "number", IPT_NUM }, + { "out", IPT_OUT }, + { "policy", IPT_POLICY }, + { "pool", IPT_POOL }, + { "random", IPT_RANDOM }, + { "round-robin", IPT_ROUNDROBIN }, + { "role", IPT_ROLE }, + { "seed", IPT_SEED }, + { "size", IPT_SIZE }, + { "src-hash", IPT_SRCHASH }, + { "table", IPT_TABLE }, + { "tree", IPT_TREE }, + { "type", IPT_TYPE }, + { "weighted", IPT_WEIGHTED }, + { "whois", IPT_WHOIS }, + { NULL, 0 } }; @@ -441,8 +680,9 @@ char *url; if (hlist == NULL) return NULL; - if (gethost(url, &hlist->al_addr) == -1) + if (gethost(hlist->al_family, url, &hlist->al_i6addr) == -1) { yyerror("Unknown hostname"); + } } hbot = NULL; @@ -453,10 +693,9 @@ char *url; if (h == NULL) break; - bcopy((char *)&a->al_addr, (char *)&h->ipe_addr, - sizeof(h->ipe_addr)); - bcopy((char *)&a->al_mask, (char *)&h->ipe_mask, - sizeof(h->ipe_mask)); + h->ipe_family = a->al_family; + h->ipe_addr = a->al_i6addr; + h->ipe_mask = a->al_i6mask; if (hbot != NULL) hbot->ipe_next = h; @@ -487,8 +726,9 @@ char *url; if (hlist == NULL) return NULL; - if (gethost(url, &hlist->al_addr) == -1) + if (gethost(hlist->al_family, url, &hlist->al_i6addr) == -1) { yyerror("Unknown hostname"); + } } pbot = NULL; @@ -498,16 +738,19 @@ char *url; p = calloc(1, sizeof(*p)); if (p == NULL) break; + p->ipn_mask.adf_addr = a->al_i6mask; - p->ipn_addr.adf_len = 8; - p->ipn_mask.adf_len = 8; - + if (a->al_family == AF_INET) { + p->ipn_addr.adf_family = AF_INET; +#ifdef USE_INET6 + } else if (a->al_family == AF_INET6) { + p->ipn_addr.adf_family = AF_INET6; +#endif + } + setadflen(&p->ipn_addr); + p->ipn_addr.adf_addr = a->al_i6addr; p->ipn_info = a->al_not; - - bcopy((char *)&a->al_addr, (char *)&p->ipn_addr.adf_addr, - sizeof(p->ipn_addr.adf_addr)); - bcopy((char *)&a->al_mask, (char *)&p->ipn_mask.adf_addr, - sizeof(p->ipn_mask.adf_addr)); + p->ipn_mask.adf_len = p->ipn_addr.adf_len; if (pbot != NULL) pbot->ipn_next = p; @@ -520,3 +763,59 @@ char *url; return ptop; } + + +ip_pool_node_t * +read_whoisfile(file) + char *file; +{ + ip_pool_node_t *ntop, *ipn, node, *last; + char line[1024]; + FILE *fp; + + fp = fopen(file, "r"); + if (fp == NULL) + return NULL; + + last = NULL; + ntop = NULL; + while (fgets(line, sizeof(line) - 1, fp) != NULL) { + line[sizeof(line) - 1] = '\0'; + + if (parsewhoisline(line, &node.ipn_addr, &node.ipn_mask)) + continue; + ipn = calloc(1, sizeof(*ipn)); + if (ipn == NULL) + continue; + ipn->ipn_addr = node.ipn_addr; + ipn->ipn_mask = node.ipn_mask; + if (last == NULL) + ntop = ipn; + else + last->ipn_next = ipn; + last = ipn; + } + fclose(fp); + return ntop; +} + + +static void +setadflen(afp) + addrfamily_t *afp; +{ + afp->adf_len = offsetof(addrfamily_t, adf_addr); + switch (afp->adf_family) + { + case AF_INET : + afp->adf_len += sizeof(struct in_addr); + break; +#ifdef USE_INET6 + case AF_INET6 : + afp->adf_len += sizeof(struct in6_addr); + break; +#endif + default : + break; + } +} diff --git a/contrib/ipfilter/tools/ipscan_y.y b/contrib/ipfilter/tools/ipscan_y.y index 5dbefd6ab5ae..d323f054bd27 100644 --- a/contrib/ipfilter/tools/ipscan_y.y +++ b/contrib/ipfilter/tools/ipscan_y.y @@ -1,7 +1,7 @@ /* $FreeBSD$ */ /* - * Copyright (C) 2001-2004 by Darren Reed. + * Copyright (C) 2012 by Darren Reed. * * See the IPFILTER.LICENCE file for details on licencing. */ @@ -13,6 +13,7 @@ #include "kmem.h" #include "ipscan_l.h" #include "netinet/ip_scan.h" +#include #define YYDEBUG 1 @@ -60,7 +61,7 @@ int fd = -1; %token YY_NUMBER YY_HEX %token YY_STR -%token YY_COMMENT +%token YY_COMMENT %token YY_CMP_EQ YY_CMP_NE YY_CMP_LE YY_CMP_GE YY_CMP_LT YY_CMP_GT %token YY_RANGE_OUT YY_RANGE_IN %token YY_IPV6 diff --git a/contrib/ipfilter/tools/ipsyncm.c b/contrib/ipfilter/tools/ipsyncm.c index 600d39ad0d6c..41513fae3bcc 100644 --- a/contrib/ipfilter/tools/ipsyncm.c +++ b/contrib/ipfilter/tools/ipsyncm.c @@ -1,13 +1,13 @@ /* $FreeBSD$ */ /* - * Copyright (C) 2001-2006 by Darren Reed. + * Copyright (C) 2012 by Darren Reed. * * See the IPFILTER.LICENCE file for details on licencing. */ #if !defined(lint) static const char sccsid[] = "@(#)ip_fil.c 2.41 6/5/96 (C) 1993-2000 Darren Reed"; -static const char rcsid[] = "@(#)$Id: ipsyncm.c,v 1.4.2.5 2006/08/26 11:21:14 darrenr Exp $"; +static const char rcsid[] = "@(#)$Id$"; #endif #include #include @@ -49,13 +49,13 @@ static void handleterm(int sig) } #endif - + /* should be large enough to hold header + any datatype */ #define BUFFERLEN 1400 int main(argc, argv) -int argc; -char *argv[]; + int argc; + char *argv[]; { struct sockaddr_in sin; char buff[BUFFERLEN]; @@ -66,14 +66,14 @@ char *argv[]; u_32_t magic; synchdr_t *sh; char *progname; - + progname = strrchr(argv[0], '/'); if (progname) { progname++; } else { progname = argv[0]; } - + if (argc < 2) { usage(progname); @@ -108,13 +108,13 @@ char *argv[]; syslog(LOG_ERR, "Opening %s :%m", IPSYNC_NAME); goto tryagain; } - + nfd = socket(AF_INET, SOCK_DGRAM, 0); if (nfd == -1) { syslog(LOG_ERR, "Socket :%m"); goto tryagain; } - + if (connect(nfd, (struct sockaddr *)&sin, sizeof(sin)) == -1) { syslog(LOG_ERR, "Connect: %m"); goto tryagain; @@ -122,15 +122,15 @@ char *argv[]; syslog(LOG_INFO, "Sending data to %s", inet_ntoa(sin.sin_addr)); - - inbuf = 0; + + inbuf = 0; while (1) { n1 = read(lfd, buff+inbuf, BUFFERLEN-inbuf); - + printf("header : %d bytes read (header = %d bytes)\n", - n1, sizeof(*sh)); - + n1, (int) sizeof(*sh)); + if (n1 < 0) { syslog(LOG_ERR, "Read error (header): %m"); goto tryagain; @@ -143,8 +143,8 @@ char *argv[]; sleep(1); continue; } - - inbuf += n1; + + inbuf += n1; moreinbuf: if (inbuf < sizeof(*sh)) { @@ -153,7 +153,7 @@ char *argv[]; sh = (synchdr_t *)buff; len = ntohl(sh->sm_len); - magic = ntohl(sh->sm_magic); + magic = ntohl(sh->sm_magic); if (magic != SYNHDRMAGIC) { syslog(LOG_ERR, @@ -181,8 +181,8 @@ char *argv[]; printf(" table:Unknown(%d)", sh->sm_table); printf(" num:%d\n", (u_32_t)ntohl(sh->sm_num)); -#endif - +#endif + if (inbuf < sizeof(*sh) + len) { continue; /* need more data */ goto tryagain; @@ -195,9 +195,9 @@ char *argv[]; } else if (sh->sm_cmd == SMC_UPDATE) { su = (syncupdent_t *)buff; if (sh->sm_p == IPPROTO_TCP) { - printf(" TCP Update: age %lu state %d/%d\n", + printf(" TCP Update: age %lu state %d/%d\n", su->sup_tcp.stu_age, - su->sup_tcp.stu_state[0], + su->sup_tcp.stu_state[0], su->sup_tcp.stu_state[1]); } } else { @@ -212,7 +212,7 @@ char *argv[]; goto tryagain; } - + if (n3 != n2) { syslog(LOG_ERR, "Incomplete write (%d/%d)", n3, n2); @@ -226,7 +226,7 @@ char *argv[]; /* move buffer to the front,we might need to make * this more efficient, by using a rolling pointer * over the buffer and only copying it, when - * we are reaching the end + * we are reaching the end */ inbuf -= n2; if (inbuf) { diff --git a/contrib/ipfilter/tools/ipsyncs.c b/contrib/ipfilter/tools/ipsyncs.c index 887eeab310c6..43692cd6a0d1 100644 --- a/contrib/ipfilter/tools/ipsyncs.c +++ b/contrib/ipfilter/tools/ipsyncs.c @@ -1,13 +1,13 @@ /* $FreeBSD$ */ /* - * Copyright (C) 2001-2006 by Darren Reed. + * Copyright (C) 2012 by Darren Reed. * * See the IPFILTER.LICENCE file for details on licencing. */ #if !defined(lint) static const char sccsid[] = "@(#)ip_fil.c 2.41 6/5/96 (C) 1993-2000 Darren Reed"; -static const char rcsid[] = "@(#)$Id: ipsyncs.c,v 1.5.2.4 2006/08/26 11:21:15 darrenr Exp $"; +static const char rcsid[] = "@(#)$Id$"; #endif #include #include @@ -54,10 +54,10 @@ static void handleterm(int sig) #define BUFFERLEN 1400 int main(argc, argv) -int argc; -char *argv[]; + int argc; + char *argv[]; { - int nfd = -1 , lfd = -1; + int nfd = -1 , lfd = -1; int n1, n2, n3, magic, len, inbuf; struct sockaddr_in sin; struct sockaddr_in in; @@ -66,14 +66,14 @@ char *argv[]; syncupdent_t *su; synchdr_t *sh; char *progname; - + progname = strrchr(argv[0], '/'); if (progname) { progname++; } else { progname = argv[0]; } - + if (argc < 2) { usage(progname); exit(1); @@ -86,7 +86,7 @@ char *argv[]; #endif openlog(progname, LOG_PID, LOG_SECURITY); - + lfd = open(IPSYNC_NAME, O_WRONLY); if (lfd == -1) { syslog(LOG_ERR, "Opening %s :%m", IPSYNC_NAME); @@ -101,14 +101,14 @@ char *argv[]; sin.sin_port = htons(atoi(argv[2])); else sin.sin_port = htons(43434); - if (argc > 3) + if (argc > 3) in.sin_addr.s_addr = inet_addr(argv[3]); else in.sin_addr.s_addr = 0; in.sin_port = 0; while(1) { - + if (lfd != -1) close(lfd); if (nfd != -1) @@ -119,7 +119,7 @@ char *argv[]; syslog(LOG_ERR, "Opening %s :%m", IPSYNC_NAME); goto tryagain; } - + nfd = socket(AF_INET, SOCK_DGRAM, 0); if (nfd == -1) { syslog(LOG_ERR, "Socket :%m"); @@ -135,20 +135,20 @@ char *argv[]; } syslog(LOG_INFO, "Listening to %s", inet_ntoa(sin.sin_addr)); - - inbuf = 0; + + inbuf = 0; while (1) { - /* + /* * XXX currently we do not check the source address * of a datagram, this can be a security risk */ n1 = read(nfd, buff+inbuf, BUFFERLEN-inbuf); - + printf("header : %d bytes read (header = %d bytes)\n", - n1, sizeof(*sh)); - + n1, (int) sizeof(*sh)); + if (n1 < 0) { syslog(LOG_ERR, "Read error (header): %m"); goto tryagain; @@ -161,8 +161,8 @@ char *argv[]; sleep(1); continue; } - - inbuf += n1; + + inbuf += n1; moreinbuf: if (inbuf < sizeof(*sh)) { @@ -171,7 +171,7 @@ char *argv[]; sh = (synchdr_t *)buff; len = ntohl(sh->sm_len); - magic = ntohl(sh->sm_magic); + magic = ntohl(sh->sm_magic); if (magic != SYNHDRMAGIC) { syslog(LOG_ERR, "Invalid header magic %x", @@ -199,8 +199,8 @@ char *argv[]; printf(" table:Unknown(%d)", sh->sm_table); printf(" num:%d\n", (u_32_t)ntohl(sh->sm_num)); -#endif - +#endif + if (inbuf < sizeof(*sh) + len) { continue; /* need more data */ goto tryagain; @@ -213,9 +213,9 @@ char *argv[]; } else if (sh->sm_cmd == SMC_UPDATE) { su = (syncupdent_t *)buff; if (sh->sm_p == IPPROTO_TCP) { - printf(" TCP Update: age %lu state %d/%d\n", + printf(" TCP Update: age %lu state %d/%d\n", su->sup_tcp.stu_age, - su->sup_tcp.stu_state[0], + su->sup_tcp.stu_state[0], su->sup_tcp.stu_state[1]); } } else { @@ -231,7 +231,7 @@ char *argv[]; goto tryagain; } - + if (n3 != n2) { syslog(LOG_ERR, "%s: Incomplete write (%d/%d)", IPSYNC_NAME, n3, n2); @@ -245,7 +245,7 @@ char *argv[]; /* move buffer to the front,we might need to make * this more efficient, by using a rolling pointer * over the buffer and only copying it, when - * we are reaching the end + * we are reaching the end */ inbuf -= n2; if (inbuf) { diff --git a/contrib/ipfilter/tools/lex_var.h b/contrib/ipfilter/tools/lex_var.h index 78c5efc4263d..eb59f5887cba 100644 --- a/contrib/ipfilter/tools/lex_var.h +++ b/contrib/ipfilter/tools/lex_var.h @@ -1,7 +1,7 @@ /* $FreeBSD$ */ /* - * Copyright (C) 2002 by Darren Reed. + * Copyright (C) 2012 by Darren Reed. * * See the IPFILTER.LICENCE file for details on licencing. */ diff --git a/contrib/ipfilter/tools/lexer.c b/contrib/ipfilter/tools/lexer.c index 989643c966b5..41b7896090ad 100644 --- a/contrib/ipfilter/tools/lexer.c +++ b/contrib/ipfilter/tools/lexer.c @@ -1,7 +1,7 @@ /* $FreeBSD$ */ /* - * Copyright (C) 2002-2006 by Darren Reed. + * Copyright (C) 2012 by Darren Reed. * * See the IPFILTER.LICENCE file for details on licencing. */ @@ -42,6 +42,7 @@ char yychars[YYBUFSIZ+1]; int yylineNum = 1; int yypos = 0; int yylast = -1; +int yydictfixed = 0; int yyexpectaddr = 0; int yybreakondot = 0; int yyvarnext = 0; @@ -60,7 +61,7 @@ static void yystrtotext __P((char *)); static char *yytexttochar __P((void)); static int yygetc(docont) -int docont; + int docont; { int c; @@ -98,7 +99,7 @@ int docont; static void yyunputc(c) -int c; + int c; { if (c == '\n') yylineNum--; @@ -107,7 +108,7 @@ int c; static int yyswallow(last) -int last; + int last; { int c; @@ -134,7 +135,7 @@ static char *yytexttochar() static void yystrtotext(str) -char *str; + char *str; { int len; char *s; @@ -150,7 +151,7 @@ char *str; static char *yytexttostr(offset, max) -int offset, max; + int offset, max; { char *str; int i; @@ -175,8 +176,11 @@ int offset, max; int yylex() { + static int prior = 0; + static int priornum = 0; int c, n, isbuilding, rval, lnext, nokey = 0; char *name; + int triedv6 = 0; isbuilding = 0; lnext = 0; @@ -190,7 +194,8 @@ int yylex() nextchar: c = yygetc(0); if (yydebug > 1) - printf("yygetc = (%x) %c [%*.*s]\n", c, c, yypos, yypos, yytexttochar()); + printf("yygetc = (%x) %c [%*.*s]\n", + c, c, yypos, yypos, yytexttochar()); switch (c) { @@ -209,6 +214,8 @@ int yylex() sizeof(yytext[0]) * (yylast - yypos + 1)); } yylast -= yypos; + if (yyexpectaddr == 2) + yyexpectaddr = 0; yypos = 0; lnext = 0; nokey = 0; @@ -232,6 +239,7 @@ int yylex() if (lnext == 1) { lnext = 0; if ((isbuilding == 0) && !ISALNUM(c)) { + prior = c; return c; } goto nextchar; @@ -246,7 +254,7 @@ int yylex() } yyswallow('\n'); rval = YY_COMMENT; - goto nextchar; + goto done; case '$' : if (isbuilding == 1) { @@ -320,6 +328,9 @@ int yylex() yybreakondot = 0; yyvarnext = 0; yytokentype = 0; + if (yydebug) + fprintf(stderr, "reset at EOF\n"); + prior = 0; return 0; } @@ -344,16 +355,21 @@ int yylex() switch (c) { case '-' : - if (yyexpectaddr) - break; - if (isbuilding == 1) - break; n = yygetc(0); if (n == '>') { isbuilding = 1; goto done; } yyunputc(n); + if (yyexpectaddr) { + if (isbuilding == 1) + yyunputc(c); + else + rval = '-'; + goto done; + } + if (isbuilding == 1) + break; rval = '-'; goto done; @@ -420,14 +436,21 @@ int yylex() * 0000:0000:0000:0000:0000:0000:0000:0000 */ #ifdef USE_INET6 - if (yyexpectaddr == 1 && isbuilding == 0 && (ishex(c) || c == ':')) { + if (yyexpectaddr != 0 && isbuilding == 0 && + (ishex(c) || isdigit(c) || c == ':')) { char ipv6buf[45 + 1], *s, oc; int start; +buildipv6: start = yypos; s = ipv6buf; oc = c; + if (prior == YY_NUMBER && c == ':') { + sprintf(s, "%d", priornum); + s += strlen(s); + } + /* * Perhaps we should implement stricter controls on what we * swallow up here, but surely it would just be duplicating @@ -451,7 +474,25 @@ int yylex() } #endif - if (c == ':') { + if ((c == ':') && (rval != YY_IPV6) && (triedv6 == 0)) { +#ifdef USE_INET6 + yystr = yytexttostr(0, yypos - 1); + if (yystr != NULL) { + char *s; + + for (s = yystr; *s && ishex(*s); s++) + ; + if (!*s && *yystr) { + isbuilding = 0; + c = *yystr; + free(yystr); + triedv6 = 1; + yypos = 1; + goto buildipv6; + } + free(yystr); + } +#endif if (isbuilding == 1) { yyunputc(c); goto done; @@ -492,8 +533,8 @@ int yylex() yystr = yytexttostr(0, yypos); if (yydebug) - printf("isbuilding %d yyvarnext %d nokey %d\n", - isbuilding, yyvarnext, nokey); + printf("isbuilding %d yyvarnext %d nokey %d fixed %d addr %d\n", + isbuilding, yyvarnext, nokey, yydictfixed, yyexpectaddr); if (isbuilding == 1) { wordtab_t *w; @@ -502,7 +543,7 @@ int yylex() if ((yyvarnext == 0) && (nokey == 0)) { w = yyfindkey(yystr); - if (w == NULL && yywordtab != NULL) { + if (w == NULL && yywordtab != NULL && !yydictfixed) { yyresetdict(); w = yyfindkey(yystr); } @@ -514,14 +555,19 @@ int yylex() rval = YY_STR; } - if (rval == YY_STR && yysavedepth > 0) - yyresetdict(); + if (rval == YY_STR) { + if (yysavedepth > 0 && !yydictfixed) + yyresetdict(); + if (yyexpectaddr != 0) + yyexpectaddr = 0; + } yytokentype = rval; if (yydebug) - printf("lexed(%s) [%d,%d,%d] => %d @%d\n", yystr, string_start, - string_end, pos, rval, yysavedepth); + printf("lexed(%s) %d,%d,%d [%d,%d,%d] => %d @%d\n", + yystr, isbuilding, yyexpectaddr, yysavedepth, + string_start, string_end, pos, rval, yysavedepth); switch (rval) { @@ -548,12 +594,15 @@ int yylex() yypos = 0; } + if (rval == YY_NUMBER) + priornum = yylval.num; + prior = rval; return rval; } static wordtab_t *yyfindkey(key) -char *key; + char *key; { wordtab_t *w; @@ -568,7 +617,7 @@ char *key; char *yykeytostr(num) -int num; + int num; { wordtab_t *w; @@ -583,7 +632,7 @@ int num; wordtab_t *yysettab(words) -wordtab_t *words; + wordtab_t *words; { wordtab_t *save; @@ -594,7 +643,7 @@ wordtab_t *words; void yyerror(msg) -char *msg; + char *msg; { char *txt, letter[2]; int freetxt = 0; @@ -620,9 +669,31 @@ char *msg; } -void yysetdict(newdict) -wordtab_t *newdict; +void yysetfixeddict(newdict) + wordtab_t *newdict; { + if (yydebug) + printf("yysetfixeddict(%lx)\n", (u_long)newdict); + + if (yysavedepth == sizeof(yysavewords)/sizeof(yysavewords[0])) { + fprintf(stderr, "%d: at maximum dictionary depth\n", + yylineNum); + return; + } + + yysavewords[yysavedepth++] = yysettab(newdict); + if (yydebug) + printf("yysavedepth++ => %d\n", yysavedepth); + yydictfixed = 1; +} + + +void yysetdict(newdict) + wordtab_t *newdict; +{ + if (yydebug) + printf("yysetdict(%lx)\n", (u_long)newdict); + if (yysavedepth == sizeof(yysavewords)/sizeof(yysavewords[0])) { fprintf(stderr, "%d: at maximum dictionary depth\n", yylineNum); @@ -643,14 +714,15 @@ void yyresetdict() if (yydebug) printf("yysavedepth-- => %d\n", yysavedepth); } + yydictfixed = 0; } #ifdef TEST_LEXER int main(argc, argv) -int argc; -char *argv[]; + int argc; + char *argv[]; { int n; diff --git a/contrib/ipfilter/tools/lexer.h b/contrib/ipfilter/tools/lexer.h index d973ea42ae35..cff24b4eb402 100644 --- a/contrib/ipfilter/tools/lexer.h +++ b/contrib/ipfilter/tools/lexer.h @@ -1,16 +1,11 @@ /* $FreeBSD$ */ /* - * Copyright (C) 2002-2004 by Darren Reed. + * Copyright (C) 2012 by Darren Reed. * * See the IPFILTER.LICENCE file for details on licencing. */ -typedef struct wordtab { - char *w_word; - int w_value; -} wordtab_t; - #ifdef NO_YACC #define YY_COMMENT 1000 #define YY_CMP_NE 1001 @@ -29,6 +24,7 @@ typedef struct wordtab { extern wordtab_t *yysettab __P((wordtab_t *)); extern void yysetdict __P((wordtab_t *)); +extern void yysetfixeddict __P((wordtab_t *)); extern int yylex __P((void)); extern void yyerror __P((char *)); extern char *yykeytostr __P((int)); diff --git a/contrib/ldns-host/Makefile b/contrib/ldns-host/Makefile new file mode 100644 index 000000000000..9d07a581fddc --- /dev/null +++ b/contrib/ldns-host/Makefile @@ -0,0 +1,23 @@ +PROG=ldns-host +SRC=ldns-host.c +MAN=ldns-host.1 + +LOCALBASE?=/usr/local +PREFIX?=${LOCALBASE} +MANDIR?=${PREFIX}/man + +XCFLAGS=${CFLAGS} -I${LOCALBASE}/include +XLDFLAGS=${LDFLAGS} -L${LOCALBASE}/lib -lldns + +${PROG}: ${SRC} + ${CC} -o $@ ${XCFLAGS} ${XLDFLAGS} ${SRC} + +clean: + rm -f ${PROG} + +install: ${PROG} + cp ${PROG} ${PREFIX}/bin/ + cp ${MAN} ${MANDIR}/man1/ + +deinstall: + rm -f ${PREFIX}/bin/${PROG} ${MANDIR}/man1/${MAN} diff --git a/contrib/ldns-host/ldns-host.1 b/contrib/ldns-host/ldns-host.1 new file mode 100644 index 000000000000..3a85ac41001f --- /dev/null +++ b/contrib/ldns-host/ldns-host.1 @@ -0,0 +1,246 @@ +.\" (c) Magerya Vitaly +.\" +.\" Copying and distribution of this file, with or without modification, +.\" are permitted in any medium without royalty provided the copyright +.\" notice and this notice are preserved. This file is offered as-is, +.\" without any warranty. +.Dd Aug 27, 2012 +.Dt LDNS-HOST 1 +.Os +.Sh NAME +.Nm ldns-host +.Nd DNS lookup utility +.Sh SYNOPSIS +.Nm +.Op Fl aCdilrsTvw46 +.Op Fl c Ar class +.Op Fl N Ar ndots +.Op Fl R Ar number +.Op Fl t Ar type +.Op Fl W Ar wait +.Ar name +.Op Ar server +.Sh DESCRIPTION +.Nm +is a simple utility for performing DNS lookups. It is normally +used to convert names to IP addresses and vice versa. +.Pp +.Ar name +is the domain name that is to be looked up. It can also be a +dotted-decimal IPv4 address or a colon-delimited IPv6 address, +in which case +.Nm +will by default perform a reverse lookup for that address. +.Pp +When +.Ar name +is not provided, +.Nm +prints a short summary of it's usage. +.Pp +.Ar server +is an optional argument which is either a domain name or an IP +address of the name server that +.Nm +should query instead of the server or servers listed in +.Pa /etc/resolv.conf . +When +.Ar server +is a domain name, system resolver is used to obtain it's address. +.Pp +Supported options: +.Bl -tag -width indent +.It Fl a +Make a verbose query of type +.Cm ANY . +Equivalent to +.Fl v Fl t Cm ANY . +.It Fl C +Query for +.Cm SOA +records for zone +.Ar name +from all of it's authoritative name servers. The list of name +servers is obtained via +.Cm NS +query for +.Ar name . +.It Fl c Ar class +Perform DNS query of class +.Ar class . +Recognized classes are +.Cm IN Pq Internet , +.Cm CH Pq Chaosnet , +.Cm HS Pq Hesiod , +.Cm NONE , +.Cm ANY +and +.Cm CLASS Ns Ar N +(where +.Ar N +is a number from 1 to 255). Default is +.Cm IN . +.It Fl d +Produce verbose output. This is a synonym for +.Fl v , +and is provided for backward compatibility. +.It Fl i +Use IP6.INT domain for reverse lookups of IPv6 addresses (as +defined in RFC1886; note that RFC4159 deprecates IP6.INT). +By default IP6.ARPA is used. +.It Fl l +List all +.Cm NS, PTR, A +and +.Cm AAAA +records in zone +.Ar name +by performing a zone transfer +.Pq Cm AXFR . +You can combine this option with +.Fl a +to print all records, or with +.Fl t +to only print specific ones. +.It Fl N Ar ndots +Consider names with at least this many dots as absolute. That +is, try to resolve them directly before consulting +.Ic domain +or +.Ic search +options from +.Pa /etc/resolv.conf . +.It Fl r +Perform non-recursive query to the name server by clearing RD +.Pq Dq recursion desired +bit of the query. +.It Fl R Ar number +Retry this many times when a query does not receive an answer +in time. The default is 1 retry. If +.Ar number +is negative or zero, 1 is used instead. +.It Fl s +Report SERVFAIL responses as they are, do not ignore them. +.It Fl T +Query name server over TCP. By default UDP is used, except for +.Cm AXFR +and +.Cm IXFR +queries, which require TCP. +.Nm +will also retry UDP queries in TCP mode if the UDP response was +truncated (i.e. had TC bit set). +.It Fl t Ar type +Perform DNS query of type +.Ar type , +which can be any standard query type name +.Pq Cm A , CNAME , MX , TXT , No etc , +a wildcard query +.Pq Cm ANY , +or +.Cm TYPE Ns Ar N , +where +.Ar N +is a number from 1 to 65535. For +.Cm IXFR Pq incremental zone transfer +queries the starting serial number can be specified by appending +an equal sign followed by the number +.Pq e.g. Fl t Cm IXFR Ns =12345678 . +.Pp +The default is to query for +.Cm A , AAAA , No and Cm MX +records, unless +.Fl C +or +.Fl l +options are given (in which case +.Cm SOA +or +.Cm AXFR +queries are made) or +.Ar name +is a valid IP address +(in which case reverse lookup using +.Cm PTR +query is performed). +.It Fl v +Produce verbose output. +.It Fl w +Wait forever (or for a very long time) for response from the +name server. +.It Fl W Ar wait +Wait this many seconds for a reply from name server before timing +out. If +.Ar wait +is negative or zero, value of 1 is used. The default is to wait +10 seconds for TCP connections, and 5 seconds for UDP (both are +subject to retries, see option +.Fl R ) . +.It Fl 4 +Only use IPv4 transport. +.It Fl 6 +Only use IPv6 transport. +.El +.Sh FILES +.Pa /etc/resolv.conf +.Sh SEE ALSO +.Xr drill 1 , +.Xr resolv.conf 5 +.Sh COMPATIBILITY +.Nm +aims to be reasonably compatible with +.Sq host +utility from BIND9 distribution, both in supported options and +in produced output. Here is a list of known notable differences: +.Bl -bullet +.It +Debugging options +.Pq Fl D No and Fl m +are not supported. +.It +Query class +.Cm CLASS0 +and type +.Cm TYPE0 +are not supported. +.It +Backslashes in domain names are treated especially. +.It +The maximum of 255 retries (option +.Fl R ) +are supported. +.It +Some resource records are formatted differently. For example, +.Cm RRSIG +and +.Cm DNSKEY +records are displayed without spaces in them. +.It +When parsing +.Pa /etc/resolv.conf +commands +.Ic sortlist +and +.Ic options +are ignored. When multiple +.Ic search +and/or +.Ic domain +commands are present, +.Nm +first uses the last +.Ic domain +command, and then all of +.Ic search +commands, while +.Sq host +from BIND9 uses whatever command was specified last. +.It +Multi-packet zone transfers are not supported; only the first +response packet is printed. +.It +.Sq Pseudosection TSIG +is missing from verbose packet output. +.El +.Sh AUTHORS +.An Vitaly Magerya Aq magv@tx97.net diff --git a/contrib/ldns-host/ldns-host.c b/contrib/ldns-host/ldns-host.c new file mode 100644 index 000000000000..85c7dcbe2e41 --- /dev/null +++ b/contrib/ldns-host/ldns-host.c @@ -0,0 +1,884 @@ +/*- + * (c) Magerya Vitaly + * + * Copying and distribution of this file, with or without modification, + * are permitted in any medium without royalty provided the copyright + * notice and this notice are preserved. This file is offered as-is, + * without any warranty. + */ + +#include + +#include +#include +#include +#include +#include + +#include + +/* General utilities. + */ + +static char *progname; + +#define countof(array) (sizeof(array)/sizeof(*(array))) + +static void +die(int code, const char *fmt, ...) { + va_list args; + + va_start(args, fmt); + fprintf(stderr, "%s: ", progname); + vfprintf(stderr, fmt, args); + fprintf(stderr, "\n"); + va_end(args); + exit(code); +} + +static int +ndots(const char *name) { + int n; + + for (n = 0; (name = strchr(name, '.')); n++, name++); + return n; +} + +/* General LDNS-specific utilities. + */ + +static ldns_status +ldns_resolver_new_default(ldns_resolver **res) { + if (ldns_resolver_new_frm_file(res, NULL) == LDNS_STATUS_OK || + (*res = ldns_resolver_new()) != NULL) + return LDNS_STATUS_OK; + return LDNS_STATUS_MEM_ERR; +} + +static ldns_status +ldns_resolver_push_default_servers(ldns_resolver *res) { + ldns_status status; + ldns_rdf *addr; + + if ((status = ldns_str2rdf_a(&addr, "127.0.0.1")) != LDNS_STATUS_OK || + (status = ldns_resolver_push_nameserver(res, addr)) != LDNS_STATUS_OK) + return ldns_rdf_deep_free(addr), status; + ldns_rdf_deep_free(addr); + if ((status = ldns_str2rdf_aaaa(&addr, "::1")) != LDNS_STATUS_OK || + (status = ldns_resolver_push_nameserver(res, addr)) != LDNS_STATUS_OK) + return ldns_rdf_deep_free(addr), status; + ldns_rdf_deep_free(addr); + return LDNS_STATUS_OK; +} + +static ldns_rdf * +ldns_rdf_new_addr_frm_str(const char *str) { + ldns_rdf *addr; + + if ((addr = ldns_rdf_new_frm_str(LDNS_RDF_TYPE_A, str)) == NULL) + addr = ldns_rdf_new_frm_str(LDNS_RDF_TYPE_AAAA, str); + return addr; +} + +static void +ldns_resolver_remove_nameservers(ldns_resolver *res) { + while (ldns_resolver_nameserver_count(res) > 0) + ldns_rdf_deep_free(ldns_resolver_pop_nameserver(res)); +} + +static ldns_rdf * +ldns_rdf_reverse_a(ldns_rdf *addr, const char *base) { + char *buf; + int i, len; + + len = strlen(base); + buf = alloca(LDNS_IP4ADDRLEN*4 + len + 1); + for (len = i = 0; i < LDNS_IP4ADDRLEN; i++) + len += sprintf(&buf[len], "%d.", + (int)ldns_rdf_data(addr)[LDNS_IP4ADDRLEN - i - 1]); + sprintf(&buf[len], "%s", base); + return ldns_dname_new_frm_str(buf); +} + +static ldns_rdf * +ldns_rdf_reverse_aaaa(ldns_rdf *addr, const char *base) { + char *buf; + int i, len; + + len = strlen(base); + buf = alloca(LDNS_IP6ADDRLEN*4 + len + 1); + for (i = 0; i < LDNS_IP6ADDRLEN; i++) { + uint8_t byte = ldns_rdf_data(addr)[LDNS_IP6ADDRLEN - i - 1]; + sprintf(&buf[i*4], "%x.%x.", byte & 0x0F, byte >> 4); + } + sprintf(&buf[LDNS_IP6ADDRLEN*4], "%s", base); + return ldns_dname_new_frm_str(buf); +} + +static ldns_status +ldns_pkt_push_rr_soa(ldns_pkt *pkt, ldns_pkt_section sec, + const ldns_rdf *name, ldns_rr_class c, uint32_t serial) { + ldns_rdf *rdf; + ldns_rr *rr; + uint32_t n; + + if ((rr = ldns_rr_new_frm_type(LDNS_RR_TYPE_SOA)) == NULL) + return LDNS_STATUS_MEM_ERR; + ldns_rr_set_class(rr, c); + ldns_rr_set_owner(rr, ldns_rdf_clone(name)); + ldns_rr_set_ttl(rr, 0); + + n = 0; + if ((rdf = ldns_rdf_new_frm_data(LDNS_RDF_TYPE_DNAME, 1, &n)) == NULL) + goto memerr; + ldns_rr_set_rdf(rr, rdf, 0); + ldns_rr_set_rdf(rr, ldns_rdf_clone(rdf), 1); + + n = htonl(serial); + if ((rdf = ldns_rdf_new_frm_data(LDNS_RDF_TYPE_INT32, 4, &n)) == NULL) + goto memerr; + ldns_rr_set_rdf(rr, rdf, 2); + + n = 0; + if ((rdf = ldns_rdf_new_frm_data(LDNS_RDF_TYPE_PERIOD, 4, &n)) == NULL) + goto memerr; + ldns_rr_set_rdf(rr, rdf, 3); + ldns_rr_set_rdf(rr, ldns_rdf_clone(rdf), 4); + ldns_rr_set_rdf(rr, ldns_rdf_clone(rdf), 5); + ldns_rr_set_rdf(rr, ldns_rdf_clone(rdf), 6); + + if (ldns_rr_rdf(rr, 1) == NULL || ldns_rr_rdf(rr, 4) == NULL || + ldns_rr_rdf(rr, 5) == NULL || ldns_rr_rdf(rr, 6) == NULL || + !ldns_pkt_push_rr(pkt, sec, rr)) + goto memerr; + return LDNS_STATUS_OK; + +memerr: + ldns_rr_free(rr); + return LDNS_STATUS_MEM_ERR; +} + +static ldns_status +ldns_resolver_send_to(ldns_pkt **answer, ldns_resolver *res, + const ldns_rdf *name, ldns_rr_type t, ldns_rr_class c, + uint16_t flags, uint32_t ixfr_serial, int nameserver) { + ldns_status status; + ldns_pkt *qpkt; + + int nscnt = ldns_resolver_nameserver_count(res); + ldns_rdf **ns = ldns_resolver_nameservers(res); + size_t *rtt = ldns_resolver_rtt(res); + + ldns_resolver_set_nameservers(res, &ns[nameserver]); + ldns_resolver_set_rtt(res, &rtt[nameserver]); + ldns_resolver_set_nameserver_count(res, 1); + + status = ldns_resolver_prepare_query_pkt(&qpkt, res, name, t, c, flags); + if (status == LDNS_STATUS_OK && t == LDNS_RR_TYPE_IXFR) + status = ldns_pkt_push_rr_soa(qpkt, + LDNS_SECTION_AUTHORITY, name, c, ixfr_serial); + if (status == LDNS_STATUS_OK) + status = ldns_resolver_send_pkt(answer, res, qpkt); + ldns_pkt_free(qpkt); + + ldns_resolver_set_nameservers(res, ns); + ldns_resolver_set_rtt(res, rtt); + ldns_resolver_set_nameserver_count(res, nscnt); + return status; +} + +static void +ldns_pkt_filter_answer(ldns_pkt *pkt, ldns_rr_type type) { + int i, j, cnt; + ldns_rr_list *rrlist; + ldns_rr *rr; + ldns_rr_type rrtype; + + rrlist = ldns_pkt_answer(pkt); + cnt = ldns_rr_list_rr_count(rrlist); + for (i = j = 0; i < cnt; i++) { + rr = ldns_rr_list_rr(rrlist, i); + rrtype = ldns_rr_get_type(rr); + if (type == LDNS_RR_TYPE_ANY || + type == rrtype || + (type == LDNS_RR_TYPE_AXFR && + (rrtype == LDNS_RR_TYPE_A || + rrtype == LDNS_RR_TYPE_AAAA || + rrtype == LDNS_RR_TYPE_NS || + rrtype == LDNS_RR_TYPE_PTR))) + ldns_rr_list_set_rr(rrlist, rr, j++); + } + ldns_rr_list_set_rr_count(rrlist, j); +} + +/* Packet content printing. + */ + +static struct { + ldns_rr_type type; + const char *text; +} rr_types[] = { + {LDNS_RR_TYPE_A, "has address"}, + {LDNS_RR_TYPE_NS, "name server"}, + {LDNS_RR_TYPE_CNAME, "is an alias for"}, + {LDNS_RR_TYPE_WKS, "has well known services"}, + {LDNS_RR_TYPE_PTR, "domain name pointer"}, + {LDNS_RR_TYPE_HINFO, "host information"}, + {LDNS_RR_TYPE_MX, "mail is handled by"}, + {LDNS_RR_TYPE_TXT, "descriptive text"}, + {LDNS_RR_TYPE_X25, "x25 address"}, + {LDNS_RR_TYPE_ISDN, "ISDN address"}, + {LDNS_RR_TYPE_SIG, "has signature"}, + {LDNS_RR_TYPE_KEY, "has key"}, + {LDNS_RR_TYPE_AAAA, "has IPv6 address"}, + {LDNS_RR_TYPE_LOC, "location"}, +}; + +static void +print_opcode(ldns_pkt_opcode opcode) { + ldns_lookup_table *lt = ldns_lookup_by_id(ldns_opcodes, opcode); + + if (lt && lt->name) + printf("%s", lt->name); + else + printf("RESERVED%d", opcode); +} + +static void +print_rcode(uint8_t rcode) { + ldns_lookup_table *lt = ldns_lookup_by_id(ldns_rcodes, rcode); + + if (lt && lt->name) + printf("%s", lt->name); + else + printf("RESERVED%d", rcode); +} + +static int +print_rr_type(ldns_rr_type type) { + char *str; + int n; + + str = ldns_rr_type2str(type); + n = printf("%s", str); + free(str); + return n; +} + +static int +print_rr_class(ldns_rr_class cls) { + char *str; + int n; + + str = ldns_rr_class2str(cls); + n = printf("%s", str); + free(str); + return n; +} + +static int +print_rdf(ldns_rdf *rdf) { + char *str; + int n; + + str = ldns_rdf2str(rdf); + n = printf("%s", str); + free(str); + return n; +} + +static int +print_rdf_nodot(ldns_rdf *rdf) { + char *str; + int len, n; + + str = ldns_rdf2str(rdf); + len = strlen(str); + n = printf("%.*s", str[len-1] == '.' ? len-1 : len, str); + free(str); + return n; +} + +static int +print_padding(int fromcol, int tocol) { + int col = fromcol, nextcol = fromcol + 8 - fromcol%8; + + if (fromcol + 1 > tocol) tocol = fromcol + 1; + for (; nextcol <= tocol; col = nextcol, nextcol += 8) + printf("\t"); + for (; col < tocol; col++) + printf(" "); + return col - fromcol; +} + +static void +print_rr_verbose(ldns_rr *rr) { + bool isq = ldns_rr_is_question(rr); + int rdcnt = ldns_rr_rd_count(rr); + int i, n; + + /* bind9-host does not count the initial ';' here */ + n = isq ? printf(";") : 0; + n = print_rdf(ldns_rr_owner(rr)); + if (!isq) { + n += print_padding(n, 24); + n += printf("%d", ldns_rr_ttl(rr)); + } + n += print_padding(n, 32); + n += print_rr_class(ldns_rr_get_class(rr)); + n += print_padding(n, 40); + n += print_rr_type(ldns_rr_get_type(rr)); + for (i = 0; i < rdcnt; i++) { + if (i == 0) print_padding(n, 48); + else printf(" "); + print_rdf(ldns_rr_rdf(rr, i)); + } + printf("\n"); +} + +static void +print_pkt_section_verbose(const char *name, ldns_rr_list *rrlist) { + int i, cnt = ldns_rr_list_rr_count(rrlist); + + if (cnt == 0) + return; + printf(";; %s SECTION:\n", name); + for (i = 0; i < cnt; i++) + print_rr_verbose(ldns_rr_list_rr(rrlist, i)); + printf("\n"); +} + +static void +print_pkt_verbose(ldns_pkt *pkt) { + int got_flags = 0; + + printf(";; ->>HEADER<<- opcode: "); + print_opcode(ldns_pkt_get_opcode(pkt)); + printf(", status: "); + print_rcode(ldns_pkt_get_rcode(pkt)); + printf(", id: %u\n", ldns_pkt_id(pkt)); + printf(";; flags:"); + if (ldns_pkt_qr(pkt)) printf(" qr"), got_flags = 1; + if (ldns_pkt_aa(pkt)) printf(" aa"), got_flags = 1; + if (ldns_pkt_tc(pkt)) printf(" tc"), got_flags = 1; + if (ldns_pkt_rd(pkt)) printf(" rd"), got_flags = 1; + if (ldns_pkt_ra(pkt)) printf(" ra"), got_flags = 1; + if (ldns_pkt_ad(pkt)) printf(" ad"), got_flags = 1; + if (ldns_pkt_cd(pkt)) printf(" cd"), got_flags = 1; + if (!got_flags) printf(" "); + printf("; QUERY: %u, ANSWER: %u, AUTHORITY: %u, ADDITIONAL: %u\n", + ldns_pkt_qdcount(pkt), ldns_pkt_ancount(pkt), + ldns_pkt_nscount(pkt), ldns_pkt_arcount(pkt)); + if (ldns_pkt_edns(pkt)) + printf(";; EDNS: version: %u, udp=%u\n", + ldns_pkt_edns_version(pkt), ldns_pkt_edns_udp_size(pkt)); + printf("\n"); + print_pkt_section_verbose("QUESTION", ldns_pkt_question(pkt)); + print_pkt_section_verbose("ANSWER", ldns_pkt_answer(pkt)); + print_pkt_section_verbose("AUTHORITY", ldns_pkt_authority(pkt)); + print_pkt_section_verbose("ADDITIONAL", ldns_pkt_additional(pkt)); +} + +static void +print_rr_short(ldns_rr *rr) { + ldns_rr_type type = ldns_rr_get_type(rr); + size_t i, rdcnt = ldns_rr_rd_count(rr); + + print_rdf_nodot(ldns_rr_owner(rr)); + printf(" "); + for (i = 0; i < countof(rr_types); i++) { + if (rr_types[i].type == type) { + printf("%s", rr_types[i].text); + goto found; + } + } + + printf("has "); + print_rr_type(type); + printf(" record"); + +found: + for (i = 0; i < rdcnt; i++) { + printf(" "); + print_rdf(ldns_rr_rdf(rr, i)); + } + printf("\n"); +} + +static void +print_pkt_short(ldns_pkt *pkt, bool print_rr_server) { + ldns_rr_list *rrlist = ldns_pkt_answer(pkt); + size_t i; + + for (i = 0; i < ldns_rr_list_rr_count(rrlist); i++) { + if (print_rr_server) { + printf("Nameserver "); + print_rdf(ldns_pkt_answerfrom(pkt)); + printf(":\n\t"); + } + print_rr_short(ldns_rr_list_rr(rrlist, i)); + } +} + +static void +print_received_line(ldns_resolver *res, ldns_pkt *pkt) { + char *from = ldns_rdf2str(ldns_pkt_answerfrom(pkt)); + + printf("Received %zu bytes from %s#%d in %d ms\n", + ldns_pkt_size(pkt), from, ldns_resolver_port(res), + ldns_pkt_querytime(pkt)); + free(from); +} + +/* Main program. + * + * Note that no memory is freed below this line by intention. + */ + +#define DEFAULT_TCP_TIMEOUT 10 +#define DEFAULT_UDP_TIMEOUT 5 + +enum operation_mode { M_AXFR, M_DEFAULT_Q, M_SINGLE_Q, M_SOA }; + +static enum operation_mode o_mode = M_DEFAULT_Q; +static bool o_ignore_servfail = true; +static bool o_ip6_int = false; +static bool o_print_pkt_server = false; +static bool o_print_rr_server = false; +static bool o_recursive = true; +static bool o_tcp = false; +static bool o_verbose = false; +static char *o_name = NULL; +static char *o_server = NULL; +static int o_ipversion = LDNS_RESOLV_INETANY; +static int o_ndots = 1; +static int o_retries = 1; +static ldns_rr_class o_rrclass = LDNS_RR_CLASS_IN; +static ldns_rr_type o_rrtype = LDNS_RR_TYPE_A; +static time_t o_timeout = 0; +static uint32_t o_ixfr_serial = 0; + +static void +usage(void) { + fputs( + "Usage: host [-aCdilrsTvw46] [-c class] [-N ndots] [-R number]\n" + " [-t type] [-W wait] name [server]\n" + "\t-a same as -v -t ANY\n" + "\t-C query SOA records from all authoritative name servers\n" + "\t-c use this query class (IN, CH, HS, etc)\n" + "\t-d produce verbose output, same as -v\n" + "\t-i use IP6.INT for IPv6 reverse lookups\n" + "\t-l list records in a zone via AXFR\n" + "\t-N consider names with at least this many dots as absolute\n" + "\t-R retry UDP queries this many times\n" + "\t-r disable recursive query\n" + "\t-s do not ignore SERVFAIL responses\n" + "\t-T send query via TCP\n" + "\t-t use this query type (A, AAAA, MX, etc)\n" + "\t-v produce verbose output\n" + "\t-w wait forever for a server reply\n" + "\t-W wait this many seconds for a reply\n" + "\t-4 use IPv4 only\n" + "\t-6 use IPv6 only\n", + stderr); + exit(1); +} + +static void +parse_args(int argc, char *argv[]) { + int ch; + + progname = argv[0]; + while ((ch = getopt(argc, argv, "aCdilrsTvw46c:N:R:t:W:")) != -1) { + switch (ch) { + case 'a': + if (o_mode != M_AXFR) + o_mode = M_SINGLE_Q; + o_rrtype = LDNS_RR_TYPE_ANY; + o_verbose = true; + break; + case 'C': + o_mode = M_SOA; + o_print_rr_server = true; + o_rrclass = LDNS_RR_CLASS_IN; + o_rrtype = LDNS_RR_TYPE_NS; + break; + case 'c': + /* bind9-host sets o_mode to M_SINGLE_Q here */ + o_rrclass = ldns_get_rr_class_by_name(optarg); + if (o_rrclass <= 0) + die(2, "invalid class: %s\n", optarg); + break; + case 'd': o_verbose = true; break; + case 'i': o_ip6_int = true; break; + case 'l': + o_mode = M_AXFR; + o_rrtype = LDNS_RR_TYPE_AXFR; + o_tcp = true; + break; + case 'N': + o_ndots = atoi(optarg); + if (o_ndots < 0) o_ndots = 0; + break; + case 'n': + /* bind9-host accepts and ignores this option */ + break; + case 'r': o_recursive = 0; break; + case 'R': + o_retries = atoi(optarg); + if (o_retries <= 0) o_retries = 1; + if (o_retries > 255) o_retries = 255; + break; + case 's': o_ignore_servfail = false; break; + case 'T': o_tcp = true; break; + case 't': + if (o_mode != M_AXFR) + o_mode = M_SINGLE_Q; + if (strncasecmp(optarg, "ixfr=", 5) == 0) { + o_rrtype = LDNS_RR_TYPE_IXFR; + o_ixfr_serial = atol(optarg + 5); + } else { + o_rrtype = ldns_get_rr_type_by_name(optarg); + if (o_rrtype <= 0) + die(2, "invalid type: %s\n", optarg); + } + if (o_rrtype == LDNS_RR_TYPE_AXFR || o_rrtype == LDNS_RR_TYPE_IXFR) + o_tcp = true; + if (o_rrtype == LDNS_RR_TYPE_AXFR) { + o_mode = M_AXFR; + o_rrtype = LDNS_RR_TYPE_ANY; + o_verbose = true; + } + break; + case 'v': o_verbose = true; break; + case 'w': + o_timeout = (time_t)INT_MAX; + break; + case 'W': + o_timeout = atol(optarg); + if (o_timeout <= 0) o_timeout = 1; + break; + case '4': o_ipversion = LDNS_RESOLV_INET; break; + case '6': o_ipversion = LDNS_RESOLV_INET6; break; + default: + usage(); + } + } + argc -= optind; + argv += optind; + /* bind9-host ignores arguments after the 2-nd one */ + if (argc < 1) + usage(); + o_name = argv[0]; + if (argc > 1) { + o_server = argv[1]; + o_print_pkt_server = true; + } +} + +static ldns_rdf* +safe_str2rdf_dname(const char *name) { + ldns_rdf *dname; + ldns_status status; + + if ((status = ldns_str2rdf_dname(&dname, name)) != LDNS_STATUS_OK) { + die(1, "'%s' is not a legal name (%s)", + name, ldns_get_errorstr_by_id(status)); + } + return dname; +} + +static ldns_rdf* +safe_dname_cat_clone(const ldns_rdf *rd1, const ldns_rdf *rd2) { + ldns_rdf *result = ldns_dname_cat_clone(rd1, rd2); + + if (!result) + die(1, "not enought memory for a domain name"); + /* Why doesn't ldns_dname_cat_clone check this condition? */ + if (ldns_rdf_size(result) > LDNS_MAX_DOMAINLEN) + die(1, "'%s' is not a legal name (%s)\n", ldns_rdf2str(result), + ldns_get_errorstr_by_id(LDNS_STATUS_DOMAINNAME_OVERFLOW)); + return result; +} + +static bool +query(ldns_resolver *res, ldns_rdf *domain, ldns_pkt **pkt) { + ldns_status status; + ldns_pkt_rcode rcode; + int i, cnt; + + if (o_verbose) { + printf("Trying \""); + print_rdf_nodot(domain); + printf("\"\n"); + } + for (cnt = ldns_resolver_nameserver_count(res), i = 0; i < cnt; i++) { + status = ldns_resolver_send_to(pkt, res, domain, o_rrtype, + o_rrclass, o_recursive ? LDNS_RD : 0, o_ixfr_serial, i); + if (status != LDNS_STATUS_OK) { + *pkt = NULL; + continue; + } + if (ldns_pkt_tc(*pkt) && !ldns_resolver_usevc(res)) { + if (o_verbose) + printf(";; Truncated, retrying in TCP mode.\n"); + ldns_resolver_set_usevc(res, true); + status = ldns_resolver_send_to(pkt, res, domain, o_rrtype, + o_rrclass, o_recursive ? LDNS_RD : 0, o_ixfr_serial, i); + ldns_resolver_set_usevc(res, false); + if (status != LDNS_STATUS_OK) + continue; + } + rcode = ldns_pkt_get_rcode(*pkt); + if (o_ignore_servfail && rcode == LDNS_RCODE_SERVFAIL && cnt > 1) + continue; + return rcode == LDNS_RCODE_NOERROR; + } + if (*pkt == NULL) { + printf(";; connection timed out; no servers could be reached\n"); + exit(1); + } + return false; +} + +static ldns_rdf * +search(ldns_resolver *res, ldns_rdf *domain, ldns_pkt **pkt, bool absolute) { + ldns_rdf *dname, **searchlist; + int i, n; + + if (absolute && query(res, domain, pkt)) + return domain; + + if ((dname = ldns_resolver_domain(res)) != NULL) { + dname = safe_dname_cat_clone(domain, dname); + if (query(res, dname, pkt)) + return dname; + } + + searchlist = ldns_resolver_searchlist(res); + n = ldns_resolver_searchlist_count(res); + for (i = 0; i < n; i++) { + dname = safe_dname_cat_clone(domain, searchlist[i]); + if (query(res, dname, pkt)) + return dname; + } + + if (!absolute && query(res, domain, pkt)) + return domain; + + return NULL; +} + +static void +report(ldns_resolver *res, ldns_rdf *domain, ldns_pkt *pkt) { + ldns_pkt_rcode rcode; + + if (o_print_pkt_server) { + printf("Using domain server:\nName: %s\nAddress: ", o_server); + print_rdf(ldns_pkt_answerfrom(pkt)); + printf("#%d\nAliases: \n\n", ldns_resolver_port(res)); + o_print_pkt_server = false; + } + rcode = ldns_pkt_get_rcode(pkt); + if (rcode != LDNS_RCODE_NOERROR) { + printf("Host "); + print_rdf_nodot(domain); + printf(" not found: %d(", rcode); + print_rcode(rcode); + printf(")\n"); + } else { + if (o_verbose) { + print_pkt_verbose(pkt); + } else { + print_pkt_short(pkt, o_print_rr_server); + if (o_mode != M_DEFAULT_Q && + ldns_rr_list_rr_count(ldns_pkt_answer(pkt)) == 0) { + print_rdf_nodot(domain); + printf(" has no "); + print_rr_type(o_rrtype); + printf(" record\n"); + } + } + } + if (o_verbose) + print_received_line(res, pkt); +} + +static bool +doquery(ldns_resolver *res, ldns_rdf *domain) { + ldns_pkt *pkt; + bool q; + + q = query(res, domain, &pkt); + report(res, domain, pkt); + return q; +} + +static bool +doquery_filtered(ldns_resolver *res, ldns_rdf *domain) { + ldns_pkt *pkt; + bool q; + + q = query(res, domain, &pkt); + ldns_pkt_filter_answer(pkt, o_rrtype); + report(res, domain, pkt); + return q; +} + +static bool +dosearch(ldns_resolver *res, ldns_rdf *domain, bool absolute) { + ldns_pkt *pkt; + ldns_rdf *dname; + + dname = search(res, domain, &pkt, absolute); + report(res, dname != NULL ? dname : domain, pkt); + return o_mode != M_DEFAULT_Q ? (dname != NULL) : + (dname != NULL) && + (o_rrtype = LDNS_RR_TYPE_AAAA, doquery_filtered(res, dname)) && + (o_rrtype = LDNS_RR_TYPE_MX, doquery_filtered(res, dname)); +} + +static bool +doaxfr(ldns_resolver *res, ldns_rdf *domain, bool absolute) { + ldns_pkt *pkt; + ldns_rdf *dname; + ldns_rr_type rrtype; + + rrtype = o_rrtype; + o_rrtype = LDNS_RR_TYPE_AXFR; + dname = search(res, domain, &pkt, absolute); + ldns_pkt_filter_answer(pkt, rrtype); + report(res, dname != NULL ? dname : domain, pkt); + return dname != NULL; +} + +static bool +dosoa(ldns_resolver *res, ldns_rdf *domain, bool absolute) { + ldns_rr_list *answer, **nsaddrs; + ldns_rdf *dname, *addr; + ldns_pkt *pkt; + ldns_rr *rr; + size_t i, j, n, cnt; + + if ((dname = search(res, domain, &pkt, absolute)) == NULL) + return false; + + answer = ldns_pkt_answer(pkt); + cnt = ldns_rr_list_rr_count(answer); + nsaddrs = alloca(cnt*sizeof(*nsaddrs)); + for (n = 0, i = 0; i < cnt; i++) + if ((addr = ldns_rr_ns_nsdname(ldns_rr_list_rr(answer, i))) != NULL) + nsaddrs[n++] = ldns_get_rr_list_addr_by_name(res, + addr, LDNS_RR_CLASS_IN, 0); + + o_print_pkt_server = false; + o_recursive = false; + o_rrtype = LDNS_RR_TYPE_SOA; + for (i = 0; i < n; i++) { + cnt = ldns_rr_list_rr_count(nsaddrs[i]); + for (j = 0; j < cnt; j++) { + ldns_resolver_remove_nameservers(res); + rr = ldns_rr_list_rr(nsaddrs[i], j); + if ((ldns_resolver_ip6(res) == LDNS_RESOLV_INET && + ldns_rr_get_type(rr) == LDNS_RR_TYPE_AAAA) || + (ldns_resolver_ip6(res) == LDNS_RESOLV_INET6 && + ldns_rr_get_type(rr) == LDNS_RR_TYPE_A)) + continue; + if (ldns_resolver_push_nameserver_rr(res, rr) == LDNS_STATUS_OK) + /* bind9-host queries for domain, not dname here */ + doquery(res, dname); + } + } + return 0; +} + +static void +resolver_set_nameserver_hostname(ldns_resolver *res, const char *server) { + struct addrinfo hints, *ailist, *ai; + ldns_status status; + ldns_rdf *rdf; + int err; + + memset(&hints, 0, sizeof hints); + switch (ldns_resolver_ip6(res)) { + case LDNS_RESOLV_INET: hints.ai_family = PF_INET; break; + case LDNS_RESOLV_INET6: hints.ai_family = PF_INET6; break; + default: hints.ai_family = PF_UNSPEC; break; + } + hints.ai_socktype = SOCK_STREAM; + do err = getaddrinfo(server, NULL, &hints, &ailist); + while (err == EAI_AGAIN); + if (err != 0) + die(1, "couldn't get address for '%s': %s", server, gai_strerror(err)); + for (ai = ailist; ai != NULL; ai = ai->ai_next) { + if ((rdf = ldns_sockaddr_storage2rdf((void*)ai->ai_addr, NULL)) == NULL) + die(1, "couldn't allocate an rdf: %s", + ldns_get_errorstr_by_id(LDNS_STATUS_MEM_ERR)); + status = ldns_resolver_push_nameserver(res, rdf); + if (status != LDNS_STATUS_OK) + die(1, "couldn't push a nameserver address: %s", + ldns_get_errorstr_by_id(status)); + } +} + +static void +resolver_set_nameserver_str(ldns_resolver *res, const char *server) { + ldns_rdf *addr; + + ldns_resolver_remove_nameservers(res); + addr = ldns_rdf_new_addr_frm_str(server); + if (addr) { + if (ldns_resolver_push_nameserver(res, addr) != LDNS_STATUS_OK) + die(1, "couldn't push a nameserver address"); + } else + resolver_set_nameserver_hostname(res, server); +} + +int +main(int argc, char *argv[]) { + ldns_rdf *addr, *dname; + ldns_resolver *res; + ldns_status status; + struct timeval restimeout; + + parse_args(argc, argv); + + status = ldns_resolver_new_default(&res); + if (status != LDNS_STATUS_OK) + die(1, "error creating resolver: %s", ldns_get_errorstr_by_id(status)); + if (ldns_resolver_nameserver_count(res) == 0) + ldns_resolver_push_default_servers(res); + + ldns_resolver_set_usevc(res, o_tcp); + restimeout.tv_sec = o_timeout > 0 ? o_timeout : + o_tcp ? DEFAULT_TCP_TIMEOUT : DEFAULT_UDP_TIMEOUT; + restimeout.tv_usec = 0; + ldns_resolver_set_timeout(res, restimeout); + ldns_resolver_set_retry(res, o_retries+1); + ldns_resolver_set_ip6(res, o_ipversion); + ldns_resolver_set_defnames(res, false); + ldns_resolver_set_fallback(res, false); + + if (o_server) + resolver_set_nameserver_str(res, o_server); + + if (ldns_str2rdf_a(&addr, o_name) == LDNS_STATUS_OK) { + dname = ldns_rdf_reverse_a(addr, "in-addr.arpa"); + if (dname == NULL) + die(1, "can't reverse '%s': %s", o_name, + ldns_get_errorstr_by_id(LDNS_STATUS_MEM_ERR)); + o_mode = M_SINGLE_Q; + o_rrtype = LDNS_RR_TYPE_PTR; + return !doquery(res, dname); + } else if (ldns_str2rdf_aaaa(&addr, o_name) == LDNS_STATUS_OK) { + dname = ldns_rdf_reverse_aaaa(addr, o_ip6_int ? "ip6.int" : "ip6.arpa"); + if (dname == NULL) + die(1, "can't reverse '%s': %s", o_name, + ldns_get_errorstr_by_id(LDNS_STATUS_MEM_ERR)); + o_mode = M_SINGLE_Q; + o_rrtype = LDNS_RR_TYPE_PTR; + return !doquery(res, dname); + } + return !(o_mode == M_SOA ? dosoa : o_mode == M_AXFR ? doaxfr : dosearch) + (res, safe_str2rdf_dname(o_name), ndots(o_name) >= o_ndots); +} diff --git a/contrib/llvm/tools/clang/lib/Driver/ToolChains.cpp b/contrib/llvm/tools/clang/lib/Driver/ToolChains.cpp index fffba0e4e50f..d8d580b8b5cc 100644 --- a/contrib/llvm/tools/clang/lib/Driver/ToolChains.cpp +++ b/contrib/llvm/tools/clang/lib/Driver/ToolChains.cpp @@ -1851,6 +1851,38 @@ bool FreeBSD::UseSjLjExceptions() const { } } +ToolChain::CXXStdlibType +FreeBSD::GetCXXStdlibType(const ArgList &Args) const { + if (Arg *A = Args.getLastArg(options::OPT_stdlib_EQ)) { + StringRef Value = A->getValue(); + if (Value == "libc++") + return ToolChain::CST_Libcxx; + if (Value == "libstdc++") + return ToolChain::CST_Libstdcxx; + getDriver().Diag(diag::err_drv_invalid_stdlib_name) + << A->getAsString(Args); + } + + return getTriple().getOSMajorVersion() >= 10 ? ToolChain::CST_Libcxx : + ToolChain::CST_Libstdcxx; +} + +void FreeBSD::AddClangCXXStdlibIncludeArgs(const ArgList &DriverArgs, + ArgStringList &CC1Args) const { + if (DriverArgs.hasArg(options::OPT_nostdlibinc) || + DriverArgs.hasArg(options::OPT_nostdincxx)) + return; + + if (GetCXXStdlibType(DriverArgs) == ToolChain::CST_Libcxx) + addSystemInclude(DriverArgs, CC1Args, + getDriver().SysRoot + "/usr/include/c++/v1"); + else + addSystemInclude(DriverArgs, CC1Args, + getDriver().SysRoot + "/usr/include/c++/4.2"); + return; + +} + /// NetBSD - NetBSD tool chain which can call as(1) and ld(1) directly. NetBSD::NetBSD(const Driver &D, const llvm::Triple& Triple, const ArgList &Args) diff --git a/contrib/llvm/tools/clang/lib/Driver/ToolChains.h b/contrib/llvm/tools/clang/lib/Driver/ToolChains.h index 3afd8dd228b6..2b140c1cd0a3 100644 --- a/contrib/llvm/tools/clang/lib/Driver/ToolChains.h +++ b/contrib/llvm/tools/clang/lib/Driver/ToolChains.h @@ -458,9 +458,14 @@ class LLVM_LIBRARY_VISIBILITY FreeBSD : public Generic_ELF { public: FreeBSD(const Driver &D, const llvm::Triple& Triple, const ArgList &Args); + virtual CXXStdlibType GetCXXStdlibType(const ArgList &Args) const; + virtual bool IsMathErrnoDefault() const { return false; } virtual bool IsObjCNonFragileABIDefault() const { return true; } + virtual void AddClangCXXStdlibIncludeArgs(const ArgList &DriverArgs, + ArgStringList &CC1Args) const; + virtual bool UseSjLjExceptions() const; protected: virtual Tool *buildAssembler() const; diff --git a/contrib/openpam/CREDITS b/contrib/openpam/CREDITS index 2725d8888cb1..dcb8a16f8f2c 100644 --- a/contrib/openpam/CREDITS +++ b/contrib/openpam/CREDITS @@ -1,4 +1,6 @@ + _Ἀπόδοτε οὖν τὰ Καίσαρος Καίσαρι καὶ τὰ τοῦ Θεοῦ τῷ Θεῷ_ + The OpenPAM library was developed for the FreeBSD Project by ThinkSec AS and Network Associates Laboratories, the Security Research Division of Network Associates, Inc. under DARPA/SPAWAR contract N66001-01-C-8035 @@ -21,12 +23,14 @@ ideas: Don Lewis Emmanuel Dreyfus Eric Melville + Espen Grøndahl Gary Winiger Gleb Smirnoff Hubert Feyrer Jason Evans Joe Marcus Clarke Juli Mallett + Ankita Pal Jörg Sonnenberger Maëlle Lesage Mark Murray @@ -43,4 +47,4 @@ ideas: Wojciech A. Koszek Yar Tikhiy -$Id: CREDITS 587 2012-04-08 11:12:10Z des $ +$Id: CREDITS 648 2013-03-05 17:54:27Z des $ diff --git a/contrib/openpam/FREEBSD-vendor b/contrib/openpam/FREEBSD-vendor deleted file mode 100644 index 51a8bbfa4803..000000000000 --- a/contrib/openpam/FREEBSD-vendor +++ /dev/null @@ -1,6 +0,0 @@ -# $FreeBSD$ -Project: OpenPAM -ProjectURL: http://www.openpam.org/ -Version: Hydrangea (20071221) -License: BSD -Maintainer: des diff --git a/contrib/openpam/HISTORY b/contrib/openpam/HISTORY index 3cc4c96e0859..ddb4d423459e 100644 --- a/contrib/openpam/HISTORY +++ b/contrib/openpam/HISTORY @@ -1,3 +1,30 @@ +OpenPAM Nummularia 2013-09-07 + + - ENHANCE: Rewrite the dynamic loader to improve readability and + reliability. Modules can now be listed without the ".so" suffix in + the policy file; OpenPAM will automatically add it, just like it + will automatically add the version number if required. + + - ENHANCE: Allow openpam_straddch(3) to be called without a character + so it can be used to preallocate a string. + + - ENHANCE: Improve portability by adding simple asprintf(3) and + vasprintf(3) implementations for platforms that don't have them. + + - ENHANCE: Move the libpam sources into a separate subdirectory. + + - ENHANCE: Substantial documentation improvements. + + - BUGFIX: When openpam_readword(3) encountered an opening quote, it + would set the first byte in the buffer to '\0', discarding all + existing text and, unless the buffer was empty to begin with, all + subsequent text as well. This went unnoticed because none of the + unit tests for quoted strings had any text preceding the opening + quote. + + - BUGFIX: make --with-modules-dir work the way it was meant to work + (but never did). +============================================================================ OpenPAM Micrampelis 2012-05-26 - FEATURE: Add an openpam_readword(3) function which reads the next @@ -401,4 +428,4 @@ OpenPAM Calamite 2002-02-09 First (beta) release. ============================================================================ -$Id: HISTORY 609 2012-05-26 13:57:45Z des $ +$Id: HISTORY 737 2013-09-07 12:53:55Z des $ diff --git a/contrib/openpam/INSTALL b/contrib/openpam/INSTALL index 6875a5eebbd8..8c27b932fc48 100644 --- a/contrib/openpam/INSTALL +++ b/contrib/openpam/INSTALL @@ -55,4 +55,4 @@ # make install -$Id: INSTALL 388 2006-04-12 10:31:52Z des $ +$Id: INSTALL 648 2013-03-05 17:54:27Z des $ diff --git a/contrib/openpam/LICENSE b/contrib/openpam/LICENSE index 511979487ae0..a894e43a3953 100644 --- a/contrib/openpam/LICENSE +++ b/contrib/openpam/LICENSE @@ -32,4 +32,4 @@ LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -$Id: LICENSE 546 2012-03-31 23:13:20Z des $ +$Id: LICENSE 648 2013-03-05 17:54:27Z des $ diff --git a/contrib/openpam/Makefile.am b/contrib/openpam/Makefile.am index 5c4fbf3f0a2a..1c873117ce08 100644 --- a/contrib/openpam/Makefile.am +++ b/contrib/openpam/Makefile.am @@ -1,4 +1,4 @@ -# $Id: Makefile.am 549 2012-04-01 20:38:30Z des $ +# $Id: Makefile.am 623 2013-02-25 07:24:51Z des $ ACLOCAL_AMFLAGS = -I m4 diff --git a/contrib/openpam/Makefile.in b/contrib/openpam/Makefile.in index 3c0c783f46fb..c8e77d9a4305 100644 --- a/contrib/openpam/Makefile.in +++ b/contrib/openpam/Makefile.in @@ -1,9 +1,8 @@ -# Makefile.in generated by automake 1.11.1 from Makefile.am. +# Makefile.in generated by automake 1.14 from Makefile.am. # @configure_input@ -# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, -# 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation, -# Inc. +# Copyright (C) 1994-2013 Free Software Foundation, Inc. + # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. @@ -15,8 +14,53 @@ @SET_MAKE@ -# $Id: Makefile.am 549 2012-04-01 20:38:30Z des $ +# $Id: Makefile.am 623 2013-02-25 07:24:51Z des $ VPATH = @srcdir@ +am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)' +am__make_running_with_option = \ + case $${target_option-} in \ + ?) ;; \ + *) echo "am__make_running_with_option: internal error: invalid" \ + "target option '$${target_option-}' specified" >&2; \ + exit 1;; \ + esac; \ + has_opt=no; \ + sane_makeflags=$$MAKEFLAGS; \ + if $(am__is_gnu_make); then \ + sane_makeflags=$$MFLAGS; \ + else \ + case $$MAKEFLAGS in \ + *\\[\ \ ]*) \ + bs=\\; \ + sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ + | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ + esac; \ + fi; \ + skip_next=no; \ + strip_trailopt () \ + { \ + flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ + }; \ + for flg in $$sane_makeflags; do \ + test $$skip_next = yes && { skip_next=no; continue; }; \ + case $$flg in \ + *=*|--*) continue;; \ + -*I) strip_trailopt 'I'; skip_next=yes;; \ + -*I?*) strip_trailopt 'I';; \ + -*O) strip_trailopt 'O'; skip_next=yes;; \ + -*O?*) strip_trailopt 'O';; \ + -*l) strip_trailopt 'l'; skip_next=yes;; \ + -*l?*) strip_trailopt 'l';; \ + -[dEDm]) skip_next=yes;; \ + -[JT]) skip_next=yes;; \ + esac; \ + case $$flg in \ + *$$target_option*) has_opt=yes; break;; \ + esac; \ + done; \ + test $$has_opt = yes +am__make_dryrun = (target_option=n; $(am__make_running_with_option)) +am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ @@ -37,44 +81,91 @@ build_triplet = @build@ host_triplet = @host@ @WITH_DOC_TRUE@am__append_1 = doc subdir = . -DIST_COMMON = README $(am__configure_deps) $(srcdir)/Makefile.am \ - $(srcdir)/Makefile.in $(srcdir)/config.h.in \ - $(srcdir)/pamgdb.in $(top_srcdir)/configure INSTALL TODO \ - config.guess config.sub depcomp install-sh ltmain.sh missing +DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \ + $(top_srcdir)/configure $(am__configure_deps) \ + $(srcdir)/config.h.in $(srcdir)/pamgdb.in $(srcdir)/mkpkgng.in \ + INSTALL README TODO compile config.guess config.sub depcomp \ + install-sh missing ltmain.sh ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 -am__aclocal_m4_deps = $(top_srcdir)/configure.ac +am__aclocal_m4_deps = $(top_srcdir)/m4/libtool.m4 \ + $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \ + $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \ + $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) am__CONFIG_DISTCLEAN_FILES = config.status config.cache config.log \ configure.lineno config.status.lineno mkinstalldirs = $(install_sh) -d CONFIG_HEADER = config.h -CONFIG_CLEAN_FILES = pamgdb +CONFIG_CLEAN_FILES = pamgdb mkpkgng CONFIG_CLEAN_VPATH_FILES = +AM_V_P = $(am__v_P_@AM_V@) +am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) +am__v_P_0 = false +am__v_P_1 = : +AM_V_GEN = $(am__v_GEN_@AM_V@) +am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) +am__v_GEN_0 = @echo " GEN " $@; +am__v_GEN_1 = +AM_V_at = $(am__v_at_@AM_V@) +am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) +am__v_at_0 = @ +am__v_at_1 = SOURCES = DIST_SOURCES = -RECURSIVE_TARGETS = all-recursive check-recursive dvi-recursive \ - html-recursive info-recursive install-data-recursive \ - install-dvi-recursive install-exec-recursive \ - install-html-recursive install-info-recursive \ - install-pdf-recursive install-ps-recursive install-recursive \ - installcheck-recursive installdirs-recursive pdf-recursive \ - ps-recursive uninstall-recursive +RECURSIVE_TARGETS = all-recursive check-recursive cscopelist-recursive \ + ctags-recursive dvi-recursive html-recursive info-recursive \ + install-data-recursive install-dvi-recursive \ + install-exec-recursive install-html-recursive \ + install-info-recursive install-pdf-recursive \ + install-ps-recursive install-recursive installcheck-recursive \ + installdirs-recursive pdf-recursive ps-recursive \ + tags-recursive uninstall-recursive +am__can_run_installinfo = \ + case $$AM_UPDATE_INFO_DIR in \ + n|no|NO) false;; \ + *) (install-info --version) >/dev/null 2>&1;; \ + esac RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \ distclean-recursive maintainer-clean-recursive -AM_RECURSIVE_TARGETS = $(RECURSIVE_TARGETS:-recursive=) \ - $(RECURSIVE_CLEAN_TARGETS:-recursive=) tags TAGS ctags CTAGS \ - distdir dist dist-all distcheck +am__recursive_targets = \ + $(RECURSIVE_TARGETS) \ + $(RECURSIVE_CLEAN_TARGETS) \ + $(am__extra_recursive_targets) +AM_RECURSIVE_TARGETS = $(am__recursive_targets:-recursive=) TAGS CTAGS \ + cscope distdir dist dist-all distcheck +am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) \ + $(LISP)config.h.in +# Read a list of newline-separated strings from the standard input, +# and print each of them once, without duplicates. Input order is +# *not* preserved. +am__uniquify_input = $(AWK) '\ + BEGIN { nonempty = 0; } \ + { items[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in items) print i; }; } \ +' +# Make sure the list of sources is unique. This is necessary because, +# e.g., the same source file might be shared among _SOURCES variables +# for different programs/libraries. +am__define_uniq_tagged_files = \ + list='$(am__tagged_files)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | $(am__uniquify_input)` ETAGS = etags CTAGS = ctags +CSCOPE = cscope DIST_SUBDIRS = lib bin modules include doc t DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) distdir = $(PACKAGE)-$(VERSION) top_distdir = $(distdir) am__remove_distdir = \ - { test ! -d "$(distdir)" \ - || { find "$(distdir)" -type d ! -perm -200 -exec chmod u+w {} ';' \ - && rm -fr "$(distdir)"; }; } + if test -d "$(distdir)"; then \ + find "$(distdir)" -type d ! -perm -200 -exec chmod u+w {} ';' \ + && rm -rf "$(distdir)" \ + || { sleep 5 && rm -rf "$(distdir)"; }; \ + else :; fi +am__post_remove_distdir = $(am__remove_distdir) am__relativize = \ dir0=`pwd`; \ sed_first='s,^\([^/]*\)/.*$$,\1,'; \ @@ -102,10 +193,14 @@ am__relativize = \ reldir="$$dir2" DIST_ARCHIVES = $(distdir).tar.gz GZIP_ENV = --best +DIST_TARGETS = dist-gzip distuninstallcheck_listfiles = find . -type f -print +am__distuninstallcheck_listfiles = $(distuninstallcheck_listfiles) \ + | sed 's|^\./|$(prefix)/|' | grep -v '$(infodir)/dir$$' distcleancheck_listfiles = find . -type f -print ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ +AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ @@ -116,6 +211,7 @@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ +CRYPTO_LIBS = @CRYPTO_LIBS@ CRYPT_LIBS = @CRYPT_LIBS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ @@ -237,7 +333,7 @@ all: config.h $(MAKE) $(AM_MAKEFLAGS) all-recursive .SUFFIXES: -am--refresh: +am--refresh: Makefile @: $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ @@ -273,10 +369,8 @@ $(ACLOCAL_M4): $(am__aclocal_m4_deps) $(am__aclocal_m4_deps): config.h: stamp-h1 - @if test ! -f $@; then \ - rm -f stamp-h1; \ - $(MAKE) $(AM_MAKEFLAGS) stamp-h1; \ - else :; fi + @test -f $@ || rm -f stamp-h1 + @test -f $@ || $(MAKE) $(AM_MAKEFLAGS) stamp-h1 stamp-h1: $(srcdir)/config.h.in $(top_builddir)/config.status @rm -f stamp-h1 @@ -290,6 +384,8 @@ distclean-hdr: -rm -f config.h stamp-h1 pamgdb: $(top_builddir)/config.status $(srcdir)/pamgdb.in cd $(top_builddir) && $(SHELL) ./config.status $@ +mkpkgng: $(top_builddir)/config.status $(srcdir)/mkpkgng.in + cd $(top_builddir) && $(SHELL) ./config.status $@ mostlyclean-libtool: -rm -f *.lo @@ -301,22 +397,25 @@ distclean-libtool: -rm -f libtool config.lt # This directory's subdirectories are mostly independent; you can cd -# into them and run `make' without going through this Makefile. -# To change the values of `make' variables: instead of editing Makefiles, -# (1) if the variable is set in `config.status', edit `config.status' -# (which will cause the Makefiles to be regenerated when you run `make'); -# (2) otherwise, pass the desired values on the `make' command line. -$(RECURSIVE_TARGETS): - @fail= failcom='exit 1'; \ - for f in x $$MAKEFLAGS; do \ - case $$f in \ - *=* | --[!k]*);; \ - *k*) failcom='fail=yes';; \ - esac; \ - done; \ +# into them and run 'make' without going through this Makefile. +# To change the values of 'make' variables: instead of editing Makefiles, +# (1) if the variable is set in 'config.status', edit 'config.status' +# (which will cause the Makefiles to be regenerated when you run 'make'); +# (2) otherwise, pass the desired values on the 'make' command line. +$(am__recursive_targets): + @fail=; \ + if $(am__make_keepgoing); then \ + failcom='fail=yes'; \ + else \ + failcom='exit 1'; \ + fi; \ dot_seen=no; \ target=`echo $@ | sed s/-recursive//`; \ - list='$(SUBDIRS)'; for subdir in $$list; do \ + case "$@" in \ + distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ + *) list='$(SUBDIRS)' ;; \ + esac; \ + for subdir in $$list; do \ echo "Making $$target in $$subdir"; \ if test "$$subdir" = "."; then \ dot_seen=yes; \ @@ -331,57 +430,12 @@ $(RECURSIVE_TARGETS): $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ fi; test -z "$$fail" -$(RECURSIVE_CLEAN_TARGETS): - @fail= failcom='exit 1'; \ - for f in x $$MAKEFLAGS; do \ - case $$f in \ - *=* | --[!k]*);; \ - *k*) failcom='fail=yes';; \ - esac; \ - done; \ - dot_seen=no; \ - case "$@" in \ - distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ - *) list='$(SUBDIRS)' ;; \ - esac; \ - rev=''; for subdir in $$list; do \ - if test "$$subdir" = "."; then :; else \ - rev="$$subdir $$rev"; \ - fi; \ - done; \ - rev="$$rev ."; \ - target=`echo $@ | sed s/-recursive//`; \ - for subdir in $$rev; do \ - echo "Making $$target in $$subdir"; \ - if test "$$subdir" = "."; then \ - local_target="$$target-am"; \ - else \ - local_target="$$target"; \ - fi; \ - ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ - || eval $$failcom; \ - done && test -z "$$fail" -tags-recursive: - list='$(SUBDIRS)'; for subdir in $$list; do \ - test "$$subdir" = . || ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) tags); \ - done -ctags-recursive: - list='$(SUBDIRS)'; for subdir in $$list; do \ - test "$$subdir" = . || ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) ctags); \ - done +ID: $(am__tagged_files) + $(am__define_uniq_tagged_files); mkid -fID $$unique +tags: tags-recursive +TAGS: tags -ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) - list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ - unique=`for i in $$list; do \ - if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ - done | \ - $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ - END { if (nonempty) { for (i in files) print i; }; }'`; \ - mkid -fID $$unique -tags: TAGS - -TAGS: tags-recursive $(HEADERS) $(SOURCES) config.h.in $(TAGS_DEPENDENCIES) \ - $(TAGS_FILES) $(LISP) +tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \ @@ -397,12 +451,7 @@ TAGS: tags-recursive $(HEADERS) $(SOURCES) config.h.in $(TAGS_DEPENDENCIES) \ set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \ fi; \ done; \ - list='$(SOURCES) $(HEADERS) config.h.in $(LISP) $(TAGS_FILES)'; \ - unique=`for i in $$list; do \ - if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ - done | \ - $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ - END { if (nonempty) { for (i in files) print i; }; }'`; \ + $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ @@ -414,15 +463,11 @@ TAGS: tags-recursive $(HEADERS) $(SOURCES) config.h.in $(TAGS_DEPENDENCIES) \ $$unique; \ fi; \ fi -ctags: CTAGS -CTAGS: ctags-recursive $(HEADERS) $(SOURCES) config.h.in $(TAGS_DEPENDENCIES) \ - $(TAGS_FILES) $(LISP) - list='$(SOURCES) $(HEADERS) config.h.in $(LISP) $(TAGS_FILES)'; \ - unique=`for i in $$list; do \ - if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ - done | \ - $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ - END { if (nonempty) { for (i in files) print i; }; }'`; \ +ctags: ctags-recursive + +CTAGS: ctags +ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique @@ -431,9 +476,31 @@ GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" +cscope: cscope.files + test ! -s cscope.files \ + || $(CSCOPE) -b -q $(AM_CSCOPEFLAGS) $(CSCOPEFLAGS) -i cscope.files $(CSCOPE_ARGS) +clean-cscope: + -rm -f cscope.files +cscope.files: clean-cscope cscopelist +cscopelist: cscopelist-recursive + +cscopelist-am: $(am__tagged_files) + list='$(am__tagged_files)'; \ + case "$(srcdir)" in \ + [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ + *) sdir=$(subdir)/$(srcdir) ;; \ + esac; \ + for i in $$list; do \ + if test -f "$$i"; then \ + echo "$(subdir)/$$i"; \ + else \ + echo "$$sdir/$$i"; \ + fi; \ + done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + -rm -f cscope.out cscope.in.out cscope.po.out cscope.files distdir: $(DISTFILES) $(am__remove_distdir) @@ -469,13 +536,10 @@ distdir: $(DISTFILES) done @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ - test -d "$(distdir)/$$subdir" \ - || $(MKDIR_P) "$(distdir)/$$subdir" \ - || exit 1; \ - fi; \ - done - @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ - if test "$$subdir" = .; then :; else \ + $(am__make_dryrun) \ + || test -d "$(distdir)/$$subdir" \ + || $(MKDIR_P) "$(distdir)/$$subdir" \ + || exit 1; \ dir1=$$subdir; dir2="$(distdir)/$$subdir"; \ $(am__relativize); \ new_distdir=$$reldir; \ @@ -504,36 +568,42 @@ distdir: $(DISTFILES) || chmod -R a+r "$(distdir)" dist-gzip: distdir tardir=$(distdir) && $(am__tar) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz - $(am__remove_distdir) + $(am__post_remove_distdir) dist-bzip2: distdir - tardir=$(distdir) && $(am__tar) | bzip2 -9 -c >$(distdir).tar.bz2 - $(am__remove_distdir) + tardir=$(distdir) && $(am__tar) | BZIP2=$${BZIP2--9} bzip2 -c >$(distdir).tar.bz2 + $(am__post_remove_distdir) -dist-lzma: distdir - tardir=$(distdir) && $(am__tar) | lzma -9 -c >$(distdir).tar.lzma - $(am__remove_distdir) +dist-lzip: distdir + tardir=$(distdir) && $(am__tar) | lzip -c $${LZIP_OPT--9} >$(distdir).tar.lz + $(am__post_remove_distdir) dist-xz: distdir - tardir=$(distdir) && $(am__tar) | xz -c >$(distdir).tar.xz - $(am__remove_distdir) + tardir=$(distdir) && $(am__tar) | XZ_OPT=$${XZ_OPT--e} xz -c >$(distdir).tar.xz + $(am__post_remove_distdir) dist-tarZ: distdir + @echo WARNING: "Support for shar distribution archives is" \ + "deprecated." >&2 + @echo WARNING: "It will be removed altogether in Automake 2.0" >&2 tardir=$(distdir) && $(am__tar) | compress -c >$(distdir).tar.Z - $(am__remove_distdir) + $(am__post_remove_distdir) dist-shar: distdir + @echo WARNING: "Support for distribution archives compressed with" \ + "legacy program 'compress' is deprecated." >&2 + @echo WARNING: "It will be removed altogether in Automake 2.0" >&2 shar $(distdir) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).shar.gz - $(am__remove_distdir) + $(am__post_remove_distdir) dist-zip: distdir -rm -f $(distdir).zip zip -rq $(distdir).zip $(distdir) - $(am__remove_distdir) + $(am__post_remove_distdir) -dist dist-all: distdir - tardir=$(distdir) && $(am__tar) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz - $(am__remove_distdir) +dist dist-all: + $(MAKE) $(AM_MAKEFLAGS) $(DIST_TARGETS) am__post_remove_distdir='@:' + $(am__post_remove_distdir) # This target untars the dist file and tries a VPATH configuration. Then # it guarantees that the distribution is self-contained by making another @@ -544,8 +614,8 @@ distcheck: dist GZIP=$(GZIP_ENV) gzip -dc $(distdir).tar.gz | $(am__untar) ;;\ *.tar.bz2*) \ bzip2 -dc $(distdir).tar.bz2 | $(am__untar) ;;\ - *.tar.lzma*) \ - lzma -dc $(distdir).tar.lzma | $(am__untar) ;;\ + *.tar.lz*) \ + lzip -dc $(distdir).tar.lz | $(am__untar) ;;\ *.tar.xz*) \ xz -dc $(distdir).tar.xz | $(am__untar) ;;\ *.tar.Z*) \ @@ -555,9 +625,9 @@ distcheck: dist *.zip*) \ unzip $(distdir).zip ;;\ esac - chmod -R a-w $(distdir); chmod a+w $(distdir) - mkdir $(distdir)/_build - mkdir $(distdir)/_inst + chmod -R a-w $(distdir) + chmod u+w $(distdir) + mkdir $(distdir)/_build $(distdir)/_inst chmod a-w $(distdir) test -d $(distdir)/_build || exit 0; \ dc_install_base=`$(am__cd) $(distdir)/_inst && pwd | sed -e 's,^[^:\\/]:[\\/],/,'` \ @@ -565,6 +635,7 @@ distcheck: dist && am__cwd=`pwd` \ && $(am__cd) $(distdir)/_build \ && ../configure --srcdir=.. --prefix="$$dc_install_base" \ + $(AM_DISTCHECK_CONFIGURE_FLAGS) \ $(DISTCHECK_CONFIGURE_FLAGS) \ && $(MAKE) $(AM_MAKEFLAGS) \ && $(MAKE) $(AM_MAKEFLAGS) dvi \ @@ -588,13 +659,21 @@ distcheck: dist && $(MAKE) $(AM_MAKEFLAGS) distcleancheck \ && cd "$$am__cwd" \ || exit 1 - $(am__remove_distdir) + $(am__post_remove_distdir) @(echo "$(distdir) archives ready for distribution: "; \ list='$(DIST_ARCHIVES)'; for i in $$list; do echo $$i; done) | \ sed -e 1h -e 1s/./=/g -e 1p -e 1x -e '$$p' -e '$$x' distuninstallcheck: - @$(am__cd) '$(distuninstallcheck_dir)' \ - && test `$(distuninstallcheck_listfiles) | wc -l` -le 1 \ + @test -n '$(distuninstallcheck_dir)' || { \ + echo 'ERROR: trying to run $@ with an empty' \ + '$$(distuninstallcheck_dir)' >&2; \ + exit 1; \ + }; \ + $(am__cd) '$(distuninstallcheck_dir)' || { \ + echo 'ERROR: cannot chdir into $(distuninstallcheck_dir)' >&2; \ + exit 1; \ + }; \ + test `$(am__distuninstallcheck_listfiles) | wc -l` -eq 0 \ || { echo "ERROR: files left after uninstall:" ; \ if test -n "$(DESTDIR)"; then \ echo " (check DESTDIR support)"; \ @@ -625,10 +704,15 @@ install-am: all-am installcheck: installcheck-recursive install-strip: - $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ - install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ - `test -z '$(STRIP)' || \ - echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install + if test -z '$(STRIP)'; then \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + install; \ + else \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ + fi mostlyclean-generic: clean-generic: @@ -710,24 +794,24 @@ ps-am: uninstall-am: -.MAKE: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) all \ - ctags-recursive install-am install-strip tags-recursive +.MAKE: $(am__recursive_targets) all install-am install-strip -.PHONY: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) CTAGS GTAGS \ - all all-am am--refresh check check-am clean clean-generic \ - clean-libtool ctags ctags-recursive dist dist-all dist-bzip2 \ - dist-gzip dist-lzma dist-shar dist-tarZ dist-xz dist-zip \ - distcheck distclean distclean-generic distclean-hdr \ - distclean-libtool distclean-tags distcleancheck distdir \ - distuninstallcheck dvi dvi-am html html-am info info-am \ - install install-am install-data install-data-am install-dvi \ - install-dvi-am install-exec install-exec-am install-html \ - install-html-am install-info install-info-am install-man \ - install-pdf install-pdf-am install-ps install-ps-am \ - install-strip installcheck installcheck-am installdirs \ - installdirs-am maintainer-clean maintainer-clean-generic \ - mostlyclean mostlyclean-generic mostlyclean-libtool pdf pdf-am \ - ps ps-am tags tags-recursive uninstall uninstall-am +.PHONY: $(am__recursive_targets) CTAGS GTAGS TAGS all all-am \ + am--refresh check check-am clean clean-cscope clean-generic \ + clean-libtool cscope cscopelist-am ctags ctags-am dist \ + dist-all dist-bzip2 dist-gzip dist-lzip dist-shar dist-tarZ \ + dist-xz dist-zip distcheck distclean distclean-generic \ + distclean-hdr distclean-libtool distclean-tags distcleancheck \ + distdir distuninstallcheck dvi dvi-am html html-am info \ + info-am install install-am install-data install-data-am \ + install-dvi install-dvi-am install-exec install-exec-am \ + install-html install-html-am install-info install-info-am \ + install-man install-pdf install-pdf-am install-ps \ + install-ps-am install-strip installcheck installcheck-am \ + installdirs installdirs-am maintainer-clean \ + maintainer-clean-generic mostlyclean mostlyclean-generic \ + mostlyclean-libtool pdf pdf-am ps ps-am tags tags-am uninstall \ + uninstall-am # Tell versions [3.59,3.63) of GNU make to not export all variables. diff --git a/contrib/openpam/README b/contrib/openpam/README index 02851d1066b1..2fe00efe47ba 100644 --- a/contrib/openpam/README +++ b/contrib/openpam/README @@ -24,4 +24,4 @@ These are some of OpenPAM's features: Please direct bug reports and inquiries to . -$Id: README 424 2009-10-29 17:10:22Z des $ +$Id: README 648 2013-03-05 17:54:27Z des $ diff --git a/contrib/openpam/RELNOTES b/contrib/openpam/RELNOTES index 536460158a0f..4518551c1e3d 100644 --- a/contrib/openpam/RELNOTES +++ b/contrib/openpam/RELNOTES @@ -1,27 +1,24 @@ - Release notes for OpenPAM Micrampelis - ===================================== + Release notes for OpenPAM Nummularia + ==================================== This release corresponds to the code used in FreeBSD HEAD as of the release date, and is also expected to work on almost any POSIX-like platform that has GNU autotools, GNU make and the GNU compiler suite installed. -The library itself is complete. Documentation exists in the form of -man pages for the library functions. These man pages are generated by -a Perl script from specially marked-up comments in the source files -themselves, which minimizes the chance that any of them should be out -of date. +The distribution consists of the following components: -The distribution also includes three sample modules (pam_deny, -pam_permit and pam_unix) and a sample application (su). These are not -intended for actual use, but rather to serve as examples for module or -application developers. It also includes a command-line application -(pamtest) which can be used to test policies and modules. + - The PAM library itself, with complete API documentation. -Unit tests for limited portions of the library can be found in the t -subdirectory. + - Sample modules (pam_permit, pam_deny and pam_unix) and a sample + application (su) which demonstrate how to use PAM. + + - A test application (pamtest) which can be used to test policies and + modules. + + - Unit tests for limited portions of the libraries. Please direct bug reports and inquiries to . -$Id: RELNOTES 609 2012-05-26 13:57:45Z des $ +$Id: RELNOTES 741 2013-09-07 13:34:02Z des $ diff --git a/contrib/openpam/TODO b/contrib/openpam/TODO index 2d0af16aa988..d245361782bc 100644 --- a/contrib/openpam/TODO +++ b/contrib/openpam/TODO @@ -1,13 +1,17 @@ Before the next release: - - Complete the transition from PAM_LOG_DEBUG to PAM_LOG_LIBDEBUG. + - Rewrite openpam_ttyconv(3). + - mostly done, needs review. -Whenever: + - Fix try_first_pass / use_first_pass (pam_get_authtok() code & + documentation are slightly incorrect, OpenPAM's pam_unix(8) is + incorrect, all FreeBSD modules are broken) - - Implement mechanism to enable / disable optional features. Use it - to disable strict error checking so pamtest and unit tests can do - things that we don't allow in production. + - Add loop detection to openpam_load_chain(). - - Rewrite the module-loading code. + - Look into the possibility of implementing a version of (or a + wrapper for) openpam_log() which respects the PAM_SILENT flag and + the no_warn module option. This would eliminate the need for + FreeBSD's _pam_verbose_error(). -$Id: TODO 592 2012-04-08 13:19:51Z des $ +$Id: TODO 736 2013-09-07 12:52:42Z des $ diff --git a/contrib/openpam/aclocal.m4 b/contrib/openpam/aclocal.m4 index 99ed44a00270..9a730e043752 100644 --- a/contrib/openpam/aclocal.m4 +++ b/contrib/openpam/aclocal.m4 @@ -1,7 +1,7 @@ -# generated automatically by aclocal 1.11.1 -*- Autoconf -*- +# generated automatically by aclocal 1.14 -*- Autoconf -*- + +# Copyright (C) 1996-2013 Free Software Foundation, Inc. -# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, -# 2005, 2006, 2007, 2008, 2009 Free Software Foundation, Inc. # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. @@ -11,8602 +11,16 @@ # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. +m4_ifndef([AC_CONFIG_MACRO_DIRS], [m4_defun([_AM_CONFIG_MACRO_DIRS], [])m4_defun([AC_CONFIG_MACRO_DIRS], [_AM_CONFIG_MACRO_DIRS($@)])]) m4_ifndef([AC_AUTOCONF_VERSION], [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl -m4_if(m4_defn([AC_AUTOCONF_VERSION]), [2.68],, -[m4_warning([this file was generated for autoconf 2.68. +m4_if(m4_defn([AC_AUTOCONF_VERSION]), [2.69],, +[m4_warning([this file was generated for autoconf 2.69. You have another version of autoconf. It may work, but is not guaranteed to. If you have problems, you may need to regenerate the build system entirely. -To do so, use the procedure documented by the package, typically `autoreconf'.])]) +To do so, use the procedure documented by the package, typically 'autoreconf'.])]) -# libtool.m4 - Configure libtool for the host system. -*-Autoconf-*- -# -# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005, -# 2006, 2007, 2008, 2009, 2010, 2011 Free Software -# Foundation, Inc. -# Written by Gordon Matzigkeit, 1996 -# -# This file is free software; the Free Software Foundation gives -# unlimited permission to copy and/or distribute it, with or without -# modifications, as long as this notice is preserved. - -m4_define([_LT_COPYING], [dnl -# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005, -# 2006, 2007, 2008, 2009, 2010, 2011 Free Software -# Foundation, Inc. -# Written by Gordon Matzigkeit, 1996 -# -# This file is part of GNU Libtool. -# -# GNU Libtool is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License as -# published by the Free Software Foundation; either version 2 of -# the License, or (at your option) any later version. -# -# As a special exception to the GNU General Public License, -# if you distribute this file as part of a program or library that -# is built using GNU Libtool, you may include this file under the -# same distribution terms that you use for the rest of that program. -# -# GNU Libtool is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with GNU Libtool; see the file COPYING. If not, a copy -# can be downloaded from http://www.gnu.org/licenses/gpl.html, or -# obtained by writing to the Free Software Foundation, Inc., -# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -]) - -# serial 57 LT_INIT - - -# LT_PREREQ(VERSION) -# ------------------ -# Complain and exit if this libtool version is less that VERSION. -m4_defun([LT_PREREQ], -[m4_if(m4_version_compare(m4_defn([LT_PACKAGE_VERSION]), [$1]), -1, - [m4_default([$3], - [m4_fatal([Libtool version $1 or higher is required], - 63)])], - [$2])]) - - -# _LT_CHECK_BUILDDIR -# ------------------ -# Complain if the absolute build directory name contains unusual characters -m4_defun([_LT_CHECK_BUILDDIR], -[case `pwd` in - *\ * | *\ *) - AC_MSG_WARN([Libtool does not cope well with whitespace in `pwd`]) ;; -esac -]) - - -# LT_INIT([OPTIONS]) -# ------------------ -AC_DEFUN([LT_INIT], -[AC_PREREQ([2.58])dnl We use AC_INCLUDES_DEFAULT -AC_REQUIRE([AC_CONFIG_AUX_DIR_DEFAULT])dnl -AC_BEFORE([$0], [LT_LANG])dnl -AC_BEFORE([$0], [LT_OUTPUT])dnl -AC_BEFORE([$0], [LTDL_INIT])dnl -m4_require([_LT_CHECK_BUILDDIR])dnl - -dnl Autoconf doesn't catch unexpanded LT_ macros by default: -m4_pattern_forbid([^_?LT_[A-Z_]+$])dnl -m4_pattern_allow([^(_LT_EOF|LT_DLGLOBAL|LT_DLLAZY_OR_NOW|LT_MULTI_MODULE)$])dnl -dnl aclocal doesn't pull ltoptions.m4, ltsugar.m4, or ltversion.m4 -dnl unless we require an AC_DEFUNed macro: -AC_REQUIRE([LTOPTIONS_VERSION])dnl -AC_REQUIRE([LTSUGAR_VERSION])dnl -AC_REQUIRE([LTVERSION_VERSION])dnl -AC_REQUIRE([LTOBSOLETE_VERSION])dnl -m4_require([_LT_PROG_LTMAIN])dnl - -_LT_SHELL_INIT([SHELL=${CONFIG_SHELL-/bin/sh}]) - -dnl Parse OPTIONS -_LT_SET_OPTIONS([$0], [$1]) - -# This can be used to rebuild libtool when needed -LIBTOOL_DEPS="$ltmain" - -# Always use our own libtool. -LIBTOOL='$(SHELL) $(top_builddir)/libtool' -AC_SUBST(LIBTOOL)dnl - -_LT_SETUP - -# Only expand once: -m4_define([LT_INIT]) -])# LT_INIT - -# Old names: -AU_ALIAS([AC_PROG_LIBTOOL], [LT_INIT]) -AU_ALIAS([AM_PROG_LIBTOOL], [LT_INIT]) -dnl aclocal-1.4 backwards compatibility: -dnl AC_DEFUN([AC_PROG_LIBTOOL], []) -dnl AC_DEFUN([AM_PROG_LIBTOOL], []) - - -# _LT_CC_BASENAME(CC) -# ------------------- -# Calculate cc_basename. Skip known compiler wrappers and cross-prefix. -m4_defun([_LT_CC_BASENAME], -[for cc_temp in $1""; do - case $cc_temp in - compile | *[[\\/]]compile | ccache | *[[\\/]]ccache ) ;; - distcc | *[[\\/]]distcc | purify | *[[\\/]]purify ) ;; - \-*) ;; - *) break;; - esac -done -cc_basename=`$ECHO "$cc_temp" | $SED "s%.*/%%; s%^$host_alias-%%"` -]) - - -# _LT_FILEUTILS_DEFAULTS -# ---------------------- -# It is okay to use these file commands and assume they have been set -# sensibly after `m4_require([_LT_FILEUTILS_DEFAULTS])'. -m4_defun([_LT_FILEUTILS_DEFAULTS], -[: ${CP="cp -f"} -: ${MV="mv -f"} -: ${RM="rm -f"} -])# _LT_FILEUTILS_DEFAULTS - - -# _LT_SETUP -# --------- -m4_defun([_LT_SETUP], -[AC_REQUIRE([AC_CANONICAL_HOST])dnl -AC_REQUIRE([AC_CANONICAL_BUILD])dnl -AC_REQUIRE([_LT_PREPARE_SED_QUOTE_VARS])dnl -AC_REQUIRE([_LT_PROG_ECHO_BACKSLASH])dnl - -_LT_DECL([], [PATH_SEPARATOR], [1], [The PATH separator for the build system])dnl -dnl -_LT_DECL([], [host_alias], [0], [The host system])dnl -_LT_DECL([], [host], [0])dnl -_LT_DECL([], [host_os], [0])dnl -dnl -_LT_DECL([], [build_alias], [0], [The build system])dnl -_LT_DECL([], [build], [0])dnl -_LT_DECL([], [build_os], [0])dnl -dnl -AC_REQUIRE([AC_PROG_CC])dnl -AC_REQUIRE([LT_PATH_LD])dnl -AC_REQUIRE([LT_PATH_NM])dnl -dnl -AC_REQUIRE([AC_PROG_LN_S])dnl -test -z "$LN_S" && LN_S="ln -s" -_LT_DECL([], [LN_S], [1], [Whether we need soft or hard links])dnl -dnl -AC_REQUIRE([LT_CMD_MAX_LEN])dnl -_LT_DECL([objext], [ac_objext], [0], [Object file suffix (normally "o")])dnl -_LT_DECL([], [exeext], [0], [Executable file suffix (normally "")])dnl -dnl -m4_require([_LT_FILEUTILS_DEFAULTS])dnl -m4_require([_LT_CHECK_SHELL_FEATURES])dnl -m4_require([_LT_PATH_CONVERSION_FUNCTIONS])dnl -m4_require([_LT_CMD_RELOAD])dnl -m4_require([_LT_CHECK_MAGIC_METHOD])dnl -m4_require([_LT_CHECK_SHAREDLIB_FROM_LINKLIB])dnl -m4_require([_LT_CMD_OLD_ARCHIVE])dnl -m4_require([_LT_CMD_GLOBAL_SYMBOLS])dnl -m4_require([_LT_WITH_SYSROOT])dnl - -_LT_CONFIG_LIBTOOL_INIT([ -# See if we are running on zsh, and set the options which allow our -# commands through without removal of \ escapes INIT. -if test -n "\${ZSH_VERSION+set}" ; then - setopt NO_GLOB_SUBST -fi -]) -if test -n "${ZSH_VERSION+set}" ; then - setopt NO_GLOB_SUBST -fi - -_LT_CHECK_OBJDIR - -m4_require([_LT_TAG_COMPILER])dnl - -case $host_os in -aix3*) - # AIX sometimes has problems with the GCC collect2 program. For some - # reason, if we set the COLLECT_NAMES environment variable, the problems - # vanish in a puff of smoke. - if test "X${COLLECT_NAMES+set}" != Xset; then - COLLECT_NAMES= - export COLLECT_NAMES - fi - ;; -esac - -# Global variables: -ofile=libtool -can_build_shared=yes - -# All known linkers require a `.a' archive for static linking (except MSVC, -# which needs '.lib'). -libext=a - -with_gnu_ld="$lt_cv_prog_gnu_ld" - -old_CC="$CC" -old_CFLAGS="$CFLAGS" - -# Set sane defaults for various variables -test -z "$CC" && CC=cc -test -z "$LTCC" && LTCC=$CC -test -z "$LTCFLAGS" && LTCFLAGS=$CFLAGS -test -z "$LD" && LD=ld -test -z "$ac_objext" && ac_objext=o - -_LT_CC_BASENAME([$compiler]) - -# Only perform the check for file, if the check method requires it -test -z "$MAGIC_CMD" && MAGIC_CMD=file -case $deplibs_check_method in -file_magic*) - if test "$file_magic_cmd" = '$MAGIC_CMD'; then - _LT_PATH_MAGIC - fi - ;; -esac - -# Use C for the default configuration in the libtool script -LT_SUPPORTED_TAG([CC]) -_LT_LANG_C_CONFIG -_LT_LANG_DEFAULT_CONFIG -_LT_CONFIG_COMMANDS -])# _LT_SETUP - - -# _LT_PREPARE_SED_QUOTE_VARS -# -------------------------- -# Define a few sed substitution that help us do robust quoting. -m4_defun([_LT_PREPARE_SED_QUOTE_VARS], -[# Backslashify metacharacters that are still active within -# double-quoted strings. -sed_quote_subst='s/\([["`$\\]]\)/\\\1/g' - -# Same as above, but do not quote variable references. -double_quote_subst='s/\([["`\\]]\)/\\\1/g' - -# Sed substitution to delay expansion of an escaped shell variable in a -# double_quote_subst'ed string. -delay_variable_subst='s/\\\\\\\\\\\$/\\\\\\$/g' - -# Sed substitution to delay expansion of an escaped single quote. -delay_single_quote_subst='s/'\''/'\'\\\\\\\'\''/g' - -# Sed substitution to avoid accidental globbing in evaled expressions -no_glob_subst='s/\*/\\\*/g' -]) - -# _LT_PROG_LTMAIN -# --------------- -# Note that this code is called both from `configure', and `config.status' -# now that we use AC_CONFIG_COMMANDS to generate libtool. Notably, -# `config.status' has no value for ac_aux_dir unless we are using Automake, -# so we pass a copy along to make sure it has a sensible value anyway. -m4_defun([_LT_PROG_LTMAIN], -[m4_ifdef([AC_REQUIRE_AUX_FILE], [AC_REQUIRE_AUX_FILE([ltmain.sh])])dnl -_LT_CONFIG_LIBTOOL_INIT([ac_aux_dir='$ac_aux_dir']) -ltmain="$ac_aux_dir/ltmain.sh" -])# _LT_PROG_LTMAIN - - - -# So that we can recreate a full libtool script including additional -# tags, we accumulate the chunks of code to send to AC_CONFIG_COMMANDS -# in macros and then make a single call at the end using the `libtool' -# label. - - -# _LT_CONFIG_LIBTOOL_INIT([INIT-COMMANDS]) -# ---------------------------------------- -# Register INIT-COMMANDS to be passed to AC_CONFIG_COMMANDS later. -m4_define([_LT_CONFIG_LIBTOOL_INIT], -[m4_ifval([$1], - [m4_append([_LT_OUTPUT_LIBTOOL_INIT], - [$1 -])])]) - -# Initialize. -m4_define([_LT_OUTPUT_LIBTOOL_INIT]) - - -# _LT_CONFIG_LIBTOOL([COMMANDS]) -# ------------------------------ -# Register COMMANDS to be passed to AC_CONFIG_COMMANDS later. -m4_define([_LT_CONFIG_LIBTOOL], -[m4_ifval([$1], - [m4_append([_LT_OUTPUT_LIBTOOL_COMMANDS], - [$1 -])])]) - -# Initialize. -m4_define([_LT_OUTPUT_LIBTOOL_COMMANDS]) - - -# _LT_CONFIG_SAVE_COMMANDS([COMMANDS], [INIT_COMMANDS]) -# ----------------------------------------------------- -m4_defun([_LT_CONFIG_SAVE_COMMANDS], -[_LT_CONFIG_LIBTOOL([$1]) -_LT_CONFIG_LIBTOOL_INIT([$2]) -]) - - -# _LT_FORMAT_COMMENT([COMMENT]) -# ----------------------------- -# Add leading comment marks to the start of each line, and a trailing -# full-stop to the whole comment if one is not present already. -m4_define([_LT_FORMAT_COMMENT], -[m4_ifval([$1], [ -m4_bpatsubst([m4_bpatsubst([$1], [^ *], [# ])], - [['`$\]], [\\\&])]m4_bmatch([$1], [[!?.]$], [], [.]) -)]) - - - - - -# _LT_DECL([CONFIGNAME], VARNAME, VALUE, [DESCRIPTION], [IS-TAGGED?]) -# ------------------------------------------------------------------- -# CONFIGNAME is the name given to the value in the libtool script. -# VARNAME is the (base) name used in the configure script. -# VALUE may be 0, 1 or 2 for a computed quote escaped value based on -# VARNAME. Any other value will be used directly. -m4_define([_LT_DECL], -[lt_if_append_uniq([lt_decl_varnames], [$2], [, ], - [lt_dict_add_subkey([lt_decl_dict], [$2], [libtool_name], - [m4_ifval([$1], [$1], [$2])]) - lt_dict_add_subkey([lt_decl_dict], [$2], [value], [$3]) - m4_ifval([$4], - [lt_dict_add_subkey([lt_decl_dict], [$2], [description], [$4])]) - lt_dict_add_subkey([lt_decl_dict], [$2], - [tagged?], [m4_ifval([$5], [yes], [no])])]) -]) - - -# _LT_TAGDECL([CONFIGNAME], VARNAME, VALUE, [DESCRIPTION]) -# -------------------------------------------------------- -m4_define([_LT_TAGDECL], [_LT_DECL([$1], [$2], [$3], [$4], [yes])]) - - -# lt_decl_tag_varnames([SEPARATOR], [VARNAME1...]) -# ------------------------------------------------ -m4_define([lt_decl_tag_varnames], -[_lt_decl_filter([tagged?], [yes], $@)]) - - -# _lt_decl_filter(SUBKEY, VALUE, [SEPARATOR], [VARNAME1..]) -# --------------------------------------------------------- -m4_define([_lt_decl_filter], -[m4_case([$#], - [0], [m4_fatal([$0: too few arguments: $#])], - [1], [m4_fatal([$0: too few arguments: $#: $1])], - [2], [lt_dict_filter([lt_decl_dict], [$1], [$2], [], lt_decl_varnames)], - [3], [lt_dict_filter([lt_decl_dict], [$1], [$2], [$3], lt_decl_varnames)], - [lt_dict_filter([lt_decl_dict], $@)])[]dnl -]) - - -# lt_decl_quote_varnames([SEPARATOR], [VARNAME1...]) -# -------------------------------------------------- -m4_define([lt_decl_quote_varnames], -[_lt_decl_filter([value], [1], $@)]) - - -# lt_decl_dquote_varnames([SEPARATOR], [VARNAME1...]) -# --------------------------------------------------- -m4_define([lt_decl_dquote_varnames], -[_lt_decl_filter([value], [2], $@)]) - - -# lt_decl_varnames_tagged([SEPARATOR], [VARNAME1...]) -# --------------------------------------------------- -m4_define([lt_decl_varnames_tagged], -[m4_assert([$# <= 2])dnl -_$0(m4_quote(m4_default([$1], [[, ]])), - m4_ifval([$2], [[$2]], [m4_dquote(lt_decl_tag_varnames)]), - m4_split(m4_normalize(m4_quote(_LT_TAGS)), [ ]))]) -m4_define([_lt_decl_varnames_tagged], -[m4_ifval([$3], [lt_combine([$1], [$2], [_], $3)])]) - - -# lt_decl_all_varnames([SEPARATOR], [VARNAME1...]) -# ------------------------------------------------ -m4_define([lt_decl_all_varnames], -[_$0(m4_quote(m4_default([$1], [[, ]])), - m4_if([$2], [], - m4_quote(lt_decl_varnames), - m4_quote(m4_shift($@))))[]dnl -]) -m4_define([_lt_decl_all_varnames], -[lt_join($@, lt_decl_varnames_tagged([$1], - lt_decl_tag_varnames([[, ]], m4_shift($@))))dnl -]) - - -# _LT_CONFIG_STATUS_DECLARE([VARNAME]) -# ------------------------------------ -# Quote a variable value, and forward it to `config.status' so that its -# declaration there will have the same value as in `configure'. VARNAME -# must have a single quote delimited value for this to work. -m4_define([_LT_CONFIG_STATUS_DECLARE], -[$1='`$ECHO "$][$1" | $SED "$delay_single_quote_subst"`']) - - -# _LT_CONFIG_STATUS_DECLARATIONS -# ------------------------------ -# We delimit libtool config variables with single quotes, so when -# we write them to config.status, we have to be sure to quote all -# embedded single quotes properly. In configure, this macro expands -# each variable declared with _LT_DECL (and _LT_TAGDECL) into: -# -# ='`$ECHO "$" | $SED "$delay_single_quote_subst"`' -m4_defun([_LT_CONFIG_STATUS_DECLARATIONS], -[m4_foreach([_lt_var], m4_quote(lt_decl_all_varnames), - [m4_n([_LT_CONFIG_STATUS_DECLARE(_lt_var)])])]) - - -# _LT_LIBTOOL_TAGS -# ---------------- -# Output comment and list of tags supported by the script -m4_defun([_LT_LIBTOOL_TAGS], -[_LT_FORMAT_COMMENT([The names of the tagged configurations supported by this script])dnl -available_tags="_LT_TAGS"dnl -]) - - -# _LT_LIBTOOL_DECLARE(VARNAME, [TAG]) -# ----------------------------------- -# Extract the dictionary values for VARNAME (optionally with TAG) and -# expand to a commented shell variable setting: -# -# # Some comment about what VAR is for. -# visible_name=$lt_internal_name -m4_define([_LT_LIBTOOL_DECLARE], -[_LT_FORMAT_COMMENT(m4_quote(lt_dict_fetch([lt_decl_dict], [$1], - [description])))[]dnl -m4_pushdef([_libtool_name], - m4_quote(lt_dict_fetch([lt_decl_dict], [$1], [libtool_name])))[]dnl -m4_case(m4_quote(lt_dict_fetch([lt_decl_dict], [$1], [value])), - [0], [_libtool_name=[$]$1], - [1], [_libtool_name=$lt_[]$1], - [2], [_libtool_name=$lt_[]$1], - [_libtool_name=lt_dict_fetch([lt_decl_dict], [$1], [value])])[]dnl -m4_ifval([$2], [_$2])[]m4_popdef([_libtool_name])[]dnl -]) - - -# _LT_LIBTOOL_CONFIG_VARS -# ----------------------- -# Produce commented declarations of non-tagged libtool config variables -# suitable for insertion in the LIBTOOL CONFIG section of the `libtool' -# script. Tagged libtool config variables (even for the LIBTOOL CONFIG -# section) are produced by _LT_LIBTOOL_TAG_VARS. -m4_defun([_LT_LIBTOOL_CONFIG_VARS], -[m4_foreach([_lt_var], - m4_quote(_lt_decl_filter([tagged?], [no], [], lt_decl_varnames)), - [m4_n([_LT_LIBTOOL_DECLARE(_lt_var)])])]) - - -# _LT_LIBTOOL_TAG_VARS(TAG) -# ------------------------- -m4_define([_LT_LIBTOOL_TAG_VARS], -[m4_foreach([_lt_var], m4_quote(lt_decl_tag_varnames), - [m4_n([_LT_LIBTOOL_DECLARE(_lt_var, [$1])])])]) - - -# _LT_TAGVAR(VARNAME, [TAGNAME]) -# ------------------------------ -m4_define([_LT_TAGVAR], [m4_ifval([$2], [$1_$2], [$1])]) - - -# _LT_CONFIG_COMMANDS -# ------------------- -# Send accumulated output to $CONFIG_STATUS. Thanks to the lists of -# variables for single and double quote escaping we saved from calls -# to _LT_DECL, we can put quote escaped variables declarations -# into `config.status', and then the shell code to quote escape them in -# for loops in `config.status'. Finally, any additional code accumulated -# from calls to _LT_CONFIG_LIBTOOL_INIT is expanded. -m4_defun([_LT_CONFIG_COMMANDS], -[AC_PROVIDE_IFELSE([LT_OUTPUT], - dnl If the libtool generation code has been placed in $CONFIG_LT, - dnl instead of duplicating it all over again into config.status, - dnl then we will have config.status run $CONFIG_LT later, so it - dnl needs to know what name is stored there: - [AC_CONFIG_COMMANDS([libtool], - [$SHELL $CONFIG_LT || AS_EXIT(1)], [CONFIG_LT='$CONFIG_LT'])], - dnl If the libtool generation code is destined for config.status, - dnl expand the accumulated commands and init code now: - [AC_CONFIG_COMMANDS([libtool], - [_LT_OUTPUT_LIBTOOL_COMMANDS], [_LT_OUTPUT_LIBTOOL_COMMANDS_INIT])]) -])#_LT_CONFIG_COMMANDS - - -# Initialize. -m4_define([_LT_OUTPUT_LIBTOOL_COMMANDS_INIT], -[ - -# The HP-UX ksh and POSIX shell print the target directory to stdout -# if CDPATH is set. -(unset CDPATH) >/dev/null 2>&1 && unset CDPATH - -sed_quote_subst='$sed_quote_subst' -double_quote_subst='$double_quote_subst' -delay_variable_subst='$delay_variable_subst' -_LT_CONFIG_STATUS_DECLARATIONS -LTCC='$LTCC' -LTCFLAGS='$LTCFLAGS' -compiler='$compiler_DEFAULT' - -# A function that is used when there is no print builtin or printf. -func_fallback_echo () -{ - eval 'cat <<_LTECHO_EOF -\$[]1 -_LTECHO_EOF' -} - -# Quote evaled strings. -for var in lt_decl_all_varnames([[ \ -]], lt_decl_quote_varnames); do - case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in - *[[\\\\\\\`\\"\\\$]]*) - eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED \\"\\\$sed_quote_subst\\"\\\`\\\\\\"" - ;; - *) - eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\"" - ;; - esac -done - -# Double-quote double-evaled strings. -for var in lt_decl_all_varnames([[ \ -]], lt_decl_dquote_varnames); do - case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in - *[[\\\\\\\`\\"\\\$]]*) - eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED -e \\"\\\$double_quote_subst\\" -e \\"\\\$sed_quote_subst\\" -e \\"\\\$delay_variable_subst\\"\\\`\\\\\\"" - ;; - *) - eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\"" - ;; - esac -done - -_LT_OUTPUT_LIBTOOL_INIT -]) - -# _LT_GENERATED_FILE_INIT(FILE, [COMMENT]) -# ------------------------------------ -# Generate a child script FILE with all initialization necessary to -# reuse the environment learned by the parent script, and make the -# file executable. If COMMENT is supplied, it is inserted after the -# `#!' sequence but before initialization text begins. After this -# macro, additional text can be appended to FILE to form the body of -# the child script. The macro ends with non-zero status if the -# file could not be fully written (such as if the disk is full). -m4_ifdef([AS_INIT_GENERATED], -[m4_defun([_LT_GENERATED_FILE_INIT],[AS_INIT_GENERATED($@)])], -[m4_defun([_LT_GENERATED_FILE_INIT], -[m4_require([AS_PREPARE])]dnl -[m4_pushdef([AS_MESSAGE_LOG_FD])]dnl -[lt_write_fail=0 -cat >$1 <<_ASEOF || lt_write_fail=1 -#! $SHELL -# Generated by $as_me. -$2 -SHELL=\${CONFIG_SHELL-$SHELL} -export SHELL -_ASEOF -cat >>$1 <<\_ASEOF || lt_write_fail=1 -AS_SHELL_SANITIZE -_AS_PREPARE -exec AS_MESSAGE_FD>&1 -_ASEOF -test $lt_write_fail = 0 && chmod +x $1[]dnl -m4_popdef([AS_MESSAGE_LOG_FD])])])# _LT_GENERATED_FILE_INIT - -# LT_OUTPUT -# --------- -# This macro allows early generation of the libtool script (before -# AC_OUTPUT is called), incase it is used in configure for compilation -# tests. -AC_DEFUN([LT_OUTPUT], -[: ${CONFIG_LT=./config.lt} -AC_MSG_NOTICE([creating $CONFIG_LT]) -_LT_GENERATED_FILE_INIT(["$CONFIG_LT"], -[# Run this file to recreate a libtool stub with the current configuration.]) - -cat >>"$CONFIG_LT" <<\_LTEOF -lt_cl_silent=false -exec AS_MESSAGE_LOG_FD>>config.log -{ - echo - AS_BOX([Running $as_me.]) -} >&AS_MESSAGE_LOG_FD - -lt_cl_help="\ -\`$as_me' creates a local libtool stub from the current configuration, -for use in further configure time tests before the real libtool is -generated. - -Usage: $[0] [[OPTIONS]] - - -h, --help print this help, then exit - -V, --version print version number, then exit - -q, --quiet do not print progress messages - -d, --debug don't remove temporary files - -Report bugs to ." - -lt_cl_version="\ -m4_ifset([AC_PACKAGE_NAME], [AC_PACKAGE_NAME ])config.lt[]dnl -m4_ifset([AC_PACKAGE_VERSION], [ AC_PACKAGE_VERSION]) -configured by $[0], generated by m4_PACKAGE_STRING. - -Copyright (C) 2011 Free Software Foundation, Inc. -This config.lt script is free software; the Free Software Foundation -gives unlimited permision to copy, distribute and modify it." - -while test $[#] != 0 -do - case $[1] in - --version | --v* | -V ) - echo "$lt_cl_version"; exit 0 ;; - --help | --h* | -h ) - echo "$lt_cl_help"; exit 0 ;; - --debug | --d* | -d ) - debug=: ;; - --quiet | --q* | --silent | --s* | -q ) - lt_cl_silent=: ;; - - -*) AC_MSG_ERROR([unrecognized option: $[1] -Try \`$[0] --help' for more information.]) ;; - - *) AC_MSG_ERROR([unrecognized argument: $[1] -Try \`$[0] --help' for more information.]) ;; - esac - shift -done - -if $lt_cl_silent; then - exec AS_MESSAGE_FD>/dev/null -fi -_LTEOF - -cat >>"$CONFIG_LT" <<_LTEOF -_LT_OUTPUT_LIBTOOL_COMMANDS_INIT -_LTEOF - -cat >>"$CONFIG_LT" <<\_LTEOF -AC_MSG_NOTICE([creating $ofile]) -_LT_OUTPUT_LIBTOOL_COMMANDS -AS_EXIT(0) -_LTEOF -chmod +x "$CONFIG_LT" - -# configure is writing to config.log, but config.lt does its own redirection, -# appending to config.log, which fails on DOS, as config.log is still kept -# open by configure. Here we exec the FD to /dev/null, effectively closing -# config.log, so it can be properly (re)opened and appended to by config.lt. -lt_cl_success=: -test "$silent" = yes && - lt_config_lt_args="$lt_config_lt_args --quiet" -exec AS_MESSAGE_LOG_FD>/dev/null -$SHELL "$CONFIG_LT" $lt_config_lt_args || lt_cl_success=false -exec AS_MESSAGE_LOG_FD>>config.log -$lt_cl_success || AS_EXIT(1) -])# LT_OUTPUT - - -# _LT_CONFIG(TAG) -# --------------- -# If TAG is the built-in tag, create an initial libtool script with a -# default configuration from the untagged config vars. Otherwise add code -# to config.status for appending the configuration named by TAG from the -# matching tagged config vars. -m4_defun([_LT_CONFIG], -[m4_require([_LT_FILEUTILS_DEFAULTS])dnl -_LT_CONFIG_SAVE_COMMANDS([ - m4_define([_LT_TAG], m4_if([$1], [], [C], [$1]))dnl - m4_if(_LT_TAG, [C], [ - # See if we are running on zsh, and set the options which allow our - # commands through without removal of \ escapes. - if test -n "${ZSH_VERSION+set}" ; then - setopt NO_GLOB_SUBST - fi - - cfgfile="${ofile}T" - trap "$RM \"$cfgfile\"; exit 1" 1 2 15 - $RM "$cfgfile" - - cat <<_LT_EOF >> "$cfgfile" -#! $SHELL - -# `$ECHO "$ofile" | sed 's%^.*/%%'` - Provide generalized library-building support services. -# Generated automatically by $as_me ($PACKAGE$TIMESTAMP) $VERSION -# Libtool was configured on host `(hostname || uname -n) 2>/dev/null | sed 1q`: -# NOTE: Changes made to this file will be lost: look at ltmain.sh. -# -_LT_COPYING -_LT_LIBTOOL_TAGS - -# ### BEGIN LIBTOOL CONFIG -_LT_LIBTOOL_CONFIG_VARS -_LT_LIBTOOL_TAG_VARS -# ### END LIBTOOL CONFIG - -_LT_EOF - - case $host_os in - aix3*) - cat <<\_LT_EOF >> "$cfgfile" -# AIX sometimes has problems with the GCC collect2 program. For some -# reason, if we set the COLLECT_NAMES environment variable, the problems -# vanish in a puff of smoke. -if test "X${COLLECT_NAMES+set}" != Xset; then - COLLECT_NAMES= - export COLLECT_NAMES -fi -_LT_EOF - ;; - esac - - _LT_PROG_LTMAIN - - # We use sed instead of cat because bash on DJGPP gets confused if - # if finds mixed CR/LF and LF-only lines. Since sed operates in - # text mode, it properly converts lines to CR/LF. This bash problem - # is reportedly fixed, but why not run on old versions too? - sed '$q' "$ltmain" >> "$cfgfile" \ - || (rm -f "$cfgfile"; exit 1) - - _LT_PROG_REPLACE_SHELLFNS - - mv -f "$cfgfile" "$ofile" || - (rm -f "$ofile" && cp "$cfgfile" "$ofile" && rm -f "$cfgfile") - chmod +x "$ofile" -], -[cat <<_LT_EOF >> "$ofile" - -dnl Unfortunately we have to use $1 here, since _LT_TAG is not expanded -dnl in a comment (ie after a #). -# ### BEGIN LIBTOOL TAG CONFIG: $1 -_LT_LIBTOOL_TAG_VARS(_LT_TAG) -# ### END LIBTOOL TAG CONFIG: $1 -_LT_EOF -])dnl /m4_if -], -[m4_if([$1], [], [ - PACKAGE='$PACKAGE' - VERSION='$VERSION' - TIMESTAMP='$TIMESTAMP' - RM='$RM' - ofile='$ofile'], []) -])dnl /_LT_CONFIG_SAVE_COMMANDS -])# _LT_CONFIG - - -# LT_SUPPORTED_TAG(TAG) -# --------------------- -# Trace this macro to discover what tags are supported by the libtool -# --tag option, using: -# autoconf --trace 'LT_SUPPORTED_TAG:$1' -AC_DEFUN([LT_SUPPORTED_TAG], []) - - -# C support is built-in for now -m4_define([_LT_LANG_C_enabled], []) -m4_define([_LT_TAGS], []) - - -# LT_LANG(LANG) -# ------------- -# Enable libtool support for the given language if not already enabled. -AC_DEFUN([LT_LANG], -[AC_BEFORE([$0], [LT_OUTPUT])dnl -m4_case([$1], - [C], [_LT_LANG(C)], - [C++], [_LT_LANG(CXX)], - [Go], [_LT_LANG(GO)], - [Java], [_LT_LANG(GCJ)], - [Fortran 77], [_LT_LANG(F77)], - [Fortran], [_LT_LANG(FC)], - [Windows Resource], [_LT_LANG(RC)], - [m4_ifdef([_LT_LANG_]$1[_CONFIG], - [_LT_LANG($1)], - [m4_fatal([$0: unsupported language: "$1"])])])dnl -])# LT_LANG - - -# _LT_LANG(LANGNAME) -# ------------------ -m4_defun([_LT_LANG], -[m4_ifdef([_LT_LANG_]$1[_enabled], [], - [LT_SUPPORTED_TAG([$1])dnl - m4_append([_LT_TAGS], [$1 ])dnl - m4_define([_LT_LANG_]$1[_enabled], [])dnl - _LT_LANG_$1_CONFIG($1)])dnl -])# _LT_LANG - - -m4_ifndef([AC_PROG_GO], [ -# NOTE: This macro has been submitted for inclusion into # -# GNU Autoconf as AC_PROG_GO. When it is available in # -# a released version of Autoconf we should remove this # -# macro and use it instead. # -m4_defun([AC_PROG_GO], -[AC_LANG_PUSH(Go)dnl -AC_ARG_VAR([GOC], [Go compiler command])dnl -AC_ARG_VAR([GOFLAGS], [Go compiler flags])dnl -_AC_ARG_VAR_LDFLAGS()dnl -AC_CHECK_TOOL(GOC, gccgo) -if test -z "$GOC"; then - if test -n "$ac_tool_prefix"; then - AC_CHECK_PROG(GOC, [${ac_tool_prefix}gccgo], [${ac_tool_prefix}gccgo]) - fi -fi -if test -z "$GOC"; then - AC_CHECK_PROG(GOC, gccgo, gccgo, false) -fi -])#m4_defun -])#m4_ifndef - - -# _LT_LANG_DEFAULT_CONFIG -# ----------------------- -m4_defun([_LT_LANG_DEFAULT_CONFIG], -[AC_PROVIDE_IFELSE([AC_PROG_CXX], - [LT_LANG(CXX)], - [m4_define([AC_PROG_CXX], defn([AC_PROG_CXX])[LT_LANG(CXX)])]) - -AC_PROVIDE_IFELSE([AC_PROG_F77], - [LT_LANG(F77)], - [m4_define([AC_PROG_F77], defn([AC_PROG_F77])[LT_LANG(F77)])]) - -AC_PROVIDE_IFELSE([AC_PROG_FC], - [LT_LANG(FC)], - [m4_define([AC_PROG_FC], defn([AC_PROG_FC])[LT_LANG(FC)])]) - -dnl The call to [A][M_PROG_GCJ] is quoted like that to stop aclocal -dnl pulling things in needlessly. -AC_PROVIDE_IFELSE([AC_PROG_GCJ], - [LT_LANG(GCJ)], - [AC_PROVIDE_IFELSE([A][M_PROG_GCJ], - [LT_LANG(GCJ)], - [AC_PROVIDE_IFELSE([LT_PROG_GCJ], - [LT_LANG(GCJ)], - [m4_ifdef([AC_PROG_GCJ], - [m4_define([AC_PROG_GCJ], defn([AC_PROG_GCJ])[LT_LANG(GCJ)])]) - m4_ifdef([A][M_PROG_GCJ], - [m4_define([A][M_PROG_GCJ], defn([A][M_PROG_GCJ])[LT_LANG(GCJ)])]) - m4_ifdef([LT_PROG_GCJ], - [m4_define([LT_PROG_GCJ], defn([LT_PROG_GCJ])[LT_LANG(GCJ)])])])])]) - -AC_PROVIDE_IFELSE([AC_PROG_GO], - [LT_LANG(GO)], - [m4_define([AC_PROG_GO], defn([AC_PROG_GO])[LT_LANG(GO)])]) - -AC_PROVIDE_IFELSE([LT_PROG_RC], - [LT_LANG(RC)], - [m4_define([LT_PROG_RC], defn([LT_PROG_RC])[LT_LANG(RC)])]) -])# _LT_LANG_DEFAULT_CONFIG - -# Obsolete macros: -AU_DEFUN([AC_LIBTOOL_CXX], [LT_LANG(C++)]) -AU_DEFUN([AC_LIBTOOL_F77], [LT_LANG(Fortran 77)]) -AU_DEFUN([AC_LIBTOOL_FC], [LT_LANG(Fortran)]) -AU_DEFUN([AC_LIBTOOL_GCJ], [LT_LANG(Java)]) -AU_DEFUN([AC_LIBTOOL_RC], [LT_LANG(Windows Resource)]) -dnl aclocal-1.4 backwards compatibility: -dnl AC_DEFUN([AC_LIBTOOL_CXX], []) -dnl AC_DEFUN([AC_LIBTOOL_F77], []) -dnl AC_DEFUN([AC_LIBTOOL_FC], []) -dnl AC_DEFUN([AC_LIBTOOL_GCJ], []) -dnl AC_DEFUN([AC_LIBTOOL_RC], []) - - -# _LT_TAG_COMPILER -# ---------------- -m4_defun([_LT_TAG_COMPILER], -[AC_REQUIRE([AC_PROG_CC])dnl - -_LT_DECL([LTCC], [CC], [1], [A C compiler])dnl -_LT_DECL([LTCFLAGS], [CFLAGS], [1], [LTCC compiler flags])dnl -_LT_TAGDECL([CC], [compiler], [1], [A language specific compiler])dnl -_LT_TAGDECL([with_gcc], [GCC], [0], [Is the compiler the GNU compiler?])dnl - -# If no C compiler was specified, use CC. -LTCC=${LTCC-"$CC"} - -# If no C compiler flags were specified, use CFLAGS. -LTCFLAGS=${LTCFLAGS-"$CFLAGS"} - -# Allow CC to be a program name with arguments. -compiler=$CC -])# _LT_TAG_COMPILER - - -# _LT_COMPILER_BOILERPLATE -# ------------------------ -# Check for compiler boilerplate output or warnings with -# the simple compiler test code. -m4_defun([_LT_COMPILER_BOILERPLATE], -[m4_require([_LT_DECL_SED])dnl -ac_outfile=conftest.$ac_objext -echo "$lt_simple_compile_test_code" >conftest.$ac_ext -eval "$ac_compile" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err -_lt_compiler_boilerplate=`cat conftest.err` -$RM conftest* -])# _LT_COMPILER_BOILERPLATE - - -# _LT_LINKER_BOILERPLATE -# ---------------------- -# Check for linker boilerplate output or warnings with -# the simple link test code. -m4_defun([_LT_LINKER_BOILERPLATE], -[m4_require([_LT_DECL_SED])dnl -ac_outfile=conftest.$ac_objext -echo "$lt_simple_link_test_code" >conftest.$ac_ext -eval "$ac_link" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err -_lt_linker_boilerplate=`cat conftest.err` -$RM -r conftest* -])# _LT_LINKER_BOILERPLATE - -# _LT_REQUIRED_DARWIN_CHECKS -# ------------------------- -m4_defun_once([_LT_REQUIRED_DARWIN_CHECKS],[ - case $host_os in - rhapsody* | darwin*) - AC_CHECK_TOOL([DSYMUTIL], [dsymutil], [:]) - AC_CHECK_TOOL([NMEDIT], [nmedit], [:]) - AC_CHECK_TOOL([LIPO], [lipo], [:]) - AC_CHECK_TOOL([OTOOL], [otool], [:]) - AC_CHECK_TOOL([OTOOL64], [otool64], [:]) - _LT_DECL([], [DSYMUTIL], [1], - [Tool to manipulate archived DWARF debug symbol files on Mac OS X]) - _LT_DECL([], [NMEDIT], [1], - [Tool to change global to local symbols on Mac OS X]) - _LT_DECL([], [LIPO], [1], - [Tool to manipulate fat objects and archives on Mac OS X]) - _LT_DECL([], [OTOOL], [1], - [ldd/readelf like tool for Mach-O binaries on Mac OS X]) - _LT_DECL([], [OTOOL64], [1], - [ldd/readelf like tool for 64 bit Mach-O binaries on Mac OS X 10.4]) - - AC_CACHE_CHECK([for -single_module linker flag],[lt_cv_apple_cc_single_mod], - [lt_cv_apple_cc_single_mod=no - if test -z "${LT_MULTI_MODULE}"; then - # By default we will add the -single_module flag. You can override - # by either setting the environment variable LT_MULTI_MODULE - # non-empty at configure time, or by adding -multi_module to the - # link flags. - rm -rf libconftest.dylib* - echo "int foo(void){return 1;}" > conftest.c - echo "$LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \ --dynamiclib -Wl,-single_module conftest.c" >&AS_MESSAGE_LOG_FD - $LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \ - -dynamiclib -Wl,-single_module conftest.c 2>conftest.err - _lt_result=$? - # If there is a non-empty error log, and "single_module" - # appears in it, assume the flag caused a linker warning - if test -s conftest.err && $GREP single_module conftest.err; then - cat conftest.err >&AS_MESSAGE_LOG_FD - # Otherwise, if the output was created with a 0 exit code from - # the compiler, it worked. - elif test -f libconftest.dylib && test $_lt_result -eq 0; then - lt_cv_apple_cc_single_mod=yes - else - cat conftest.err >&AS_MESSAGE_LOG_FD - fi - rm -rf libconftest.dylib* - rm -f conftest.* - fi]) - - AC_CACHE_CHECK([for -exported_symbols_list linker flag], - [lt_cv_ld_exported_symbols_list], - [lt_cv_ld_exported_symbols_list=no - save_LDFLAGS=$LDFLAGS - echo "_main" > conftest.sym - LDFLAGS="$LDFLAGS -Wl,-exported_symbols_list,conftest.sym" - AC_LINK_IFELSE([AC_LANG_PROGRAM([],[])], - [lt_cv_ld_exported_symbols_list=yes], - [lt_cv_ld_exported_symbols_list=no]) - LDFLAGS="$save_LDFLAGS" - ]) - - AC_CACHE_CHECK([for -force_load linker flag],[lt_cv_ld_force_load], - [lt_cv_ld_force_load=no - cat > conftest.c << _LT_EOF -int forced_loaded() { return 2;} -_LT_EOF - echo "$LTCC $LTCFLAGS -c -o conftest.o conftest.c" >&AS_MESSAGE_LOG_FD - $LTCC $LTCFLAGS -c -o conftest.o conftest.c 2>&AS_MESSAGE_LOG_FD - echo "$AR cru libconftest.a conftest.o" >&AS_MESSAGE_LOG_FD - $AR cru libconftest.a conftest.o 2>&AS_MESSAGE_LOG_FD - echo "$RANLIB libconftest.a" >&AS_MESSAGE_LOG_FD - $RANLIB libconftest.a 2>&AS_MESSAGE_LOG_FD - cat > conftest.c << _LT_EOF -int main() { return 0;} -_LT_EOF - echo "$LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a" >&AS_MESSAGE_LOG_FD - $LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a 2>conftest.err - _lt_result=$? - if test -s conftest.err && $GREP force_load conftest.err; then - cat conftest.err >&AS_MESSAGE_LOG_FD - elif test -f conftest && test $_lt_result -eq 0 && $GREP forced_load conftest >/dev/null 2>&1 ; then - lt_cv_ld_force_load=yes - else - cat conftest.err >&AS_MESSAGE_LOG_FD - fi - rm -f conftest.err libconftest.a conftest conftest.c - rm -rf conftest.dSYM - ]) - case $host_os in - rhapsody* | darwin1.[[012]]) - _lt_dar_allow_undefined='${wl}-undefined ${wl}suppress' ;; - darwin1.*) - _lt_dar_allow_undefined='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' ;; - darwin*) # darwin 5.x on - # if running on 10.5 or later, the deployment target defaults - # to the OS version, if on x86, and 10.4, the deployment - # target defaults to 10.4. Don't you love it? - case ${MACOSX_DEPLOYMENT_TARGET-10.0},$host in - 10.0,*86*-darwin8*|10.0,*-darwin[[91]]*) - _lt_dar_allow_undefined='${wl}-undefined ${wl}dynamic_lookup' ;; - 10.[[012]]*) - _lt_dar_allow_undefined='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' ;; - 10.*) - _lt_dar_allow_undefined='${wl}-undefined ${wl}dynamic_lookup' ;; - esac - ;; - esac - if test "$lt_cv_apple_cc_single_mod" = "yes"; then - _lt_dar_single_mod='$single_module' - fi - if test "$lt_cv_ld_exported_symbols_list" = "yes"; then - _lt_dar_export_syms=' ${wl}-exported_symbols_list,$output_objdir/${libname}-symbols.expsym' - else - _lt_dar_export_syms='~$NMEDIT -s $output_objdir/${libname}-symbols.expsym ${lib}' - fi - if test "$DSYMUTIL" != ":" && test "$lt_cv_ld_force_load" = "no"; then - _lt_dsymutil='~$DSYMUTIL $lib || :' - else - _lt_dsymutil= - fi - ;; - esac -]) - - -# _LT_DARWIN_LINKER_FEATURES([TAG]) -# --------------------------------- -# Checks for linker and compiler features on darwin -m4_defun([_LT_DARWIN_LINKER_FEATURES], -[ - m4_require([_LT_REQUIRED_DARWIN_CHECKS]) - _LT_TAGVAR(archive_cmds_need_lc, $1)=no - _LT_TAGVAR(hardcode_direct, $1)=no - _LT_TAGVAR(hardcode_automatic, $1)=yes - _LT_TAGVAR(hardcode_shlibpath_var, $1)=unsupported - if test "$lt_cv_ld_force_load" = "yes"; then - _LT_TAGVAR(whole_archive_flag_spec, $1)='`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience ${wl}-force_load,$conv\"; done; func_echo_all \"$new_convenience\"`' - m4_case([$1], [F77], [_LT_TAGVAR(compiler_needs_object, $1)=yes], - [FC], [_LT_TAGVAR(compiler_needs_object, $1)=yes]) - else - _LT_TAGVAR(whole_archive_flag_spec, $1)='' - fi - _LT_TAGVAR(link_all_deplibs, $1)=yes - _LT_TAGVAR(allow_undefined_flag, $1)="$_lt_dar_allow_undefined" - case $cc_basename in - ifort*) _lt_dar_can_shared=yes ;; - *) _lt_dar_can_shared=$GCC ;; - esac - if test "$_lt_dar_can_shared" = "yes"; then - output_verbose_link_cmd=func_echo_all - _LT_TAGVAR(archive_cmds, $1)="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod${_lt_dsymutil}" - _LT_TAGVAR(module_cmds, $1)="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dsymutil}" - _LT_TAGVAR(archive_expsym_cmds, $1)="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring ${_lt_dar_single_mod}${_lt_dar_export_syms}${_lt_dsymutil}" - _LT_TAGVAR(module_expsym_cmds, $1)="sed -e 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dar_export_syms}${_lt_dsymutil}" - m4_if([$1], [CXX], -[ if test "$lt_cv_apple_cc_single_mod" != "yes"; then - _LT_TAGVAR(archive_cmds, $1)="\$CC -r -keep_private_externs -nostdlib -o \${lib}-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \${lib}-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring${_lt_dsymutil}" - _LT_TAGVAR(archive_expsym_cmds, $1)="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -r -keep_private_externs -nostdlib -o \${lib}-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \${lib}-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring${_lt_dar_export_syms}${_lt_dsymutil}" - fi -],[]) - else - _LT_TAGVAR(ld_shlibs, $1)=no - fi -]) - -# _LT_SYS_MODULE_PATH_AIX([TAGNAME]) -# ---------------------------------- -# Links a minimal program and checks the executable -# for the system default hardcoded library path. In most cases, -# this is /usr/lib:/lib, but when the MPI compilers are used -# the location of the communication and MPI libs are included too. -# If we don't find anything, use the default library path according -# to the aix ld manual. -# Store the results from the different compilers for each TAGNAME. -# Allow to override them for all tags through lt_cv_aix_libpath. -m4_defun([_LT_SYS_MODULE_PATH_AIX], -[m4_require([_LT_DECL_SED])dnl -if test "${lt_cv_aix_libpath+set}" = set; then - aix_libpath=$lt_cv_aix_libpath -else - AC_CACHE_VAL([_LT_TAGVAR([lt_cv_aix_libpath_], [$1])], - [AC_LINK_IFELSE([AC_LANG_PROGRAM],[ - lt_aix_libpath_sed='[ - /Import File Strings/,/^$/ { - /^0/ { - s/^0 *\([^ ]*\) *$/\1/ - p - } - }]' - _LT_TAGVAR([lt_cv_aix_libpath_], [$1])=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` - # Check for a 64-bit object if we didn't find anything. - if test -z "$_LT_TAGVAR([lt_cv_aix_libpath_], [$1])"; then - _LT_TAGVAR([lt_cv_aix_libpath_], [$1])=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` - fi],[]) - if test -z "$_LT_TAGVAR([lt_cv_aix_libpath_], [$1])"; then - _LT_TAGVAR([lt_cv_aix_libpath_], [$1])="/usr/lib:/lib" - fi - ]) - aix_libpath=$_LT_TAGVAR([lt_cv_aix_libpath_], [$1]) -fi -])# _LT_SYS_MODULE_PATH_AIX - - -# _LT_SHELL_INIT(ARG) -# ------------------- -m4_define([_LT_SHELL_INIT], -[m4_divert_text([M4SH-INIT], [$1 -])])# _LT_SHELL_INIT - - - -# _LT_PROG_ECHO_BACKSLASH -# ----------------------- -# Find how we can fake an echo command that does not interpret backslash. -# In particular, with Autoconf 2.60 or later we add some code to the start -# of the generated configure script which will find a shell with a builtin -# printf (which we can use as an echo command). -m4_defun([_LT_PROG_ECHO_BACKSLASH], -[ECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' -ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO -ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO$ECHO - -AC_MSG_CHECKING([how to print strings]) -# Test print first, because it will be a builtin if present. -if test "X`( print -r -- -n ) 2>/dev/null`" = X-n && \ - test "X`print -r -- $ECHO 2>/dev/null`" = "X$ECHO"; then - ECHO='print -r --' -elif test "X`printf %s $ECHO 2>/dev/null`" = "X$ECHO"; then - ECHO='printf %s\n' -else - # Use this function as a fallback that always works. - func_fallback_echo () - { - eval 'cat <<_LTECHO_EOF -$[]1 -_LTECHO_EOF' - } - ECHO='func_fallback_echo' -fi - -# func_echo_all arg... -# Invoke $ECHO with all args, space-separated. -func_echo_all () -{ - $ECHO "$*" -} - -case "$ECHO" in - printf*) AC_MSG_RESULT([printf]) ;; - print*) AC_MSG_RESULT([print -r]) ;; - *) AC_MSG_RESULT([cat]) ;; -esac - -m4_ifdef([_AS_DETECT_SUGGESTED], -[_AS_DETECT_SUGGESTED([ - test -n "${ZSH_VERSION+set}${BASH_VERSION+set}" || ( - ECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' - ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO - ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO$ECHO - PATH=/empty FPATH=/empty; export PATH FPATH - test "X`printf %s $ECHO`" = "X$ECHO" \ - || test "X`print -r -- $ECHO`" = "X$ECHO" )])]) - -_LT_DECL([], [SHELL], [1], [Shell to use when invoking shell scripts]) -_LT_DECL([], [ECHO], [1], [An echo program that protects backslashes]) -])# _LT_PROG_ECHO_BACKSLASH - - -# _LT_WITH_SYSROOT -# ---------------- -AC_DEFUN([_LT_WITH_SYSROOT], -[AC_MSG_CHECKING([for sysroot]) -AC_ARG_WITH([sysroot], -[ --with-sysroot[=DIR] Search for dependent libraries within DIR - (or the compiler's sysroot if not specified).], -[], [with_sysroot=no]) - -dnl lt_sysroot will always be passed unquoted. We quote it here -dnl in case the user passed a directory name. -lt_sysroot= -case ${with_sysroot} in #( - yes) - if test "$GCC" = yes; then - lt_sysroot=`$CC --print-sysroot 2>/dev/null` - fi - ;; #( - /*) - lt_sysroot=`echo "$with_sysroot" | sed -e "$sed_quote_subst"` - ;; #( - no|'') - ;; #( - *) - AC_MSG_RESULT([${with_sysroot}]) - AC_MSG_ERROR([The sysroot must be an absolute path.]) - ;; -esac - - AC_MSG_RESULT([${lt_sysroot:-no}]) -_LT_DECL([], [lt_sysroot], [0], [The root where to search for ]dnl -[dependent libraries, and in which our libraries should be installed.])]) - -# _LT_ENABLE_LOCK -# --------------- -m4_defun([_LT_ENABLE_LOCK], -[AC_ARG_ENABLE([libtool-lock], - [AS_HELP_STRING([--disable-libtool-lock], - [avoid locking (might break parallel builds)])]) -test "x$enable_libtool_lock" != xno && enable_libtool_lock=yes - -# Some flags need to be propagated to the compiler or linker for good -# libtool support. -case $host in -ia64-*-hpux*) - # Find out which ABI we are using. - echo 'int i;' > conftest.$ac_ext - if AC_TRY_EVAL(ac_compile); then - case `/usr/bin/file conftest.$ac_objext` in - *ELF-32*) - HPUX_IA64_MODE="32" - ;; - *ELF-64*) - HPUX_IA64_MODE="64" - ;; - esac - fi - rm -rf conftest* - ;; -*-*-irix6*) - # Find out which ABI we are using. - echo '[#]line '$LINENO' "configure"' > conftest.$ac_ext - if AC_TRY_EVAL(ac_compile); then - if test "$lt_cv_prog_gnu_ld" = yes; then - case `/usr/bin/file conftest.$ac_objext` in - *32-bit*) - LD="${LD-ld} -melf32bsmip" - ;; - *N32*) - LD="${LD-ld} -melf32bmipn32" - ;; - *64-bit*) - LD="${LD-ld} -melf64bmip" - ;; - esac - else - case `/usr/bin/file conftest.$ac_objext` in - *32-bit*) - LD="${LD-ld} -32" - ;; - *N32*) - LD="${LD-ld} -n32" - ;; - *64-bit*) - LD="${LD-ld} -64" - ;; - esac - fi - fi - rm -rf conftest* - ;; - -x86_64-*kfreebsd*-gnu|x86_64-*linux*|ppc*-*linux*|powerpc*-*linux*| \ -s390*-*linux*|s390*-*tpf*|sparc*-*linux*) - # Find out which ABI we are using. - echo 'int i;' > conftest.$ac_ext - if AC_TRY_EVAL(ac_compile); then - case `/usr/bin/file conftest.o` in - *32-bit*) - case $host in - x86_64-*kfreebsd*-gnu) - LD="${LD-ld} -m elf_i386_fbsd" - ;; - x86_64-*linux*) - LD="${LD-ld} -m elf_i386" - ;; - ppc64-*linux*|powerpc64-*linux*) - LD="${LD-ld} -m elf32ppclinux" - ;; - s390x-*linux*) - LD="${LD-ld} -m elf_s390" - ;; - sparc64-*linux*) - LD="${LD-ld} -m elf32_sparc" - ;; - esac - ;; - *64-bit*) - case $host in - x86_64-*kfreebsd*-gnu) - LD="${LD-ld} -m elf_x86_64_fbsd" - ;; - x86_64-*linux*) - LD="${LD-ld} -m elf_x86_64" - ;; - ppc*-*linux*|powerpc*-*linux*) - LD="${LD-ld} -m elf64ppc" - ;; - s390*-*linux*|s390*-*tpf*) - LD="${LD-ld} -m elf64_s390" - ;; - sparc*-*linux*) - LD="${LD-ld} -m elf64_sparc" - ;; - esac - ;; - esac - fi - rm -rf conftest* - ;; - -*-*-sco3.2v5*) - # On SCO OpenServer 5, we need -belf to get full-featured binaries. - SAVE_CFLAGS="$CFLAGS" - CFLAGS="$CFLAGS -belf" - AC_CACHE_CHECK([whether the C compiler needs -belf], lt_cv_cc_needs_belf, - [AC_LANG_PUSH(C) - AC_LINK_IFELSE([AC_LANG_PROGRAM([[]],[[]])],[lt_cv_cc_needs_belf=yes],[lt_cv_cc_needs_belf=no]) - AC_LANG_POP]) - if test x"$lt_cv_cc_needs_belf" != x"yes"; then - # this is probably gcc 2.8.0, egcs 1.0 or newer; no need for -belf - CFLAGS="$SAVE_CFLAGS" - fi - ;; -*-*solaris*) - # Find out which ABI we are using. - echo 'int i;' > conftest.$ac_ext - if AC_TRY_EVAL(ac_compile); then - case `/usr/bin/file conftest.o` in - *64-bit*) - case $lt_cv_prog_gnu_ld in - yes*) - case $host in - i?86-*-solaris*) - LD="${LD-ld} -m elf_x86_64" - ;; - sparc*-*-solaris*) - LD="${LD-ld} -m elf64_sparc" - ;; - esac - # GNU ld 2.21 introduced _sol2 emulations. Use them if available. - if ${LD-ld} -V | grep _sol2 >/dev/null 2>&1; then - LD="${LD-ld}_sol2" - fi - ;; - *) - if ${LD-ld} -64 -r -o conftest2.o conftest.o >/dev/null 2>&1; then - LD="${LD-ld} -64" - fi - ;; - esac - ;; - esac - fi - rm -rf conftest* - ;; -esac - -need_locks="$enable_libtool_lock" -])# _LT_ENABLE_LOCK - - -# _LT_PROG_AR -# ----------- -m4_defun([_LT_PROG_AR], -[AC_CHECK_TOOLS(AR, [ar], false) -: ${AR=ar} -: ${AR_FLAGS=cru} -_LT_DECL([], [AR], [1], [The archiver]) -_LT_DECL([], [AR_FLAGS], [1], [Flags to create an archive]) - -AC_CACHE_CHECK([for archiver @FILE support], [lt_cv_ar_at_file], - [lt_cv_ar_at_file=no - AC_COMPILE_IFELSE([AC_LANG_PROGRAM], - [echo conftest.$ac_objext > conftest.lst - lt_ar_try='$AR $AR_FLAGS libconftest.a @conftest.lst >&AS_MESSAGE_LOG_FD' - AC_TRY_EVAL([lt_ar_try]) - if test "$ac_status" -eq 0; then - # Ensure the archiver fails upon bogus file names. - rm -f conftest.$ac_objext libconftest.a - AC_TRY_EVAL([lt_ar_try]) - if test "$ac_status" -ne 0; then - lt_cv_ar_at_file=@ - fi - fi - rm -f conftest.* libconftest.a - ]) - ]) - -if test "x$lt_cv_ar_at_file" = xno; then - archiver_list_spec= -else - archiver_list_spec=$lt_cv_ar_at_file -fi -_LT_DECL([], [archiver_list_spec], [1], - [How to feed a file listing to the archiver]) -])# _LT_PROG_AR - - -# _LT_CMD_OLD_ARCHIVE -# ------------------- -m4_defun([_LT_CMD_OLD_ARCHIVE], -[_LT_PROG_AR - -AC_CHECK_TOOL(STRIP, strip, :) -test -z "$STRIP" && STRIP=: -_LT_DECL([], [STRIP], [1], [A symbol stripping program]) - -AC_CHECK_TOOL(RANLIB, ranlib, :) -test -z "$RANLIB" && RANLIB=: -_LT_DECL([], [RANLIB], [1], - [Commands used to install an old-style archive]) - -# Determine commands to create old-style static archives. -old_archive_cmds='$AR $AR_FLAGS $oldlib$oldobjs' -old_postinstall_cmds='chmod 644 $oldlib' -old_postuninstall_cmds= - -if test -n "$RANLIB"; then - case $host_os in - openbsd*) - old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB -t \$tool_oldlib" - ;; - *) - old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB \$tool_oldlib" - ;; - esac - old_archive_cmds="$old_archive_cmds~\$RANLIB \$tool_oldlib" -fi - -case $host_os in - darwin*) - lock_old_archive_extraction=yes ;; - *) - lock_old_archive_extraction=no ;; -esac -_LT_DECL([], [old_postinstall_cmds], [2]) -_LT_DECL([], [old_postuninstall_cmds], [2]) -_LT_TAGDECL([], [old_archive_cmds], [2], - [Commands used to build an old-style archive]) -_LT_DECL([], [lock_old_archive_extraction], [0], - [Whether to use a lock for old archive extraction]) -])# _LT_CMD_OLD_ARCHIVE - - -# _LT_COMPILER_OPTION(MESSAGE, VARIABLE-NAME, FLAGS, -# [OUTPUT-FILE], [ACTION-SUCCESS], [ACTION-FAILURE]) -# ---------------------------------------------------------------- -# Check whether the given compiler option works -AC_DEFUN([_LT_COMPILER_OPTION], -[m4_require([_LT_FILEUTILS_DEFAULTS])dnl -m4_require([_LT_DECL_SED])dnl -AC_CACHE_CHECK([$1], [$2], - [$2=no - m4_if([$4], , [ac_outfile=conftest.$ac_objext], [ac_outfile=$4]) - echo "$lt_simple_compile_test_code" > conftest.$ac_ext - lt_compiler_flag="$3" - # Insert the option either (1) after the last *FLAGS variable, or - # (2) before a word containing "conftest.", or (3) at the end. - # Note that $ac_compile itself does not contain backslashes and begins - # with a dollar sign (not a hyphen), so the echo should work correctly. - # The option is referenced via a variable to avoid confusing sed. - lt_compile=`echo "$ac_compile" | $SED \ - -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ - -e 's: [[^ ]]*conftest\.: $lt_compiler_flag&:; t' \ - -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&AS_MESSAGE_LOG_FD) - (eval "$lt_compile" 2>conftest.err) - ac_status=$? - cat conftest.err >&AS_MESSAGE_LOG_FD - echo "$as_me:$LINENO: \$? = $ac_status" >&AS_MESSAGE_LOG_FD - if (exit $ac_status) && test -s "$ac_outfile"; then - # The compiler can only warn and ignore the option if not recognized - # So say no if there are warnings other than the usual output. - $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' >conftest.exp - $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 - if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then - $2=yes - fi - fi - $RM conftest* -]) - -if test x"[$]$2" = xyes; then - m4_if([$5], , :, [$5]) -else - m4_if([$6], , :, [$6]) -fi -])# _LT_COMPILER_OPTION - -# Old name: -AU_ALIAS([AC_LIBTOOL_COMPILER_OPTION], [_LT_COMPILER_OPTION]) -dnl aclocal-1.4 backwards compatibility: -dnl AC_DEFUN([AC_LIBTOOL_COMPILER_OPTION], []) - - -# _LT_LINKER_OPTION(MESSAGE, VARIABLE-NAME, FLAGS, -# [ACTION-SUCCESS], [ACTION-FAILURE]) -# ---------------------------------------------------- -# Check whether the given linker option works -AC_DEFUN([_LT_LINKER_OPTION], -[m4_require([_LT_FILEUTILS_DEFAULTS])dnl -m4_require([_LT_DECL_SED])dnl -AC_CACHE_CHECK([$1], [$2], - [$2=no - save_LDFLAGS="$LDFLAGS" - LDFLAGS="$LDFLAGS $3" - echo "$lt_simple_link_test_code" > conftest.$ac_ext - if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then - # The linker can only warn and ignore the option if not recognized - # So say no if there are warnings - if test -s conftest.err; then - # Append any errors to the config.log. - cat conftest.err 1>&AS_MESSAGE_LOG_FD - $ECHO "$_lt_linker_boilerplate" | $SED '/^$/d' > conftest.exp - $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 - if diff conftest.exp conftest.er2 >/dev/null; then - $2=yes - fi - else - $2=yes - fi - fi - $RM -r conftest* - LDFLAGS="$save_LDFLAGS" -]) - -if test x"[$]$2" = xyes; then - m4_if([$4], , :, [$4]) -else - m4_if([$5], , :, [$5]) -fi -])# _LT_LINKER_OPTION - -# Old name: -AU_ALIAS([AC_LIBTOOL_LINKER_OPTION], [_LT_LINKER_OPTION]) -dnl aclocal-1.4 backwards compatibility: -dnl AC_DEFUN([AC_LIBTOOL_LINKER_OPTION], []) - - -# LT_CMD_MAX_LEN -#--------------- -AC_DEFUN([LT_CMD_MAX_LEN], -[AC_REQUIRE([AC_CANONICAL_HOST])dnl -# find the maximum length of command line arguments -AC_MSG_CHECKING([the maximum length of command line arguments]) -AC_CACHE_VAL([lt_cv_sys_max_cmd_len], [dnl - i=0 - teststring="ABCD" - - case $build_os in - msdosdjgpp*) - # On DJGPP, this test can blow up pretty badly due to problems in libc - # (any single argument exceeding 2000 bytes causes a buffer overrun - # during glob expansion). Even if it were fixed, the result of this - # check would be larger than it should be. - lt_cv_sys_max_cmd_len=12288; # 12K is about right - ;; - - gnu*) - # Under GNU Hurd, this test is not required because there is - # no limit to the length of command line arguments. - # Libtool will interpret -1 as no limit whatsoever - lt_cv_sys_max_cmd_len=-1; - ;; - - cygwin* | mingw* | cegcc*) - # On Win9x/ME, this test blows up -- it succeeds, but takes - # about 5 minutes as the teststring grows exponentially. - # Worse, since 9x/ME are not pre-emptively multitasking, - # you end up with a "frozen" computer, even though with patience - # the test eventually succeeds (with a max line length of 256k). - # Instead, let's just punt: use the minimum linelength reported by - # all of the supported platforms: 8192 (on NT/2K/XP). - lt_cv_sys_max_cmd_len=8192; - ;; - - mint*) - # On MiNT this can take a long time and run out of memory. - lt_cv_sys_max_cmd_len=8192; - ;; - - amigaos*) - # On AmigaOS with pdksh, this test takes hours, literally. - # So we just punt and use a minimum line length of 8192. - lt_cv_sys_max_cmd_len=8192; - ;; - - netbsd* | freebsd* | openbsd* | darwin* | dragonfly*) - # This has been around since 386BSD, at least. Likely further. - if test -x /sbin/sysctl; then - lt_cv_sys_max_cmd_len=`/sbin/sysctl -n kern.argmax` - elif test -x /usr/sbin/sysctl; then - lt_cv_sys_max_cmd_len=`/usr/sbin/sysctl -n kern.argmax` - else - lt_cv_sys_max_cmd_len=65536 # usable default for all BSDs - fi - # And add a safety zone - lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4` - lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3` - ;; - - interix*) - # We know the value 262144 and hardcode it with a safety zone (like BSD) - lt_cv_sys_max_cmd_len=196608 - ;; - - os2*) - # The test takes a long time on OS/2. - lt_cv_sys_max_cmd_len=8192 - ;; - - osf*) - # Dr. Hans Ekkehard Plesser reports seeing a kernel panic running configure - # due to this test when exec_disable_arg_limit is 1 on Tru64. It is not - # nice to cause kernel panics so lets avoid the loop below. - # First set a reasonable default. - lt_cv_sys_max_cmd_len=16384 - # - if test -x /sbin/sysconfig; then - case `/sbin/sysconfig -q proc exec_disable_arg_limit` in - *1*) lt_cv_sys_max_cmd_len=-1 ;; - esac - fi - ;; - sco3.2v5*) - lt_cv_sys_max_cmd_len=102400 - ;; - sysv5* | sco5v6* | sysv4.2uw2*) - kargmax=`grep ARG_MAX /etc/conf/cf.d/stune 2>/dev/null` - if test -n "$kargmax"; then - lt_cv_sys_max_cmd_len=`echo $kargmax | sed 's/.*[[ ]]//'` - else - lt_cv_sys_max_cmd_len=32768 - fi - ;; - *) - lt_cv_sys_max_cmd_len=`(getconf ARG_MAX) 2> /dev/null` - if test -n "$lt_cv_sys_max_cmd_len"; then - lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4` - lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3` - else - # Make teststring a little bigger before we do anything with it. - # a 1K string should be a reasonable start. - for i in 1 2 3 4 5 6 7 8 ; do - teststring=$teststring$teststring - done - SHELL=${SHELL-${CONFIG_SHELL-/bin/sh}} - # If test is not a shell built-in, we'll probably end up computing a - # maximum length that is only half of the actual maximum length, but - # we can't tell. - while { test "X"`env echo "$teststring$teststring" 2>/dev/null` \ - = "X$teststring$teststring"; } >/dev/null 2>&1 && - test $i != 17 # 1/2 MB should be enough - do - i=`expr $i + 1` - teststring=$teststring$teststring - done - # Only check the string length outside the loop. - lt_cv_sys_max_cmd_len=`expr "X$teststring" : ".*" 2>&1` - teststring= - # Add a significant safety factor because C++ compilers can tack on - # massive amounts of additional arguments before passing them to the - # linker. It appears as though 1/2 is a usable value. - lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 2` - fi - ;; - esac -]) -if test -n $lt_cv_sys_max_cmd_len ; then - AC_MSG_RESULT($lt_cv_sys_max_cmd_len) -else - AC_MSG_RESULT(none) -fi -max_cmd_len=$lt_cv_sys_max_cmd_len -_LT_DECL([], [max_cmd_len], [0], - [What is the maximum length of a command?]) -])# LT_CMD_MAX_LEN - -# Old name: -AU_ALIAS([AC_LIBTOOL_SYS_MAX_CMD_LEN], [LT_CMD_MAX_LEN]) -dnl aclocal-1.4 backwards compatibility: -dnl AC_DEFUN([AC_LIBTOOL_SYS_MAX_CMD_LEN], []) - - -# _LT_HEADER_DLFCN -# ---------------- -m4_defun([_LT_HEADER_DLFCN], -[AC_CHECK_HEADERS([dlfcn.h], [], [], [AC_INCLUDES_DEFAULT])dnl -])# _LT_HEADER_DLFCN - - -# _LT_TRY_DLOPEN_SELF (ACTION-IF-TRUE, ACTION-IF-TRUE-W-USCORE, -# ACTION-IF-FALSE, ACTION-IF-CROSS-COMPILING) -# ---------------------------------------------------------------- -m4_defun([_LT_TRY_DLOPEN_SELF], -[m4_require([_LT_HEADER_DLFCN])dnl -if test "$cross_compiling" = yes; then : - [$4] -else - lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 - lt_status=$lt_dlunknown - cat > conftest.$ac_ext <<_LT_EOF -[#line $LINENO "configure" -#include "confdefs.h" - -#if HAVE_DLFCN_H -#include -#endif - -#include - -#ifdef RTLD_GLOBAL -# define LT_DLGLOBAL RTLD_GLOBAL -#else -# ifdef DL_GLOBAL -# define LT_DLGLOBAL DL_GLOBAL -# else -# define LT_DLGLOBAL 0 -# endif -#endif - -/* We may have to define LT_DLLAZY_OR_NOW in the command line if we - find out it does not work in some platform. */ -#ifndef LT_DLLAZY_OR_NOW -# ifdef RTLD_LAZY -# define LT_DLLAZY_OR_NOW RTLD_LAZY -# else -# ifdef DL_LAZY -# define LT_DLLAZY_OR_NOW DL_LAZY -# else -# ifdef RTLD_NOW -# define LT_DLLAZY_OR_NOW RTLD_NOW -# else -# ifdef DL_NOW -# define LT_DLLAZY_OR_NOW DL_NOW -# else -# define LT_DLLAZY_OR_NOW 0 -# endif -# endif -# endif -# endif -#endif - -/* When -fvisbility=hidden is used, assume the code has been annotated - correspondingly for the symbols needed. */ -#if defined(__GNUC__) && (((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 3)) -int fnord () __attribute__((visibility("default"))); -#endif - -int fnord () { return 42; } -int main () -{ - void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW); - int status = $lt_dlunknown; - - if (self) - { - if (dlsym (self,"fnord")) status = $lt_dlno_uscore; - else - { - if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore; - else puts (dlerror ()); - } - /* dlclose (self); */ - } - else - puts (dlerror ()); - - return status; -}] -_LT_EOF - if AC_TRY_EVAL(ac_link) && test -s conftest${ac_exeext} 2>/dev/null; then - (./conftest; exit; ) >&AS_MESSAGE_LOG_FD 2>/dev/null - lt_status=$? - case x$lt_status in - x$lt_dlno_uscore) $1 ;; - x$lt_dlneed_uscore) $2 ;; - x$lt_dlunknown|x*) $3 ;; - esac - else : - # compilation failed - $3 - fi -fi -rm -fr conftest* -])# _LT_TRY_DLOPEN_SELF - - -# LT_SYS_DLOPEN_SELF -# ------------------ -AC_DEFUN([LT_SYS_DLOPEN_SELF], -[m4_require([_LT_HEADER_DLFCN])dnl -if test "x$enable_dlopen" != xyes; then - enable_dlopen=unknown - enable_dlopen_self=unknown - enable_dlopen_self_static=unknown -else - lt_cv_dlopen=no - lt_cv_dlopen_libs= - - case $host_os in - beos*) - lt_cv_dlopen="load_add_on" - lt_cv_dlopen_libs= - lt_cv_dlopen_self=yes - ;; - - mingw* | pw32* | cegcc*) - lt_cv_dlopen="LoadLibrary" - lt_cv_dlopen_libs= - ;; - - cygwin*) - lt_cv_dlopen="dlopen" - lt_cv_dlopen_libs= - ;; - - darwin*) - # if libdl is installed we need to link against it - AC_CHECK_LIB([dl], [dlopen], - [lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl"],[ - lt_cv_dlopen="dyld" - lt_cv_dlopen_libs= - lt_cv_dlopen_self=yes - ]) - ;; - - *) - AC_CHECK_FUNC([shl_load], - [lt_cv_dlopen="shl_load"], - [AC_CHECK_LIB([dld], [shl_load], - [lt_cv_dlopen="shl_load" lt_cv_dlopen_libs="-ldld"], - [AC_CHECK_FUNC([dlopen], - [lt_cv_dlopen="dlopen"], - [AC_CHECK_LIB([dl], [dlopen], - [lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl"], - [AC_CHECK_LIB([svld], [dlopen], - [lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-lsvld"], - [AC_CHECK_LIB([dld], [dld_link], - [lt_cv_dlopen="dld_link" lt_cv_dlopen_libs="-ldld"]) - ]) - ]) - ]) - ]) - ]) - ;; - esac - - if test "x$lt_cv_dlopen" != xno; then - enable_dlopen=yes - else - enable_dlopen=no - fi - - case $lt_cv_dlopen in - dlopen) - save_CPPFLAGS="$CPPFLAGS" - test "x$ac_cv_header_dlfcn_h" = xyes && CPPFLAGS="$CPPFLAGS -DHAVE_DLFCN_H" - - save_LDFLAGS="$LDFLAGS" - wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $export_dynamic_flag_spec\" - - save_LIBS="$LIBS" - LIBS="$lt_cv_dlopen_libs $LIBS" - - AC_CACHE_CHECK([whether a program can dlopen itself], - lt_cv_dlopen_self, [dnl - _LT_TRY_DLOPEN_SELF( - lt_cv_dlopen_self=yes, lt_cv_dlopen_self=yes, - lt_cv_dlopen_self=no, lt_cv_dlopen_self=cross) - ]) - - if test "x$lt_cv_dlopen_self" = xyes; then - wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $lt_prog_compiler_static\" - AC_CACHE_CHECK([whether a statically linked program can dlopen itself], - lt_cv_dlopen_self_static, [dnl - _LT_TRY_DLOPEN_SELF( - lt_cv_dlopen_self_static=yes, lt_cv_dlopen_self_static=yes, - lt_cv_dlopen_self_static=no, lt_cv_dlopen_self_static=cross) - ]) - fi - - CPPFLAGS="$save_CPPFLAGS" - LDFLAGS="$save_LDFLAGS" - LIBS="$save_LIBS" - ;; - esac - - case $lt_cv_dlopen_self in - yes|no) enable_dlopen_self=$lt_cv_dlopen_self ;; - *) enable_dlopen_self=unknown ;; - esac - - case $lt_cv_dlopen_self_static in - yes|no) enable_dlopen_self_static=$lt_cv_dlopen_self_static ;; - *) enable_dlopen_self_static=unknown ;; - esac -fi -_LT_DECL([dlopen_support], [enable_dlopen], [0], - [Whether dlopen is supported]) -_LT_DECL([dlopen_self], [enable_dlopen_self], [0], - [Whether dlopen of programs is supported]) -_LT_DECL([dlopen_self_static], [enable_dlopen_self_static], [0], - [Whether dlopen of statically linked programs is supported]) -])# LT_SYS_DLOPEN_SELF - -# Old name: -AU_ALIAS([AC_LIBTOOL_DLOPEN_SELF], [LT_SYS_DLOPEN_SELF]) -dnl aclocal-1.4 backwards compatibility: -dnl AC_DEFUN([AC_LIBTOOL_DLOPEN_SELF], []) - - -# _LT_COMPILER_C_O([TAGNAME]) -# --------------------------- -# Check to see if options -c and -o are simultaneously supported by compiler. -# This macro does not hard code the compiler like AC_PROG_CC_C_O. -m4_defun([_LT_COMPILER_C_O], -[m4_require([_LT_DECL_SED])dnl -m4_require([_LT_FILEUTILS_DEFAULTS])dnl -m4_require([_LT_TAG_COMPILER])dnl -AC_CACHE_CHECK([if $compiler supports -c -o file.$ac_objext], - [_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)], - [_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)=no - $RM -r conftest 2>/dev/null - mkdir conftest - cd conftest - mkdir out - echo "$lt_simple_compile_test_code" > conftest.$ac_ext - - lt_compiler_flag="-o out/conftest2.$ac_objext" - # Insert the option either (1) after the last *FLAGS variable, or - # (2) before a word containing "conftest.", or (3) at the end. - # Note that $ac_compile itself does not contain backslashes and begins - # with a dollar sign (not a hyphen), so the echo should work correctly. - lt_compile=`echo "$ac_compile" | $SED \ - -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ - -e 's: [[^ ]]*conftest\.: $lt_compiler_flag&:; t' \ - -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&AS_MESSAGE_LOG_FD) - (eval "$lt_compile" 2>out/conftest.err) - ac_status=$? - cat out/conftest.err >&AS_MESSAGE_LOG_FD - echo "$as_me:$LINENO: \$? = $ac_status" >&AS_MESSAGE_LOG_FD - if (exit $ac_status) && test -s out/conftest2.$ac_objext - then - # The compiler can only warn and ignore the option if not recognized - # So say no if there are warnings - $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' > out/conftest.exp - $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2 - if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then - _LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)=yes - fi - fi - chmod u+w . 2>&AS_MESSAGE_LOG_FD - $RM conftest* - # SGI C++ compiler will create directory out/ii_files/ for - # template instantiation - test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files - $RM out/* && rmdir out - cd .. - $RM -r conftest - $RM conftest* -]) -_LT_TAGDECL([compiler_c_o], [lt_cv_prog_compiler_c_o], [1], - [Does compiler simultaneously support -c and -o options?]) -])# _LT_COMPILER_C_O - - -# _LT_COMPILER_FILE_LOCKS([TAGNAME]) -# ---------------------------------- -# Check to see if we can do hard links to lock some files if needed -m4_defun([_LT_COMPILER_FILE_LOCKS], -[m4_require([_LT_ENABLE_LOCK])dnl -m4_require([_LT_FILEUTILS_DEFAULTS])dnl -_LT_COMPILER_C_O([$1]) - -hard_links="nottested" -if test "$_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)" = no && test "$need_locks" != no; then - # do not overwrite the value of need_locks provided by the user - AC_MSG_CHECKING([if we can lock with hard links]) - hard_links=yes - $RM conftest* - ln conftest.a conftest.b 2>/dev/null && hard_links=no - touch conftest.a - ln conftest.a conftest.b 2>&5 || hard_links=no - ln conftest.a conftest.b 2>/dev/null && hard_links=no - AC_MSG_RESULT([$hard_links]) - if test "$hard_links" = no; then - AC_MSG_WARN([`$CC' does not support `-c -o', so `make -j' may be unsafe]) - need_locks=warn - fi -else - need_locks=no -fi -_LT_DECL([], [need_locks], [1], [Must we lock files when doing compilation?]) -])# _LT_COMPILER_FILE_LOCKS - - -# _LT_CHECK_OBJDIR -# ---------------- -m4_defun([_LT_CHECK_OBJDIR], -[AC_CACHE_CHECK([for objdir], [lt_cv_objdir], -[rm -f .libs 2>/dev/null -mkdir .libs 2>/dev/null -if test -d .libs; then - lt_cv_objdir=.libs -else - # MS-DOS does not allow filenames that begin with a dot. - lt_cv_objdir=_libs -fi -rmdir .libs 2>/dev/null]) -objdir=$lt_cv_objdir -_LT_DECL([], [objdir], [0], - [The name of the directory that contains temporary libtool files])dnl -m4_pattern_allow([LT_OBJDIR])dnl -AC_DEFINE_UNQUOTED(LT_OBJDIR, "$lt_cv_objdir/", - [Define to the sub-directory in which libtool stores uninstalled libraries.]) -])# _LT_CHECK_OBJDIR - - -# _LT_LINKER_HARDCODE_LIBPATH([TAGNAME]) -# -------------------------------------- -# Check hardcoding attributes. -m4_defun([_LT_LINKER_HARDCODE_LIBPATH], -[AC_MSG_CHECKING([how to hardcode library paths into programs]) -_LT_TAGVAR(hardcode_action, $1)= -if test -n "$_LT_TAGVAR(hardcode_libdir_flag_spec, $1)" || - test -n "$_LT_TAGVAR(runpath_var, $1)" || - test "X$_LT_TAGVAR(hardcode_automatic, $1)" = "Xyes" ; then - - # We can hardcode non-existent directories. - if test "$_LT_TAGVAR(hardcode_direct, $1)" != no && - # If the only mechanism to avoid hardcoding is shlibpath_var, we - # have to relink, otherwise we might link with an installed library - # when we should be linking with a yet-to-be-installed one - ## test "$_LT_TAGVAR(hardcode_shlibpath_var, $1)" != no && - test "$_LT_TAGVAR(hardcode_minus_L, $1)" != no; then - # Linking always hardcodes the temporary library directory. - _LT_TAGVAR(hardcode_action, $1)=relink - else - # We can link without hardcoding, and we can hardcode nonexisting dirs. - _LT_TAGVAR(hardcode_action, $1)=immediate - fi -else - # We cannot hardcode anything, or else we can only hardcode existing - # directories. - _LT_TAGVAR(hardcode_action, $1)=unsupported -fi -AC_MSG_RESULT([$_LT_TAGVAR(hardcode_action, $1)]) - -if test "$_LT_TAGVAR(hardcode_action, $1)" = relink || - test "$_LT_TAGVAR(inherit_rpath, $1)" = yes; then - # Fast installation is not supported - enable_fast_install=no -elif test "$shlibpath_overrides_runpath" = yes || - test "$enable_shared" = no; then - # Fast installation is not necessary - enable_fast_install=needless -fi -_LT_TAGDECL([], [hardcode_action], [0], - [How to hardcode a shared library path into an executable]) -])# _LT_LINKER_HARDCODE_LIBPATH - - -# _LT_CMD_STRIPLIB -# ---------------- -m4_defun([_LT_CMD_STRIPLIB], -[m4_require([_LT_DECL_EGREP]) -striplib= -old_striplib= -AC_MSG_CHECKING([whether stripping libraries is possible]) -if test -n "$STRIP" && $STRIP -V 2>&1 | $GREP "GNU strip" >/dev/null; then - test -z "$old_striplib" && old_striplib="$STRIP --strip-debug" - test -z "$striplib" && striplib="$STRIP --strip-unneeded" - AC_MSG_RESULT([yes]) -else -# FIXME - insert some real tests, host_os isn't really good enough - case $host_os in - darwin*) - if test -n "$STRIP" ; then - striplib="$STRIP -x" - old_striplib="$STRIP -S" - AC_MSG_RESULT([yes]) - else - AC_MSG_RESULT([no]) - fi - ;; - *) - AC_MSG_RESULT([no]) - ;; - esac -fi -_LT_DECL([], [old_striplib], [1], [Commands to strip libraries]) -_LT_DECL([], [striplib], [1]) -])# _LT_CMD_STRIPLIB - - -# _LT_SYS_DYNAMIC_LINKER([TAG]) -# ----------------------------- -# PORTME Fill in your ld.so characteristics -m4_defun([_LT_SYS_DYNAMIC_LINKER], -[AC_REQUIRE([AC_CANONICAL_HOST])dnl -m4_require([_LT_DECL_EGREP])dnl -m4_require([_LT_FILEUTILS_DEFAULTS])dnl -m4_require([_LT_DECL_OBJDUMP])dnl -m4_require([_LT_DECL_SED])dnl -m4_require([_LT_CHECK_SHELL_FEATURES])dnl -AC_MSG_CHECKING([dynamic linker characteristics]) -m4_if([$1], - [], [ -if test "$GCC" = yes; then - case $host_os in - darwin*) lt_awk_arg="/^libraries:/,/LR/" ;; - *) lt_awk_arg="/^libraries:/" ;; - esac - case $host_os in - mingw* | cegcc*) lt_sed_strip_eq="s,=\([[A-Za-z]]:\),\1,g" ;; - *) lt_sed_strip_eq="s,=/,/,g" ;; - esac - lt_search_path_spec=`$CC -print-search-dirs | awk $lt_awk_arg | $SED -e "s/^libraries://" -e $lt_sed_strip_eq` - case $lt_search_path_spec in - *\;*) - # if the path contains ";" then we assume it to be the separator - # otherwise default to the standard path separator (i.e. ":") - it is - # assumed that no part of a normal pathname contains ";" but that should - # okay in the real world where ";" in dirpaths is itself problematic. - lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED 's/;/ /g'` - ;; - *) - lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED "s/$PATH_SEPARATOR/ /g"` - ;; - esac - # Ok, now we have the path, separated by spaces, we can step through it - # and add multilib dir if necessary. - lt_tmp_lt_search_path_spec= - lt_multi_os_dir=`$CC $CPPFLAGS $CFLAGS $LDFLAGS -print-multi-os-directory 2>/dev/null` - for lt_sys_path in $lt_search_path_spec; do - if test -d "$lt_sys_path/$lt_multi_os_dir"; then - lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path/$lt_multi_os_dir" - else - test -d "$lt_sys_path" && \ - lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path" - fi - done - lt_search_path_spec=`$ECHO "$lt_tmp_lt_search_path_spec" | awk ' -BEGIN {RS=" "; FS="/|\n";} { - lt_foo=""; - lt_count=0; - for (lt_i = NF; lt_i > 0; lt_i--) { - if ($lt_i != "" && $lt_i != ".") { - if ($lt_i == "..") { - lt_count++; - } else { - if (lt_count == 0) { - lt_foo="/" $lt_i lt_foo; - } else { - lt_count--; - } - } - } - } - if (lt_foo != "") { lt_freq[[lt_foo]]++; } - if (lt_freq[[lt_foo]] == 1) { print lt_foo; } -}'` - # AWK program above erroneously prepends '/' to C:/dos/paths - # for these hosts. - case $host_os in - mingw* | cegcc*) lt_search_path_spec=`$ECHO "$lt_search_path_spec" |\ - $SED 's,/\([[A-Za-z]]:\),\1,g'` ;; - esac - sys_lib_search_path_spec=`$ECHO "$lt_search_path_spec" | $lt_NL2SP` -else - sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib" -fi]) -library_names_spec= -libname_spec='lib$name' -soname_spec= -shrext_cmds=".so" -postinstall_cmds= -postuninstall_cmds= -finish_cmds= -finish_eval= -shlibpath_var= -shlibpath_overrides_runpath=unknown -version_type=none -dynamic_linker="$host_os ld.so" -sys_lib_dlsearch_path_spec="/lib /usr/lib" -need_lib_prefix=unknown -hardcode_into_libs=no - -# when you set need_version to no, make sure it does not cause -set_version -# flags to be left without arguments -need_version=unknown - -case $host_os in -aix3*) - version_type=linux # correct to gnu/linux during the next big refactor - library_names_spec='${libname}${release}${shared_ext}$versuffix $libname.a' - shlibpath_var=LIBPATH - - # AIX 3 has no versioning support, so we append a major version to the name. - soname_spec='${libname}${release}${shared_ext}$major' - ;; - -aix[[4-9]]*) - version_type=linux # correct to gnu/linux during the next big refactor - need_lib_prefix=no - need_version=no - hardcode_into_libs=yes - if test "$host_cpu" = ia64; then - # AIX 5 supports IA64 - library_names_spec='${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext}$versuffix $libname${shared_ext}' - shlibpath_var=LD_LIBRARY_PATH - else - # With GCC up to 2.95.x, collect2 would create an import file - # for dependence libraries. The import file would start with - # the line `#! .'. This would cause the generated library to - # depend on `.', always an invalid library. This was fixed in - # development snapshots of GCC prior to 3.0. - case $host_os in - aix4 | aix4.[[01]] | aix4.[[01]].*) - if { echo '#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 97)' - echo ' yes ' - echo '#endif'; } | ${CC} -E - | $GREP yes > /dev/null; then - : - else - can_build_shared=no - fi - ;; - esac - # AIX (on Power*) has no versioning support, so currently we can not hardcode correct - # soname into executable. Probably we can add versioning support to - # collect2, so additional links can be useful in future. - if test "$aix_use_runtimelinking" = yes; then - # If using run time linking (on AIX 4.2 or later) use lib.so - # instead of lib.a to let people know that these are not - # typical AIX shared libraries. - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - else - # We preserve .a as extension for shared libraries through AIX4.2 - # and later when we are not doing run time linking. - library_names_spec='${libname}${release}.a $libname.a' - soname_spec='${libname}${release}${shared_ext}$major' - fi - shlibpath_var=LIBPATH - fi - ;; - -amigaos*) - case $host_cpu in - powerpc) - # Since July 2007 AmigaOS4 officially supports .so libraries. - # When compiling the executable, add -use-dynld -Lsobjs: to the compileline. - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - ;; - m68k) - library_names_spec='$libname.ixlibrary $libname.a' - # Create ${libname}_ixlibrary.a entries in /sys/libs. - finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`func_echo_all "$lib" | $SED '\''s%^.*/\([[^/]]*\)\.ixlibrary$%\1%'\''`; test $RM /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done' - ;; - esac - ;; - -beos*) - library_names_spec='${libname}${shared_ext}' - dynamic_linker="$host_os ld.so" - shlibpath_var=LIBRARY_PATH - ;; - -bsdi[[45]]*) - version_type=linux # correct to gnu/linux during the next big refactor - need_version=no - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' - finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir' - shlibpath_var=LD_LIBRARY_PATH - sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib" - sys_lib_dlsearch_path_spec="/shlib /usr/lib /usr/local/lib" - # the default ld.so.conf also contains /usr/contrib/lib and - # /usr/X11R6/lib (/usr/X11 is a link to /usr/X11R6), but let us allow - # libtool to hard-code these into programs - ;; - -cygwin* | mingw* | pw32* | cegcc*) - version_type=windows - shrext_cmds=".dll" - need_version=no - need_lib_prefix=no - - case $GCC,$cc_basename in - yes,*) - # gcc - library_names_spec='$libname.dll.a' - # DLL is installed to $(libdir)/../bin by postinstall_cmds - postinstall_cmds='base_file=`basename \${file}`~ - dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i; echo \$dlname'\''`~ - dldir=$destdir/`dirname \$dlpath`~ - test -d \$dldir || mkdir -p \$dldir~ - $install_prog $dir/$dlname \$dldir/$dlname~ - chmod a+x \$dldir/$dlname~ - if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then - eval '\''$striplib \$dldir/$dlname'\'' || exit \$?; - fi' - postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ - dlpath=$dir/\$dldll~ - $RM \$dlpath' - shlibpath_overrides_runpath=yes - - case $host_os in - cygwin*) - # Cygwin DLLs use 'cyg' prefix rather than 'lib' - soname_spec='`echo ${libname} | sed -e 's/^lib/cyg/'``echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext}' -m4_if([$1], [],[ - sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/lib/w32api"]) - ;; - mingw* | cegcc*) - # MinGW DLLs use traditional 'lib' prefix - soname_spec='${libname}`echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext}' - ;; - pw32*) - # pw32 DLLs use 'pw' prefix rather than 'lib' - library_names_spec='`echo ${libname} | sed -e 's/^lib/pw/'``echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext}' - ;; - esac - dynamic_linker='Win32 ld.exe' - ;; - - *,cl*) - # Native MSVC - libname_spec='$name' - soname_spec='${libname}`echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext}' - library_names_spec='${libname}.dll.lib' - - case $build_os in - mingw*) - sys_lib_search_path_spec= - lt_save_ifs=$IFS - IFS=';' - for lt_path in $LIB - do - IFS=$lt_save_ifs - # Let DOS variable expansion print the short 8.3 style file name. - lt_path=`cd "$lt_path" 2>/dev/null && cmd //C "for %i in (".") do @echo %~si"` - sys_lib_search_path_spec="$sys_lib_search_path_spec $lt_path" - done - IFS=$lt_save_ifs - # Convert to MSYS style. - sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | sed -e 's|\\\\|/|g' -e 's| \\([[a-zA-Z]]\\):| /\\1|g' -e 's|^ ||'` - ;; - cygwin*) - # Convert to unix form, then to dos form, then back to unix form - # but this time dos style (no spaces!) so that the unix form looks - # like /cygdrive/c/PROGRA~1:/cygdr... - sys_lib_search_path_spec=`cygpath --path --unix "$LIB"` - sys_lib_search_path_spec=`cygpath --path --dos "$sys_lib_search_path_spec" 2>/dev/null` - sys_lib_search_path_spec=`cygpath --path --unix "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` - ;; - *) - sys_lib_search_path_spec="$LIB" - if $ECHO "$sys_lib_search_path_spec" | [$GREP ';[c-zC-Z]:/' >/dev/null]; then - # It is most probably a Windows format PATH. - sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'` - else - sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` - fi - # FIXME: find the short name or the path components, as spaces are - # common. (e.g. "Program Files" -> "PROGRA~1") - ;; - esac - - # DLL is installed to $(libdir)/../bin by postinstall_cmds - postinstall_cmds='base_file=`basename \${file}`~ - dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i; echo \$dlname'\''`~ - dldir=$destdir/`dirname \$dlpath`~ - test -d \$dldir || mkdir -p \$dldir~ - $install_prog $dir/$dlname \$dldir/$dlname' - postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ - dlpath=$dir/\$dldll~ - $RM \$dlpath' - shlibpath_overrides_runpath=yes - dynamic_linker='Win32 link.exe' - ;; - - *) - # Assume MSVC wrapper - library_names_spec='${libname}`echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext} $libname.lib' - dynamic_linker='Win32 ld.exe' - ;; - esac - # FIXME: first we should search . and the directory the executable is in - shlibpath_var=PATH - ;; - -darwin* | rhapsody*) - dynamic_linker="$host_os dyld" - version_type=darwin - need_lib_prefix=no - need_version=no - library_names_spec='${libname}${release}${major}$shared_ext ${libname}$shared_ext' - soname_spec='${libname}${release}${major}$shared_ext' - shlibpath_overrides_runpath=yes - shlibpath_var=DYLD_LIBRARY_PATH - shrext_cmds='`test .$module = .yes && echo .so || echo .dylib`' -m4_if([$1], [],[ - sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/local/lib"]) - sys_lib_dlsearch_path_spec='/usr/local/lib /lib /usr/lib' - ;; - -dgux*) - version_type=linux # correct to gnu/linux during the next big refactor - need_lib_prefix=no - need_version=no - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname$shared_ext' - soname_spec='${libname}${release}${shared_ext}$major' - shlibpath_var=LD_LIBRARY_PATH - ;; - -freebsd* | dragonfly*) - # DragonFly does not have aout. When/if they implement a new - # versioning mechanism, adjust this. - if test -x /usr/bin/objformat; then - objformat=`/usr/bin/objformat` - else - case $host_os in - freebsd[[23]].*) objformat=aout ;; - *) objformat=elf ;; - esac - fi - version_type=freebsd-$objformat - case $version_type in - freebsd-elf*) - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}' - need_version=no - need_lib_prefix=no - ;; - freebsd-*) - library_names_spec='${libname}${release}${shared_ext}$versuffix $libname${shared_ext}$versuffix' - need_version=yes - ;; - esac - shlibpath_var=LD_LIBRARY_PATH - case $host_os in - freebsd2.*) - shlibpath_overrides_runpath=yes - ;; - freebsd3.[[01]]* | freebsdelf3.[[01]]*) - shlibpath_overrides_runpath=yes - hardcode_into_libs=yes - ;; - freebsd3.[[2-9]]* | freebsdelf3.[[2-9]]* | \ - freebsd4.[[0-5]] | freebsdelf4.[[0-5]] | freebsd4.1.1 | freebsdelf4.1.1) - shlibpath_overrides_runpath=no - hardcode_into_libs=yes - ;; - *) # from 4.6 on, and DragonFly - shlibpath_overrides_runpath=yes - hardcode_into_libs=yes - ;; - esac - ;; - -gnu*) - version_type=linux # correct to gnu/linux during the next big refactor - need_lib_prefix=no - need_version=no - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' - shlibpath_var=LD_LIBRARY_PATH - shlibpath_overrides_runpath=no - hardcode_into_libs=yes - ;; - -haiku*) - version_type=linux # correct to gnu/linux during the next big refactor - need_lib_prefix=no - need_version=no - dynamic_linker="$host_os runtime_loader" - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' - shlibpath_var=LIBRARY_PATH - shlibpath_overrides_runpath=yes - sys_lib_dlsearch_path_spec='/boot/home/config/lib /boot/common/lib /boot/system/lib' - hardcode_into_libs=yes - ;; - -hpux9* | hpux10* | hpux11*) - # Give a soname corresponding to the major version so that dld.sl refuses to - # link against other versions. - version_type=sunos - need_lib_prefix=no - need_version=no - case $host_cpu in - ia64*) - shrext_cmds='.so' - hardcode_into_libs=yes - dynamic_linker="$host_os dld.so" - shlibpath_var=LD_LIBRARY_PATH - shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' - if test "X$HPUX_IA64_MODE" = X32; then - sys_lib_search_path_spec="/usr/lib/hpux32 /usr/local/lib/hpux32 /usr/local/lib" - else - sys_lib_search_path_spec="/usr/lib/hpux64 /usr/local/lib/hpux64" - fi - sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec - ;; - hppa*64*) - shrext_cmds='.sl' - hardcode_into_libs=yes - dynamic_linker="$host_os dld.sl" - shlibpath_var=LD_LIBRARY_PATH # How should we handle SHLIB_PATH - shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' - sys_lib_search_path_spec="/usr/lib/pa20_64 /usr/ccs/lib/pa20_64" - sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec - ;; - *) - shrext_cmds='.sl' - dynamic_linker="$host_os dld.sl" - shlibpath_var=SHLIB_PATH - shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' - ;; - esac - # HP-UX runs *really* slowly unless shared libraries are mode 555, ... - postinstall_cmds='chmod 555 $lib' - # or fails outright, so override atomically: - install_override_mode=555 - ;; - -interix[[3-9]]*) - version_type=linux # correct to gnu/linux during the next big refactor - need_lib_prefix=no - need_version=no - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' - dynamic_linker='Interix 3.x ld.so.1 (PE, like ELF)' - shlibpath_var=LD_LIBRARY_PATH - shlibpath_overrides_runpath=no - hardcode_into_libs=yes - ;; - -irix5* | irix6* | nonstopux*) - case $host_os in - nonstopux*) version_type=nonstopux ;; - *) - if test "$lt_cv_prog_gnu_ld" = yes; then - version_type=linux # correct to gnu/linux during the next big refactor - else - version_type=irix - fi ;; - esac - need_lib_prefix=no - need_version=no - soname_spec='${libname}${release}${shared_ext}$major' - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext} $libname${shared_ext}' - case $host_os in - irix5* | nonstopux*) - libsuff= shlibsuff= - ;; - *) - case $LD in # libtool.m4 will add one of these switches to LD - *-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ") - libsuff= shlibsuff= libmagic=32-bit;; - *-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ") - libsuff=32 shlibsuff=N32 libmagic=N32;; - *-64|*"-64 "|*-melf64bmip|*"-melf64bmip ") - libsuff=64 shlibsuff=64 libmagic=64-bit;; - *) libsuff= shlibsuff= libmagic=never-match;; - esac - ;; - esac - shlibpath_var=LD_LIBRARY${shlibsuff}_PATH - shlibpath_overrides_runpath=no - sys_lib_search_path_spec="/usr/lib${libsuff} /lib${libsuff} /usr/local/lib${libsuff}" - sys_lib_dlsearch_path_spec="/usr/lib${libsuff} /lib${libsuff}" - hardcode_into_libs=yes - ;; - -# No shared lib support for Linux oldld, aout, or coff. -linux*oldld* | linux*aout* | linux*coff*) - dynamic_linker=no - ;; - -# This must be glibc/ELF. -linux* | k*bsd*-gnu | kopensolaris*-gnu) - version_type=linux # correct to gnu/linux during the next big refactor - need_lib_prefix=no - need_version=no - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' - finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir' - shlibpath_var=LD_LIBRARY_PATH - shlibpath_overrides_runpath=no - - # Some binutils ld are patched to set DT_RUNPATH - AC_CACHE_VAL([lt_cv_shlibpath_overrides_runpath], - [lt_cv_shlibpath_overrides_runpath=no - save_LDFLAGS=$LDFLAGS - save_libdir=$libdir - eval "libdir=/foo; wl=\"$_LT_TAGVAR(lt_prog_compiler_wl, $1)\"; \ - LDFLAGS=\"\$LDFLAGS $_LT_TAGVAR(hardcode_libdir_flag_spec, $1)\"" - AC_LINK_IFELSE([AC_LANG_PROGRAM([],[])], - [AS_IF([ ($OBJDUMP -p conftest$ac_exeext) 2>/dev/null | grep "RUNPATH.*$libdir" >/dev/null], - [lt_cv_shlibpath_overrides_runpath=yes])]) - LDFLAGS=$save_LDFLAGS - libdir=$save_libdir - ]) - shlibpath_overrides_runpath=$lt_cv_shlibpath_overrides_runpath - - # This implies no fast_install, which is unacceptable. - # Some rework will be needed to allow for fast_install - # before this can be enabled. - hardcode_into_libs=yes - - # Append ld.so.conf contents to the search path - if test -f /etc/ld.so.conf; then - lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s 2>/dev/null", \[$]2)); skip = 1; } { if (!skip) print \[$]0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;/^[ ]*hwcap[ ]/d;s/[:, ]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;s/"//g;/^$/d' | tr '\n' ' '` - sys_lib_dlsearch_path_spec="/lib /usr/lib $lt_ld_extra" - fi - - # We used to test for /lib/ld.so.1 and disable shared libraries on - # powerpc, because MkLinux only supported shared libraries with the - # GNU dynamic linker. Since this was broken with cross compilers, - # most powerpc-linux boxes support dynamic linking these days and - # people can always --disable-shared, the test was removed, and we - # assume the GNU/Linux dynamic linker is in use. - dynamic_linker='GNU/Linux ld.so' - ;; - -netbsd*) - version_type=sunos - need_lib_prefix=no - need_version=no - if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' - finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' - dynamic_linker='NetBSD (a.out) ld.so' - else - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' - dynamic_linker='NetBSD ld.elf_so' - fi - shlibpath_var=LD_LIBRARY_PATH - shlibpath_overrides_runpath=yes - hardcode_into_libs=yes - ;; - -newsos6) - version_type=linux # correct to gnu/linux during the next big refactor - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - shlibpath_var=LD_LIBRARY_PATH - shlibpath_overrides_runpath=yes - ;; - -*nto* | *qnx*) - version_type=qnx - need_lib_prefix=no - need_version=no - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' - shlibpath_var=LD_LIBRARY_PATH - shlibpath_overrides_runpath=no - hardcode_into_libs=yes - dynamic_linker='ldqnx.so' - ;; - -openbsd*) - version_type=sunos - sys_lib_dlsearch_path_spec="/usr/lib" - need_lib_prefix=no - # Some older versions of OpenBSD (3.3 at least) *do* need versioned libs. - case $host_os in - openbsd3.3 | openbsd3.3.*) need_version=yes ;; - *) need_version=no ;; - esac - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' - finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' - shlibpath_var=LD_LIBRARY_PATH - if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then - case $host_os in - openbsd2.[[89]] | openbsd2.[[89]].*) - shlibpath_overrides_runpath=no - ;; - *) - shlibpath_overrides_runpath=yes - ;; - esac - else - shlibpath_overrides_runpath=yes - fi - ;; - -os2*) - libname_spec='$name' - shrext_cmds=".dll" - need_lib_prefix=no - library_names_spec='$libname${shared_ext} $libname.a' - dynamic_linker='OS/2 ld.exe' - shlibpath_var=LIBPATH - ;; - -osf3* | osf4* | osf5*) - version_type=osf - need_lib_prefix=no - need_version=no - soname_spec='${libname}${release}${shared_ext}$major' - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - shlibpath_var=LD_LIBRARY_PATH - sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib" - sys_lib_dlsearch_path_spec="$sys_lib_search_path_spec" - ;; - -rdos*) - dynamic_linker=no - ;; - -solaris*) - version_type=linux # correct to gnu/linux during the next big refactor - need_lib_prefix=no - need_version=no - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' - shlibpath_var=LD_LIBRARY_PATH - shlibpath_overrides_runpath=yes - hardcode_into_libs=yes - # ldd complains unless libraries are executable - postinstall_cmds='chmod +x $lib' - ;; - -sunos4*) - version_type=sunos - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' - finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir' - shlibpath_var=LD_LIBRARY_PATH - shlibpath_overrides_runpath=yes - if test "$with_gnu_ld" = yes; then - need_lib_prefix=no - fi - need_version=yes - ;; - -sysv4 | sysv4.3*) - version_type=linux # correct to gnu/linux during the next big refactor - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' - shlibpath_var=LD_LIBRARY_PATH - case $host_vendor in - sni) - shlibpath_overrides_runpath=no - need_lib_prefix=no - runpath_var=LD_RUN_PATH - ;; - siemens) - need_lib_prefix=no - ;; - motorola) - need_lib_prefix=no - need_version=no - shlibpath_overrides_runpath=no - sys_lib_search_path_spec='/lib /usr/lib /usr/ccs/lib' - ;; - esac - ;; - -sysv4*MP*) - if test -d /usr/nec ;then - version_type=linux # correct to gnu/linux during the next big refactor - library_names_spec='$libname${shared_ext}.$versuffix $libname${shared_ext}.$major $libname${shared_ext}' - soname_spec='$libname${shared_ext}.$major' - shlibpath_var=LD_LIBRARY_PATH - fi - ;; - -sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) - version_type=freebsd-elf - need_lib_prefix=no - need_version=no - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' - shlibpath_var=LD_LIBRARY_PATH - shlibpath_overrides_runpath=yes - hardcode_into_libs=yes - if test "$with_gnu_ld" = yes; then - sys_lib_search_path_spec='/usr/local/lib /usr/gnu/lib /usr/ccs/lib /usr/lib /lib' - else - sys_lib_search_path_spec='/usr/ccs/lib /usr/lib' - case $host_os in - sco3.2v5*) - sys_lib_search_path_spec="$sys_lib_search_path_spec /lib" - ;; - esac - fi - sys_lib_dlsearch_path_spec='/usr/lib' - ;; - -tpf*) - # TPF is a cross-target only. Preferred cross-host = GNU/Linux. - version_type=linux # correct to gnu/linux during the next big refactor - need_lib_prefix=no - need_version=no - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - shlibpath_var=LD_LIBRARY_PATH - shlibpath_overrides_runpath=no - hardcode_into_libs=yes - ;; - -uts4*) - version_type=linux # correct to gnu/linux during the next big refactor - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' - shlibpath_var=LD_LIBRARY_PATH - ;; - -*) - dynamic_linker=no - ;; -esac -AC_MSG_RESULT([$dynamic_linker]) -test "$dynamic_linker" = no && can_build_shared=no - -variables_saved_for_relink="PATH $shlibpath_var $runpath_var" -if test "$GCC" = yes; then - variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH" -fi - -if test "${lt_cv_sys_lib_search_path_spec+set}" = set; then - sys_lib_search_path_spec="$lt_cv_sys_lib_search_path_spec" -fi -if test "${lt_cv_sys_lib_dlsearch_path_spec+set}" = set; then - sys_lib_dlsearch_path_spec="$lt_cv_sys_lib_dlsearch_path_spec" -fi - -_LT_DECL([], [variables_saved_for_relink], [1], - [Variables whose values should be saved in libtool wrapper scripts and - restored at link time]) -_LT_DECL([], [need_lib_prefix], [0], - [Do we need the "lib" prefix for modules?]) -_LT_DECL([], [need_version], [0], [Do we need a version for libraries?]) -_LT_DECL([], [version_type], [0], [Library versioning type]) -_LT_DECL([], [runpath_var], [0], [Shared library runtime path variable]) -_LT_DECL([], [shlibpath_var], [0],[Shared library path variable]) -_LT_DECL([], [shlibpath_overrides_runpath], [0], - [Is shlibpath searched before the hard-coded library search path?]) -_LT_DECL([], [libname_spec], [1], [Format of library name prefix]) -_LT_DECL([], [library_names_spec], [1], - [[List of archive names. First name is the real one, the rest are links. - The last name is the one that the linker finds with -lNAME]]) -_LT_DECL([], [soname_spec], [1], - [[The coded name of the library, if different from the real name]]) -_LT_DECL([], [install_override_mode], [1], - [Permission mode override for installation of shared libraries]) -_LT_DECL([], [postinstall_cmds], [2], - [Command to use after installation of a shared archive]) -_LT_DECL([], [postuninstall_cmds], [2], - [Command to use after uninstallation of a shared archive]) -_LT_DECL([], [finish_cmds], [2], - [Commands used to finish a libtool library installation in a directory]) -_LT_DECL([], [finish_eval], [1], - [[As "finish_cmds", except a single script fragment to be evaled but - not shown]]) -_LT_DECL([], [hardcode_into_libs], [0], - [Whether we should hardcode library paths into libraries]) -_LT_DECL([], [sys_lib_search_path_spec], [2], - [Compile-time system search path for libraries]) -_LT_DECL([], [sys_lib_dlsearch_path_spec], [2], - [Run-time system search path for libraries]) -])# _LT_SYS_DYNAMIC_LINKER - - -# _LT_PATH_TOOL_PREFIX(TOOL) -# -------------------------- -# find a file program which can recognize shared library -AC_DEFUN([_LT_PATH_TOOL_PREFIX], -[m4_require([_LT_DECL_EGREP])dnl -AC_MSG_CHECKING([for $1]) -AC_CACHE_VAL(lt_cv_path_MAGIC_CMD, -[case $MAGIC_CMD in -[[\\/*] | ?:[\\/]*]) - lt_cv_path_MAGIC_CMD="$MAGIC_CMD" # Let the user override the test with a path. - ;; -*) - lt_save_MAGIC_CMD="$MAGIC_CMD" - lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR -dnl $ac_dummy forces splitting on constant user-supplied paths. -dnl POSIX.2 word splitting is done only on the output of word expansions, -dnl not every word. This closes a longstanding sh security hole. - ac_dummy="m4_if([$2], , $PATH, [$2])" - for ac_dir in $ac_dummy; do - IFS="$lt_save_ifs" - test -z "$ac_dir" && ac_dir=. - if test -f $ac_dir/$1; then - lt_cv_path_MAGIC_CMD="$ac_dir/$1" - if test -n "$file_magic_test_file"; then - case $deplibs_check_method in - "file_magic "*) - file_magic_regex=`expr "$deplibs_check_method" : "file_magic \(.*\)"` - MAGIC_CMD="$lt_cv_path_MAGIC_CMD" - if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null | - $EGREP "$file_magic_regex" > /dev/null; then - : - else - cat <<_LT_EOF 1>&2 - -*** Warning: the command libtool uses to detect shared libraries, -*** $file_magic_cmd, produces output that libtool cannot recognize. -*** The result is that libtool may fail to recognize shared libraries -*** as such. This will affect the creation of libtool libraries that -*** depend on shared libraries, but programs linked with such libtool -*** libraries will work regardless of this problem. Nevertheless, you -*** may want to report the problem to your system manager and/or to -*** bug-libtool@gnu.org - -_LT_EOF - fi ;; - esac - fi - break - fi - done - IFS="$lt_save_ifs" - MAGIC_CMD="$lt_save_MAGIC_CMD" - ;; -esac]) -MAGIC_CMD="$lt_cv_path_MAGIC_CMD" -if test -n "$MAGIC_CMD"; then - AC_MSG_RESULT($MAGIC_CMD) -else - AC_MSG_RESULT(no) -fi -_LT_DECL([], [MAGIC_CMD], [0], - [Used to examine libraries when file_magic_cmd begins with "file"])dnl -])# _LT_PATH_TOOL_PREFIX - -# Old name: -AU_ALIAS([AC_PATH_TOOL_PREFIX], [_LT_PATH_TOOL_PREFIX]) -dnl aclocal-1.4 backwards compatibility: -dnl AC_DEFUN([AC_PATH_TOOL_PREFIX], []) - - -# _LT_PATH_MAGIC -# -------------- -# find a file program which can recognize a shared library -m4_defun([_LT_PATH_MAGIC], -[_LT_PATH_TOOL_PREFIX(${ac_tool_prefix}file, /usr/bin$PATH_SEPARATOR$PATH) -if test -z "$lt_cv_path_MAGIC_CMD"; then - if test -n "$ac_tool_prefix"; then - _LT_PATH_TOOL_PREFIX(file, /usr/bin$PATH_SEPARATOR$PATH) - else - MAGIC_CMD=: - fi -fi -])# _LT_PATH_MAGIC - - -# LT_PATH_LD -# ---------- -# find the pathname to the GNU or non-GNU linker -AC_DEFUN([LT_PATH_LD], -[AC_REQUIRE([AC_PROG_CC])dnl -AC_REQUIRE([AC_CANONICAL_HOST])dnl -AC_REQUIRE([AC_CANONICAL_BUILD])dnl -m4_require([_LT_DECL_SED])dnl -m4_require([_LT_DECL_EGREP])dnl -m4_require([_LT_PROG_ECHO_BACKSLASH])dnl - -AC_ARG_WITH([gnu-ld], - [AS_HELP_STRING([--with-gnu-ld], - [assume the C compiler uses GNU ld @<:@default=no@:>@])], - [test "$withval" = no || with_gnu_ld=yes], - [with_gnu_ld=no])dnl - -ac_prog=ld -if test "$GCC" = yes; then - # Check if gcc -print-prog-name=ld gives a path. - AC_MSG_CHECKING([for ld used by $CC]) - case $host in - *-*-mingw*) - # gcc leaves a trailing carriage return which upsets mingw - ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;; - *) - ac_prog=`($CC -print-prog-name=ld) 2>&5` ;; - esac - case $ac_prog in - # Accept absolute paths. - [[\\/]]* | ?:[[\\/]]*) - re_direlt='/[[^/]][[^/]]*/\.\./' - # Canonicalize the pathname of ld - ac_prog=`$ECHO "$ac_prog"| $SED 's%\\\\%/%g'` - while $ECHO "$ac_prog" | $GREP "$re_direlt" > /dev/null 2>&1; do - ac_prog=`$ECHO $ac_prog| $SED "s%$re_direlt%/%"` - done - test -z "$LD" && LD="$ac_prog" - ;; - "") - # If it fails, then pretend we aren't using GCC. - ac_prog=ld - ;; - *) - # If it is relative, then search for the first ld in PATH. - with_gnu_ld=unknown - ;; - esac -elif test "$with_gnu_ld" = yes; then - AC_MSG_CHECKING([for GNU ld]) -else - AC_MSG_CHECKING([for non-GNU ld]) -fi -AC_CACHE_VAL(lt_cv_path_LD, -[if test -z "$LD"; then - lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR - for ac_dir in $PATH; do - IFS="$lt_save_ifs" - test -z "$ac_dir" && ac_dir=. - if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then - lt_cv_path_LD="$ac_dir/$ac_prog" - # Check to see if the program is GNU ld. I'd rather use --version, - # but apparently some variants of GNU ld only accept -v. - # Break only if it was the GNU/non-GNU ld that we prefer. - case `"$lt_cv_path_LD" -v 2>&1 &1 /dev/null 2>&1; then - lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL' - lt_cv_file_magic_cmd='func_win32_libid' - else - # Keep this pattern in sync with the one in func_win32_libid. - lt_cv_deplibs_check_method='file_magic file format (pei*-i386(.*architecture: i386)?|pe-arm-wince|pe-x86-64)' - lt_cv_file_magic_cmd='$OBJDUMP -f' - fi - ;; - -cegcc*) - # use the weaker test based on 'objdump'. See mingw*. - lt_cv_deplibs_check_method='file_magic file format pe-arm-.*little(.*architecture: arm)?' - lt_cv_file_magic_cmd='$OBJDUMP -f' - ;; - -darwin* | rhapsody*) - lt_cv_deplibs_check_method=pass_all - ;; - -freebsd* | dragonfly*) - if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then - case $host_cpu in - i*86 ) - # Not sure whether the presence of OpenBSD here was a mistake. - # Let's accept both of them until this is cleared up. - lt_cv_deplibs_check_method='file_magic (FreeBSD|OpenBSD|DragonFly)/i[[3-9]]86 (compact )?demand paged shared library' - lt_cv_file_magic_cmd=/usr/bin/file - lt_cv_file_magic_test_file=`echo /usr/lib/libc.so.*` - ;; - esac - else - lt_cv_deplibs_check_method=pass_all - fi - ;; - -gnu*) - lt_cv_deplibs_check_method=pass_all - ;; - -haiku*) - lt_cv_deplibs_check_method=pass_all - ;; - -hpux10.20* | hpux11*) - lt_cv_file_magic_cmd=/usr/bin/file - case $host_cpu in - ia64*) - lt_cv_deplibs_check_method='file_magic (s[[0-9]][[0-9]][[0-9]]|ELF-[[0-9]][[0-9]]) shared object file - IA64' - lt_cv_file_magic_test_file=/usr/lib/hpux32/libc.so - ;; - hppa*64*) - [lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF[ -][0-9][0-9])(-bit)?( [LM]SB)? shared object( file)?[, -]* PA-RISC [0-9]\.[0-9]'] - lt_cv_file_magic_test_file=/usr/lib/pa20_64/libc.sl - ;; - *) - lt_cv_deplibs_check_method='file_magic (s[[0-9]][[0-9]][[0-9]]|PA-RISC[[0-9]]\.[[0-9]]) shared library' - lt_cv_file_magic_test_file=/usr/lib/libc.sl - ;; - esac - ;; - -interix[[3-9]]*) - # PIC code is broken on Interix 3.x, that's why |\.a not |_pic\.a here - lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so|\.a)$' - ;; - -irix5* | irix6* | nonstopux*) - case $LD in - *-32|*"-32 ") libmagic=32-bit;; - *-n32|*"-n32 ") libmagic=N32;; - *-64|*"-64 ") libmagic=64-bit;; - *) libmagic=never-match;; - esac - lt_cv_deplibs_check_method=pass_all - ;; - -# This must be glibc/ELF. -linux* | k*bsd*-gnu | kopensolaris*-gnu) - lt_cv_deplibs_check_method=pass_all - ;; - -netbsd*) - if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then - lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|_pic\.a)$' - else - lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so|_pic\.a)$' - fi - ;; - -newos6*) - lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[ML]]SB (executable|dynamic lib)' - lt_cv_file_magic_cmd=/usr/bin/file - lt_cv_file_magic_test_file=/usr/lib/libnls.so - ;; - -*nto* | *qnx*) - lt_cv_deplibs_check_method=pass_all - ;; - -openbsd*) - if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then - lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|\.so|_pic\.a)$' - else - lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|_pic\.a)$' - fi - ;; - -osf3* | osf4* | osf5*) - lt_cv_deplibs_check_method=pass_all - ;; - -rdos*) - lt_cv_deplibs_check_method=pass_all - ;; - -solaris*) - lt_cv_deplibs_check_method=pass_all - ;; - -sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) - lt_cv_deplibs_check_method=pass_all - ;; - -sysv4 | sysv4.3*) - case $host_vendor in - motorola) - lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[ML]]SB (shared object|dynamic lib) M[[0-9]][[0-9]]* Version [[0-9]]' - lt_cv_file_magic_test_file=`echo /usr/lib/libc.so*` - ;; - ncr) - lt_cv_deplibs_check_method=pass_all - ;; - sequent) - lt_cv_file_magic_cmd='/bin/file' - lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[LM]]SB (shared object|dynamic lib )' - ;; - sni) - lt_cv_file_magic_cmd='/bin/file' - lt_cv_deplibs_check_method="file_magic ELF [[0-9]][[0-9]]*-bit [[LM]]SB dynamic lib" - lt_cv_file_magic_test_file=/lib/libc.so - ;; - siemens) - lt_cv_deplibs_check_method=pass_all - ;; - pc) - lt_cv_deplibs_check_method=pass_all - ;; - esac - ;; - -tpf*) - lt_cv_deplibs_check_method=pass_all - ;; -esac -]) - -file_magic_glob= -want_nocaseglob=no -if test "$build" = "$host"; then - case $host_os in - mingw* | pw32*) - if ( shopt | grep nocaseglob ) >/dev/null 2>&1; then - want_nocaseglob=yes - else - file_magic_glob=`echo aAbBcCdDeEfFgGhHiIjJkKlLmMnNoOpPqQrRsStTuUvVwWxXyYzZ | $SED -e "s/\(..\)/s\/[[\1]]\/[[\1]]\/g;/g"` - fi - ;; - esac -fi - -file_magic_cmd=$lt_cv_file_magic_cmd -deplibs_check_method=$lt_cv_deplibs_check_method -test -z "$deplibs_check_method" && deplibs_check_method=unknown - -_LT_DECL([], [deplibs_check_method], [1], - [Method to check whether dependent libraries are shared objects]) -_LT_DECL([], [file_magic_cmd], [1], - [Command to use when deplibs_check_method = "file_magic"]) -_LT_DECL([], [file_magic_glob], [1], - [How to find potential files when deplibs_check_method = "file_magic"]) -_LT_DECL([], [want_nocaseglob], [1], - [Find potential files using nocaseglob when deplibs_check_method = "file_magic"]) -])# _LT_CHECK_MAGIC_METHOD - - -# LT_PATH_NM -# ---------- -# find the pathname to a BSD- or MS-compatible name lister -AC_DEFUN([LT_PATH_NM], -[AC_REQUIRE([AC_PROG_CC])dnl -AC_CACHE_CHECK([for BSD- or MS-compatible name lister (nm)], lt_cv_path_NM, -[if test -n "$NM"; then - # Let the user override the test. - lt_cv_path_NM="$NM" -else - lt_nm_to_check="${ac_tool_prefix}nm" - if test -n "$ac_tool_prefix" && test "$build" = "$host"; then - lt_nm_to_check="$lt_nm_to_check nm" - fi - for lt_tmp_nm in $lt_nm_to_check; do - lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR - for ac_dir in $PATH /usr/ccs/bin/elf /usr/ccs/bin /usr/ucb /bin; do - IFS="$lt_save_ifs" - test -z "$ac_dir" && ac_dir=. - tmp_nm="$ac_dir/$lt_tmp_nm" - if test -f "$tmp_nm" || test -f "$tmp_nm$ac_exeext" ; then - # Check to see if the nm accepts a BSD-compat flag. - # Adding the `sed 1q' prevents false positives on HP-UX, which says: - # nm: unknown option "B" ignored - # Tru64's nm complains that /dev/null is an invalid object file - case `"$tmp_nm" -B /dev/null 2>&1 | sed '1q'` in - */dev/null* | *'Invalid file or object type'*) - lt_cv_path_NM="$tmp_nm -B" - break - ;; - *) - case `"$tmp_nm" -p /dev/null 2>&1 | sed '1q'` in - */dev/null*) - lt_cv_path_NM="$tmp_nm -p" - break - ;; - *) - lt_cv_path_NM=${lt_cv_path_NM="$tmp_nm"} # keep the first match, but - continue # so that we can try to find one that supports BSD flags - ;; - esac - ;; - esac - fi - done - IFS="$lt_save_ifs" - done - : ${lt_cv_path_NM=no} -fi]) -if test "$lt_cv_path_NM" != "no"; then - NM="$lt_cv_path_NM" -else - # Didn't find any BSD compatible name lister, look for dumpbin. - if test -n "$DUMPBIN"; then : - # Let the user override the test. - else - AC_CHECK_TOOLS(DUMPBIN, [dumpbin "link -dump"], :) - case `$DUMPBIN -symbols /dev/null 2>&1 | sed '1q'` in - *COFF*) - DUMPBIN="$DUMPBIN -symbols" - ;; - *) - DUMPBIN=: - ;; - esac - fi - AC_SUBST([DUMPBIN]) - if test "$DUMPBIN" != ":"; then - NM="$DUMPBIN" - fi -fi -test -z "$NM" && NM=nm -AC_SUBST([NM]) -_LT_DECL([], [NM], [1], [A BSD- or MS-compatible name lister])dnl - -AC_CACHE_CHECK([the name lister ($NM) interface], [lt_cv_nm_interface], - [lt_cv_nm_interface="BSD nm" - echo "int some_variable = 0;" > conftest.$ac_ext - (eval echo "\"\$as_me:$LINENO: $ac_compile\"" >&AS_MESSAGE_LOG_FD) - (eval "$ac_compile" 2>conftest.err) - cat conftest.err >&AS_MESSAGE_LOG_FD - (eval echo "\"\$as_me:$LINENO: $NM \\\"conftest.$ac_objext\\\"\"" >&AS_MESSAGE_LOG_FD) - (eval "$NM \"conftest.$ac_objext\"" 2>conftest.err > conftest.out) - cat conftest.err >&AS_MESSAGE_LOG_FD - (eval echo "\"\$as_me:$LINENO: output\"" >&AS_MESSAGE_LOG_FD) - cat conftest.out >&AS_MESSAGE_LOG_FD - if $GREP 'External.*some_variable' conftest.out > /dev/null; then - lt_cv_nm_interface="MS dumpbin" - fi - rm -f conftest*]) -])# LT_PATH_NM - -# Old names: -AU_ALIAS([AM_PROG_NM], [LT_PATH_NM]) -AU_ALIAS([AC_PROG_NM], [LT_PATH_NM]) -dnl aclocal-1.4 backwards compatibility: -dnl AC_DEFUN([AM_PROG_NM], []) -dnl AC_DEFUN([AC_PROG_NM], []) - -# _LT_CHECK_SHAREDLIB_FROM_LINKLIB -# -------------------------------- -# how to determine the name of the shared library -# associated with a specific link library. -# -- PORTME fill in with the dynamic library characteristics -m4_defun([_LT_CHECK_SHAREDLIB_FROM_LINKLIB], -[m4_require([_LT_DECL_EGREP]) -m4_require([_LT_DECL_OBJDUMP]) -m4_require([_LT_DECL_DLLTOOL]) -AC_CACHE_CHECK([how to associate runtime and link libraries], -lt_cv_sharedlib_from_linklib_cmd, -[lt_cv_sharedlib_from_linklib_cmd='unknown' - -case $host_os in -cygwin* | mingw* | pw32* | cegcc*) - # two different shell functions defined in ltmain.sh - # decide which to use based on capabilities of $DLLTOOL - case `$DLLTOOL --help 2>&1` in - *--identify-strict*) - lt_cv_sharedlib_from_linklib_cmd=func_cygming_dll_for_implib - ;; - *) - lt_cv_sharedlib_from_linklib_cmd=func_cygming_dll_for_implib_fallback - ;; - esac - ;; -*) - # fallback: assume linklib IS sharedlib - lt_cv_sharedlib_from_linklib_cmd="$ECHO" - ;; -esac -]) -sharedlib_from_linklib_cmd=$lt_cv_sharedlib_from_linklib_cmd -test -z "$sharedlib_from_linklib_cmd" && sharedlib_from_linklib_cmd=$ECHO - -_LT_DECL([], [sharedlib_from_linklib_cmd], [1], - [Command to associate shared and link libraries]) -])# _LT_CHECK_SHAREDLIB_FROM_LINKLIB - - -# _LT_PATH_MANIFEST_TOOL -# ---------------------- -# locate the manifest tool -m4_defun([_LT_PATH_MANIFEST_TOOL], -[AC_CHECK_TOOL(MANIFEST_TOOL, mt, :) -test -z "$MANIFEST_TOOL" && MANIFEST_TOOL=mt -AC_CACHE_CHECK([if $MANIFEST_TOOL is a manifest tool], [lt_cv_path_mainfest_tool], - [lt_cv_path_mainfest_tool=no - echo "$as_me:$LINENO: $MANIFEST_TOOL '-?'" >&AS_MESSAGE_LOG_FD - $MANIFEST_TOOL '-?' 2>conftest.err > conftest.out - cat conftest.err >&AS_MESSAGE_LOG_FD - if $GREP 'Manifest Tool' conftest.out > /dev/null; then - lt_cv_path_mainfest_tool=yes - fi - rm -f conftest*]) -if test "x$lt_cv_path_mainfest_tool" != xyes; then - MANIFEST_TOOL=: -fi -_LT_DECL([], [MANIFEST_TOOL], [1], [Manifest tool])dnl -])# _LT_PATH_MANIFEST_TOOL - - -# LT_LIB_M -# -------- -# check for math library -AC_DEFUN([LT_LIB_M], -[AC_REQUIRE([AC_CANONICAL_HOST])dnl -LIBM= -case $host in -*-*-beos* | *-*-cegcc* | *-*-cygwin* | *-*-haiku* | *-*-pw32* | *-*-darwin*) - # These system don't have libm, or don't need it - ;; -*-ncr-sysv4.3*) - AC_CHECK_LIB(mw, _mwvalidcheckl, LIBM="-lmw") - AC_CHECK_LIB(m, cos, LIBM="$LIBM -lm") - ;; -*) - AC_CHECK_LIB(m, cos, LIBM="-lm") - ;; -esac -AC_SUBST([LIBM]) -])# LT_LIB_M - -# Old name: -AU_ALIAS([AC_CHECK_LIBM], [LT_LIB_M]) -dnl aclocal-1.4 backwards compatibility: -dnl AC_DEFUN([AC_CHECK_LIBM], []) - - -# _LT_COMPILER_NO_RTTI([TAGNAME]) -# ------------------------------- -m4_defun([_LT_COMPILER_NO_RTTI], -[m4_require([_LT_TAG_COMPILER])dnl - -_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)= - -if test "$GCC" = yes; then - case $cc_basename in - nvcc*) - _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=' -Xcompiler -fno-builtin' ;; - *) - _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=' -fno-builtin' ;; - esac - - _LT_COMPILER_OPTION([if $compiler supports -fno-rtti -fno-exceptions], - lt_cv_prog_compiler_rtti_exceptions, - [-fno-rtti -fno-exceptions], [], - [_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)="$_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1) -fno-rtti -fno-exceptions"]) -fi -_LT_TAGDECL([no_builtin_flag], [lt_prog_compiler_no_builtin_flag], [1], - [Compiler flag to turn off builtin functions]) -])# _LT_COMPILER_NO_RTTI - - -# _LT_CMD_GLOBAL_SYMBOLS -# ---------------------- -m4_defun([_LT_CMD_GLOBAL_SYMBOLS], -[AC_REQUIRE([AC_CANONICAL_HOST])dnl -AC_REQUIRE([AC_PROG_CC])dnl -AC_REQUIRE([AC_PROG_AWK])dnl -AC_REQUIRE([LT_PATH_NM])dnl -AC_REQUIRE([LT_PATH_LD])dnl -m4_require([_LT_DECL_SED])dnl -m4_require([_LT_DECL_EGREP])dnl -m4_require([_LT_TAG_COMPILER])dnl - -# Check for command to grab the raw symbol name followed by C symbol from nm. -AC_MSG_CHECKING([command to parse $NM output from $compiler object]) -AC_CACHE_VAL([lt_cv_sys_global_symbol_pipe], -[ -# These are sane defaults that work on at least a few old systems. -# [They come from Ultrix. What could be older than Ultrix?!! ;)] - -# Character class describing NM global symbol codes. -symcode='[[BCDEGRST]]' - -# Regexp to match symbols that can be accessed directly from C. -sympat='\([[_A-Za-z]][[_A-Za-z0-9]]*\)' - -# Define system-specific variables. -case $host_os in -aix*) - symcode='[[BCDT]]' - ;; -cygwin* | mingw* | pw32* | cegcc*) - symcode='[[ABCDGISTW]]' - ;; -hpux*) - if test "$host_cpu" = ia64; then - symcode='[[ABCDEGRST]]' - fi - ;; -irix* | nonstopux*) - symcode='[[BCDEGRST]]' - ;; -osf*) - symcode='[[BCDEGQRST]]' - ;; -solaris*) - symcode='[[BDRT]]' - ;; -sco3.2v5*) - symcode='[[DT]]' - ;; -sysv4.2uw2*) - symcode='[[DT]]' - ;; -sysv5* | sco5v6* | unixware* | OpenUNIX*) - symcode='[[ABDT]]' - ;; -sysv4) - symcode='[[DFNSTU]]' - ;; -esac - -# If we're using GNU nm, then use its standard symbol codes. -case `$NM -V 2>&1` in -*GNU* | *'with BFD'*) - symcode='[[ABCDGIRSTW]]' ;; -esac - -# Transform an extracted symbol line into a proper C declaration. -# Some systems (esp. on ia64) link data and code symbols differently, -# so use this general approach. -lt_cv_sys_global_symbol_to_cdecl="sed -n -e 's/^T .* \(.*\)$/extern int \1();/p' -e 's/^$symcode* .* \(.*\)$/extern char \1;/p'" - -# Transform an extracted symbol line into symbol name and symbol address -lt_cv_sys_global_symbol_to_c_name_address="sed -n -e 's/^: \([[^ ]]*\)[[ ]]*$/ {\\\"\1\\\", (void *) 0},/p' -e 's/^$symcode* \([[^ ]]*\) \([[^ ]]*\)$/ {\"\2\", (void *) \&\2},/p'" -lt_cv_sys_global_symbol_to_c_name_address_lib_prefix="sed -n -e 's/^: \([[^ ]]*\)[[ ]]*$/ {\\\"\1\\\", (void *) 0},/p' -e 's/^$symcode* \([[^ ]]*\) \(lib[[^ ]]*\)$/ {\"\2\", (void *) \&\2},/p' -e 's/^$symcode* \([[^ ]]*\) \([[^ ]]*\)$/ {\"lib\2\", (void *) \&\2},/p'" - -# Handle CRLF in mingw tool chain -opt_cr= -case $build_os in -mingw*) - opt_cr=`$ECHO 'x\{0,1\}' | tr x '\015'` # option cr in regexp - ;; -esac - -# Try without a prefix underscore, then with it. -for ac_symprfx in "" "_"; do - - # Transform symcode, sympat, and symprfx into a raw symbol and a C symbol. - symxfrm="\\1 $ac_symprfx\\2 \\2" - - # Write the raw and C identifiers. - if test "$lt_cv_nm_interface" = "MS dumpbin"; then - # Fake it for dumpbin and say T for any non-static function - # and D for any global variable. - # Also find C++ and __fastcall symbols from MSVC++, - # which start with @ or ?. - lt_cv_sys_global_symbol_pipe="$AWK ['"\ -" {last_section=section; section=\$ 3};"\ -" /^COFF SYMBOL TABLE/{for(i in hide) delete hide[i]};"\ -" /Section length .*#relocs.*(pick any)/{hide[last_section]=1};"\ -" \$ 0!~/External *\|/{next};"\ -" / 0+ UNDEF /{next}; / UNDEF \([^|]\)*()/{next};"\ -" {if(hide[section]) next};"\ -" {f=0}; \$ 0~/\(\).*\|/{f=1}; {printf f ? \"T \" : \"D \"};"\ -" {split(\$ 0, a, /\||\r/); split(a[2], s)};"\ -" s[1]~/^[@?]/{print s[1], s[1]; next};"\ -" s[1]~prfx {split(s[1],t,\"@\"); print t[1], substr(t[1],length(prfx))}"\ -" ' prfx=^$ac_symprfx]" - else - lt_cv_sys_global_symbol_pipe="sed -n -e 's/^.*[[ ]]\($symcode$symcode*\)[[ ]][[ ]]*$ac_symprfx$sympat$opt_cr$/$symxfrm/p'" - fi - lt_cv_sys_global_symbol_pipe="$lt_cv_sys_global_symbol_pipe | sed '/ __gnu_lto/d'" - - # Check to see that the pipe works correctly. - pipe_works=no - - rm -f conftest* - cat > conftest.$ac_ext <<_LT_EOF -#ifdef __cplusplus -extern "C" { -#endif -char nm_test_var; -void nm_test_func(void); -void nm_test_func(void){} -#ifdef __cplusplus -} -#endif -int main(){nm_test_var='a';nm_test_func();return(0);} -_LT_EOF - - if AC_TRY_EVAL(ac_compile); then - # Now try to grab the symbols. - nlist=conftest.nm - if AC_TRY_EVAL(NM conftest.$ac_objext \| "$lt_cv_sys_global_symbol_pipe" \> $nlist) && test -s "$nlist"; then - # Try sorting and uniquifying the output. - if sort "$nlist" | uniq > "$nlist"T; then - mv -f "$nlist"T "$nlist" - else - rm -f "$nlist"T - fi - - # Make sure that we snagged all the symbols we need. - if $GREP ' nm_test_var$' "$nlist" >/dev/null; then - if $GREP ' nm_test_func$' "$nlist" >/dev/null; then - cat <<_LT_EOF > conftest.$ac_ext -/* Keep this code in sync between libtool.m4, ltmain, lt_system.h, and tests. */ -#if defined(_WIN32) || defined(__CYGWIN__) || defined(_WIN32_WCE) -/* DATA imports from DLLs on WIN32 con't be const, because runtime - relocations are performed -- see ld's documentation on pseudo-relocs. */ -# define LT@&t@_DLSYM_CONST -#elif defined(__osf__) -/* This system does not cope well with relocations in const data. */ -# define LT@&t@_DLSYM_CONST -#else -# define LT@&t@_DLSYM_CONST const -#endif - -#ifdef __cplusplus -extern "C" { -#endif - -_LT_EOF - # Now generate the symbol file. - eval "$lt_cv_sys_global_symbol_to_cdecl"' < "$nlist" | $GREP -v main >> conftest.$ac_ext' - - cat <<_LT_EOF >> conftest.$ac_ext - -/* The mapping between symbol names and symbols. */ -LT@&t@_DLSYM_CONST struct { - const char *name; - void *address; -} -lt__PROGRAM__LTX_preloaded_symbols[[]] = -{ - { "@PROGRAM@", (void *) 0 }, -_LT_EOF - $SED "s/^$symcode$symcode* \(.*\) \(.*\)$/ {\"\2\", (void *) \&\2},/" < "$nlist" | $GREP -v main >> conftest.$ac_ext - cat <<\_LT_EOF >> conftest.$ac_ext - {0, (void *) 0} -}; - -/* This works around a problem in FreeBSD linker */ -#ifdef FREEBSD_WORKAROUND -static const void *lt_preloaded_setup() { - return lt__PROGRAM__LTX_preloaded_symbols; -} -#endif - -#ifdef __cplusplus -} -#endif -_LT_EOF - # Now try linking the two files. - mv conftest.$ac_objext conftstm.$ac_objext - lt_globsym_save_LIBS=$LIBS - lt_globsym_save_CFLAGS=$CFLAGS - LIBS="conftstm.$ac_objext" - CFLAGS="$CFLAGS$_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)" - if AC_TRY_EVAL(ac_link) && test -s conftest${ac_exeext}; then - pipe_works=yes - fi - LIBS=$lt_globsym_save_LIBS - CFLAGS=$lt_globsym_save_CFLAGS - else - echo "cannot find nm_test_func in $nlist" >&AS_MESSAGE_LOG_FD - fi - else - echo "cannot find nm_test_var in $nlist" >&AS_MESSAGE_LOG_FD - fi - else - echo "cannot run $lt_cv_sys_global_symbol_pipe" >&AS_MESSAGE_LOG_FD - fi - else - echo "$progname: failed program was:" >&AS_MESSAGE_LOG_FD - cat conftest.$ac_ext >&5 - fi - rm -rf conftest* conftst* - - # Do not use the global_symbol_pipe unless it works. - if test "$pipe_works" = yes; then - break - else - lt_cv_sys_global_symbol_pipe= - fi -done -]) -if test -z "$lt_cv_sys_global_symbol_pipe"; then - lt_cv_sys_global_symbol_to_cdecl= -fi -if test -z "$lt_cv_sys_global_symbol_pipe$lt_cv_sys_global_symbol_to_cdecl"; then - AC_MSG_RESULT(failed) -else - AC_MSG_RESULT(ok) -fi - -# Response file support. -if test "$lt_cv_nm_interface" = "MS dumpbin"; then - nm_file_list_spec='@' -elif $NM --help 2>/dev/null | grep '[[@]]FILE' >/dev/null; then - nm_file_list_spec='@' -fi - -_LT_DECL([global_symbol_pipe], [lt_cv_sys_global_symbol_pipe], [1], - [Take the output of nm and produce a listing of raw symbols and C names]) -_LT_DECL([global_symbol_to_cdecl], [lt_cv_sys_global_symbol_to_cdecl], [1], - [Transform the output of nm in a proper C declaration]) -_LT_DECL([global_symbol_to_c_name_address], - [lt_cv_sys_global_symbol_to_c_name_address], [1], - [Transform the output of nm in a C name address pair]) -_LT_DECL([global_symbol_to_c_name_address_lib_prefix], - [lt_cv_sys_global_symbol_to_c_name_address_lib_prefix], [1], - [Transform the output of nm in a C name address pair when lib prefix is needed]) -_LT_DECL([], [nm_file_list_spec], [1], - [Specify filename containing input files for $NM]) -]) # _LT_CMD_GLOBAL_SYMBOLS - - -# _LT_COMPILER_PIC([TAGNAME]) -# --------------------------- -m4_defun([_LT_COMPILER_PIC], -[m4_require([_LT_TAG_COMPILER])dnl -_LT_TAGVAR(lt_prog_compiler_wl, $1)= -_LT_TAGVAR(lt_prog_compiler_pic, $1)= -_LT_TAGVAR(lt_prog_compiler_static, $1)= - -m4_if([$1], [CXX], [ - # C++ specific cases for pic, static, wl, etc. - if test "$GXX" = yes; then - _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' - _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' - - case $host_os in - aix*) - # All AIX code is PIC. - if test "$host_cpu" = ia64; then - # AIX 5 now supports IA64 processor - _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' - fi - ;; - - amigaos*) - case $host_cpu in - powerpc) - # see comment about AmigaOS4 .so support - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' - ;; - m68k) - # FIXME: we need at least 68020 code to build shared libraries, but - # adding the `-m68020' flag to GCC prevents building anything better, - # like `-m68040'. - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-m68020 -resident32 -malways-restore-a4' - ;; - esac - ;; - - beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*) - # PIC is the default for these OSes. - ;; - mingw* | cygwin* | os2* | pw32* | cegcc*) - # This hack is so that the source file can tell whether it is being - # built for inclusion in a dll (and should export symbols for example). - # Although the cygwin gcc ignores -fPIC, still need this for old-style - # (--disable-auto-import) libraries - m4_if([$1], [GCJ], [], - [_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT']) - ;; - darwin* | rhapsody*) - # PIC is the default on this platform - # Common symbols not allowed in MH_DYLIB files - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fno-common' - ;; - *djgpp*) - # DJGPP does not support shared libraries at all - _LT_TAGVAR(lt_prog_compiler_pic, $1)= - ;; - haiku*) - # PIC is the default for Haiku. - # The "-static" flag exists, but is broken. - _LT_TAGVAR(lt_prog_compiler_static, $1)= - ;; - interix[[3-9]]*) - # Interix 3.x gcc -fpic/-fPIC options generate broken code. - # Instead, we relocate shared libraries at runtime. - ;; - sysv4*MP*) - if test -d /usr/nec; then - _LT_TAGVAR(lt_prog_compiler_pic, $1)=-Kconform_pic - fi - ;; - hpux*) - # PIC is the default for 64-bit PA HP-UX, but not for 32-bit - # PA HP-UX. On IA64 HP-UX, PIC is the default but the pic flag - # sets the default TLS model and affects inlining. - case $host_cpu in - hppa*64*) - ;; - *) - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' - ;; - esac - ;; - *qnx* | *nto*) - # QNX uses GNU C++, but need to define -shared option too, otherwise - # it will coredump. - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared' - ;; - *) - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' - ;; - esac - else - case $host_os in - aix[[4-9]]*) - # All AIX code is PIC. - if test "$host_cpu" = ia64; then - # AIX 5 now supports IA64 processor - _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' - else - _LT_TAGVAR(lt_prog_compiler_static, $1)='-bnso -bI:/lib/syscalls.exp' - fi - ;; - chorus*) - case $cc_basename in - cxch68*) - # Green Hills C++ Compiler - # _LT_TAGVAR(lt_prog_compiler_static, $1)="--no_auto_instantiation -u __main -u __premain -u _abort -r $COOL_DIR/lib/libOrb.a $MVME_DIR/lib/CC/libC.a $MVME_DIR/lib/classix/libcx.s.a" - ;; - esac - ;; - mingw* | cygwin* | os2* | pw32* | cegcc*) - # This hack is so that the source file can tell whether it is being - # built for inclusion in a dll (and should export symbols for example). - m4_if([$1], [GCJ], [], - [_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT']) - ;; - dgux*) - case $cc_basename in - ec++*) - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' - ;; - ghcx*) - # Green Hills C++ Compiler - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic' - ;; - *) - ;; - esac - ;; - freebsd* | dragonfly*) - # FreeBSD uses GNU C++ - ;; - hpux9* | hpux10* | hpux11*) - case $cc_basename in - CC*) - _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' - _LT_TAGVAR(lt_prog_compiler_static, $1)='${wl}-a ${wl}archive' - if test "$host_cpu" != ia64; then - _LT_TAGVAR(lt_prog_compiler_pic, $1)='+Z' - fi - ;; - aCC*) - _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' - _LT_TAGVAR(lt_prog_compiler_static, $1)='${wl}-a ${wl}archive' - case $host_cpu in - hppa*64*|ia64*) - # +Z the default - ;; - *) - _LT_TAGVAR(lt_prog_compiler_pic, $1)='+Z' - ;; - esac - ;; - *) - ;; - esac - ;; - interix*) - # This is c89, which is MS Visual C++ (no shared libs) - # Anyone wants to do a port? - ;; - irix5* | irix6* | nonstopux*) - case $cc_basename in - CC*) - _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' - _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' - # CC pic flag -KPIC is the default. - ;; - *) - ;; - esac - ;; - linux* | k*bsd*-gnu | kopensolaris*-gnu) - case $cc_basename in - KCC*) - # KAI C++ Compiler - _LT_TAGVAR(lt_prog_compiler_wl, $1)='--backend -Wl,' - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' - ;; - ecpc* ) - # old Intel C++ for x86_64 which still supported -KPIC. - _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' - _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' - ;; - icpc* ) - # Intel C++, used to be incompatible with GCC. - # ICC 10 doesn't accept -KPIC any more. - _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' - _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' - ;; - pgCC* | pgcpp*) - # Portland Group C++ compiler - _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fpic' - _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' - ;; - cxx*) - # Compaq C++ - # Make sure the PIC flag is empty. It appears that all Alpha - # Linux and Compaq Tru64 Unix objects are PIC. - _LT_TAGVAR(lt_prog_compiler_pic, $1)= - _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' - ;; - xlc* | xlC* | bgxl[[cC]]* | mpixl[[cC]]*) - # IBM XL 8.0, 9.0 on PPC and BlueGene - _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-qpic' - _LT_TAGVAR(lt_prog_compiler_static, $1)='-qstaticlink' - ;; - *) - case `$CC -V 2>&1 | sed 5q` in - *Sun\ C*) - # Sun C++ 5.9 - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' - _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' - _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ' - ;; - esac - ;; - esac - ;; - lynxos*) - ;; - m88k*) - ;; - mvs*) - case $cc_basename in - cxx*) - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-W c,exportall' - ;; - *) - ;; - esac - ;; - netbsd*) - ;; - *qnx* | *nto*) - # QNX uses GNU C++, but need to define -shared option too, otherwise - # it will coredump. - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared' - ;; - osf3* | osf4* | osf5*) - case $cc_basename in - KCC*) - _LT_TAGVAR(lt_prog_compiler_wl, $1)='--backend -Wl,' - ;; - RCC*) - # Rational C++ 2.4.1 - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic' - ;; - cxx*) - # Digital/Compaq C++ - _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' - # Make sure the PIC flag is empty. It appears that all Alpha - # Linux and Compaq Tru64 Unix objects are PIC. - _LT_TAGVAR(lt_prog_compiler_pic, $1)= - _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' - ;; - *) - ;; - esac - ;; - psos*) - ;; - solaris*) - case $cc_basename in - CC* | sunCC*) - # Sun C++ 4.2, 5.x and Centerline C++ - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' - _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' - _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ' - ;; - gcx*) - # Green Hills C++ Compiler - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-PIC' - ;; - *) - ;; - esac - ;; - sunos4*) - case $cc_basename in - CC*) - # Sun C++ 4.x - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic' - _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' - ;; - lcc*) - # Lucid - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic' - ;; - *) - ;; - esac - ;; - sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*) - case $cc_basename in - CC*) - _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' - _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' - ;; - esac - ;; - tandem*) - case $cc_basename in - NCC*) - # NonStop-UX NCC 3.20 - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' - ;; - *) - ;; - esac - ;; - vxworks*) - ;; - *) - _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no - ;; - esac - fi -], -[ - if test "$GCC" = yes; then - _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' - _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' - - case $host_os in - aix*) - # All AIX code is PIC. - if test "$host_cpu" = ia64; then - # AIX 5 now supports IA64 processor - _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' - fi - ;; - - amigaos*) - case $host_cpu in - powerpc) - # see comment about AmigaOS4 .so support - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' - ;; - m68k) - # FIXME: we need at least 68020 code to build shared libraries, but - # adding the `-m68020' flag to GCC prevents building anything better, - # like `-m68040'. - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-m68020 -resident32 -malways-restore-a4' - ;; - esac - ;; - - beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*) - # PIC is the default for these OSes. - ;; - - mingw* | cygwin* | pw32* | os2* | cegcc*) - # This hack is so that the source file can tell whether it is being - # built for inclusion in a dll (and should export symbols for example). - # Although the cygwin gcc ignores -fPIC, still need this for old-style - # (--disable-auto-import) libraries - m4_if([$1], [GCJ], [], - [_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT']) - ;; - - darwin* | rhapsody*) - # PIC is the default on this platform - # Common symbols not allowed in MH_DYLIB files - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fno-common' - ;; - - haiku*) - # PIC is the default for Haiku. - # The "-static" flag exists, but is broken. - _LT_TAGVAR(lt_prog_compiler_static, $1)= - ;; - - hpux*) - # PIC is the default for 64-bit PA HP-UX, but not for 32-bit - # PA HP-UX. On IA64 HP-UX, PIC is the default but the pic flag - # sets the default TLS model and affects inlining. - case $host_cpu in - hppa*64*) - # +Z the default - ;; - *) - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' - ;; - esac - ;; - - interix[[3-9]]*) - # Interix 3.x gcc -fpic/-fPIC options generate broken code. - # Instead, we relocate shared libraries at runtime. - ;; - - msdosdjgpp*) - # Just because we use GCC doesn't mean we suddenly get shared libraries - # on systems that don't support them. - _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no - enable_shared=no - ;; - - *nto* | *qnx*) - # QNX uses GNU C++, but need to define -shared option too, otherwise - # it will coredump. - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared' - ;; - - sysv4*MP*) - if test -d /usr/nec; then - _LT_TAGVAR(lt_prog_compiler_pic, $1)=-Kconform_pic - fi - ;; - - *) - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' - ;; - esac - - case $cc_basename in - nvcc*) # Cuda Compiler Driver 2.2 - _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Xlinker ' - if test -n "$_LT_TAGVAR(lt_prog_compiler_pic, $1)"; then - _LT_TAGVAR(lt_prog_compiler_pic, $1)="-Xcompiler $_LT_TAGVAR(lt_prog_compiler_pic, $1)" - fi - ;; - esac - else - # PORTME Check for flag to pass linker flags through the system compiler. - case $host_os in - aix*) - _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' - if test "$host_cpu" = ia64; then - # AIX 5 now supports IA64 processor - _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' - else - _LT_TAGVAR(lt_prog_compiler_static, $1)='-bnso -bI:/lib/syscalls.exp' - fi - ;; - - mingw* | cygwin* | pw32* | os2* | cegcc*) - # This hack is so that the source file can tell whether it is being - # built for inclusion in a dll (and should export symbols for example). - m4_if([$1], [GCJ], [], - [_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT']) - ;; - - hpux9* | hpux10* | hpux11*) - _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' - # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but - # not for PA HP-UX. - case $host_cpu in - hppa*64*|ia64*) - # +Z the default - ;; - *) - _LT_TAGVAR(lt_prog_compiler_pic, $1)='+Z' - ;; - esac - # Is there a better lt_prog_compiler_static that works with the bundled CC? - _LT_TAGVAR(lt_prog_compiler_static, $1)='${wl}-a ${wl}archive' - ;; - - irix5* | irix6* | nonstopux*) - _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' - # PIC (with -KPIC) is the default. - _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' - ;; - - linux* | k*bsd*-gnu | kopensolaris*-gnu) - case $cc_basename in - # old Intel for x86_64 which still supported -KPIC. - ecc*) - _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' - _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' - ;; - # icc used to be incompatible with GCC. - # ICC 10 doesn't accept -KPIC any more. - icc* | ifort*) - _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' - _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' - ;; - # Lahey Fortran 8.1. - lf95*) - _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' - _LT_TAGVAR(lt_prog_compiler_pic, $1)='--shared' - _LT_TAGVAR(lt_prog_compiler_static, $1)='--static' - ;; - nagfor*) - # NAG Fortran compiler - _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,-Wl,,' - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-PIC' - _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' - ;; - pgcc* | pgf77* | pgf90* | pgf95* | pgfortran*) - # Portland Group compilers (*not* the Pentium gcc compiler, - # which looks to be a dead project) - _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fpic' - _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' - ;; - ccc*) - _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' - # All Alpha code is PIC. - _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' - ;; - xl* | bgxl* | bgf* | mpixl*) - # IBM XL C 8.0/Fortran 10.1, 11.1 on PPC and BlueGene - _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-qpic' - _LT_TAGVAR(lt_prog_compiler_static, $1)='-qstaticlink' - ;; - *) - case `$CC -V 2>&1 | sed 5q` in - *Sun\ Ceres\ Fortran* | *Sun*Fortran*\ [[1-7]].* | *Sun*Fortran*\ 8.[[0-3]]*) - # Sun Fortran 8.3 passes all unrecognized flags to the linker - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' - _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' - _LT_TAGVAR(lt_prog_compiler_wl, $1)='' - ;; - *Sun\ F* | *Sun*Fortran*) - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' - _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' - _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ' - ;; - *Sun\ C*) - # Sun C 5.9 - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' - _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' - _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' - ;; - *Intel*\ [[CF]]*Compiler*) - _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' - _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' - ;; - *Portland\ Group*) - _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fpic' - _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' - ;; - esac - ;; - esac - ;; - - newsos6) - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' - _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' - ;; - - *nto* | *qnx*) - # QNX uses GNU C++, but need to define -shared option too, otherwise - # it will coredump. - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared' - ;; - - osf3* | osf4* | osf5*) - _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' - # All OSF/1 code is PIC. - _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' - ;; - - rdos*) - _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' - ;; - - solaris*) - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' - _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' - case $cc_basename in - f77* | f90* | f95* | sunf77* | sunf90* | sunf95*) - _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ';; - *) - _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,';; - esac - ;; - - sunos4*) - _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ' - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-PIC' - _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' - ;; - - sysv4 | sysv4.2uw2* | sysv4.3*) - _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' - _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' - ;; - - sysv4*MP*) - if test -d /usr/nec ;then - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-Kconform_pic' - _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' - fi - ;; - - sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*) - _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' - _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' - ;; - - unicos*) - _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' - _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no - ;; - - uts4*) - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic' - _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' - ;; - - *) - _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no - ;; - esac - fi -]) -case $host_os in - # For platforms which do not support PIC, -DPIC is meaningless: - *djgpp*) - _LT_TAGVAR(lt_prog_compiler_pic, $1)= - ;; - *) - _LT_TAGVAR(lt_prog_compiler_pic, $1)="$_LT_TAGVAR(lt_prog_compiler_pic, $1)@&t@m4_if([$1],[],[ -DPIC],[m4_if([$1],[CXX],[ -DPIC],[])])" - ;; -esac - -AC_CACHE_CHECK([for $compiler option to produce PIC], - [_LT_TAGVAR(lt_cv_prog_compiler_pic, $1)], - [_LT_TAGVAR(lt_cv_prog_compiler_pic, $1)=$_LT_TAGVAR(lt_prog_compiler_pic, $1)]) -_LT_TAGVAR(lt_prog_compiler_pic, $1)=$_LT_TAGVAR(lt_cv_prog_compiler_pic, $1) - -# -# Check to make sure the PIC flag actually works. -# -if test -n "$_LT_TAGVAR(lt_prog_compiler_pic, $1)"; then - _LT_COMPILER_OPTION([if $compiler PIC flag $_LT_TAGVAR(lt_prog_compiler_pic, $1) works], - [_LT_TAGVAR(lt_cv_prog_compiler_pic_works, $1)], - [$_LT_TAGVAR(lt_prog_compiler_pic, $1)@&t@m4_if([$1],[],[ -DPIC],[m4_if([$1],[CXX],[ -DPIC],[])])], [], - [case $_LT_TAGVAR(lt_prog_compiler_pic, $1) in - "" | " "*) ;; - *) _LT_TAGVAR(lt_prog_compiler_pic, $1)=" $_LT_TAGVAR(lt_prog_compiler_pic, $1)" ;; - esac], - [_LT_TAGVAR(lt_prog_compiler_pic, $1)= - _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no]) -fi -_LT_TAGDECL([pic_flag], [lt_prog_compiler_pic], [1], - [Additional compiler flags for building library objects]) - -_LT_TAGDECL([wl], [lt_prog_compiler_wl], [1], - [How to pass a linker flag through the compiler]) -# -# Check to make sure the static flag actually works. -# -wl=$_LT_TAGVAR(lt_prog_compiler_wl, $1) eval lt_tmp_static_flag=\"$_LT_TAGVAR(lt_prog_compiler_static, $1)\" -_LT_LINKER_OPTION([if $compiler static flag $lt_tmp_static_flag works], - _LT_TAGVAR(lt_cv_prog_compiler_static_works, $1), - $lt_tmp_static_flag, - [], - [_LT_TAGVAR(lt_prog_compiler_static, $1)=]) -_LT_TAGDECL([link_static_flag], [lt_prog_compiler_static], [1], - [Compiler flag to prevent dynamic linking]) -])# _LT_COMPILER_PIC - - -# _LT_LINKER_SHLIBS([TAGNAME]) -# ---------------------------- -# See if the linker supports building shared libraries. -m4_defun([_LT_LINKER_SHLIBS], -[AC_REQUIRE([LT_PATH_LD])dnl -AC_REQUIRE([LT_PATH_NM])dnl -m4_require([_LT_PATH_MANIFEST_TOOL])dnl -m4_require([_LT_FILEUTILS_DEFAULTS])dnl -m4_require([_LT_DECL_EGREP])dnl -m4_require([_LT_DECL_SED])dnl -m4_require([_LT_CMD_GLOBAL_SYMBOLS])dnl -m4_require([_LT_TAG_COMPILER])dnl -AC_MSG_CHECKING([whether the $compiler linker ($LD) supports shared libraries]) -m4_if([$1], [CXX], [ - _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' - _LT_TAGVAR(exclude_expsyms, $1)=['_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*'] - case $host_os in - aix[[4-9]]*) - # If we're using GNU nm, then we don't want the "-C" option. - # -C means demangle to AIX nm, but means don't demangle with GNU nm - # Also, AIX nm treats weak defined symbols like other global defined - # symbols, whereas GNU nm marks them as "W". - if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then - _LT_TAGVAR(export_symbols_cmds, $1)='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W")) && ([substr](\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols' - else - _LT_TAGVAR(export_symbols_cmds, $1)='$NM -BCpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B")) && ([substr](\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols' - fi - ;; - pw32*) - _LT_TAGVAR(export_symbols_cmds, $1)="$ltdll_cmds" - ;; - cygwin* | mingw* | cegcc*) - case $cc_basename in - cl*) - _LT_TAGVAR(exclude_expsyms, $1)='_NULL_IMPORT_DESCRIPTOR|_IMPORT_DESCRIPTOR_.*' - ;; - *) - _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[[BCDGRS]][[ ]]/s/.*[[ ]]\([[^ ]]*\)/\1 DATA/;s/^.*[[ ]]__nm__\([[^ ]]*\)[[ ]][[^ ]]*/\1 DATA/;/^I[[ ]]/d;/^[[AITW]][[ ]]/s/.* //'\'' | sort | uniq > $export_symbols' - _LT_TAGVAR(exclude_expsyms, $1)=['[_]+GLOBAL_OFFSET_TABLE_|[_]+GLOBAL__[FID]_.*|[_]+head_[A-Za-z0-9_]+_dll|[A-Za-z0-9_]+_dll_iname'] - ;; - esac - ;; - *) - _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' - ;; - esac -], [ - runpath_var= - _LT_TAGVAR(allow_undefined_flag, $1)= - _LT_TAGVAR(always_export_symbols, $1)=no - _LT_TAGVAR(archive_cmds, $1)= - _LT_TAGVAR(archive_expsym_cmds, $1)= - _LT_TAGVAR(compiler_needs_object, $1)=no - _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no - _LT_TAGVAR(export_dynamic_flag_spec, $1)= - _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' - _LT_TAGVAR(hardcode_automatic, $1)=no - _LT_TAGVAR(hardcode_direct, $1)=no - _LT_TAGVAR(hardcode_direct_absolute, $1)=no - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)= - _LT_TAGVAR(hardcode_libdir_separator, $1)= - _LT_TAGVAR(hardcode_minus_L, $1)=no - _LT_TAGVAR(hardcode_shlibpath_var, $1)=unsupported - _LT_TAGVAR(inherit_rpath, $1)=no - _LT_TAGVAR(link_all_deplibs, $1)=unknown - _LT_TAGVAR(module_cmds, $1)= - _LT_TAGVAR(module_expsym_cmds, $1)= - _LT_TAGVAR(old_archive_from_new_cmds, $1)= - _LT_TAGVAR(old_archive_from_expsyms_cmds, $1)= - _LT_TAGVAR(thread_safe_flag_spec, $1)= - _LT_TAGVAR(whole_archive_flag_spec, $1)= - # include_expsyms should be a list of space-separated symbols to be *always* - # included in the symbol list - _LT_TAGVAR(include_expsyms, $1)= - # exclude_expsyms can be an extended regexp of symbols to exclude - # it will be wrapped by ` (' and `)$', so one must not match beginning or - # end of line. Example: `a|bc|.*d.*' will exclude the symbols `a' and `bc', - # as well as any symbol that contains `d'. - _LT_TAGVAR(exclude_expsyms, $1)=['_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*'] - # Although _GLOBAL_OFFSET_TABLE_ is a valid symbol C name, most a.out - # platforms (ab)use it in PIC code, but their linkers get confused if - # the symbol is explicitly referenced. Since portable code cannot - # rely on this symbol name, it's probably fine to never include it in - # preloaded symbol tables. - # Exclude shared library initialization/finalization symbols. -dnl Note also adjust exclude_expsyms for C++ above. - extract_expsyms_cmds= - - case $host_os in - cygwin* | mingw* | pw32* | cegcc*) - # FIXME: the MSVC++ port hasn't been tested in a loooong time - # When not using gcc, we currently assume that we are using - # Microsoft Visual C++. - if test "$GCC" != yes; then - with_gnu_ld=no - fi - ;; - interix*) - # we just hope/assume this is gcc and not c89 (= MSVC++) - with_gnu_ld=yes - ;; - openbsd*) - with_gnu_ld=no - ;; - esac - - _LT_TAGVAR(ld_shlibs, $1)=yes - - # On some targets, GNU ld is compatible enough with the native linker - # that we're better off using the native interface for both. - lt_use_gnu_ld_interface=no - if test "$with_gnu_ld" = yes; then - case $host_os in - aix*) - # The AIX port of GNU ld has always aspired to compatibility - # with the native linker. However, as the warning in the GNU ld - # block says, versions before 2.19.5* couldn't really create working - # shared libraries, regardless of the interface used. - case `$LD -v 2>&1` in - *\ \(GNU\ Binutils\)\ 2.19.5*) ;; - *\ \(GNU\ Binutils\)\ 2.[[2-9]]*) ;; - *\ \(GNU\ Binutils\)\ [[3-9]]*) ;; - *) - lt_use_gnu_ld_interface=yes - ;; - esac - ;; - *) - lt_use_gnu_ld_interface=yes - ;; - esac - fi - - if test "$lt_use_gnu_ld_interface" = yes; then - # If archive_cmds runs LD, not CC, wlarc should be empty - wlarc='${wl}' - - # Set some defaults for GNU ld with shared library support. These - # are reset later if shared libraries are not supported. Putting them - # here allows them to be overridden if necessary. - runpath_var=LD_RUN_PATH - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' - _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic' - # ancient GNU ld didn't support --whole-archive et. al. - if $LD --help 2>&1 | $GREP 'no-whole-archive' > /dev/null; then - _LT_TAGVAR(whole_archive_flag_spec, $1)="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive' - else - _LT_TAGVAR(whole_archive_flag_spec, $1)= - fi - supports_anon_versioning=no - case `$LD -v 2>&1` in - *GNU\ gold*) supports_anon_versioning=yes ;; - *\ [[01]].* | *\ 2.[[0-9]].* | *\ 2.10.*) ;; # catch versions < 2.11 - *\ 2.11.93.0.2\ *) supports_anon_versioning=yes ;; # RH7.3 ... - *\ 2.11.92.0.12\ *) supports_anon_versioning=yes ;; # Mandrake 8.2 ... - *\ 2.11.*) ;; # other 2.11 versions - *) supports_anon_versioning=yes ;; - esac - - # See if GNU ld supports shared libraries. - case $host_os in - aix[[3-9]]*) - # On AIX/PPC, the GNU linker is very broken - if test "$host_cpu" != ia64; then - _LT_TAGVAR(ld_shlibs, $1)=no - cat <<_LT_EOF 1>&2 - -*** Warning: the GNU linker, at least up to release 2.19, is reported -*** to be unable to reliably create shared libraries on AIX. -*** Therefore, libtool is disabling shared libraries support. If you -*** really care for shared libraries, you may want to install binutils -*** 2.20 or above, or modify your PATH so that a non-GNU linker is found. -*** You will then need to restart the configuration process. - -_LT_EOF - fi - ;; - - amigaos*) - case $host_cpu in - powerpc) - # see comment about AmigaOS4 .so support - _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' - _LT_TAGVAR(archive_expsym_cmds, $1)='' - ;; - m68k) - _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' - _LT_TAGVAR(hardcode_minus_L, $1)=yes - ;; - esac - ;; - - beos*) - if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then - _LT_TAGVAR(allow_undefined_flag, $1)=unsupported - # Joseph Beckenbach says some releases of gcc - # support --undefined. This deserves some investigation. FIXME - _LT_TAGVAR(archive_cmds, $1)='$CC -nostart $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' - else - _LT_TAGVAR(ld_shlibs, $1)=no - fi - ;; - - cygwin* | mingw* | pw32* | cegcc*) - # _LT_TAGVAR(hardcode_libdir_flag_spec, $1) is actually meaningless, - # as there is no search path for DLLs. - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' - _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-all-symbols' - _LT_TAGVAR(allow_undefined_flag, $1)=unsupported - _LT_TAGVAR(always_export_symbols, $1)=no - _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes - _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[[BCDGRS]][[ ]]/s/.*[[ ]]\([[^ ]]*\)/\1 DATA/;s/^.*[[ ]]__nm__\([[^ ]]*\)[[ ]][[^ ]]*/\1 DATA/;/^I[[ ]]/d;/^[[AITW]][[ ]]/s/.* //'\'' | sort | uniq > $export_symbols' - _LT_TAGVAR(exclude_expsyms, $1)=['[_]+GLOBAL_OFFSET_TABLE_|[_]+GLOBAL__[FID]_.*|[_]+head_[A-Za-z0-9_]+_dll|[A-Za-z0-9_]+_dll_iname'] - - if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then - _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' - # If the export-symbols file already is a .def file (1st line - # is EXPORTS), use it as is; otherwise, prepend... - _LT_TAGVAR(archive_expsym_cmds, $1)='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then - cp $export_symbols $output_objdir/$soname.def; - else - echo EXPORTS > $output_objdir/$soname.def; - cat $export_symbols >> $output_objdir/$soname.def; - fi~ - $CC -shared $output_objdir/$soname.def $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' - else - _LT_TAGVAR(ld_shlibs, $1)=no - fi - ;; - - haiku*) - _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' - _LT_TAGVAR(link_all_deplibs, $1)=yes - ;; - - interix[[3-9]]*) - _LT_TAGVAR(hardcode_direct, $1)=no - _LT_TAGVAR(hardcode_shlibpath_var, $1)=no - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' - _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' - # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc. - # Instead, shared libraries are loaded at an image base (0x10000000 by - # default) and relocated if they conflict, which is a slow very memory - # consuming and fragmenting process. To avoid this, we pick a random, - # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link - # time. Moving up from 0x10000000 also allows more sbrk(2) space. - _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' - _LT_TAGVAR(archive_expsym_cmds, $1)='sed "s,^,_," $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--retain-symbols-file,$output_objdir/$soname.expsym ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' - ;; - - gnu* | linux* | tpf* | k*bsd*-gnu | kopensolaris*-gnu) - tmp_diet=no - if test "$host_os" = linux-dietlibc; then - case $cc_basename in - diet\ *) tmp_diet=yes;; # linux-dietlibc with static linking (!diet-dyn) - esac - fi - if $LD --help 2>&1 | $EGREP ': supported targets:.* elf' > /dev/null \ - && test "$tmp_diet" = no - then - tmp_addflag=' $pic_flag' - tmp_sharedflag='-shared' - case $cc_basename,$host_cpu in - pgcc*) # Portland Group C compiler - _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' - tmp_addflag=' $pic_flag' - ;; - pgf77* | pgf90* | pgf95* | pgfortran*) - # Portland Group f77 and f90 compilers - _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' - tmp_addflag=' $pic_flag -Mnomain' ;; - ecc*,ia64* | icc*,ia64*) # Intel C compiler on ia64 - tmp_addflag=' -i_dynamic' ;; - efc*,ia64* | ifort*,ia64*) # Intel Fortran compiler on ia64 - tmp_addflag=' -i_dynamic -nofor_main' ;; - ifc* | ifort*) # Intel Fortran compiler - tmp_addflag=' -nofor_main' ;; - lf95*) # Lahey Fortran 8.1 - _LT_TAGVAR(whole_archive_flag_spec, $1)= - tmp_sharedflag='--shared' ;; - xl[[cC]]* | bgxl[[cC]]* | mpixl[[cC]]*) # IBM XL C 8.0 on PPC (deal with xlf below) - tmp_sharedflag='-qmkshrobj' - tmp_addflag= ;; - nvcc*) # Cuda Compiler Driver 2.2 - _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' - _LT_TAGVAR(compiler_needs_object, $1)=yes - ;; - esac - case `$CC -V 2>&1 | sed 5q` in - *Sun\ C*) # Sun C 5.9 - _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' - _LT_TAGVAR(compiler_needs_object, $1)=yes - tmp_sharedflag='-G' ;; - *Sun\ F*) # Sun Fortran 8.3 - tmp_sharedflag='-G' ;; - esac - _LT_TAGVAR(archive_cmds, $1)='$CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' - - if test "x$supports_anon_versioning" = xyes; then - _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $output_objdir/$libname.ver~ - cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ - echo "local: *; };" >> $output_objdir/$libname.ver~ - $CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-version-script ${wl}$output_objdir/$libname.ver -o $lib' - fi - - case $cc_basename in - xlf* | bgf* | bgxlf* | mpixlf*) - # IBM XL Fortran 10.1 on PPC cannot create shared libs itself - _LT_TAGVAR(whole_archive_flag_spec, $1)='--whole-archive$convenience --no-whole-archive' - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' - _LT_TAGVAR(archive_cmds, $1)='$LD -shared $libobjs $deplibs $linker_flags -soname $soname -o $lib' - if test "x$supports_anon_versioning" = xyes; then - _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $output_objdir/$libname.ver~ - cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ - echo "local: *; };" >> $output_objdir/$libname.ver~ - $LD -shared $libobjs $deplibs $linker_flags -soname $soname -version-script $output_objdir/$libname.ver -o $lib' - fi - ;; - esac - else - _LT_TAGVAR(ld_shlibs, $1)=no - fi - ;; - - netbsd*) - if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then - _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable $libobjs $deplibs $linker_flags -o $lib' - wlarc= - else - _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' - _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' - fi - ;; - - solaris*) - if $LD -v 2>&1 | $GREP 'BFD 2\.8' > /dev/null; then - _LT_TAGVAR(ld_shlibs, $1)=no - cat <<_LT_EOF 1>&2 - -*** Warning: The releases 2.8.* of the GNU linker cannot reliably -*** create shared libraries on Solaris systems. Therefore, libtool -*** is disabling shared libraries support. We urge you to upgrade GNU -*** binutils to release 2.9.1 or newer. Another option is to modify -*** your PATH or compiler configuration so that the native linker is -*** used, and then restart. - -_LT_EOF - elif $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then - _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' - _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' - else - _LT_TAGVAR(ld_shlibs, $1)=no - fi - ;; - - sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX*) - case `$LD -v 2>&1` in - *\ [[01]].* | *\ 2.[[0-9]].* | *\ 2.1[[0-5]].*) - _LT_TAGVAR(ld_shlibs, $1)=no - cat <<_LT_EOF 1>&2 - -*** Warning: Releases of the GNU linker prior to 2.16.91.0.3 can not -*** reliably create shared libraries on SCO systems. Therefore, libtool -*** is disabling shared libraries support. We urge you to upgrade GNU -*** binutils to release 2.16.91.0.3 or newer. Another option is to modify -*** your PATH or compiler configuration so that the native linker is -*** used, and then restart. - -_LT_EOF - ;; - *) - # For security reasons, it is highly recommended that you always - # use absolute paths for naming shared libraries, and exclude the - # DT_RUNPATH tag from executables and libraries. But doing so - # requires that you compile everything twice, which is a pain. - if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' - _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' - _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' - else - _LT_TAGVAR(ld_shlibs, $1)=no - fi - ;; - esac - ;; - - sunos4*) - _LT_TAGVAR(archive_cmds, $1)='$LD -assert pure-text -Bshareable -o $lib $libobjs $deplibs $linker_flags' - wlarc= - _LT_TAGVAR(hardcode_direct, $1)=yes - _LT_TAGVAR(hardcode_shlibpath_var, $1)=no - ;; - - *) - if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then - _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' - _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' - else - _LT_TAGVAR(ld_shlibs, $1)=no - fi - ;; - esac - - if test "$_LT_TAGVAR(ld_shlibs, $1)" = no; then - runpath_var= - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)= - _LT_TAGVAR(export_dynamic_flag_spec, $1)= - _LT_TAGVAR(whole_archive_flag_spec, $1)= - fi - else - # PORTME fill in a description of your system's linker (not GNU ld) - case $host_os in - aix3*) - _LT_TAGVAR(allow_undefined_flag, $1)=unsupported - _LT_TAGVAR(always_export_symbols, $1)=yes - _LT_TAGVAR(archive_expsym_cmds, $1)='$LD -o $output_objdir/$soname $libobjs $deplibs $linker_flags -bE:$export_symbols -T512 -H512 -bM:SRE~$AR $AR_FLAGS $lib $output_objdir/$soname' - # Note: this linker hardcodes the directories in LIBPATH if there - # are no directories specified by -L. - _LT_TAGVAR(hardcode_minus_L, $1)=yes - if test "$GCC" = yes && test -z "$lt_prog_compiler_static"; then - # Neither direct hardcoding nor static linking is supported with a - # broken collect2. - _LT_TAGVAR(hardcode_direct, $1)=unsupported - fi - ;; - - aix[[4-9]]*) - if test "$host_cpu" = ia64; then - # On IA64, the linker does run time linking by default, so we don't - # have to do anything special. - aix_use_runtimelinking=no - exp_sym_flag='-Bexport' - no_entry_flag="" - else - # If we're using GNU nm, then we don't want the "-C" option. - # -C means demangle to AIX nm, but means don't demangle with GNU nm - # Also, AIX nm treats weak defined symbols like other global - # defined symbols, whereas GNU nm marks them as "W". - if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then - _LT_TAGVAR(export_symbols_cmds, $1)='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W")) && ([substr](\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols' - else - _LT_TAGVAR(export_symbols_cmds, $1)='$NM -BCpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B")) && ([substr](\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols' - fi - aix_use_runtimelinking=no - - # Test if we are trying to use run time linking or normal - # AIX style linking. If -brtl is somewhere in LDFLAGS, we - # need to do runtime linking. - case $host_os in aix4.[[23]]|aix4.[[23]].*|aix[[5-9]]*) - for ld_flag in $LDFLAGS; do - if (test $ld_flag = "-brtl" || test $ld_flag = "-Wl,-brtl"); then - aix_use_runtimelinking=yes - break - fi - done - ;; - esac - - exp_sym_flag='-bexport' - no_entry_flag='-bnoentry' - fi - - # When large executables or shared objects are built, AIX ld can - # have problems creating the table of contents. If linking a library - # or program results in "error TOC overflow" add -mminimal-toc to - # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not - # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS. - - _LT_TAGVAR(archive_cmds, $1)='' - _LT_TAGVAR(hardcode_direct, $1)=yes - _LT_TAGVAR(hardcode_direct_absolute, $1)=yes - _LT_TAGVAR(hardcode_libdir_separator, $1)=':' - _LT_TAGVAR(link_all_deplibs, $1)=yes - _LT_TAGVAR(file_list_spec, $1)='${wl}-f,' - - if test "$GCC" = yes; then - case $host_os in aix4.[[012]]|aix4.[[012]].*) - # We only want to do this on AIX 4.2 and lower, the check - # below for broken collect2 doesn't work under 4.3+ - collect2name=`${CC} -print-prog-name=collect2` - if test -f "$collect2name" && - strings "$collect2name" | $GREP resolve_lib_name >/dev/null - then - # We have reworked collect2 - : - else - # We have old collect2 - _LT_TAGVAR(hardcode_direct, $1)=unsupported - # It fails to find uninstalled libraries when the uninstalled - # path is not listed in the libpath. Setting hardcode_minus_L - # to unsupported forces relinking - _LT_TAGVAR(hardcode_minus_L, $1)=yes - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' - _LT_TAGVAR(hardcode_libdir_separator, $1)= - fi - ;; - esac - shared_flag='-shared' - if test "$aix_use_runtimelinking" = yes; then - shared_flag="$shared_flag "'${wl}-G' - fi - else - # not using gcc - if test "$host_cpu" = ia64; then - # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release - # chokes on -Wl,-G. The following line is correct: - shared_flag='-G' - else - if test "$aix_use_runtimelinking" = yes; then - shared_flag='${wl}-G' - else - shared_flag='${wl}-bM:SRE' - fi - fi - fi - - _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-bexpall' - # It seems that -bexpall does not export symbols beginning with - # underscore (_), so it is better to generate a list of symbols to export. - _LT_TAGVAR(always_export_symbols, $1)=yes - if test "$aix_use_runtimelinking" = yes; then - # Warning - without using the other runtime loading flags (-brtl), - # -berok will link without error, but may produce a broken library. - _LT_TAGVAR(allow_undefined_flag, $1)='-berok' - # Determine the default libpath from the value encoded in an - # empty executable. - _LT_SYS_MODULE_PATH_AIX([$1]) - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath" - _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then func_echo_all "${wl}${allow_undefined_flag}"; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag" - else - if test "$host_cpu" = ia64; then - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R $libdir:/usr/lib:/lib' - _LT_TAGVAR(allow_undefined_flag, $1)="-z nodefs" - _LT_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$exp_sym_flag:\$export_symbols" - else - # Determine the default libpath from the value encoded in an - # empty executable. - _LT_SYS_MODULE_PATH_AIX([$1]) - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath" - # Warning - without using the other run time loading flags, - # -berok will link without error, but may produce a broken library. - _LT_TAGVAR(no_undefined_flag, $1)=' ${wl}-bernotok' - _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-berok' - if test "$with_gnu_ld" = yes; then - # We only use this code for GNU lds that support --whole-archive. - _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive$convenience ${wl}--no-whole-archive' - else - # Exported symbols can be pulled into shared objects from archives - _LT_TAGVAR(whole_archive_flag_spec, $1)='$convenience' - fi - _LT_TAGVAR(archive_cmds_need_lc, $1)=yes - # This is similar to how AIX traditionally builds its shared libraries. - _LT_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs ${wl}-bnoentry $compiler_flags ${wl}-bE:$export_symbols${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname' - fi - fi - ;; - - amigaos*) - case $host_cpu in - powerpc) - # see comment about AmigaOS4 .so support - _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' - _LT_TAGVAR(archive_expsym_cmds, $1)='' - ;; - m68k) - _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' - _LT_TAGVAR(hardcode_minus_L, $1)=yes - ;; - esac - ;; - - bsdi[[45]]*) - _LT_TAGVAR(export_dynamic_flag_spec, $1)=-rdynamic - ;; - - cygwin* | mingw* | pw32* | cegcc*) - # When not using gcc, we currently assume that we are using - # Microsoft Visual C++. - # hardcode_libdir_flag_spec is actually meaningless, as there is - # no search path for DLLs. - case $cc_basename in - cl*) - # Native MSVC - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)=' ' - _LT_TAGVAR(allow_undefined_flag, $1)=unsupported - _LT_TAGVAR(always_export_symbols, $1)=yes - _LT_TAGVAR(file_list_spec, $1)='@' - # Tell ltmain to make .lib files, not .a files. - libext=lib - # Tell ltmain to make .dll files, not .so files. - shrext_cmds=".dll" - # FIXME: Setting linknames here is a bad hack. - _LT_TAGVAR(archive_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $compiler_flags $deplibs -Wl,-dll~linknames=' - _LT_TAGVAR(archive_expsym_cmds, $1)='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then - sed -n -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' -e '1\\\!p' < $export_symbols > $output_objdir/$soname.exp; - else - sed -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' < $export_symbols > $output_objdir/$soname.exp; - fi~ - $CC -o $tool_output_objdir$soname $libobjs $compiler_flags $deplibs "@$tool_output_objdir$soname.exp" -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~ - linknames=' - # The linker will not automatically build a static lib if we build a DLL. - # _LT_TAGVAR(old_archive_from_new_cmds, $1)='true' - _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes - _LT_TAGVAR(exclude_expsyms, $1)='_NULL_IMPORT_DESCRIPTOR|_IMPORT_DESCRIPTOR_.*' - _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[[BCDGRS]][[ ]]/s/.*[[ ]]\([[^ ]]*\)/\1,DATA/'\'' | $SED -e '\''/^[[AITW]][[ ]]/s/.*[[ ]]//'\'' | sort | uniq > $export_symbols' - # Don't use ranlib - _LT_TAGVAR(old_postinstall_cmds, $1)='chmod 644 $oldlib' - _LT_TAGVAR(postlink_cmds, $1)='lt_outputfile="@OUTPUT@"~ - lt_tool_outputfile="@TOOL_OUTPUT@"~ - case $lt_outputfile in - *.exe|*.EXE) ;; - *) - lt_outputfile="$lt_outputfile.exe" - lt_tool_outputfile="$lt_tool_outputfile.exe" - ;; - esac~ - if test "$MANIFEST_TOOL" != ":" && test -f "$lt_outputfile.manifest"; then - $MANIFEST_TOOL -manifest "$lt_tool_outputfile.manifest" -outputresource:"$lt_tool_outputfile" || exit 1; - $RM "$lt_outputfile.manifest"; - fi' - ;; - *) - # Assume MSVC wrapper - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)=' ' - _LT_TAGVAR(allow_undefined_flag, $1)=unsupported - # Tell ltmain to make .lib files, not .a files. - libext=lib - # Tell ltmain to make .dll files, not .so files. - shrext_cmds=".dll" - # FIXME: Setting linknames here is a bad hack. - _LT_TAGVAR(archive_cmds, $1)='$CC -o $lib $libobjs $compiler_flags `func_echo_all "$deplibs" | $SED '\''s/ -lc$//'\''` -link -dll~linknames=' - # The linker will automatically build a .lib file if we build a DLL. - _LT_TAGVAR(old_archive_from_new_cmds, $1)='true' - # FIXME: Should let the user specify the lib program. - _LT_TAGVAR(old_archive_cmds, $1)='lib -OUT:$oldlib$oldobjs$old_deplibs' - _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes - ;; - esac - ;; - - darwin* | rhapsody*) - _LT_DARWIN_LINKER_FEATURES($1) - ;; - - dgux*) - _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' - _LT_TAGVAR(hardcode_shlibpath_var, $1)=no - ;; - - # FreeBSD 2.2.[012] allows us to include c++rt0.o to get C++ constructor - # support. Future versions do this automatically, but an explicit c++rt0.o - # does not break anything, and helps significantly (at the cost of a little - # extra space). - freebsd2.2*) - _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags /usr/lib/c++rt0.o' - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' - _LT_TAGVAR(hardcode_direct, $1)=yes - _LT_TAGVAR(hardcode_shlibpath_var, $1)=no - ;; - - # Unfortunately, older versions of FreeBSD 2 do not have this feature. - freebsd2.*) - _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' - _LT_TAGVAR(hardcode_direct, $1)=yes - _LT_TAGVAR(hardcode_minus_L, $1)=yes - _LT_TAGVAR(hardcode_shlibpath_var, $1)=no - ;; - - # FreeBSD 3 and greater uses gcc -shared to do shared libraries. - freebsd* | dragonfly*) - _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' - _LT_TAGVAR(hardcode_direct, $1)=yes - _LT_TAGVAR(hardcode_shlibpath_var, $1)=no - ;; - - hpux9*) - if test "$GCC" = yes; then - _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$CC -shared $pic_flag ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $libobjs $deplibs $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' - else - _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$LD -b +b $install_libdir -o $output_objdir/$soname $libobjs $deplibs $linker_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' - fi - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir' - _LT_TAGVAR(hardcode_libdir_separator, $1)=: - _LT_TAGVAR(hardcode_direct, $1)=yes - - # hardcode_minus_L: Not really in the search PATH, - # but as the default location of the library. - _LT_TAGVAR(hardcode_minus_L, $1)=yes - _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' - ;; - - hpux10*) - if test "$GCC" = yes && test "$with_gnu_ld" = no; then - _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' - else - _LT_TAGVAR(archive_cmds, $1)='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags' - fi - if test "$with_gnu_ld" = no; then - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir' - _LT_TAGVAR(hardcode_libdir_separator, $1)=: - _LT_TAGVAR(hardcode_direct, $1)=yes - _LT_TAGVAR(hardcode_direct_absolute, $1)=yes - _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' - # hardcode_minus_L: Not really in the search PATH, - # but as the default location of the library. - _LT_TAGVAR(hardcode_minus_L, $1)=yes - fi - ;; - - hpux11*) - if test "$GCC" = yes && test "$with_gnu_ld" = no; then - case $host_cpu in - hppa*64*) - _LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' - ;; - ia64*) - _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' - ;; - *) - _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' - ;; - esac - else - case $host_cpu in - hppa*64*) - _LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' - ;; - ia64*) - _LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' - ;; - *) - m4_if($1, [], [ - # Older versions of the 11.00 compiler do not understand -b yet - # (HP92453-01 A.11.01.20 doesn't, HP92453-01 B.11.X.35175-35176.GP does) - _LT_LINKER_OPTION([if $CC understands -b], - _LT_TAGVAR(lt_cv_prog_compiler__b, $1), [-b], - [_LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags'], - [_LT_TAGVAR(archive_cmds, $1)='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags'])], - [_LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags']) - ;; - esac - fi - if test "$with_gnu_ld" = no; then - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir' - _LT_TAGVAR(hardcode_libdir_separator, $1)=: - - case $host_cpu in - hppa*64*|ia64*) - _LT_TAGVAR(hardcode_direct, $1)=no - _LT_TAGVAR(hardcode_shlibpath_var, $1)=no - ;; - *) - _LT_TAGVAR(hardcode_direct, $1)=yes - _LT_TAGVAR(hardcode_direct_absolute, $1)=yes - _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' - - # hardcode_minus_L: Not really in the search PATH, - # but as the default location of the library. - _LT_TAGVAR(hardcode_minus_L, $1)=yes - ;; - esac - fi - ;; - - irix5* | irix6* | nonstopux*) - if test "$GCC" = yes; then - _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' - # Try to use the -exported_symbol ld option, if it does not - # work, assume that -exports_file does not work either and - # implicitly export all symbols. - # This should be the same for all languages, so no per-tag cache variable. - AC_CACHE_CHECK([whether the $host_os linker accepts -exported_symbol], - [lt_cv_irix_exported_symbol], - [save_LDFLAGS="$LDFLAGS" - LDFLAGS="$LDFLAGS -shared ${wl}-exported_symbol ${wl}foo ${wl}-update_registry ${wl}/dev/null" - AC_LINK_IFELSE( - [AC_LANG_SOURCE( - [AC_LANG_CASE([C], [[int foo (void) { return 0; }]], - [C++], [[int foo (void) { return 0; }]], - [Fortran 77], [[ - subroutine foo - end]], - [Fortran], [[ - subroutine foo - end]])])], - [lt_cv_irix_exported_symbol=yes], - [lt_cv_irix_exported_symbol=no]) - LDFLAGS="$save_LDFLAGS"]) - if test "$lt_cv_irix_exported_symbol" = yes; then - _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations ${wl}-exports_file ${wl}$export_symbols -o $lib' - fi - else - _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib' - _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -exports_file $export_symbols -o $lib' - fi - _LT_TAGVAR(archive_cmds_need_lc, $1)='no' - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' - _LT_TAGVAR(hardcode_libdir_separator, $1)=: - _LT_TAGVAR(inherit_rpath, $1)=yes - _LT_TAGVAR(link_all_deplibs, $1)=yes - ;; - - netbsd*) - if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then - _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' # a.out - else - _LT_TAGVAR(archive_cmds, $1)='$LD -shared -o $lib $libobjs $deplibs $linker_flags' # ELF - fi - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' - _LT_TAGVAR(hardcode_direct, $1)=yes - _LT_TAGVAR(hardcode_shlibpath_var, $1)=no - ;; - - newsos6) - _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' - _LT_TAGVAR(hardcode_direct, $1)=yes - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' - _LT_TAGVAR(hardcode_libdir_separator, $1)=: - _LT_TAGVAR(hardcode_shlibpath_var, $1)=no - ;; - - *nto* | *qnx*) - ;; - - openbsd*) - if test -f /usr/libexec/ld.so; then - _LT_TAGVAR(hardcode_direct, $1)=yes - _LT_TAGVAR(hardcode_shlibpath_var, $1)=no - _LT_TAGVAR(hardcode_direct_absolute, $1)=yes - if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then - _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' - _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-retain-symbols-file,$export_symbols' - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' - _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' - else - case $host_os in - openbsd[[01]].* | openbsd2.[[0-7]] | openbsd2.[[0-7]].*) - _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' - ;; - *) - _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' - ;; - esac - fi - else - _LT_TAGVAR(ld_shlibs, $1)=no - fi - ;; - - os2*) - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' - _LT_TAGVAR(hardcode_minus_L, $1)=yes - _LT_TAGVAR(allow_undefined_flag, $1)=unsupported - _LT_TAGVAR(archive_cmds, $1)='$ECHO "LIBRARY $libname INITINSTANCE" > $output_objdir/$libname.def~$ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~echo DATA >> $output_objdir/$libname.def~echo " SINGLE NONSHARED" >> $output_objdir/$libname.def~echo EXPORTS >> $output_objdir/$libname.def~emxexp $libobjs >> $output_objdir/$libname.def~$CC -Zdll -Zcrtdll -o $lib $libobjs $deplibs $compiler_flags $output_objdir/$libname.def' - _LT_TAGVAR(old_archive_from_new_cmds, $1)='emximp -o $output_objdir/$libname.a $output_objdir/$libname.def' - ;; - - osf3*) - if test "$GCC" = yes; then - _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*' - _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' - else - _LT_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*' - _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib' - fi - _LT_TAGVAR(archive_cmds_need_lc, $1)='no' - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' - _LT_TAGVAR(hardcode_libdir_separator, $1)=: - ;; - - osf4* | osf5*) # as osf3* with the addition of -msym flag - if test "$GCC" = yes; then - _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*' - _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $pic_flag $libobjs $deplibs $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' - else - _LT_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*' - _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags -msym -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib' - _LT_TAGVAR(archive_expsym_cmds, $1)='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done; printf "%s\\n" "-hidden">> $lib.exp~ - $CC -shared${allow_undefined_flag} ${wl}-input ${wl}$lib.exp $compiler_flags $libobjs $deplibs -soname $soname `test -n "$verstring" && $ECHO "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib~$RM $lib.exp' - - # Both c and cxx compiler support -rpath directly - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir' - fi - _LT_TAGVAR(archive_cmds_need_lc, $1)='no' - _LT_TAGVAR(hardcode_libdir_separator, $1)=: - ;; - - solaris*) - _LT_TAGVAR(no_undefined_flag, $1)=' -z defs' - if test "$GCC" = yes; then - wlarc='${wl}' - _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag ${wl}-z ${wl}text ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' - _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ - $CC -shared $pic_flag ${wl}-z ${wl}text ${wl}-M ${wl}$lib.exp ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp' - else - case `$CC -V 2>&1` in - *"Compilers 5.0"*) - wlarc='' - _LT_TAGVAR(archive_cmds, $1)='$LD -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $linker_flags' - _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ - $LD -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$RM $lib.exp' - ;; - *) - wlarc='${wl}' - _LT_TAGVAR(archive_cmds, $1)='$CC -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $compiler_flags' - _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ - $CC -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp' - ;; - esac - fi - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' - _LT_TAGVAR(hardcode_shlibpath_var, $1)=no - case $host_os in - solaris2.[[0-5]] | solaris2.[[0-5]].*) ;; - *) - # The compiler driver will combine and reorder linker options, - # but understands `-z linker_flag'. GCC discards it without `$wl', - # but is careful enough not to reorder. - # Supported since Solaris 2.6 (maybe 2.5.1?) - if test "$GCC" = yes; then - _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}-z ${wl}allextract$convenience ${wl}-z ${wl}defaultextract' - else - _LT_TAGVAR(whole_archive_flag_spec, $1)='-z allextract$convenience -z defaultextract' - fi - ;; - esac - _LT_TAGVAR(link_all_deplibs, $1)=yes - ;; - - sunos4*) - if test "x$host_vendor" = xsequent; then - # Use $CC to link under sequent, because it throws in some extra .o - # files that make .init and .fini sections work. - _LT_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h $soname -o $lib $libobjs $deplibs $compiler_flags' - else - _LT_TAGVAR(archive_cmds, $1)='$LD -assert pure-text -Bstatic -o $lib $libobjs $deplibs $linker_flags' - fi - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' - _LT_TAGVAR(hardcode_direct, $1)=yes - _LT_TAGVAR(hardcode_minus_L, $1)=yes - _LT_TAGVAR(hardcode_shlibpath_var, $1)=no - ;; - - sysv4) - case $host_vendor in - sni) - _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' - _LT_TAGVAR(hardcode_direct, $1)=yes # is this really true??? - ;; - siemens) - ## LD is ld it makes a PLAMLIB - ## CC just makes a GrossModule. - _LT_TAGVAR(archive_cmds, $1)='$LD -G -o $lib $libobjs $deplibs $linker_flags' - _LT_TAGVAR(reload_cmds, $1)='$CC -r -o $output$reload_objs' - _LT_TAGVAR(hardcode_direct, $1)=no - ;; - motorola) - _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' - _LT_TAGVAR(hardcode_direct, $1)=no #Motorola manual says yes, but my tests say they lie - ;; - esac - runpath_var='LD_RUN_PATH' - _LT_TAGVAR(hardcode_shlibpath_var, $1)=no - ;; - - sysv4.3*) - _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' - _LT_TAGVAR(hardcode_shlibpath_var, $1)=no - _LT_TAGVAR(export_dynamic_flag_spec, $1)='-Bexport' - ;; - - sysv4*MP*) - if test -d /usr/nec; then - _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' - _LT_TAGVAR(hardcode_shlibpath_var, $1)=no - runpath_var=LD_RUN_PATH - hardcode_runpath_var=yes - _LT_TAGVAR(ld_shlibs, $1)=yes - fi - ;; - - sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[[01]].[[10]]* | unixware7* | sco3.2v5.0.[[024]]*) - _LT_TAGVAR(no_undefined_flag, $1)='${wl}-z,text' - _LT_TAGVAR(archive_cmds_need_lc, $1)=no - _LT_TAGVAR(hardcode_shlibpath_var, $1)=no - runpath_var='LD_RUN_PATH' - - if test "$GCC" = yes; then - _LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' - _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' - else - _LT_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' - _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' - fi - ;; - - sysv5* | sco3.2v5* | sco5v6*) - # Note: We can NOT use -z defs as we might desire, because we do not - # link with -lc, and that would cause any symbols used from libc to - # always be unresolved, which means just about no library would - # ever link correctly. If we're not using GNU ld we use -z text - # though, which does catch some bad symbols but isn't as heavy-handed - # as -z defs. - _LT_TAGVAR(no_undefined_flag, $1)='${wl}-z,text' - _LT_TAGVAR(allow_undefined_flag, $1)='${wl}-z,nodefs' - _LT_TAGVAR(archive_cmds_need_lc, $1)=no - _LT_TAGVAR(hardcode_shlibpath_var, $1)=no - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R,$libdir' - _LT_TAGVAR(hardcode_libdir_separator, $1)=':' - _LT_TAGVAR(link_all_deplibs, $1)=yes - _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-Bexport' - runpath_var='LD_RUN_PATH' - - if test "$GCC" = yes; then - _LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' - _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' - else - _LT_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' - _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' - fi - ;; - - uts4*) - _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' - _LT_TAGVAR(hardcode_shlibpath_var, $1)=no - ;; - - *) - _LT_TAGVAR(ld_shlibs, $1)=no - ;; - esac - - if test x$host_vendor = xsni; then - case $host in - sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*) - _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-Blargedynsym' - ;; - esac - fi - fi -]) -AC_MSG_RESULT([$_LT_TAGVAR(ld_shlibs, $1)]) -test "$_LT_TAGVAR(ld_shlibs, $1)" = no && can_build_shared=no - -_LT_TAGVAR(with_gnu_ld, $1)=$with_gnu_ld - -_LT_DECL([], [libext], [0], [Old archive suffix (normally "a")])dnl -_LT_DECL([], [shrext_cmds], [1], [Shared library suffix (normally ".so")])dnl -_LT_DECL([], [extract_expsyms_cmds], [2], - [The commands to extract the exported symbol list from a shared archive]) - -# -# Do we need to explicitly link libc? -# -case "x$_LT_TAGVAR(archive_cmds_need_lc, $1)" in -x|xyes) - # Assume -lc should be added - _LT_TAGVAR(archive_cmds_need_lc, $1)=yes - - if test "$enable_shared" = yes && test "$GCC" = yes; then - case $_LT_TAGVAR(archive_cmds, $1) in - *'~'*) - # FIXME: we may have to deal with multi-command sequences. - ;; - '$CC '*) - # Test whether the compiler implicitly links with -lc since on some - # systems, -lgcc has to come before -lc. If gcc already passes -lc - # to ld, don't add -lc before -lgcc. - AC_CACHE_CHECK([whether -lc should be explicitly linked in], - [lt_cv_]_LT_TAGVAR(archive_cmds_need_lc, $1), - [$RM conftest* - echo "$lt_simple_compile_test_code" > conftest.$ac_ext - - if AC_TRY_EVAL(ac_compile) 2>conftest.err; then - soname=conftest - lib=conftest - libobjs=conftest.$ac_objext - deplibs= - wl=$_LT_TAGVAR(lt_prog_compiler_wl, $1) - pic_flag=$_LT_TAGVAR(lt_prog_compiler_pic, $1) - compiler_flags=-v - linker_flags=-v - verstring= - output_objdir=. - libname=conftest - lt_save_allow_undefined_flag=$_LT_TAGVAR(allow_undefined_flag, $1) - _LT_TAGVAR(allow_undefined_flag, $1)= - if AC_TRY_EVAL(_LT_TAGVAR(archive_cmds, $1) 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1) - then - lt_cv_[]_LT_TAGVAR(archive_cmds_need_lc, $1)=no - else - lt_cv_[]_LT_TAGVAR(archive_cmds_need_lc, $1)=yes - fi - _LT_TAGVAR(allow_undefined_flag, $1)=$lt_save_allow_undefined_flag - else - cat conftest.err 1>&5 - fi - $RM conftest* - ]) - _LT_TAGVAR(archive_cmds_need_lc, $1)=$lt_cv_[]_LT_TAGVAR(archive_cmds_need_lc, $1) - ;; - esac - fi - ;; -esac - -_LT_TAGDECL([build_libtool_need_lc], [archive_cmds_need_lc], [0], - [Whether or not to add -lc for building shared libraries]) -_LT_TAGDECL([allow_libtool_libs_with_static_runtimes], - [enable_shared_with_static_runtimes], [0], - [Whether or not to disallow shared libs when runtime libs are static]) -_LT_TAGDECL([], [export_dynamic_flag_spec], [1], - [Compiler flag to allow reflexive dlopens]) -_LT_TAGDECL([], [whole_archive_flag_spec], [1], - [Compiler flag to generate shared objects directly from archives]) -_LT_TAGDECL([], [compiler_needs_object], [1], - [Whether the compiler copes with passing no objects directly]) -_LT_TAGDECL([], [old_archive_from_new_cmds], [2], - [Create an old-style archive from a shared archive]) -_LT_TAGDECL([], [old_archive_from_expsyms_cmds], [2], - [Create a temporary old-style archive to link instead of a shared archive]) -_LT_TAGDECL([], [archive_cmds], [2], [Commands used to build a shared archive]) -_LT_TAGDECL([], [archive_expsym_cmds], [2]) -_LT_TAGDECL([], [module_cmds], [2], - [Commands used to build a loadable module if different from building - a shared archive.]) -_LT_TAGDECL([], [module_expsym_cmds], [2]) -_LT_TAGDECL([], [with_gnu_ld], [1], - [Whether we are building with GNU ld or not]) -_LT_TAGDECL([], [allow_undefined_flag], [1], - [Flag that allows shared libraries with undefined symbols to be built]) -_LT_TAGDECL([], [no_undefined_flag], [1], - [Flag that enforces no undefined symbols]) -_LT_TAGDECL([], [hardcode_libdir_flag_spec], [1], - [Flag to hardcode $libdir into a binary during linking. - This must work even if $libdir does not exist]) -_LT_TAGDECL([], [hardcode_libdir_separator], [1], - [Whether we need a single "-rpath" flag with a separated argument]) -_LT_TAGDECL([], [hardcode_direct], [0], - [Set to "yes" if using DIR/libNAME${shared_ext} during linking hardcodes - DIR into the resulting binary]) -_LT_TAGDECL([], [hardcode_direct_absolute], [0], - [Set to "yes" if using DIR/libNAME${shared_ext} during linking hardcodes - DIR into the resulting binary and the resulting library dependency is - "absolute", i.e impossible to change by setting ${shlibpath_var} if the - library is relocated]) -_LT_TAGDECL([], [hardcode_minus_L], [0], - [Set to "yes" if using the -LDIR flag during linking hardcodes DIR - into the resulting binary]) -_LT_TAGDECL([], [hardcode_shlibpath_var], [0], - [Set to "yes" if using SHLIBPATH_VAR=DIR during linking hardcodes DIR - into the resulting binary]) -_LT_TAGDECL([], [hardcode_automatic], [0], - [Set to "yes" if building a shared library automatically hardcodes DIR - into the library and all subsequent libraries and executables linked - against it]) -_LT_TAGDECL([], [inherit_rpath], [0], - [Set to yes if linker adds runtime paths of dependent libraries - to runtime path list]) -_LT_TAGDECL([], [link_all_deplibs], [0], - [Whether libtool must link a program against all its dependency libraries]) -_LT_TAGDECL([], [always_export_symbols], [0], - [Set to "yes" if exported symbols are required]) -_LT_TAGDECL([], [export_symbols_cmds], [2], - [The commands to list exported symbols]) -_LT_TAGDECL([], [exclude_expsyms], [1], - [Symbols that should not be listed in the preloaded symbols]) -_LT_TAGDECL([], [include_expsyms], [1], - [Symbols that must always be exported]) -_LT_TAGDECL([], [prelink_cmds], [2], - [Commands necessary for linking programs (against libraries) with templates]) -_LT_TAGDECL([], [postlink_cmds], [2], - [Commands necessary for finishing linking programs]) -_LT_TAGDECL([], [file_list_spec], [1], - [Specify filename containing input files]) -dnl FIXME: Not yet implemented -dnl _LT_TAGDECL([], [thread_safe_flag_spec], [1], -dnl [Compiler flag to generate thread safe objects]) -])# _LT_LINKER_SHLIBS - - -# _LT_LANG_C_CONFIG([TAG]) -# ------------------------ -# Ensure that the configuration variables for a C compiler are suitably -# defined. These variables are subsequently used by _LT_CONFIG to write -# the compiler configuration to `libtool'. -m4_defun([_LT_LANG_C_CONFIG], -[m4_require([_LT_DECL_EGREP])dnl -lt_save_CC="$CC" -AC_LANG_PUSH(C) - -# Source file extension for C test sources. -ac_ext=c - -# Object file extension for compiled C test sources. -objext=o -_LT_TAGVAR(objext, $1)=$objext - -# Code to be used in simple compile tests -lt_simple_compile_test_code="int some_variable = 0;" - -# Code to be used in simple link tests -lt_simple_link_test_code='int main(){return(0);}' - -_LT_TAG_COMPILER -# Save the default compiler, since it gets overwritten when the other -# tags are being tested, and _LT_TAGVAR(compiler, []) is a NOP. -compiler_DEFAULT=$CC - -# save warnings/boilerplate of simple test code -_LT_COMPILER_BOILERPLATE -_LT_LINKER_BOILERPLATE - -if test -n "$compiler"; then - _LT_COMPILER_NO_RTTI($1) - _LT_COMPILER_PIC($1) - _LT_COMPILER_C_O($1) - _LT_COMPILER_FILE_LOCKS($1) - _LT_LINKER_SHLIBS($1) - _LT_SYS_DYNAMIC_LINKER($1) - _LT_LINKER_HARDCODE_LIBPATH($1) - LT_SYS_DLOPEN_SELF - _LT_CMD_STRIPLIB - - # Report which library types will actually be built - AC_MSG_CHECKING([if libtool supports shared libraries]) - AC_MSG_RESULT([$can_build_shared]) - - AC_MSG_CHECKING([whether to build shared libraries]) - test "$can_build_shared" = "no" && enable_shared=no - - # On AIX, shared libraries and static libraries use the same namespace, and - # are all built from PIC. - case $host_os in - aix3*) - test "$enable_shared" = yes && enable_static=no - if test -n "$RANLIB"; then - archive_cmds="$archive_cmds~\$RANLIB \$lib" - postinstall_cmds='$RANLIB $lib' - fi - ;; - - aix[[4-9]]*) - if test "$host_cpu" != ia64 && test "$aix_use_runtimelinking" = no ; then - test "$enable_shared" = yes && enable_static=no - fi - ;; - esac - AC_MSG_RESULT([$enable_shared]) - - AC_MSG_CHECKING([whether to build static libraries]) - # Make sure either enable_shared or enable_static is yes. - test "$enable_shared" = yes || enable_static=yes - AC_MSG_RESULT([$enable_static]) - - _LT_CONFIG($1) -fi -AC_LANG_POP -CC="$lt_save_CC" -])# _LT_LANG_C_CONFIG - - -# _LT_LANG_CXX_CONFIG([TAG]) -# -------------------------- -# Ensure that the configuration variables for a C++ compiler are suitably -# defined. These variables are subsequently used by _LT_CONFIG to write -# the compiler configuration to `libtool'. -m4_defun([_LT_LANG_CXX_CONFIG], -[m4_require([_LT_FILEUTILS_DEFAULTS])dnl -m4_require([_LT_DECL_EGREP])dnl -m4_require([_LT_PATH_MANIFEST_TOOL])dnl -if test -n "$CXX" && ( test "X$CXX" != "Xno" && - ( (test "X$CXX" = "Xg++" && `g++ -v >/dev/null 2>&1` ) || - (test "X$CXX" != "Xg++"))) ; then - AC_PROG_CXXCPP -else - _lt_caught_CXX_error=yes -fi - -AC_LANG_PUSH(C++) -_LT_TAGVAR(archive_cmds_need_lc, $1)=no -_LT_TAGVAR(allow_undefined_flag, $1)= -_LT_TAGVAR(always_export_symbols, $1)=no -_LT_TAGVAR(archive_expsym_cmds, $1)= -_LT_TAGVAR(compiler_needs_object, $1)=no -_LT_TAGVAR(export_dynamic_flag_spec, $1)= -_LT_TAGVAR(hardcode_direct, $1)=no -_LT_TAGVAR(hardcode_direct_absolute, $1)=no -_LT_TAGVAR(hardcode_libdir_flag_spec, $1)= -_LT_TAGVAR(hardcode_libdir_separator, $1)= -_LT_TAGVAR(hardcode_minus_L, $1)=no -_LT_TAGVAR(hardcode_shlibpath_var, $1)=unsupported -_LT_TAGVAR(hardcode_automatic, $1)=no -_LT_TAGVAR(inherit_rpath, $1)=no -_LT_TAGVAR(module_cmds, $1)= -_LT_TAGVAR(module_expsym_cmds, $1)= -_LT_TAGVAR(link_all_deplibs, $1)=unknown -_LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds -_LT_TAGVAR(reload_flag, $1)=$reload_flag -_LT_TAGVAR(reload_cmds, $1)=$reload_cmds -_LT_TAGVAR(no_undefined_flag, $1)= -_LT_TAGVAR(whole_archive_flag_spec, $1)= -_LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no - -# Source file extension for C++ test sources. -ac_ext=cpp - -# Object file extension for compiled C++ test sources. -objext=o -_LT_TAGVAR(objext, $1)=$objext - -# No sense in running all these tests if we already determined that -# the CXX compiler isn't working. Some variables (like enable_shared) -# are currently assumed to apply to all compilers on this platform, -# and will be corrupted by setting them based on a non-working compiler. -if test "$_lt_caught_CXX_error" != yes; then - # Code to be used in simple compile tests - lt_simple_compile_test_code="int some_variable = 0;" - - # Code to be used in simple link tests - lt_simple_link_test_code='int main(int, char *[[]]) { return(0); }' - - # ltmain only uses $CC for tagged configurations so make sure $CC is set. - _LT_TAG_COMPILER - - # save warnings/boilerplate of simple test code - _LT_COMPILER_BOILERPLATE - _LT_LINKER_BOILERPLATE - - # Allow CC to be a program name with arguments. - lt_save_CC=$CC - lt_save_CFLAGS=$CFLAGS - lt_save_LD=$LD - lt_save_GCC=$GCC - GCC=$GXX - lt_save_with_gnu_ld=$with_gnu_ld - lt_save_path_LD=$lt_cv_path_LD - if test -n "${lt_cv_prog_gnu_ldcxx+set}"; then - lt_cv_prog_gnu_ld=$lt_cv_prog_gnu_ldcxx - else - $as_unset lt_cv_prog_gnu_ld - fi - if test -n "${lt_cv_path_LDCXX+set}"; then - lt_cv_path_LD=$lt_cv_path_LDCXX - else - $as_unset lt_cv_path_LD - fi - test -z "${LDCXX+set}" || LD=$LDCXX - CC=${CXX-"c++"} - CFLAGS=$CXXFLAGS - compiler=$CC - _LT_TAGVAR(compiler, $1)=$CC - _LT_CC_BASENAME([$compiler]) - - if test -n "$compiler"; then - # We don't want -fno-exception when compiling C++ code, so set the - # no_builtin_flag separately - if test "$GXX" = yes; then - _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=' -fno-builtin' - else - _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)= - fi - - if test "$GXX" = yes; then - # Set up default GNU C++ configuration - - LT_PATH_LD - - # Check if GNU C++ uses GNU ld as the underlying linker, since the - # archiving commands below assume that GNU ld is being used. - if test "$with_gnu_ld" = yes; then - _LT_TAGVAR(archive_cmds, $1)='$CC $pic_flag -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib' - _LT_TAGVAR(archive_expsym_cmds, $1)='$CC $pic_flag -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' - - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' - _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic' - - # If archive_cmds runs LD, not CC, wlarc should be empty - # XXX I think wlarc can be eliminated in ltcf-cxx, but I need to - # investigate it a little bit more. (MM) - wlarc='${wl}' - - # ancient GNU ld didn't support --whole-archive et. al. - if eval "`$CC -print-prog-name=ld` --help 2>&1" | - $GREP 'no-whole-archive' > /dev/null; then - _LT_TAGVAR(whole_archive_flag_spec, $1)="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive' - else - _LT_TAGVAR(whole_archive_flag_spec, $1)= - fi - else - with_gnu_ld=no - wlarc= - - # A generic and very simple default shared library creation - # command for GNU C++ for the case where it uses the native - # linker, instead of GNU ld. If possible, this setting should - # overridden to take advantage of the native linker features on - # the platform it is being used on. - _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib' - fi - - # Commands to make compiler produce verbose output that lists - # what "hidden" libraries, object files and flags are used when - # linking a shared library. - output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"' - - else - GXX=no - with_gnu_ld=no - wlarc= - fi - - # PORTME: fill in a description of your system's C++ link characteristics - AC_MSG_CHECKING([whether the $compiler linker ($LD) supports shared libraries]) - _LT_TAGVAR(ld_shlibs, $1)=yes - case $host_os in - aix3*) - # FIXME: insert proper C++ library support - _LT_TAGVAR(ld_shlibs, $1)=no - ;; - aix[[4-9]]*) - if test "$host_cpu" = ia64; then - # On IA64, the linker does run time linking by default, so we don't - # have to do anything special. - aix_use_runtimelinking=no - exp_sym_flag='-Bexport' - no_entry_flag="" - else - aix_use_runtimelinking=no - - # Test if we are trying to use run time linking or normal - # AIX style linking. If -brtl is somewhere in LDFLAGS, we - # need to do runtime linking. - case $host_os in aix4.[[23]]|aix4.[[23]].*|aix[[5-9]]*) - for ld_flag in $LDFLAGS; do - case $ld_flag in - *-brtl*) - aix_use_runtimelinking=yes - break - ;; - esac - done - ;; - esac - - exp_sym_flag='-bexport' - no_entry_flag='-bnoentry' - fi - - # When large executables or shared objects are built, AIX ld can - # have problems creating the table of contents. If linking a library - # or program results in "error TOC overflow" add -mminimal-toc to - # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not - # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS. - - _LT_TAGVAR(archive_cmds, $1)='' - _LT_TAGVAR(hardcode_direct, $1)=yes - _LT_TAGVAR(hardcode_direct_absolute, $1)=yes - _LT_TAGVAR(hardcode_libdir_separator, $1)=':' - _LT_TAGVAR(link_all_deplibs, $1)=yes - _LT_TAGVAR(file_list_spec, $1)='${wl}-f,' - - if test "$GXX" = yes; then - case $host_os in aix4.[[012]]|aix4.[[012]].*) - # We only want to do this on AIX 4.2 and lower, the check - # below for broken collect2 doesn't work under 4.3+ - collect2name=`${CC} -print-prog-name=collect2` - if test -f "$collect2name" && - strings "$collect2name" | $GREP resolve_lib_name >/dev/null - then - # We have reworked collect2 - : - else - # We have old collect2 - _LT_TAGVAR(hardcode_direct, $1)=unsupported - # It fails to find uninstalled libraries when the uninstalled - # path is not listed in the libpath. Setting hardcode_minus_L - # to unsupported forces relinking - _LT_TAGVAR(hardcode_minus_L, $1)=yes - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' - _LT_TAGVAR(hardcode_libdir_separator, $1)= - fi - esac - shared_flag='-shared' - if test "$aix_use_runtimelinking" = yes; then - shared_flag="$shared_flag "'${wl}-G' - fi - else - # not using gcc - if test "$host_cpu" = ia64; then - # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release - # chokes on -Wl,-G. The following line is correct: - shared_flag='-G' - else - if test "$aix_use_runtimelinking" = yes; then - shared_flag='${wl}-G' - else - shared_flag='${wl}-bM:SRE' - fi - fi - fi - - _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-bexpall' - # It seems that -bexpall does not export symbols beginning with - # underscore (_), so it is better to generate a list of symbols to - # export. - _LT_TAGVAR(always_export_symbols, $1)=yes - if test "$aix_use_runtimelinking" = yes; then - # Warning - without using the other runtime loading flags (-brtl), - # -berok will link without error, but may produce a broken library. - _LT_TAGVAR(allow_undefined_flag, $1)='-berok' - # Determine the default libpath from the value encoded in an empty - # executable. - _LT_SYS_MODULE_PATH_AIX([$1]) - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath" - - _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then func_echo_all "${wl}${allow_undefined_flag}"; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag" - else - if test "$host_cpu" = ia64; then - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R $libdir:/usr/lib:/lib' - _LT_TAGVAR(allow_undefined_flag, $1)="-z nodefs" - _LT_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$exp_sym_flag:\$export_symbols" - else - # Determine the default libpath from the value encoded in an - # empty executable. - _LT_SYS_MODULE_PATH_AIX([$1]) - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath" - # Warning - without using the other run time loading flags, - # -berok will link without error, but may produce a broken library. - _LT_TAGVAR(no_undefined_flag, $1)=' ${wl}-bernotok' - _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-berok' - if test "$with_gnu_ld" = yes; then - # We only use this code for GNU lds that support --whole-archive. - _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive$convenience ${wl}--no-whole-archive' - else - # Exported symbols can be pulled into shared objects from archives - _LT_TAGVAR(whole_archive_flag_spec, $1)='$convenience' - fi - _LT_TAGVAR(archive_cmds_need_lc, $1)=yes - # This is similar to how AIX traditionally builds its shared - # libraries. - _LT_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs ${wl}-bnoentry $compiler_flags ${wl}-bE:$export_symbols${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname' - fi - fi - ;; - - beos*) - if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then - _LT_TAGVAR(allow_undefined_flag, $1)=unsupported - # Joseph Beckenbach says some releases of gcc - # support --undefined. This deserves some investigation. FIXME - _LT_TAGVAR(archive_cmds, $1)='$CC -nostart $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' - else - _LT_TAGVAR(ld_shlibs, $1)=no - fi - ;; - - chorus*) - case $cc_basename in - *) - # FIXME: insert proper C++ library support - _LT_TAGVAR(ld_shlibs, $1)=no - ;; - esac - ;; - - cygwin* | mingw* | pw32* | cegcc*) - case $GXX,$cc_basename in - ,cl* | no,cl*) - # Native MSVC - # hardcode_libdir_flag_spec is actually meaningless, as there is - # no search path for DLLs. - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)=' ' - _LT_TAGVAR(allow_undefined_flag, $1)=unsupported - _LT_TAGVAR(always_export_symbols, $1)=yes - _LT_TAGVAR(file_list_spec, $1)='@' - # Tell ltmain to make .lib files, not .a files. - libext=lib - # Tell ltmain to make .dll files, not .so files. - shrext_cmds=".dll" - # FIXME: Setting linknames here is a bad hack. - _LT_TAGVAR(archive_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $compiler_flags $deplibs -Wl,-dll~linknames=' - _LT_TAGVAR(archive_expsym_cmds, $1)='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then - $SED -n -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' -e '1\\\!p' < $export_symbols > $output_objdir/$soname.exp; - else - $SED -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' < $export_symbols > $output_objdir/$soname.exp; - fi~ - $CC -o $tool_output_objdir$soname $libobjs $compiler_flags $deplibs "@$tool_output_objdir$soname.exp" -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~ - linknames=' - # The linker will not automatically build a static lib if we build a DLL. - # _LT_TAGVAR(old_archive_from_new_cmds, $1)='true' - _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes - # Don't use ranlib - _LT_TAGVAR(old_postinstall_cmds, $1)='chmod 644 $oldlib' - _LT_TAGVAR(postlink_cmds, $1)='lt_outputfile="@OUTPUT@"~ - lt_tool_outputfile="@TOOL_OUTPUT@"~ - case $lt_outputfile in - *.exe|*.EXE) ;; - *) - lt_outputfile="$lt_outputfile.exe" - lt_tool_outputfile="$lt_tool_outputfile.exe" - ;; - esac~ - func_to_tool_file "$lt_outputfile"~ - if test "$MANIFEST_TOOL" != ":" && test -f "$lt_outputfile.manifest"; then - $MANIFEST_TOOL -manifest "$lt_tool_outputfile.manifest" -outputresource:"$lt_tool_outputfile" || exit 1; - $RM "$lt_outputfile.manifest"; - fi' - ;; - *) - # g++ - # _LT_TAGVAR(hardcode_libdir_flag_spec, $1) is actually meaningless, - # as there is no search path for DLLs. - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' - _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-all-symbols' - _LT_TAGVAR(allow_undefined_flag, $1)=unsupported - _LT_TAGVAR(always_export_symbols, $1)=no - _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes - - if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then - _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' - # If the export-symbols file already is a .def file (1st line - # is EXPORTS), use it as is; otherwise, prepend... - _LT_TAGVAR(archive_expsym_cmds, $1)='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then - cp $export_symbols $output_objdir/$soname.def; - else - echo EXPORTS > $output_objdir/$soname.def; - cat $export_symbols >> $output_objdir/$soname.def; - fi~ - $CC -shared -nostdlib $output_objdir/$soname.def $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' - else - _LT_TAGVAR(ld_shlibs, $1)=no - fi - ;; - esac - ;; - darwin* | rhapsody*) - _LT_DARWIN_LINKER_FEATURES($1) - ;; - - dgux*) - case $cc_basename in - ec++*) - # FIXME: insert proper C++ library support - _LT_TAGVAR(ld_shlibs, $1)=no - ;; - ghcx*) - # Green Hills C++ Compiler - # FIXME: insert proper C++ library support - _LT_TAGVAR(ld_shlibs, $1)=no - ;; - *) - # FIXME: insert proper C++ library support - _LT_TAGVAR(ld_shlibs, $1)=no - ;; - esac - ;; - - freebsd2.*) - # C++ shared libraries reported to be fairly broken before - # switch to ELF - _LT_TAGVAR(ld_shlibs, $1)=no - ;; - - freebsd-elf*) - _LT_TAGVAR(archive_cmds_need_lc, $1)=no - ;; - - freebsd* | dragonfly*) - # FreeBSD 3 and later use GNU C++ and GNU ld with standard ELF - # conventions - _LT_TAGVAR(ld_shlibs, $1)=yes - ;; - - gnu*) - ;; - - haiku*) - _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' - _LT_TAGVAR(link_all_deplibs, $1)=yes - ;; - - hpux9*) - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir' - _LT_TAGVAR(hardcode_libdir_separator, $1)=: - _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' - _LT_TAGVAR(hardcode_direct, $1)=yes - _LT_TAGVAR(hardcode_minus_L, $1)=yes # Not in the search PATH, - # but as the default - # location of the library. - - case $cc_basename in - CC*) - # FIXME: insert proper C++ library support - _LT_TAGVAR(ld_shlibs, $1)=no - ;; - aCC*) - _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$CC -b ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' - # Commands to make compiler produce verbose output that lists - # what "hidden" libraries, object files and flags are used when - # linking a shared library. - # - # There doesn't appear to be a way to prevent this compiler from - # explicitly linking system object files so we need to strip them - # from the output so that they don't get included in the library - # dependencies. - output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $EGREP "\-L"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' - ;; - *) - if test "$GXX" = yes; then - _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$CC -shared -nostdlib $pic_flag ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' - else - # FIXME: insert proper C++ library support - _LT_TAGVAR(ld_shlibs, $1)=no - fi - ;; - esac - ;; - - hpux10*|hpux11*) - if test $with_gnu_ld = no; then - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir' - _LT_TAGVAR(hardcode_libdir_separator, $1)=: - - case $host_cpu in - hppa*64*|ia64*) - ;; - *) - _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' - ;; - esac - fi - case $host_cpu in - hppa*64*|ia64*) - _LT_TAGVAR(hardcode_direct, $1)=no - _LT_TAGVAR(hardcode_shlibpath_var, $1)=no - ;; - *) - _LT_TAGVAR(hardcode_direct, $1)=yes - _LT_TAGVAR(hardcode_direct_absolute, $1)=yes - _LT_TAGVAR(hardcode_minus_L, $1)=yes # Not in the search PATH, - # but as the default - # location of the library. - ;; - esac - - case $cc_basename in - CC*) - # FIXME: insert proper C++ library support - _LT_TAGVAR(ld_shlibs, $1)=no - ;; - aCC*) - case $host_cpu in - hppa*64*) - _LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' - ;; - ia64*) - _LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' - ;; - *) - _LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' - ;; - esac - # Commands to make compiler produce verbose output that lists - # what "hidden" libraries, object files and flags are used when - # linking a shared library. - # - # There doesn't appear to be a way to prevent this compiler from - # explicitly linking system object files so we need to strip them - # from the output so that they don't get included in the library - # dependencies. - output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $GREP "\-L"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' - ;; - *) - if test "$GXX" = yes; then - if test $with_gnu_ld = no; then - case $host_cpu in - hppa*64*) - _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib -fPIC ${wl}+h ${wl}$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' - ;; - ia64*) - _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $pic_flag ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' - ;; - *) - _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $pic_flag ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' - ;; - esac - fi - else - # FIXME: insert proper C++ library support - _LT_TAGVAR(ld_shlibs, $1)=no - fi - ;; - esac - ;; - - interix[[3-9]]*) - _LT_TAGVAR(hardcode_direct, $1)=no - _LT_TAGVAR(hardcode_shlibpath_var, $1)=no - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' - _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' - # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc. - # Instead, shared libraries are loaded at an image base (0x10000000 by - # default) and relocated if they conflict, which is a slow very memory - # consuming and fragmenting process. To avoid this, we pick a random, - # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link - # time. Moving up from 0x10000000 also allows more sbrk(2) space. - _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' - _LT_TAGVAR(archive_expsym_cmds, $1)='sed "s,^,_," $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--retain-symbols-file,$output_objdir/$soname.expsym ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' - ;; - irix5* | irix6*) - case $cc_basename in - CC*) - # SGI C++ - _LT_TAGVAR(archive_cmds, $1)='$CC -shared -all -multigot $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib' - - # Archives containing C++ object files must be created using - # "CC -ar", where "CC" is the IRIX C++ compiler. This is - # necessary to make sure instantiated templates are included - # in the archive. - _LT_TAGVAR(old_archive_cmds, $1)='$CC -ar -WR,-u -o $oldlib $oldobjs' - ;; - *) - if test "$GXX" = yes; then - if test "$with_gnu_ld" = no; then - _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' - else - _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` -o $lib' - fi - fi - _LT_TAGVAR(link_all_deplibs, $1)=yes - ;; - esac - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' - _LT_TAGVAR(hardcode_libdir_separator, $1)=: - _LT_TAGVAR(inherit_rpath, $1)=yes - ;; - - linux* | k*bsd*-gnu | kopensolaris*-gnu) - case $cc_basename in - KCC*) - # Kuck and Associates, Inc. (KAI) C++ Compiler - - # KCC will only create a shared library if the output file - # ends with ".so" (or ".sl" for HP-UX), so rename the library - # to its proper name (with version) after linking. - _LT_TAGVAR(archive_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib' - _LT_TAGVAR(archive_expsym_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib ${wl}-retain-symbols-file,$export_symbols; mv \$templib $lib' - # Commands to make compiler produce verbose output that lists - # what "hidden" libraries, object files and flags are used when - # linking a shared library. - # - # There doesn't appear to be a way to prevent this compiler from - # explicitly linking system object files so we need to strip them - # from the output so that they don't get included in the library - # dependencies. - output_verbose_link_cmd='templist=`$CC $CFLAGS -v conftest.$objext -o libconftest$shared_ext 2>&1 | $GREP "ld"`; rm -f libconftest$shared_ext; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' - - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' - _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic' - - # Archives containing C++ object files must be created using - # "CC -Bstatic", where "CC" is the KAI C++ compiler. - _LT_TAGVAR(old_archive_cmds, $1)='$CC -Bstatic -o $oldlib $oldobjs' - ;; - icpc* | ecpc* ) - # Intel C++ - with_gnu_ld=yes - # version 8.0 and above of icpc choke on multiply defined symbols - # if we add $predep_objects and $postdep_objects, however 7.1 and - # earlier do not add the objects themselves. - case `$CC -V 2>&1` in - *"Version 7."*) - _LT_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib' - _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' - ;; - *) # Version 8.0 or newer - tmp_idyn= - case $host_cpu in - ia64*) tmp_idyn=' -i_dynamic';; - esac - _LT_TAGVAR(archive_cmds, $1)='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' - _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' - ;; - esac - _LT_TAGVAR(archive_cmds_need_lc, $1)=no - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' - _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic' - _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive$convenience ${wl}--no-whole-archive' - ;; - pgCC* | pgcpp*) - # Portland Group C++ compiler - case `$CC -V` in - *pgCC\ [[1-5]].* | *pgcpp\ [[1-5]].*) - _LT_TAGVAR(prelink_cmds, $1)='tpldir=Template.dir~ - rm -rf $tpldir~ - $CC --prelink_objects --instantiation_dir $tpldir $objs $libobjs $compile_deplibs~ - compile_command="$compile_command `find $tpldir -name \*.o | sort | $NL2SP`"' - _LT_TAGVAR(old_archive_cmds, $1)='tpldir=Template.dir~ - rm -rf $tpldir~ - $CC --prelink_objects --instantiation_dir $tpldir $oldobjs$old_deplibs~ - $AR $AR_FLAGS $oldlib$oldobjs$old_deplibs `find $tpldir -name \*.o | sort | $NL2SP`~ - $RANLIB $oldlib' - _LT_TAGVAR(archive_cmds, $1)='tpldir=Template.dir~ - rm -rf $tpldir~ - $CC --prelink_objects --instantiation_dir $tpldir $predep_objects $libobjs $deplibs $convenience $postdep_objects~ - $CC -shared $pic_flag $predep_objects $libobjs $deplibs `find $tpldir -name \*.o | sort | $NL2SP` $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname -o $lib' - _LT_TAGVAR(archive_expsym_cmds, $1)='tpldir=Template.dir~ - rm -rf $tpldir~ - $CC --prelink_objects --instantiation_dir $tpldir $predep_objects $libobjs $deplibs $convenience $postdep_objects~ - $CC -shared $pic_flag $predep_objects $libobjs $deplibs `find $tpldir -name \*.o | sort | $NL2SP` $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname ${wl}-retain-symbols-file ${wl}$export_symbols -o $lib' - ;; - *) # Version 6 and above use weak symbols - _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname -o $lib' - _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname ${wl}-retain-symbols-file ${wl}$export_symbols -o $lib' - ;; - esac - - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}--rpath ${wl}$libdir' - _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic' - _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' - ;; - cxx*) - # Compaq C++ - _LT_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib' - _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib ${wl}-retain-symbols-file $wl$export_symbols' - - runpath_var=LD_RUN_PATH - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir' - _LT_TAGVAR(hardcode_libdir_separator, $1)=: - - # Commands to make compiler produce verbose output that lists - # what "hidden" libraries, object files and flags are used when - # linking a shared library. - # - # There doesn't appear to be a way to prevent this compiler from - # explicitly linking system object files so we need to strip them - # from the output so that they don't get included in the library - # dependencies. - output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "ld"`; templist=`func_echo_all "$templist" | $SED "s/\(^.*ld.*\)\( .*ld .*$\)/\1/"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "X$list" | $Xsed' - ;; - xl* | mpixl* | bgxl*) - # IBM XL 8.0 on PPC, with GNU ld - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' - _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic' - _LT_TAGVAR(archive_cmds, $1)='$CC -qmkshrobj $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' - if test "x$supports_anon_versioning" = xyes; then - _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $output_objdir/$libname.ver~ - cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ - echo "local: *; };" >> $output_objdir/$libname.ver~ - $CC -qmkshrobj $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-version-script ${wl}$output_objdir/$libname.ver -o $lib' - fi - ;; - *) - case `$CC -V 2>&1 | sed 5q` in - *Sun\ C*) - # Sun C++ 5.9 - _LT_TAGVAR(no_undefined_flag, $1)=' -zdefs' - _LT_TAGVAR(archive_cmds, $1)='$CC -G${allow_undefined_flag} -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' - _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G${allow_undefined_flag} -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-retain-symbols-file ${wl}$export_symbols' - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' - _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' - _LT_TAGVAR(compiler_needs_object, $1)=yes - - # Not sure whether something based on - # $CC $CFLAGS -v conftest.$objext -o libconftest$shared_ext 2>&1 - # would be better. - output_verbose_link_cmd='func_echo_all' - - # Archives containing C++ object files must be created using - # "CC -xar", where "CC" is the Sun C++ compiler. This is - # necessary to make sure instantiated templates are included - # in the archive. - _LT_TAGVAR(old_archive_cmds, $1)='$CC -xar -o $oldlib $oldobjs' - ;; - esac - ;; - esac - ;; - - lynxos*) - # FIXME: insert proper C++ library support - _LT_TAGVAR(ld_shlibs, $1)=no - ;; - - m88k*) - # FIXME: insert proper C++ library support - _LT_TAGVAR(ld_shlibs, $1)=no - ;; - - mvs*) - case $cc_basename in - cxx*) - # FIXME: insert proper C++ library support - _LT_TAGVAR(ld_shlibs, $1)=no - ;; - *) - # FIXME: insert proper C++ library support - _LT_TAGVAR(ld_shlibs, $1)=no - ;; - esac - ;; - - netbsd*) - if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then - _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $predep_objects $libobjs $deplibs $postdep_objects $linker_flags' - wlarc= - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' - _LT_TAGVAR(hardcode_direct, $1)=yes - _LT_TAGVAR(hardcode_shlibpath_var, $1)=no - fi - # Workaround some broken pre-1.5 toolchains - output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP conftest.$objext | $SED -e "s:-lgcc -lc -lgcc::"' - ;; - - *nto* | *qnx*) - _LT_TAGVAR(ld_shlibs, $1)=yes - ;; - - openbsd2*) - # C++ shared libraries are fairly broken - _LT_TAGVAR(ld_shlibs, $1)=no - ;; - - openbsd*) - if test -f /usr/libexec/ld.so; then - _LT_TAGVAR(hardcode_direct, $1)=yes - _LT_TAGVAR(hardcode_shlibpath_var, $1)=no - _LT_TAGVAR(hardcode_direct_absolute, $1)=yes - _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib' - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' - if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then - _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-retain-symbols-file,$export_symbols -o $lib' - _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' - _LT_TAGVAR(whole_archive_flag_spec, $1)="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive' - fi - output_verbose_link_cmd=func_echo_all - else - _LT_TAGVAR(ld_shlibs, $1)=no - fi - ;; - - osf3* | osf4* | osf5*) - case $cc_basename in - KCC*) - # Kuck and Associates, Inc. (KAI) C++ Compiler - - # KCC will only create a shared library if the output file - # ends with ".so" (or ".sl" for HP-UX), so rename the library - # to its proper name (with version) after linking. - _LT_TAGVAR(archive_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo "$lib" | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib' - - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' - _LT_TAGVAR(hardcode_libdir_separator, $1)=: - - # Archives containing C++ object files must be created using - # the KAI C++ compiler. - case $host in - osf3*) _LT_TAGVAR(old_archive_cmds, $1)='$CC -Bstatic -o $oldlib $oldobjs' ;; - *) _LT_TAGVAR(old_archive_cmds, $1)='$CC -o $oldlib $oldobjs' ;; - esac - ;; - RCC*) - # Rational C++ 2.4.1 - # FIXME: insert proper C++ library support - _LT_TAGVAR(ld_shlibs, $1)=no - ;; - cxx*) - case $host in - osf3*) - _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*' - _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $soname `test -n "$verstring" && func_echo_all "${wl}-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib' - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' - ;; - *) - _LT_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*' - _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib' - _LT_TAGVAR(archive_expsym_cmds, $1)='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done~ - echo "-hidden">> $lib.exp~ - $CC -shared$allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname ${wl}-input ${wl}$lib.exp `test -n "$verstring" && $ECHO "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib~ - $RM $lib.exp' - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir' - ;; - esac - - _LT_TAGVAR(hardcode_libdir_separator, $1)=: - - # Commands to make compiler produce verbose output that lists - # what "hidden" libraries, object files and flags are used when - # linking a shared library. - # - # There doesn't appear to be a way to prevent this compiler from - # explicitly linking system object files so we need to strip them - # from the output so that they don't get included in the library - # dependencies. - output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "ld" | $GREP -v "ld:"`; templist=`func_echo_all "$templist" | $SED "s/\(^.*ld.*\)\( .*ld.*$\)/\1/"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' - ;; - *) - if test "$GXX" = yes && test "$with_gnu_ld" = no; then - _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*' - case $host in - osf3*) - _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib ${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' - ;; - *) - _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib ${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' - ;; - esac - - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' - _LT_TAGVAR(hardcode_libdir_separator, $1)=: - - # Commands to make compiler produce verbose output that lists - # what "hidden" libraries, object files and flags are used when - # linking a shared library. - output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"' - - else - # FIXME: insert proper C++ library support - _LT_TAGVAR(ld_shlibs, $1)=no - fi - ;; - esac - ;; - - psos*) - # FIXME: insert proper C++ library support - _LT_TAGVAR(ld_shlibs, $1)=no - ;; - - sunos4*) - case $cc_basename in - CC*) - # Sun C++ 4.x - # FIXME: insert proper C++ library support - _LT_TAGVAR(ld_shlibs, $1)=no - ;; - lcc*) - # Lucid - # FIXME: insert proper C++ library support - _LT_TAGVAR(ld_shlibs, $1)=no - ;; - *) - # FIXME: insert proper C++ library support - _LT_TAGVAR(ld_shlibs, $1)=no - ;; - esac - ;; - - solaris*) - case $cc_basename in - CC* | sunCC*) - # Sun C++ 4.2, 5.x and Centerline C++ - _LT_TAGVAR(archive_cmds_need_lc,$1)=yes - _LT_TAGVAR(no_undefined_flag, $1)=' -zdefs' - _LT_TAGVAR(archive_cmds, $1)='$CC -G${allow_undefined_flag} -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' - _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ - $CC -G${allow_undefined_flag} ${wl}-M ${wl}$lib.exp -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp' - - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' - _LT_TAGVAR(hardcode_shlibpath_var, $1)=no - case $host_os in - solaris2.[[0-5]] | solaris2.[[0-5]].*) ;; - *) - # The compiler driver will combine and reorder linker options, - # but understands `-z linker_flag'. - # Supported since Solaris 2.6 (maybe 2.5.1?) - _LT_TAGVAR(whole_archive_flag_spec, $1)='-z allextract$convenience -z defaultextract' - ;; - esac - _LT_TAGVAR(link_all_deplibs, $1)=yes - - output_verbose_link_cmd='func_echo_all' - - # Archives containing C++ object files must be created using - # "CC -xar", where "CC" is the Sun C++ compiler. This is - # necessary to make sure instantiated templates are included - # in the archive. - _LT_TAGVAR(old_archive_cmds, $1)='$CC -xar -o $oldlib $oldobjs' - ;; - gcx*) - # Green Hills C++ Compiler - _LT_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib' - - # The C++ compiler must be used to create the archive. - _LT_TAGVAR(old_archive_cmds, $1)='$CC $LDFLAGS -archive -o $oldlib $oldobjs' - ;; - *) - # GNU C++ compiler with Solaris linker - if test "$GXX" = yes && test "$with_gnu_ld" = no; then - _LT_TAGVAR(no_undefined_flag, $1)=' ${wl}-z ${wl}defs' - if $CC --version | $GREP -v '^2\.7' > /dev/null; then - _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib $LDFLAGS $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib' - _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ - $CC -shared $pic_flag -nostdlib ${wl}-M $wl$lib.exp -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp' - - # Commands to make compiler produce verbose output that lists - # what "hidden" libraries, object files and flags are used when - # linking a shared library. - output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"' - else - # g++ 2.7 appears to require `-G' NOT `-shared' on this - # platform. - _LT_TAGVAR(archive_cmds, $1)='$CC -G -nostdlib $LDFLAGS $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib' - _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ - $CC -G -nostdlib ${wl}-M $wl$lib.exp -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp' - - # Commands to make compiler produce verbose output that lists - # what "hidden" libraries, object files and flags are used when - # linking a shared library. - output_verbose_link_cmd='$CC -G $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"' - fi - - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R $wl$libdir' - case $host_os in - solaris2.[[0-5]] | solaris2.[[0-5]].*) ;; - *) - _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}-z ${wl}allextract$convenience ${wl}-z ${wl}defaultextract' - ;; - esac - fi - ;; - esac - ;; - - sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[[01]].[[10]]* | unixware7* | sco3.2v5.0.[[024]]*) - _LT_TAGVAR(no_undefined_flag, $1)='${wl}-z,text' - _LT_TAGVAR(archive_cmds_need_lc, $1)=no - _LT_TAGVAR(hardcode_shlibpath_var, $1)=no - runpath_var='LD_RUN_PATH' - - case $cc_basename in - CC*) - _LT_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' - _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' - ;; - *) - _LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' - _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' - ;; - esac - ;; - - sysv5* | sco3.2v5* | sco5v6*) - # Note: We can NOT use -z defs as we might desire, because we do not - # link with -lc, and that would cause any symbols used from libc to - # always be unresolved, which means just about no library would - # ever link correctly. If we're not using GNU ld we use -z text - # though, which does catch some bad symbols but isn't as heavy-handed - # as -z defs. - _LT_TAGVAR(no_undefined_flag, $1)='${wl}-z,text' - _LT_TAGVAR(allow_undefined_flag, $1)='${wl}-z,nodefs' - _LT_TAGVAR(archive_cmds_need_lc, $1)=no - _LT_TAGVAR(hardcode_shlibpath_var, $1)=no - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R,$libdir' - _LT_TAGVAR(hardcode_libdir_separator, $1)=':' - _LT_TAGVAR(link_all_deplibs, $1)=yes - _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-Bexport' - runpath_var='LD_RUN_PATH' - - case $cc_basename in - CC*) - _LT_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' - _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' - _LT_TAGVAR(old_archive_cmds, $1)='$CC -Tprelink_objects $oldobjs~ - '"$_LT_TAGVAR(old_archive_cmds, $1)" - _LT_TAGVAR(reload_cmds, $1)='$CC -Tprelink_objects $reload_objs~ - '"$_LT_TAGVAR(reload_cmds, $1)" - ;; - *) - _LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' - _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' - ;; - esac - ;; - - tandem*) - case $cc_basename in - NCC*) - # NonStop-UX NCC 3.20 - # FIXME: insert proper C++ library support - _LT_TAGVAR(ld_shlibs, $1)=no - ;; - *) - # FIXME: insert proper C++ library support - _LT_TAGVAR(ld_shlibs, $1)=no - ;; - esac - ;; - - vxworks*) - # FIXME: insert proper C++ library support - _LT_TAGVAR(ld_shlibs, $1)=no - ;; - - *) - # FIXME: insert proper C++ library support - _LT_TAGVAR(ld_shlibs, $1)=no - ;; - esac - - AC_MSG_RESULT([$_LT_TAGVAR(ld_shlibs, $1)]) - test "$_LT_TAGVAR(ld_shlibs, $1)" = no && can_build_shared=no - - _LT_TAGVAR(GCC, $1)="$GXX" - _LT_TAGVAR(LD, $1)="$LD" - - ## CAVEAT EMPTOR: - ## There is no encapsulation within the following macros, do not change - ## the running order or otherwise move them around unless you know exactly - ## what you are doing... - _LT_SYS_HIDDEN_LIBDEPS($1) - _LT_COMPILER_PIC($1) - _LT_COMPILER_C_O($1) - _LT_COMPILER_FILE_LOCKS($1) - _LT_LINKER_SHLIBS($1) - _LT_SYS_DYNAMIC_LINKER($1) - _LT_LINKER_HARDCODE_LIBPATH($1) - - _LT_CONFIG($1) - fi # test -n "$compiler" - - CC=$lt_save_CC - CFLAGS=$lt_save_CFLAGS - LDCXX=$LD - LD=$lt_save_LD - GCC=$lt_save_GCC - with_gnu_ld=$lt_save_with_gnu_ld - lt_cv_path_LDCXX=$lt_cv_path_LD - lt_cv_path_LD=$lt_save_path_LD - lt_cv_prog_gnu_ldcxx=$lt_cv_prog_gnu_ld - lt_cv_prog_gnu_ld=$lt_save_with_gnu_ld -fi # test "$_lt_caught_CXX_error" != yes - -AC_LANG_POP -])# _LT_LANG_CXX_CONFIG - - -# _LT_FUNC_STRIPNAME_CNF -# ---------------------- -# func_stripname_cnf prefix suffix name -# strip PREFIX and SUFFIX off of NAME. -# PREFIX and SUFFIX must not contain globbing or regex special -# characters, hashes, percent signs, but SUFFIX may contain a leading -# dot (in which case that matches only a dot). -# -# This function is identical to the (non-XSI) version of func_stripname, -# except this one can be used by m4 code that may be executed by configure, -# rather than the libtool script. -m4_defun([_LT_FUNC_STRIPNAME_CNF],[dnl -AC_REQUIRE([_LT_DECL_SED]) -AC_REQUIRE([_LT_PROG_ECHO_BACKSLASH]) -func_stripname_cnf () -{ - case ${2} in - .*) func_stripname_result=`$ECHO "${3}" | $SED "s%^${1}%%; s%\\\\${2}\$%%"`;; - *) func_stripname_result=`$ECHO "${3}" | $SED "s%^${1}%%; s%${2}\$%%"`;; - esac -} # func_stripname_cnf -])# _LT_FUNC_STRIPNAME_CNF - -# _LT_SYS_HIDDEN_LIBDEPS([TAGNAME]) -# --------------------------------- -# Figure out "hidden" library dependencies from verbose -# compiler output when linking a shared library. -# Parse the compiler output and extract the necessary -# objects, libraries and library flags. -m4_defun([_LT_SYS_HIDDEN_LIBDEPS], -[m4_require([_LT_FILEUTILS_DEFAULTS])dnl -AC_REQUIRE([_LT_FUNC_STRIPNAME_CNF])dnl -# Dependencies to place before and after the object being linked: -_LT_TAGVAR(predep_objects, $1)= -_LT_TAGVAR(postdep_objects, $1)= -_LT_TAGVAR(predeps, $1)= -_LT_TAGVAR(postdeps, $1)= -_LT_TAGVAR(compiler_lib_search_path, $1)= - -dnl we can't use the lt_simple_compile_test_code here, -dnl because it contains code intended for an executable, -dnl not a library. It's possible we should let each -dnl tag define a new lt_????_link_test_code variable, -dnl but it's only used here... -m4_if([$1], [], [cat > conftest.$ac_ext <<_LT_EOF -int a; -void foo (void) { a = 0; } -_LT_EOF -], [$1], [CXX], [cat > conftest.$ac_ext <<_LT_EOF -class Foo -{ -public: - Foo (void) { a = 0; } -private: - int a; -}; -_LT_EOF -], [$1], [F77], [cat > conftest.$ac_ext <<_LT_EOF - subroutine foo - implicit none - integer*4 a - a=0 - return - end -_LT_EOF -], [$1], [FC], [cat > conftest.$ac_ext <<_LT_EOF - subroutine foo - implicit none - integer a - a=0 - return - end -_LT_EOF -], [$1], [GCJ], [cat > conftest.$ac_ext <<_LT_EOF -public class foo { - private int a; - public void bar (void) { - a = 0; - } -}; -_LT_EOF -], [$1], [GO], [cat > conftest.$ac_ext <<_LT_EOF -package foo -func foo() { -} -_LT_EOF -]) - -_lt_libdeps_save_CFLAGS=$CFLAGS -case "$CC $CFLAGS " in #( -*\ -flto*\ *) CFLAGS="$CFLAGS -fno-lto" ;; -*\ -fwhopr*\ *) CFLAGS="$CFLAGS -fno-whopr" ;; -*\ -fuse-linker-plugin*\ *) CFLAGS="$CFLAGS -fno-use-linker-plugin" ;; -esac - -dnl Parse the compiler output and extract the necessary -dnl objects, libraries and library flags. -if AC_TRY_EVAL(ac_compile); then - # Parse the compiler output and extract the necessary - # objects, libraries and library flags. - - # Sentinel used to keep track of whether or not we are before - # the conftest object file. - pre_test_object_deps_done=no - - for p in `eval "$output_verbose_link_cmd"`; do - case ${prev}${p} in - - -L* | -R* | -l*) - # Some compilers place space between "-{L,R}" and the path. - # Remove the space. - if test $p = "-L" || - test $p = "-R"; then - prev=$p - continue - fi - - # Expand the sysroot to ease extracting the directories later. - if test -z "$prev"; then - case $p in - -L*) func_stripname_cnf '-L' '' "$p"; prev=-L; p=$func_stripname_result ;; - -R*) func_stripname_cnf '-R' '' "$p"; prev=-R; p=$func_stripname_result ;; - -l*) func_stripname_cnf '-l' '' "$p"; prev=-l; p=$func_stripname_result ;; - esac - fi - case $p in - =*) func_stripname_cnf '=' '' "$p"; p=$lt_sysroot$func_stripname_result ;; - esac - if test "$pre_test_object_deps_done" = no; then - case ${prev} in - -L | -R) - # Internal compiler library paths should come after those - # provided the user. The postdeps already come after the - # user supplied libs so there is no need to process them. - if test -z "$_LT_TAGVAR(compiler_lib_search_path, $1)"; then - _LT_TAGVAR(compiler_lib_search_path, $1)="${prev}${p}" - else - _LT_TAGVAR(compiler_lib_search_path, $1)="${_LT_TAGVAR(compiler_lib_search_path, $1)} ${prev}${p}" - fi - ;; - # The "-l" case would never come before the object being - # linked, so don't bother handling this case. - esac - else - if test -z "$_LT_TAGVAR(postdeps, $1)"; then - _LT_TAGVAR(postdeps, $1)="${prev}${p}" - else - _LT_TAGVAR(postdeps, $1)="${_LT_TAGVAR(postdeps, $1)} ${prev}${p}" - fi - fi - prev= - ;; - - *.lto.$objext) ;; # Ignore GCC LTO objects - *.$objext) - # This assumes that the test object file only shows up - # once in the compiler output. - if test "$p" = "conftest.$objext"; then - pre_test_object_deps_done=yes - continue - fi - - if test "$pre_test_object_deps_done" = no; then - if test -z "$_LT_TAGVAR(predep_objects, $1)"; then - _LT_TAGVAR(predep_objects, $1)="$p" - else - _LT_TAGVAR(predep_objects, $1)="$_LT_TAGVAR(predep_objects, $1) $p" - fi - else - if test -z "$_LT_TAGVAR(postdep_objects, $1)"; then - _LT_TAGVAR(postdep_objects, $1)="$p" - else - _LT_TAGVAR(postdep_objects, $1)="$_LT_TAGVAR(postdep_objects, $1) $p" - fi - fi - ;; - - *) ;; # Ignore the rest. - - esac - done - - # Clean up. - rm -f a.out a.exe -else - echo "libtool.m4: error: problem compiling $1 test program" -fi - -$RM -f confest.$objext -CFLAGS=$_lt_libdeps_save_CFLAGS - -# PORTME: override above test on systems where it is broken -m4_if([$1], [CXX], -[case $host_os in -interix[[3-9]]*) - # Interix 3.5 installs completely hosed .la files for C++, so rather than - # hack all around it, let's just trust "g++" to DTRT. - _LT_TAGVAR(predep_objects,$1)= - _LT_TAGVAR(postdep_objects,$1)= - _LT_TAGVAR(postdeps,$1)= - ;; - -linux*) - case `$CC -V 2>&1 | sed 5q` in - *Sun\ C*) - # Sun C++ 5.9 - - # The more standards-conforming stlport4 library is - # incompatible with the Cstd library. Avoid specifying - # it if it's in CXXFLAGS. Ignore libCrun as - # -library=stlport4 depends on it. - case " $CXX $CXXFLAGS " in - *" -library=stlport4 "*) - solaris_use_stlport4=yes - ;; - esac - - if test "$solaris_use_stlport4" != yes; then - _LT_TAGVAR(postdeps,$1)='-library=Cstd -library=Crun' - fi - ;; - esac - ;; - -solaris*) - case $cc_basename in - CC* | sunCC*) - # The more standards-conforming stlport4 library is - # incompatible with the Cstd library. Avoid specifying - # it if it's in CXXFLAGS. Ignore libCrun as - # -library=stlport4 depends on it. - case " $CXX $CXXFLAGS " in - *" -library=stlport4 "*) - solaris_use_stlport4=yes - ;; - esac - - # Adding this requires a known-good setup of shared libraries for - # Sun compiler versions before 5.6, else PIC objects from an old - # archive will be linked into the output, leading to subtle bugs. - if test "$solaris_use_stlport4" != yes; then - _LT_TAGVAR(postdeps,$1)='-library=Cstd -library=Crun' - fi - ;; - esac - ;; -esac -]) - -case " $_LT_TAGVAR(postdeps, $1) " in -*" -lc "*) _LT_TAGVAR(archive_cmds_need_lc, $1)=no ;; -esac - _LT_TAGVAR(compiler_lib_search_dirs, $1)= -if test -n "${_LT_TAGVAR(compiler_lib_search_path, $1)}"; then - _LT_TAGVAR(compiler_lib_search_dirs, $1)=`echo " ${_LT_TAGVAR(compiler_lib_search_path, $1)}" | ${SED} -e 's! -L! !g' -e 's!^ !!'` -fi -_LT_TAGDECL([], [compiler_lib_search_dirs], [1], - [The directories searched by this compiler when creating a shared library]) -_LT_TAGDECL([], [predep_objects], [1], - [Dependencies to place before and after the objects being linked to - create a shared library]) -_LT_TAGDECL([], [postdep_objects], [1]) -_LT_TAGDECL([], [predeps], [1]) -_LT_TAGDECL([], [postdeps], [1]) -_LT_TAGDECL([], [compiler_lib_search_path], [1], - [The library search path used internally by the compiler when linking - a shared library]) -])# _LT_SYS_HIDDEN_LIBDEPS - - -# _LT_LANG_F77_CONFIG([TAG]) -# -------------------------- -# Ensure that the configuration variables for a Fortran 77 compiler are -# suitably defined. These variables are subsequently used by _LT_CONFIG -# to write the compiler configuration to `libtool'. -m4_defun([_LT_LANG_F77_CONFIG], -[AC_LANG_PUSH(Fortran 77) -if test -z "$F77" || test "X$F77" = "Xno"; then - _lt_disable_F77=yes -fi - -_LT_TAGVAR(archive_cmds_need_lc, $1)=no -_LT_TAGVAR(allow_undefined_flag, $1)= -_LT_TAGVAR(always_export_symbols, $1)=no -_LT_TAGVAR(archive_expsym_cmds, $1)= -_LT_TAGVAR(export_dynamic_flag_spec, $1)= -_LT_TAGVAR(hardcode_direct, $1)=no -_LT_TAGVAR(hardcode_direct_absolute, $1)=no -_LT_TAGVAR(hardcode_libdir_flag_spec, $1)= -_LT_TAGVAR(hardcode_libdir_separator, $1)= -_LT_TAGVAR(hardcode_minus_L, $1)=no -_LT_TAGVAR(hardcode_automatic, $1)=no -_LT_TAGVAR(inherit_rpath, $1)=no -_LT_TAGVAR(module_cmds, $1)= -_LT_TAGVAR(module_expsym_cmds, $1)= -_LT_TAGVAR(link_all_deplibs, $1)=unknown -_LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds -_LT_TAGVAR(reload_flag, $1)=$reload_flag -_LT_TAGVAR(reload_cmds, $1)=$reload_cmds -_LT_TAGVAR(no_undefined_flag, $1)= -_LT_TAGVAR(whole_archive_flag_spec, $1)= -_LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no - -# Source file extension for f77 test sources. -ac_ext=f - -# Object file extension for compiled f77 test sources. -objext=o -_LT_TAGVAR(objext, $1)=$objext - -# No sense in running all these tests if we already determined that -# the F77 compiler isn't working. Some variables (like enable_shared) -# are currently assumed to apply to all compilers on this platform, -# and will be corrupted by setting them based on a non-working compiler. -if test "$_lt_disable_F77" != yes; then - # Code to be used in simple compile tests - lt_simple_compile_test_code="\ - subroutine t - return - end -" - - # Code to be used in simple link tests - lt_simple_link_test_code="\ - program t - end -" - - # ltmain only uses $CC for tagged configurations so make sure $CC is set. - _LT_TAG_COMPILER - - # save warnings/boilerplate of simple test code - _LT_COMPILER_BOILERPLATE - _LT_LINKER_BOILERPLATE - - # Allow CC to be a program name with arguments. - lt_save_CC="$CC" - lt_save_GCC=$GCC - lt_save_CFLAGS=$CFLAGS - CC=${F77-"f77"} - CFLAGS=$FFLAGS - compiler=$CC - _LT_TAGVAR(compiler, $1)=$CC - _LT_CC_BASENAME([$compiler]) - GCC=$G77 - if test -n "$compiler"; then - AC_MSG_CHECKING([if libtool supports shared libraries]) - AC_MSG_RESULT([$can_build_shared]) - - AC_MSG_CHECKING([whether to build shared libraries]) - test "$can_build_shared" = "no" && enable_shared=no - - # On AIX, shared libraries and static libraries use the same namespace, and - # are all built from PIC. - case $host_os in - aix3*) - test "$enable_shared" = yes && enable_static=no - if test -n "$RANLIB"; then - archive_cmds="$archive_cmds~\$RANLIB \$lib" - postinstall_cmds='$RANLIB $lib' - fi - ;; - aix[[4-9]]*) - if test "$host_cpu" != ia64 && test "$aix_use_runtimelinking" = no ; then - test "$enable_shared" = yes && enable_static=no - fi - ;; - esac - AC_MSG_RESULT([$enable_shared]) - - AC_MSG_CHECKING([whether to build static libraries]) - # Make sure either enable_shared or enable_static is yes. - test "$enable_shared" = yes || enable_static=yes - AC_MSG_RESULT([$enable_static]) - - _LT_TAGVAR(GCC, $1)="$G77" - _LT_TAGVAR(LD, $1)="$LD" - - ## CAVEAT EMPTOR: - ## There is no encapsulation within the following macros, do not change - ## the running order or otherwise move them around unless you know exactly - ## what you are doing... - _LT_COMPILER_PIC($1) - _LT_COMPILER_C_O($1) - _LT_COMPILER_FILE_LOCKS($1) - _LT_LINKER_SHLIBS($1) - _LT_SYS_DYNAMIC_LINKER($1) - _LT_LINKER_HARDCODE_LIBPATH($1) - - _LT_CONFIG($1) - fi # test -n "$compiler" - - GCC=$lt_save_GCC - CC="$lt_save_CC" - CFLAGS="$lt_save_CFLAGS" -fi # test "$_lt_disable_F77" != yes - -AC_LANG_POP -])# _LT_LANG_F77_CONFIG - - -# _LT_LANG_FC_CONFIG([TAG]) -# ------------------------- -# Ensure that the configuration variables for a Fortran compiler are -# suitably defined. These variables are subsequently used by _LT_CONFIG -# to write the compiler configuration to `libtool'. -m4_defun([_LT_LANG_FC_CONFIG], -[AC_LANG_PUSH(Fortran) - -if test -z "$FC" || test "X$FC" = "Xno"; then - _lt_disable_FC=yes -fi - -_LT_TAGVAR(archive_cmds_need_lc, $1)=no -_LT_TAGVAR(allow_undefined_flag, $1)= -_LT_TAGVAR(always_export_symbols, $1)=no -_LT_TAGVAR(archive_expsym_cmds, $1)= -_LT_TAGVAR(export_dynamic_flag_spec, $1)= -_LT_TAGVAR(hardcode_direct, $1)=no -_LT_TAGVAR(hardcode_direct_absolute, $1)=no -_LT_TAGVAR(hardcode_libdir_flag_spec, $1)= -_LT_TAGVAR(hardcode_libdir_separator, $1)= -_LT_TAGVAR(hardcode_minus_L, $1)=no -_LT_TAGVAR(hardcode_automatic, $1)=no -_LT_TAGVAR(inherit_rpath, $1)=no -_LT_TAGVAR(module_cmds, $1)= -_LT_TAGVAR(module_expsym_cmds, $1)= -_LT_TAGVAR(link_all_deplibs, $1)=unknown -_LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds -_LT_TAGVAR(reload_flag, $1)=$reload_flag -_LT_TAGVAR(reload_cmds, $1)=$reload_cmds -_LT_TAGVAR(no_undefined_flag, $1)= -_LT_TAGVAR(whole_archive_flag_spec, $1)= -_LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no - -# Source file extension for fc test sources. -ac_ext=${ac_fc_srcext-f} - -# Object file extension for compiled fc test sources. -objext=o -_LT_TAGVAR(objext, $1)=$objext - -# No sense in running all these tests if we already determined that -# the FC compiler isn't working. Some variables (like enable_shared) -# are currently assumed to apply to all compilers on this platform, -# and will be corrupted by setting them based on a non-working compiler. -if test "$_lt_disable_FC" != yes; then - # Code to be used in simple compile tests - lt_simple_compile_test_code="\ - subroutine t - return - end -" - - # Code to be used in simple link tests - lt_simple_link_test_code="\ - program t - end -" - - # ltmain only uses $CC for tagged configurations so make sure $CC is set. - _LT_TAG_COMPILER - - # save warnings/boilerplate of simple test code - _LT_COMPILER_BOILERPLATE - _LT_LINKER_BOILERPLATE - - # Allow CC to be a program name with arguments. - lt_save_CC="$CC" - lt_save_GCC=$GCC - lt_save_CFLAGS=$CFLAGS - CC=${FC-"f95"} - CFLAGS=$FCFLAGS - compiler=$CC - GCC=$ac_cv_fc_compiler_gnu - - _LT_TAGVAR(compiler, $1)=$CC - _LT_CC_BASENAME([$compiler]) - - if test -n "$compiler"; then - AC_MSG_CHECKING([if libtool supports shared libraries]) - AC_MSG_RESULT([$can_build_shared]) - - AC_MSG_CHECKING([whether to build shared libraries]) - test "$can_build_shared" = "no" && enable_shared=no - - # On AIX, shared libraries and static libraries use the same namespace, and - # are all built from PIC. - case $host_os in - aix3*) - test "$enable_shared" = yes && enable_static=no - if test -n "$RANLIB"; then - archive_cmds="$archive_cmds~\$RANLIB \$lib" - postinstall_cmds='$RANLIB $lib' - fi - ;; - aix[[4-9]]*) - if test "$host_cpu" != ia64 && test "$aix_use_runtimelinking" = no ; then - test "$enable_shared" = yes && enable_static=no - fi - ;; - esac - AC_MSG_RESULT([$enable_shared]) - - AC_MSG_CHECKING([whether to build static libraries]) - # Make sure either enable_shared or enable_static is yes. - test "$enable_shared" = yes || enable_static=yes - AC_MSG_RESULT([$enable_static]) - - _LT_TAGVAR(GCC, $1)="$ac_cv_fc_compiler_gnu" - _LT_TAGVAR(LD, $1)="$LD" - - ## CAVEAT EMPTOR: - ## There is no encapsulation within the following macros, do not change - ## the running order or otherwise move them around unless you know exactly - ## what you are doing... - _LT_SYS_HIDDEN_LIBDEPS($1) - _LT_COMPILER_PIC($1) - _LT_COMPILER_C_O($1) - _LT_COMPILER_FILE_LOCKS($1) - _LT_LINKER_SHLIBS($1) - _LT_SYS_DYNAMIC_LINKER($1) - _LT_LINKER_HARDCODE_LIBPATH($1) - - _LT_CONFIG($1) - fi # test -n "$compiler" - - GCC=$lt_save_GCC - CC=$lt_save_CC - CFLAGS=$lt_save_CFLAGS -fi # test "$_lt_disable_FC" != yes - -AC_LANG_POP -])# _LT_LANG_FC_CONFIG - - -# _LT_LANG_GCJ_CONFIG([TAG]) -# -------------------------- -# Ensure that the configuration variables for the GNU Java Compiler compiler -# are suitably defined. These variables are subsequently used by _LT_CONFIG -# to write the compiler configuration to `libtool'. -m4_defun([_LT_LANG_GCJ_CONFIG], -[AC_REQUIRE([LT_PROG_GCJ])dnl -AC_LANG_SAVE - -# Source file extension for Java test sources. -ac_ext=java - -# Object file extension for compiled Java test sources. -objext=o -_LT_TAGVAR(objext, $1)=$objext - -# Code to be used in simple compile tests -lt_simple_compile_test_code="class foo {}" - -# Code to be used in simple link tests -lt_simple_link_test_code='public class conftest { public static void main(String[[]] argv) {}; }' - -# ltmain only uses $CC for tagged configurations so make sure $CC is set. -_LT_TAG_COMPILER - -# save warnings/boilerplate of simple test code -_LT_COMPILER_BOILERPLATE -_LT_LINKER_BOILERPLATE - -# Allow CC to be a program name with arguments. -lt_save_CC=$CC -lt_save_CFLAGS=$CFLAGS -lt_save_GCC=$GCC -GCC=yes -CC=${GCJ-"gcj"} -CFLAGS=$GCJFLAGS -compiler=$CC -_LT_TAGVAR(compiler, $1)=$CC -_LT_TAGVAR(LD, $1)="$LD" -_LT_CC_BASENAME([$compiler]) - -# GCJ did not exist at the time GCC didn't implicitly link libc in. -_LT_TAGVAR(archive_cmds_need_lc, $1)=no - -_LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds -_LT_TAGVAR(reload_flag, $1)=$reload_flag -_LT_TAGVAR(reload_cmds, $1)=$reload_cmds - -if test -n "$compiler"; then - _LT_COMPILER_NO_RTTI($1) - _LT_COMPILER_PIC($1) - _LT_COMPILER_C_O($1) - _LT_COMPILER_FILE_LOCKS($1) - _LT_LINKER_SHLIBS($1) - _LT_LINKER_HARDCODE_LIBPATH($1) - - _LT_CONFIG($1) -fi - -AC_LANG_RESTORE - -GCC=$lt_save_GCC -CC=$lt_save_CC -CFLAGS=$lt_save_CFLAGS -])# _LT_LANG_GCJ_CONFIG - - -# _LT_LANG_GO_CONFIG([TAG]) -# -------------------------- -# Ensure that the configuration variables for the GNU Go compiler -# are suitably defined. These variables are subsequently used by _LT_CONFIG -# to write the compiler configuration to `libtool'. -m4_defun([_LT_LANG_GO_CONFIG], -[AC_REQUIRE([LT_PROG_GO])dnl -AC_LANG_SAVE - -# Source file extension for Go test sources. -ac_ext=go - -# Object file extension for compiled Go test sources. -objext=o -_LT_TAGVAR(objext, $1)=$objext - -# Code to be used in simple compile tests -lt_simple_compile_test_code="package main; func main() { }" - -# Code to be used in simple link tests -lt_simple_link_test_code='package main; func main() { }' - -# ltmain only uses $CC for tagged configurations so make sure $CC is set. -_LT_TAG_COMPILER - -# save warnings/boilerplate of simple test code -_LT_COMPILER_BOILERPLATE -_LT_LINKER_BOILERPLATE - -# Allow CC to be a program name with arguments. -lt_save_CC=$CC -lt_save_CFLAGS=$CFLAGS -lt_save_GCC=$GCC -GCC=yes -CC=${GOC-"gccgo"} -CFLAGS=$GOFLAGS -compiler=$CC -_LT_TAGVAR(compiler, $1)=$CC -_LT_TAGVAR(LD, $1)="$LD" -_LT_CC_BASENAME([$compiler]) - -# Go did not exist at the time GCC didn't implicitly link libc in. -_LT_TAGVAR(archive_cmds_need_lc, $1)=no - -_LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds -_LT_TAGVAR(reload_flag, $1)=$reload_flag -_LT_TAGVAR(reload_cmds, $1)=$reload_cmds - -if test -n "$compiler"; then - _LT_COMPILER_NO_RTTI($1) - _LT_COMPILER_PIC($1) - _LT_COMPILER_C_O($1) - _LT_COMPILER_FILE_LOCKS($1) - _LT_LINKER_SHLIBS($1) - _LT_LINKER_HARDCODE_LIBPATH($1) - - _LT_CONFIG($1) -fi - -AC_LANG_RESTORE - -GCC=$lt_save_GCC -CC=$lt_save_CC -CFLAGS=$lt_save_CFLAGS -])# _LT_LANG_GO_CONFIG - - -# _LT_LANG_RC_CONFIG([TAG]) -# ------------------------- -# Ensure that the configuration variables for the Windows resource compiler -# are suitably defined. These variables are subsequently used by _LT_CONFIG -# to write the compiler configuration to `libtool'. -m4_defun([_LT_LANG_RC_CONFIG], -[AC_REQUIRE([LT_PROG_RC])dnl -AC_LANG_SAVE - -# Source file extension for RC test sources. -ac_ext=rc - -# Object file extension for compiled RC test sources. -objext=o -_LT_TAGVAR(objext, $1)=$objext - -# Code to be used in simple compile tests -lt_simple_compile_test_code='sample MENU { MENUITEM "&Soup", 100, CHECKED }' - -# Code to be used in simple link tests -lt_simple_link_test_code="$lt_simple_compile_test_code" - -# ltmain only uses $CC for tagged configurations so make sure $CC is set. -_LT_TAG_COMPILER - -# save warnings/boilerplate of simple test code -_LT_COMPILER_BOILERPLATE -_LT_LINKER_BOILERPLATE - -# Allow CC to be a program name with arguments. -lt_save_CC="$CC" -lt_save_CFLAGS=$CFLAGS -lt_save_GCC=$GCC -GCC= -CC=${RC-"windres"} -CFLAGS= -compiler=$CC -_LT_TAGVAR(compiler, $1)=$CC -_LT_CC_BASENAME([$compiler]) -_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)=yes - -if test -n "$compiler"; then - : - _LT_CONFIG($1) -fi - -GCC=$lt_save_GCC -AC_LANG_RESTORE -CC=$lt_save_CC -CFLAGS=$lt_save_CFLAGS -])# _LT_LANG_RC_CONFIG - - -# LT_PROG_GCJ -# ----------- -AC_DEFUN([LT_PROG_GCJ], -[m4_ifdef([AC_PROG_GCJ], [AC_PROG_GCJ], - [m4_ifdef([A][M_PROG_GCJ], [A][M_PROG_GCJ], - [AC_CHECK_TOOL(GCJ, gcj,) - test "x${GCJFLAGS+set}" = xset || GCJFLAGS="-g -O2" - AC_SUBST(GCJFLAGS)])])[]dnl -]) - -# Old name: -AU_ALIAS([LT_AC_PROG_GCJ], [LT_PROG_GCJ]) -dnl aclocal-1.4 backwards compatibility: -dnl AC_DEFUN([LT_AC_PROG_GCJ], []) - - -# LT_PROG_GO -# ---------- -AC_DEFUN([LT_PROG_GO], -[AC_CHECK_TOOL(GOC, gccgo,) -]) - - -# LT_PROG_RC -# ---------- -AC_DEFUN([LT_PROG_RC], -[AC_CHECK_TOOL(RC, windres,) -]) - -# Old name: -AU_ALIAS([LT_AC_PROG_RC], [LT_PROG_RC]) -dnl aclocal-1.4 backwards compatibility: -dnl AC_DEFUN([LT_AC_PROG_RC], []) - - -# _LT_DECL_EGREP -# -------------- -# If we don't have a new enough Autoconf to choose the best grep -# available, choose the one first in the user's PATH. -m4_defun([_LT_DECL_EGREP], -[AC_REQUIRE([AC_PROG_EGREP])dnl -AC_REQUIRE([AC_PROG_FGREP])dnl -test -z "$GREP" && GREP=grep -_LT_DECL([], [GREP], [1], [A grep program that handles long lines]) -_LT_DECL([], [EGREP], [1], [An ERE matcher]) -_LT_DECL([], [FGREP], [1], [A literal string matcher]) -dnl Non-bleeding-edge autoconf doesn't subst GREP, so do it here too -AC_SUBST([GREP]) -]) - - -# _LT_DECL_OBJDUMP -# -------------- -# If we don't have a new enough Autoconf to choose the best objdump -# available, choose the one first in the user's PATH. -m4_defun([_LT_DECL_OBJDUMP], -[AC_CHECK_TOOL(OBJDUMP, objdump, false) -test -z "$OBJDUMP" && OBJDUMP=objdump -_LT_DECL([], [OBJDUMP], [1], [An object symbol dumper]) -AC_SUBST([OBJDUMP]) -]) - -# _LT_DECL_DLLTOOL -# ---------------- -# Ensure DLLTOOL variable is set. -m4_defun([_LT_DECL_DLLTOOL], -[AC_CHECK_TOOL(DLLTOOL, dlltool, false) -test -z "$DLLTOOL" && DLLTOOL=dlltool -_LT_DECL([], [DLLTOOL], [1], [DLL creation program]) -AC_SUBST([DLLTOOL]) -]) - -# _LT_DECL_SED -# ------------ -# Check for a fully-functional sed program, that truncates -# as few characters as possible. Prefer GNU sed if found. -m4_defun([_LT_DECL_SED], -[AC_PROG_SED -test -z "$SED" && SED=sed -Xsed="$SED -e 1s/^X//" -_LT_DECL([], [SED], [1], [A sed program that does not truncate output]) -_LT_DECL([], [Xsed], ["\$SED -e 1s/^X//"], - [Sed that helps us avoid accidentally triggering echo(1) options like -n]) -])# _LT_DECL_SED - -m4_ifndef([AC_PROG_SED], [ -# NOTE: This macro has been submitted for inclusion into # -# GNU Autoconf as AC_PROG_SED. When it is available in # -# a released version of Autoconf we should remove this # -# macro and use it instead. # - -m4_defun([AC_PROG_SED], -[AC_MSG_CHECKING([for a sed that does not truncate output]) -AC_CACHE_VAL(lt_cv_path_SED, -[# Loop through the user's path and test for sed and gsed. -# Then use that list of sed's as ones to test for truncation. -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for lt_ac_prog in sed gsed; do - for ac_exec_ext in '' $ac_executable_extensions; do - if $as_executable_p "$as_dir/$lt_ac_prog$ac_exec_ext"; then - lt_ac_sed_list="$lt_ac_sed_list $as_dir/$lt_ac_prog$ac_exec_ext" - fi - done - done -done -IFS=$as_save_IFS -lt_ac_max=0 -lt_ac_count=0 -# Add /usr/xpg4/bin/sed as it is typically found on Solaris -# along with /bin/sed that truncates output. -for lt_ac_sed in $lt_ac_sed_list /usr/xpg4/bin/sed; do - test ! -f $lt_ac_sed && continue - cat /dev/null > conftest.in - lt_ac_count=0 - echo $ECHO_N "0123456789$ECHO_C" >conftest.in - # Check for GNU sed and select it if it is found. - if "$lt_ac_sed" --version 2>&1 < /dev/null | grep 'GNU' > /dev/null; then - lt_cv_path_SED=$lt_ac_sed - break - fi - while true; do - cat conftest.in conftest.in >conftest.tmp - mv conftest.tmp conftest.in - cp conftest.in conftest.nl - echo >>conftest.nl - $lt_ac_sed -e 's/a$//' < conftest.nl >conftest.out || break - cmp -s conftest.out conftest.nl || break - # 10000 chars as input seems more than enough - test $lt_ac_count -gt 10 && break - lt_ac_count=`expr $lt_ac_count + 1` - if test $lt_ac_count -gt $lt_ac_max; then - lt_ac_max=$lt_ac_count - lt_cv_path_SED=$lt_ac_sed - fi - done -done -]) -SED=$lt_cv_path_SED -AC_SUBST([SED]) -AC_MSG_RESULT([$SED]) -])#AC_PROG_SED -])#m4_ifndef - -# Old name: -AU_ALIAS([LT_AC_PROG_SED], [AC_PROG_SED]) -dnl aclocal-1.4 backwards compatibility: -dnl AC_DEFUN([LT_AC_PROG_SED], []) - - -# _LT_CHECK_SHELL_FEATURES -# ------------------------ -# Find out whether the shell is Bourne or XSI compatible, -# or has some other useful features. -m4_defun([_LT_CHECK_SHELL_FEATURES], -[AC_MSG_CHECKING([whether the shell understands some XSI constructs]) -# Try some XSI features -xsi_shell=no -( _lt_dummy="a/b/c" - test "${_lt_dummy##*/},${_lt_dummy%/*},${_lt_dummy#??}"${_lt_dummy%"$_lt_dummy"}, \ - = c,a/b,b/c, \ - && eval 'test $(( 1 + 1 )) -eq 2 \ - && test "${#_lt_dummy}" -eq 5' ) >/dev/null 2>&1 \ - && xsi_shell=yes -AC_MSG_RESULT([$xsi_shell]) -_LT_CONFIG_LIBTOOL_INIT([xsi_shell='$xsi_shell']) - -AC_MSG_CHECKING([whether the shell understands "+="]) -lt_shell_append=no -( foo=bar; set foo baz; eval "$[1]+=\$[2]" && test "$foo" = barbaz ) \ - >/dev/null 2>&1 \ - && lt_shell_append=yes -AC_MSG_RESULT([$lt_shell_append]) -_LT_CONFIG_LIBTOOL_INIT([lt_shell_append='$lt_shell_append']) - -if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then - lt_unset=unset -else - lt_unset=false -fi -_LT_DECL([], [lt_unset], [0], [whether the shell understands "unset"])dnl - -# test EBCDIC or ASCII -case `echo X|tr X '\101'` in - A) # ASCII based system - # \n is not interpreted correctly by Solaris 8 /usr/ucb/tr - lt_SP2NL='tr \040 \012' - lt_NL2SP='tr \015\012 \040\040' - ;; - *) # EBCDIC based system - lt_SP2NL='tr \100 \n' - lt_NL2SP='tr \r\n \100\100' - ;; -esac -_LT_DECL([SP2NL], [lt_SP2NL], [1], [turn spaces into newlines])dnl -_LT_DECL([NL2SP], [lt_NL2SP], [1], [turn newlines into spaces])dnl -])# _LT_CHECK_SHELL_FEATURES - - -# _LT_PROG_FUNCTION_REPLACE (FUNCNAME, REPLACEMENT-BODY) -# ------------------------------------------------------ -# In `$cfgfile', look for function FUNCNAME delimited by `^FUNCNAME ()$' and -# '^} FUNCNAME ', and replace its body with REPLACEMENT-BODY. -m4_defun([_LT_PROG_FUNCTION_REPLACE], -[dnl { -sed -e '/^$1 ()$/,/^} # $1 /c\ -$1 ()\ -{\ -m4_bpatsubsts([$2], [$], [\\], [^\([ ]\)], [\\\1]) -} # Extended-shell $1 implementation' "$cfgfile" > $cfgfile.tmp \ - && mv -f "$cfgfile.tmp" "$cfgfile" \ - || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") -test 0 -eq $? || _lt_function_replace_fail=: -]) - - -# _LT_PROG_REPLACE_SHELLFNS -# ------------------------- -# Replace existing portable implementations of several shell functions with -# equivalent extended shell implementations where those features are available.. -m4_defun([_LT_PROG_REPLACE_SHELLFNS], -[if test x"$xsi_shell" = xyes; then - _LT_PROG_FUNCTION_REPLACE([func_dirname], [dnl - case ${1} in - */*) func_dirname_result="${1%/*}${2}" ;; - * ) func_dirname_result="${3}" ;; - esac]) - - _LT_PROG_FUNCTION_REPLACE([func_basename], [dnl - func_basename_result="${1##*/}"]) - - _LT_PROG_FUNCTION_REPLACE([func_dirname_and_basename], [dnl - case ${1} in - */*) func_dirname_result="${1%/*}${2}" ;; - * ) func_dirname_result="${3}" ;; - esac - func_basename_result="${1##*/}"]) - - _LT_PROG_FUNCTION_REPLACE([func_stripname], [dnl - # pdksh 5.2.14 does not do ${X%$Y} correctly if both X and Y are - # positional parameters, so assign one to ordinary parameter first. - func_stripname_result=${3} - func_stripname_result=${func_stripname_result#"${1}"} - func_stripname_result=${func_stripname_result%"${2}"}]) - - _LT_PROG_FUNCTION_REPLACE([func_split_long_opt], [dnl - func_split_long_opt_name=${1%%=*} - func_split_long_opt_arg=${1#*=}]) - - _LT_PROG_FUNCTION_REPLACE([func_split_short_opt], [dnl - func_split_short_opt_arg=${1#??} - func_split_short_opt_name=${1%"$func_split_short_opt_arg"}]) - - _LT_PROG_FUNCTION_REPLACE([func_lo2o], [dnl - case ${1} in - *.lo) func_lo2o_result=${1%.lo}.${objext} ;; - *) func_lo2o_result=${1} ;; - esac]) - - _LT_PROG_FUNCTION_REPLACE([func_xform], [ func_xform_result=${1%.*}.lo]) - - _LT_PROG_FUNCTION_REPLACE([func_arith], [ func_arith_result=$(( $[*] ))]) - - _LT_PROG_FUNCTION_REPLACE([func_len], [ func_len_result=${#1}]) -fi - -if test x"$lt_shell_append" = xyes; then - _LT_PROG_FUNCTION_REPLACE([func_append], [ eval "${1}+=\\${2}"]) - - _LT_PROG_FUNCTION_REPLACE([func_append_quoted], [dnl - func_quote_for_eval "${2}" -dnl m4 expansion turns \\\\ into \\, and then the shell eval turns that into \ - eval "${1}+=\\\\ \\$func_quote_for_eval_result"]) - - # Save a `func_append' function call where possible by direct use of '+=' - sed -e 's%func_append \([[a-zA-Z_]]\{1,\}\) "%\1+="%g' $cfgfile > $cfgfile.tmp \ - && mv -f "$cfgfile.tmp" "$cfgfile" \ - || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") - test 0 -eq $? || _lt_function_replace_fail=: -else - # Save a `func_append' function call even when '+=' is not available - sed -e 's%func_append \([[a-zA-Z_]]\{1,\}\) "%\1="$\1%g' $cfgfile > $cfgfile.tmp \ - && mv -f "$cfgfile.tmp" "$cfgfile" \ - || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") - test 0 -eq $? || _lt_function_replace_fail=: -fi - -if test x"$_lt_function_replace_fail" = x":"; then - AC_MSG_WARN([Unable to substitute extended shell functions in $ofile]) -fi -]) - -# _LT_PATH_CONVERSION_FUNCTIONS -# ----------------------------- -# Determine which file name conversion functions should be used by -# func_to_host_file (and, implicitly, by func_to_host_path). These are needed -# for certain cross-compile configurations and native mingw. -m4_defun([_LT_PATH_CONVERSION_FUNCTIONS], -[AC_REQUIRE([AC_CANONICAL_HOST])dnl -AC_REQUIRE([AC_CANONICAL_BUILD])dnl -AC_MSG_CHECKING([how to convert $build file names to $host format]) -AC_CACHE_VAL(lt_cv_to_host_file_cmd, -[case $host in - *-*-mingw* ) - case $build in - *-*-mingw* ) # actually msys - lt_cv_to_host_file_cmd=func_convert_file_msys_to_w32 - ;; - *-*-cygwin* ) - lt_cv_to_host_file_cmd=func_convert_file_cygwin_to_w32 - ;; - * ) # otherwise, assume *nix - lt_cv_to_host_file_cmd=func_convert_file_nix_to_w32 - ;; - esac - ;; - *-*-cygwin* ) - case $build in - *-*-mingw* ) # actually msys - lt_cv_to_host_file_cmd=func_convert_file_msys_to_cygwin - ;; - *-*-cygwin* ) - lt_cv_to_host_file_cmd=func_convert_file_noop - ;; - * ) # otherwise, assume *nix - lt_cv_to_host_file_cmd=func_convert_file_nix_to_cygwin - ;; - esac - ;; - * ) # unhandled hosts (and "normal" native builds) - lt_cv_to_host_file_cmd=func_convert_file_noop - ;; -esac -]) -to_host_file_cmd=$lt_cv_to_host_file_cmd -AC_MSG_RESULT([$lt_cv_to_host_file_cmd]) -_LT_DECL([to_host_file_cmd], [lt_cv_to_host_file_cmd], - [0], [convert $build file names to $host format])dnl - -AC_MSG_CHECKING([how to convert $build file names to toolchain format]) -AC_CACHE_VAL(lt_cv_to_tool_file_cmd, -[#assume ordinary cross tools, or native build. -lt_cv_to_tool_file_cmd=func_convert_file_noop -case $host in - *-*-mingw* ) - case $build in - *-*-mingw* ) # actually msys - lt_cv_to_tool_file_cmd=func_convert_file_msys_to_w32 - ;; - esac - ;; -esac -]) -to_tool_file_cmd=$lt_cv_to_tool_file_cmd -AC_MSG_RESULT([$lt_cv_to_tool_file_cmd]) -_LT_DECL([to_tool_file_cmd], [lt_cv_to_tool_file_cmd], - [0], [convert $build files to toolchain format])dnl -])# _LT_PATH_CONVERSION_FUNCTIONS - -# Helper functions for option handling. -*- Autoconf -*- -# -# Copyright (C) 2004, 2005, 2007, 2008, 2009 Free Software Foundation, -# Inc. -# Written by Gary V. Vaughan, 2004 -# -# This file is free software; the Free Software Foundation gives -# unlimited permission to copy and/or distribute it, with or without -# modifications, as long as this notice is preserved. - -# serial 7 ltoptions.m4 - -# This is to help aclocal find these macros, as it can't see m4_define. -AC_DEFUN([LTOPTIONS_VERSION], [m4_if([1])]) - - -# _LT_MANGLE_OPTION(MACRO-NAME, OPTION-NAME) -# ------------------------------------------ -m4_define([_LT_MANGLE_OPTION], -[[_LT_OPTION_]m4_bpatsubst($1__$2, [[^a-zA-Z0-9_]], [_])]) - - -# _LT_SET_OPTION(MACRO-NAME, OPTION-NAME) -# --------------------------------------- -# Set option OPTION-NAME for macro MACRO-NAME, and if there is a -# matching handler defined, dispatch to it. Other OPTION-NAMEs are -# saved as a flag. -m4_define([_LT_SET_OPTION], -[m4_define(_LT_MANGLE_OPTION([$1], [$2]))dnl -m4_ifdef(_LT_MANGLE_DEFUN([$1], [$2]), - _LT_MANGLE_DEFUN([$1], [$2]), - [m4_warning([Unknown $1 option `$2'])])[]dnl -]) - - -# _LT_IF_OPTION(MACRO-NAME, OPTION-NAME, IF-SET, [IF-NOT-SET]) -# ------------------------------------------------------------ -# Execute IF-SET if OPTION is set, IF-NOT-SET otherwise. -m4_define([_LT_IF_OPTION], -[m4_ifdef(_LT_MANGLE_OPTION([$1], [$2]), [$3], [$4])]) - - -# _LT_UNLESS_OPTIONS(MACRO-NAME, OPTION-LIST, IF-NOT-SET) -# ------------------------------------------------------- -# Execute IF-NOT-SET unless all options in OPTION-LIST for MACRO-NAME -# are set. -m4_define([_LT_UNLESS_OPTIONS], -[m4_foreach([_LT_Option], m4_split(m4_normalize([$2])), - [m4_ifdef(_LT_MANGLE_OPTION([$1], _LT_Option), - [m4_define([$0_found])])])[]dnl -m4_ifdef([$0_found], [m4_undefine([$0_found])], [$3 -])[]dnl -]) - - -# _LT_SET_OPTIONS(MACRO-NAME, OPTION-LIST) -# ---------------------------------------- -# OPTION-LIST is a space-separated list of Libtool options associated -# with MACRO-NAME. If any OPTION has a matching handler declared with -# LT_OPTION_DEFINE, dispatch to that macro; otherwise complain about -# the unknown option and exit. -m4_defun([_LT_SET_OPTIONS], -[# Set options -m4_foreach([_LT_Option], m4_split(m4_normalize([$2])), - [_LT_SET_OPTION([$1], _LT_Option)]) - -m4_if([$1],[LT_INIT],[ - dnl - dnl Simply set some default values (i.e off) if boolean options were not - dnl specified: - _LT_UNLESS_OPTIONS([LT_INIT], [dlopen], [enable_dlopen=no - ]) - _LT_UNLESS_OPTIONS([LT_INIT], [win32-dll], [enable_win32_dll=no - ]) - dnl - dnl If no reference was made to various pairs of opposing options, then - dnl we run the default mode handler for the pair. For example, if neither - dnl `shared' nor `disable-shared' was passed, we enable building of shared - dnl archives by default: - _LT_UNLESS_OPTIONS([LT_INIT], [shared disable-shared], [_LT_ENABLE_SHARED]) - _LT_UNLESS_OPTIONS([LT_INIT], [static disable-static], [_LT_ENABLE_STATIC]) - _LT_UNLESS_OPTIONS([LT_INIT], [pic-only no-pic], [_LT_WITH_PIC]) - _LT_UNLESS_OPTIONS([LT_INIT], [fast-install disable-fast-install], - [_LT_ENABLE_FAST_INSTALL]) - ]) -])# _LT_SET_OPTIONS - - - -# _LT_MANGLE_DEFUN(MACRO-NAME, OPTION-NAME) -# ----------------------------------------- -m4_define([_LT_MANGLE_DEFUN], -[[_LT_OPTION_DEFUN_]m4_bpatsubst(m4_toupper([$1__$2]), [[^A-Z0-9_]], [_])]) - - -# LT_OPTION_DEFINE(MACRO-NAME, OPTION-NAME, CODE) -# ----------------------------------------------- -m4_define([LT_OPTION_DEFINE], -[m4_define(_LT_MANGLE_DEFUN([$1], [$2]), [$3])[]dnl -])# LT_OPTION_DEFINE - - -# dlopen -# ------ -LT_OPTION_DEFINE([LT_INIT], [dlopen], [enable_dlopen=yes -]) - -AU_DEFUN([AC_LIBTOOL_DLOPEN], -[_LT_SET_OPTION([LT_INIT], [dlopen]) -AC_DIAGNOSE([obsolete], -[$0: Remove this warning and the call to _LT_SET_OPTION when you -put the `dlopen' option into LT_INIT's first parameter.]) -]) - -dnl aclocal-1.4 backwards compatibility: -dnl AC_DEFUN([AC_LIBTOOL_DLOPEN], []) - - -# win32-dll -# --------- -# Declare package support for building win32 dll's. -LT_OPTION_DEFINE([LT_INIT], [win32-dll], -[enable_win32_dll=yes - -case $host in -*-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-cegcc*) - AC_CHECK_TOOL(AS, as, false) - AC_CHECK_TOOL(DLLTOOL, dlltool, false) - AC_CHECK_TOOL(OBJDUMP, objdump, false) - ;; -esac - -test -z "$AS" && AS=as -_LT_DECL([], [AS], [1], [Assembler program])dnl - -test -z "$DLLTOOL" && DLLTOOL=dlltool -_LT_DECL([], [DLLTOOL], [1], [DLL creation program])dnl - -test -z "$OBJDUMP" && OBJDUMP=objdump -_LT_DECL([], [OBJDUMP], [1], [Object dumper program])dnl -])# win32-dll - -AU_DEFUN([AC_LIBTOOL_WIN32_DLL], -[AC_REQUIRE([AC_CANONICAL_HOST])dnl -_LT_SET_OPTION([LT_INIT], [win32-dll]) -AC_DIAGNOSE([obsolete], -[$0: Remove this warning and the call to _LT_SET_OPTION when you -put the `win32-dll' option into LT_INIT's first parameter.]) -]) - -dnl aclocal-1.4 backwards compatibility: -dnl AC_DEFUN([AC_LIBTOOL_WIN32_DLL], []) - - -# _LT_ENABLE_SHARED([DEFAULT]) -# ---------------------------- -# implement the --enable-shared flag, and supports the `shared' and -# `disable-shared' LT_INIT options. -# DEFAULT is either `yes' or `no'. If omitted, it defaults to `yes'. -m4_define([_LT_ENABLE_SHARED], -[m4_define([_LT_ENABLE_SHARED_DEFAULT], [m4_if($1, no, no, yes)])dnl -AC_ARG_ENABLE([shared], - [AS_HELP_STRING([--enable-shared@<:@=PKGS@:>@], - [build shared libraries @<:@default=]_LT_ENABLE_SHARED_DEFAULT[@:>@])], - [p=${PACKAGE-default} - case $enableval in - yes) enable_shared=yes ;; - no) enable_shared=no ;; - *) - enable_shared=no - # Look at the argument we got. We use all the common list separators. - lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," - for pkg in $enableval; do - IFS="$lt_save_ifs" - if test "X$pkg" = "X$p"; then - enable_shared=yes - fi - done - IFS="$lt_save_ifs" - ;; - esac], - [enable_shared=]_LT_ENABLE_SHARED_DEFAULT) - - _LT_DECL([build_libtool_libs], [enable_shared], [0], - [Whether or not to build shared libraries]) -])# _LT_ENABLE_SHARED - -LT_OPTION_DEFINE([LT_INIT], [shared], [_LT_ENABLE_SHARED([yes])]) -LT_OPTION_DEFINE([LT_INIT], [disable-shared], [_LT_ENABLE_SHARED([no])]) - -# Old names: -AC_DEFUN([AC_ENABLE_SHARED], -[_LT_SET_OPTION([LT_INIT], m4_if([$1], [no], [disable-])[shared]) -]) - -AC_DEFUN([AC_DISABLE_SHARED], -[_LT_SET_OPTION([LT_INIT], [disable-shared]) -]) - -AU_DEFUN([AM_ENABLE_SHARED], [AC_ENABLE_SHARED($@)]) -AU_DEFUN([AM_DISABLE_SHARED], [AC_DISABLE_SHARED($@)]) - -dnl aclocal-1.4 backwards compatibility: -dnl AC_DEFUN([AM_ENABLE_SHARED], []) -dnl AC_DEFUN([AM_DISABLE_SHARED], []) - - - -# _LT_ENABLE_STATIC([DEFAULT]) -# ---------------------------- -# implement the --enable-static flag, and support the `static' and -# `disable-static' LT_INIT options. -# DEFAULT is either `yes' or `no'. If omitted, it defaults to `yes'. -m4_define([_LT_ENABLE_STATIC], -[m4_define([_LT_ENABLE_STATIC_DEFAULT], [m4_if($1, no, no, yes)])dnl -AC_ARG_ENABLE([static], - [AS_HELP_STRING([--enable-static@<:@=PKGS@:>@], - [build static libraries @<:@default=]_LT_ENABLE_STATIC_DEFAULT[@:>@])], - [p=${PACKAGE-default} - case $enableval in - yes) enable_static=yes ;; - no) enable_static=no ;; - *) - enable_static=no - # Look at the argument we got. We use all the common list separators. - lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," - for pkg in $enableval; do - IFS="$lt_save_ifs" - if test "X$pkg" = "X$p"; then - enable_static=yes - fi - done - IFS="$lt_save_ifs" - ;; - esac], - [enable_static=]_LT_ENABLE_STATIC_DEFAULT) - - _LT_DECL([build_old_libs], [enable_static], [0], - [Whether or not to build static libraries]) -])# _LT_ENABLE_STATIC - -LT_OPTION_DEFINE([LT_INIT], [static], [_LT_ENABLE_STATIC([yes])]) -LT_OPTION_DEFINE([LT_INIT], [disable-static], [_LT_ENABLE_STATIC([no])]) - -# Old names: -AC_DEFUN([AC_ENABLE_STATIC], -[_LT_SET_OPTION([LT_INIT], m4_if([$1], [no], [disable-])[static]) -]) - -AC_DEFUN([AC_DISABLE_STATIC], -[_LT_SET_OPTION([LT_INIT], [disable-static]) -]) - -AU_DEFUN([AM_ENABLE_STATIC], [AC_ENABLE_STATIC($@)]) -AU_DEFUN([AM_DISABLE_STATIC], [AC_DISABLE_STATIC($@)]) - -dnl aclocal-1.4 backwards compatibility: -dnl AC_DEFUN([AM_ENABLE_STATIC], []) -dnl AC_DEFUN([AM_DISABLE_STATIC], []) - - - -# _LT_ENABLE_FAST_INSTALL([DEFAULT]) -# ---------------------------------- -# implement the --enable-fast-install flag, and support the `fast-install' -# and `disable-fast-install' LT_INIT options. -# DEFAULT is either `yes' or `no'. If omitted, it defaults to `yes'. -m4_define([_LT_ENABLE_FAST_INSTALL], -[m4_define([_LT_ENABLE_FAST_INSTALL_DEFAULT], [m4_if($1, no, no, yes)])dnl -AC_ARG_ENABLE([fast-install], - [AS_HELP_STRING([--enable-fast-install@<:@=PKGS@:>@], - [optimize for fast installation @<:@default=]_LT_ENABLE_FAST_INSTALL_DEFAULT[@:>@])], - [p=${PACKAGE-default} - case $enableval in - yes) enable_fast_install=yes ;; - no) enable_fast_install=no ;; - *) - enable_fast_install=no - # Look at the argument we got. We use all the common list separators. - lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," - for pkg in $enableval; do - IFS="$lt_save_ifs" - if test "X$pkg" = "X$p"; then - enable_fast_install=yes - fi - done - IFS="$lt_save_ifs" - ;; - esac], - [enable_fast_install=]_LT_ENABLE_FAST_INSTALL_DEFAULT) - -_LT_DECL([fast_install], [enable_fast_install], [0], - [Whether or not to optimize for fast installation])dnl -])# _LT_ENABLE_FAST_INSTALL - -LT_OPTION_DEFINE([LT_INIT], [fast-install], [_LT_ENABLE_FAST_INSTALL([yes])]) -LT_OPTION_DEFINE([LT_INIT], [disable-fast-install], [_LT_ENABLE_FAST_INSTALL([no])]) - -# Old names: -AU_DEFUN([AC_ENABLE_FAST_INSTALL], -[_LT_SET_OPTION([LT_INIT], m4_if([$1], [no], [disable-])[fast-install]) -AC_DIAGNOSE([obsolete], -[$0: Remove this warning and the call to _LT_SET_OPTION when you put -the `fast-install' option into LT_INIT's first parameter.]) -]) - -AU_DEFUN([AC_DISABLE_FAST_INSTALL], -[_LT_SET_OPTION([LT_INIT], [disable-fast-install]) -AC_DIAGNOSE([obsolete], -[$0: Remove this warning and the call to _LT_SET_OPTION when you put -the `disable-fast-install' option into LT_INIT's first parameter.]) -]) - -dnl aclocal-1.4 backwards compatibility: -dnl AC_DEFUN([AC_ENABLE_FAST_INSTALL], []) -dnl AC_DEFUN([AM_DISABLE_FAST_INSTALL], []) - - -# _LT_WITH_PIC([MODE]) -# -------------------- -# implement the --with-pic flag, and support the `pic-only' and `no-pic' -# LT_INIT options. -# MODE is either `yes' or `no'. If omitted, it defaults to `both'. -m4_define([_LT_WITH_PIC], -[AC_ARG_WITH([pic], - [AS_HELP_STRING([--with-pic@<:@=PKGS@:>@], - [try to use only PIC/non-PIC objects @<:@default=use both@:>@])], - [lt_p=${PACKAGE-default} - case $withval in - yes|no) pic_mode=$withval ;; - *) - pic_mode=default - # Look at the argument we got. We use all the common list separators. - lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," - for lt_pkg in $withval; do - IFS="$lt_save_ifs" - if test "X$lt_pkg" = "X$lt_p"; then - pic_mode=yes - fi - done - IFS="$lt_save_ifs" - ;; - esac], - [pic_mode=default]) - -test -z "$pic_mode" && pic_mode=m4_default([$1], [default]) - -_LT_DECL([], [pic_mode], [0], [What type of objects to build])dnl -])# _LT_WITH_PIC - -LT_OPTION_DEFINE([LT_INIT], [pic-only], [_LT_WITH_PIC([yes])]) -LT_OPTION_DEFINE([LT_INIT], [no-pic], [_LT_WITH_PIC([no])]) - -# Old name: -AU_DEFUN([AC_LIBTOOL_PICMODE], -[_LT_SET_OPTION([LT_INIT], [pic-only]) -AC_DIAGNOSE([obsolete], -[$0: Remove this warning and the call to _LT_SET_OPTION when you -put the `pic-only' option into LT_INIT's first parameter.]) -]) - -dnl aclocal-1.4 backwards compatibility: -dnl AC_DEFUN([AC_LIBTOOL_PICMODE], []) - - -m4_define([_LTDL_MODE], []) -LT_OPTION_DEFINE([LTDL_INIT], [nonrecursive], - [m4_define([_LTDL_MODE], [nonrecursive])]) -LT_OPTION_DEFINE([LTDL_INIT], [recursive], - [m4_define([_LTDL_MODE], [recursive])]) -LT_OPTION_DEFINE([LTDL_INIT], [subproject], - [m4_define([_LTDL_MODE], [subproject])]) - -m4_define([_LTDL_TYPE], []) -LT_OPTION_DEFINE([LTDL_INIT], [installable], - [m4_define([_LTDL_TYPE], [installable])]) -LT_OPTION_DEFINE([LTDL_INIT], [convenience], - [m4_define([_LTDL_TYPE], [convenience])]) - -# ltsugar.m4 -- libtool m4 base layer. -*-Autoconf-*- -# -# Copyright (C) 2004, 2005, 2007, 2008 Free Software Foundation, Inc. -# Written by Gary V. Vaughan, 2004 -# -# This file is free software; the Free Software Foundation gives -# unlimited permission to copy and/or distribute it, with or without -# modifications, as long as this notice is preserved. - -# serial 6 ltsugar.m4 - -# This is to help aclocal find these macros, as it can't see m4_define. -AC_DEFUN([LTSUGAR_VERSION], [m4_if([0.1])]) - - -# lt_join(SEP, ARG1, [ARG2...]) -# ----------------------------- -# Produce ARG1SEPARG2...SEPARGn, omitting [] arguments and their -# associated separator. -# Needed until we can rely on m4_join from Autoconf 2.62, since all earlier -# versions in m4sugar had bugs. -m4_define([lt_join], -[m4_if([$#], [1], [], - [$#], [2], [[$2]], - [m4_if([$2], [], [], [[$2]_])$0([$1], m4_shift(m4_shift($@)))])]) -m4_define([_lt_join], -[m4_if([$#$2], [2], [], - [m4_if([$2], [], [], [[$1$2]])$0([$1], m4_shift(m4_shift($@)))])]) - - -# lt_car(LIST) -# lt_cdr(LIST) -# ------------ -# Manipulate m4 lists. -# These macros are necessary as long as will still need to support -# Autoconf-2.59 which quotes differently. -m4_define([lt_car], [[$1]]) -m4_define([lt_cdr], -[m4_if([$#], 0, [m4_fatal([$0: cannot be called without arguments])], - [$#], 1, [], - [m4_dquote(m4_shift($@))])]) -m4_define([lt_unquote], $1) - - -# lt_append(MACRO-NAME, STRING, [SEPARATOR]) -# ------------------------------------------ -# Redefine MACRO-NAME to hold its former content plus `SEPARATOR'`STRING'. -# Note that neither SEPARATOR nor STRING are expanded; they are appended -# to MACRO-NAME as is (leaving the expansion for when MACRO-NAME is invoked). -# No SEPARATOR is output if MACRO-NAME was previously undefined (different -# than defined and empty). -# -# This macro is needed until we can rely on Autoconf 2.62, since earlier -# versions of m4sugar mistakenly expanded SEPARATOR but not STRING. -m4_define([lt_append], -[m4_define([$1], - m4_ifdef([$1], [m4_defn([$1])[$3]])[$2])]) - - - -# lt_combine(SEP, PREFIX-LIST, INFIX, SUFFIX1, [SUFFIX2...]) -# ---------------------------------------------------------- -# Produce a SEP delimited list of all paired combinations of elements of -# PREFIX-LIST with SUFFIX1 through SUFFIXn. Each element of the list -# has the form PREFIXmINFIXSUFFIXn. -# Needed until we can rely on m4_combine added in Autoconf 2.62. -m4_define([lt_combine], -[m4_if(m4_eval([$# > 3]), [1], - [m4_pushdef([_Lt_sep], [m4_define([_Lt_sep], m4_defn([lt_car]))])]]dnl -[[m4_foreach([_Lt_prefix], [$2], - [m4_foreach([_Lt_suffix], - ]m4_dquote(m4_dquote(m4_shift(m4_shift(m4_shift($@)))))[, - [_Lt_sep([$1])[]m4_defn([_Lt_prefix])[$3]m4_defn([_Lt_suffix])])])])]) - - -# lt_if_append_uniq(MACRO-NAME, VARNAME, [SEPARATOR], [UNIQ], [NOT-UNIQ]) -# ----------------------------------------------------------------------- -# Iff MACRO-NAME does not yet contain VARNAME, then append it (delimited -# by SEPARATOR if supplied) and expand UNIQ, else NOT-UNIQ. -m4_define([lt_if_append_uniq], -[m4_ifdef([$1], - [m4_if(m4_index([$3]m4_defn([$1])[$3], [$3$2$3]), [-1], - [lt_append([$1], [$2], [$3])$4], - [$5])], - [lt_append([$1], [$2], [$3])$4])]) - - -# lt_dict_add(DICT, KEY, VALUE) -# ----------------------------- -m4_define([lt_dict_add], -[m4_define([$1($2)], [$3])]) - - -# lt_dict_add_subkey(DICT, KEY, SUBKEY, VALUE) -# -------------------------------------------- -m4_define([lt_dict_add_subkey], -[m4_define([$1($2:$3)], [$4])]) - - -# lt_dict_fetch(DICT, KEY, [SUBKEY]) -# ---------------------------------- -m4_define([lt_dict_fetch], -[m4_ifval([$3], - m4_ifdef([$1($2:$3)], [m4_defn([$1($2:$3)])]), - m4_ifdef([$1($2)], [m4_defn([$1($2)])]))]) - - -# lt_if_dict_fetch(DICT, KEY, [SUBKEY], VALUE, IF-TRUE, [IF-FALSE]) -# ----------------------------------------------------------------- -m4_define([lt_if_dict_fetch], -[m4_if(lt_dict_fetch([$1], [$2], [$3]), [$4], - [$5], - [$6])]) - - -# lt_dict_filter(DICT, [SUBKEY], VALUE, [SEPARATOR], KEY, [...]) -# -------------------------------------------------------------- -m4_define([lt_dict_filter], -[m4_if([$5], [], [], - [lt_join(m4_quote(m4_default([$4], [[, ]])), - lt_unquote(m4_split(m4_normalize(m4_foreach(_Lt_key, lt_car([m4_shiftn(4, $@)]), - [lt_if_dict_fetch([$1], _Lt_key, [$2], [$3], [_Lt_key ])])))))])[]dnl -]) - -# ltversion.m4 -- version numbers -*- Autoconf -*- -# -# Copyright (C) 2004 Free Software Foundation, Inc. -# Written by Scott James Remnant, 2004 -# -# This file is free software; the Free Software Foundation gives -# unlimited permission to copy and/or distribute it, with or without -# modifications, as long as this notice is preserved. - -# @configure_input@ - -# serial 3337 ltversion.m4 -# This file is part of GNU Libtool - -m4_define([LT_PACKAGE_VERSION], [2.4.2]) -m4_define([LT_PACKAGE_REVISION], [1.3337]) - -AC_DEFUN([LTVERSION_VERSION], -[macro_version='2.4.2' -macro_revision='1.3337' -_LT_DECL(, macro_version, 0, [Which release of libtool.m4 was used?]) -_LT_DECL(, macro_revision, 0) -]) - -# lt~obsolete.m4 -- aclocal satisfying obsolete definitions. -*-Autoconf-*- -# -# Copyright (C) 2004, 2005, 2007, 2009 Free Software Foundation, Inc. -# Written by Scott James Remnant, 2004. -# -# This file is free software; the Free Software Foundation gives -# unlimited permission to copy and/or distribute it, with or without -# modifications, as long as this notice is preserved. - -# serial 5 lt~obsolete.m4 - -# These exist entirely to fool aclocal when bootstrapping libtool. -# -# In the past libtool.m4 has provided macros via AC_DEFUN (or AU_DEFUN) -# which have later been changed to m4_define as they aren't part of the -# exported API, or moved to Autoconf or Automake where they belong. -# -# The trouble is, aclocal is a bit thick. It'll see the old AC_DEFUN -# in /usr/share/aclocal/libtool.m4 and remember it, then when it sees us -# using a macro with the same name in our local m4/libtool.m4 it'll -# pull the old libtool.m4 in (it doesn't see our shiny new m4_define -# and doesn't know about Autoconf macros at all.) -# -# So we provide this file, which has a silly filename so it's always -# included after everything else. This provides aclocal with the -# AC_DEFUNs it wants, but when m4 processes it, it doesn't do anything -# because those macros already exist, or will be overwritten later. -# We use AC_DEFUN over AU_DEFUN for compatibility with aclocal-1.6. -# -# Anytime we withdraw an AC_DEFUN or AU_DEFUN, remember to add it here. -# Yes, that means every name once taken will need to remain here until -# we give up compatibility with versions before 1.7, at which point -# we need to keep only those names which we still refer to. - -# This is to help aclocal find these macros, as it can't see m4_define. -AC_DEFUN([LTOBSOLETE_VERSION], [m4_if([1])]) - -m4_ifndef([AC_LIBTOOL_LINKER_OPTION], [AC_DEFUN([AC_LIBTOOL_LINKER_OPTION])]) -m4_ifndef([AC_PROG_EGREP], [AC_DEFUN([AC_PROG_EGREP])]) -m4_ifndef([_LT_AC_PROG_ECHO_BACKSLASH], [AC_DEFUN([_LT_AC_PROG_ECHO_BACKSLASH])]) -m4_ifndef([_LT_AC_SHELL_INIT], [AC_DEFUN([_LT_AC_SHELL_INIT])]) -m4_ifndef([_LT_AC_SYS_LIBPATH_AIX], [AC_DEFUN([_LT_AC_SYS_LIBPATH_AIX])]) -m4_ifndef([_LT_PROG_LTMAIN], [AC_DEFUN([_LT_PROG_LTMAIN])]) -m4_ifndef([_LT_AC_TAGVAR], [AC_DEFUN([_LT_AC_TAGVAR])]) -m4_ifndef([AC_LTDL_ENABLE_INSTALL], [AC_DEFUN([AC_LTDL_ENABLE_INSTALL])]) -m4_ifndef([AC_LTDL_PREOPEN], [AC_DEFUN([AC_LTDL_PREOPEN])]) -m4_ifndef([_LT_AC_SYS_COMPILER], [AC_DEFUN([_LT_AC_SYS_COMPILER])]) -m4_ifndef([_LT_AC_LOCK], [AC_DEFUN([_LT_AC_LOCK])]) -m4_ifndef([AC_LIBTOOL_SYS_OLD_ARCHIVE], [AC_DEFUN([AC_LIBTOOL_SYS_OLD_ARCHIVE])]) -m4_ifndef([_LT_AC_TRY_DLOPEN_SELF], [AC_DEFUN([_LT_AC_TRY_DLOPEN_SELF])]) -m4_ifndef([AC_LIBTOOL_PROG_CC_C_O], [AC_DEFUN([AC_LIBTOOL_PROG_CC_C_O])]) -m4_ifndef([AC_LIBTOOL_SYS_HARD_LINK_LOCKS], [AC_DEFUN([AC_LIBTOOL_SYS_HARD_LINK_LOCKS])]) -m4_ifndef([AC_LIBTOOL_OBJDIR], [AC_DEFUN([AC_LIBTOOL_OBJDIR])]) -m4_ifndef([AC_LTDL_OBJDIR], [AC_DEFUN([AC_LTDL_OBJDIR])]) -m4_ifndef([AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH], [AC_DEFUN([AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH])]) -m4_ifndef([AC_LIBTOOL_SYS_LIB_STRIP], [AC_DEFUN([AC_LIBTOOL_SYS_LIB_STRIP])]) -m4_ifndef([AC_PATH_MAGIC], [AC_DEFUN([AC_PATH_MAGIC])]) -m4_ifndef([AC_PROG_LD_GNU], [AC_DEFUN([AC_PROG_LD_GNU])]) -m4_ifndef([AC_PROG_LD_RELOAD_FLAG], [AC_DEFUN([AC_PROG_LD_RELOAD_FLAG])]) -m4_ifndef([AC_DEPLIBS_CHECK_METHOD], [AC_DEFUN([AC_DEPLIBS_CHECK_METHOD])]) -m4_ifndef([AC_LIBTOOL_PROG_COMPILER_NO_RTTI], [AC_DEFUN([AC_LIBTOOL_PROG_COMPILER_NO_RTTI])]) -m4_ifndef([AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE], [AC_DEFUN([AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE])]) -m4_ifndef([AC_LIBTOOL_PROG_COMPILER_PIC], [AC_DEFUN([AC_LIBTOOL_PROG_COMPILER_PIC])]) -m4_ifndef([AC_LIBTOOL_PROG_LD_SHLIBS], [AC_DEFUN([AC_LIBTOOL_PROG_LD_SHLIBS])]) -m4_ifndef([AC_LIBTOOL_POSTDEP_PREDEP], [AC_DEFUN([AC_LIBTOOL_POSTDEP_PREDEP])]) -m4_ifndef([LT_AC_PROG_EGREP], [AC_DEFUN([LT_AC_PROG_EGREP])]) -m4_ifndef([LT_AC_PROG_SED], [AC_DEFUN([LT_AC_PROG_SED])]) -m4_ifndef([_LT_CC_BASENAME], [AC_DEFUN([_LT_CC_BASENAME])]) -m4_ifndef([_LT_COMPILER_BOILERPLATE], [AC_DEFUN([_LT_COMPILER_BOILERPLATE])]) -m4_ifndef([_LT_LINKER_BOILERPLATE], [AC_DEFUN([_LT_LINKER_BOILERPLATE])]) -m4_ifndef([_AC_PROG_LIBTOOL], [AC_DEFUN([_AC_PROG_LIBTOOL])]) -m4_ifndef([AC_LIBTOOL_SETUP], [AC_DEFUN([AC_LIBTOOL_SETUP])]) -m4_ifndef([_LT_AC_CHECK_DLFCN], [AC_DEFUN([_LT_AC_CHECK_DLFCN])]) -m4_ifndef([AC_LIBTOOL_SYS_DYNAMIC_LINKER], [AC_DEFUN([AC_LIBTOOL_SYS_DYNAMIC_LINKER])]) -m4_ifndef([_LT_AC_TAGCONFIG], [AC_DEFUN([_LT_AC_TAGCONFIG])]) -m4_ifndef([AC_DISABLE_FAST_INSTALL], [AC_DEFUN([AC_DISABLE_FAST_INSTALL])]) -m4_ifndef([_LT_AC_LANG_CXX], [AC_DEFUN([_LT_AC_LANG_CXX])]) -m4_ifndef([_LT_AC_LANG_F77], [AC_DEFUN([_LT_AC_LANG_F77])]) -m4_ifndef([_LT_AC_LANG_GCJ], [AC_DEFUN([_LT_AC_LANG_GCJ])]) -m4_ifndef([AC_LIBTOOL_LANG_C_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_C_CONFIG])]) -m4_ifndef([_LT_AC_LANG_C_CONFIG], [AC_DEFUN([_LT_AC_LANG_C_CONFIG])]) -m4_ifndef([AC_LIBTOOL_LANG_CXX_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_CXX_CONFIG])]) -m4_ifndef([_LT_AC_LANG_CXX_CONFIG], [AC_DEFUN([_LT_AC_LANG_CXX_CONFIG])]) -m4_ifndef([AC_LIBTOOL_LANG_F77_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_F77_CONFIG])]) -m4_ifndef([_LT_AC_LANG_F77_CONFIG], [AC_DEFUN([_LT_AC_LANG_F77_CONFIG])]) -m4_ifndef([AC_LIBTOOL_LANG_GCJ_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_GCJ_CONFIG])]) -m4_ifndef([_LT_AC_LANG_GCJ_CONFIG], [AC_DEFUN([_LT_AC_LANG_GCJ_CONFIG])]) -m4_ifndef([AC_LIBTOOL_LANG_RC_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_RC_CONFIG])]) -m4_ifndef([_LT_AC_LANG_RC_CONFIG], [AC_DEFUN([_LT_AC_LANG_RC_CONFIG])]) -m4_ifndef([AC_LIBTOOL_CONFIG], [AC_DEFUN([AC_LIBTOOL_CONFIG])]) -m4_ifndef([_LT_AC_FILE_LTDLL_C], [AC_DEFUN([_LT_AC_FILE_LTDLL_C])]) -m4_ifndef([_LT_REQUIRED_DARWIN_CHECKS], [AC_DEFUN([_LT_REQUIRED_DARWIN_CHECKS])]) -m4_ifndef([_LT_AC_PROG_CXXCPP], [AC_DEFUN([_LT_AC_PROG_CXXCPP])]) -m4_ifndef([_LT_PREPARE_SED_QUOTE_VARS], [AC_DEFUN([_LT_PREPARE_SED_QUOTE_VARS])]) -m4_ifndef([_LT_PROG_ECHO_BACKSLASH], [AC_DEFUN([_LT_PROG_ECHO_BACKSLASH])]) -m4_ifndef([_LT_PROG_F77], [AC_DEFUN([_LT_PROG_F77])]) -m4_ifndef([_LT_PROG_FC], [AC_DEFUN([_LT_PROG_FC])]) -m4_ifndef([_LT_PROG_CXX], [AC_DEFUN([_LT_PROG_CXX])]) - -# Copyright (C) 2002, 2003, 2005, 2006, 2007, 2008 Free Software Foundation, Inc. +# Copyright (C) 2002-2013 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -8618,10 +32,10 @@ m4_ifndef([_LT_PROG_CXX], [AC_DEFUN([_LT_PROG_CXX])]) # generated from the m4 files accompanying Automake X.Y. # (This private macro should not be called outside this file.) AC_DEFUN([AM_AUTOMAKE_VERSION], -[am__api_version='1.11' +[am__api_version='1.14' dnl Some users find AM_AUTOMAKE_VERSION and mistake it for a way to dnl require some minimum version. Point them to the right macro. -m4_if([$1], [1.11.1], [], +m4_if([$1], [1.14], [], [AC_FATAL([Do not call $0, use AM_INIT_AUTOMAKE([$1]).])])dnl ]) @@ -8637,22 +51,22 @@ m4_define([_AM_AUTOCONF_VERSION], []) # Call AM_AUTOMAKE_VERSION and AM_AUTOMAKE_VERSION so they can be traced. # This function is AC_REQUIREd by AM_INIT_AUTOMAKE. AC_DEFUN([AM_SET_CURRENT_AUTOMAKE_VERSION], -[AM_AUTOMAKE_VERSION([1.11.1])dnl +[AM_AUTOMAKE_VERSION([1.14])dnl m4_ifndef([AC_AUTOCONF_VERSION], [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl _AM_AUTOCONF_VERSION(m4_defn([AC_AUTOCONF_VERSION]))]) # AM_AUX_DIR_EXPAND -*- Autoconf -*- -# Copyright (C) 2001, 2003, 2005 Free Software Foundation, Inc. +# Copyright (C) 2001-2013 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # For projects using AC_CONFIG_AUX_DIR([foo]), Autoconf sets -# $ac_aux_dir to `$srcdir/foo'. In other projects, it is set to -# `$srcdir', `$srcdir/..', or `$srcdir/../..'. +# $ac_aux_dir to '$srcdir/foo'. In other projects, it is set to +# '$srcdir', '$srcdir/..', or '$srcdir/../..'. # # Of course, Automake must honor this variable whenever it calls a # tool from the auxiliary directory. The problem is that $srcdir (and @@ -8671,7 +85,7 @@ _AM_AUTOCONF_VERSION(m4_defn([AC_AUTOCONF_VERSION]))]) # # The reason of the latter failure is that $top_srcdir and $ac_aux_dir # are both prefixed by $srcdir. In an in-source build this is usually -# harmless because $srcdir is `.', but things will broke when you +# harmless because $srcdir is '.', but things will broke when you # start a VPATH build or use an absolute $srcdir. # # So we could use something similar to $top_srcdir/$ac_aux_dir/missing, @@ -8697,22 +111,19 @@ am_aux_dir=`cd $ac_aux_dir && pwd` # AM_CONDITIONAL -*- Autoconf -*- -# Copyright (C) 1997, 2000, 2001, 2003, 2004, 2005, 2006, 2008 -# Free Software Foundation, Inc. +# Copyright (C) 1997-2013 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. -# serial 9 - # AM_CONDITIONAL(NAME, SHELL-CONDITION) # ------------------------------------- # Define a conditional. AC_DEFUN([AM_CONDITIONAL], -[AC_PREREQ(2.52)dnl - ifelse([$1], [TRUE], [AC_FATAL([$0: invalid condition: $1])], - [$1], [FALSE], [AC_FATAL([$0: invalid condition: $1])])dnl +[AC_PREREQ([2.52])dnl + m4_if([$1], [TRUE], [AC_FATAL([$0: invalid condition: $1])], + [$1], [FALSE], [AC_FATAL([$0: invalid condition: $1])])dnl AC_SUBST([$1_TRUE])dnl AC_SUBST([$1_FALSE])dnl _AM_SUBST_NOTMAKE([$1_TRUE])dnl @@ -8731,16 +142,14 @@ AC_CONFIG_COMMANDS_PRE( Usually this means the macro was only invoked conditionally.]]) fi])]) -# Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2009 -# Free Software Foundation, Inc. +# Copyright (C) 1999-2013 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. -# serial 10 -# There are a few dirty hacks below to avoid letting `AC_PROG_CC' be +# There are a few dirty hacks below to avoid letting 'AC_PROG_CC' be # written in clear, in which case automake, when reading aclocal.m4, # will think it sees a *use*, and therefore will trigger all it's # C support machinery. Also note that it means that autoscan, seeing @@ -8750,7 +159,7 @@ fi])]) # _AM_DEPENDENCIES(NAME) # ---------------------- # See how the compiler implements dependency checking. -# NAME is "CC", "CXX", "GCJ", or "OBJC". +# NAME is "CC", "CXX", "OBJC", "OBJCXX", "UPC", or "GJC". # We try a few techniques and use that to set a single cache variable. # # We don't AC_REQUIRE the corresponding AC_PROG_CC since the latter was @@ -8763,12 +172,13 @@ AC_REQUIRE([AM_OUTPUT_DEPENDENCY_COMMANDS])dnl AC_REQUIRE([AM_MAKE_INCLUDE])dnl AC_REQUIRE([AM_DEP_TRACK])dnl -ifelse([$1], CC, [depcc="$CC" am_compiler_list=], - [$1], CXX, [depcc="$CXX" am_compiler_list=], - [$1], OBJC, [depcc="$OBJC" am_compiler_list='gcc3 gcc'], - [$1], UPC, [depcc="$UPC" am_compiler_list=], - [$1], GCJ, [depcc="$GCJ" am_compiler_list='gcc3 gcc'], - [depcc="$$1" am_compiler_list=]) +m4_if([$1], [CC], [depcc="$CC" am_compiler_list=], + [$1], [CXX], [depcc="$CXX" am_compiler_list=], + [$1], [OBJC], [depcc="$OBJC" am_compiler_list='gcc3 gcc'], + [$1], [OBJCXX], [depcc="$OBJCXX" am_compiler_list='gcc3 gcc'], + [$1], [UPC], [depcc="$UPC" am_compiler_list=], + [$1], [GCJ], [depcc="$GCJ" am_compiler_list='gcc3 gcc'], + [depcc="$$1" am_compiler_list=]) AC_CACHE_CHECK([dependency style of $depcc], [am_cv_$1_dependencies_compiler_type], @@ -8776,8 +186,9 @@ AC_CACHE_CHECK([dependency style of $depcc], # We make a subdir and do the tests there. Otherwise we can end up # making bogus files that we don't know about and never remove. For # instance it was reported that on HP-UX the gcc test will end up - # making a dummy file named `D' -- because `-MD' means `put the output - # in D'. + # making a dummy file named 'D' -- because '-MD' means "put the output + # in D". + rm -rf conftest.dir mkdir conftest.dir # Copy depcomp to subdir because otherwise we won't find it if we're # using a relative directory. @@ -8816,16 +227,16 @@ AC_CACHE_CHECK([dependency style of $depcc], : > sub/conftest.c for i in 1 2 3 4 5 6; do echo '#include "conftst'$i'.h"' >> sub/conftest.c - # Using `: > sub/conftst$i.h' creates only sub/conftst1.h with - # Solaris 8's {/usr,}/bin/sh. - touch sub/conftst$i.h + # Using ": > sub/conftst$i.h" creates only sub/conftst1.h with + # Solaris 10 /bin/sh. + echo '/* dummy */' > sub/conftst$i.h done echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf - # We check with `-c' and `-o' for the sake of the "dashmstdout" + # We check with '-c' and '-o' for the sake of the "dashmstdout" # mode. It turns out that the SunPro C++ compiler does not properly - # handle `-M -o', and we need to detect this. Also, some Intel - # versions had trouble with output in subdirs + # handle '-M -o', and we need to detect this. Also, some Intel + # versions had trouble with output in subdirs. am__obj=sub/conftest.${OBJEXT-o} am__minus_obj="-o $am__obj" case $depmode in @@ -8834,16 +245,16 @@ AC_CACHE_CHECK([dependency style of $depcc], test "$am__universal" = false || continue ;; nosideeffect) - # after this tag, mechanisms are not by side-effect, so they'll - # only be used when explicitly requested + # After this tag, mechanisms are not by side-effect, so they'll + # only be used when explicitly requested. if test "x$enable_dependency_tracking" = xyes; then continue else break fi ;; - msvisualcpp | msvcmsys) - # This compiler won't grok `-c -o', but also, the minuso test has + msvc7 | msvc7msys | msvisualcpp | msvcmsys) + # This compiler won't grok '-c -o', but also, the minuso test has # not run yet. These depmodes are late enough in the game, and # so weak that their functioning should not be impacted. am__obj=conftest.${OBJEXT-o} @@ -8891,7 +302,7 @@ AM_CONDITIONAL([am__fastdep$1], [ # AM_SET_DEPDIR # ------------- # Choose a directory name for dependency files. -# This macro is AC_REQUIREd in _AM_DEPENDENCIES +# This macro is AC_REQUIREd in _AM_DEPENDENCIES. AC_DEFUN([AM_SET_DEPDIR], [AC_REQUIRE([AM_SET_LEADING_DOT])dnl AC_SUBST([DEPDIR], ["${am__leading_dot}deps"])dnl @@ -8901,34 +312,39 @@ AC_SUBST([DEPDIR], ["${am__leading_dot}deps"])dnl # AM_DEP_TRACK # ------------ AC_DEFUN([AM_DEP_TRACK], -[AC_ARG_ENABLE(dependency-tracking, -[ --disable-dependency-tracking speeds up one-time build - --enable-dependency-tracking do not reject slow dependency extractors]) +[AC_ARG_ENABLE([dependency-tracking], [dnl +AS_HELP_STRING( + [--enable-dependency-tracking], + [do not reject slow dependency extractors]) +AS_HELP_STRING( + [--disable-dependency-tracking], + [speeds up one-time build])]) if test "x$enable_dependency_tracking" != xno; then am_depcomp="$ac_aux_dir/depcomp" AMDEPBACKSLASH='\' + am__nodep='_no' fi AM_CONDITIONAL([AMDEP], [test "x$enable_dependency_tracking" != xno]) AC_SUBST([AMDEPBACKSLASH])dnl _AM_SUBST_NOTMAKE([AMDEPBACKSLASH])dnl +AC_SUBST([am__nodep])dnl +_AM_SUBST_NOTMAKE([am__nodep])dnl ]) # Generate code to set up dependency tracking. -*- Autoconf -*- -# Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2008 -# Free Software Foundation, Inc. +# Copyright (C) 1999-2013 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. -#serial 5 # _AM_OUTPUT_DEPENDENCY_COMMANDS # ------------------------------ AC_DEFUN([_AM_OUTPUT_DEPENDENCY_COMMANDS], [{ - # Autoconf 2.62 quotes --file arguments for eval, but not when files + # Older Autoconf quotes --file arguments for eval, but not when files # are listed without --file. Let's play safe and only enable the eval # if we detect the quoting. case $CONFIG_FILES in @@ -8941,7 +357,7 @@ AC_DEFUN([_AM_OUTPUT_DEPENDENCY_COMMANDS], # Strip MF so we end up with the name of the file. mf=`echo "$mf" | sed -e 's/:.*$//'` # Check whether this is an Automake generated Makefile or not. - # We used to match only the files named `Makefile.in', but + # We used to match only the files named 'Makefile.in', but # some people rename them; so instead we look at the file content. # Grep'ing the first line is not enough: some people post-process # each Makefile.in and add a new line on top of each file to say so. @@ -8953,21 +369,19 @@ AC_DEFUN([_AM_OUTPUT_DEPENDENCY_COMMANDS], continue fi # Extract the definition of DEPDIR, am__include, and am__quote - # from the Makefile without running `make'. + # from the Makefile without running 'make'. DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"` test -z "$DEPDIR" && continue am__include=`sed -n 's/^am__include = //p' < "$mf"` - test -z "am__include" && continue + test -z "$am__include" && continue am__quote=`sed -n 's/^am__quote = //p' < "$mf"` - # When using ansi2knr, U may be empty or an underscore; expand it - U=`sed -n 's/^U = //p' < "$mf"` # Find all dependency output files, they are included files with # $(DEPDIR) in their names. We invoke sed twice because it is the # simplest approach to changing $(DEPDIR) to its actual value in the # expansion. for file in `sed -n " s/^$am__include $am__quote\(.*(DEPDIR).*\)$am__quote"'$/\1/p' <"$mf" | \ - sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g' -e 's/\$U/'"$U"'/g'`; do + sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g'`; do # Make sure the directory exists. test -f "$dirpart/$file" && continue fdir=`AS_DIRNAME(["$file"])` @@ -8985,7 +399,7 @@ AC_DEFUN([_AM_OUTPUT_DEPENDENCY_COMMANDS], # This macro should only be invoked once -- use via AC_REQUIRE. # # This code is only required when automatic dependency tracking -# is enabled. FIXME. This creates each `.P' file that we will +# is enabled. FIXME. This creates each '.P' file that we will # need in order to bootstrap the dependency handling code. AC_DEFUN([AM_OUTPUT_DEPENDENCY_COMMANDS], [AC_CONFIG_COMMANDS([depfiles], @@ -8993,32 +407,23 @@ AC_DEFUN([AM_OUTPUT_DEPENDENCY_COMMANDS], [AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir"]) ]) -# Copyright (C) 1996, 1997, 2000, 2001, 2003, 2005 -# Free Software Foundation, Inc. -# -# This file is free software; the Free Software Foundation -# gives unlimited permission to copy and/or distribute it, -# with or without modifications, as long as this notice is preserved. - -# serial 8 - -# AM_CONFIG_HEADER is obsolete. It has been replaced by AC_CONFIG_HEADERS. -AU_DEFUN([AM_CONFIG_HEADER], [AC_CONFIG_HEADERS($@)]) - # Do all the work for Automake. -*- Autoconf -*- -# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, -# 2005, 2006, 2008, 2009 Free Software Foundation, Inc. +# Copyright (C) 1996-2013 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. -# serial 16 - # This macro actually does too much. Some checks are only needed if # your package does certain things. But this isn't really a big deal. +dnl Redefine AC_PROG_CC to automatically invoke _AM_PROG_CC_C_O. +m4_define([AC_PROG_CC], +m4_defn([AC_PROG_CC]) +[_AM_PROG_CC_C_O +]) + # AM_INIT_AUTOMAKE(PACKAGE, VERSION, [NO-DEFINE]) # AM_INIT_AUTOMAKE([OPTIONS]) # ----------------------------------------------- @@ -9031,7 +436,7 @@ AU_DEFUN([AM_CONFIG_HEADER], [AC_CONFIG_HEADERS($@)]) # arguments mandatory, and then we can depend on a new Autoconf # release and drop the old call support. AC_DEFUN([AM_INIT_AUTOMAKE], -[AC_PREREQ([2.62])dnl +[AC_PREREQ([2.65])dnl dnl Autoconf wants to disallow AM_ names. We explicitly allow dnl the ones we care about. m4_pattern_allow([^AM_[A-Z]+FLAGS$])dnl @@ -9060,31 +465,40 @@ AC_SUBST([CYGPATH_W]) # Define the identity of the package. dnl Distinguish between old-style and new-style calls. m4_ifval([$2], -[m4_ifval([$3], [_AM_SET_OPTION([no-define])])dnl +[AC_DIAGNOSE([obsolete], + [$0: two- and three-arguments forms are deprecated.]) +m4_ifval([$3], [_AM_SET_OPTION([no-define])])dnl AC_SUBST([PACKAGE], [$1])dnl AC_SUBST([VERSION], [$2])], [_AM_SET_OPTIONS([$1])dnl dnl Diagnose old-style AC_INIT with new-style AM_AUTOMAKE_INIT. -m4_if(m4_ifdef([AC_PACKAGE_NAME], 1)m4_ifdef([AC_PACKAGE_VERSION], 1), 11,, +m4_if( + m4_ifdef([AC_PACKAGE_NAME], [ok]):m4_ifdef([AC_PACKAGE_VERSION], [ok]), + [ok:ok],, [m4_fatal([AC_INIT should be called with package and version arguments])])dnl AC_SUBST([PACKAGE], ['AC_PACKAGE_TARNAME'])dnl AC_SUBST([VERSION], ['AC_PACKAGE_VERSION'])])dnl _AM_IF_OPTION([no-define],, -[AC_DEFINE_UNQUOTED(PACKAGE, "$PACKAGE", [Name of package]) - AC_DEFINE_UNQUOTED(VERSION, "$VERSION", [Version number of package])])dnl +[AC_DEFINE_UNQUOTED([PACKAGE], ["$PACKAGE"], [Name of package]) + AC_DEFINE_UNQUOTED([VERSION], ["$VERSION"], [Version number of package])])dnl # Some tools Automake needs. AC_REQUIRE([AM_SANITY_CHECK])dnl AC_REQUIRE([AC_ARG_PROGRAM])dnl -AM_MISSING_PROG(ACLOCAL, aclocal-${am__api_version}) -AM_MISSING_PROG(AUTOCONF, autoconf) -AM_MISSING_PROG(AUTOMAKE, automake-${am__api_version}) -AM_MISSING_PROG(AUTOHEADER, autoheader) -AM_MISSING_PROG(MAKEINFO, makeinfo) +AM_MISSING_PROG([ACLOCAL], [aclocal-${am__api_version}]) +AM_MISSING_PROG([AUTOCONF], [autoconf]) +AM_MISSING_PROG([AUTOMAKE], [automake-${am__api_version}]) +AM_MISSING_PROG([AUTOHEADER], [autoheader]) +AM_MISSING_PROG([MAKEINFO], [makeinfo]) AC_REQUIRE([AM_PROG_INSTALL_SH])dnl AC_REQUIRE([AM_PROG_INSTALL_STRIP])dnl -AC_REQUIRE([AM_PROG_MKDIR_P])dnl +AC_REQUIRE([AC_PROG_MKDIR_P])dnl +# For better backward compatibility. To be removed once Automake 1.9.x +# dies out for good. For more background, see: +# +# +AC_SUBST([mkdir_p], ['$(MKDIR_P)']) # We need awk for the "check" target. The system "awk" is bad on # some platforms. AC_REQUIRE([AC_PROG_AWK])dnl @@ -9095,34 +509,78 @@ _AM_IF_OPTION([tar-ustar], [_AM_PROG_TAR([ustar])], [_AM_PROG_TAR([v7])])]) _AM_IF_OPTION([no-dependencies],, [AC_PROVIDE_IFELSE([AC_PROG_CC], - [_AM_DEPENDENCIES(CC)], - [define([AC_PROG_CC], - defn([AC_PROG_CC])[_AM_DEPENDENCIES(CC)])])dnl + [_AM_DEPENDENCIES([CC])], + [m4_define([AC_PROG_CC], + m4_defn([AC_PROG_CC])[_AM_DEPENDENCIES([CC])])])dnl AC_PROVIDE_IFELSE([AC_PROG_CXX], - [_AM_DEPENDENCIES(CXX)], - [define([AC_PROG_CXX], - defn([AC_PROG_CXX])[_AM_DEPENDENCIES(CXX)])])dnl + [_AM_DEPENDENCIES([CXX])], + [m4_define([AC_PROG_CXX], + m4_defn([AC_PROG_CXX])[_AM_DEPENDENCIES([CXX])])])dnl AC_PROVIDE_IFELSE([AC_PROG_OBJC], - [_AM_DEPENDENCIES(OBJC)], - [define([AC_PROG_OBJC], - defn([AC_PROG_OBJC])[_AM_DEPENDENCIES(OBJC)])])dnl + [_AM_DEPENDENCIES([OBJC])], + [m4_define([AC_PROG_OBJC], + m4_defn([AC_PROG_OBJC])[_AM_DEPENDENCIES([OBJC])])])dnl +AC_PROVIDE_IFELSE([AC_PROG_OBJCXX], + [_AM_DEPENDENCIES([OBJCXX])], + [m4_define([AC_PROG_OBJCXX], + m4_defn([AC_PROG_OBJCXX])[_AM_DEPENDENCIES([OBJCXX])])])dnl ]) -_AM_IF_OPTION([silent-rules], [AC_REQUIRE([AM_SILENT_RULES])])dnl -dnl The `parallel-tests' driver may need to know about EXEEXT, so add the -dnl `am__EXEEXT' conditional if _AM_COMPILER_EXEEXT was seen. This macro -dnl is hooked onto _AC_COMPILER_EXEEXT early, see below. +AC_REQUIRE([AM_SILENT_RULES])dnl +dnl The testsuite driver may need to know about EXEEXT, so add the +dnl 'am__EXEEXT' conditional if _AM_COMPILER_EXEEXT was seen. This +dnl macro is hooked onto _AC_COMPILER_EXEEXT early, see below. AC_CONFIG_COMMANDS_PRE(dnl [m4_provide_if([_AM_COMPILER_EXEEXT], [AM_CONDITIONAL([am__EXEEXT], [test -n "$EXEEXT"])])])dnl -]) -dnl Hook into `_AC_COMPILER_EXEEXT' early to learn its expansion. Do not +# POSIX will say in a future version that running "rm -f" with no argument +# is OK; and we want to be able to make that assumption in our Makefile +# recipes. So use an aggressive probe to check that the usage we want is +# actually supported "in the wild" to an acceptable degree. +# See automake bug#10828. +# To make any issue more visible, cause the running configure to be aborted +# by default if the 'rm' program in use doesn't match our expectations; the +# user can still override this though. +if rm -f && rm -fr && rm -rf; then : OK; else + cat >&2 <<'END' +Oops! + +Your 'rm' program seems unable to run without file operands specified +on the command line, even when the '-f' option is present. This is contrary +to the behaviour of most rm programs out there, and not conforming with +the upcoming POSIX standard: + +Please tell bug-automake@gnu.org about your system, including the value +of your $PATH and any error possibly output before this message. This +can help us improve future automake versions. + +END + if test x"$ACCEPT_INFERIOR_RM_PROGRAM" = x"yes"; then + echo 'Configuration will proceed anyway, since you have set the' >&2 + echo 'ACCEPT_INFERIOR_RM_PROGRAM variable to "yes"' >&2 + echo >&2 + else + cat >&2 <<'END' +Aborting the configuration process, to ensure you take notice of the issue. + +You can download and install GNU coreutils to get an 'rm' implementation +that behaves properly: . + +If you want to complete the configuration process using your problematic +'rm' anyway, export the environment variable ACCEPT_INFERIOR_RM_PROGRAM +to "yes", and re-run configure. + +END + AC_MSG_ERROR([Your 'rm' program is bad, sorry.]) + fi +fi]) + +dnl Hook into '_AC_COMPILER_EXEEXT' early to learn its expansion. Do not dnl add the conditional right here, as _AC_COMPILER_EXEEXT may be further dnl mangled by Autoconf and run in a shell conditional statement. m4_define([_AC_COMPILER_EXEEXT], m4_defn([_AC_COMPILER_EXEEXT])[m4_provide([_AM_COMPILER_EXEEXT])]) - # When config.status generates a header, we must update the stamp-h file. # This file resides in the same directory as the config header # that is generated. The stamp files are numbered to have different names. @@ -9144,7 +602,7 @@ for _am_header in $config_headers :; do done echo "timestamp for $_am_arg" >`AS_DIRNAME(["$_am_arg"])`/stamp-h[]$_am_stamp_count]) -# Copyright (C) 2001, 2003, 2005, 2008 Free Software Foundation, Inc. +# Copyright (C) 2001-2013 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -9163,16 +621,14 @@ if test x"${install_sh}" != xset; then install_sh="\${SHELL} $am_aux_dir/install-sh" esac fi -AC_SUBST(install_sh)]) +AC_SUBST([install_sh])]) -# Copyright (C) 2003, 2005 Free Software Foundation, Inc. +# Copyright (C) 2003-2013 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. -# serial 2 - # Check whether the underlying file-system supports filenames # with a leading dot. For instance MS-DOS doesn't. AC_DEFUN([AM_SET_LEADING_DOT], @@ -9188,14 +644,12 @@ AC_SUBST([am__leading_dot])]) # Check to see how 'make' treats includes. -*- Autoconf -*- -# Copyright (C) 2001, 2002, 2003, 2005, 2009 Free Software Foundation, Inc. +# Copyright (C) 2001-2013 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. -# serial 4 - # AM_MAKE_INCLUDE() # ----------------- # Check to see how make treats includes. @@ -9213,7 +667,7 @@ am__quote= _am_result=none # First try GNU make style include. echo "include confinc" > confmf -# Ignore all kinds of additional output from `make'. +# Ignore all kinds of additional output from 'make'. case `$am_make -s -f confmf 2> /dev/null` in #( *the\ am__doit\ target*) am__include=include @@ -9240,15 +694,12 @@ rm -f confinc confmf # Fake the existence of programs that GNU maintainers use. -*- Autoconf -*- -# Copyright (C) 1997, 1999, 2000, 2001, 2003, 2004, 2005, 2008 -# Free Software Foundation, Inc. +# Copyright (C) 1997-2013 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. -# serial 6 - # AM_MISSING_PROG(NAME, PROGRAM) # ------------------------------ AC_DEFUN([AM_MISSING_PROG], @@ -9256,11 +707,10 @@ AC_DEFUN([AM_MISSING_PROG], $1=${$1-"${am_missing_run}$2"} AC_SUBST($1)]) - # AM_MISSING_HAS_RUN # ------------------ -# Define MISSING if not defined so far and test if it supports --run. -# If it does, set am_missing_run to use it, otherwise, to nothing. +# Define MISSING if not defined so far and test if it is modern enough. +# If it is, set am_missing_run to use it, otherwise, to nothing. AC_DEFUN([AM_MISSING_HAS_RUN], [AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl AC_REQUIRE_AUX_FILE([missing])dnl @@ -9273,63 +723,64 @@ if test x"${MISSING+set}" != xset; then esac fi # Use eval to expand $SHELL -if eval "$MISSING --run true"; then - am_missing_run="$MISSING --run " +if eval "$MISSING --is-lightweight"; then + am_missing_run="$MISSING " else am_missing_run= - AC_MSG_WARN([`missing' script is too old or missing]) + AC_MSG_WARN(['missing' script is too old or missing]) fi ]) -# Copyright (C) 2003, 2004, 2005, 2006 Free Software Foundation, Inc. +# -*- Autoconf -*- +# Obsolete and "removed" macros, that must however still report explicit +# error messages when used, to smooth transition. +# +# Copyright (C) 1996-2013 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. -# AM_PROG_MKDIR_P -# --------------- -# Check for `mkdir -p'. -AC_DEFUN([AM_PROG_MKDIR_P], -[AC_PREREQ([2.60])dnl -AC_REQUIRE([AC_PROG_MKDIR_P])dnl -dnl Automake 1.8 to 1.9.6 used to define mkdir_p. We now use MKDIR_P, -dnl while keeping a definition of mkdir_p for backward compatibility. -dnl @MKDIR_P@ is magic: AC_OUTPUT adjusts its value for each Makefile. -dnl However we cannot define mkdir_p as $(MKDIR_P) for the sake of -dnl Makefile.ins that do not define MKDIR_P, so we do our own -dnl adjustment using top_builddir (which is defined more often than -dnl MKDIR_P). -AC_SUBST([mkdir_p], ["$MKDIR_P"])dnl -case $mkdir_p in - [[\\/$]]* | ?:[[\\/]]*) ;; - */*) mkdir_p="\$(top_builddir)/$mkdir_p" ;; -esac -]) +AC_DEFUN([AM_CONFIG_HEADER], +[AC_DIAGNOSE([obsolete], +['$0': this macro is obsolete. +You should use the 'AC][_CONFIG_HEADERS' macro instead.])dnl +AC_CONFIG_HEADERS($@)]) + +AC_DEFUN([AM_PROG_CC_STDC], +[AC_PROG_CC +am_cv_prog_cc_stdc=$ac_cv_prog_cc_stdc +AC_DIAGNOSE([obsolete], +['$0': this macro is obsolete. +You should simply use the 'AC][_PROG_CC' macro instead. +Also, your code should no longer depend upon 'am_cv_prog_cc_stdc', +but upon 'ac_cv_prog_cc_stdc'.])]) + +AC_DEFUN([AM_C_PROTOTYPES], + [AC_FATAL([automatic de-ANSI-fication support has been removed])]) +AU_DEFUN([fp_C_PROTOTYPES], [AM_C_PROTOTYPES]) # Helper functions for option handling. -*- Autoconf -*- -# Copyright (C) 2001, 2002, 2003, 2005, 2008 Free Software Foundation, Inc. +# Copyright (C) 2001-2013 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. -# serial 4 - # _AM_MANGLE_OPTION(NAME) # ----------------------- AC_DEFUN([_AM_MANGLE_OPTION], [[_AM_OPTION_]m4_bpatsubst($1, [[^a-zA-Z0-9_]], [_])]) # _AM_SET_OPTION(NAME) -# ------------------------------ +# -------------------- # Set option NAME. Presently that only means defining a flag for this option. AC_DEFUN([_AM_SET_OPTION], -[m4_define(_AM_MANGLE_OPTION([$1]), 1)]) +[m4_define(_AM_MANGLE_OPTION([$1]), [1])]) # _AM_SET_OPTIONS(OPTIONS) -# ---------------------------------- +# ------------------------ # OPTIONS is a space-separated list of Automake options. AC_DEFUN([_AM_SET_OPTIONS], [m4_foreach_w([_AM_Option], [$1], [_AM_SET_OPTION(_AM_Option)])]) @@ -9340,24 +791,82 @@ AC_DEFUN([_AM_SET_OPTIONS], AC_DEFUN([_AM_IF_OPTION], [m4_ifset(_AM_MANGLE_OPTION([$1]), [$2], [$3])]) -# Check to make sure that the build environment is sane. -*- Autoconf -*- - -# Copyright (C) 1996, 1997, 2000, 2001, 2003, 2005, 2008 -# Free Software Foundation, Inc. +# Copyright (C) 1999-2013 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. -# serial 5 +# _AM_PROG_CC_C_O +# --------------- +# Like AC_PROG_CC_C_O, but changed for automake. We rewrite AC_PROG_CC +# to automatically call this. +AC_DEFUN([_AM_PROG_CC_C_O], +[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl +AC_REQUIRE_AUX_FILE([compile])dnl +AC_LANG_PUSH([C])dnl +AC_CACHE_CHECK( + [whether $CC understands -c and -o together], + [am_cv_prog_cc_c_o], + [AC_LANG_CONFTEST([AC_LANG_PROGRAM([])]) + # Make sure it works both with $CC and with simple cc. + # Following AC_PROG_CC_C_O, we do the test twice because some + # compilers refuse to overwrite an existing .o file with -o, + # though they will create one. + am_cv_prog_cc_c_o=yes + for am_i in 1 2; do + if AM_RUN_LOG([$CC -c conftest.$ac_ext -o conftest2.$ac_objext]) \ + && test -f conftest2.$ac_objext; then + : OK + else + am_cv_prog_cc_c_o=no + break + fi + done + rm -f core conftest* + unset am_i]) +if test "$am_cv_prog_cc_c_o" != yes; then + # Losing compiler, so override with the script. + # FIXME: It is wrong to rewrite CC. + # But if we don't then we get into trouble of one sort or another. + # A longer-term fix would be to have automake use am__CC in this case, + # and then we could set am__CC="\$(top_srcdir)/compile \$(CC)" + CC="$am_aux_dir/compile $CC" +fi +AC_LANG_POP([C])]) + +# For backward compatibility. +AC_DEFUN_ONCE([AM_PROG_CC_C_O], [AC_REQUIRE([AC_PROG_CC])]) + +# Copyright (C) 2001-2013 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# AM_RUN_LOG(COMMAND) +# ------------------- +# Run COMMAND, save the exit status in ac_status, and log it. +# (This has been adapted from Autoconf's _AC_RUN_LOG macro.) +AC_DEFUN([AM_RUN_LOG], +[{ echo "$as_me:$LINENO: $1" >&AS_MESSAGE_LOG_FD + ($1) >&AS_MESSAGE_LOG_FD 2>&AS_MESSAGE_LOG_FD + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&AS_MESSAGE_LOG_FD + (exit $ac_status); }]) + +# Check to make sure that the build environment is sane. -*- Autoconf -*- + +# Copyright (C) 1996-2013 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. # AM_SANITY_CHECK # --------------- AC_DEFUN([AM_SANITY_CHECK], [AC_MSG_CHECKING([whether build environment is sane]) -# Just in case -sleep 1 -echo timestamp > conftest.file # Reject unsafe characters in $srcdir or the absolute working directory # name. Accept space and tab only in the latter. am_lf=' @@ -9368,32 +877,40 @@ case `pwd` in esac case $srcdir in *[[\\\"\#\$\&\'\`$am_lf\ \ ]]*) - AC_MSG_ERROR([unsafe srcdir value: `$srcdir']);; + AC_MSG_ERROR([unsafe srcdir value: '$srcdir']);; esac -# Do `set' in a subshell so we don't clobber the current shell's +# Do 'set' in a subshell so we don't clobber the current shell's # arguments. Must try -L first in case configure is actually a # symlink; some systems play weird games with the mod time of symlinks # (eg FreeBSD returns the mod time of the symlink's containing # directory). if ( - set X `ls -Lt "$srcdir/configure" conftest.file 2> /dev/null` - if test "$[*]" = "X"; then - # -L didn't work. - set X `ls -t "$srcdir/configure" conftest.file` - fi - rm -f conftest.file - if test "$[*]" != "X $srcdir/configure conftest.file" \ - && test "$[*]" != "X conftest.file $srcdir/configure"; then - - # If neither matched, then we have a broken ls. This can happen - # if, for instance, CONFIG_SHELL is bash and it inherits a - # broken ls alias from the environment. This has actually - # happened. Such a system could not be considered "sane". - AC_MSG_ERROR([ls -t appears to fail. Make sure there is not a broken -alias in your environment]) - fi + am_has_slept=no + for am_try in 1 2; do + echo "timestamp, slept: $am_has_slept" > conftest.file + set X `ls -Lt "$srcdir/configure" conftest.file 2> /dev/null` + if test "$[*]" = "X"; then + # -L didn't work. + set X `ls -t "$srcdir/configure" conftest.file` + fi + if test "$[*]" != "X $srcdir/configure conftest.file" \ + && test "$[*]" != "X conftest.file $srcdir/configure"; then + # If neither matched, then we have a broken ls. This can happen + # if, for instance, CONFIG_SHELL is bash and it inherits a + # broken ls alias from the environment. This has actually + # happened. Such a system could not be considered "sane". + AC_MSG_ERROR([ls -t appears to fail. Make sure there is not a broken + alias in your environment]) + fi + if test "$[2]" = conftest.file || test $am_try -eq 2; then + break + fi + # Just in case. + sleep 1 + am_has_slept=yes + done test "$[2]" = conftest.file ) then @@ -9403,9 +920,85 @@ else AC_MSG_ERROR([newly created file is older than distributed files! Check your system clock]) fi -AC_MSG_RESULT(yes)]) +AC_MSG_RESULT([yes]) +# If we didn't sleep, we still need to ensure time stamps of config.status and +# generated files are strictly newer. +am_sleep_pid= +if grep 'slept: no' conftest.file >/dev/null 2>&1; then + ( sleep 1 ) & + am_sleep_pid=$! +fi +AC_CONFIG_COMMANDS_PRE( + [AC_MSG_CHECKING([that generated files are newer than configure]) + if test -n "$am_sleep_pid"; then + # Hide warnings about reused PIDs. + wait $am_sleep_pid 2>/dev/null + fi + AC_MSG_RESULT([done])]) +rm -f conftest.file +]) -# Copyright (C) 2001, 2003, 2005 Free Software Foundation, Inc. +# Copyright (C) 2009-2013 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# AM_SILENT_RULES([DEFAULT]) +# -------------------------- +# Enable less verbose build rules; with the default set to DEFAULT +# ("yes" being less verbose, "no" or empty being verbose). +AC_DEFUN([AM_SILENT_RULES], +[AC_ARG_ENABLE([silent-rules], [dnl +AS_HELP_STRING( + [--enable-silent-rules], + [less verbose build output (undo: "make V=1")]) +AS_HELP_STRING( + [--disable-silent-rules], + [verbose build output (undo: "make V=0")])dnl +]) +case $enable_silent_rules in @%:@ ((( + yes) AM_DEFAULT_VERBOSITY=0;; + no) AM_DEFAULT_VERBOSITY=1;; + *) AM_DEFAULT_VERBOSITY=m4_if([$1], [yes], [0], [1]);; +esac +dnl +dnl A few 'make' implementations (e.g., NonStop OS and NextStep) +dnl do not support nested variable expansions. +dnl See automake bug#9928 and bug#10237. +am_make=${MAKE-make} +AC_CACHE_CHECK([whether $am_make supports nested variables], + [am_cv_make_support_nested_variables], + [if AS_ECHO([['TRUE=$(BAR$(V)) +BAR0=false +BAR1=true +V=1 +am__doit: + @$(TRUE) +.PHONY: am__doit']]) | $am_make -f - >/dev/null 2>&1; then + am_cv_make_support_nested_variables=yes +else + am_cv_make_support_nested_variables=no +fi]) +if test $am_cv_make_support_nested_variables = yes; then + dnl Using '$V' instead of '$(V)' breaks IRIX make. + AM_V='$(V)' + AM_DEFAULT_V='$(AM_DEFAULT_VERBOSITY)' +else + AM_V=$AM_DEFAULT_VERBOSITY + AM_DEFAULT_V=$AM_DEFAULT_VERBOSITY +fi +AC_SUBST([AM_V])dnl +AM_SUBST_NOTMAKE([AM_V])dnl +AC_SUBST([AM_DEFAULT_V])dnl +AM_SUBST_NOTMAKE([AM_DEFAULT_V])dnl +AC_SUBST([AM_DEFAULT_VERBOSITY])dnl +AM_BACKSLASH='\' +AC_SUBST([AM_BACKSLASH])dnl +_AM_SUBST_NOTMAKE([AM_BACKSLASH])dnl +]) + +# Copyright (C) 2001-2013 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -9413,34 +1006,32 @@ AC_MSG_RESULT(yes)]) # AM_PROG_INSTALL_STRIP # --------------------- -# One issue with vendor `install' (even GNU) is that you can't +# One issue with vendor 'install' (even GNU) is that you can't # specify the program used to strip binaries. This is especially # annoying in cross-compiling environments, where the build's strip # is unlikely to handle the host's binaries. # Fortunately install-sh will honor a STRIPPROG variable, so we -# always use install-sh in `make install-strip', and initialize +# always use install-sh in "make install-strip", and initialize # STRIPPROG with the value of the STRIP variable (set by the user). AC_DEFUN([AM_PROG_INSTALL_STRIP], [AC_REQUIRE([AM_PROG_INSTALL_SH])dnl -# Installed binaries are usually stripped using `strip' when the user -# run `make install-strip'. However `strip' might not be the right +# Installed binaries are usually stripped using 'strip' when the user +# run "make install-strip". However 'strip' might not be the right # tool to use in cross-compilation environments, therefore Automake -# will honor the `STRIP' environment variable to overrule this program. -dnl Don't test for $cross_compiling = yes, because it might be `maybe'. +# will honor the 'STRIP' environment variable to overrule this program. +dnl Don't test for $cross_compiling = yes, because it might be 'maybe'. if test "$cross_compiling" != no; then AC_CHECK_TOOL([STRIP], [strip], :) fi INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s" AC_SUBST([INSTALL_STRIP_PROGRAM])]) -# Copyright (C) 2006, 2008 Free Software Foundation, Inc. +# Copyright (C) 2006-2013 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. -# serial 2 - # _AM_SUBST_NOTMAKE(VARIABLE) # --------------------------- # Prevent Automake from outputting VARIABLE = @VARIABLE@ in Makefile.in. @@ -9448,24 +1039,22 @@ AC_SUBST([INSTALL_STRIP_PROGRAM])]) AC_DEFUN([_AM_SUBST_NOTMAKE]) # AM_SUBST_NOTMAKE(VARIABLE) -# --------------------------- +# -------------------------- # Public sister of _AM_SUBST_NOTMAKE. AC_DEFUN([AM_SUBST_NOTMAKE], [_AM_SUBST_NOTMAKE($@)]) # Check how to create a tarball. -*- Autoconf -*- -# Copyright (C) 2004, 2005 Free Software Foundation, Inc. +# Copyright (C) 2004-2013 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. -# serial 2 - # _AM_PROG_TAR(FORMAT) # -------------------- # Check how to create a tarball in format FORMAT. -# FORMAT should be one of `v7', `ustar', or `pax'. +# FORMAT should be one of 'v7', 'ustar', or 'pax'. # # Substitute a variable $(am__tar) that is a command # writing to stdout a FORMAT-tarball containing the directory @@ -9475,76 +1064,120 @@ AC_DEFUN([AM_SUBST_NOTMAKE], [_AM_SUBST_NOTMAKE($@)]) # Substitute a variable $(am__untar) that extract such # a tarball read from stdin. # $(am__untar) < result.tar +# AC_DEFUN([_AM_PROG_TAR], -[# Always define AMTAR for backward compatibility. -AM_MISSING_PROG([AMTAR], [tar]) -m4_if([$1], [v7], - [am__tar='${AMTAR} chof - "$$tardir"'; am__untar='${AMTAR} xf -'], - [m4_case([$1], [ustar],, [pax],, - [m4_fatal([Unknown tar format])]) -AC_MSG_CHECKING([how to create a $1 tar archive]) -# Loop over all known methods to create a tar archive until one works. +[# Always define AMTAR for backward compatibility. Yes, it's still used +# in the wild :-( We should find a proper way to deprecate it ... +AC_SUBST([AMTAR], ['$${TAR-tar}']) + +# We'll loop over all known methods to create a tar archive until one works. _am_tools='gnutar m4_if([$1], [ustar], [plaintar]) pax cpio none' -_am_tools=${am_cv_prog_tar_$1-$_am_tools} -# Do not fold the above two line into one, because Tru64 sh and -# Solaris sh will not grok spaces in the rhs of `-'. -for _am_tool in $_am_tools -do - case $_am_tool in - gnutar) - for _am_tar in tar gnutar gtar; - do - AM_RUN_LOG([$_am_tar --version]) && break - done - am__tar="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$$tardir"' - am__tar_="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$tardir"' - am__untar="$_am_tar -xf -" - ;; - plaintar) - # Must skip GNU tar: if it does not support --format= it doesn't create - # ustar tarball either. - (tar --version) >/dev/null 2>&1 && continue - am__tar='tar chf - "$$tardir"' - am__tar_='tar chf - "$tardir"' - am__untar='tar xf -' - ;; - pax) - am__tar='pax -L -x $1 -w "$$tardir"' - am__tar_='pax -L -x $1 -w "$tardir"' - am__untar='pax -r' - ;; - cpio) - am__tar='find "$$tardir" -print | cpio -o -H $1 -L' - am__tar_='find "$tardir" -print | cpio -o -H $1 -L' - am__untar='cpio -i -H $1 -d' - ;; - none) - am__tar=false - am__tar_=false - am__untar=false - ;; - esac - # If the value was cached, stop now. We just wanted to have am__tar - # and am__untar set. - test -n "${am_cv_prog_tar_$1}" && break +m4_if([$1], [v7], + [am__tar='$${TAR-tar} chof - "$$tardir"' am__untar='$${TAR-tar} xf -'], - # tar/untar a dummy directory, and stop if the command works + [m4_case([$1], + [ustar], + [# The POSIX 1988 'ustar' format is defined with fixed-size fields. + # There is notably a 21 bits limit for the UID and the GID. In fact, + # the 'pax' utility can hang on bigger UID/GID (see automake bug#8343 + # and bug#13588). + am_max_uid=2097151 # 2^21 - 1 + am_max_gid=$am_max_uid + # The $UID and $GID variables are not portable, so we need to resort + # to the POSIX-mandated id(1) utility. Errors in the 'id' calls + # below are definitely unexpected, so allow the users to see them + # (that is, avoid stderr redirection). + am_uid=`id -u || echo unknown` + am_gid=`id -g || echo unknown` + AC_MSG_CHECKING([whether UID '$am_uid' is supported by ustar format]) + if test $am_uid -le $am_max_uid; then + AC_MSG_RESULT([yes]) + else + AC_MSG_RESULT([no]) + _am_tools=none + fi + AC_MSG_CHECKING([whether GID '$am_gid' is supported by ustar format]) + if test $am_gid -le $am_max_gid; then + AC_MSG_RESULT([yes]) + else + AC_MSG_RESULT([no]) + _am_tools=none + fi], + + [pax], + [], + + [m4_fatal([Unknown tar format])]) + + AC_MSG_CHECKING([how to create a $1 tar archive]) + + # Go ahead even if we have the value already cached. We do so because we + # need to set the values for the 'am__tar' and 'am__untar' variables. + _am_tools=${am_cv_prog_tar_$1-$_am_tools} + + for _am_tool in $_am_tools; do + case $_am_tool in + gnutar) + for _am_tar in tar gnutar gtar; do + AM_RUN_LOG([$_am_tar --version]) && break + done + am__tar="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$$tardir"' + am__tar_="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$tardir"' + am__untar="$_am_tar -xf -" + ;; + plaintar) + # Must skip GNU tar: if it does not support --format= it doesn't create + # ustar tarball either. + (tar --version) >/dev/null 2>&1 && continue + am__tar='tar chf - "$$tardir"' + am__tar_='tar chf - "$tardir"' + am__untar='tar xf -' + ;; + pax) + am__tar='pax -L -x $1 -w "$$tardir"' + am__tar_='pax -L -x $1 -w "$tardir"' + am__untar='pax -r' + ;; + cpio) + am__tar='find "$$tardir" -print | cpio -o -H $1 -L' + am__tar_='find "$tardir" -print | cpio -o -H $1 -L' + am__untar='cpio -i -H $1 -d' + ;; + none) + am__tar=false + am__tar_=false + am__untar=false + ;; + esac + + # If the value was cached, stop now. We just wanted to have am__tar + # and am__untar set. + test -n "${am_cv_prog_tar_$1}" && break + + # tar/untar a dummy directory, and stop if the command works. + rm -rf conftest.dir + mkdir conftest.dir + echo GrepMe > conftest.dir/file + AM_RUN_LOG([tardir=conftest.dir && eval $am__tar_ >conftest.tar]) + rm -rf conftest.dir + if test -s conftest.tar; then + AM_RUN_LOG([$am__untar /dev/null 2>&1 && break + fi + done rm -rf conftest.dir - mkdir conftest.dir - echo GrepMe > conftest.dir/file - AM_RUN_LOG([tardir=conftest.dir && eval $am__tar_ >conftest.tar]) - rm -rf conftest.dir - if test -s conftest.tar; then - AM_RUN_LOG([$am__untar /dev/null 2>&1 && break - fi -done -rm -rf conftest.dir -AC_CACHE_VAL([am_cv_prog_tar_$1], [am_cv_prog_tar_$1=$_am_tool]) -AC_MSG_RESULT([$am_cv_prog_tar_$1])]) + AC_CACHE_VAL([am_cv_prog_tar_$1], [am_cv_prog_tar_$1=$_am_tool]) + AC_MSG_RESULT([$am_cv_prog_tar_$1])]) + AC_SUBST([am__tar]) AC_SUBST([am__untar]) ]) # _AM_PROG_TAR +m4_include([m4/libtool.m4]) +m4_include([m4/ltoptions.m4]) +m4_include([m4/ltsugar.m4]) +m4_include([m4/ltversion.m4]) +m4_include([m4/lt~obsolete.m4]) diff --git a/contrib/openpam/autogen.sh b/contrib/openpam/autogen.sh index 64196cdbb6a1..1958dfc958cf 100755 --- a/contrib/openpam/autogen.sh +++ b/contrib/openpam/autogen.sh @@ -1,9 +1,9 @@ #!/bin/sh # -# $Id: autogen.sh 396 2007-10-24 09:58:18Z des $ +# $Id: autogen.sh 709 2013-08-18 14:47:20Z des $ # -aclocal +aclocal -I m4 libtoolize --copy --force autoheader automake -a -c --foreign diff --git a/contrib/openpam/bin/Makefile.am b/contrib/openpam/bin/Makefile.am index ec7a99e06001..489ea82ab1c3 100644 --- a/contrib/openpam/bin/Makefile.am +++ b/contrib/openpam/bin/Makefile.am @@ -1,4 +1,4 @@ -# $Id: Makefile.am 538 2012-03-31 17:04:29Z des $ +# $Id: Makefile.am 648 2013-03-05 17:54:27Z des $ SUBDIRS = openpam_dump_policy diff --git a/contrib/openpam/bin/Makefile.in b/contrib/openpam/bin/Makefile.in index 3c11bbfa92f9..1df083a2498a 100644 --- a/contrib/openpam/bin/Makefile.in +++ b/contrib/openpam/bin/Makefile.in @@ -1,9 +1,8 @@ -# Makefile.in generated by automake 1.11.1 from Makefile.am. +# Makefile.in generated by automake 1.14 from Makefile.am. # @configure_input@ -# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, -# 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation, -# Inc. +# Copyright (C) 1994-2013 Free Software Foundation, Inc. + # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. @@ -15,8 +14,53 @@ @SET_MAKE@ -# $Id: Makefile.am 538 2012-03-31 17:04:29Z des $ +# $Id: Makefile.am 648 2013-03-05 17:54:27Z des $ VPATH = @srcdir@ +am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)' +am__make_running_with_option = \ + case $${target_option-} in \ + ?) ;; \ + *) echo "am__make_running_with_option: internal error: invalid" \ + "target option '$${target_option-}' specified" >&2; \ + exit 1;; \ + esac; \ + has_opt=no; \ + sane_makeflags=$$MAKEFLAGS; \ + if $(am__is_gnu_make); then \ + sane_makeflags=$$MFLAGS; \ + else \ + case $$MAKEFLAGS in \ + *\\[\ \ ]*) \ + bs=\\; \ + sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ + | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ + esac; \ + fi; \ + skip_next=no; \ + strip_trailopt () \ + { \ + flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ + }; \ + for flg in $$sane_makeflags; do \ + test $$skip_next = yes && { skip_next=no; continue; }; \ + case $$flg in \ + *=*|--*) continue;; \ + -*I) strip_trailopt 'I'; skip_next=yes;; \ + -*I?*) strip_trailopt 'I';; \ + -*O) strip_trailopt 'O'; skip_next=yes;; \ + -*O?*) strip_trailopt 'O';; \ + -*l) strip_trailopt 'l'; skip_next=yes;; \ + -*l?*) strip_trailopt 'l';; \ + -[dEDm]) skip_next=yes;; \ + -[JT]) skip_next=yes;; \ + esac; \ + case $$flg in \ + *$$target_option*) has_opt=yes; break;; \ + esac; \ + done; \ + test $$has_opt = yes +am__make_dryrun = (target_option=n; $(am__make_running_with_option)) +am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ @@ -38,29 +82,70 @@ host_triplet = @host@ @WITH_PAMTEST_TRUE@am__append_1 = pamtest @WITH_SU_TRUE@am__append_2 = su subdir = bin -DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in +DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 -am__aclocal_m4_deps = $(top_srcdir)/configure.ac +am__aclocal_m4_deps = $(top_srcdir)/m4/libtool.m4 \ + $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \ + $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \ + $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = +AM_V_P = $(am__v_P_@AM_V@) +am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) +am__v_P_0 = false +am__v_P_1 = : +AM_V_GEN = $(am__v_GEN_@AM_V@) +am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) +am__v_GEN_0 = @echo " GEN " $@; +am__v_GEN_1 = +AM_V_at = $(am__v_at_@AM_V@) +am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) +am__v_at_0 = @ +am__v_at_1 = SOURCES = DIST_SOURCES = -RECURSIVE_TARGETS = all-recursive check-recursive dvi-recursive \ - html-recursive info-recursive install-data-recursive \ - install-dvi-recursive install-exec-recursive \ - install-html-recursive install-info-recursive \ - install-pdf-recursive install-ps-recursive install-recursive \ - installcheck-recursive installdirs-recursive pdf-recursive \ - ps-recursive uninstall-recursive +RECURSIVE_TARGETS = all-recursive check-recursive cscopelist-recursive \ + ctags-recursive dvi-recursive html-recursive info-recursive \ + install-data-recursive install-dvi-recursive \ + install-exec-recursive install-html-recursive \ + install-info-recursive install-pdf-recursive \ + install-ps-recursive install-recursive installcheck-recursive \ + installdirs-recursive pdf-recursive ps-recursive \ + tags-recursive uninstall-recursive +am__can_run_installinfo = \ + case $$AM_UPDATE_INFO_DIR in \ + n|no|NO) false;; \ + *) (install-info --version) >/dev/null 2>&1;; \ + esac RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \ distclean-recursive maintainer-clean-recursive -AM_RECURSIVE_TARGETS = $(RECURSIVE_TARGETS:-recursive=) \ - $(RECURSIVE_CLEAN_TARGETS:-recursive=) tags TAGS ctags CTAGS \ +am__recursive_targets = \ + $(RECURSIVE_TARGETS) \ + $(RECURSIVE_CLEAN_TARGETS) \ + $(am__extra_recursive_targets) +AM_RECURSIVE_TARGETS = $(am__recursive_targets:-recursive=) TAGS CTAGS \ distdir +am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) +# Read a list of newline-separated strings from the standard input, +# and print each of them once, without duplicates. Input order is +# *not* preserved. +am__uniquify_input = $(AWK) '\ + BEGIN { nonempty = 0; } \ + { items[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in items) print i; }; } \ +' +# Make sure the list of sources is unique. This is necessary because, +# e.g., the same source file might be shared among _SOURCES variables +# for different programs/libraries. +am__define_uniq_tagged_files = \ + list='$(am__tagged_files)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | $(am__uniquify_input)` ETAGS = etags CTAGS = ctags DIST_SUBDIRS = openpam_dump_policy pamtest su @@ -92,6 +177,7 @@ am__relativize = \ reldir="$$dir2" ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ +AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ @@ -102,6 +188,7 @@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ +CRYPTO_LIBS = @CRYPTO_LIBS@ CRYPT_LIBS = @CRYPT_LIBS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ @@ -249,22 +336,25 @@ clean-libtool: -rm -rf .libs _libs # This directory's subdirectories are mostly independent; you can cd -# into them and run `make' without going through this Makefile. -# To change the values of `make' variables: instead of editing Makefiles, -# (1) if the variable is set in `config.status', edit `config.status' -# (which will cause the Makefiles to be regenerated when you run `make'); -# (2) otherwise, pass the desired values on the `make' command line. -$(RECURSIVE_TARGETS): - @fail= failcom='exit 1'; \ - for f in x $$MAKEFLAGS; do \ - case $$f in \ - *=* | --[!k]*);; \ - *k*) failcom='fail=yes';; \ - esac; \ - done; \ +# into them and run 'make' without going through this Makefile. +# To change the values of 'make' variables: instead of editing Makefiles, +# (1) if the variable is set in 'config.status', edit 'config.status' +# (which will cause the Makefiles to be regenerated when you run 'make'); +# (2) otherwise, pass the desired values on the 'make' command line. +$(am__recursive_targets): + @fail=; \ + if $(am__make_keepgoing); then \ + failcom='fail=yes'; \ + else \ + failcom='exit 1'; \ + fi; \ dot_seen=no; \ target=`echo $@ | sed s/-recursive//`; \ - list='$(SUBDIRS)'; for subdir in $$list; do \ + case "$@" in \ + distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ + *) list='$(SUBDIRS)' ;; \ + esac; \ + for subdir in $$list; do \ echo "Making $$target in $$subdir"; \ if test "$$subdir" = "."; then \ dot_seen=yes; \ @@ -279,57 +369,12 @@ $(RECURSIVE_TARGETS): $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ fi; test -z "$$fail" -$(RECURSIVE_CLEAN_TARGETS): - @fail= failcom='exit 1'; \ - for f in x $$MAKEFLAGS; do \ - case $$f in \ - *=* | --[!k]*);; \ - *k*) failcom='fail=yes';; \ - esac; \ - done; \ - dot_seen=no; \ - case "$@" in \ - distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ - *) list='$(SUBDIRS)' ;; \ - esac; \ - rev=''; for subdir in $$list; do \ - if test "$$subdir" = "."; then :; else \ - rev="$$subdir $$rev"; \ - fi; \ - done; \ - rev="$$rev ."; \ - target=`echo $@ | sed s/-recursive//`; \ - for subdir in $$rev; do \ - echo "Making $$target in $$subdir"; \ - if test "$$subdir" = "."; then \ - local_target="$$target-am"; \ - else \ - local_target="$$target"; \ - fi; \ - ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ - || eval $$failcom; \ - done && test -z "$$fail" -tags-recursive: - list='$(SUBDIRS)'; for subdir in $$list; do \ - test "$$subdir" = . || ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) tags); \ - done -ctags-recursive: - list='$(SUBDIRS)'; for subdir in $$list; do \ - test "$$subdir" = . || ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) ctags); \ - done +ID: $(am__tagged_files) + $(am__define_uniq_tagged_files); mkid -fID $$unique +tags: tags-recursive +TAGS: tags -ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) - list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ - unique=`for i in $$list; do \ - if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ - done | \ - $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ - END { if (nonempty) { for (i in files) print i; }; }'`; \ - mkid -fID $$unique -tags: TAGS - -TAGS: tags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ - $(TAGS_FILES) $(LISP) +tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \ @@ -345,12 +390,7 @@ TAGS: tags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \ fi; \ done; \ - list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ - unique=`for i in $$list; do \ - if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ - done | \ - $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ - END { if (nonempty) { for (i in files) print i; }; }'`; \ + $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ @@ -362,15 +402,11 @@ TAGS: tags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $$unique; \ fi; \ fi -ctags: CTAGS -CTAGS: ctags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ - $(TAGS_FILES) $(LISP) - list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ - unique=`for i in $$list; do \ - if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ - done | \ - $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ - END { if (nonempty) { for (i in files) print i; }; }'`; \ +ctags: ctags-recursive + +CTAGS: ctags +ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique @@ -379,6 +415,21 @@ GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" +cscopelist: cscopelist-recursive + +cscopelist-am: $(am__tagged_files) + list='$(am__tagged_files)'; \ + case "$(srcdir)" in \ + [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ + *) sdir=$(subdir)/$(srcdir) ;; \ + esac; \ + for i in $$list; do \ + if test -f "$$i"; then \ + echo "$(subdir)/$$i"; \ + else \ + echo "$$sdir/$$i"; \ + fi; \ + done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags @@ -415,13 +466,10 @@ distdir: $(DISTFILES) done @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ - test -d "$(distdir)/$$subdir" \ - || $(MKDIR_P) "$(distdir)/$$subdir" \ - || exit 1; \ - fi; \ - done - @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ - if test "$$subdir" = .; then :; else \ + $(am__make_dryrun) \ + || test -d "$(distdir)/$$subdir" \ + || $(MKDIR_P) "$(distdir)/$$subdir" \ + || exit 1; \ dir1=$$subdir; dir2="$(distdir)/$$subdir"; \ $(am__relativize); \ new_distdir=$$reldir; \ @@ -456,10 +504,15 @@ install-am: all-am installcheck: installcheck-recursive install-strip: - $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ - install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ - `test -z '$(STRIP)' || \ - echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install + if test -z '$(STRIP)'; then \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + install; \ + else \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ + fi mostlyclean-generic: clean-generic: @@ -537,22 +590,20 @@ ps-am: uninstall-am: -.MAKE: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) ctags-recursive \ - install-am install-strip tags-recursive +.MAKE: $(am__recursive_targets) install-am install-strip -.PHONY: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) CTAGS GTAGS \ - all all-am check check-am clean clean-generic clean-libtool \ - ctags ctags-recursive distclean distclean-generic \ - distclean-libtool distclean-tags distdir dvi dvi-am html \ - html-am info info-am install install-am install-data \ - install-data-am install-dvi install-dvi-am install-exec \ - install-exec-am install-html install-html-am install-info \ - install-info-am install-man install-pdf install-pdf-am \ - install-ps install-ps-am install-strip installcheck \ - installcheck-am installdirs installdirs-am maintainer-clean \ - maintainer-clean-generic mostlyclean mostlyclean-generic \ - mostlyclean-libtool pdf pdf-am ps ps-am tags tags-recursive \ - uninstall uninstall-am +.PHONY: $(am__recursive_targets) CTAGS GTAGS TAGS all all-am check \ + check-am clean clean-generic clean-libtool cscopelist-am ctags \ + ctags-am distclean distclean-generic distclean-libtool \ + distclean-tags distdir dvi dvi-am html html-am info info-am \ + install install-am install-data install-data-am install-dvi \ + install-dvi-am install-exec install-exec-am install-html \ + install-html-am install-info install-info-am install-man \ + install-pdf install-pdf-am install-ps install-ps-am \ + install-strip installcheck installcheck-am installdirs \ + installdirs-am maintainer-clean maintainer-clean-generic \ + mostlyclean mostlyclean-generic mostlyclean-libtool pdf pdf-am \ + ps ps-am tags tags-am uninstall uninstall-am # Tell versions [3.59,3.63) of GNU make to not export all variables. diff --git a/contrib/openpam/bin/openpam_dump_policy/Makefile.am b/contrib/openpam/bin/openpam_dump_policy/Makefile.am index a5fda16068bf..59ae86f39fc9 100644 --- a/contrib/openpam/bin/openpam_dump_policy/Makefile.am +++ b/contrib/openpam/bin/openpam_dump_policy/Makefile.am @@ -1,7 +1,7 @@ -# $Id: Makefile.am 538 2012-03-31 17:04:29Z des $ +# $Id: Makefile.am 648 2013-03-05 17:54:27Z des $ -INCLUDES = -I$(top_srcdir)/include -I$(top_srcdir)/lib +AM_CPPFLAGS = -I$(top_srcdir)/include -I$(top_srcdir)/lib/libpam noinst_PROGRAMS = openpam_dump_policy openpam_dump_policy_SOURCES = openpam_dump_policy.c -openpam_dump_policy_LDADD = $(top_builddir)/lib/libpam.la +openpam_dump_policy_LDADD = $(top_builddir)/lib/libpam/libpam.la diff --git a/contrib/openpam/bin/openpam_dump_policy/Makefile.in b/contrib/openpam/bin/openpam_dump_policy/Makefile.in index 54f09a49baa0..3bef96dce3c1 100644 --- a/contrib/openpam/bin/openpam_dump_policy/Makefile.in +++ b/contrib/openpam/bin/openpam_dump_policy/Makefile.in @@ -1,9 +1,8 @@ -# Makefile.in generated by automake 1.11.1 from Makefile.am. +# Makefile.in generated by automake 1.14 from Makefile.am. # @configure_input@ -# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, -# 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation, -# Inc. +# Copyright (C) 1994-2013 Free Software Foundation, Inc. + # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. @@ -15,9 +14,54 @@ @SET_MAKE@ -# $Id: Makefile.am 538 2012-03-31 17:04:29Z des $ +# $Id: Makefile.am 648 2013-03-05 17:54:27Z des $ VPATH = @srcdir@ +am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)' +am__make_running_with_option = \ + case $${target_option-} in \ + ?) ;; \ + *) echo "am__make_running_with_option: internal error: invalid" \ + "target option '$${target_option-}' specified" >&2; \ + exit 1;; \ + esac; \ + has_opt=no; \ + sane_makeflags=$$MAKEFLAGS; \ + if $(am__is_gnu_make); then \ + sane_makeflags=$$MFLAGS; \ + else \ + case $$MAKEFLAGS in \ + *\\[\ \ ]*) \ + bs=\\; \ + sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ + | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ + esac; \ + fi; \ + skip_next=no; \ + strip_trailopt () \ + { \ + flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ + }; \ + for flg in $$sane_makeflags; do \ + test $$skip_next = yes && { skip_next=no; continue; }; \ + case $$flg in \ + *=*|--*) continue;; \ + -*I) strip_trailopt 'I'; skip_next=yes;; \ + -*I?*) strip_trailopt 'I';; \ + -*O) strip_trailopt 'O'; skip_next=yes;; \ + -*O?*) strip_trailopt 'O';; \ + -*l) strip_trailopt 'l'; skip_next=yes;; \ + -*l?*) strip_trailopt 'l';; \ + -[dEDm]) skip_next=yes;; \ + -[JT]) skip_next=yes;; \ + esac; \ + case $$flg in \ + *$$target_option*) has_opt=yes; break;; \ + esac; \ + done; \ + test $$has_opt = yes +am__make_dryrun = (target_option=n; $(am__make_running_with_option)) +am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ @@ -38,9 +82,13 @@ build_triplet = @build@ host_triplet = @host@ noinst_PROGRAMS = openpam_dump_policy$(EXEEXT) subdir = bin/openpam_dump_policy -DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in +DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \ + $(top_srcdir)/depcomp ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 -am__aclocal_m4_deps = $(top_srcdir)/configure.ac +am__aclocal_m4_deps = $(top_srcdir)/m4/libtool.m4 \ + $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \ + $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \ + $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d @@ -50,27 +98,76 @@ CONFIG_CLEAN_VPATH_FILES = PROGRAMS = $(noinst_PROGRAMS) am_openpam_dump_policy_OBJECTS = openpam_dump_policy.$(OBJEXT) openpam_dump_policy_OBJECTS = $(am_openpam_dump_policy_OBJECTS) -openpam_dump_policy_DEPENDENCIES = $(top_builddir)/lib/libpam.la +openpam_dump_policy_DEPENDENCIES = \ + $(top_builddir)/lib/libpam/libpam.la +AM_V_lt = $(am__v_lt_@AM_V@) +am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) +am__v_lt_0 = --silent +am__v_lt_1 = +AM_V_P = $(am__v_P_@AM_V@) +am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) +am__v_P_0 = false +am__v_P_1 = : +AM_V_GEN = $(am__v_GEN_@AM_V@) +am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) +am__v_GEN_0 = @echo " GEN " $@; +am__v_GEN_1 = +AM_V_at = $(am__v_at_@AM_V@) +am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) +am__v_at_0 = @ +am__v_at_1 = DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) depcomp = $(SHELL) $(top_srcdir)/depcomp am__depfiles_maybe = depfiles am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -LTCOMPILE = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ - --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ - $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ + $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ + $(AM_CFLAGS) $(CFLAGS) +AM_V_CC = $(am__v_CC_@AM_V@) +am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) +am__v_CC_0 = @echo " CC " $@; +am__v_CC_1 = CCLD = $(CC) -LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ - --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \ - $(LDFLAGS) -o $@ +LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(AM_LDFLAGS) $(LDFLAGS) -o $@ +AM_V_CCLD = $(am__v_CCLD_@AM_V@) +am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) +am__v_CCLD_0 = @echo " CCLD " $@; +am__v_CCLD_1 = SOURCES = $(openpam_dump_policy_SOURCES) DIST_SOURCES = $(openpam_dump_policy_SOURCES) +am__can_run_installinfo = \ + case $$AM_UPDATE_INFO_DIR in \ + n|no|NO) false;; \ + *) (install-info --version) >/dev/null 2>&1;; \ + esac +am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) +# Read a list of newline-separated strings from the standard input, +# and print each of them once, without duplicates. Input order is +# *not* preserved. +am__uniquify_input = $(AWK) '\ + BEGIN { nonempty = 0; } \ + { items[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in items) print i; }; } \ +' +# Make sure the list of sources is unique. This is necessary because, +# e.g., the same source file might be shared among _SOURCES variables +# for different programs/libraries. +am__define_uniq_tagged_files = \ + list='$(am__tagged_files)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | $(am__uniquify_input)` ETAGS = etags CTAGS = ctags DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ +AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ @@ -81,6 +178,7 @@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ +CRYPTO_LIBS = @CRYPTO_LIBS@ CRYPT_LIBS = @CRYPT_LIBS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ @@ -186,9 +284,9 @@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ -INCLUDES = -I$(top_srcdir)/include -I$(top_srcdir)/lib +AM_CPPFLAGS = -I$(top_srcdir)/include -I$(top_srcdir)/lib/libpam openpam_dump_policy_SOURCES = openpam_dump_policy.c -openpam_dump_policy_LDADD = $(top_builddir)/lib/libpam.la +openpam_dump_policy_LDADD = $(top_builddir)/lib/libpam/libpam.la all: all-am .SUFFIXES: @@ -232,9 +330,10 @@ clean-noinstPROGRAMS: list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \ echo " rm -f" $$list; \ rm -f $$list -openpam_dump_policy$(EXEEXT): $(openpam_dump_policy_OBJECTS) $(openpam_dump_policy_DEPENDENCIES) + +openpam_dump_policy$(EXEEXT): $(openpam_dump_policy_OBJECTS) $(openpam_dump_policy_DEPENDENCIES) $(EXTRA_openpam_dump_policy_DEPENDENCIES) @rm -f openpam_dump_policy$(EXEEXT) - $(LINK) $(openpam_dump_policy_OBJECTS) $(openpam_dump_policy_LDADD) $(LIBS) + $(AM_V_CCLD)$(LINK) $(openpam_dump_policy_OBJECTS) $(openpam_dump_policy_LDADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) @@ -245,25 +344,25 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/openpam_dump_policy.Po@am__quote@ .c.o: -@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(COMPILE) -c $< +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< .c.obj: -@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'` +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` .c.lo: -@am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $< +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< mostlyclean-libtool: -rm -f *.lo @@ -271,26 +370,15 @@ mostlyclean-libtool: clean-libtool: -rm -rf .libs _libs -ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) - list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ - unique=`for i in $$list; do \ - if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ - done | \ - $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ - END { if (nonempty) { for (i in files) print i; }; }'`; \ - mkid -fID $$unique -tags: TAGS +ID: $(am__tagged_files) + $(am__define_uniq_tagged_files); mkid -fID $$unique +tags: tags-am +TAGS: tags -TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ - $(TAGS_FILES) $(LISP) +tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ - list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ - unique=`for i in $$list; do \ - if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ - done | \ - $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ - END { if (nonempty) { for (i in files) print i; }; }'`; \ + $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ @@ -302,15 +390,11 @@ TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $$unique; \ fi; \ fi -ctags: CTAGS -CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ - $(TAGS_FILES) $(LISP) - list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ - unique=`for i in $$list; do \ - if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ - done | \ - $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ - END { if (nonempty) { for (i in files) print i; }; }'`; \ +ctags: ctags-am + +CTAGS: ctags +ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique @@ -319,6 +403,21 @@ GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" +cscopelist: cscopelist-am + +cscopelist-am: $(am__tagged_files) + list='$(am__tagged_files)'; \ + case "$(srcdir)" in \ + [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ + *) sdir=$(subdir)/$(srcdir) ;; \ + esac; \ + for i in $$list; do \ + if test -f "$$i"; then \ + echo "$(subdir)/$$i"; \ + else \ + echo "$$sdir/$$i"; \ + fi; \ + done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags @@ -367,10 +466,15 @@ install-am: all-am installcheck: installcheck-am install-strip: - $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ - install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ - `test -z '$(STRIP)' || \ - echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install + if test -z '$(STRIP)'; then \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + install; \ + else \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ + fi mostlyclean-generic: clean-generic: @@ -455,18 +559,19 @@ uninstall-am: .MAKE: install-am install-strip -.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \ - clean-libtool clean-noinstPROGRAMS ctags distclean \ - distclean-compile distclean-generic distclean-libtool \ - distclean-tags distdir dvi dvi-am html html-am info info-am \ - install install-am install-data install-data-am install-dvi \ - install-dvi-am install-exec install-exec-am install-html \ - install-html-am install-info install-info-am install-man \ - install-pdf install-pdf-am install-ps install-ps-am \ - install-strip installcheck installcheck-am installdirs \ - maintainer-clean maintainer-clean-generic mostlyclean \ - mostlyclean-compile mostlyclean-generic mostlyclean-libtool \ - pdf pdf-am ps ps-am tags uninstall uninstall-am +.PHONY: CTAGS GTAGS TAGS all all-am check check-am clean clean-generic \ + clean-libtool clean-noinstPROGRAMS cscopelist-am ctags \ + ctags-am distclean distclean-compile distclean-generic \ + distclean-libtool distclean-tags distdir dvi dvi-am html \ + html-am info info-am install install-am install-data \ + install-data-am install-dvi install-dvi-am install-exec \ + install-exec-am install-html install-html-am install-info \ + install-info-am install-man install-pdf install-pdf-am \ + install-ps install-ps-am install-strip installcheck \ + installcheck-am installdirs maintainer-clean \ + maintainer-clean-generic mostlyclean mostlyclean-compile \ + mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ + tags tags-am uninstall uninstall-am # Tell versions [3.59,3.63) of GNU make to not export all variables. diff --git a/contrib/openpam/bin/openpam_dump_policy/openpam_dump_policy.c b/contrib/openpam/bin/openpam_dump_policy/openpam_dump_policy.c index b65dbbd0888c..d16289c07a4b 100644 --- a/contrib/openpam/bin/openpam_dump_policy/openpam_dump_policy.c +++ b/contrib/openpam/bin/openpam_dump_policy/openpam_dump_policy.c @@ -6,8 +6,7 @@ * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer - * in this position and unchanged. + * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. @@ -27,7 +26,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: openpam_dump_policy.c 582 2012-04-06 23:23:35Z des $ + * $Id: openpam_dump_policy.c 648 2013-03-05 17:54:27Z des $ */ #ifdef HAVE_CONFIG_H @@ -43,6 +42,7 @@ #include #include "openpam_impl.h" +#include "openpam_asprintf.h" static char * openpam_chain_name(const char *service, pam_facility_t fclt) diff --git a/contrib/openpam/bin/pamtest/Makefile.am b/contrib/openpam/bin/pamtest/Makefile.am index 80694def17a4..c0e4ea9eb817 100644 --- a/contrib/openpam/bin/pamtest/Makefile.am +++ b/contrib/openpam/bin/pamtest/Makefile.am @@ -1,9 +1,9 @@ -# $Id: Makefile.am 471 2011-11-03 09:44:40Z des $ +# $Id: Makefile.am 648 2013-03-05 17:54:27Z des $ -INCLUDES = -I$(top_srcdir)/include +AM_CPPFLAGS = -I$(top_srcdir)/include bin_PROGRAMS = pamtest pamtest_SOURCES = pamtest.c -pamtest_LDADD = $(top_builddir)/lib/libpam.la +pamtest_LDADD = $(top_builddir)/lib/libpam/libpam.la dist_man1_MANS = pamtest.1 diff --git a/contrib/openpam/bin/pamtest/Makefile.in b/contrib/openpam/bin/pamtest/Makefile.in index e5ba2f1dca7b..c9b933f777ae 100644 --- a/contrib/openpam/bin/pamtest/Makefile.in +++ b/contrib/openpam/bin/pamtest/Makefile.in @@ -1,9 +1,8 @@ -# Makefile.in generated by automake 1.11.1 from Makefile.am. +# Makefile.in generated by automake 1.14 from Makefile.am. # @configure_input@ -# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, -# 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation, -# Inc. +# Copyright (C) 1994-2013 Free Software Foundation, Inc. + # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. @@ -15,9 +14,54 @@ @SET_MAKE@ -# $Id: Makefile.am 471 2011-11-03 09:44:40Z des $ +# $Id: Makefile.am 648 2013-03-05 17:54:27Z des $ VPATH = @srcdir@ +am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)' +am__make_running_with_option = \ + case $${target_option-} in \ + ?) ;; \ + *) echo "am__make_running_with_option: internal error: invalid" \ + "target option '$${target_option-}' specified" >&2; \ + exit 1;; \ + esac; \ + has_opt=no; \ + sane_makeflags=$$MAKEFLAGS; \ + if $(am__is_gnu_make); then \ + sane_makeflags=$$MFLAGS; \ + else \ + case $$MAKEFLAGS in \ + *\\[\ \ ]*) \ + bs=\\; \ + sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ + | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ + esac; \ + fi; \ + skip_next=no; \ + strip_trailopt () \ + { \ + flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ + }; \ + for flg in $$sane_makeflags; do \ + test $$skip_next = yes && { skip_next=no; continue; }; \ + case $$flg in \ + *=*|--*) continue;; \ + -*I) strip_trailopt 'I'; skip_next=yes;; \ + -*I?*) strip_trailopt 'I';; \ + -*O) strip_trailopt 'O'; skip_next=yes;; \ + -*O?*) strip_trailopt 'O';; \ + -*l) strip_trailopt 'l'; skip_next=yes;; \ + -*l?*) strip_trailopt 'l';; \ + -[dEDm]) skip_next=yes;; \ + -[JT]) skip_next=yes;; \ + esac; \ + case $$flg in \ + *$$target_option*) has_opt=yes; break;; \ + esac; \ + done; \ + test $$has_opt = yes +am__make_dryrun = (target_option=n; $(am__make_running_with_option)) +am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ @@ -38,10 +82,13 @@ build_triplet = @build@ host_triplet = @host@ bin_PROGRAMS = pamtest$(EXEEXT) subdir = bin/pamtest -DIST_COMMON = $(dist_man1_MANS) $(srcdir)/Makefile.am \ - $(srcdir)/Makefile.in +DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \ + $(top_srcdir)/depcomp $(dist_man1_MANS) ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 -am__aclocal_m4_deps = $(top_srcdir)/configure.ac +am__aclocal_m4_deps = $(top_srcdir)/m4/libtool.m4 \ + $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \ + $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \ + $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d @@ -52,22 +99,52 @@ am__installdirs = "$(DESTDIR)$(bindir)" "$(DESTDIR)$(man1dir)" PROGRAMS = $(bin_PROGRAMS) am_pamtest_OBJECTS = pamtest.$(OBJEXT) pamtest_OBJECTS = $(am_pamtest_OBJECTS) -pamtest_DEPENDENCIES = $(top_builddir)/lib/libpam.la +pamtest_DEPENDENCIES = $(top_builddir)/lib/libpam/libpam.la +AM_V_lt = $(am__v_lt_@AM_V@) +am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) +am__v_lt_0 = --silent +am__v_lt_1 = +AM_V_P = $(am__v_P_@AM_V@) +am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) +am__v_P_0 = false +am__v_P_1 = : +AM_V_GEN = $(am__v_GEN_@AM_V@) +am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) +am__v_GEN_0 = @echo " GEN " $@; +am__v_GEN_1 = +AM_V_at = $(am__v_at_@AM_V@) +am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) +am__v_at_0 = @ +am__v_at_1 = DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) depcomp = $(SHELL) $(top_srcdir)/depcomp am__depfiles_maybe = depfiles am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -LTCOMPILE = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ - --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ - $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ + $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ + $(AM_CFLAGS) $(CFLAGS) +AM_V_CC = $(am__v_CC_@AM_V@) +am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) +am__v_CC_0 = @echo " CC " $@; +am__v_CC_1 = CCLD = $(CC) -LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ - --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \ - $(LDFLAGS) -o $@ +LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(AM_LDFLAGS) $(LDFLAGS) -o $@ +AM_V_CCLD = $(am__v_CCLD_@AM_V@) +am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) +am__v_CCLD_0 = @echo " CCLD " $@; +am__v_CCLD_1 = SOURCES = $(pamtest_SOURCES) DIST_SOURCES = $(pamtest_SOURCES) +am__can_run_installinfo = \ + case $$AM_UPDATE_INFO_DIR in \ + n|no|NO) false;; \ + *) (install-info --version) >/dev/null 2>&1;; \ + esac am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; am__vpath_adj = case $$p in \ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ @@ -89,14 +166,38 @@ am__nobase_list = $(am__nobase_strip_setup); \ am__base_list = \ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' +am__uninstall_files_from_dir = { \ + test -z "$$files" \ + || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ + || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ + $(am__cd) "$$dir" && rm -f $$files; }; \ + } man1dir = $(mandir)/man1 NROFF = nroff MANS = $(dist_man1_MANS) +am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) +# Read a list of newline-separated strings from the standard input, +# and print each of them once, without duplicates. Input order is +# *not* preserved. +am__uniquify_input = $(AWK) '\ + BEGIN { nonempty = 0; } \ + { items[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in items) print i; }; } \ +' +# Make sure the list of sources is unique. This is necessary because, +# e.g., the same source file might be shared among _SOURCES variables +# for different programs/libraries. +am__define_uniq_tagged_files = \ + list='$(am__tagged_files)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | $(am__uniquify_input)` ETAGS = etags CTAGS = ctags DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ +AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ @@ -107,6 +208,7 @@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ +CRYPTO_LIBS = @CRYPTO_LIBS@ CRYPT_LIBS = @CRYPT_LIBS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ @@ -212,9 +314,9 @@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ -INCLUDES = -I$(top_srcdir)/include +AM_CPPFLAGS = -I$(top_srcdir)/include pamtest_SOURCES = pamtest.c -pamtest_LDADD = $(top_builddir)/lib/libpam.la +pamtest_LDADD = $(top_builddir)/lib/libpam/libpam.la dist_man1_MANS = pamtest.1 all: all-am @@ -252,14 +354,19 @@ $(ACLOCAL_M4): $(am__aclocal_m4_deps) $(am__aclocal_m4_deps): install-binPROGRAMS: $(bin_PROGRAMS) @$(NORMAL_INSTALL) - test -z "$(bindir)" || $(MKDIR_P) "$(DESTDIR)$(bindir)" @list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \ + if test -n "$$list"; then \ + echo " $(MKDIR_P) '$(DESTDIR)$(bindir)'"; \ + $(MKDIR_P) "$(DESTDIR)$(bindir)" || exit 1; \ + fi; \ for p in $$list; do echo "$$p $$p"; done | \ sed 's/$(EXEEXT)$$//' | \ - while read p p1; do if test -f $$p || test -f $$p1; \ - then echo "$$p"; echo "$$p"; else :; fi; \ + while read p p1; do if test -f $$p \ + || test -f $$p1 \ + ; then echo "$$p"; echo "$$p"; else :; fi; \ done | \ - sed -e 'p;s,.*/,,;n;h' -e 's|.*|.|' \ + sed -e 'p;s,.*/,,;n;h' \ + -e 's|.*|.|' \ -e 'p;x;s,.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/' | \ sed 'N;N;N;s,\n, ,g' | \ $(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1 } \ @@ -280,7 +387,8 @@ uninstall-binPROGRAMS: @list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \ files=`for p in $$list; do echo "$$p"; done | \ sed -e 'h;s,^.*/,,;s/$(EXEEXT)$$//;$(transform)' \ - -e 's/$$/$(EXEEXT)/' `; \ + -e 's/$$/$(EXEEXT)/' \ + `; \ test -n "$$list" || exit 0; \ echo " ( cd '$(DESTDIR)$(bindir)' && rm -f" $$files ")"; \ cd "$(DESTDIR)$(bindir)" && rm -f $$files @@ -293,9 +401,10 @@ clean-binPROGRAMS: list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \ echo " rm -f" $$list; \ rm -f $$list -pamtest$(EXEEXT): $(pamtest_OBJECTS) $(pamtest_DEPENDENCIES) + +pamtest$(EXEEXT): $(pamtest_OBJECTS) $(pamtest_DEPENDENCIES) $(EXTRA_pamtest_DEPENDENCIES) @rm -f pamtest$(EXEEXT) - $(LINK) $(pamtest_OBJECTS) $(pamtest_LDADD) $(LIBS) + $(AM_V_CCLD)$(LINK) $(pamtest_OBJECTS) $(pamtest_LDADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) @@ -306,25 +415,25 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pamtest.Po@am__quote@ .c.o: -@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(COMPILE) -c $< +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< .c.obj: -@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'` +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` .c.lo: -@am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $< +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< mostlyclean-libtool: -rm -f *.lo @@ -333,9 +442,18 @@ clean-libtool: -rm -rf .libs _libs install-man1: $(dist_man1_MANS) @$(NORMAL_INSTALL) - test -z "$(man1dir)" || $(MKDIR_P) "$(DESTDIR)$(man1dir)" - @list='$(dist_man1_MANS)'; test -n "$(man1dir)" || exit 0; \ - { for i in $$list; do echo "$$i"; done; \ + @list1='$(dist_man1_MANS)'; \ + list2=''; \ + test -n "$(man1dir)" \ + && test -n "`echo $$list1$$list2`" \ + || exit 0; \ + echo " $(MKDIR_P) '$(DESTDIR)$(man1dir)'"; \ + $(MKDIR_P) "$(DESTDIR)$(man1dir)" || exit 1; \ + { for i in $$list1; do echo "$$i"; done; \ + if test -n "$$list2"; then \ + for i in $$list2; do echo "$$i"; done \ + | sed -n '/\.1[a-z]*$$/p'; \ + fi; \ } | while read p; do \ if test -f $$p; then d=; else d="$(srcdir)/"; fi; \ echo "$$d$$p"; echo "$$p"; \ @@ -362,30 +480,17 @@ uninstall-man1: files=`{ for i in $$list; do echo "$$i"; done; \ } | sed -e 's,.*/,,;h;s,.*\.,,;s,^[^1][0-9a-z]*$$,1,;x' \ -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,'`; \ - test -z "$$files" || { \ - echo " ( cd '$(DESTDIR)$(man1dir)' && rm -f" $$files ")"; \ - cd "$(DESTDIR)$(man1dir)" && rm -f $$files; } + dir='$(DESTDIR)$(man1dir)'; $(am__uninstall_files_from_dir) -ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) - list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ - unique=`for i in $$list; do \ - if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ - done | \ - $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ - END { if (nonempty) { for (i in files) print i; }; }'`; \ - mkid -fID $$unique -tags: TAGS +ID: $(am__tagged_files) + $(am__define_uniq_tagged_files); mkid -fID $$unique +tags: tags-am +TAGS: tags -TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ - $(TAGS_FILES) $(LISP) +tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ - list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ - unique=`for i in $$list; do \ - if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ - done | \ - $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ - END { if (nonempty) { for (i in files) print i; }; }'`; \ + $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ @@ -397,15 +502,11 @@ TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $$unique; \ fi; \ fi -ctags: CTAGS -CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ - $(TAGS_FILES) $(LISP) - list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ - unique=`for i in $$list; do \ - if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ - done | \ - $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ - END { if (nonempty) { for (i in files) print i; }; }'`; \ +ctags: ctags-am + +CTAGS: ctags +ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique @@ -414,24 +515,26 @@ GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" +cscopelist: cscopelist-am + +cscopelist-am: $(am__tagged_files) + list='$(am__tagged_files)'; \ + case "$(srcdir)" in \ + [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ + *) sdir=$(subdir)/$(srcdir) ;; \ + esac; \ + for i in $$list; do \ + if test -f "$$i"; then \ + echo "$(subdir)/$$i"; \ + else \ + echo "$$sdir/$$i"; \ + fi; \ + done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(DISTFILES) - @list='$(MANS)'; if test -n "$$list"; then \ - list=`for p in $$list; do \ - if test -f $$p; then d=; else d="$(srcdir)/"; fi; \ - if test -f "$$d$$p"; then echo "$$d$$p"; else :; fi; done`; \ - if test -n "$$list" && \ - grep 'ab help2man is required to generate this page' $$list >/dev/null; then \ - echo "error: found man pages containing the \`missing help2man' replacement text:" >&2; \ - grep -l 'ab help2man is required to generate this page' $$list | sed 's/^/ /' >&2; \ - echo " to fix them, install help2man, remove and regenerate the man pages;" >&2; \ - echo " typically \`make maintainer-clean' will remove them" >&2; \ - exit 1; \ - else :; fi; \ - else :; fi @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ @@ -478,10 +581,15 @@ install-am: all-am installcheck: installcheck-am install-strip: - $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ - install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ - `test -z '$(STRIP)' || \ - echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install + if test -z '$(STRIP)'; then \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + install; \ + else \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ + fi mostlyclean-generic: clean-generic: @@ -567,20 +675,20 @@ uninstall-man: uninstall-man1 .MAKE: install-am install-strip -.PHONY: CTAGS GTAGS all all-am check check-am clean clean-binPROGRAMS \ - clean-generic clean-libtool ctags distclean distclean-compile \ - distclean-generic distclean-libtool distclean-tags distdir dvi \ - dvi-am html html-am info info-am install install-am \ - install-binPROGRAMS install-data install-data-am install-dvi \ - install-dvi-am install-exec install-exec-am install-html \ - install-html-am install-info install-info-am install-man \ - install-man1 install-pdf install-pdf-am install-ps \ - install-ps-am install-strip installcheck installcheck-am \ - installdirs maintainer-clean maintainer-clean-generic \ - mostlyclean mostlyclean-compile mostlyclean-generic \ - mostlyclean-libtool pdf pdf-am ps ps-am tags uninstall \ - uninstall-am uninstall-binPROGRAMS uninstall-man \ - uninstall-man1 +.PHONY: CTAGS GTAGS TAGS all all-am check check-am clean \ + clean-binPROGRAMS clean-generic clean-libtool cscopelist-am \ + ctags ctags-am distclean distclean-compile distclean-generic \ + distclean-libtool distclean-tags distdir dvi dvi-am html \ + html-am info info-am install install-am install-binPROGRAMS \ + install-data install-data-am install-dvi install-dvi-am \ + install-exec install-exec-am install-html install-html-am \ + install-info install-info-am install-man install-man1 \ + install-pdf install-pdf-am install-ps install-ps-am \ + install-strip installcheck installcheck-am installdirs \ + maintainer-clean maintainer-clean-generic mostlyclean \ + mostlyclean-compile mostlyclean-generic mostlyclean-libtool \ + pdf pdf-am ps ps-am tags tags-am uninstall uninstall-am \ + uninstall-binPROGRAMS uninstall-man uninstall-man1 # Tell versions [3.59,3.63) of GNU make to not export all variables. diff --git a/contrib/openpam/bin/pamtest/pamtest.1 b/contrib/openpam/bin/pamtest/pamtest.1 index 5cf2e0c51d9d..76fc99ecd9e2 100644 --- a/contrib/openpam/bin/pamtest/pamtest.1 +++ b/contrib/openpam/bin/pamtest/pamtest.1 @@ -26,9 +26,9 @@ .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" SUCH DAMAGE. .\" -.\" $Id: pamtest.1 610 2012-05-26 14:03:45Z des $ +.\" $Id: pamtest.1 741 2013-09-07 13:34:02Z des $ .\" -.Dd May 26, 2012 +.Dd September 7, 2013 .Dt PAMTEST 1 .Os .Sh NAME @@ -39,6 +39,7 @@ .Op Fl dkMPsv .Op Fl H Ar rhost .Op Fl h Ar host +.Op Fl T Ar timeout .Op Fl t Ar tty .Op Fl U Ar ruser .Op Fl u Ar user @@ -136,6 +137,9 @@ flag when calling the and .Xr pam_close_session 3 primitives. +.It Fl T Ar timeout +Set the conversation timeout (in seconds) for +.Xr openpam_ttyconv 3 . .It Fl t Ar tty Specify the name of the tty. The default is to use the result of calling diff --git a/contrib/openpam/bin/pamtest/pamtest.c b/contrib/openpam/bin/pamtest/pamtest.c index bfc612e72c13..e67bf7766f90 100644 --- a/contrib/openpam/bin/pamtest/pamtest.c +++ b/contrib/openpam/bin/pamtest/pamtest.c @@ -6,8 +6,7 @@ * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer - * in this position and unchanged. + * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. @@ -27,7 +26,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: pamtest.c 595 2012-04-14 14:28:35Z des $ + * $Id: pamtest.c 685 2013-07-11 16:33:34Z des $ */ #ifdef HAVE_CONFIG_H @@ -35,6 +34,7 @@ #endif #include +#include #include #include #include @@ -116,6 +116,7 @@ pt_authenticate(int flags) int pame; flags |= silent; + pt_verbose("pam_authenticate()"); if ((pame = pam_authenticate(pamh, flags)) != PAM_SUCCESS) pt_error(pame, "pam_authenticate()"); return (pame); @@ -130,6 +131,7 @@ pt_acct_mgmt(int flags) int pame; flags |= silent; + pt_verbose("pam_acct_mgmt()"); if ((pame = pam_acct_mgmt(pamh, flags)) != PAM_SUCCESS) pt_error(pame, "pam_acct_mgmt()"); return (pame); @@ -144,6 +146,7 @@ pt_chauthtok(int flags) int pame; flags |= silent; + pt_verbose("pam_chauthtok()"); if ((pame = pam_chauthtok(pamh, flags)) != PAM_SUCCESS) pt_error(pame, "pam_chauthtok()"); return (pame); @@ -158,6 +161,7 @@ pt_setcred(int flags) int pame; flags |= silent; + pt_verbose("pam_setcred()"); if ((pame = pam_setcred(pamh, flags)) != PAM_SUCCESS) pt_error(pame, "pam_setcred()"); return (pame); @@ -172,6 +176,7 @@ pt_open_session(int flags) int pame; flags |= silent; + pt_verbose("pam_open_session()"); if ((pame = pam_open_session(pamh, flags)) != PAM_SUCCESS) pt_error(pame, "pam_open_session()"); return (pame); @@ -186,6 +191,7 @@ pt_close_session(int flags) int pame; flags |= silent; + pt_verbose("pam_close_session()"); if ((pame = pam_close_session(pamh, flags)) != PAM_SUCCESS) pt_error(pame, "pam_close_session()"); return (pame); @@ -269,6 +275,24 @@ usage(void) exit(1); } +/* + * Handle an option that takes an int argument and can be used only once + */ +static void +opt_num_once(int opt, long *num, const char *arg) +{ + char *end; + long l; + + l = strtol(arg, &end, 0); + if (end == optarg || *end != '\0') { + fprintf(stderr, + "The -%c option expects a numeric argument\n", opt); + usage(); + } + *num = l; +} + /* * Handle an option that takes a string argument and can be used only once */ @@ -296,11 +320,12 @@ main(int argc, char *argv[]) const char *user = NULL; const char *service = NULL; const char *tty = NULL; + long timeout = 0; int keepatit = 0; int pame; int opt; - while ((opt = getopt(argc, argv, "dH:h:kMPst:U:u:v")) != -1) + while ((opt = getopt(argc, argv, "dH:h:kMPsT:t:U:u:v")) != -1) switch (opt) { case 'd': openpam_debug++; @@ -325,6 +350,15 @@ main(int argc, char *argv[]) case 's': silent = PAM_SILENT; break; + case 'T': + opt_num_once(opt, &timeout, optarg); + if (timeout < 0 || timeout > INT_MAX) { + fprintf(stderr, + "Invalid conversation timeout\n"); + usage(); + } + openpam_ttyconv_timeout = (int)timeout; + break; case 't': opt_str_once(opt, &tty, optarg); break; @@ -352,6 +386,8 @@ main(int argc, char *argv[]) ++argv; /* defaults */ + if (service == NULL) + service = "pamtest"; if (rhost == NULL) { if (gethostname(hostname, sizeof(hostname)) == -1) err(1, "gethostname()"); diff --git a/contrib/openpam/bin/su/Makefile.am b/contrib/openpam/bin/su/Makefile.am index 50f0cb986e45..52b6cb821bb8 100644 --- a/contrib/openpam/bin/su/Makefile.am +++ b/contrib/openpam/bin/su/Makefile.am @@ -1,9 +1,9 @@ -# $Id: Makefile.am 458 2011-11-02 13:10:25Z des $ +# $Id: Makefile.am 648 2013-03-05 17:54:27Z des $ -INCLUDES = -I$(top_srcdir)/include +AM_CPPFLAGS = -I$(top_srcdir)/include bin_PROGRAMS = su su_SOURCES = su.c -su_LDADD = $(top_builddir)/lib/libpam.la +su_LDADD = $(top_builddir)/lib/libpam/libpam.la dist_man1_MANS = su.1 diff --git a/contrib/openpam/bin/su/Makefile.in b/contrib/openpam/bin/su/Makefile.in index 700d6ca35d6f..7a37fc7e4bd0 100644 --- a/contrib/openpam/bin/su/Makefile.in +++ b/contrib/openpam/bin/su/Makefile.in @@ -1,9 +1,8 @@ -# Makefile.in generated by automake 1.11.1 from Makefile.am. +# Makefile.in generated by automake 1.14 from Makefile.am. # @configure_input@ -# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, -# 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation, -# Inc. +# Copyright (C) 1994-2013 Free Software Foundation, Inc. + # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. @@ -15,9 +14,54 @@ @SET_MAKE@ -# $Id: Makefile.am 458 2011-11-02 13:10:25Z des $ +# $Id: Makefile.am 648 2013-03-05 17:54:27Z des $ VPATH = @srcdir@ +am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)' +am__make_running_with_option = \ + case $${target_option-} in \ + ?) ;; \ + *) echo "am__make_running_with_option: internal error: invalid" \ + "target option '$${target_option-}' specified" >&2; \ + exit 1;; \ + esac; \ + has_opt=no; \ + sane_makeflags=$$MAKEFLAGS; \ + if $(am__is_gnu_make); then \ + sane_makeflags=$$MFLAGS; \ + else \ + case $$MAKEFLAGS in \ + *\\[\ \ ]*) \ + bs=\\; \ + sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ + | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ + esac; \ + fi; \ + skip_next=no; \ + strip_trailopt () \ + { \ + flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ + }; \ + for flg in $$sane_makeflags; do \ + test $$skip_next = yes && { skip_next=no; continue; }; \ + case $$flg in \ + *=*|--*) continue;; \ + -*I) strip_trailopt 'I'; skip_next=yes;; \ + -*I?*) strip_trailopt 'I';; \ + -*O) strip_trailopt 'O'; skip_next=yes;; \ + -*O?*) strip_trailopt 'O';; \ + -*l) strip_trailopt 'l'; skip_next=yes;; \ + -*l?*) strip_trailopt 'l';; \ + -[dEDm]) skip_next=yes;; \ + -[JT]) skip_next=yes;; \ + esac; \ + case $$flg in \ + *$$target_option*) has_opt=yes; break;; \ + esac; \ + done; \ + test $$has_opt = yes +am__make_dryrun = (target_option=n; $(am__make_running_with_option)) +am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ @@ -38,10 +82,13 @@ build_triplet = @build@ host_triplet = @host@ bin_PROGRAMS = su$(EXEEXT) subdir = bin/su -DIST_COMMON = $(dist_man1_MANS) $(srcdir)/Makefile.am \ - $(srcdir)/Makefile.in +DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \ + $(top_srcdir)/depcomp $(dist_man1_MANS) ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 -am__aclocal_m4_deps = $(top_srcdir)/configure.ac +am__aclocal_m4_deps = $(top_srcdir)/m4/libtool.m4 \ + $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \ + $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \ + $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d @@ -52,22 +99,52 @@ am__installdirs = "$(DESTDIR)$(bindir)" "$(DESTDIR)$(man1dir)" PROGRAMS = $(bin_PROGRAMS) am_su_OBJECTS = su.$(OBJEXT) su_OBJECTS = $(am_su_OBJECTS) -su_DEPENDENCIES = $(top_builddir)/lib/libpam.la +su_DEPENDENCIES = $(top_builddir)/lib/libpam/libpam.la +AM_V_lt = $(am__v_lt_@AM_V@) +am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) +am__v_lt_0 = --silent +am__v_lt_1 = +AM_V_P = $(am__v_P_@AM_V@) +am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) +am__v_P_0 = false +am__v_P_1 = : +AM_V_GEN = $(am__v_GEN_@AM_V@) +am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) +am__v_GEN_0 = @echo " GEN " $@; +am__v_GEN_1 = +AM_V_at = $(am__v_at_@AM_V@) +am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) +am__v_at_0 = @ +am__v_at_1 = DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) depcomp = $(SHELL) $(top_srcdir)/depcomp am__depfiles_maybe = depfiles am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -LTCOMPILE = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ - --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ - $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ + $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ + $(AM_CFLAGS) $(CFLAGS) +AM_V_CC = $(am__v_CC_@AM_V@) +am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) +am__v_CC_0 = @echo " CC " $@; +am__v_CC_1 = CCLD = $(CC) -LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ - --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \ - $(LDFLAGS) -o $@ +LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(AM_LDFLAGS) $(LDFLAGS) -o $@ +AM_V_CCLD = $(am__v_CCLD_@AM_V@) +am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) +am__v_CCLD_0 = @echo " CCLD " $@; +am__v_CCLD_1 = SOURCES = $(su_SOURCES) DIST_SOURCES = $(su_SOURCES) +am__can_run_installinfo = \ + case $$AM_UPDATE_INFO_DIR in \ + n|no|NO) false;; \ + *) (install-info --version) >/dev/null 2>&1;; \ + esac am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; am__vpath_adj = case $$p in \ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ @@ -89,14 +166,38 @@ am__nobase_list = $(am__nobase_strip_setup); \ am__base_list = \ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' +am__uninstall_files_from_dir = { \ + test -z "$$files" \ + || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ + || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ + $(am__cd) "$$dir" && rm -f $$files; }; \ + } man1dir = $(mandir)/man1 NROFF = nroff MANS = $(dist_man1_MANS) +am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) +# Read a list of newline-separated strings from the standard input, +# and print each of them once, without duplicates. Input order is +# *not* preserved. +am__uniquify_input = $(AWK) '\ + BEGIN { nonempty = 0; } \ + { items[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in items) print i; }; } \ +' +# Make sure the list of sources is unique. This is necessary because, +# e.g., the same source file might be shared among _SOURCES variables +# for different programs/libraries. +am__define_uniq_tagged_files = \ + list='$(am__tagged_files)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | $(am__uniquify_input)` ETAGS = etags CTAGS = ctags DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ +AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ @@ -107,6 +208,7 @@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ +CRYPTO_LIBS = @CRYPTO_LIBS@ CRYPT_LIBS = @CRYPT_LIBS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ @@ -212,9 +314,9 @@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ -INCLUDES = -I$(top_srcdir)/include +AM_CPPFLAGS = -I$(top_srcdir)/include su_SOURCES = su.c -su_LDADD = $(top_builddir)/lib/libpam.la +su_LDADD = $(top_builddir)/lib/libpam/libpam.la dist_man1_MANS = su.1 all: all-am @@ -252,14 +354,19 @@ $(ACLOCAL_M4): $(am__aclocal_m4_deps) $(am__aclocal_m4_deps): install-binPROGRAMS: $(bin_PROGRAMS) @$(NORMAL_INSTALL) - test -z "$(bindir)" || $(MKDIR_P) "$(DESTDIR)$(bindir)" @list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \ + if test -n "$$list"; then \ + echo " $(MKDIR_P) '$(DESTDIR)$(bindir)'"; \ + $(MKDIR_P) "$(DESTDIR)$(bindir)" || exit 1; \ + fi; \ for p in $$list; do echo "$$p $$p"; done | \ sed 's/$(EXEEXT)$$//' | \ - while read p p1; do if test -f $$p || test -f $$p1; \ - then echo "$$p"; echo "$$p"; else :; fi; \ + while read p p1; do if test -f $$p \ + || test -f $$p1 \ + ; then echo "$$p"; echo "$$p"; else :; fi; \ done | \ - sed -e 'p;s,.*/,,;n;h' -e 's|.*|.|' \ + sed -e 'p;s,.*/,,;n;h' \ + -e 's|.*|.|' \ -e 'p;x;s,.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/' | \ sed 'N;N;N;s,\n, ,g' | \ $(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1 } \ @@ -280,7 +387,8 @@ uninstall-binPROGRAMS: @list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \ files=`for p in $$list; do echo "$$p"; done | \ sed -e 'h;s,^.*/,,;s/$(EXEEXT)$$//;$(transform)' \ - -e 's/$$/$(EXEEXT)/' `; \ + -e 's/$$/$(EXEEXT)/' \ + `; \ test -n "$$list" || exit 0; \ echo " ( cd '$(DESTDIR)$(bindir)' && rm -f" $$files ")"; \ cd "$(DESTDIR)$(bindir)" && rm -f $$files @@ -293,9 +401,10 @@ clean-binPROGRAMS: list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \ echo " rm -f" $$list; \ rm -f $$list -su$(EXEEXT): $(su_OBJECTS) $(su_DEPENDENCIES) + +su$(EXEEXT): $(su_OBJECTS) $(su_DEPENDENCIES) $(EXTRA_su_DEPENDENCIES) @rm -f su$(EXEEXT) - $(LINK) $(su_OBJECTS) $(su_LDADD) $(LIBS) + $(AM_V_CCLD)$(LINK) $(su_OBJECTS) $(su_LDADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) @@ -306,25 +415,25 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/su.Po@am__quote@ .c.o: -@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(COMPILE) -c $< +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< .c.obj: -@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'` +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` .c.lo: -@am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $< +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< mostlyclean-libtool: -rm -f *.lo @@ -333,9 +442,18 @@ clean-libtool: -rm -rf .libs _libs install-man1: $(dist_man1_MANS) @$(NORMAL_INSTALL) - test -z "$(man1dir)" || $(MKDIR_P) "$(DESTDIR)$(man1dir)" - @list='$(dist_man1_MANS)'; test -n "$(man1dir)" || exit 0; \ - { for i in $$list; do echo "$$i"; done; \ + @list1='$(dist_man1_MANS)'; \ + list2=''; \ + test -n "$(man1dir)" \ + && test -n "`echo $$list1$$list2`" \ + || exit 0; \ + echo " $(MKDIR_P) '$(DESTDIR)$(man1dir)'"; \ + $(MKDIR_P) "$(DESTDIR)$(man1dir)" || exit 1; \ + { for i in $$list1; do echo "$$i"; done; \ + if test -n "$$list2"; then \ + for i in $$list2; do echo "$$i"; done \ + | sed -n '/\.1[a-z]*$$/p'; \ + fi; \ } | while read p; do \ if test -f $$p; then d=; else d="$(srcdir)/"; fi; \ echo "$$d$$p"; echo "$$p"; \ @@ -362,30 +480,17 @@ uninstall-man1: files=`{ for i in $$list; do echo "$$i"; done; \ } | sed -e 's,.*/,,;h;s,.*\.,,;s,^[^1][0-9a-z]*$$,1,;x' \ -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,'`; \ - test -z "$$files" || { \ - echo " ( cd '$(DESTDIR)$(man1dir)' && rm -f" $$files ")"; \ - cd "$(DESTDIR)$(man1dir)" && rm -f $$files; } + dir='$(DESTDIR)$(man1dir)'; $(am__uninstall_files_from_dir) -ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) - list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ - unique=`for i in $$list; do \ - if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ - done | \ - $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ - END { if (nonempty) { for (i in files) print i; }; }'`; \ - mkid -fID $$unique -tags: TAGS +ID: $(am__tagged_files) + $(am__define_uniq_tagged_files); mkid -fID $$unique +tags: tags-am +TAGS: tags -TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ - $(TAGS_FILES) $(LISP) +tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ - list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ - unique=`for i in $$list; do \ - if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ - done | \ - $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ - END { if (nonempty) { for (i in files) print i; }; }'`; \ + $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ @@ -397,15 +502,11 @@ TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $$unique; \ fi; \ fi -ctags: CTAGS -CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ - $(TAGS_FILES) $(LISP) - list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ - unique=`for i in $$list; do \ - if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ - done | \ - $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ - END { if (nonempty) { for (i in files) print i; }; }'`; \ +ctags: ctags-am + +CTAGS: ctags +ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique @@ -414,24 +515,26 @@ GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" +cscopelist: cscopelist-am + +cscopelist-am: $(am__tagged_files) + list='$(am__tagged_files)'; \ + case "$(srcdir)" in \ + [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ + *) sdir=$(subdir)/$(srcdir) ;; \ + esac; \ + for i in $$list; do \ + if test -f "$$i"; then \ + echo "$(subdir)/$$i"; \ + else \ + echo "$$sdir/$$i"; \ + fi; \ + done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(DISTFILES) - @list='$(MANS)'; if test -n "$$list"; then \ - list=`for p in $$list; do \ - if test -f $$p; then d=; else d="$(srcdir)/"; fi; \ - if test -f "$$d$$p"; then echo "$$d$$p"; else :; fi; done`; \ - if test -n "$$list" && \ - grep 'ab help2man is required to generate this page' $$list >/dev/null; then \ - echo "error: found man pages containing the \`missing help2man' replacement text:" >&2; \ - grep -l 'ab help2man is required to generate this page' $$list | sed 's/^/ /' >&2; \ - echo " to fix them, install help2man, remove and regenerate the man pages;" >&2; \ - echo " typically \`make maintainer-clean' will remove them" >&2; \ - exit 1; \ - else :; fi; \ - else :; fi @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ @@ -478,10 +581,15 @@ install-am: all-am installcheck: installcheck-am install-strip: - $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ - install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ - `test -z '$(STRIP)' || \ - echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install + if test -z '$(STRIP)'; then \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + install; \ + else \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ + fi mostlyclean-generic: clean-generic: @@ -567,20 +675,20 @@ uninstall-man: uninstall-man1 .MAKE: install-am install-strip -.PHONY: CTAGS GTAGS all all-am check check-am clean clean-binPROGRAMS \ - clean-generic clean-libtool ctags distclean distclean-compile \ - distclean-generic distclean-libtool distclean-tags distdir dvi \ - dvi-am html html-am info info-am install install-am \ - install-binPROGRAMS install-data install-data-am install-dvi \ - install-dvi-am install-exec install-exec-am install-html \ - install-html-am install-info install-info-am install-man \ - install-man1 install-pdf install-pdf-am install-ps \ - install-ps-am install-strip installcheck installcheck-am \ - installdirs maintainer-clean maintainer-clean-generic \ - mostlyclean mostlyclean-compile mostlyclean-generic \ - mostlyclean-libtool pdf pdf-am ps ps-am tags uninstall \ - uninstall-am uninstall-binPROGRAMS uninstall-man \ - uninstall-man1 +.PHONY: CTAGS GTAGS TAGS all all-am check check-am clean \ + clean-binPROGRAMS clean-generic clean-libtool cscopelist-am \ + ctags ctags-am distclean distclean-compile distclean-generic \ + distclean-libtool distclean-tags distdir dvi dvi-am html \ + html-am info info-am install install-am install-binPROGRAMS \ + install-data install-data-am install-dvi install-dvi-am \ + install-exec install-exec-am install-html install-html-am \ + install-info install-info-am install-man install-man1 \ + install-pdf install-pdf-am install-ps install-ps-am \ + install-strip installcheck installcheck-am installdirs \ + maintainer-clean maintainer-clean-generic mostlyclean \ + mostlyclean-compile mostlyclean-generic mostlyclean-libtool \ + pdf pdf-am ps ps-am tags tags-am uninstall uninstall-am \ + uninstall-binPROGRAMS uninstall-man uninstall-man1 # Tell versions [3.59,3.63) of GNU make to not export all variables. diff --git a/contrib/openpam/bin/su/su.1 b/contrib/openpam/bin/su/su.1 index 2dc11bbb1b22..9d328e7fc996 100644 --- a/contrib/openpam/bin/su/su.1 +++ b/contrib/openpam/bin/su/su.1 @@ -26,9 +26,9 @@ .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" SUCH DAMAGE. .\" -.\" $Id: su.1 610 2012-05-26 14:03:45Z des $ +.\" $Id: su.1 741 2013-09-07 13:34:02Z des $ .\" -.Dd May 26, 2012 +.Dd September 7, 2013 .Dt SU 1 .Os .Sh NAME diff --git a/contrib/openpam/bin/su/su.c b/contrib/openpam/bin/su/su.c index d87309ebcbf2..18a3cee75d37 100644 --- a/contrib/openpam/bin/su/su.c +++ b/contrib/openpam/bin/su/su.c @@ -32,7 +32,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: su.c 458 2011-11-02 13:10:25Z des $ + * $Id: su.c 648 2013-03-05 17:54:27Z des $ */ #ifdef HAVE_CONFIG_H diff --git a/contrib/openpam/compile b/contrib/openpam/compile index 1b1d23216958..531136b068ef 100755 --- a/contrib/openpam/compile +++ b/contrib/openpam/compile @@ -1,9 +1,9 @@ #! /bin/sh -# Wrapper for compilers which do not understand `-c -o'. +# Wrapper for compilers which do not understand '-c -o'. -scriptversion=2005-05-14.22 +scriptversion=2012-10-14.11; # UTC -# Copyright (C) 1999, 2000, 2003, 2004, 2005 Free Software Foundation, Inc. +# Copyright (C) 1999-2013 Free Software Foundation, Inc. # Written by Tom Tromey . # # This program is free software; you can redistribute it and/or modify @@ -17,8 +17,7 @@ scriptversion=2005-05-14.22 # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +# along with this program. If not, see . # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a @@ -29,21 +28,224 @@ scriptversion=2005-05-14.22 # bugs to or send patches to # . +nl=' +' + +# We need space, tab and new line, in precisely that order. Quoting is +# there to prevent tools from complaining about whitespace usage. +IFS=" "" $nl" + +file_conv= + +# func_file_conv build_file lazy +# Convert a $build file to $host form and store it in $file +# Currently only supports Windows hosts. If the determined conversion +# type is listed in (the comma separated) LAZY, no conversion will +# take place. +func_file_conv () +{ + file=$1 + case $file in + / | /[!/]*) # absolute file, and not a UNC file + if test -z "$file_conv"; then + # lazily determine how to convert abs files + case `uname -s` in + MINGW*) + file_conv=mingw + ;; + CYGWIN*) + file_conv=cygwin + ;; + *) + file_conv=wine + ;; + esac + fi + case $file_conv/,$2, in + *,$file_conv,*) + ;; + mingw/*) + file=`cmd //C echo "$file " | sed -e 's/"\(.*\) " *$/\1/'` + ;; + cygwin/*) + file=`cygpath -m "$file" || echo "$file"` + ;; + wine/*) + file=`winepath -w "$file" || echo "$file"` + ;; + esac + ;; + esac +} + +# func_cl_dashL linkdir +# Make cl look for libraries in LINKDIR +func_cl_dashL () +{ + func_file_conv "$1" + if test -z "$lib_path"; then + lib_path=$file + else + lib_path="$lib_path;$file" + fi + linker_opts="$linker_opts -LIBPATH:$file" +} + +# func_cl_dashl library +# Do a library search-path lookup for cl +func_cl_dashl () +{ + lib=$1 + found=no + save_IFS=$IFS + IFS=';' + for dir in $lib_path $LIB + do + IFS=$save_IFS + if $shared && test -f "$dir/$lib.dll.lib"; then + found=yes + lib=$dir/$lib.dll.lib + break + fi + if test -f "$dir/$lib.lib"; then + found=yes + lib=$dir/$lib.lib + break + fi + if test -f "$dir/lib$lib.a"; then + found=yes + lib=$dir/lib$lib.a + break + fi + done + IFS=$save_IFS + + if test "$found" != yes; then + lib=$lib.lib + fi +} + +# func_cl_wrapper cl arg... +# Adjust compile command to suit cl +func_cl_wrapper () +{ + # Assume a capable shell + lib_path= + shared=: + linker_opts= + for arg + do + if test -n "$eat"; then + eat= + else + case $1 in + -o) + # configure might choose to run compile as 'compile cc -o foo foo.c'. + eat=1 + case $2 in + *.o | *.[oO][bB][jJ]) + func_file_conv "$2" + set x "$@" -Fo"$file" + shift + ;; + *) + func_file_conv "$2" + set x "$@" -Fe"$file" + shift + ;; + esac + ;; + -I) + eat=1 + func_file_conv "$2" mingw + set x "$@" -I"$file" + shift + ;; + -I*) + func_file_conv "${1#-I}" mingw + set x "$@" -I"$file" + shift + ;; + -l) + eat=1 + func_cl_dashl "$2" + set x "$@" "$lib" + shift + ;; + -l*) + func_cl_dashl "${1#-l}" + set x "$@" "$lib" + shift + ;; + -L) + eat=1 + func_cl_dashL "$2" + ;; + -L*) + func_cl_dashL "${1#-L}" + ;; + -static) + shared=false + ;; + -Wl,*) + arg=${1#-Wl,} + save_ifs="$IFS"; IFS=',' + for flag in $arg; do + IFS="$save_ifs" + linker_opts="$linker_opts $flag" + done + IFS="$save_ifs" + ;; + -Xlinker) + eat=1 + linker_opts="$linker_opts $2" + ;; + -*) + set x "$@" "$1" + shift + ;; + *.cc | *.CC | *.cxx | *.CXX | *.[cC]++) + func_file_conv "$1" + set x "$@" -Tp"$file" + shift + ;; + *.c | *.cpp | *.CPP | *.lib | *.LIB | *.Lib | *.OBJ | *.obj | *.[oO]) + func_file_conv "$1" mingw + set x "$@" "$file" + shift + ;; + *) + set x "$@" "$1" + shift + ;; + esac + fi + shift + done + if test -n "$linker_opts"; then + linker_opts="-link$linker_opts" + fi + exec "$@" $linker_opts + exit 1 +} + +eat= + case $1 in '') - echo "$0: No command. Try \`$0 --help' for more information." 1>&2 + echo "$0: No command. Try '$0 --help' for more information." 1>&2 exit 1; ;; -h | --h*) cat <<\EOF Usage: compile [--help] [--version] PROGRAM [ARGS] -Wrapper for compilers which do not understand `-c -o'. -Remove `-o dest.o' from ARGS, run PROGRAM with the remaining +Wrapper for compilers which do not understand '-c -o'. +Remove '-o dest.o' from ARGS, run PROGRAM with the remaining arguments, and rename the output as expected. If you are trying to build a whole package this is not the -right script to run: please start by reading the file `INSTALL'. +right script to run: please start by reading the file 'INSTALL'. Report bugs to . EOF @@ -53,11 +255,13 @@ EOF echo "compile $scriptversion" exit $? ;; + cl | *[/\\]cl | cl.exe | *[/\\]cl.exe ) + func_cl_wrapper "$@" # Doesn't return... + ;; esac ofile= cfile= -eat= for arg do @@ -66,8 +270,8 @@ do else case $1 in -o) - # configure might choose to run compile as `compile cc -o foo foo.c'. - # So we strip `-o arg' only if arg is an object. + # configure might choose to run compile as 'compile cc -o foo foo.c'. + # So we strip '-o arg' only if arg is an object. eat=1 case $2 in *.o | *.obj) @@ -94,22 +298,22 @@ do done if test -z "$ofile" || test -z "$cfile"; then - # If no `-o' option was seen then we might have been invoked from a + # If no '-o' option was seen then we might have been invoked from a # pattern rule where we don't need one. That is ok -- this is a # normal compilation that the losing compiler can handle. If no - # `.c' file was seen then we are probably linking. That is also + # '.c' file was seen then we are probably linking. That is also # ok. exec "$@" fi # Name of file we expect compiler to create. -cofile=`echo "$cfile" | sed -e 's|^.*/||' -e 's/\.c$/.o/'` +cofile=`echo "$cfile" | sed 's|^.*[\\/]||; s|^[a-zA-Z]:||; s/\.c$/.o/'` # Create the lock directory. -# Note: use `[/.-]' here to ensure that we don't use the same name +# Note: use '[/\\:.-]' here to ensure that we don't use the same name # that we are using for the .o file. Also, base the name on the expected # object file name, since that is what matters with a parallel build. -lockdir=`echo "$cofile" | sed -e 's|[/.-]|_|g'`.d +lockdir=`echo "$cofile" | sed -e 's|[/\\:.-]|_|g'`.d while true; do if mkdir "$lockdir" >/dev/null 2>&1; then break @@ -124,9 +328,9 @@ trap "rmdir '$lockdir'; exit 1" 1 2 15 ret=$? if test -f "$cofile"; then - mv "$cofile" "$ofile" + test "$cofile" = "$ofile" || mv "$cofile" "$ofile" elif test -f "${cofile}bj"; then - mv "${cofile}bj" "$ofile" + test "${cofile}bj" = "$ofile" || mv "${cofile}bj" "$ofile" fi rmdir "$lockdir" @@ -138,5 +342,6 @@ exit $ret # eval: (add-hook 'write-file-hooks 'time-stamp) # time-stamp-start: "scriptversion=" # time-stamp-format: "%:y-%02m-%02d.%02H" -# time-stamp-end: "$" +# time-stamp-time-zone: "UTC" +# time-stamp-end: "; # UTC" # End: diff --git a/contrib/openpam/config.guess b/contrib/openpam/config.guess index 0e30d56e94e0..5a328aabca55 100644 --- a/contrib/openpam/config.guess +++ b/contrib/openpam/config.guess @@ -1,13 +1,12 @@ #! /bin/sh # Attempt to guess a canonical system name. -# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, -# 2000, 2001, 2002, 2003 Free Software Foundation, Inc. +# Copyright 1992-2013 Free Software Foundation, Inc. -timestamp='2003-07-02' +timestamp='2013-05-16' # This file is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2 of the License, or +# the Free Software Foundation; either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, but @@ -16,24 +15,22 @@ timestamp='2003-07-02' # General Public License for more details. # # You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +# along with this program; if not, see . # # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a # configuration script generated by Autoconf, you may include it under -# the same distribution terms that you use for the rest of that program. +# the same distribution terms that you use for the rest of that +# program. This Exception is an additional permission under section 7 +# of the GNU General Public License, version 3 ("GPLv3"). +# +# Originally written by Per Bothner. +# +# You can get the latest version of this script from: +# http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess;hb=HEAD +# +# Please send patches with a ChangeLog entry to config-patches@gnu.org. -# Originally written by Per Bothner . -# Please send patches to . Submit a context -# diff and a properly formatted ChangeLog entry. -# -# This script attempts to guess a canonical system name similar to -# config.sub. If it succeeds, it prints the system name on stdout, and -# exits with 0. Otherwise, it exits with 1. -# -# The plan is that this can be called by configure scripts if you -# don't specify an explicit build system type. me=`echo "$0" | sed -e 's,.*/,,'` @@ -53,8 +50,7 @@ version="\ GNU config.guess ($timestamp) Originally written by Per Bothner. -Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001 -Free Software Foundation, Inc. +Copyright 1992-2013 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." @@ -66,11 +62,11 @@ Try \`$me --help' for more information." while test $# -gt 0 ; do case $1 in --time-stamp | --time* | -t ) - echo "$timestamp" ; exit 0 ;; + echo "$timestamp" ; exit ;; --version | -v ) - echo "$version" ; exit 0 ;; + echo "$version" ; exit ;; --help | --h* | -h ) - echo "$usage"; exit 0 ;; + echo "$usage"; exit ;; -- ) # Stop option processing shift; break ;; - ) # Use stdin as input. @@ -104,7 +100,7 @@ set_cc_for_build=' trap "exitcode=\$?; (rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null) && exit \$exitcode" 0 ; trap "rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null; exit 1" 1 2 13 15 ; : ${TMPDIR=/tmp} ; - { tmp=`(umask 077 && mktemp -d -q "$TMPDIR/cgXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" ; } || + { tmp=`(umask 077 && mktemp -d "$TMPDIR/cgXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" ; } || { test -n "$RANDOM" && tmp=$TMPDIR/cg$$-$RANDOM && (umask 077 && mkdir $tmp) ; } || { tmp=$TMPDIR/cg-$$ && (umask 077 && mkdir $tmp) && echo "Warning: creating insecure temp directory" >&2 ; } || { echo "$me: cannot create a temporary directory in $TMPDIR" >&2 ; exit 1 ; } ; @@ -123,7 +119,7 @@ case $CC_FOR_BUILD,$HOST_CC,$CC in ;; ,,*) CC_FOR_BUILD=$CC ;; ,*,*) CC_FOR_BUILD=$HOST_CC ;; -esac ;' +esac ; set_cc_for_build= ;' # This is needed to find uname on a Pyramid OSx when run in the BSD universe. # (ghazi@noc.rutgers.edu 1994-08-24) @@ -136,12 +132,33 @@ UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown UNAME_SYSTEM=`(uname -s) 2>/dev/null` || UNAME_SYSTEM=unknown UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown +case "${UNAME_SYSTEM}" in +Linux|GNU|GNU/*) + # If the system lacks a compiler, then just pick glibc. + # We could probably try harder. + LIBC=gnu + + eval $set_cc_for_build + cat <<-EOF > $dummy.c + #include + #if defined(__UCLIBC__) + LIBC=uclibc + #elif defined(__dietlibc__) + LIBC=dietlibc + #else + LIBC=gnu + #endif + EOF + eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^LIBC'` + ;; +esac + # Note: order is significant - the case branches are not exclusive. case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in *:NetBSD:*:*) # NetBSD (nbsd) targets should (where applicable) match one or - # more of the tupples: *-*-netbsdelf*, *-*-netbsdaout*, + # more of the tuples: *-*-netbsdelf*, *-*-netbsdaout*, # *-*-netbsdecoff* and *-*-netbsd*. For targets that recently # switched to ELF, *-*-netbsd* would select the old # object file format. This provides both forward @@ -158,6 +175,7 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in arm*) machine=arm-unknown ;; sh3el) machine=shl-unknown ;; sh3eb) machine=sh-unknown ;; + sh5el) machine=sh5le-unknown ;; *) machine=${UNAME_MACHINE_ARCH}-unknown ;; esac # The Operating System including object format, if it has switched @@ -166,7 +184,7 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in arm*|i386|m68k|ns32k|sh3*|sparc|vax) eval $set_cc_for_build if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \ - | grep __ELF__ >/dev/null + | grep -q __ELF__ then # Once all utilities can be ECOFF (netbsdecoff) or a.out (netbsdaout). # Return netbsd for either. FIX? @@ -176,7 +194,7 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in fi ;; *) - os=netbsd + os=netbsd ;; esac # The OS release @@ -196,50 +214,36 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in # contains redundant information, the shorter form: # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used. echo "${machine}-${os}${release}" - exit 0 ;; - amiga:OpenBSD:*:*) - echo m68k-unknown-openbsd${UNAME_RELEASE} - exit 0 ;; - arc:OpenBSD:*:*) - echo mipsel-unknown-openbsd${UNAME_RELEASE} - exit 0 ;; - hp300:OpenBSD:*:*) - echo m68k-unknown-openbsd${UNAME_RELEASE} - exit 0 ;; - mac68k:OpenBSD:*:*) - echo m68k-unknown-openbsd${UNAME_RELEASE} - exit 0 ;; - macppc:OpenBSD:*:*) - echo powerpc-unknown-openbsd${UNAME_RELEASE} - exit 0 ;; - mvme68k:OpenBSD:*:*) - echo m68k-unknown-openbsd${UNAME_RELEASE} - exit 0 ;; - mvme88k:OpenBSD:*:*) - echo m88k-unknown-openbsd${UNAME_RELEASE} - exit 0 ;; - mvmeppc:OpenBSD:*:*) - echo powerpc-unknown-openbsd${UNAME_RELEASE} - exit 0 ;; - pmax:OpenBSD:*:*) - echo mipsel-unknown-openbsd${UNAME_RELEASE} - exit 0 ;; - sgi:OpenBSD:*:*) - echo mipseb-unknown-openbsd${UNAME_RELEASE} - exit 0 ;; - sun3:OpenBSD:*:*) - echo m68k-unknown-openbsd${UNAME_RELEASE} - exit 0 ;; - wgrisc:OpenBSD:*:*) - echo mipsel-unknown-openbsd${UNAME_RELEASE} - exit 0 ;; + exit ;; + *:Bitrig:*:*) + UNAME_MACHINE_ARCH=`arch | sed 's/Bitrig.//'` + echo ${UNAME_MACHINE_ARCH}-unknown-bitrig${UNAME_RELEASE} + exit ;; *:OpenBSD:*:*) - echo ${UNAME_MACHINE}-unknown-openbsd${UNAME_RELEASE} - exit 0 ;; + UNAME_MACHINE_ARCH=`arch | sed 's/OpenBSD.//'` + echo ${UNAME_MACHINE_ARCH}-unknown-openbsd${UNAME_RELEASE} + exit ;; + *:ekkoBSD:*:*) + echo ${UNAME_MACHINE}-unknown-ekkobsd${UNAME_RELEASE} + exit ;; + *:SolidBSD:*:*) + echo ${UNAME_MACHINE}-unknown-solidbsd${UNAME_RELEASE} + exit ;; + macppc:MirBSD:*:*) + echo powerpc-unknown-mirbsd${UNAME_RELEASE} + exit ;; + *:MirBSD:*:*) + echo ${UNAME_MACHINE}-unknown-mirbsd${UNAME_RELEASE} + exit ;; alpha:OSF1:*:*) - if test $UNAME_RELEASE = "V4.0"; then + case $UNAME_RELEASE in + *4.0) UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'` - fi + ;; + *5.*) + UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $4}'` + ;; + esac # According to Compaq, /usr/sbin/psrinfo has been available on # OSF/1 and Tru64 systems produced since 1995. I hope that # covers most systems running today. This code pipes the CPU @@ -277,42 +281,52 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in "EV7.9 (21364A)") UNAME_MACHINE="alphaev79" ;; esac + # A Pn.n version is a patched version. # A Vn.n version is a released version. # A Tn.n version is a released field test version. # A Xn.n version is an unreleased experimental baselevel. # 1.2 uses "1.2" for uname -r. - echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[VTX]//' | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` - exit 0 ;; - Alpha*:OpenVMS:*:*) - echo alpha-hp-vms - exit 0 ;; + echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[PVTX]//' | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` + # Reset EXIT trap before exiting to avoid spurious non-zero exit code. + exitcode=$? + trap '' 0 + exit $exitcode ;; Alpha\ *:Windows_NT*:*) # How do we know it's Interix rather than the generic POSIX subsystem? # Should we change UNAME_MACHINE based on the output of uname instead # of the specific Alpha model? echo alpha-pc-interix - exit 0 ;; + exit ;; 21064:Windows_NT:50:3) echo alpha-dec-winnt3.5 - exit 0 ;; + exit ;; Amiga*:UNIX_System_V:4.0:*) echo m68k-unknown-sysv4 - exit 0;; + exit ;; *:[Aa]miga[Oo][Ss]:*:*) echo ${UNAME_MACHINE}-unknown-amigaos - exit 0 ;; + exit ;; *:[Mm]orph[Oo][Ss]:*:*) echo ${UNAME_MACHINE}-unknown-morphos - exit 0 ;; + exit ;; *:OS/390:*:*) echo i370-ibm-openedition - exit 0 ;; + exit ;; + *:z/VM:*:*) + echo s390-ibm-zvmoe + exit ;; + *:OS400:*:*) + echo powerpc-ibm-os400 + exit ;; arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*) echo arm-acorn-riscix${UNAME_RELEASE} - exit 0;; + exit ;; + arm*:riscos:*:*|arm*:RISCOS:*:*) + echo arm-unknown-riscos + exit ;; SR2?01:HI-UX/MPP:*:* | SR8000:HI-UX/MPP:*:*) echo hppa1.1-hitachi-hiuxmpp - exit 0;; + exit ;; Pyramid*:OSx*:*:* | MIS*:OSx*:*:* | MIS*:SMP_DC-OSx*:*:*) # akee@wpdis03.wpafb.af.mil (Earle F. Ake) contributed MIS and NILE. if test "`(/bin/universe) 2>/dev/null`" = att ; then @@ -320,32 +334,51 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in else echo pyramid-pyramid-bsd fi - exit 0 ;; + exit ;; NILE*:*:*:dcosx) echo pyramid-pyramid-svr4 - exit 0 ;; + exit ;; DRS?6000:unix:4.0:6*) echo sparc-icl-nx6 - exit 0 ;; - DRS?6000:UNIX_SV:4.2*:7*) + exit ;; + DRS?6000:UNIX_SV:4.2*:7* | DRS?6000:isis:4.2*:7*) case `/usr/bin/uname -p` in - sparc) echo sparc-icl-nx7 && exit 0 ;; + sparc) echo sparc-icl-nx7; exit ;; esac ;; + s390x:SunOS:*:*) + echo ${UNAME_MACHINE}-ibm-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit ;; sun4H:SunOS:5.*:*) echo sparc-hal-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` - exit 0 ;; + exit ;; sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*) echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` - exit 0 ;; - i86pc:SunOS:5.*:*) - echo i386-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` - exit 0 ;; + exit ;; + i86pc:AuroraUX:5.*:* | i86xen:AuroraUX:5.*:*) + echo i386-pc-auroraux${UNAME_RELEASE} + exit ;; + i86pc:SunOS:5.*:* | i86xen:SunOS:5.*:*) + eval $set_cc_for_build + SUN_ARCH="i386" + # If there is a compiler, see if it is configured for 64-bit objects. + # Note that the Sun cc does not turn __LP64__ into 1 like gcc does. + # This test works for both compilers. + if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then + if (echo '#ifdef __amd64'; echo IS_64BIT_ARCH; echo '#endif') | \ + (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \ + grep IS_64BIT_ARCH >/dev/null + then + SUN_ARCH="x86_64" + fi + fi + echo ${SUN_ARCH}-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit ;; sun4*:SunOS:6*:*) # According to config.sub, this is the proper way to canonicalize # SunOS6. Hard to guess exactly what SunOS6 will be like, but # it's likely to be more like Solaris than SunOS4. echo sparc-sun-solaris3`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` - exit 0 ;; + exit ;; sun4*:SunOS:*:*) case "`/usr/bin/arch -k`" in Series*|S4*) @@ -354,10 +387,10 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in esac # Japanese Language versions have a version number like `4.1.3-JL'. echo sparc-sun-sunos`echo ${UNAME_RELEASE}|sed -e 's/-/_/'` - exit 0 ;; + exit ;; sun3*:SunOS:*:*) echo m68k-sun-sunos${UNAME_RELEASE} - exit 0 ;; + exit ;; sun*:*:4.2BSD:*) UNAME_RELEASE=`(sed 1q /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null` test "x${UNAME_RELEASE}" = "x" && UNAME_RELEASE=3 @@ -369,10 +402,10 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in echo sparc-sun-sunos${UNAME_RELEASE} ;; esac - exit 0 ;; + exit ;; aushp:SunOS:*:*) echo sparc-auspex-sunos${UNAME_RELEASE} - exit 0 ;; + exit ;; # The situation for MiNT is a little confusing. The machine name # can be virtually everything (everything which is not # "atarist" or "atariste" at least should have a processor @@ -382,38 +415,41 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in # MiNT. But MiNT is downward compatible to TOS, so this should # be no problem. atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*) - echo m68k-atari-mint${UNAME_RELEASE} - exit 0 ;; + echo m68k-atari-mint${UNAME_RELEASE} + exit ;; atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*) echo m68k-atari-mint${UNAME_RELEASE} - exit 0 ;; + exit ;; *falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*) - echo m68k-atari-mint${UNAME_RELEASE} - exit 0 ;; + echo m68k-atari-mint${UNAME_RELEASE} + exit ;; milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*) - echo m68k-milan-mint${UNAME_RELEASE} - exit 0 ;; + echo m68k-milan-mint${UNAME_RELEASE} + exit ;; hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*) - echo m68k-hades-mint${UNAME_RELEASE} - exit 0 ;; + echo m68k-hades-mint${UNAME_RELEASE} + exit ;; *:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*) - echo m68k-unknown-mint${UNAME_RELEASE} - exit 0 ;; + echo m68k-unknown-mint${UNAME_RELEASE} + exit ;; + m68k:machten:*:*) + echo m68k-apple-machten${UNAME_RELEASE} + exit ;; powerpc:machten:*:*) echo powerpc-apple-machten${UNAME_RELEASE} - exit 0 ;; + exit ;; RISC*:Mach:*:*) echo mips-dec-mach_bsd4.3 - exit 0 ;; + exit ;; RISC*:ULTRIX:*:*) echo mips-dec-ultrix${UNAME_RELEASE} - exit 0 ;; + exit ;; VAX*:ULTRIX*:*:*) echo vax-dec-ultrix${UNAME_RELEASE} - exit 0 ;; + exit ;; 2020:CLIX:*:* | 2430:CLIX:*:*) echo clipper-intergraph-clix${UNAME_RELEASE} - exit 0 ;; + exit ;; mips:*:*:UMIPS | mips:*:*:RISCos) eval $set_cc_for_build sed 's/^ //' << EOF >$dummy.c @@ -437,35 +473,36 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in exit (-1); } EOF - $CC_FOR_BUILD -o $dummy $dummy.c \ - && $dummy `echo "${UNAME_RELEASE}" | sed -n 's/\([0-9]*\).*/\1/p'` \ - && exit 0 + $CC_FOR_BUILD -o $dummy $dummy.c && + dummyarg=`echo "${UNAME_RELEASE}" | sed -n 's/\([0-9]*\).*/\1/p'` && + SYSTEM_NAME=`$dummy $dummyarg` && + { echo "$SYSTEM_NAME"; exit; } echo mips-mips-riscos${UNAME_RELEASE} - exit 0 ;; + exit ;; Motorola:PowerMAX_OS:*:*) echo powerpc-motorola-powermax - exit 0 ;; + exit ;; Motorola:*:4.3:PL8-*) echo powerpc-harris-powermax - exit 0 ;; + exit ;; Night_Hawk:*:*:PowerMAX_OS | Synergy:PowerMAX_OS:*:*) echo powerpc-harris-powermax - exit 0 ;; + exit ;; Night_Hawk:Power_UNIX:*:*) echo powerpc-harris-powerunix - exit 0 ;; + exit ;; m88k:CX/UX:7*:*) echo m88k-harris-cxux7 - exit 0 ;; + exit ;; m88k:*:4*:R4*) echo m88k-motorola-sysv4 - exit 0 ;; + exit ;; m88k:*:3*:R3*) echo m88k-motorola-sysv3 - exit 0 ;; + exit ;; AViiON:dgux:*:*) - # DG/UX returns AViiON for all architectures - UNAME_PROCESSOR=`/usr/bin/uname -p` + # DG/UX returns AViiON for all architectures + UNAME_PROCESSOR=`/usr/bin/uname -p` if [ $UNAME_PROCESSOR = mc88100 ] || [ $UNAME_PROCESSOR = mc88110 ] then if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx ] || \ @@ -478,29 +515,29 @@ EOF else echo i586-dg-dgux${UNAME_RELEASE} fi - exit 0 ;; + exit ;; M88*:DolphinOS:*:*) # DolphinOS (SVR3) echo m88k-dolphin-sysv3 - exit 0 ;; + exit ;; M88*:*:R3*:*) # Delta 88k system running SVR3 echo m88k-motorola-sysv3 - exit 0 ;; + exit ;; XD88*:*:*:*) # Tektronix XD88 system running UTekV (SVR3) echo m88k-tektronix-sysv3 - exit 0 ;; + exit ;; Tek43[0-9][0-9]:UTek:*:*) # Tektronix 4300 system running UTek (BSD) echo m68k-tektronix-bsd - exit 0 ;; + exit ;; *:IRIX*:*:*) echo mips-sgi-irix`echo ${UNAME_RELEASE}|sed -e 's/-/_/g'` - exit 0 ;; + exit ;; ????????:AIX?:[12].1:2) # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX. - echo romp-ibm-aix # uname -m gives an 8 hex-code CPU id - exit 0 ;; # Note that: echo "'`uname -s`'" gives 'AIX ' + echo romp-ibm-aix # uname -m gives an 8 hex-code CPU id + exit ;; # Note that: echo "'`uname -s`'" gives 'AIX ' i*86:AIX:*:*) echo i386-ibm-aix - exit 0 ;; + exit ;; ia64:AIX:*:*) if [ -x /usr/bin/oslevel ] ; then IBM_REV=`/usr/bin/oslevel` @@ -508,7 +545,7 @@ EOF IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE} fi echo ${UNAME_MACHINE}-ibm-aix${IBM_REV} - exit 0 ;; + exit ;; *:AIX:2:3) if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then eval $set_cc_for_build @@ -523,15 +560,19 @@ EOF exit(0); } EOF - $CC_FOR_BUILD -o $dummy $dummy.c && $dummy && exit 0 - echo rs6000-ibm-aix3.2.5 + if $CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy` + then + echo "$SYSTEM_NAME" + else + echo rs6000-ibm-aix3.2.5 + fi elif grep bos324 /usr/include/stdio.h >/dev/null 2>&1; then echo rs6000-ibm-aix3.2.4 else echo rs6000-ibm-aix3.2 fi - exit 0 ;; - *:AIX:*:[45]) + exit ;; + *:AIX:*:[4567]) IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | sed 1q | awk '{ print $1 }'` if /usr/sbin/lsattr -El ${IBM_CPU_ID} | grep ' POWER' >/dev/null 2>&1; then IBM_ARCH=rs6000 @@ -544,28 +585,28 @@ EOF IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE} fi echo ${IBM_ARCH}-ibm-aix${IBM_REV} - exit 0 ;; + exit ;; *:AIX:*:*) echo rs6000-ibm-aix - exit 0 ;; + exit ;; ibmrt:4.4BSD:*|romp-ibm:BSD:*) echo romp-ibm-bsd4.4 - exit 0 ;; + exit ;; ibmrt:*BSD:*|romp-ibm:BSD:*) # covers RT/PC BSD and echo romp-ibm-bsd${UNAME_RELEASE} # 4.3 with uname added to - exit 0 ;; # report: romp-ibm BSD 4.3 + exit ;; # report: romp-ibm BSD 4.3 *:BOSX:*:*) echo rs6000-bull-bosx - exit 0 ;; + exit ;; DPX/2?00:B.O.S.:*:*) echo m68k-bull-sysv3 - exit 0 ;; + exit ;; 9000/[34]??:4.3bsd:1.*:*) echo m68k-hp-bsd - exit 0 ;; + exit ;; hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*) echo m68k-hp-bsd4.4 - exit 0 ;; + exit ;; 9000/[34678]??:HP-UX:*:*) HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` case "${UNAME_MACHINE}" in @@ -574,52 +615,52 @@ EOF 9000/[678][0-9][0-9]) if [ -x /usr/bin/getconf ]; then sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null` - sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null` - case "${sc_cpu_version}" in - 523) HP_ARCH="hppa1.0" ;; # CPU_PA_RISC1_0 - 528) HP_ARCH="hppa1.1" ;; # CPU_PA_RISC1_1 - 532) # CPU_PA_RISC2_0 - case "${sc_kernel_bits}" in - 32) HP_ARCH="hppa2.0n" ;; - 64) HP_ARCH="hppa2.0w" ;; + sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null` + case "${sc_cpu_version}" in + 523) HP_ARCH="hppa1.0" ;; # CPU_PA_RISC1_0 + 528) HP_ARCH="hppa1.1" ;; # CPU_PA_RISC1_1 + 532) # CPU_PA_RISC2_0 + case "${sc_kernel_bits}" in + 32) HP_ARCH="hppa2.0n" ;; + 64) HP_ARCH="hppa2.0w" ;; '') HP_ARCH="hppa2.0" ;; # HP-UX 10.20 - esac ;; - esac + esac ;; + esac fi if [ "${HP_ARCH}" = "" ]; then eval $set_cc_for_build - sed 's/^ //' << EOF >$dummy.c + sed 's/^ //' << EOF >$dummy.c - #define _HPUX_SOURCE - #include - #include + #define _HPUX_SOURCE + #include + #include - int main () - { - #if defined(_SC_KERNEL_BITS) - long bits = sysconf(_SC_KERNEL_BITS); - #endif - long cpu = sysconf (_SC_CPU_VERSION); + int main () + { + #if defined(_SC_KERNEL_BITS) + long bits = sysconf(_SC_KERNEL_BITS); + #endif + long cpu = sysconf (_SC_CPU_VERSION); - switch (cpu) - { - case CPU_PA_RISC1_0: puts ("hppa1.0"); break; - case CPU_PA_RISC1_1: puts ("hppa1.1"); break; - case CPU_PA_RISC2_0: - #if defined(_SC_KERNEL_BITS) - switch (bits) - { - case 64: puts ("hppa2.0w"); break; - case 32: puts ("hppa2.0n"); break; - default: puts ("hppa2.0"); break; - } break; - #else /* !defined(_SC_KERNEL_BITS) */ - puts ("hppa2.0"); break; - #endif - default: puts ("hppa1.0"); break; - } - exit (0); - } + switch (cpu) + { + case CPU_PA_RISC1_0: puts ("hppa1.0"); break; + case CPU_PA_RISC1_1: puts ("hppa1.1"); break; + case CPU_PA_RISC2_0: + #if defined(_SC_KERNEL_BITS) + switch (bits) + { + case 64: puts ("hppa2.0w"); break; + case 32: puts ("hppa2.0n"); break; + default: puts ("hppa2.0"); break; + } break; + #else /* !defined(_SC_KERNEL_BITS) */ + puts ("hppa2.0"); break; + #endif + default: puts ("hppa1.0"); break; + } + exit (0); + } EOF (CCOPTS= $CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null) && HP_ARCH=`$dummy` test -z "$HP_ARCH" && HP_ARCH=hppa @@ -627,9 +668,19 @@ EOF esac if [ ${HP_ARCH} = "hppa2.0w" ] then - # avoid double evaluation of $set_cc_for_build - test -n "$CC_FOR_BUILD" || eval $set_cc_for_build - if echo __LP64__ | (CCOPTS= $CC_FOR_BUILD -E -) | grep __LP64__ >/dev/null + eval $set_cc_for_build + + # hppa2.0w-hp-hpux* has a 64-bit kernel and a compiler generating + # 32-bit code. hppa64-hp-hpux* has the same kernel and a compiler + # generating 64-bit code. GNU and HP use different nomenclature: + # + # $ CC_FOR_BUILD=cc ./config.guess + # => hppa2.0w-hp-hpux11.23 + # $ CC_FOR_BUILD="cc +DA2.0w" ./config.guess + # => hppa64-hp-hpux11.23 + + if echo __LP64__ | (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | + grep -q __LP64__ then HP_ARCH="hppa2.0w" else @@ -637,11 +688,11 @@ EOF fi fi echo ${HP_ARCH}-hp-hpux${HPUX_REV} - exit 0 ;; + exit ;; ia64:HP-UX:*:*) HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` echo ia64-hp-hpux${HPUX_REV} - exit 0 ;; + exit ;; 3050*:HI-UX:*:*) eval $set_cc_for_build sed 's/^ //' << EOF >$dummy.c @@ -669,197 +720,171 @@ EOF exit (0); } EOF - $CC_FOR_BUILD -o $dummy $dummy.c && $dummy && exit 0 + $CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy` && + { echo "$SYSTEM_NAME"; exit; } echo unknown-hitachi-hiuxwe2 - exit 0 ;; + exit ;; 9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:* ) echo hppa1.1-hp-bsd - exit 0 ;; + exit ;; 9000/8??:4.3bsd:*:*) echo hppa1.0-hp-bsd - exit 0 ;; + exit ;; *9??*:MPE/iX:*:* | *3000*:MPE/iX:*:*) echo hppa1.0-hp-mpeix - exit 0 ;; + exit ;; hp7??:OSF1:*:* | hp8?[79]:OSF1:*:* ) echo hppa1.1-hp-osf - exit 0 ;; + exit ;; hp8??:OSF1:*:*) echo hppa1.0-hp-osf - exit 0 ;; + exit ;; i*86:OSF1:*:*) if [ -x /usr/sbin/sysversion ] ; then echo ${UNAME_MACHINE}-unknown-osf1mk else echo ${UNAME_MACHINE}-unknown-osf1 fi - exit 0 ;; + exit ;; parisc*:Lites*:*:*) echo hppa1.1-hp-lites - exit 0 ;; + exit ;; C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*) echo c1-convex-bsd - exit 0 ;; + exit ;; C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*) if getsysinfo -f scalar_acc then echo c32-convex-bsd else echo c2-convex-bsd fi - exit 0 ;; + exit ;; C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*) echo c34-convex-bsd - exit 0 ;; + exit ;; C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*) echo c38-convex-bsd - exit 0 ;; + exit ;; C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*) echo c4-convex-bsd - exit 0 ;; + exit ;; CRAY*Y-MP:*:*:*) echo ymp-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' - exit 0 ;; + exit ;; CRAY*[A-Z]90:*:*:*) echo ${UNAME_MACHINE}-cray-unicos${UNAME_RELEASE} \ | sed -e 's/CRAY.*\([A-Z]90\)/\1/' \ -e y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/ \ -e 's/\.[^.]*$/.X/' - exit 0 ;; + exit ;; CRAY*TS:*:*:*) echo t90-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' - exit 0 ;; + exit ;; CRAY*T3E:*:*:*) echo alphaev5-cray-unicosmk${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' - exit 0 ;; + exit ;; CRAY*SV1:*:*:*) echo sv1-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' - exit 0 ;; + exit ;; *:UNICOS/mp:*:*) - echo nv1-cray-unicosmp${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' - exit 0 ;; + echo craynv-cray-unicosmp${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit ;; F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*) FUJITSU_PROC=`uname -m | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` - FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'` - FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'` - echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" - exit 0 ;; + FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'` + FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'` + echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" + exit ;; + 5000:UNIX_System_V:4.*:*) + FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'` + FUJITSU_REL=`echo ${UNAME_RELEASE} | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/ /_/'` + echo "sparc-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" + exit ;; i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*) echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE} - exit 0 ;; + exit ;; sparc*:BSD/OS:*:*) echo sparc-unknown-bsdi${UNAME_RELEASE} - exit 0 ;; + exit ;; *:BSD/OS:*:*) echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE} - exit 0 ;; - *:FreeBSD:*:*|*:GNU/FreeBSD:*:*) - # Determine whether the default compiler uses glibc. - eval $set_cc_for_build - sed 's/^ //' << EOF >$dummy.c - #include - #if __GLIBC__ >= 2 - LIBC=gnu - #else - LIBC= - #endif -EOF - eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep ^LIBC=` - # GNU/FreeBSD systems have a "k" prefix to indicate we are using - # FreeBSD's kernel, but not the complete OS. - case ${LIBC} in gnu) kernel_only='k' ;; esac - echo ${UNAME_MACHINE}-unknown-${kernel_only}freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`${LIBC:+-$LIBC} - exit 0 ;; + exit ;; + *:FreeBSD:*:*) + UNAME_PROCESSOR=`/usr/bin/uname -p` + echo ${UNAME_PROCESSOR}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` + exit ;; i*:CYGWIN*:*) echo ${UNAME_MACHINE}-pc-cygwin - exit 0 ;; - i*:MINGW*:*) + exit ;; + *:MINGW64*:*) + echo ${UNAME_MACHINE}-pc-mingw64 + exit ;; + *:MINGW*:*) echo ${UNAME_MACHINE}-pc-mingw32 - exit 0 ;; + exit ;; + i*:MSYS*:*) + echo ${UNAME_MACHINE}-pc-msys + exit ;; + i*:windows32*:*) + # uname -m includes "-pc" on this system. + echo ${UNAME_MACHINE}-mingw32 + exit ;; i*:PW*:*) echo ${UNAME_MACHINE}-pc-pw32 - exit 0 ;; - x86:Interix*:[34]*) - echo i586-pc-interix${UNAME_RELEASE}|sed -e 's/\..*//' - exit 0 ;; + exit ;; + *:Interix*:*) + case ${UNAME_MACHINE} in + x86) + echo i586-pc-interix${UNAME_RELEASE} + exit ;; + authenticamd | genuineintel | EM64T) + echo x86_64-unknown-interix${UNAME_RELEASE} + exit ;; + IA64) + echo ia64-unknown-interix${UNAME_RELEASE} + exit ;; + esac ;; [345]86:Windows_95:* | [345]86:Windows_98:* | [345]86:Windows_NT:*) echo i${UNAME_MACHINE}-pc-mks - exit 0 ;; + exit ;; + 8664:Windows_NT:*) + echo x86_64-pc-mks + exit ;; i*:Windows_NT*:* | Pentium*:Windows_NT*:*) # How do we know it's Interix rather than the generic POSIX subsystem? # It also conflicts with pre-2.0 versions of AT&T UWIN. Should we # UNAME_MACHINE based on the output of uname instead of i386? echo i586-pc-interix - exit 0 ;; + exit ;; i*:UWIN*:*) echo ${UNAME_MACHINE}-pc-uwin - exit 0 ;; + exit ;; + amd64:CYGWIN*:*:* | x86_64:CYGWIN*:*:*) + echo x86_64-unknown-cygwin + exit ;; p*:CYGWIN*:*) echo powerpcle-unknown-cygwin - exit 0 ;; + exit ;; prep*:SunOS:5.*:*) echo powerpcle-unknown-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` - exit 0 ;; + exit ;; *:GNU:*:*) - echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-gnu`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'` - exit 0 ;; + # the GNU system + echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-${LIBC}`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'` + exit ;; + *:GNU/*:*:*) + # other systems with GNU libc and userland + echo ${UNAME_MACHINE}-unknown-`echo ${UNAME_SYSTEM} | sed 's,^[^/]*/,,' | tr '[A-Z]' '[a-z]'``echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`-${LIBC} + exit ;; i*86:Minix:*:*) echo ${UNAME_MACHINE}-pc-minix - exit 0 ;; - arm*:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-gnu - exit 0 ;; - cris:Linux:*:*) - echo cris-axis-linux-gnu - exit 0 ;; - ia64:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-gnu - exit 0 ;; - m68*:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-gnu - exit 0 ;; - mips:Linux:*:*) - eval $set_cc_for_build - sed 's/^ //' << EOF >$dummy.c - #undef CPU - #undef mips - #undef mipsel - #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL) - CPU=mipsel - #else - #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB) - CPU=mips - #else - CPU= - #endif - #endif -EOF - eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep ^CPU=` - test x"${CPU}" != x && echo "${CPU}-unknown-linux-gnu" && exit 0 - ;; - mips64:Linux:*:*) - eval $set_cc_for_build - sed 's/^ //' << EOF >$dummy.c - #undef CPU - #undef mips64 - #undef mips64el - #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL) - CPU=mips64el - #else - #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB) - CPU=mips64 - #else - CPU= - #endif - #endif -EOF - eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep ^CPU=` - test x"${CPU}" != x && echo "${CPU}-unknown-linux-gnu" && exit 0 - ;; - ppc:Linux:*:*) - echo powerpc-unknown-linux-gnu - exit 0 ;; - ppc64:Linux:*:*) - echo powerpc64-unknown-linux-gnu - exit 0 ;; + exit ;; + aarch64:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + exit ;; + aarch64_be:Linux:*:*) + UNAME_MACHINE=aarch64_be + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + exit ;; alpha:Linux:*:*) case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in EV5) UNAME_MACHINE=alphaev5 ;; @@ -869,121 +894,160 @@ EOF EV6) UNAME_MACHINE=alphaev6 ;; EV67) UNAME_MACHINE=alphaev67 ;; EV68*) UNAME_MACHINE=alphaev68 ;; - esac - objdump --private-headers /bin/sh | grep ld.so.1 >/dev/null - if test "$?" = 0 ; then LIBC="libc1" ; else LIBC="" ; fi - echo ${UNAME_MACHINE}-unknown-linux-gnu${LIBC} - exit 0 ;; - parisc:Linux:*:* | hppa:Linux:*:*) - # Look for CPU level - case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in - PA7*) echo hppa1.1-unknown-linux-gnu ;; - PA8*) echo hppa2.0-unknown-linux-gnu ;; - *) echo hppa-unknown-linux-gnu ;; esac - exit 0 ;; - parisc64:Linux:*:* | hppa64:Linux:*:*) - echo hppa64-unknown-linux-gnu - exit 0 ;; - s390:Linux:*:* | s390x:Linux:*:*) - echo ${UNAME_MACHINE}-ibm-linux - exit 0 ;; - sh64*:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-gnu - exit 0 ;; - sh*:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-gnu - exit 0 ;; - sparc:Linux:*:* | sparc64:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-gnu - exit 0 ;; - x86_64:Linux:*:*) - echo x86_64-unknown-linux-gnu - exit 0 ;; + objdump --private-headers /bin/sh | grep -q ld.so.1 + if test "$?" = 0 ; then LIBC="gnulibc1" ; fi + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + exit ;; + arc:Linux:*:* | arceb:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + exit ;; + arm*:Linux:*:*) + eval $set_cc_for_build + if echo __ARM_EABI__ | $CC_FOR_BUILD -E - 2>/dev/null \ + | grep -q __ARM_EABI__ + then + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + else + if echo __ARM_PCS_VFP | $CC_FOR_BUILD -E - 2>/dev/null \ + | grep -q __ARM_PCS_VFP + then + echo ${UNAME_MACHINE}-unknown-linux-${LIBC}eabi + else + echo ${UNAME_MACHINE}-unknown-linux-${LIBC}eabihf + fi + fi + exit ;; + avr32*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + exit ;; + cris:Linux:*:*) + echo ${UNAME_MACHINE}-axis-linux-${LIBC} + exit ;; + crisv32:Linux:*:*) + echo ${UNAME_MACHINE}-axis-linux-${LIBC} + exit ;; + frv:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + exit ;; + hexagon:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + exit ;; i*86:Linux:*:*) - # The BFD linker knows what the default object file format is, so - # first see if it will tell us. cd to the root directory to prevent - # problems with other programs or directories called `ld' in the path. - # Set LC_ALL=C to ensure ld outputs messages in English. - ld_supported_targets=`cd /; LC_ALL=C ld --help 2>&1 \ - | sed -ne '/supported targets:/!d - s/[ ][ ]*/ /g - s/.*supported targets: *// - s/ .*// - p'` - case "$ld_supported_targets" in - elf32-i386) - TENTATIVE="${UNAME_MACHINE}-pc-linux-gnu" - ;; - a.out-i386-linux) - echo "${UNAME_MACHINE}-pc-linux-gnuaout" - exit 0 ;; - coff-i386) - echo "${UNAME_MACHINE}-pc-linux-gnucoff" - exit 0 ;; - "") - # Either a pre-BFD a.out linker (linux-gnuoldld) or - # one that does not give us useful --help. - echo "${UNAME_MACHINE}-pc-linux-gnuoldld" - exit 0 ;; - esac - # Determine whether the default compiler is a.out or elf + echo ${UNAME_MACHINE}-pc-linux-${LIBC} + exit ;; + ia64:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + exit ;; + m32r*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + exit ;; + m68*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + exit ;; + mips:Linux:*:* | mips64:Linux:*:*) eval $set_cc_for_build sed 's/^ //' << EOF >$dummy.c - #include - #ifdef __ELF__ - # ifdef __GLIBC__ - # if __GLIBC__ >= 2 - LIBC=gnu - # else - LIBC=gnulibc1 - # endif - # else - LIBC=gnulibc1 - # endif + #undef CPU + #undef ${UNAME_MACHINE} + #undef ${UNAME_MACHINE}el + #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL) + CPU=${UNAME_MACHINE}el #else - #ifdef __INTEL_COMPILER - LIBC=gnu + #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB) + CPU=${UNAME_MACHINE} #else - LIBC=gnuaout + CPU= #endif #endif EOF - eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep ^LIBC=` - test x"${LIBC}" != x && echo "${UNAME_MACHINE}-pc-linux-${LIBC}" && exit 0 - test x"${TENTATIVE}" != x && echo "${TENTATIVE}" && exit 0 + eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^CPU'` + test x"${CPU}" != x && { echo "${CPU}-unknown-linux-${LIBC}"; exit; } ;; + or1k:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + exit ;; + or32:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + exit ;; + padre:Linux:*:*) + echo sparc-unknown-linux-${LIBC} + exit ;; + parisc64:Linux:*:* | hppa64:Linux:*:*) + echo hppa64-unknown-linux-${LIBC} + exit ;; + parisc:Linux:*:* | hppa:Linux:*:*) + # Look for CPU level + case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in + PA7*) echo hppa1.1-unknown-linux-${LIBC} ;; + PA8*) echo hppa2.0-unknown-linux-${LIBC} ;; + *) echo hppa-unknown-linux-${LIBC} ;; + esac + exit ;; + ppc64:Linux:*:*) + echo powerpc64-unknown-linux-${LIBC} + exit ;; + ppc:Linux:*:*) + echo powerpc-unknown-linux-${LIBC} + exit ;; + s390:Linux:*:* | s390x:Linux:*:*) + echo ${UNAME_MACHINE}-ibm-linux-${LIBC} + exit ;; + sh64*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + exit ;; + sh*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + exit ;; + sparc:Linux:*:* | sparc64:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + exit ;; + tile*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + exit ;; + vax:Linux:*:*) + echo ${UNAME_MACHINE}-dec-linux-${LIBC} + exit ;; + x86_64:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + exit ;; + xtensa*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + exit ;; i*86:DYNIX/ptx:4*:*) # ptx 4.0 does uname -s correctly, with DYNIX/ptx in there. # earlier versions are messed up and put the nodename in both # sysname and nodename. echo i386-sequent-sysv4 - exit 0 ;; + exit ;; i*86:UNIX_SV:4.2MP:2.*) - # Unixware is an offshoot of SVR4, but it has its own version - # number series starting with 2... - # I am not positive that other SVR4 systems won't match this, + # Unixware is an offshoot of SVR4, but it has its own version + # number series starting with 2... + # I am not positive that other SVR4 systems won't match this, # I just have to hope. -- rms. - # Use sysv4.2uw... so that sysv4* matches it. + # Use sysv4.2uw... so that sysv4* matches it. echo ${UNAME_MACHINE}-pc-sysv4.2uw${UNAME_VERSION} - exit 0 ;; + exit ;; i*86:OS/2:*:*) # If we were able to find `uname', then EMX Unix compatibility # is probably installed. echo ${UNAME_MACHINE}-pc-os2-emx - exit 0 ;; + exit ;; i*86:XTS-300:*:STOP) echo ${UNAME_MACHINE}-unknown-stop - exit 0 ;; + exit ;; i*86:atheos:*:*) echo ${UNAME_MACHINE}-unknown-atheos - exit 0 ;; - i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.0*:*) + exit ;; + i*86:syllable:*:*) + echo ${UNAME_MACHINE}-pc-syllable + exit ;; + i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.[02]*:*) echo i386-unknown-lynxos${UNAME_RELEASE} - exit 0 ;; + exit ;; i*86:*DOS:*:*) echo ${UNAME_MACHINE}-pc-msdosdjgpp - exit 0 ;; + exit ;; i*86:*:4.*:* | i*86:SYSTEM_V:4.*:*) UNAME_REL=`echo ${UNAME_RELEASE} | sed 's/\/MP$//'` if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then @@ -991,15 +1055,16 @@ EOF else echo ${UNAME_MACHINE}-pc-sysv${UNAME_REL} fi - exit 0 ;; - i*86:*:5:[78]*) + exit ;; + i*86:*:5:[678]*) + # UnixWare 7.x, OpenUNIX and OpenServer 6. case `/bin/uname -X | grep "^Machine"` in *486*) UNAME_MACHINE=i486 ;; *Pentium) UNAME_MACHINE=i586 ;; *Pent*|*Celeron) UNAME_MACHINE=i686 ;; esac echo ${UNAME_MACHINE}-unknown-sysv${UNAME_RELEASE}${UNAME_SYSTEM}${UNAME_VERSION} - exit 0 ;; + exit ;; i*86:*:3.2:*) if test -f /usr/options/cb.name; then UNAME_REL=`sed -n 's/.*Version //p' /dev/null 2>&1 ; then echo i860-stardent-sysv${UNAME_RELEASE} # Stardent Vistra i860-SVR4 else # Add other i860-SVR4 vendors below as they are discovered. echo i860-unknown-sysv${UNAME_RELEASE} # Unknown i860-SVR4 fi - exit 0 ;; + exit ;; mini*:CTIX:SYS*5:*) # "miniframe" echo m68010-convergent-sysv - exit 0 ;; + exit ;; mc68k:UNIX:SYSTEM5:3.51m) echo m68k-convergent-sysv - exit 0 ;; + exit ;; M680?0:D-NIX:5.3:*) echo m68k-diab-dnix - exit 0 ;; - M68*:*:R3V[567]*:*) - test -r /sysV68 && echo 'm68k-motorola-sysv' && exit 0 ;; - 3[34]??:*:4.0:3.0 | 3[34]??A:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 3[34]??/*:*:4.0:3.0 | 4400:*:4.0:3.0 | 4850:*:4.0:3.0 | SKA40:*:4.0:3.0 | SDS2:*:4.0:3.0 | SHG2:*:4.0:3.0) + exit ;; + M68*:*:R3V[5678]*:*) + test -r /sysV68 && { echo 'm68k-motorola-sysv'; exit; } ;; + 3[345]??:*:4.0:3.0 | 3[34]??A:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 3[34]??/*:*:4.0:3.0 | 4400:*:4.0:3.0 | 4850:*:4.0:3.0 | SKA40:*:4.0:3.0 | SDS2:*:4.0:3.0 | SHG2:*:4.0:3.0 | S7501*:*:4.0:3.0) OS_REL='' test -r /etc/.relid \ && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid` /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ - && echo i486-ncr-sysv4.3${OS_REL} && exit 0 + && { echo i486-ncr-sysv4.3${OS_REL}; exit; } /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ - && echo i586-ncr-sysv4.3${OS_REL} && exit 0 ;; + && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;; 3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*) - /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ - && echo i486-ncr-sysv4 && exit 0 ;; + /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ + && { echo i486-ncr-sysv4; exit; } ;; + NCR*:*:4.2:* | MPRAS*:*:4.2:*) + OS_REL='.3' + test -r /etc/.relid \ + && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid` + /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ + && { echo i486-ncr-sysv4.3${OS_REL}; exit; } + /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ + && { echo i586-ncr-sysv4.3${OS_REL}; exit; } + /bin/uname -p 2>/dev/null | /bin/grep pteron >/dev/null \ + && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;; m68*:LynxOS:2.*:* | m68*:LynxOS:3.0*:*) echo m68k-unknown-lynxos${UNAME_RELEASE} - exit 0 ;; + exit ;; mc68030:UNIX_System_V:4.*:*) echo m68k-atari-sysv4 - exit 0 ;; + exit ;; TSUNAMI:LynxOS:2.*:*) echo sparc-unknown-lynxos${UNAME_RELEASE} - exit 0 ;; + exit ;; rs6000:LynxOS:2.*:*) echo rs6000-unknown-lynxos${UNAME_RELEASE} - exit 0 ;; - PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.0*:*) + exit ;; + PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.[02]*:*) echo powerpc-unknown-lynxos${UNAME_RELEASE} - exit 0 ;; + exit ;; SM[BE]S:UNIX_SV:*:*) echo mips-dde-sysv${UNAME_RELEASE} - exit 0 ;; + exit ;; RM*:ReliantUNIX-*:*:*) echo mips-sni-sysv4 - exit 0 ;; + exit ;; RM*:SINIX-*:*:*) echo mips-sni-sysv4 - exit 0 ;; + exit ;; *:SINIX-*:*:*) if uname -p 2>/dev/null >/dev/null ; then UNAME_MACHINE=`(uname -p) 2>/dev/null` @@ -1091,68 +1169,99 @@ EOF else echo ns32k-sni-sysv fi - exit 0 ;; - PENTIUM:*:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort - # says - echo i586-unisys-sysv4 - exit 0 ;; + exit ;; + PENTIUM:*:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort + # says + echo i586-unisys-sysv4 + exit ;; *:UNIX_System_V:4*:FTX*) # From Gerald Hewes . # How about differentiating between stratus architectures? -djm echo hppa1.1-stratus-sysv4 - exit 0 ;; + exit ;; *:*:*:FTX*) # From seanf@swdc.stratus.com. echo i860-stratus-sysv4 - exit 0 ;; + exit ;; + i*86:VOS:*:*) + # From Paul.Green@stratus.com. + echo ${UNAME_MACHINE}-stratus-vos + exit ;; *:VOS:*:*) # From Paul.Green@stratus.com. echo hppa1.1-stratus-vos - exit 0 ;; + exit ;; mc68*:A/UX:*:*) echo m68k-apple-aux${UNAME_RELEASE} - exit 0 ;; + exit ;; news*:NEWS-OS:6*:*) echo mips-sony-newsos6 - exit 0 ;; + exit ;; R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*) if [ -d /usr/nec ]; then - echo mips-nec-sysv${UNAME_RELEASE} + echo mips-nec-sysv${UNAME_RELEASE} else - echo mips-unknown-sysv${UNAME_RELEASE} + echo mips-unknown-sysv${UNAME_RELEASE} fi - exit 0 ;; + exit ;; BeBox:BeOS:*:*) # BeOS running on hardware made by Be, PPC only. echo powerpc-be-beos - exit 0 ;; + exit ;; BeMac:BeOS:*:*) # BeOS running on Mac or Mac clone, PPC only. echo powerpc-apple-beos - exit 0 ;; + exit ;; BePC:BeOS:*:*) # BeOS running on Intel PC compatible. echo i586-pc-beos - exit 0 ;; + exit ;; + BePC:Haiku:*:*) # Haiku running on Intel PC compatible. + echo i586-pc-haiku + exit ;; + x86_64:Haiku:*:*) + echo x86_64-unknown-haiku + exit ;; SX-4:SUPER-UX:*:*) echo sx4-nec-superux${UNAME_RELEASE} - exit 0 ;; + exit ;; SX-5:SUPER-UX:*:*) echo sx5-nec-superux${UNAME_RELEASE} - exit 0 ;; + exit ;; SX-6:SUPER-UX:*:*) echo sx6-nec-superux${UNAME_RELEASE} - exit 0 ;; + exit ;; + SX-7:SUPER-UX:*:*) + echo sx7-nec-superux${UNAME_RELEASE} + exit ;; + SX-8:SUPER-UX:*:*) + echo sx8-nec-superux${UNAME_RELEASE} + exit ;; + SX-8R:SUPER-UX:*:*) + echo sx8r-nec-superux${UNAME_RELEASE} + exit ;; Power*:Rhapsody:*:*) echo powerpc-apple-rhapsody${UNAME_RELEASE} - exit 0 ;; + exit ;; *:Rhapsody:*:*) echo ${UNAME_MACHINE}-apple-rhapsody${UNAME_RELEASE} - exit 0 ;; + exit ;; *:Darwin:*:*) - case `uname -p` in - *86) UNAME_PROCESSOR=i686 ;; - powerpc) UNAME_PROCESSOR=powerpc ;; - esac + UNAME_PROCESSOR=`uname -p` || UNAME_PROCESSOR=unknown + eval $set_cc_for_build + if test "$UNAME_PROCESSOR" = unknown ; then + UNAME_PROCESSOR=powerpc + fi + if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then + if (echo '#ifdef __LP64__'; echo IS_64BIT_ARCH; echo '#endif') | \ + (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \ + grep IS_64BIT_ARCH >/dev/null + then + case $UNAME_PROCESSOR in + i386) UNAME_PROCESSOR=x86_64 ;; + powerpc) UNAME_PROCESSOR=powerpc64 ;; + esac + fi + fi echo ${UNAME_PROCESSOR}-apple-darwin${UNAME_RELEASE} - exit 0 ;; + exit ;; *:procnto*:*:* | *:QNX:[0123456789]*:*) UNAME_PROCESSOR=`uname -p` if test "$UNAME_PROCESSOR" = "x86"; then @@ -1160,22 +1269,28 @@ EOF UNAME_MACHINE=pc fi echo ${UNAME_PROCESSOR}-${UNAME_MACHINE}-nto-qnx${UNAME_RELEASE} - exit 0 ;; + exit ;; *:QNX:*:4*) echo i386-pc-qnx - exit 0 ;; - NSR-[DGKLNPTVW]:NONSTOP_KERNEL:*:*) + exit ;; + NEO-?:NONSTOP_KERNEL:*:*) + echo neo-tandem-nsk${UNAME_RELEASE} + exit ;; + NSE-*:NONSTOP_KERNEL:*:*) + echo nse-tandem-nsk${UNAME_RELEASE} + exit ;; + NSR-?:NONSTOP_KERNEL:*:*) echo nsr-tandem-nsk${UNAME_RELEASE} - exit 0 ;; + exit ;; *:NonStop-UX:*:*) echo mips-compaq-nonstopux - exit 0 ;; + exit ;; BS2000:POSIX*:*:*) echo bs2000-siemens-sysv - exit 0 ;; + exit ;; DS/*:UNIX_System_V:*:*) echo ${UNAME_MACHINE}-${UNAME_SYSTEM}-${UNAME_RELEASE} - exit 0 ;; + exit ;; *:Plan9:*:*) # "uname -m" is not consistent, so use $cputype instead. 386 # is converted to i386 for consistency with other x86 @@ -1186,33 +1301,55 @@ EOF UNAME_MACHINE="$cputype" fi echo ${UNAME_MACHINE}-unknown-plan9 - exit 0 ;; + exit ;; *:TOPS-10:*:*) echo pdp10-unknown-tops10 - exit 0 ;; + exit ;; *:TENEX:*:*) echo pdp10-unknown-tenex - exit 0 ;; + exit ;; KS10:TOPS-20:*:* | KL10:TOPS-20:*:* | TYPE4:TOPS-20:*:*) echo pdp10-dec-tops20 - exit 0 ;; + exit ;; XKL-1:TOPS-20:*:* | TYPE5:TOPS-20:*:*) echo pdp10-xkl-tops20 - exit 0 ;; + exit ;; *:TOPS-20:*:*) echo pdp10-unknown-tops20 - exit 0 ;; + exit ;; *:ITS:*:*) echo pdp10-unknown-its - exit 0 ;; + exit ;; SEI:*:*:SEIUX) - echo mips-sei-seiux${UNAME_RELEASE} - exit 0 ;; + echo mips-sei-seiux${UNAME_RELEASE} + exit ;; + *:DragonFly:*:*) + echo ${UNAME_MACHINE}-unknown-dragonfly`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` + exit ;; + *:*VMS:*:*) + UNAME_MACHINE=`(uname -p) 2>/dev/null` + case "${UNAME_MACHINE}" in + A*) echo alpha-dec-vms ; exit ;; + I*) echo ia64-dec-vms ; exit ;; + V*) echo vax-dec-vms ; exit ;; + esac ;; + *:XENIX:*:SysV) + echo i386-pc-xenix + exit ;; + i*86:skyos:*:*) + echo ${UNAME_MACHINE}-pc-skyos`echo ${UNAME_RELEASE}` | sed -e 's/ .*$//' + exit ;; + i*86:rdos:*:*) + echo ${UNAME_MACHINE}-pc-rdos + exit ;; + i*86:AROS:*:*) + echo ${UNAME_MACHINE}-pc-aros + exit ;; + x86_64:VMkernel:*:*) + echo ${UNAME_MACHINE}-unknown-esx + exit ;; esac -#echo '(No uname command or uname output not recognized.)' 1>&2 -#echo "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" 1>&2 - eval $set_cc_for_build cat >$dummy.c < printf ("m68k-sony-newsos%s\n", #ifdef NEWSOS4 - "4" + "4" #else - "" + "" #endif - ); exit (0); + ); exit (0); #endif #endif #if defined (__arm) && defined (__acorn) && defined (__unix) - printf ("arm-acorn-riscix"); exit (0); + printf ("arm-acorn-riscix\n"); exit (0); #endif #if defined (hp300) && !defined (hpux) @@ -1328,11 +1465,12 @@ main () } EOF -$CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null && $dummy && exit 0 +$CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null && SYSTEM_NAME=`$dummy` && + { echo "$SYSTEM_NAME"; exit; } # Apollos put the system type in the environment. -test -d /usr/apollo && { echo ${ISP}-apollo-${SYSTYPE}; exit 0; } +test -d /usr/apollo && { echo ${ISP}-apollo-${SYSTYPE}; exit; } # Convex versions that predate uname can use getsysinfo(1) @@ -1341,22 +1479,22 @@ then case `getsysinfo -f cpu_type` in c1*) echo c1-convex-bsd - exit 0 ;; + exit ;; c2*) if getsysinfo -f scalar_acc then echo c32-convex-bsd else echo c2-convex-bsd fi - exit 0 ;; + exit ;; c34*) echo c34-convex-bsd - exit 0 ;; + exit ;; c38*) echo c38-convex-bsd - exit 0 ;; + exit ;; c4*) echo c4-convex-bsd - exit 0 ;; + exit ;; esac fi @@ -1367,7 +1505,9 @@ This script, last modified $timestamp, has failed to recognize the operating system you are using. It is advised that you download the most up to date version of the config scripts from - ftp://ftp.gnu.org/pub/gnu/config/ + http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess;hb=HEAD +and + http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub;hb=HEAD If the version you run ($0) is already up to date, please send the following data and any information you think might be diff --git a/contrib/openpam/config.h.in b/contrib/openpam/config.h.in index 69f703ca2556..780803efcd81 100644 --- a/contrib/openpam/config.h.in +++ b/contrib/openpam/config.h.in @@ -3,12 +3,18 @@ /* Whether loading unversioned modules support is disabled */ #undef DISABLE_UNVERSIONED_MODULES +/* Define to 1 if you have the `asprintf' function. */ +#undef HAVE_ASPRINTF + /* Define to 1 if you have the header file. */ #undef HAVE_CRYPT_H /* Define to 1 if you have the header file. */ #undef HAVE_DLFCN_H +/* Define to 1 if you have the `dlfunc' function. */ +#undef HAVE_DLFUNC + /* Define to 1 if you have the `fdlopen' function. */ #undef HAVE_FDLOPEN @@ -21,12 +27,18 @@ /* Define to 1 if you have the `crypt' library (-lcrypt). */ #undef HAVE_LIBCRYPT +/* Define to 1 if you have the `crypto' library (-lcrypto). */ +#undef HAVE_LIBCRYPTO + /* Define to 1 if you have the `dl' library (-ldl). */ #undef HAVE_LIBDL /* Define to 1 if you have the header file. */ #undef HAVE_MEMORY_H +/* Define to 1 if you have the `setlogmask' function. */ +#undef HAVE_SETLOGMASK + /* Define to 1 if you have the header file. */ #undef HAVE_STDINT_H @@ -57,6 +69,9 @@ /* Define to 1 if you have the header file. */ #undef HAVE_UNISTD_H +/* Define to 1 if you have the `vasprintf' function. */ +#undef HAVE_VASPRINTF + /* OpenPAM library major number */ #undef LIB_MAJ @@ -64,7 +79,7 @@ */ #undef LT_OBJDIR -/* Turn debugging on by default */ +/* Turn debugging macros on */ #undef OPENPAM_DEBUG /* OpenPAM modules directory */ diff --git a/contrib/openpam/config.sub b/contrib/openpam/config.sub index 9d7f73390549..68e658274f03 100644 --- a/contrib/openpam/config.sub +++ b/contrib/openpam/config.sub @@ -1,42 +1,40 @@ #! /bin/sh # Configuration validation subroutine script. -# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, -# 2000, 2001, 2002, 2003 Free Software Foundation, Inc. +# Copyright 1992-2013 Free Software Foundation, Inc. -timestamp='2003-07-04' +timestamp='2013-04-24' -# This file is (in principle) common to ALL GNU software. -# The presence of a machine in this file suggests that SOME GNU software -# can handle that machine. It does not imply ALL GNU software can. -# -# This file is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2 of the License, or +# This file is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or # (at your option) any later version. # -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. # # You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place - Suite 330, -# Boston, MA 02111-1307, USA. - +# along with this program; if not, see . +# # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a # configuration script generated by Autoconf, you may include it under -# the same distribution terms that you use for the rest of that program. +# the same distribution terms that you use for the rest of that +# program. This Exception is an additional permission under section 7 +# of the GNU General Public License, version 3 ("GPLv3"). -# Please send patches to . Submit a context -# diff and a properly formatted ChangeLog entry. + +# Please send patches with a ChangeLog entry to config-patches@gnu.org. # # Configuration subroutine to validate and canonicalize a configuration type. # Supply the specified configuration type as an argument. # If it is invalid, we print an error message on stderr and exit with code 1. # Otherwise, we print the canonical config type on stdout and succeed. +# You can get the latest version of this script from: +# http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub;hb=HEAD + # This file is supposed to be the same for all GNU packages # and recognize all the CPU types, system types and aliases # that are meaningful with *any* GNU software. @@ -70,8 +68,7 @@ Report bugs and patches to ." version="\ GNU config.sub ($timestamp) -Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001 -Free Software Foundation, Inc. +Copyright 1992-2013 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." @@ -83,11 +80,11 @@ Try \`$me --help' for more information." while test $# -gt 0 ; do case $1 in --time-stamp | --time* | -t ) - echo "$timestamp" ; exit 0 ;; + echo "$timestamp" ; exit ;; --version | -v ) - echo "$version" ; exit 0 ;; + echo "$version" ; exit ;; --help | --h* | -h ) - echo "$usage"; exit 0 ;; + echo "$usage"; exit ;; -- ) # Stop option processing shift; break ;; - ) # Use stdin as input. @@ -99,7 +96,7 @@ while test $# -gt 0 ; do *local*) # First pass through any local machine types. echo $1 - exit 0;; + exit ;; * ) break ;; @@ -118,10 +115,18 @@ esac # Here we must recognize all the valid KERNEL-OS combinations. maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'` case $maybe_os in - nto-qnx* | linux-gnu* | kfreebsd*-gnu* | netbsd*-gnu* | storm-chaos* | os2-emx* | rtmk-nova*) + nto-qnx* | linux-gnu* | linux-android* | linux-dietlibc | linux-newlib* | \ + linux-musl* | linux-uclibc* | uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | \ + knetbsd*-gnu* | netbsd*-gnu* | \ + kopensolaris*-gnu* | \ + storm-chaos* | os2-emx* | rtmk-nova*) os=-$maybe_os basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'` ;; + android-linux) + os=-linux-android + basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`-unknown + ;; *) basic_machine=`echo $1 | sed 's/-[^-]*$//'` if [ $basic_machine != $1 ] @@ -144,10 +149,13 @@ case $os in -convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\ -c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \ -harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \ - -apple | -axis) + -apple | -axis | -knuth | -cray | -microblaze*) os= basic_machine=$1 ;; + -bluegene*) + os=-cnk + ;; -sim | -cisco | -oki | -wec | -winbond) os= basic_machine=$1 @@ -162,13 +170,17 @@ case $os in os=-chorusos basic_machine=$1 ;; - -chorusrdb) - os=-chorusrdb + -chorusrdb) + os=-chorusrdb basic_machine=$1 - ;; + ;; -hiux*) os=-hiuxwe2 ;; + -sco6) + os=-sco5v6 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; -sco5) os=-sco3.2v5 basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` @@ -185,6 +197,10 @@ case $os in # Don't forget version if it is 3.2v4 or newer. basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; + -sco5v6*) + # Don't forget version if it is 3.2v4 or newer. + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; -sco*) os=-sco3.2v2 basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` @@ -202,6 +218,12 @@ case $os in -isc*) basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; + -lynx*178) + os=-lynxos178 + ;; + -lynx*5) + os=-lynxos5 + ;; -lynx*) os=-lynxos ;; @@ -226,55 +248,106 @@ case $basic_machine in # Some are omitted here because they have special meanings below. 1750a | 580 \ | a29k \ + | aarch64 | aarch64_be \ | alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \ | alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \ - | arc | arm | arm[bl]e | arme[lb] | armv[2345] | armv[345][lb] | avr \ + | am33_2.0 \ + | arc | arceb \ + | arm | arm[bl]e | arme[lb] | armv[2-8] | armv[3-8][lb] | armv7[arm] \ + | avr | avr32 \ + | be32 | be64 \ + | bfin \ | c4x | clipper \ | d10v | d30v | dlx | dsp16xx \ - | fr30 | frv \ + | epiphany \ + | fido | fr30 | frv \ | h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \ + | hexagon \ | i370 | i860 | i960 | ia64 \ - | ip2k \ - | m32r | m68000 | m68k | m88k | mcore \ + | ip2k | iq2000 \ + | le32 | le64 \ + | lm32 \ + | m32c | m32r | m32rle | m68000 | m68k | m88k \ + | maxq | mb | microblaze | microblazeel | mcore | mep | metag \ | mips | mipsbe | mipseb | mipsel | mipsle \ | mips16 \ | mips64 | mips64el \ - | mips64vr | mips64vrel \ + | mips64octeon | mips64octeonel \ | mips64orion | mips64orionel \ + | mips64r5900 | mips64r5900el \ + | mips64vr | mips64vrel \ | mips64vr4100 | mips64vr4100el \ | mips64vr4300 | mips64vr4300el \ | mips64vr5000 | mips64vr5000el \ + | mips64vr5900 | mips64vr5900el \ | mipsisa32 | mipsisa32el \ | mipsisa32r2 | mipsisa32r2el \ | mipsisa64 | mipsisa64el \ + | mipsisa64r2 | mipsisa64r2el \ | mipsisa64sb1 | mipsisa64sb1el \ | mipsisa64sr71k | mipsisa64sr71kel \ + | mipsr5900 | mipsr5900el \ | mipstx39 | mipstx39el \ | mn10200 | mn10300 \ + | moxie \ + | mt \ | msp430 \ + | nds32 | nds32le | nds32be \ + | nios | nios2 | nios2eb | nios2el \ | ns16k | ns32k \ - | openrisc | or32 \ + | open8 \ + | or1k | or32 \ | pdp10 | pdp11 | pj | pjl \ - | powerpc | powerpc64 | powerpc64le | powerpcle | ppcbe \ + | powerpc | powerpc64 | powerpc64le | powerpcle \ | pyramid \ - | sh | sh[1234] | sh[23]e | sh[34]eb | shbe | shle | sh[1234]le | sh3ele \ + | rl78 | rx \ + | score \ + | sh | sh[1234] | sh[24]a | sh[24]aeb | sh[23]e | sh[34]eb | sheb | shbe | shle | sh[1234]le | sh3ele \ | sh64 | sh64le \ - | sparc | sparc64 | sparc86x | sparclet | sparclite | sparcv9 | sparcv9b \ - | strongarm \ - | tahoe | thumb | tic4x | tic80 | tron \ - | v850 | v850e \ + | sparc | sparc64 | sparc64b | sparc64v | sparc86x | sparclet | sparclite \ + | sparcv8 | sparcv9 | sparcv9b | sparcv9v \ + | spu \ + | tahoe | tic4x | tic54x | tic55x | tic6x | tic80 | tron \ + | ubicom32 \ + | v850 | v850e | v850e1 | v850e2 | v850es | v850e2v3 \ | we32k \ - | x86 | xscale | xstormy16 | xtensa \ - | z8k) + | x86 | xc16x | xstormy16 | xtensa \ + | z8k | z80) basic_machine=$basic_machine-unknown ;; - m6811 | m68hc11 | m6812 | m68hc12) - # Motorola 68HC11/12. + c54x) + basic_machine=tic54x-unknown + ;; + c55x) + basic_machine=tic55x-unknown + ;; + c6x) + basic_machine=tic6x-unknown + ;; + m6811 | m68hc11 | m6812 | m68hc12 | m68hcs12x | picochip) basic_machine=$basic_machine-unknown os=-none ;; m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | v70 | w65 | z8k) ;; + ms1) + basic_machine=mt-unknown + ;; + + strongarm | thumb | xscale) + basic_machine=arm-unknown + ;; + xgate) + basic_machine=$basic_machine-unknown + os=-none + ;; + xscaleeb) + basic_machine=armeb-unknown + ;; + + xscaleel) + basic_machine=armel-unknown + ;; # We use `pc' rather than `unknown' # because (1) that's what they normally are, and @@ -290,58 +363,82 @@ case $basic_machine in # Recognize the basic CPU types with company name. 580-* \ | a29k-* \ + | aarch64-* | aarch64_be-* \ | alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \ | alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \ - | alphapca5[67]-* | alpha64pca5[67]-* | amd64-* | arc-* \ + | alphapca5[67]-* | alpha64pca5[67]-* | amd64-* | arc-* | arceb-* \ | arm-* | armbe-* | armle-* | armeb-* | armv*-* \ - | avr-* \ - | bs2000-* \ - | c[123]* | c30-* | [cjt]90-* | c4x-* | c54x-* | c55x-* | c6x-* \ - | clipper-* | cydra-* \ + | avr-* | avr32-* \ + | be32-* | be64-* \ + | bfin-* | bs2000-* \ + | c[123]* | c30-* | [cjt]90-* | c4x-* \ + | clipper-* | craynv-* | cydra-* \ | d10v-* | d30v-* | dlx-* \ | elxsi-* \ - | f30[01]-* | f700-* | fr30-* | frv-* | fx80-* \ + | f30[01]-* | f700-* | fido-* | fr30-* | frv-* | fx80-* \ | h8300-* | h8500-* \ | hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \ + | hexagon-* \ | i*86-* | i860-* | i960-* | ia64-* \ - | ip2k-* \ - | m32r-* \ + | ip2k-* | iq2000-* \ + | le32-* | le64-* \ + | lm32-* \ + | m32c-* | m32r-* | m32rle-* \ | m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \ - | m88110-* | m88k-* | mcore-* \ + | m88110-* | m88k-* | maxq-* | mcore-* | metag-* \ + | microblaze-* | microblazeel-* \ | mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \ | mips16-* \ | mips64-* | mips64el-* \ - | mips64vr-* | mips64vrel-* \ + | mips64octeon-* | mips64octeonel-* \ | mips64orion-* | mips64orionel-* \ + | mips64r5900-* | mips64r5900el-* \ + | mips64vr-* | mips64vrel-* \ | mips64vr4100-* | mips64vr4100el-* \ | mips64vr4300-* | mips64vr4300el-* \ | mips64vr5000-* | mips64vr5000el-* \ + | mips64vr5900-* | mips64vr5900el-* \ | mipsisa32-* | mipsisa32el-* \ | mipsisa32r2-* | mipsisa32r2el-* \ | mipsisa64-* | mipsisa64el-* \ + | mipsisa64r2-* | mipsisa64r2el-* \ | mipsisa64sb1-* | mipsisa64sb1el-* \ | mipsisa64sr71k-* | mipsisa64sr71kel-* \ + | mipsr5900-* | mipsr5900el-* \ | mipstx39-* | mipstx39el-* \ + | mmix-* \ + | mt-* \ | msp430-* \ - | none-* | np1-* | nv1-* | ns16k-* | ns32k-* \ + | nds32-* | nds32le-* | nds32be-* \ + | nios-* | nios2-* | nios2eb-* | nios2el-* \ + | none-* | np1-* | ns16k-* | ns32k-* \ + | open8-* \ | orion-* \ | pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \ - | powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* | ppcbe-* \ + | powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* \ | pyramid-* \ - | romp-* | rs6000-* \ - | sh-* | sh[1234]-* | sh[23]e-* | sh[34]eb-* | shbe-* \ + | rl78-* | romp-* | rs6000-* | rx-* \ + | sh-* | sh[1234]-* | sh[24]a-* | sh[24]aeb-* | sh[23]e-* | sh[34]eb-* | sheb-* | shbe-* \ | shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \ - | sparc-* | sparc64-* | sparc86x-* | sparclet-* | sparclite-* \ - | sparcv9-* | sparcv9b-* | strongarm-* | sv1-* | sx?-* \ - | tahoe-* | thumb-* \ + | sparc-* | sparc64-* | sparc64b-* | sparc64v-* | sparc86x-* | sparclet-* \ + | sparclite-* \ + | sparcv8-* | sparcv9-* | sparcv9b-* | sparcv9v-* | sv1-* | sx?-* \ + | tahoe-* \ | tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* \ + | tile*-* \ | tron-* \ - | v850-* | v850e-* | vax-* \ + | ubicom32-* \ + | v850-* | v850e-* | v850e1-* | v850es-* | v850e2-* | v850e2v3-* \ + | vax-* \ | we32k-* \ - | x86-* | x86_64-* | xps100-* | xscale-* | xstormy16-* \ - | xtensa-* \ + | x86-* | x86_64-* | xc16x-* | xps100-* \ + | xstormy16-* | xtensa*-* \ | ymp-* \ - | z8k-*) + | z8k-* | z80-*) + ;; + # Recognize the basic CPU types without company name, with glob match. + xtensa*) + basic_machine=$basic_machine-unknown ;; # Recognize the various machine names and aliases which stand # for a CPU type and a company and sometimes even an OS. @@ -359,6 +456,9 @@ case $basic_machine in basic_machine=a29k-amd os=-udi ;; + abacus) + basic_machine=abacus-unknown + ;; adobe68k) basic_machine=m68010-adobe os=-scout @@ -373,9 +473,6 @@ case $basic_machine in basic_machine=a29k-none os=-bsd ;; - amd64) - basic_machine=x86_64-pc - ;; amdahl) basic_machine=580-amdahl os=-sysv @@ -399,6 +496,10 @@ case $basic_machine in basic_machine=m68k-apollo os=-bsd ;; + aros) + basic_machine=i386-pc + os=-aros + ;; aux) basic_machine=m68k-apple os=-aux @@ -407,10 +508,35 @@ case $basic_machine in basic_machine=ns32k-sequent os=-dynix ;; + blackfin) + basic_machine=bfin-unknown + os=-linux + ;; + blackfin-*) + basic_machine=bfin-`echo $basic_machine | sed 's/^[^-]*-//'` + os=-linux + ;; + bluegene*) + basic_machine=powerpc-ibm + os=-cnk + ;; + c54x-*) + basic_machine=tic54x-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + c55x-*) + basic_machine=tic55x-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + c6x-*) + basic_machine=tic6x-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; c90) basic_machine=c90-cray os=-unicos ;; + cegcc) + basic_machine=arm-unknown + os=-cegcc + ;; convex-c1) basic_machine=c1-convex os=-bsd @@ -435,12 +561,27 @@ case $basic_machine in basic_machine=j90-cray os=-unicos ;; + craynv) + basic_machine=craynv-cray + os=-unicosmp + ;; + cr16 | cr16-*) + basic_machine=cr16-unknown + os=-elf + ;; crds | unos) basic_machine=m68k-crds ;; + crisv32 | crisv32-* | etraxfs*) + basic_machine=crisv32-axis + ;; cris | cris-* | etrax*) basic_machine=cris-axis ;; + crx) + basic_machine=crx-unknown + os=-elf + ;; da30 | da30-*) basic_machine=m68k-da30 ;; @@ -463,6 +604,14 @@ case $basic_machine in basic_machine=m88k-motorola os=-sysv3 ;; + dicos) + basic_machine=i686-pc + os=-dicos + ;; + djgpp) + basic_machine=i586-pc + os=-msdosdjgpp + ;; dpx20 | dpx20-*) basic_machine=rs6000-bull os=-bosx @@ -574,7 +723,6 @@ case $basic_machine in i370-ibm* | ibm*) basic_machine=i370-ibm ;; -# I'm not sure what "Sysv32" means. Should this be sysv3.2? i*86v32) basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` os=-sysv32 @@ -613,6 +761,14 @@ case $basic_machine in basic_machine=m68k-isi os=-sysv ;; + m68knommu) + basic_machine=m68k-unknown + os=-linux + ;; + m68knommu-*) + basic_machine=m68k-`echo $basic_machine | sed 's/^[^-]*-//'` + os=-linux + ;; m88k-omron*) basic_machine=m88k-omron ;; @@ -624,10 +780,21 @@ case $basic_machine in basic_machine=ns32k-utek os=-sysv ;; + microblaze*) + basic_machine=microblaze-xilinx + ;; + mingw64) + basic_machine=x86_64-pc + os=-mingw64 + ;; mingw32) basic_machine=i386-pc os=-mingw32 ;; + mingw32ce) + basic_machine=arm-unknown + os=-mingw32ce + ;; miniframe) basic_machine=m68000-convergent ;; @@ -641,10 +808,6 @@ case $basic_machine in mips3*) basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`-unknown ;; - mmix*) - basic_machine=mmix-knuth - os=-mmixware - ;; monitor) basic_machine=m68k-rom68k os=-coff @@ -657,10 +820,21 @@ case $basic_machine in basic_machine=i386-pc os=-msdos ;; + ms1-*) + basic_machine=`echo $basic_machine | sed -e 's/ms1-/mt-/'` + ;; + msys) + basic_machine=i386-pc + os=-msys + ;; mvs) basic_machine=i370-ibm os=-mvs ;; + nacl) + basic_machine=le32-unknown + os=-nacl + ;; ncr3000) basic_machine=i486-ncr os=-sysv4 @@ -725,9 +899,11 @@ case $basic_machine in np1) basic_machine=np1-gould ;; - nv1) - basic_machine=nv1-cray - os=-unicosmp + neo-tandem) + basic_machine=neo-tandem + ;; + nse-tandem) + basic_machine=nse-tandem ;; nsr-tandem) basic_machine=nsr-tandem @@ -736,9 +912,12 @@ case $basic_machine in basic_machine=hppa1.1-oki os=-proelf ;; - or32 | or32-*) + openrisc | openrisc-*) basic_machine=or32-unknown - os=-coff + ;; + os400) + basic_machine=powerpc-ibm + os=-os400 ;; OSE68000 | ose68000) basic_machine=m68000-ericsson @@ -756,6 +935,14 @@ case $basic_machine in basic_machine=i860-intel os=-osf ;; + parisc) + basic_machine=hppa-unknown + os=-linux + ;; + parisc-*) + basic_machine=hppa-`echo $basic_machine | sed 's/^[^-]*-//'` + os=-linux + ;; pbd) basic_machine=sparc-tti ;; @@ -765,6 +952,12 @@ case $basic_machine in pc532 | pc532-*) basic_machine=ns32k-pc532 ;; + pc98) + basic_machine=i386-pc + ;; + pc98-*) + basic_machine=i386-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; pentium | p5 | k5 | k6 | nexgen | viac3) basic_machine=i586-pc ;; @@ -794,9 +987,10 @@ case $basic_machine in ;; power) basic_machine=power-ibm ;; - ppc) basic_machine=powerpc-unknown + ppc | ppcbe) basic_machine=powerpc-unknown ;; - ppc-*) basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'` + ppc-* | ppcbe-*) + basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'` ;; ppcle | powerpclittle | ppc-le | powerpc-little) basic_machine=powerpcle-unknown @@ -821,6 +1015,14 @@ case $basic_machine in basic_machine=i586-unknown os=-pw32 ;; + rdos | rdos64) + basic_machine=x86_64-pc + os=-rdos + ;; + rdos32) + basic_machine=i386-pc + os=-rdos + ;; rom68k) basic_machine=m68k-rom68k os=-coff @@ -847,6 +1049,10 @@ case $basic_machine in sb1el) basic_machine=mipsisa64sb1el-unknown ;; + sde) + basic_machine=mipsisa32-sde + os=-elf + ;; sei) basic_machine=mips-sei os=-seiux @@ -858,6 +1064,9 @@ case $basic_machine in basic_machine=sh-hitachi os=-hms ;; + sh5el) + basic_machine=sh5le-unknown + ;; sh64) basic_machine=sh64-unknown ;; @@ -879,6 +1088,9 @@ case $basic_machine in basic_machine=i860-stratus os=-sysv4 ;; + strongarm-* | thumb-*) + basic_machine=arm-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; sun2) basic_machine=m68000-sun ;; @@ -935,17 +1147,9 @@ case $basic_machine in basic_machine=t90-cray os=-unicos ;; - tic54x | c54x*) - basic_machine=tic54x-unknown - os=-coff - ;; - tic55x | c55x*) - basic_machine=tic55x-unknown - os=-coff - ;; - tic6x | c6x*) - basic_machine=tic6x-unknown - os=-coff + tile*) + basic_machine=$basic_machine-unknown + os=-linux-gnu ;; tx39) basic_machine=mipstx39-unknown @@ -960,6 +1164,10 @@ case $basic_machine in tower | tower-32) basic_machine=m68k-ncr ;; + tpf) + basic_machine=s390x-ibm + os=-tpf + ;; udi29k) basic_machine=a29k-amd os=-udi @@ -1003,9 +1211,16 @@ case $basic_machine in basic_machine=hppa1.1-winbond os=-proelf ;; + xbox) + basic_machine=i686-pc + os=-mingw32 + ;; xps | xps100) basic_machine=xps100-honeywell ;; + xscale-* | xscalee[bl]-*) + basic_machine=`echo $basic_machine | sed 's/^xscale/arm/'` + ;; ymp) basic_machine=ymp-cray os=-unicos @@ -1014,6 +1229,10 @@ case $basic_machine in basic_machine=z8k-unknown os=-sim ;; + z80-*-coff) + basic_machine=z80-unknown + os=-sim + ;; none) basic_machine=none-none os=-none @@ -1033,6 +1252,9 @@ case $basic_machine in romp) basic_machine=romp-ibm ;; + mmix) + basic_machine=mmix-knuth + ;; rs6000) basic_machine=rs6000-ibm ;; @@ -1049,13 +1271,10 @@ case $basic_machine in we32k) basic_machine=we32k-att ;; - sh3 | sh4 | sh[34]eb | sh[1234]le | sh[23]ele) + sh[1234] | sh[24]a | sh[24]aeb | sh[34]eb | sh[1234]le | sh[23]ele) basic_machine=sh-unknown ;; - sh64) - basic_machine=sh64-unknown - ;; - sparc | sparcv9 | sparcv9b) + sparc | sparcv8 | sparcv9 | sparcv9b | sparcv9v) basic_machine=sparc-sun ;; cydra) @@ -1099,9 +1318,12 @@ esac if [ x"$os" != x"" ] then case $os in - # First match some system type aliases - # that might get confused with valid system types. + # First match some system type aliases + # that might get confused with valid system types. # -solaris* is a basic system type, with this one exception. + -auroraux) + os=-auroraux + ;; -solaris1 | -solaris1.*) os=`echo $os | sed -e 's|solaris1|sunos4|'` ;; @@ -1122,25 +1344,31 @@ case $os in # Each alternative MUST END IN A *, to match a version number. # -sysv* is not here because it comes later, after sysvr4. -gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \ - | -*vms* | -sco* | -esix* | -isc* | -aix* | -sunos | -sunos[34]*\ - | -hpux* | -unos* | -osf* | -luna* | -dgux* | -solaris* | -sym* \ + | -*vms* | -sco* | -esix* | -isc* | -aix* | -cnk* | -sunos | -sunos[34]*\ + | -hpux* | -unos* | -osf* | -luna* | -dgux* | -auroraux* | -solaris* \ + | -sym* | -kopensolaris* | -plan9* \ | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \ - | -aos* \ + | -aos* | -aros* \ | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \ | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \ - | -hiux* | -386bsd* | -netbsd* | -openbsd* | -kfreebsd* | -freebsd* | -riscix* \ - | -lynxos* | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \ + | -hiux* | -386bsd* | -knetbsd* | -mirbsd* | -netbsd* \ + | -bitrig* | -openbsd* | -solidbsd* \ + | -ekkobsd* | -kfreebsd* | -freebsd* | -riscix* | -lynxos* \ + | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \ | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \ | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \ - | -chorusos* | -chorusrdb* \ - | -cygwin* | -pe* | -psos* | -moss* | -proelf* | -rtems* \ - | -mingw32* | -linux-gnu* | -uxpv* | -beos* | -mpeix* | -udk* \ + | -chorusos* | -chorusrdb* | -cegcc* \ + | -cygwin* | -msys* | -pe* | -psos* | -moss* | -proelf* | -rtems* \ + | -mingw32* | -mingw64* | -linux-gnu* | -linux-android* \ + | -linux-newlib* | -linux-musl* | -linux-uclibc* \ + | -uxpv* | -beos* | -mpeix* | -udk* \ | -interix* | -uwin* | -mks* | -rhapsody* | -darwin* | -opened* \ | -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \ | -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* \ | -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \ | -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* \ - | -powermax* | -dnix* | -nx6 | -nx7 | -sei*) + | -powermax* | -dnix* | -nx6 | -nx7 | -sei* | -dragonfly* \ + | -skyos* | -haiku* | -rdos* | -toppers* | -drops* | -es*) # Remember, each alternative MUST END IN *, to match a version number. ;; -qnx*) @@ -1158,12 +1386,15 @@ case $os in os=`echo $os | sed -e 's|nto|nto-qnx|'` ;; -sim | -es1800* | -hms* | -xray | -os68k* | -none* | -v88r* \ - | -windows* | -osx | -abug | -netware* | -os9* | -beos* \ + | -windows* | -osx | -abug | -netware* | -os9* | -beos* | -haiku* \ | -macos* | -mpw* | -magic* | -mmixware* | -mon960* | -lnews*) ;; -mac*) os=`echo $os | sed -e 's|mac|macos|'` ;; + -linux-dietlibc) + os=-linux-dietlibc + ;; -linux*) os=`echo $os | sed -e 's|linux|linux-gnu|'` ;; @@ -1176,6 +1407,9 @@ case $os in -opened*) os=-openedition ;; + -os400*) + os=-os400 + ;; -wince*) os=-wince ;; @@ -1197,6 +1431,9 @@ case $os in -atheos*) os=-atheos ;; + -syllable*) + os=-syllable + ;; -386bsd) os=-bsd ;; @@ -1219,6 +1456,9 @@ case $os in -sinix*) os=-sysv4 ;; + -tpf*) + os=-tpf + ;; -triton*) os=-sysv3 ;; @@ -1252,8 +1492,13 @@ case $os in -aros*) os=-aros ;; - -kaos*) - os=-kaos + -zvmoe) + os=-zvmoe + ;; + -dicos*) + os=-dicos + ;; + -nacl*) ;; -none) ;; @@ -1277,6 +1522,12 @@ else # system, and we'll never get to this point. case $basic_machine in + score-*) + os=-elf + ;; + spu-*) + os=-elf + ;; *-acorn) os=-riscix1.2 ;; @@ -1286,9 +1537,21 @@ case $basic_machine in arm*-semi) os=-aout ;; - c4x-* | tic4x-*) - os=-coff - ;; + c4x-* | tic4x-*) + os=-coff + ;; + hexagon-*) + os=-elf + ;; + tic54x-*) + os=-coff + ;; + tic55x-*) + os=-coff + ;; + tic6x-*) + os=-coff + ;; # This must come before the *-dec entry. pdp10-*) os=-tops20 @@ -1307,19 +1570,22 @@ case $basic_machine in ;; m68000-sun) os=-sunos3 - # This also exists in the configure program, but was not the - # default. - # os=-sunos4 ;; m68*-cisco) os=-aout ;; + mep-*) + os=-elf + ;; mips*-cisco) os=-elf ;; mips*-*) os=-elf ;; + or1k-*) + os=-elf + ;; or32-*) os=-coff ;; @@ -1332,9 +1598,15 @@ case $basic_machine in *-be) os=-beos ;; + *-haiku) + os=-haiku + ;; *-ibm) os=-aix ;; + *-knuth) + os=-mmixware + ;; *-wec) os=-proelf ;; @@ -1437,7 +1709,7 @@ case $basic_machine in -sunos*) vendor=sun ;; - -aix*) + -cnk*|-aix*) vendor=ibm ;; -beos*) @@ -1467,9 +1739,15 @@ case $basic_machine in -mvs* | -opened*) vendor=ibm ;; + -os400*) + vendor=ibm + ;; -ptx*) vendor=sequent ;; + -tpf*) + vendor=ibm + ;; -vxsim* | -vxworks* | -windiss*) vendor=wrs ;; @@ -1494,7 +1772,7 @@ case $basic_machine in esac echo $basic_machine$os -exit 0 +exit # Local variables: # eval: (add-hook 'write-file-hooks 'time-stamp) diff --git a/contrib/openpam/configure b/contrib/openpam/configure index 5348d3f5a085..bad8c990942c 100755 --- a/contrib/openpam/configure +++ b/contrib/openpam/configure @@ -1,14 +1,12 @@ #! /bin/sh -# From configure.ac Id: configure.ac 610 2012-05-26 14:03:45Z des . +# From configure.ac Id: configure.ac 741 2013-09-07 13:34:02Z des . # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.68 for OpenPAM 20120526. +# Generated by GNU Autoconf 2.69 for OpenPAM 20130907. # # Report bugs to . # # -# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, -# 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 Free Software -# Foundation, Inc. +# Copyright (C) 1992-1996, 1998-2012 Free Software Foundation, Inc. # # # This configure script is free software; the Free Software Foundation @@ -137,6 +135,31 @@ export LANGUAGE # CDPATH. (unset CDPATH) >/dev/null 2>&1 && unset CDPATH +# Use a proper internal environment variable to ensure we don't fall + # into an infinite loop, continuously re-executing ourselves. + if test x"${_as_can_reexec}" != xno && test "x$CONFIG_SHELL" != x; then + _as_can_reexec=no; export _as_can_reexec; + # We cannot yet assume a decent shell, so we have to provide a +# neutralization value for shells without unset; and this also +# works around shells that cannot unset nonexistent variables. +# Preserve -v and -x to the replacement shell. +BASH_ENV=/dev/null +ENV=/dev/null +(unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV +case $- in # (((( + *v*x* | *x*v* ) as_opts=-vx ;; + *v* ) as_opts=-v ;; + *x* ) as_opts=-x ;; + * ) as_opts= ;; +esac +exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"} +# Admittedly, this is quite paranoid, since all the known shells bail +# out after a failed `exec'. +$as_echo "$0: could not re-execute with $CONFIG_SHELL" >&2 +as_fn_exit 255 + fi + # We don't want this to propagate to other subprocesses. + { _as_can_reexec=; unset _as_can_reexec;} if test "x$CONFIG_SHELL" = x; then as_bourne_compatible="if test -n \"\${ZSH_VERSION+set}\" && (emulate sh) >/dev/null 2>&1; then : emulate sh @@ -170,7 +193,8 @@ if ( set x; as_fn_ret_success y && test x = \"\$1\" ); then : else exitcode=1; echo positional parameters were not saved. fi -test x\$exitcode = x0 || exit 1" +test x\$exitcode = x0 || exit 1 +test -x / || exit 1" as_suggested=" as_lineno_1=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_1a=\$LINENO as_lineno_2=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_2a=\$LINENO eval 'test \"x\$as_lineno_1'\$as_run'\" != \"x\$as_lineno_2'\$as_run'\" && @@ -223,21 +247,25 @@ IFS=$as_save_IFS if test "x$CONFIG_SHELL" != x; then : - # We cannot yet assume a decent shell, so we have to provide a - # neutralization value for shells without unset; and this also - # works around shells that cannot unset nonexistent variables. - # Preserve -v and -x to the replacement shell. - BASH_ENV=/dev/null - ENV=/dev/null - (unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV - export CONFIG_SHELL - case $- in # (((( - *v*x* | *x*v* ) as_opts=-vx ;; - *v* ) as_opts=-v ;; - *x* ) as_opts=-x ;; - * ) as_opts= ;; - esac - exec "$CONFIG_SHELL" $as_opts "$as_myself" ${1+"$@"} + export CONFIG_SHELL + # We cannot yet assume a decent shell, so we have to provide a +# neutralization value for shells without unset; and this also +# works around shells that cannot unset nonexistent variables. +# Preserve -v and -x to the replacement shell. +BASH_ENV=/dev/null +ENV=/dev/null +(unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV +case $- in # (((( + *v*x* | *x*v* ) as_opts=-vx ;; + *v* ) as_opts=-v ;; + *x* ) as_opts=-x ;; + * ) as_opts= ;; +esac +exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"} +# Admittedly, this is quite paranoid, since all the known shells bail +# out after a failed `exec'. +$as_echo "$0: could not re-execute with $CONFIG_SHELL" >&2 +exit 255 fi if test x$as_have_required = xno; then : @@ -339,6 +367,14 @@ $as_echo X"$as_dir" | } # as_fn_mkdir_p + +# as_fn_executable_p FILE +# ----------------------- +# Test if FILE is an executable regular file. +as_fn_executable_p () +{ + test -f "$1" && test -x "$1" +} # as_fn_executable_p # as_fn_append VAR VALUE # ---------------------- # Append the text in VALUE to the end of the definition contained in VAR. Take @@ -460,6 +496,10 @@ as_cr_alnum=$as_cr_Letters$as_cr_digits chmod +x "$as_me.lineno" || { $as_echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2; as_fn_exit 1; } + # If we had to re-execute with $CONFIG_SHELL, we're ensured to have + # already done that, so ensure we don't try to do so again and fall + # in an infinite loop. This has already happened in practice. + _as_can_reexec=no; export _as_can_reexec # Don't try to exec as it changes $[0], causing all sort of problems # (the dirname of $[0] is not the place where we might find the # original and so on. Autoconf is especially sensitive to this). @@ -494,16 +534,16 @@ if (echo >conf$$.file) 2>/dev/null; then # ... but there are two gotchas: # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. - # In both cases, we have to default to `cp -p'. + # In both cases, we have to default to `cp -pR'. ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || - as_ln_s='cp -p' + as_ln_s='cp -pR' elif ln conf$$.file conf$$ 2>/dev/null; then as_ln_s=ln else - as_ln_s='cp -p' + as_ln_s='cp -pR' fi else - as_ln_s='cp -p' + as_ln_s='cp -pR' fi rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file rmdir conf$$.dir 2>/dev/null @@ -515,28 +555,8 @@ else as_mkdir_p=false fi -if test -x / >/dev/null 2>&1; then - as_test_x='test -x' -else - if ls -dL / >/dev/null 2>&1; then - as_ls_L_option=L - else - as_ls_L_option= - fi - as_test_x=' - eval sh -c '\'' - if test -d "$1"; then - test -d "$1/."; - else - case $1 in #( - -*)set "./$1";; - esac; - case `ls -ld'$as_ls_L_option' "$1" 2>/dev/null` in #(( - ???[sx]*):;;*)false;;esac;fi - '\'' sh - ' -fi -as_executable_p=$as_test_x +as_test_x='test -x' +as_executable_p=as_fn_executable_p # Sed expression to map a string onto a valid CPP name. as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" @@ -570,12 +590,12 @@ MAKEFLAGS= # Identity of this package. PACKAGE_NAME='OpenPAM' PACKAGE_TARNAME='openpam' -PACKAGE_VERSION='20120526' -PACKAGE_STRING='OpenPAM 20120526' +PACKAGE_VERSION='20130907' +PACKAGE_STRING='OpenPAM 20130907' PACKAGE_BUGREPORT='des@des.no' -PACKAGE_URL='' +PACKAGE_URL='http://www.openpam.org/' -ac_unique_file="lib/pam_start.c" +ac_unique_file="lib/libpam/pam_start.c" # Factoring default headers for most tests. ac_includes_default="\ #include @@ -616,6 +636,7 @@ ac_subst_vars='am__EXEEXT_FALSE am__EXEEXT_TRUE LTLIBOBJS LIBOBJS +CRYPTO_LIBS CRYPT_LIBS DL_LIBS WITH_SU_FALSE @@ -626,6 +647,8 @@ WITH_PAM_UNIX_FALSE WITH_PAM_UNIX_TRUE WITH_DOC_FALSE WITH_DOC_TRUE +CUSTOM_MODULES_DIR_FALSE +CUSTOM_MODULES_DIR_TRUE OPENPAM_MODULES_DIR LIB_MAJ OTOOL64 @@ -661,6 +684,7 @@ CPP am__fastdepCC_FALSE am__fastdepCC_TRUE CCDEPMODE +am__nodep AMDEPBACKSLASH AMDEP_FALSE AMDEP_TRUE @@ -674,6 +698,10 @@ CPPFLAGS LDFLAGS CFLAGS CC +AM_BACKSLASH +AM_DEFAULT_VERBOSITY +AM_DEFAULT_V +AM_V am__untar am__tar AMTAR @@ -738,6 +766,7 @@ SHELL' ac_subst_files='' ac_user_opts=' enable_option_checking +enable_silent_rules enable_dependency_tracking enable_static enable_shared @@ -1221,8 +1250,6 @@ target=$target_alias if test "x$host_alias" != x; then if test "x$build_alias" = x; then cross_compiling=maybe - $as_echo "$as_me: WARNING: if you wanted to set the --build type, don't use --host. - If a cross compiler is detected then cross compile mode will be used" >&2 elif test "x$build_alias" != "x$host_alias"; then cross_compiling=yes fi @@ -1308,7 +1335,7 @@ if test "$ac_init_help" = "long"; then # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF -\`configure' configures OpenPAM 20120526 to adapt to many kinds of systems. +\`configure' configures OpenPAM 20130907 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -1378,7 +1405,7 @@ fi if test -n "$ac_init_help"; then case $ac_init_help in - short | recursive ) echo "Configuration of OpenPAM 20120526:";; + short | recursive ) echo "Configuration of OpenPAM 20130907:";; esac cat <<\_ACEOF @@ -1386,14 +1413,18 @@ Optional Features: --disable-option-checking ignore unrecognized --enable/--with options --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no) --enable-FEATURE[=ARG] include FEATURE [ARG=yes] - --disable-dependency-tracking speeds up one-time build - --enable-dependency-tracking do not reject slow dependency extractors + --enable-silent-rules less verbose build output (undo: "make V=1") + --disable-silent-rules verbose build output (undo: "make V=0") + --enable-dependency-tracking + do not reject slow dependency extractors + --disable-dependency-tracking + speeds up one-time build --enable-static[=PKGS] build static libraries [default=no] --enable-shared[=PKGS] build shared libraries [default=yes] --enable-fast-install[=PKGS] optimize for fast installation [default=yes] --disable-libtool-lock avoid locking (might break parallel builds) - --enable-debug turn debugging on by default + --enable-debug turn debugging macros on --disable-unversioned-modules support loading of unversioned modules --enable-developer-warnings @@ -1412,7 +1443,7 @@ Optional Packages: (or the compiler's sysroot if not specified). --with-modules-dir=DIR OpenPAM modules directory --without-doc do not build documentation - --with-pam-unix compile sample pam_unix(8) implementation + --with-pam-unix compile sample pam_unix(8) module --with-pamtest compile test application --with-su compile sample su(1) implementation @@ -1430,6 +1461,7 @@ Use these variables to override the choices made by `configure' or to help it to find libraries and programs with nonstandard names/locations. Report bugs to . +OpenPAM home page: . _ACEOF ac_status=$? fi @@ -1492,10 +1524,10 @@ fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF -OpenPAM configure 20120526 -generated by GNU Autoconf 2.68 +OpenPAM configure 20130907 +generated by GNU Autoconf 2.69 -Copyright (C) 2010 Free Software Foundation, Inc. +Copyright (C) 2012 Free Software Foundation, Inc. This configure script is free software; the Free Software Foundation gives unlimited permission to copy, distribute and modify it. _ACEOF @@ -1772,7 +1804,7 @@ $as_echo "$ac_try_echo"; } >&5 test ! -s conftest.err } && test -s conftest$ac_exeext && { test "$cross_compiling" = yes || - $as_test_x conftest$ac_exeext + test -x conftest$ac_exeext }; then : ac_retval=0 else @@ -1861,8 +1893,8 @@ cat >config.log <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. -It was created by OpenPAM $as_me 20120526, which was -generated by GNU Autoconf 2.68. Invocation command line was +It was created by OpenPAM $as_me 20130907, which was +generated by GNU Autoconf 2.69. Invocation command line was $ $0 $@ @@ -2211,7 +2243,7 @@ ac_compiler_gnu=$ac_cv_c_compiler_gnu -am__api_version='1.11' +am__api_version='1.14' ac_aux_dir= for ac_dir in "$srcdir" "$srcdir/.." "$srcdir/../.."; do @@ -2279,7 +2311,7 @@ case $as_dir/ in #(( # by default. for ac_prog in ginstall scoinst install; do for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_prog$ac_exec_ext" && $as_test_x "$as_dir/$ac_prog$ac_exec_ext"; }; then + if as_fn_executable_p "$as_dir/$ac_prog$ac_exec_ext"; then if test $ac_prog = install && grep dspmsg "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then # AIX install. It has an incompatible calling convention. @@ -2337,9 +2369,6 @@ test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644' { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether build environment is sane" >&5 $as_echo_n "checking whether build environment is sane... " >&6; } -# Just in case -sleep 1 -echo timestamp > conftest.file # Reject unsafe characters in $srcdir or the absolute working directory # name. Accept space and tab only in the latter. am_lf=' @@ -2350,32 +2379,40 @@ case `pwd` in esac case $srcdir in *[\\\"\#\$\&\'\`$am_lf\ \ ]*) - as_fn_error $? "unsafe srcdir value: \`$srcdir'" "$LINENO" 5;; + as_fn_error $? "unsafe srcdir value: '$srcdir'" "$LINENO" 5;; esac -# Do `set' in a subshell so we don't clobber the current shell's +# Do 'set' in a subshell so we don't clobber the current shell's # arguments. Must try -L first in case configure is actually a # symlink; some systems play weird games with the mod time of symlinks # (eg FreeBSD returns the mod time of the symlink's containing # directory). if ( - set X `ls -Lt "$srcdir/configure" conftest.file 2> /dev/null` - if test "$*" = "X"; then - # -L didn't work. - set X `ls -t "$srcdir/configure" conftest.file` - fi - rm -f conftest.file - if test "$*" != "X $srcdir/configure conftest.file" \ - && test "$*" != "X conftest.file $srcdir/configure"; then - - # If neither matched, then we have a broken ls. This can happen - # if, for instance, CONFIG_SHELL is bash and it inherits a - # broken ls alias from the environment. This has actually - # happened. Such a system could not be considered "sane". - as_fn_error $? "ls -t appears to fail. Make sure there is not a broken -alias in your environment" "$LINENO" 5 - fi + am_has_slept=no + for am_try in 1 2; do + echo "timestamp, slept: $am_has_slept" > conftest.file + set X `ls -Lt "$srcdir/configure" conftest.file 2> /dev/null` + if test "$*" = "X"; then + # -L didn't work. + set X `ls -t "$srcdir/configure" conftest.file` + fi + if test "$*" != "X $srcdir/configure conftest.file" \ + && test "$*" != "X conftest.file $srcdir/configure"; then + # If neither matched, then we have a broken ls. This can happen + # if, for instance, CONFIG_SHELL is bash and it inherits a + # broken ls alias from the environment. This has actually + # happened. Such a system could not be considered "sane". + as_fn_error $? "ls -t appears to fail. Make sure there is not a broken + alias in your environment" "$LINENO" 5 + fi + if test "$2" = conftest.file || test $am_try -eq 2; then + break + fi + # Just in case. + sleep 1 + am_has_slept=yes + done test "$2" = conftest.file ) then @@ -2387,6 +2424,16 @@ Check your system clock" "$LINENO" 5 fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } +# If we didn't sleep, we still need to ensure time stamps of config.status and +# generated files are strictly newer. +am_sleep_pid= +if grep 'slept: no' conftest.file >/dev/null 2>&1; then + ( sleep 1 ) & + am_sleep_pid=$! +fi + +rm -f conftest.file + test "$program_prefix" != NONE && program_transform_name="s&^&$program_prefix&;$program_transform_name" # Use a double $ so make ignores it. @@ -2409,12 +2456,12 @@ if test x"${MISSING+set}" != xset; then esac fi # Use eval to expand $SHELL -if eval "$MISSING --run true"; then - am_missing_run="$MISSING --run " +if eval "$MISSING --is-lightweight"; then + am_missing_run="$MISSING " else am_missing_run= - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: \`missing' script is too old or missing" >&5 -$as_echo "$as_me: WARNING: \`missing' script is too old or missing" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: 'missing' script is too old or missing" >&5 +$as_echo "$as_me: WARNING: 'missing' script is too old or missing" >&2;} fi if test x"${install_sh}" != xset; then @@ -2426,10 +2473,10 @@ if test x"${install_sh}" != xset; then esac fi -# Installed binaries are usually stripped using `strip' when the user -# run `make install-strip'. However `strip' might not be the right +# Installed binaries are usually stripped using 'strip' when the user +# run "make install-strip". However 'strip' might not be the right # tool to use in cross-compilation environments, therefore Automake -# will honor the `STRIP' environment variable to overrule this program. +# will honor the 'STRIP' environment variable to overrule this program. if test "$cross_compiling" != no; then if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}strip", so it can be a program name with args. @@ -2448,7 +2495,7 @@ do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_STRIP="${ac_tool_prefix}strip" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -2488,7 +2535,7 @@ do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_STRIP="strip" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -2539,7 +2586,7 @@ do test -z "$as_dir" && as_dir=. for ac_prog in mkdir gmkdir; do for ac_exec_ext in '' $ac_executable_extensions; do - { test -f "$as_dir/$ac_prog$ac_exec_ext" && $as_test_x "$as_dir/$ac_prog$ac_exec_ext"; } || continue + as_fn_executable_p "$as_dir/$ac_prog$ac_exec_ext" || continue case `"$as_dir/$ac_prog$ac_exec_ext" --version 2>&1` in #( 'mkdir (GNU coreutils) '* | \ 'mkdir (coreutils) '* | \ @@ -2568,12 +2615,6 @@ fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MKDIR_P" >&5 $as_echo "$MKDIR_P" >&6; } -mkdir_p="$MKDIR_P" -case $mkdir_p in - [\\/$]* | ?:[\\/]*) ;; - */*) mkdir_p="\$(top_builddir)/$mkdir_p" ;; -esac - for ac_prog in gawk mawk nawk awk do # Extract the first word of "$ac_prog", so it can be a program name with args. @@ -2592,7 +2633,7 @@ do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_AWK="$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -2656,6 +2697,45 @@ else fi rmdir .tst 2>/dev/null +# Check whether --enable-silent-rules was given. +if test "${enable_silent_rules+set}" = set; then : + enableval=$enable_silent_rules; +fi + +case $enable_silent_rules in # ((( + yes) AM_DEFAULT_VERBOSITY=0;; + no) AM_DEFAULT_VERBOSITY=1;; + *) AM_DEFAULT_VERBOSITY=1;; +esac +am_make=${MAKE-make} +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $am_make supports nested variables" >&5 +$as_echo_n "checking whether $am_make supports nested variables... " >&6; } +if ${am_cv_make_support_nested_variables+:} false; then : + $as_echo_n "(cached) " >&6 +else + if $as_echo 'TRUE=$(BAR$(V)) +BAR0=false +BAR1=true +V=1 +am__doit: + @$(TRUE) +.PHONY: am__doit' | $am_make -f - >/dev/null 2>&1; then + am_cv_make_support_nested_variables=yes +else + am_cv_make_support_nested_variables=no +fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_make_support_nested_variables" >&5 +$as_echo "$am_cv_make_support_nested_variables" >&6; } +if test $am_cv_make_support_nested_variables = yes; then + AM_V='$(V)' + AM_DEFAULT_V='$(AM_DEFAULT_VERBOSITY)' +else + AM_V=$AM_DEFAULT_VERBOSITY + AM_DEFAULT_V=$AM_DEFAULT_VERBOSITY +fi +AM_BACKSLASH='\' + if test "`cd $srcdir && pwd`" != "`pwd`"; then # Use -I$(srcdir) only when $(srcdir) != ., so that make's output # is not polluted with repeated "-I." @@ -2678,7 +2758,7 @@ fi # Define the identity of the package. PACKAGE='openpam' - VERSION='20120526' + VERSION='20130907' cat >>confdefs.h <<_ACEOF @@ -2706,18 +2786,70 @@ AUTOHEADER=${AUTOHEADER-"${am_missing_run}autoheader"} MAKEINFO=${MAKEINFO-"${am_missing_run}makeinfo"} +# For better backward compatibility. To be removed once Automake 1.9.x +# dies out for good. For more background, see: +# +# +mkdir_p='$(MKDIR_P)' + # We need awk for the "check" target. The system "awk" is bad on # some platforms. -# Always define AMTAR for backward compatibility. +# Always define AMTAR for backward compatibility. Yes, it's still used +# in the wild :-( We should find a proper way to deprecate it ... +AMTAR='$${TAR-tar}' -AMTAR=${AMTAR-"${am_missing_run}tar"} -am__tar='${AMTAR} chof - "$$tardir"'; am__untar='${AMTAR} xf -' +# We'll loop over all known methods to create a tar archive until one works. +_am_tools='gnutar pax cpio none' + +am__tar='$${TAR-tar} chof - "$$tardir"' am__untar='$${TAR-tar} xf -' + +# POSIX will say in a future version that running "rm -f" with no argument +# is OK; and we want to be able to make that assumption in our Makefile +# recipes. So use an aggressive probe to check that the usage we want is +# actually supported "in the wild" to an acceptable degree. +# See automake bug#10828. +# To make any issue more visible, cause the running configure to be aborted +# by default if the 'rm' program in use doesn't match our expectations; the +# user can still override this though. +if rm -f && rm -fr && rm -rf; then : OK; else + cat >&2 <<'END' +Oops! + +Your 'rm' program seems unable to run without file operands specified +on the command line, even when the '-f' option is present. This is contrary +to the behaviour of most rm programs out there, and not conforming with +the upcoming POSIX standard: + +Please tell bug-automake@gnu.org about your system, including the value +of your $PATH and any error possibly output before this message. This +can help us improve future automake versions. + +END + if test x"$ACCEPT_INFERIOR_RM_PROGRAM" = x"yes"; then + echo 'Configuration will proceed anyway, since you have set the' >&2 + echo 'ACCEPT_INFERIOR_RM_PROGRAM variable to "yes"' >&2 + echo >&2 + else + cat >&2 <<'END' +Aborting the configuration process, to ensure you take notice of the issue. + +You can download and install GNU coreutils to get an 'rm' implementation +that behaves properly: . + +If you want to complete the configuration process using your problematic +'rm' anyway, export the environment variable ACCEPT_INFERIOR_RM_PROGRAM +to "yes", and re-run configure. + +END + as_fn_error $? "Your 'rm' program is bad, sorry." "$LINENO" 5 + fi +fi ac_config_headers="$ac_config_headers config.h" @@ -2750,7 +2882,7 @@ do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_CC="${ac_tool_prefix}gcc" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -2790,7 +2922,7 @@ do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_CC="gcc" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -2843,7 +2975,7 @@ do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_CC="${ac_tool_prefix}cc" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -2884,7 +3016,7 @@ do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then ac_prog_rejected=yes continue @@ -2942,7 +3074,7 @@ do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_CC="$ac_tool_prefix$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -2986,7 +3118,7 @@ do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_CC="$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -3432,8 +3564,7 @@ cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include -#include -#include +struct stat; /* Most of the following tests are stolen from RCS 5.7's src/conf.sh. */ struct buf { int x; }; FILE * (*rcsopen) (struct buf *, struct stat *, int); @@ -3517,6 +3648,65 @@ ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC understands -c and -o together" >&5 +$as_echo_n "checking whether $CC understands -c and -o together... " >&6; } +if ${am_cv_prog_cc_c_o+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF + # Make sure it works both with $CC and with simple cc. + # Following AC_PROG_CC_C_O, we do the test twice because some + # compilers refuse to overwrite an existing .o file with -o, + # though they will create one. + am_cv_prog_cc_c_o=yes + for am_i in 1 2; do + if { echo "$as_me:$LINENO: $CC -c conftest.$ac_ext -o conftest2.$ac_objext" >&5 + ($CC -c conftest.$ac_ext -o conftest2.$ac_objext) >&5 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } \ + && test -f conftest2.$ac_objext; then + : OK + else + am_cv_prog_cc_c_o=no + break + fi + done + rm -f core conftest* + unset am_i +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_prog_cc_c_o" >&5 +$as_echo "$am_cv_prog_cc_c_o" >&6; } +if test "$am_cv_prog_cc_c_o" != yes; then + # Losing compiler, so override with the script. + # FIXME: It is wrong to rewrite CC. + # But if we don't then we get into trouble of one sort or another. + # A longer-term fix would be to have automake use am__CC in this case, + # and then we could set am__CC="\$(top_srcdir)/compile \$(CC)" + CC="$am_aux_dir/compile $CC" +fi +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + DEPDIR="${am__leading_dot}deps" ac_config_commands="$ac_config_commands depfiles" @@ -3536,7 +3726,7 @@ am__quote= _am_result=none # First try GNU make style include. echo "include confinc" > confmf -# Ignore all kinds of additional output from `make'. +# Ignore all kinds of additional output from 'make'. case `$am_make -s -f confmf 2> /dev/null` in #( *the\ am__doit\ target*) am__include=include @@ -3569,6 +3759,7 @@ fi if test "x$enable_dependency_tracking" != xno; then am_depcomp="$ac_aux_dir/depcomp" AMDEPBACKSLASH='\' + am__nodep='_no' fi if test "x$enable_dependency_tracking" != xno; then AMDEP_TRUE= @@ -3591,8 +3782,9 @@ else # We make a subdir and do the tests there. Otherwise we can end up # making bogus files that we don't know about and never remove. For # instance it was reported that on HP-UX the gcc test will end up - # making a dummy file named `D' -- because `-MD' means `put the output - # in D'. + # making a dummy file named 'D' -- because '-MD' means "put the output + # in D". + rm -rf conftest.dir mkdir conftest.dir # Copy depcomp to subdir because otherwise we won't find it if we're # using a relative directory. @@ -3626,16 +3818,16 @@ else : > sub/conftest.c for i in 1 2 3 4 5 6; do echo '#include "conftst'$i'.h"' >> sub/conftest.c - # Using `: > sub/conftst$i.h' creates only sub/conftst1.h with - # Solaris 8's {/usr,}/bin/sh. - touch sub/conftst$i.h + # Using ": > sub/conftst$i.h" creates only sub/conftst1.h with + # Solaris 10 /bin/sh. + echo '/* dummy */' > sub/conftst$i.h done echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf - # We check with `-c' and `-o' for the sake of the "dashmstdout" + # We check with '-c' and '-o' for the sake of the "dashmstdout" # mode. It turns out that the SunPro C++ compiler does not properly - # handle `-M -o', and we need to detect this. Also, some Intel - # versions had trouble with output in subdirs + # handle '-M -o', and we need to detect this. Also, some Intel + # versions had trouble with output in subdirs. am__obj=sub/conftest.${OBJEXT-o} am__minus_obj="-o $am__obj" case $depmode in @@ -3644,16 +3836,16 @@ else test "$am__universal" = false || continue ;; nosideeffect) - # after this tag, mechanisms are not by side-effect, so they'll - # only be used when explicitly requested + # After this tag, mechanisms are not by side-effect, so they'll + # only be used when explicitly requested. if test "x$enable_dependency_tracking" = xyes; then continue else break fi ;; - msvisualcpp | msvcmsys) - # This compiler won't grok `-c -o', but also, the minuso test has + msvc7 | msvc7msys | msvisualcpp | msvcmsys) + # This compiler won't grok '-c -o', but also, the minuso test has # not run yet. These depmodes are late enough in the game, and # so weak that their functioning should not be impacted. am__obj=conftest.${OBJEXT-o} @@ -3857,7 +4049,7 @@ main () return 0; } _ACEOF -for ac_arg in '' -std=gnu99 -std=c99 -c99 -AC99 -xc99=all -qlanglvl=extc99 +for ac_arg in '' -std=gnu99 -std=c99 -c99 -AC99 -D_STDC_C99= -qlanglvl=extc99 do CC="$ac_save_CC $ac_arg" if ac_fn_c_try_compile "$LINENO"; then : @@ -3897,8 +4089,7 @@ cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include -#include -#include +struct stat; /* Most of the following tests are stolen from RCS 5.7's src/conf.sh. */ struct buf { int x; }; FILE * (*rcsopen) (struct buf *, struct stat *, int); @@ -4155,7 +4346,7 @@ do for ac_prog in grep ggrep; do for ac_exec_ext in '' $ac_executable_extensions; do ac_path_GREP="$as_dir/$ac_prog$ac_exec_ext" - { test -f "$ac_path_GREP" && $as_test_x "$ac_path_GREP"; } || continue + as_fn_executable_p "$ac_path_GREP" || continue # Check for GNU ac_path_GREP and select it if it is found. # Check for GNU $ac_path_GREP case `"$ac_path_GREP" --version 2>&1` in @@ -4221,7 +4412,7 @@ do for ac_prog in egrep; do for ac_exec_ext in '' $ac_executable_extensions; do ac_path_EGREP="$as_dir/$ac_prog$ac_exec_ext" - { test -f "$ac_path_EGREP" && $as_test_x "$ac_path_EGREP"; } || continue + as_fn_executable_p "$ac_path_EGREP" || continue # Check for GNU ac_path_EGREP and select it if it is found. # Check for GNU $ac_path_EGREP case `"$ac_path_EGREP" --version 2>&1` in @@ -4428,8 +4619,8 @@ else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ -# define __EXTENSIONS__ 1 - $ac_includes_default +# define __EXTENSIONS__ 1 + $ac_includes_default int main () { @@ -4471,11 +4662,11 @@ else int main () { -/* FIXME: Include the comments suggested by Paul. */ + #ifndef __cplusplus - /* Ultrix mips cc rejects this. */ + /* Ultrix mips cc rejects this sort of thing. */ typedef int charset[2]; - const charset cs; + const charset cs = { 0, 0 }; /* SunOS 4.1.1 cc rejects this. */ char const *const *pcpcc; char **ppc; @@ -4492,8 +4683,9 @@ main () ++pcpcc; ppc = (char**) pcpcc; pcpcc = (char const *const *) ppc; - { /* SCO 3.2v4 cc rejects this. */ - char *t; + { /* SCO 3.2v4 cc rejects this sort of thing. */ + char tx; + char *t = &tx; char const *s = 0 ? (char *) 0 : (char const *) 0; *t++ = 0; @@ -4509,10 +4701,10 @@ main () iptr p = 0; ++p; } - { /* AIX XL C 1.02.0.0 rejects this saying + { /* AIX XL C 1.02.0.0 rejects this sort of thing, saying "k.c", line 2.27: 1506-025 (S) Operand must be a modifiable lvalue. */ - struct s { int j; const int *ap[3]; }; - struct s *b; b->j = 5; + struct s { int j; const int *ap[3]; } bx; + struct s *b = &bx; b->j = 5; } { /* ULTRIX-32 V3.1 (Rev 9) vcc rejects this */ const int foo = 10; @@ -4810,7 +5002,7 @@ do for ac_prog in sed gsed; do for ac_exec_ext in '' $ac_executable_extensions; do ac_path_SED="$as_dir/$ac_prog$ac_exec_ext" - { test -f "$ac_path_SED" && $as_test_x "$ac_path_SED"; } || continue + as_fn_executable_p "$ac_path_SED" || continue # Check for GNU ac_path_SED and select it if it is found. # Check for GNU $ac_path_SED case `"$ac_path_SED" --version 2>&1` in @@ -4889,7 +5081,7 @@ do for ac_prog in fgrep; do for ac_exec_ext in '' $ac_executable_extensions; do ac_path_FGREP="$as_dir/$ac_prog$ac_exec_ext" - { test -f "$ac_path_FGREP" && $as_test_x "$ac_path_FGREP"; } || continue + as_fn_executable_p "$ac_path_FGREP" || continue # Check for GNU ac_path_FGREP and select it if it is found. # Check for GNU $ac_path_FGREP case `"$ac_path_FGREP" --version 2>&1` in @@ -5145,7 +5337,7 @@ do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_DUMPBIN="$ac_tool_prefix$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -5189,7 +5381,7 @@ do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_DUMPBIN="$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -5613,7 +5805,7 @@ do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_OBJDUMP="${ac_tool_prefix}objdump" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -5653,7 +5845,7 @@ do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_OBJDUMP="objdump" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -5959,7 +6151,7 @@ do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_DLLTOOL="${ac_tool_prefix}dlltool" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -5999,7 +6191,7 @@ do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_DLLTOOL="dlltool" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -6102,7 +6294,7 @@ do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_AR="$ac_tool_prefix$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -6146,7 +6338,7 @@ do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_AR="$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -6271,7 +6463,7 @@ do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_STRIP="${ac_tool_prefix}strip" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -6311,7 +6503,7 @@ do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_STRIP="strip" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -6370,7 +6562,7 @@ do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_RANLIB="${ac_tool_prefix}ranlib" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -6410,7 +6602,7 @@ do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_RANLIB="ranlib" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -7059,7 +7251,7 @@ do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_MANIFEST_TOOL="${ac_tool_prefix}mt" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -7099,7 +7291,7 @@ do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_MANIFEST_TOOL="mt" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -7179,7 +7371,7 @@ do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_DSYMUTIL="${ac_tool_prefix}dsymutil" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -7219,7 +7411,7 @@ do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_DSYMUTIL="dsymutil" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -7271,7 +7463,7 @@ do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_NMEDIT="${ac_tool_prefix}nmedit" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -7311,7 +7503,7 @@ do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_NMEDIT="nmedit" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -7363,7 +7555,7 @@ do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_LIPO="${ac_tool_prefix}lipo" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -7403,7 +7595,7 @@ do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_LIPO="lipo" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -7455,7 +7647,7 @@ do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_OTOOL="${ac_tool_prefix}otool" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -7495,7 +7687,7 @@ do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_OTOOL="otool" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -7547,7 +7739,7 @@ do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_OTOOL64="${ac_tool_prefix}otool64" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -7587,7 +7779,7 @@ do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_OTOOL64="otool64" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -8262,6 +8454,10 @@ _lt_linker_boilerplate=`cat conftest.err` $RM -r conftest* +## CAVEAT EMPTOR: +## There is no encapsulation within the following macros, do not change +## the running order or otherwise move them around unless you know exactly +## what you are doing... if test -n "$compiler"; then lt_prog_compiler_no_builtin_flag= @@ -11840,21 +12036,23 @@ if test "${with_modules_dir+set}" = set; then : OPENPAM_MODULES_DIR="$withval" -else - - OPENPAM_MODULES_DIR="$libdir" - -fi -else - OPENPAM_MODULES_DIR="$libdir" -fi - - cat >>confdefs.h <<_ACEOF -#define OPENPAM_MODULES_DIR "${OPENPAM_MODULES_DIR%/}/" +#define OPENPAM_MODULES_DIR "${OPENPAM_MODULES_DIR%/}" _ACEOF +fi +fi + + + if test x"$OPENPAM_MODULES_DIR" != x""; then + CUSTOM_MODULES_DIR_TRUE= + CUSTOM_MODULES_DIR_FALSE='#' +else + CUSTOM_MODULES_DIR_TRUE='#' + CUSTOM_MODULES_DIR_FALSE= +fi + # Check whether --with-doc was given. @@ -11937,7 +12135,53 @@ fi done -for ac_func in fdlopen fpurge strlcat strlcmp strlcpy +for ac_func in asprintf vasprintf +do : + as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` +ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var" +if eval test \"x\$"$as_ac_var"\" = x"yes"; then : + cat >>confdefs.h <<_ACEOF +#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1 +_ACEOF + +fi +done + +for ac_func in dlfunc fdlopen +do : + as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` +ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var" +if eval test \"x\$"$as_ac_var"\" = x"yes"; then : + cat >>confdefs.h <<_ACEOF +#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1 +_ACEOF + +fi +done + +for ac_func in fpurge +do : + ac_fn_c_check_func "$LINENO" "fpurge" "ac_cv_func_fpurge" +if test "x$ac_cv_func_fpurge" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_FPURGE 1 +_ACEOF + +fi +done + +for ac_func in setlogmask +do : + ac_fn_c_check_func "$LINENO" "setlogmask" "ac_cv_func_setlogmask" +if test "x$ac_cv_func_setlogmask" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_SETLOGMASK 1 +_ACEOF + +fi +done + +for ac_func in strlcat strlcmp strlcpy do : as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var" @@ -12052,6 +12296,57 @@ CRYPT_LIBS="${LIBS}" LIBS="${saved_LIBS}" +saved_LIBS="${LIBS}" +LIBS="" +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for HMAC_CTX_init in -lcrypto" >&5 +$as_echo_n "checking for HMAC_CTX_init in -lcrypto... " >&6; } +if ${ac_cv_lib_crypto_HMAC_CTX_init+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lcrypto $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char HMAC_CTX_init (); +int +main () +{ +return HMAC_CTX_init (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_crypto_HMAC_CTX_init=yes +else + ac_cv_lib_crypto_HMAC_CTX_init=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_crypto_HMAC_CTX_init" >&5 +$as_echo "$ac_cv_lib_crypto_HMAC_CTX_init" >&6; } +if test "x$ac_cv_lib_crypto_HMAC_CTX_init" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_LIBCRYPTO 1 +_ACEOF + + LIBS="-lcrypto $LIBS" + +fi + +CRYPTO_LIBS="${LIBS}" +LIBS="${saved_LIBS}" + + # Check whether --enable-developer-warnings was given. if test "${enable_developer_warnings+set}" = set; then : enableval=$enable_developer_warnings; CFLAGS="${CFLAGS} -Wall -Wextra" @@ -12068,10 +12363,12 @@ if test "${enable_werror+set}" = set; then : fi -ac_config_files="$ac_config_files Makefile bin/Makefile bin/openpam_dump_policy/Makefile bin/pamtest/Makefile bin/su/Makefile doc/Makefile doc/man/Makefile include/Makefile include/security/Makefile lib/Makefile modules/Makefile modules/pam_deny/Makefile modules/pam_permit/Makefile modules/pam_unix/Makefile t/Makefile" +ac_config_files="$ac_config_files Makefile bin/Makefile bin/openpam_dump_policy/Makefile bin/pamtest/Makefile bin/su/Makefile doc/Makefile doc/man/Makefile include/Makefile include/security/Makefile lib/Makefile lib/libpam/Makefile modules/Makefile modules/pam_deny/Makefile modules/pam_permit/Makefile modules/pam_unix/Makefile t/Makefile" ac_config_files="$ac_config_files pamgdb" +ac_config_files="$ac_config_files mkpkgng" + cat >confcache <<\_ACEOF # This file is a shell script that caches the results of configure # tests run on this system so they can be shared between configure @@ -12166,7 +12463,6 @@ DEFS=-DHAVE_CONFIG_H ac_libobjs= ac_ltlibobjs= -U= for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue # 1. Remove the extension, and $U if already installed. ac_script='s/\$U\././;s/\.o$//;s/\.obj$//' @@ -12181,6 +12477,14 @@ LIBOBJS=$ac_libobjs LTLIBOBJS=$ac_ltlibobjs +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking that generated files are newer than configure" >&5 +$as_echo_n "checking that generated files are newer than configure... " >&6; } + if test -n "$am_sleep_pid"; then + # Hide warnings about reused PIDs. + wait $am_sleep_pid 2>/dev/null + fi + { $as_echo "$as_me:${as_lineno-$LINENO}: result: done" >&5 +$as_echo "done" >&6; } if test -n "$EXEEXT"; then am__EXEEXT_TRUE= am__EXEEXT_FALSE='#' @@ -12197,6 +12501,10 @@ if test -z "${am__fastdepCC_TRUE}" && test -z "${am__fastdepCC_FALSE}"; then as_fn_error $? "conditional \"am__fastdepCC\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi +if test -z "${CUSTOM_MODULES_DIR_TRUE}" && test -z "${CUSTOM_MODULES_DIR_FALSE}"; then + as_fn_error $? "conditional \"CUSTOM_MODULES_DIR\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi if test -z "${WITH_DOC_TRUE}" && test -z "${WITH_DOC_FALSE}"; then as_fn_error $? "conditional \"WITH_DOC\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 @@ -12511,16 +12819,16 @@ if (echo >conf$$.file) 2>/dev/null; then # ... but there are two gotchas: # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. - # In both cases, we have to default to `cp -p'. + # In both cases, we have to default to `cp -pR'. ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || - as_ln_s='cp -p' + as_ln_s='cp -pR' elif ln conf$$.file conf$$ 2>/dev/null; then as_ln_s=ln else - as_ln_s='cp -p' + as_ln_s='cp -pR' fi else - as_ln_s='cp -p' + as_ln_s='cp -pR' fi rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file rmdir conf$$.dir 2>/dev/null @@ -12580,28 +12888,16 @@ else as_mkdir_p=false fi -if test -x / >/dev/null 2>&1; then - as_test_x='test -x' -else - if ls -dL / >/dev/null 2>&1; then - as_ls_L_option=L - else - as_ls_L_option= - fi - as_test_x=' - eval sh -c '\'' - if test -d "$1"; then - test -d "$1/."; - else - case $1 in #( - -*)set "./$1";; - esac; - case `ls -ld'$as_ls_L_option' "$1" 2>/dev/null` in #(( - ???[sx]*):;;*)false;;esac;fi - '\'' sh - ' -fi -as_executable_p=$as_test_x + +# as_fn_executable_p FILE +# ----------------------- +# Test if FILE is an executable regular file. +as_fn_executable_p () +{ + test -f "$1" && test -x "$1" +} # as_fn_executable_p +as_test_x='test -x' +as_executable_p=as_fn_executable_p # Sed expression to map a string onto a valid CPP name. as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" @@ -12622,8 +12918,8 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" -This file was extended by OpenPAM $as_me 20120526, which was -generated by GNU Autoconf 2.68. Invocation command line was +This file was extended by OpenPAM $as_me 20130907, which was +generated by GNU Autoconf 2.69. Invocation command line was CONFIG_FILES = $CONFIG_FILES CONFIG_HEADERS = $CONFIG_HEADERS @@ -12682,17 +12978,18 @@ $config_headers Configuration commands: $config_commands -Report bugs to ." +Report bugs to . +OpenPAM home page: ." _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" ac_cs_version="\\ -OpenPAM config.status 20120526 -configured by $0, generated by GNU Autoconf 2.68, +OpenPAM config.status 20130907 +configured by $0, generated by GNU Autoconf 2.69, with options \\"\$ac_cs_config\\" -Copyright (C) 2010 Free Software Foundation, Inc. +Copyright (C) 2012 Free Software Foundation, Inc. This config.status script is free software; the Free Software Foundation gives unlimited permission to copy, distribute and modify it." @@ -12783,7 +13080,7 @@ fi _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 if \$ac_cs_recheck; then - set X '$SHELL' '$0' $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion + set X $SHELL '$0' $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion shift \$as_echo "running CONFIG_SHELL=$SHELL \$*" >&6 CONFIG_SHELL='$SHELL' @@ -13107,12 +13404,14 @@ do "include/Makefile") CONFIG_FILES="$CONFIG_FILES include/Makefile" ;; "include/security/Makefile") CONFIG_FILES="$CONFIG_FILES include/security/Makefile" ;; "lib/Makefile") CONFIG_FILES="$CONFIG_FILES lib/Makefile" ;; + "lib/libpam/Makefile") CONFIG_FILES="$CONFIG_FILES lib/libpam/Makefile" ;; "modules/Makefile") CONFIG_FILES="$CONFIG_FILES modules/Makefile" ;; "modules/pam_deny/Makefile") CONFIG_FILES="$CONFIG_FILES modules/pam_deny/Makefile" ;; "modules/pam_permit/Makefile") CONFIG_FILES="$CONFIG_FILES modules/pam_permit/Makefile" ;; "modules/pam_unix/Makefile") CONFIG_FILES="$CONFIG_FILES modules/pam_unix/Makefile" ;; "t/Makefile") CONFIG_FILES="$CONFIG_FILES t/Makefile" ;; "pamgdb") CONFIG_FILES="$CONFIG_FILES pamgdb" ;; + "mkpkgng") CONFIG_FILES="$CONFIG_FILES mkpkgng" ;; *) as_fn_error $? "invalid argument: \`$ac_config_target'" "$LINENO" 5;; esac @@ -13709,7 +14008,7 @@ $as_echo "$as_me: executing $ac_file commands" >&6;} case $ac_file$ac_mode in "depfiles":C) test x"$AMDEP_TRUE" != x"" || { - # Autoconf 2.62 quotes --file arguments for eval, but not when files + # Older Autoconf quotes --file arguments for eval, but not when files # are listed without --file. Let's play safe and only enable the eval # if we detect the quoting. case $CONFIG_FILES in @@ -13722,7 +14021,7 @@ $as_echo "$as_me: executing $ac_file commands" >&6;} # Strip MF so we end up with the name of the file. mf=`echo "$mf" | sed -e 's/:.*$//'` # Check whether this is an Automake generated Makefile or not. - # We used to match only the files named `Makefile.in', but + # We used to match only the files named 'Makefile.in', but # some people rename them; so instead we look at the file content. # Grep'ing the first line is not enough: some people post-process # each Makefile.in and add a new line on top of each file to say so. @@ -13756,21 +14055,19 @@ $as_echo X"$mf" | continue fi # Extract the definition of DEPDIR, am__include, and am__quote - # from the Makefile without running `make'. + # from the Makefile without running 'make'. DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"` test -z "$DEPDIR" && continue am__include=`sed -n 's/^am__include = //p' < "$mf"` - test -z "am__include" && continue + test -z "$am__include" && continue am__quote=`sed -n 's/^am__quote = //p' < "$mf"` - # When using ansi2knr, U may be empty or an underscore; expand it - U=`sed -n 's/^U = //p' < "$mf"` # Find all dependency output files, they are included files with # $(DEPDIR) in their names. We invoke sed twice because it is the # simplest approach to changing $(DEPDIR) to its actual value in the # expansion. for file in `sed -n " s/^$am__include $am__quote\(.*(DEPDIR).*\)$am__quote"'$/\1/p' <"$mf" | \ - sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g' -e 's/\$U/'"$U"'/g'`; do + sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g'`; do # Make sure the directory exists. test -f "$dirpart/$file" && continue fdir=`$as_dirname -- "$file" || @@ -14434,6 +14731,7 @@ fi ;; "pamgdb":F) chmod +x pamgdb ;; + "mkpkgng":F) chmod +x mkpkgng ;; esac done # for ac_tag diff --git a/contrib/openpam/configure.ac b/contrib/openpam/configure.ac index fb30726a4d1b..1dd0053747dc 100644 --- a/contrib/openpam/configure.ac +++ b/contrib/openpam/configure.ac @@ -1,9 +1,9 @@ -dnl $Id: configure.ac 610 2012-05-26 14:03:45Z des $ +dnl $Id: configure.ac 741 2013-09-07 13:34:02Z des $ AC_PREREQ([2.62]) -AC_REVISION([$Id: configure.ac 610 2012-05-26 14:03:45Z des $]) -AC_INIT([OpenPAM], [20120526], [des@des.no]) -AC_CONFIG_SRCDIR([lib/pam_start.c]) +AC_REVISION([$Id: configure.ac 741 2013-09-07 13:34:02Z des $]) +AC_INIT([OpenPAM], [20130907], [des@des.no], [openpam], [http://www.openpam.org/]) +AC_CONFIG_SRCDIR([lib/libpam/pam_start.c]) AC_CONFIG_MACRO_DIR([m4]) AM_INIT_AUTOMAKE([foreign]) AM_CONFIG_HEADER([config.h]) @@ -31,8 +31,8 @@ AC_DEFINE_UNQUOTED(LIB_MAJ, $LIB_MAJ, [OpenPAM library major number]) AC_ARG_ENABLE([debug], AC_HELP_STRING([--enable-debug], - [turn debugging on by default]), - AC_DEFINE(OPENPAM_DEBUG, 1, [Turn debugging on by default])) + [turn debugging macros on]), + AC_DEFINE(OPENPAM_DEBUG, 1, [Turn debugging macros on])) AC_ARG_ENABLE([unversioned-modules], AC_HELP_STRING([--disable-unversioned-modules], @@ -48,14 +48,12 @@ AC_ARG_WITH([modules-dir], [OpenPAM modules directory]), [AS_IF([test x"$withval" != x"no"], [ OPENPAM_MODULES_DIR="$withval" - ], [ - OPENPAM_MODULES_DIR="$libdir" - ])], - [OPENPAM_MODULES_DIR="$libdir"]) -AC_DEFINE_UNQUOTED(OPENPAM_MODULES_DIR, - "${OPENPAM_MODULES_DIR%/}/", - [OpenPAM modules directory]) + AC_DEFINE_UNQUOTED(OPENPAM_MODULES_DIR, + "${OPENPAM_MODULES_DIR%/}", + [OpenPAM modules directory]) + ])]) AC_SUBST(OPENPAM_MODULES_DIR) +AM_CONDITIONAL([CUSTOM_MODULES_DIR], [test x"$OPENPAM_MODULES_DIR" != x""]) AC_ARG_WITH([doc], AC_HELP_STRING([--without-doc], [do not build documentation]), @@ -64,7 +62,7 @@ AC_ARG_WITH([doc], AM_CONDITIONAL([WITH_DOC], [test x"$with_doc" = x"yes"]) AC_ARG_WITH([pam-unix], - AC_HELP_STRING([--with-pam-unix], [compile sample pam_unix(8) implementation]), + AC_HELP_STRING([--with-pam-unix], [compile sample pam_unix(8) module]), [], [with_pam_unix=no]) AM_CONDITIONAL([WITH_PAM_UNIX], [test x"$with_pam_unix" = x"yes"]) @@ -83,7 +81,11 @@ AM_CONDITIONAL([WITH_SU], [test x"$with_su" = x"yes"]) AC_CHECK_HEADERS([crypt.h]) -AC_CHECK_FUNCS([fdlopen fpurge strlcat strlcmp strlcpy]) +AC_CHECK_FUNCS([asprintf vasprintf]) +AC_CHECK_FUNCS([dlfunc fdlopen]) +AC_CHECK_FUNCS([fpurge]) +AC_CHECK_FUNCS([setlogmask]) +AC_CHECK_FUNCS([strlcat strlcmp strlcpy]) saved_LIBS="${LIBS}" LIBS="" @@ -99,6 +101,13 @@ CRYPT_LIBS="${LIBS}" LIBS="${saved_LIBS}" AC_SUBST(CRYPT_LIBS) +saved_LIBS="${LIBS}" +LIBS="" +AC_CHECK_LIB([crypto], [HMAC_CTX_init]) +CRYPTO_LIBS="${LIBS}" +LIBS="${saved_LIBS}" +AC_SUBST(CRYPTO_LIBS) + AC_ARG_ENABLE([developer-warnings], AS_HELP_STRING([--enable-developer-warnings], [enable strict warnings (default is NO)]), [CFLAGS="${CFLAGS} -Wall -Wextra"]) @@ -120,6 +129,7 @@ AC_CONFIG_FILES([ include/Makefile include/security/Makefile lib/Makefile + lib/libpam/Makefile modules/Makefile modules/pam_deny/Makefile modules/pam_permit/Makefile @@ -127,4 +137,5 @@ AC_CONFIG_FILES([ t/Makefile ]) AC_CONFIG_FILES([pamgdb],[chmod +x pamgdb]) +AC_CONFIG_FILES([mkpkgng],[chmod +x mkpkgng]) AC_OUTPUT diff --git a/contrib/openpam/depcomp b/contrib/openpam/depcomp index df8eea7e4ce8..4ebd5b3a2f2d 100755 --- a/contrib/openpam/depcomp +++ b/contrib/openpam/depcomp @@ -1,10 +1,9 @@ #! /bin/sh # depcomp - compile a program generating dependencies as side-effects -scriptversion=2009-04-28.21; # UTC +scriptversion=2013-05-30.07; # UTC -# Copyright (C) 1999, 2000, 2003, 2004, 2005, 2006, 2007, 2009 Free -# Software Foundation, Inc. +# Copyright (C) 1999-2013 Free Software Foundation, Inc. # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by @@ -28,9 +27,9 @@ scriptversion=2009-04-28.21; # UTC case $1 in '') - echo "$0: No command. Try \`$0 --help' for more information." 1>&2 - exit 1; - ;; + echo "$0: No command. Try '$0 --help' for more information." 1>&2 + exit 1; + ;; -h | --h*) cat <<\EOF Usage: depcomp [--help] [--version] PROGRAM [ARGS] @@ -40,11 +39,11 @@ as side-effects. Environment variables: depmode Dependency tracking mode. - source Source file read by `PROGRAMS ARGS'. - object Object file output by `PROGRAMS ARGS'. + source Source file read by 'PROGRAMS ARGS'. + object Object file output by 'PROGRAMS ARGS'. DEPDIR directory where to store dependencies. depfile Dependency file to output. - tmpdepfile Temporary file to use when outputing dependencies. + tmpdepfile Temporary file to use when outputting dependencies. libtool Whether libtool is used (yes/no). Report bugs to . @@ -57,6 +56,66 @@ EOF ;; esac +# Get the directory component of the given path, and save it in the +# global variables '$dir'. Note that this directory component will +# be either empty or ending with a '/' character. This is deliberate. +set_dir_from () +{ + case $1 in + */*) dir=`echo "$1" | sed -e 's|/[^/]*$|/|'`;; + *) dir=;; + esac +} + +# Get the suffix-stripped basename of the given path, and save it the +# global variable '$base'. +set_base_from () +{ + base=`echo "$1" | sed -e 's|^.*/||' -e 's/\.[^.]*$//'` +} + +# If no dependency file was actually created by the compiler invocation, +# we still have to create a dummy depfile, to avoid errors with the +# Makefile "include basename.Plo" scheme. +make_dummy_depfile () +{ + echo "#dummy" > "$depfile" +} + +# Factor out some common post-processing of the generated depfile. +# Requires the auxiliary global variable '$tmpdepfile' to be set. +aix_post_process_depfile () +{ + # If the compiler actually managed to produce a dependency file, + # post-process it. + if test -f "$tmpdepfile"; then + # Each line is of the form 'foo.o: dependency.h'. + # Do two passes, one to just change these to + # $object: dependency.h + # and one to simply output + # dependency.h: + # which is needed to avoid the deleted-header problem. + { sed -e "s,^.*\.[$lower]*:,$object:," < "$tmpdepfile" + sed -e "s,^.*\.[$lower]*:[$tab ]*,," -e 's,$,:,' < "$tmpdepfile" + } > "$depfile" + rm -f "$tmpdepfile" + else + make_dummy_depfile + fi +} + +# A tabulation character. +tab=' ' +# A newline character. +nl=' +' +# Character ranges might be problematic outside the C locale. +# These definitions help. +upper=ABCDEFGHIJKLMNOPQRSTUVWXYZ +lower=abcdefghijklmnopqrstuvwxyz +digits=0123456789 +alpha=${upper}${lower} + if test -z "$depmode" || test -z "$source" || test -z "$object"; then echo "depcomp: Variables source, object and depmode must be set" 1>&2 exit 1 @@ -69,6 +128,9 @@ tmpdepfile=${tmpdepfile-`echo "$depfile" | sed 's/\.\([^.]*\)$/.T\1/'`} rm -f "$tmpdepfile" +# Avoid interferences from the environment. +gccflag= dashmflag= + # Some modes work just like other modes, but use different flags. We # parameterize here, but still list the modes in the big case below, # to make depend.m4 easier to write. Note that we *cannot* use a case @@ -80,18 +142,32 @@ if test "$depmode" = hp; then fi if test "$depmode" = dashXmstdout; then - # This is just like dashmstdout with a different argument. - dashmflag=-xM - depmode=dashmstdout + # This is just like dashmstdout with a different argument. + dashmflag=-xM + depmode=dashmstdout fi cygpath_u="cygpath -u -f -" if test "$depmode" = msvcmsys; then - # This is just like msvisualcpp but w/o cygpath translation. - # Just convert the backslash-escaped backslashes to single forward - # slashes to satisfy depend.m4 - cygpath_u="sed s,\\\\\\\\,/,g" - depmode=msvisualcpp + # This is just like msvisualcpp but w/o cygpath translation. + # Just convert the backslash-escaped backslashes to single forward + # slashes to satisfy depend.m4 + cygpath_u='sed s,\\\\,/,g' + depmode=msvisualcpp +fi + +if test "$depmode" = msvc7msys; then + # This is just like msvc7 but w/o cygpath translation. + # Just convert the backslash-escaped backslashes to single forward + # slashes to satisfy depend.m4 + cygpath_u='sed s,\\\\,/,g' + depmode=msvc7 +fi + +if test "$depmode" = xlc; then + # IBM C/C++ Compilers xlc/xlC can output gcc-like dependency information. + gccflag=-qmakedep=gcc,-MF + depmode=gcc fi case "$depmode" in @@ -114,8 +190,7 @@ gcc3) done "$@" stat=$? - if test $stat -eq 0; then : - else + if test $stat -ne 0; then rm -f "$tmpdepfile" exit $stat fi @@ -123,13 +198,17 @@ gcc3) ;; gcc) +## Note that this doesn't just cater to obsosete pre-3.x GCC compilers. +## but also to in-use compilers like IMB xlc/xlC and the HP C compiler. +## (see the conditional assignment to $gccflag above). ## There are various ways to get dependency output from gcc. Here's ## why we pick this rather obscure method: ## - Don't want to use -MD because we'd like the dependencies to end ## up in a subdir. Having to rename by hand is ugly. ## (We might end up doing this anyway to support other compilers.) ## - The DEPENDENCIES_OUTPUT environment variable makes gcc act like -## -MM, not -M (despite what the docs say). +## -MM, not -M (despite what the docs say). Also, it might not be +## supported by the other compilers which use the 'gcc' depmode. ## - Using -M directly means running the compiler twice (even worse ## than renaming). if test -z "$gccflag"; then @@ -137,31 +216,31 @@ gcc) fi "$@" -Wp,"$gccflag$tmpdepfile" stat=$? - if test $stat -eq 0; then : - else + if test $stat -ne 0; then rm -f "$tmpdepfile" exit $stat fi rm -f "$depfile" echo "$object : \\" > "$depfile" - alpha=ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz -## The second -e expression handles DOS-style file names with drive letters. + # The second -e expression handles DOS-style file names with drive + # letters. sed -e 's/^[^:]*: / /' \ -e 's/^['$alpha']:\/[^:]*: / /' < "$tmpdepfile" >> "$depfile" -## This next piece of magic avoids the `deleted header file' problem. +## This next piece of magic avoids the "deleted header file" problem. ## The problem is that when a header file which appears in a .P file ## is deleted, the dependency causes make to die (because there is ## typically no way to rebuild the header). We avoid this by adding ## dummy dependencies for each header file. Too bad gcc doesn't do ## this for us directly. - tr ' ' ' -' < "$tmpdepfile" | -## Some versions of gcc put a space before the `:'. On the theory +## Some versions of gcc put a space before the ':'. On the theory ## that the space means something, we add a space to the output as -## well. +## well. hp depmode also adds that space, but also prefixes the VPATH +## to the object. Take care to not repeat it in the output. ## Some versions of the HPUX 10.20 sed can't process this invocation ## correctly. Breaking it into two sed invocations is a workaround. - sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile" + tr ' ' "$nl" < "$tmpdepfile" \ + | sed -e 's/^\\$//' -e '/^$/d' -e "s|.*$object$||" -e '/:$/d' \ + | sed -e 's/$/ :/' >> "$depfile" rm -f "$tmpdepfile" ;; @@ -179,8 +258,7 @@ sgi) "$@" -MDupdate "$tmpdepfile" fi stat=$? - if test $stat -eq 0; then : - else + if test $stat -ne 0; then rm -f "$tmpdepfile" exit $stat fi @@ -188,43 +266,41 @@ sgi) if test -f "$tmpdepfile"; then # yes, the sourcefile depend on other files echo "$object : \\" > "$depfile" - # Clip off the initial element (the dependent). Don't try to be # clever and replace this with sed code, as IRIX sed won't handle # lines with more than a fixed number of characters (4096 in # IRIX 6.2 sed, 8192 in IRIX 6.5). We also remove comment lines; - # the IRIX cc adds comments like `#:fec' to the end of the + # the IRIX cc adds comments like '#:fec' to the end of the # dependency line. - tr ' ' ' -' < "$tmpdepfile" \ - | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' | \ - tr ' -' ' ' >> "$depfile" + tr ' ' "$nl" < "$tmpdepfile" \ + | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' \ + | tr "$nl" ' ' >> "$depfile" echo >> "$depfile" - # The second pass generates a dummy entry for each header file. - tr ' ' ' -' < "$tmpdepfile" \ - | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' -e 's/$/:/' \ - >> "$depfile" + tr ' ' "$nl" < "$tmpdepfile" \ + | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' -e 's/$/:/' \ + >> "$depfile" else - # The sourcefile does not contain any dependencies, so just - # store a dummy comment line, to avoid errors with the Makefile - # "include basename.Plo" scheme. - echo "#dummy" > "$depfile" + make_dummy_depfile fi rm -f "$tmpdepfile" ;; +xlc) + # This case exists only to let depend.m4 do its work. It works by + # looking at the text of this script. This case will never be run, + # since it is checked for above. + exit 1 + ;; + aix) # The C for AIX Compiler uses -M and outputs the dependencies # in a .u file. In older versions, this file always lives in the - # current directory. Also, the AIX compiler puts `$object:' at the + # current directory. Also, the AIX compiler puts '$object:' at the # start of each line; $object doesn't have directory information. # Version 6 uses the directory in both cases. - dir=`echo "$object" | sed -e 's|/[^/]*$|/|'` - test "x$dir" = "x$object" && dir= - base=`echo "$object" | sed -e 's|^.*/||' -e 's/\.o$//' -e 's/\.lo$//'` + set_dir_from "$object" + set_base_from "$object" if test "$libtool" = yes; then tmpdepfile1=$dir$base.u tmpdepfile2=$base.u @@ -237,9 +313,7 @@ aix) "$@" -M fi stat=$? - - if test $stat -eq 0; then : - else + if test $stat -ne 0; then rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" exit $stat fi @@ -248,44 +322,100 @@ aix) do test -f "$tmpdepfile" && break done - if test -f "$tmpdepfile"; then - # Each line is of the form `foo.o: dependent.h'. - # Do two passes, one to just change these to - # `$object: dependent.h' and one to simply `dependent.h:'. - sed -e "s,^.*\.[a-z]*:,$object:," < "$tmpdepfile" > "$depfile" - # That's a tab and a space in the []. - sed -e 's,^.*\.[a-z]*:[ ]*,,' -e 's,$,:,' < "$tmpdepfile" >> "$depfile" - else - # The sourcefile does not contain any dependencies, so just - # store a dummy comment line, to avoid errors with the Makefile - # "include basename.Plo" scheme. - echo "#dummy" > "$depfile" + aix_post_process_depfile + ;; + +tcc) + # tcc (Tiny C Compiler) understand '-MD -MF file' since version 0.9.26 + # FIXME: That version still under development at the moment of writing. + # Make that this statement remains true also for stable, released + # versions. + # It will wrap lines (doesn't matter whether long or short) with a + # trailing '\', as in: + # + # foo.o : \ + # foo.c \ + # foo.h \ + # + # It will put a trailing '\' even on the last line, and will use leading + # spaces rather than leading tabs (at least since its commit 0394caf7 + # "Emit spaces for -MD"). + "$@" -MD -MF "$tmpdepfile" + stat=$? + if test $stat -ne 0; then + rm -f "$tmpdepfile" + exit $stat fi + rm -f "$depfile" + # Each non-empty line is of the form 'foo.o : \' or ' dep.h \'. + # We have to change lines of the first kind to '$object: \'. + sed -e "s|.*:|$object :|" < "$tmpdepfile" > "$depfile" + # And for each line of the second kind, we have to emit a 'dep.h:' + # dummy dependency, to avoid the deleted-header problem. + sed -n -e 's|^ *\(.*\) *\\$|\1:|p' < "$tmpdepfile" >> "$depfile" rm -f "$tmpdepfile" ;; -icc) - # Intel's C compiler understands `-MD -MF file'. However on - # icc -MD -MF foo.d -c -o sub/foo.o sub/foo.c - # ICC 7.0 will fill foo.d with something like - # foo.o: sub/foo.c - # foo.o: sub/foo.h - # which is wrong. We want: - # sub/foo.o: sub/foo.c - # sub/foo.o: sub/foo.h - # sub/foo.c: - # sub/foo.h: - # ICC 7.1 will output +## The order of this option in the case statement is important, since the +## shell code in configure will try each of these formats in the order +## listed in this file. A plain '-MD' option would be understood by many +## compilers, so we must ensure this comes after the gcc and icc options. +pgcc) + # Portland's C compiler understands '-MD'. + # Will always output deps to 'file.d' where file is the root name of the + # source file under compilation, even if file resides in a subdirectory. + # The object file name does not affect the name of the '.d' file. + # pgcc 10.2 will output # foo.o: sub/foo.c sub/foo.h - # and will wrap long lines using \ : + # and will wrap long lines using '\' : # foo.o: sub/foo.c ... \ # sub/foo.h ... \ # ... + set_dir_from "$object" + # Use the source, not the object, to determine the base name, since + # that's sadly what pgcc will do too. + set_base_from "$source" + tmpdepfile=$base.d - "$@" -MD -MF "$tmpdepfile" - stat=$? - if test $stat -eq 0; then : - else + # For projects that build the same source file twice into different object + # files, the pgcc approach of using the *source* file root name can cause + # problems in parallel builds. Use a locking strategy to avoid stomping on + # the same $tmpdepfile. + lockdir=$base.d-lock + trap " + echo '$0: caught signal, cleaning up...' >&2 + rmdir '$lockdir' + exit 1 + " 1 2 13 15 + numtries=100 + i=$numtries + while test $i -gt 0; do + # mkdir is a portable test-and-set. + if mkdir "$lockdir" 2>/dev/null; then + # This process acquired the lock. + "$@" -MD + stat=$? + # Release the lock. + rmdir "$lockdir" + break + else + # If the lock is being held by a different process, wait + # until the winning process is done or we timeout. + while test -d "$lockdir" && test $i -gt 0; do + sleep 1 + i=`expr $i - 1` + done + fi + i=`expr $i - 1` + done + trap - 1 2 13 15 + if test $i -le 0; then + echo "$0: failed to acquire lock after $numtries attempts" >&2 + echo "$0: check lockdir '$lockdir'" >&2 + exit 1 + fi + + if test $stat -ne 0; then rm -f "$tmpdepfile" exit $stat fi @@ -297,8 +427,8 @@ icc) sed "s,^[^:]*:,$object :," < "$tmpdepfile" > "$depfile" # Some versions of the HPUX 10.20 sed can't process this invocation # correctly. Breaking it into two sed invocations is a workaround. - sed 's,^[^:]*: \(.*\)$,\1,;s/^\\$//;/^$/d;/:$/d' < "$tmpdepfile" | - sed -e 's/$/ :/' >> "$depfile" + sed 's,^[^:]*: \(.*\)$,\1,;s/^\\$//;/^$/d;/:$/d' < "$tmpdepfile" \ + | sed -e 's/$/ :/' >> "$depfile" rm -f "$tmpdepfile" ;; @@ -309,9 +439,8 @@ hp2) # 'foo.d', which lands next to the object file, wherever that # happens to be. # Much of this is similar to the tru64 case; see comments there. - dir=`echo "$object" | sed -e 's|/[^/]*$|/|'` - test "x$dir" = "x$object" && dir= - base=`echo "$object" | sed -e 's|^.*/||' -e 's/\.o$//' -e 's/\.lo$//'` + set_dir_from "$object" + set_base_from "$object" if test "$libtool" = yes; then tmpdepfile1=$dir$base.d tmpdepfile2=$dir.libs/$base.d @@ -322,8 +451,7 @@ hp2) "$@" +Maked fi stat=$? - if test $stat -eq 0; then : - else + if test $stat -ne 0; then rm -f "$tmpdepfile1" "$tmpdepfile2" exit $stat fi @@ -333,77 +461,107 @@ hp2) test -f "$tmpdepfile" && break done if test -f "$tmpdepfile"; then - sed -e "s,^.*\.[a-z]*:,$object:," "$tmpdepfile" > "$depfile" - # Add `dependent.h:' lines. + sed -e "s,^.*\.[$lower]*:,$object:," "$tmpdepfile" > "$depfile" + # Add 'dependent.h:' lines. sed -ne '2,${ - s/^ *// - s/ \\*$// - s/$/:/ - p - }' "$tmpdepfile" >> "$depfile" + s/^ *// + s/ \\*$// + s/$/:/ + p + }' "$tmpdepfile" >> "$depfile" else - echo "#dummy" > "$depfile" + make_dummy_depfile fi rm -f "$tmpdepfile" "$tmpdepfile2" ;; tru64) - # The Tru64 compiler uses -MD to generate dependencies as a side - # effect. `cc -MD -o foo.o ...' puts the dependencies into `foo.o.d'. - # At least on Alpha/Redhat 6.1, Compaq CCC V6.2-504 seems to put - # dependencies in `foo.d' instead, so we check for that too. - # Subdirectories are respected. - dir=`echo "$object" | sed -e 's|/[^/]*$|/|'` - test "x$dir" = "x$object" && dir= - base=`echo "$object" | sed -e 's|^.*/||' -e 's/\.o$//' -e 's/\.lo$//'` + # The Tru64 compiler uses -MD to generate dependencies as a side + # effect. 'cc -MD -o foo.o ...' puts the dependencies into 'foo.o.d'. + # At least on Alpha/Redhat 6.1, Compaq CCC V6.2-504 seems to put + # dependencies in 'foo.d' instead, so we check for that too. + # Subdirectories are respected. + set_dir_from "$object" + set_base_from "$object" - if test "$libtool" = yes; then - # With Tru64 cc, shared objects can also be used to make a - # static library. This mechanism is used in libtool 1.4 series to - # handle both shared and static libraries in a single compilation. - # With libtool 1.4, dependencies were output in $dir.libs/$base.lo.d. - # - # With libtool 1.5 this exception was removed, and libtool now - # generates 2 separate objects for the 2 libraries. These two - # compilations output dependencies in $dir.libs/$base.o.d and - # in $dir$base.o.d. We have to check for both files, because - # one of the two compilations can be disabled. We should prefer - # $dir$base.o.d over $dir.libs/$base.o.d because the latter is - # automatically cleaned when .libs/ is deleted, while ignoring - # the former would cause a distcleancheck panic. - tmpdepfile1=$dir.libs/$base.lo.d # libtool 1.4 - tmpdepfile2=$dir$base.o.d # libtool 1.5 - tmpdepfile3=$dir.libs/$base.o.d # libtool 1.5 - tmpdepfile4=$dir.libs/$base.d # Compaq CCC V6.2-504 - "$@" -Wc,-MD - else - tmpdepfile1=$dir$base.o.d - tmpdepfile2=$dir$base.d - tmpdepfile3=$dir$base.d - tmpdepfile4=$dir$base.d - "$@" -MD - fi + if test "$libtool" = yes; then + # Libtool generates 2 separate objects for the 2 libraries. These + # two compilations output dependencies in $dir.libs/$base.o.d and + # in $dir$base.o.d. We have to check for both files, because + # one of the two compilations can be disabled. We should prefer + # $dir$base.o.d over $dir.libs/$base.o.d because the latter is + # automatically cleaned when .libs/ is deleted, while ignoring + # the former would cause a distcleancheck panic. + tmpdepfile1=$dir$base.o.d # libtool 1.5 + tmpdepfile2=$dir.libs/$base.o.d # Likewise. + tmpdepfile3=$dir.libs/$base.d # Compaq CCC V6.2-504 + "$@" -Wc,-MD + else + tmpdepfile1=$dir$base.d + tmpdepfile2=$dir$base.d + tmpdepfile3=$dir$base.d + "$@" -MD + fi - stat=$? - if test $stat -eq 0; then : - else - rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" "$tmpdepfile4" - exit $stat - fi + stat=$? + if test $stat -ne 0; then + rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" + exit $stat + fi - for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" "$tmpdepfile4" - do - test -f "$tmpdepfile" && break - done - if test -f "$tmpdepfile"; then - sed -e "s,^.*\.[a-z]*:,$object:," < "$tmpdepfile" > "$depfile" - # That's a tab and a space in the []. - sed -e 's,^.*\.[a-z]*:[ ]*,,' -e 's,$,:,' < "$tmpdepfile" >> "$depfile" - else - echo "#dummy" > "$depfile" - fi - rm -f "$tmpdepfile" - ;; + for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" + do + test -f "$tmpdepfile" && break + done + # Same post-processing that is required for AIX mode. + aix_post_process_depfile + ;; + +msvc7) + if test "$libtool" = yes; then + showIncludes=-Wc,-showIncludes + else + showIncludes=-showIncludes + fi + "$@" $showIncludes > "$tmpdepfile" + stat=$? + grep -v '^Note: including file: ' "$tmpdepfile" + if test $stat -ne 0; then + rm -f "$tmpdepfile" + exit $stat + fi + rm -f "$depfile" + echo "$object : \\" > "$depfile" + # The first sed program below extracts the file names and escapes + # backslashes for cygpath. The second sed program outputs the file + # name when reading, but also accumulates all include files in the + # hold buffer in order to output them again at the end. This only + # works with sed implementations that can handle large buffers. + sed < "$tmpdepfile" -n ' +/^Note: including file: *\(.*\)/ { + s//\1/ + s/\\/\\\\/g + p +}' | $cygpath_u | sort -u | sed -n ' +s/ /\\ /g +s/\(.*\)/'"$tab"'\1 \\/p +s/.\(.*\) \\/\1:/ +H +$ { + s/.*/'"$tab"'/ + G + p +}' >> "$depfile" + echo >> "$depfile" # make sure the fragment doesn't end with a backslash + rm -f "$tmpdepfile" + ;; + +msvc7msys) + # This case exists only to let depend.m4 do its work. It works by + # looking at the text of this script. This case will never be run, + # since it is checked for above. + exit 1 + ;; #nosideeffect) # This comment above is used by automake to tell side-effect @@ -422,7 +580,7 @@ dashmstdout) shift fi - # Remove `-o $object'. + # Remove '-o $object'. IFS=" " for arg do @@ -442,18 +600,18 @@ dashmstdout) done test -z "$dashmflag" && dashmflag=-M - # Require at least two characters before searching for `:' + # Require at least two characters before searching for ':' # in the target name. This is to cope with DOS-style filenames: - # a dependency such as `c:/foo/bar' could be seen as target `c' otherwise. + # a dependency such as 'c:/foo/bar' could be seen as target 'c' otherwise. "$@" $dashmflag | - sed 's:^[ ]*[^: ][^:][^:]*\:[ ]*:'"$object"'\: :' > "$tmpdepfile" + sed "s|^[$tab ]*[^:$tab ][^:][^:]*:[$tab ]*|$object: |" > "$tmpdepfile" rm -f "$depfile" cat < "$tmpdepfile" > "$depfile" - tr ' ' ' -' < "$tmpdepfile" | \ -## Some versions of the HPUX 10.20 sed can't process this invocation -## correctly. Breaking it into two sed invocations is a workaround. - sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile" + # Some versions of the HPUX 10.20 sed can't process this sed invocation + # correctly. Breaking it into two sed invocations is a workaround. + tr ' ' "$nl" < "$tmpdepfile" \ + | sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' \ + | sed -e 's/$/ :/' >> "$depfile" rm -f "$tmpdepfile" ;; @@ -503,12 +661,15 @@ makedepend) touch "$tmpdepfile" ${MAKEDEPEND-makedepend} -o"$obj_suffix" -f"$tmpdepfile" "$@" rm -f "$depfile" - cat < "$tmpdepfile" > "$depfile" - sed '1,2d' "$tmpdepfile" | tr ' ' ' -' | \ -## Some versions of the HPUX 10.20 sed can't process this invocation -## correctly. Breaking it into two sed invocations is a workaround. - sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile" + # makedepend may prepend the VPATH from the source file name to the object. + # No need to regex-escape $object, excess matching of '.' is harmless. + sed "s|^.*\($object *:\)|\1|" "$tmpdepfile" > "$depfile" + # Some versions of the HPUX 10.20 sed can't process the last invocation + # correctly. Breaking it into two sed invocations is a workaround. + sed '1,2d' "$tmpdepfile" \ + | tr ' ' "$nl" \ + | sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' \ + | sed -e 's/$/ :/' >> "$depfile" rm -f "$tmpdepfile" "$tmpdepfile".bak ;; @@ -525,7 +686,7 @@ cpp) shift fi - # Remove `-o $object'. + # Remove '-o $object'. IFS=" " for arg do @@ -544,10 +705,10 @@ cpp) esac done - "$@" -E | - sed -n -e '/^# [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' \ - -e '/^#line [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' | - sed '$ s: \\$::' > "$tmpdepfile" + "$@" -E \ + | sed -n -e '/^# [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' \ + -e '/^#line [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' \ + | sed '$ s: \\$::' > "$tmpdepfile" rm -f "$depfile" echo "$object : \\" > "$depfile" cat < "$tmpdepfile" >> "$depfile" @@ -579,23 +740,23 @@ msvisualcpp) shift ;; "-Gm"|"/Gm"|"-Gi"|"/Gi"|"-ZI"|"/ZI") - set fnord "$@" - shift - shift - ;; + set fnord "$@" + shift + shift + ;; *) - set fnord "$@" "$arg" - shift - shift - ;; + set fnord "$@" "$arg" + shift + shift + ;; esac done "$@" -E 2>/dev/null | sed -n '/^#line [0-9][0-9]* "\([^"]*\)"/ s::\1:p' | $cygpath_u | sort -u > "$tmpdepfile" rm -f "$depfile" echo "$object : \\" > "$depfile" - sed < "$tmpdepfile" -n -e 's% %\\ %g' -e '/^\(.*\)$/ s:: \1 \\:p' >> "$depfile" - echo " " >> "$depfile" + sed < "$tmpdepfile" -n -e 's% %\\ %g' -e '/^\(.*\)$/ s::'"$tab"'\1 \\:p' >> "$depfile" + echo "$tab" >> "$depfile" sed < "$tmpdepfile" -n -e 's% %\\ %g' -e '/^\(.*\)$/ s::\1\::p' >> "$depfile" rm -f "$tmpdepfile" ;; diff --git a/contrib/openpam/doc/Makefile.am b/contrib/openpam/doc/Makefile.am index 374d969b7e22..cb9f04a1f6fe 100644 --- a/contrib/openpam/doc/Makefile.am +++ b/contrib/openpam/doc/Makefile.am @@ -1,3 +1,3 @@ -# $Id: Makefile.am 320 2006-02-16 20:33:19Z des $ +# $Id: Makefile.am 648 2013-03-05 17:54:27Z des $ SUBDIRS = man diff --git a/contrib/openpam/doc/Makefile.in b/contrib/openpam/doc/Makefile.in index 9962a72ccc7d..83070401d420 100644 --- a/contrib/openpam/doc/Makefile.in +++ b/contrib/openpam/doc/Makefile.in @@ -1,9 +1,8 @@ -# Makefile.in generated by automake 1.11.1 from Makefile.am. +# Makefile.in generated by automake 1.14 from Makefile.am. # @configure_input@ -# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, -# 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation, -# Inc. +# Copyright (C) 1994-2013 Free Software Foundation, Inc. + # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. @@ -15,8 +14,53 @@ @SET_MAKE@ -# $Id: Makefile.am 320 2006-02-16 20:33:19Z des $ +# $Id: Makefile.am 648 2013-03-05 17:54:27Z des $ VPATH = @srcdir@ +am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)' +am__make_running_with_option = \ + case $${target_option-} in \ + ?) ;; \ + *) echo "am__make_running_with_option: internal error: invalid" \ + "target option '$${target_option-}' specified" >&2; \ + exit 1;; \ + esac; \ + has_opt=no; \ + sane_makeflags=$$MAKEFLAGS; \ + if $(am__is_gnu_make); then \ + sane_makeflags=$$MFLAGS; \ + else \ + case $$MAKEFLAGS in \ + *\\[\ \ ]*) \ + bs=\\; \ + sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ + | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ + esac; \ + fi; \ + skip_next=no; \ + strip_trailopt () \ + { \ + flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ + }; \ + for flg in $$sane_makeflags; do \ + test $$skip_next = yes && { skip_next=no; continue; }; \ + case $$flg in \ + *=*|--*) continue;; \ + -*I) strip_trailopt 'I'; skip_next=yes;; \ + -*I?*) strip_trailopt 'I';; \ + -*O) strip_trailopt 'O'; skip_next=yes;; \ + -*O?*) strip_trailopt 'O';; \ + -*l) strip_trailopt 'l'; skip_next=yes;; \ + -*l?*) strip_trailopt 'l';; \ + -[dEDm]) skip_next=yes;; \ + -[JT]) skip_next=yes;; \ + esac; \ + case $$flg in \ + *$$target_option*) has_opt=yes; break;; \ + esac; \ + done; \ + test $$has_opt = yes +am__make_dryrun = (target_option=n; $(am__make_running_with_option)) +am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ @@ -36,29 +80,70 @@ POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = doc -DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in +DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 -am__aclocal_m4_deps = $(top_srcdir)/configure.ac +am__aclocal_m4_deps = $(top_srcdir)/m4/libtool.m4 \ + $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \ + $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \ + $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = +AM_V_P = $(am__v_P_@AM_V@) +am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) +am__v_P_0 = false +am__v_P_1 = : +AM_V_GEN = $(am__v_GEN_@AM_V@) +am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) +am__v_GEN_0 = @echo " GEN " $@; +am__v_GEN_1 = +AM_V_at = $(am__v_at_@AM_V@) +am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) +am__v_at_0 = @ +am__v_at_1 = SOURCES = DIST_SOURCES = -RECURSIVE_TARGETS = all-recursive check-recursive dvi-recursive \ - html-recursive info-recursive install-data-recursive \ - install-dvi-recursive install-exec-recursive \ - install-html-recursive install-info-recursive \ - install-pdf-recursive install-ps-recursive install-recursive \ - installcheck-recursive installdirs-recursive pdf-recursive \ - ps-recursive uninstall-recursive +RECURSIVE_TARGETS = all-recursive check-recursive cscopelist-recursive \ + ctags-recursive dvi-recursive html-recursive info-recursive \ + install-data-recursive install-dvi-recursive \ + install-exec-recursive install-html-recursive \ + install-info-recursive install-pdf-recursive \ + install-ps-recursive install-recursive installcheck-recursive \ + installdirs-recursive pdf-recursive ps-recursive \ + tags-recursive uninstall-recursive +am__can_run_installinfo = \ + case $$AM_UPDATE_INFO_DIR in \ + n|no|NO) false;; \ + *) (install-info --version) >/dev/null 2>&1;; \ + esac RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \ distclean-recursive maintainer-clean-recursive -AM_RECURSIVE_TARGETS = $(RECURSIVE_TARGETS:-recursive=) \ - $(RECURSIVE_CLEAN_TARGETS:-recursive=) tags TAGS ctags CTAGS \ +am__recursive_targets = \ + $(RECURSIVE_TARGETS) \ + $(RECURSIVE_CLEAN_TARGETS) \ + $(am__extra_recursive_targets) +AM_RECURSIVE_TARGETS = $(am__recursive_targets:-recursive=) TAGS CTAGS \ distdir +am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) +# Read a list of newline-separated strings from the standard input, +# and print each of them once, without duplicates. Input order is +# *not* preserved. +am__uniquify_input = $(AWK) '\ + BEGIN { nonempty = 0; } \ + { items[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in items) print i; }; } \ +' +# Make sure the list of sources is unique. This is necessary because, +# e.g., the same source file might be shared among _SOURCES variables +# for different programs/libraries. +am__define_uniq_tagged_files = \ + list='$(am__tagged_files)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | $(am__uniquify_input)` ETAGS = etags CTAGS = ctags DIST_SUBDIRS = $(SUBDIRS) @@ -90,6 +175,7 @@ am__relativize = \ reldir="$$dir2" ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ +AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ @@ -100,6 +186,7 @@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ +CRYPTO_LIBS = @CRYPTO_LIBS@ CRYPT_LIBS = @CRYPT_LIBS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ @@ -247,22 +334,25 @@ clean-libtool: -rm -rf .libs _libs # This directory's subdirectories are mostly independent; you can cd -# into them and run `make' without going through this Makefile. -# To change the values of `make' variables: instead of editing Makefiles, -# (1) if the variable is set in `config.status', edit `config.status' -# (which will cause the Makefiles to be regenerated when you run `make'); -# (2) otherwise, pass the desired values on the `make' command line. -$(RECURSIVE_TARGETS): - @fail= failcom='exit 1'; \ - for f in x $$MAKEFLAGS; do \ - case $$f in \ - *=* | --[!k]*);; \ - *k*) failcom='fail=yes';; \ - esac; \ - done; \ +# into them and run 'make' without going through this Makefile. +# To change the values of 'make' variables: instead of editing Makefiles, +# (1) if the variable is set in 'config.status', edit 'config.status' +# (which will cause the Makefiles to be regenerated when you run 'make'); +# (2) otherwise, pass the desired values on the 'make' command line. +$(am__recursive_targets): + @fail=; \ + if $(am__make_keepgoing); then \ + failcom='fail=yes'; \ + else \ + failcom='exit 1'; \ + fi; \ dot_seen=no; \ target=`echo $@ | sed s/-recursive//`; \ - list='$(SUBDIRS)'; for subdir in $$list; do \ + case "$@" in \ + distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ + *) list='$(SUBDIRS)' ;; \ + esac; \ + for subdir in $$list; do \ echo "Making $$target in $$subdir"; \ if test "$$subdir" = "."; then \ dot_seen=yes; \ @@ -277,57 +367,12 @@ $(RECURSIVE_TARGETS): $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ fi; test -z "$$fail" -$(RECURSIVE_CLEAN_TARGETS): - @fail= failcom='exit 1'; \ - for f in x $$MAKEFLAGS; do \ - case $$f in \ - *=* | --[!k]*);; \ - *k*) failcom='fail=yes';; \ - esac; \ - done; \ - dot_seen=no; \ - case "$@" in \ - distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ - *) list='$(SUBDIRS)' ;; \ - esac; \ - rev=''; for subdir in $$list; do \ - if test "$$subdir" = "."; then :; else \ - rev="$$subdir $$rev"; \ - fi; \ - done; \ - rev="$$rev ."; \ - target=`echo $@ | sed s/-recursive//`; \ - for subdir in $$rev; do \ - echo "Making $$target in $$subdir"; \ - if test "$$subdir" = "."; then \ - local_target="$$target-am"; \ - else \ - local_target="$$target"; \ - fi; \ - ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ - || eval $$failcom; \ - done && test -z "$$fail" -tags-recursive: - list='$(SUBDIRS)'; for subdir in $$list; do \ - test "$$subdir" = . || ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) tags); \ - done -ctags-recursive: - list='$(SUBDIRS)'; for subdir in $$list; do \ - test "$$subdir" = . || ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) ctags); \ - done +ID: $(am__tagged_files) + $(am__define_uniq_tagged_files); mkid -fID $$unique +tags: tags-recursive +TAGS: tags -ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) - list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ - unique=`for i in $$list; do \ - if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ - done | \ - $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ - END { if (nonempty) { for (i in files) print i; }; }'`; \ - mkid -fID $$unique -tags: TAGS - -TAGS: tags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ - $(TAGS_FILES) $(LISP) +tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \ @@ -343,12 +388,7 @@ TAGS: tags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \ fi; \ done; \ - list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ - unique=`for i in $$list; do \ - if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ - done | \ - $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ - END { if (nonempty) { for (i in files) print i; }; }'`; \ + $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ @@ -360,15 +400,11 @@ TAGS: tags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $$unique; \ fi; \ fi -ctags: CTAGS -CTAGS: ctags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ - $(TAGS_FILES) $(LISP) - list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ - unique=`for i in $$list; do \ - if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ - done | \ - $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ - END { if (nonempty) { for (i in files) print i; }; }'`; \ +ctags: ctags-recursive + +CTAGS: ctags +ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique @@ -377,6 +413,21 @@ GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" +cscopelist: cscopelist-recursive + +cscopelist-am: $(am__tagged_files) + list='$(am__tagged_files)'; \ + case "$(srcdir)" in \ + [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ + *) sdir=$(subdir)/$(srcdir) ;; \ + esac; \ + for i in $$list; do \ + if test -f "$$i"; then \ + echo "$(subdir)/$$i"; \ + else \ + echo "$$sdir/$$i"; \ + fi; \ + done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags @@ -413,13 +464,10 @@ distdir: $(DISTFILES) done @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ - test -d "$(distdir)/$$subdir" \ - || $(MKDIR_P) "$(distdir)/$$subdir" \ - || exit 1; \ - fi; \ - done - @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ - if test "$$subdir" = .; then :; else \ + $(am__make_dryrun) \ + || test -d "$(distdir)/$$subdir" \ + || $(MKDIR_P) "$(distdir)/$$subdir" \ + || exit 1; \ dir1=$$subdir; dir2="$(distdir)/$$subdir"; \ $(am__relativize); \ new_distdir=$$reldir; \ @@ -454,10 +502,15 @@ install-am: all-am installcheck: installcheck-recursive install-strip: - $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ - install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ - `test -z '$(STRIP)' || \ - echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install + if test -z '$(STRIP)'; then \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + install; \ + else \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ + fi mostlyclean-generic: clean-generic: @@ -535,22 +588,20 @@ ps-am: uninstall-am: -.MAKE: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) ctags-recursive \ - install-am install-strip tags-recursive +.MAKE: $(am__recursive_targets) install-am install-strip -.PHONY: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) CTAGS GTAGS \ - all all-am check check-am clean clean-generic clean-libtool \ - ctags ctags-recursive distclean distclean-generic \ - distclean-libtool distclean-tags distdir dvi dvi-am html \ - html-am info info-am install install-am install-data \ - install-data-am install-dvi install-dvi-am install-exec \ - install-exec-am install-html install-html-am install-info \ - install-info-am install-man install-pdf install-pdf-am \ - install-ps install-ps-am install-strip installcheck \ - installcheck-am installdirs installdirs-am maintainer-clean \ - maintainer-clean-generic mostlyclean mostlyclean-generic \ - mostlyclean-libtool pdf pdf-am ps ps-am tags tags-recursive \ - uninstall uninstall-am +.PHONY: $(am__recursive_targets) CTAGS GTAGS TAGS all all-am check \ + check-am clean clean-generic clean-libtool cscopelist-am ctags \ + ctags-am distclean distclean-generic distclean-libtool \ + distclean-tags distdir dvi dvi-am html html-am info info-am \ + install install-am install-data install-data-am install-dvi \ + install-dvi-am install-exec install-exec-am install-html \ + install-html-am install-info install-info-am install-man \ + install-pdf install-pdf-am install-ps install-ps-am \ + install-strip installcheck installcheck-am installdirs \ + installdirs-am maintainer-clean maintainer-clean-generic \ + mostlyclean mostlyclean-generic mostlyclean-libtool pdf pdf-am \ + ps ps-am tags tags-am uninstall uninstall-am # Tell versions [3.59,3.63) of GNU make to not export all variables. diff --git a/contrib/openpam/doc/man/Makefile.am b/contrib/openpam/doc/man/Makefile.am index 4062a54d54fb..920c709dcf21 100644 --- a/contrib/openpam/doc/man/Makefile.am +++ b/contrib/openpam/doc/man/Makefile.am @@ -1,4 +1,4 @@ -# $Id: Makefile.am 594 2012-04-14 14:18:41Z des $ +# $Id: Makefile.am 720 2013-08-19 16:02:10Z des $ NULL = @@ -64,26 +64,29 @@ OMAN = \ EXTRA_DIST = openpam.man pam.man ALLCMAN = $(PMAN) $(MMAN) $(OMAN) +GENMAN = $(ALLCMAN) openpam.3 pam.3 -dist_man3_MANS = $(ALLCMAN) openpam.3 pam.3 pam_conv.3 +dist_man3_MANS = $(GENMAN) pam_conv.3 dist_man5_MANS = pam.conf.5 -CLEANFILES = $(ALLCMAN) openpam.3 pam.3 +CLEANFILES = $(GENMAN) GENDOC = $(top_srcdir)/misc/gendoc.pl -LIBSRCDIR = $(top_srcdir)/lib +LIBSRCDIR = $(top_srcdir)/lib/libpam VPATH = $(LIBSRCDIR) $(srcdir) SUFFIXES = .3 .c.3: $(GENDOC) - perl -w $(GENDOC) $< + perl -w $(GENDOC) $< || rm $@ -openpam.3: $(OMAN) $(GENDOC) $(srcdir)/openpam.man - perl -w $(GENDOC) -o $(abs_srcdir)/$(OMAN) <$(srcdir)/openpam.man +openpam.3: $(OPENPAM_MAN) $(GENDOC) $(srcdir)/openpam.man + perl -w $(GENDOC) -o $(OPENPAM_MAN) <$(srcdir)/openpam.man || rm $@ -pam.3: $(PMAN) $(GENDOC) $(srcdir)/pam.man - perl -w $(GENDOC) -p $(abs_srcdir)/$(PMAN) <$(srcdir)/pam.man +pam.3: $(PAM_MAN) $(GENDOC) $(srcdir)/pam.man + perl -w $(GENDOC) -p $(PAM_MAN) <$(srcdir)/pam.man || rm $@ + +$(GENMAN): $(GENDOC) diff --git a/contrib/openpam/doc/man/Makefile.in b/contrib/openpam/doc/man/Makefile.in index 298304d0ec47..efb43c1ed947 100644 --- a/contrib/openpam/doc/man/Makefile.in +++ b/contrib/openpam/doc/man/Makefile.in @@ -1,9 +1,8 @@ -# Makefile.in generated by automake 1.11.1 from Makefile.am. +# Makefile.in generated by automake 1.14 from Makefile.am. # @configure_input@ -# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, -# 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation, -# Inc. +# Copyright (C) 1994-2013 Free Software Foundation, Inc. + # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. @@ -15,7 +14,52 @@ @SET_MAKE@ -# $Id: Makefile.am 594 2012-04-14 14:18:41Z des $ +# $Id: Makefile.am 720 2013-08-19 16:02:10Z des $ +am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)' +am__make_running_with_option = \ + case $${target_option-} in \ + ?) ;; \ + *) echo "am__make_running_with_option: internal error: invalid" \ + "target option '$${target_option-}' specified" >&2; \ + exit 1;; \ + esac; \ + has_opt=no; \ + sane_makeflags=$$MAKEFLAGS; \ + if $(am__is_gnu_make); then \ + sane_makeflags=$$MFLAGS; \ + else \ + case $$MAKEFLAGS in \ + *\\[\ \ ]*) \ + bs=\\; \ + sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ + | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ + esac; \ + fi; \ + skip_next=no; \ + strip_trailopt () \ + { \ + flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ + }; \ + for flg in $$sane_makeflags; do \ + test $$skip_next = yes && { skip_next=no; continue; }; \ + case $$flg in \ + *=*|--*) continue;; \ + -*I) strip_trailopt 'I'; skip_next=yes;; \ + -*I?*) strip_trailopt 'I';; \ + -*O) strip_trailopt 'O'; skip_next=yes;; \ + -*O?*) strip_trailopt 'O';; \ + -*l) strip_trailopt 'l'; skip_next=yes;; \ + -*l?*) strip_trailopt 'l';; \ + -[dEDm]) skip_next=yes;; \ + -[JT]) skip_next=yes;; \ + esac; \ + case $$flg in \ + *$$target_option*) has_opt=yes; break;; \ + esac; \ + done; \ + test $$has_opt = yes +am__make_dryrun = (target_option=n; $(am__make_running_with_option)) +am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ @@ -35,18 +79,38 @@ POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = doc/man -DIST_COMMON = $(dist_man3_MANS) $(dist_man5_MANS) \ - $(srcdir)/Makefile.am $(srcdir)/Makefile.in +DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \ + $(dist_man3_MANS) $(dist_man5_MANS) ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 -am__aclocal_m4_deps = $(top_srcdir)/configure.ac +am__aclocal_m4_deps = $(top_srcdir)/m4/libtool.m4 \ + $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \ + $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \ + $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = +AM_V_P = $(am__v_P_@AM_V@) +am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) +am__v_P_0 = false +am__v_P_1 = : +AM_V_GEN = $(am__v_GEN_@AM_V@) +am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) +am__v_GEN_0 = @echo " GEN " $@; +am__v_GEN_1 = +AM_V_at = $(am__v_at_@AM_V@) +am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) +am__v_at_0 = @ +am__v_at_1 = SOURCES = DIST_SOURCES = +am__can_run_installinfo = \ + case $$AM_UPDATE_INFO_DIR in \ + n|no|NO) false;; \ + *) (install-info --version) >/dev/null 2>&1;; \ + esac am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; am__vpath_adj = case $$p in \ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ @@ -68,15 +132,23 @@ am__nobase_list = $(am__nobase_strip_setup); \ am__base_list = \ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' +am__uninstall_files_from_dir = { \ + test -z "$$files" \ + || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ + || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ + $(am__cd) "$$dir" && rm -f $$files; }; \ + } man3dir = $(mandir)/man3 am__installdirs = "$(DESTDIR)$(man3dir)" "$(DESTDIR)$(man5dir)" man5dir = $(mandir)/man5 NROFF = nroff MANS = $(dist_man3_MANS) $(dist_man5_MANS) +am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) VPATH = $(LIBSRCDIR) $(srcdir) ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ +AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ @@ -87,6 +159,7 @@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ +CRYPTO_LIBS = @CRYPTO_LIBS@ CRYPT_LIBS = @CRYPT_LIBS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ @@ -257,11 +330,12 @@ OMAN = \ EXTRA_DIST = openpam.man pam.man ALLCMAN = $(PMAN) $(MMAN) $(OMAN) -dist_man3_MANS = $(ALLCMAN) openpam.3 pam.3 pam_conv.3 +GENMAN = $(ALLCMAN) openpam.3 pam.3 +dist_man3_MANS = $(GENMAN) pam_conv.3 dist_man5_MANS = pam.conf.5 -CLEANFILES = $(ALLCMAN) openpam.3 pam.3 +CLEANFILES = $(GENMAN) GENDOC = $(top_srcdir)/misc/gendoc.pl -LIBSRCDIR = $(top_srcdir)/lib +LIBSRCDIR = $(top_srcdir)/lib/libpam SUFFIXES = .3 all: all-am @@ -305,9 +379,18 @@ clean-libtool: -rm -rf .libs _libs install-man3: $(dist_man3_MANS) @$(NORMAL_INSTALL) - test -z "$(man3dir)" || $(MKDIR_P) "$(DESTDIR)$(man3dir)" - @list='$(dist_man3_MANS)'; test -n "$(man3dir)" || exit 0; \ - { for i in $$list; do echo "$$i"; done; \ + @list1='$(dist_man3_MANS)'; \ + list2=''; \ + test -n "$(man3dir)" \ + && test -n "`echo $$list1$$list2`" \ + || exit 0; \ + echo " $(MKDIR_P) '$(DESTDIR)$(man3dir)'"; \ + $(MKDIR_P) "$(DESTDIR)$(man3dir)" || exit 1; \ + { for i in $$list1; do echo "$$i"; done; \ + if test -n "$$list2"; then \ + for i in $$list2; do echo "$$i"; done \ + | sed -n '/\.3[a-z]*$$/p'; \ + fi; \ } | while read p; do \ if test -f $$p; then d=; else d="$(srcdir)/"; fi; \ echo "$$d$$p"; echo "$$p"; \ @@ -334,14 +417,21 @@ uninstall-man3: files=`{ for i in $$list; do echo "$$i"; done; \ } | sed -e 's,.*/,,;h;s,.*\.,,;s,^[^3][0-9a-z]*$$,3,;x' \ -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,'`; \ - test -z "$$files" || { \ - echo " ( cd '$(DESTDIR)$(man3dir)' && rm -f" $$files ")"; \ - cd "$(DESTDIR)$(man3dir)" && rm -f $$files; } + dir='$(DESTDIR)$(man3dir)'; $(am__uninstall_files_from_dir) install-man5: $(dist_man5_MANS) @$(NORMAL_INSTALL) - test -z "$(man5dir)" || $(MKDIR_P) "$(DESTDIR)$(man5dir)" - @list='$(dist_man5_MANS)'; test -n "$(man5dir)" || exit 0; \ - { for i in $$list; do echo "$$i"; done; \ + @list1='$(dist_man5_MANS)'; \ + list2=''; \ + test -n "$(man5dir)" \ + && test -n "`echo $$list1$$list2`" \ + || exit 0; \ + echo " $(MKDIR_P) '$(DESTDIR)$(man5dir)'"; \ + $(MKDIR_P) "$(DESTDIR)$(man5dir)" || exit 1; \ + { for i in $$list1; do echo "$$i"; done; \ + if test -n "$$list2"; then \ + for i in $$list2; do echo "$$i"; done \ + | sed -n '/\.5[a-z]*$$/p'; \ + fi; \ } | while read p; do \ if test -f $$p; then d=; else d="$(srcdir)/"; fi; \ echo "$$d$$p"; echo "$$p"; \ @@ -368,30 +458,15 @@ uninstall-man5: files=`{ for i in $$list; do echo "$$i"; done; \ } | sed -e 's,.*/,,;h;s,.*\.,,;s,^[^5][0-9a-z]*$$,5,;x' \ -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,'`; \ - test -z "$$files" || { \ - echo " ( cd '$(DESTDIR)$(man5dir)' && rm -f" $$files ")"; \ - cd "$(DESTDIR)$(man5dir)" && rm -f $$files; } -tags: TAGS -TAGS: + dir='$(DESTDIR)$(man5dir)'; $(am__uninstall_files_from_dir) +tags TAGS: -ctags: CTAGS -CTAGS: +ctags CTAGS: + +cscope cscopelist: distdir: $(DISTFILES) - @list='$(MANS)'; if test -n "$$list"; then \ - list=`for p in $$list; do \ - if test -f $$p; then d=; else d="$(srcdir)/"; fi; \ - if test -f "$$d$$p"; then echo "$$d$$p"; else :; fi; done`; \ - if test -n "$$list" && \ - grep 'ab help2man is required to generate this page' $$list >/dev/null; then \ - echo "error: found man pages containing the \`missing help2man' replacement text:" >&2; \ - grep -l 'ab help2man is required to generate this page' $$list | sed 's/^/ /' >&2; \ - echo " to fix them, install help2man, remove and regenerate the man pages;" >&2; \ - echo " typically \`make maintainer-clean' will remove them" >&2; \ - exit 1; \ - else :; fi; \ - else :; fi @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ @@ -438,10 +513,15 @@ install-am: all-am installcheck: installcheck-am install-strip: - $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ - install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ - `test -z '$(STRIP)' || \ - echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install + if test -z '$(STRIP)'; then \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + install; \ + else \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ + fi mostlyclean-generic: clean-generic: @@ -525,27 +605,29 @@ uninstall-man: uninstall-man3 uninstall-man5 .MAKE: install-am install-strip .PHONY: all all-am check check-am clean clean-generic clean-libtool \ - distclean distclean-generic distclean-libtool distdir dvi \ - dvi-am html html-am info info-am install install-am \ - install-data install-data-am install-dvi install-dvi-am \ - install-exec install-exec-am install-html install-html-am \ - install-info install-info-am install-man install-man3 \ - install-man5 install-pdf install-pdf-am install-ps \ - install-ps-am install-strip installcheck installcheck-am \ - installdirs maintainer-clean maintainer-clean-generic \ - mostlyclean mostlyclean-generic mostlyclean-libtool pdf pdf-am \ - ps ps-am uninstall uninstall-am uninstall-man uninstall-man3 \ - uninstall-man5 + cscopelist-am ctags-am distclean distclean-generic \ + distclean-libtool distdir dvi dvi-am html html-am info info-am \ + install install-am install-data install-data-am install-dvi \ + install-dvi-am install-exec install-exec-am install-html \ + install-html-am install-info install-info-am install-man \ + install-man3 install-man5 install-pdf install-pdf-am \ + install-ps install-ps-am install-strip installcheck \ + installcheck-am installdirs maintainer-clean \ + maintainer-clean-generic mostlyclean mostlyclean-generic \ + mostlyclean-libtool pdf pdf-am ps ps-am tags-am uninstall \ + uninstall-am uninstall-man uninstall-man3 uninstall-man5 .c.3: $(GENDOC) - perl -w $(GENDOC) $< + perl -w $(GENDOC) $< || rm $@ -openpam.3: $(OMAN) $(GENDOC) $(srcdir)/openpam.man - perl -w $(GENDOC) -o $(abs_srcdir)/$(OMAN) <$(srcdir)/openpam.man +openpam.3: $(OPENPAM_MAN) $(GENDOC) $(srcdir)/openpam.man + perl -w $(GENDOC) -o $(OPENPAM_MAN) <$(srcdir)/openpam.man || rm $@ -pam.3: $(PMAN) $(GENDOC) $(srcdir)/pam.man - perl -w $(GENDOC) -p $(abs_srcdir)/$(PMAN) <$(srcdir)/pam.man +pam.3: $(PAM_MAN) $(GENDOC) $(srcdir)/pam.man + perl -w $(GENDOC) -p $(PAM_MAN) <$(srcdir)/pam.man || rm $@ + +$(GENMAN): $(GENDOC) # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. diff --git a/contrib/openpam/doc/man/openpam.3 b/contrib/openpam/doc/man/openpam.3 index a3ff7fc6ce2e..f7b737386ff6 100644 --- a/contrib/openpam/doc/man/openpam.3 +++ b/contrib/openpam/doc/man/openpam.3 @@ -1,122 +1,15 @@ -.\"- -.\" Copyright (c) 2001-2003 Networks Associates Technology, Inc. -.\" Copyright (c) 2004-2011 Dag-Erling Smørgrav -.\" All rights reserved. -.\" -.\" This software was developed for the FreeBSD Project by ThinkSec AS and -.\" Network Associates Laboratories, the Security Research Division of -.\" Network Associates, Inc. under DARPA/SPAWAR contract N66001-01-C-8035 -.\" ("CBOSS"), as part of the DARPA CHATS research program. -.\" -.\" Redistribution and use in source and binary forms, with or without -.\" modification, are permitted provided that the following conditions -.\" are met: -.\" 1. Redistributions of source code must retain the above copyright -.\" notice, this list of conditions and the following disclaimer. -.\" 2. Redistributions in binary form must reproduce the above copyright -.\" notice, this list of conditions and the following disclaimer in the -.\" documentation and/or other materials provided with the distribution. -.\" 3. The name of the author may not be used to endorse or promote -.\" products derived from this software without specific prior written -.\" permission. -.\" -.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND -.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE -.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS -.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY -.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -.\" SUCH DAMAGE. -.\" -.\" $Id$ -.\" -.Dd May 26, 2012 +.\" Generated by gendoc.pl +.Dd September 7, 2013 .Dt OPENPAM 3 .Os .Sh NAME -.Nm openpam_borrow_cred , -.Nm openpam_free_data , -.Nm openpam_free_envlist , -.Nm openpam_get_feature , -.Nm openpam_get_option , -.Nm openpam_log , -.Nm openpam_nullconv , -.Nm openpam_readline , -.Nm openpam_readlinev , -.Nm openpam_readword , -.Nm openpam_restore_cred , -.Nm openpam_set_feature , -.Nm openpam_set_option , -.Nm openpam_straddch , -.Nm openpam_subst , -.Nm openpam_ttyconv , -.Nm pam_error , -.Nm pam_get_authtok , -.Nm pam_info , -.Nm pam_prompt , -.Nm pam_setenv , -.Nm pam_verror , -.Nm pam_vinfo , -.Nm pam_vprompt .Nd Pluggable Authentication Modules Library .Sh LIBRARY .Lb libpam .Sh SYNOPSIS .In security/openpam.h -.Ft "int" -.Fn openpam_borrow_cred "pam_handle_t *pamh" "const struct passwd *pwd" -.Ft "void" -.Fn openpam_free_data "pam_handle_t *pamh" "void *data" "int status" -.Ft "void" -.Fn openpam_free_envlist "char **envlist" -.Ft "int" -.Fn openpam_get_feature "int feature" "int *onoff" -.Ft "const char *" -.Fn openpam_get_option "pam_handle_t *pamh" "const char *option" -.Ft "void" -.Fn openpam_log "int level" "const char *fmt" "..." -.Ft "int" -.Fn openpam_nullconv "int n" "const struct pam_message **msg" "struct pam_response **resp" "void *data" -.Ft "char *" -.Fn openpam_readline "FILE *f" "int *lineno" "size_t *lenp" -.Ft "char **" -.Fn openpam_readlinev "FILE *f" "int *lineno" "int *lenp" -.Ft "char *" -.Fn openpam_readword "FILE *f" "int *lineno" "size_t *lenp" -.Ft "int" -.Fn openpam_restore_cred "pam_handle_t *pamh" -.Ft "int" -.Fn openpam_set_feature "int feature" "int onoff" -.Ft "int" -.Fn openpam_set_option "pam_handle_t *pamh" "const char *option" "const char *value" -.Ft "int" -.Fn openpam_straddch "char **str" "size_t *size" "size_t *len" "int ch" -.Ft "int" -.Fn openpam_subst "const pam_handle_t *pamh" "char *buf" "size_t *bufsize" "const char *template" -.Ft "int" -.Fn openpam_ttyconv "int n" "const struct pam_message **msg" "struct pam_response **resp" "void *data" -.Ft "int" -.Fn pam_error "const pam_handle_t *pamh" "const char *fmt" "..." -.Ft "int" -.Fn pam_get_authtok "pam_handle_t *pamh" "int item" "const char **authtok" "const char *prompt" -.Ft "int" -.Fn pam_info "const pam_handle_t *pamh" "const char *fmt" "..." -.Ft "int" -.Fn pam_prompt "const pam_handle_t *pamh" "int style" "char **resp" "const char *fmt" "..." -.Ft "int" -.Fn pam_setenv "pam_handle_t *pamh" "const char *name" "const char *value" "int overwrite" -.Ft "int" -.Fn pam_verror "const pam_handle_t *pamh" "const char *fmt" "va_list ap" -.Ft "int" -.Fn pam_vinfo "const pam_handle_t *pamh" "const char *fmt" "va_list ap" -.Ft "int" -.Fn pam_vprompt "const pam_handle_t *pamh" "int style" "char **resp" "const char *fmt" "va_list ap" .\" -.\" $Id: openpam.man 320 2006-02-16 20:33:19Z des $ +.\" $Id: openpam.man 648 2013-03-05 17:54:27Z des $ .\" .Sh DESCRIPTION These functions are OpenPAM extensions to the PAM API. @@ -129,30 +22,6 @@ are either simple convenience functions, or functions intimately tied to OpenPAM implementation details, and therefore not well suited to standardization. .Sh SEE ALSO -.Xr openpam_borrow_cred 3 , -.Xr openpam_free_data 3 , -.Xr openpam_free_envlist 3 , -.Xr openpam_get_feature 3 , -.Xr openpam_get_option 3 , -.Xr openpam_log 3 , -.Xr openpam_nullconv 3 , -.Xr openpam_readline 3 , -.Xr openpam_readlinev 3 , -.Xr openpam_readword 3 , -.Xr openpam_restore_cred 3 , -.Xr openpam_set_feature 3 , -.Xr openpam_set_option 3 , -.Xr openpam_straddch 3 , -.Xr openpam_subst 3 , -.Xr openpam_ttyconv 3 , -.Xr pam_error 3 , -.Xr pam_get_authtok 3 , -.Xr pam_info 3 , -.Xr pam_prompt 3 , -.Xr pam_setenv 3 , -.Xr pam_verror 3 , -.Xr pam_vinfo 3 , -.Xr pam_vprompt 3 .Sh STANDARDS .Rs .%T "X/Open Single Sign-On Service (XSSO) - Pluggable Authentication Modules" diff --git a/contrib/openpam/doc/man/openpam.man b/contrib/openpam/doc/man/openpam.man index 38a10b59cb9d..a7dd7f0a9ff8 100644 --- a/contrib/openpam/doc/man/openpam.man +++ b/contrib/openpam/doc/man/openpam.man @@ -1,5 +1,5 @@ .\" -.\" $Id: openpam.man 320 2006-02-16 20:33:19Z des $ +.\" $Id: openpam.man 648 2013-03-05 17:54:27Z des $ .\" .Sh DESCRIPTION These functions are OpenPAM extensions to the PAM API. diff --git a/contrib/openpam/doc/man/openpam_borrow_cred.3 b/contrib/openpam/doc/man/openpam_borrow_cred.3 index dd05b4430ce4..57a1fe0a9e92 100644 --- a/contrib/openpam/doc/man/openpam_borrow_cred.3 +++ b/contrib/openpam/doc/man/openpam_borrow_cred.3 @@ -1,40 +1,6 @@ -.\"- -.\" Copyright (c) 2001-2003 Networks Associates Technology, Inc. -.\" Copyright (c) 2004-2011 Dag-Erling Smørgrav -.\" All rights reserved. -.\" -.\" This software was developed for the FreeBSD Project by ThinkSec AS and -.\" Network Associates Laboratories, the Security Research Division of -.\" Network Associates, Inc. under DARPA/SPAWAR contract N66001-01-C-8035 -.\" ("CBOSS"), as part of the DARPA CHATS research program. -.\" -.\" Redistribution and use in source and binary forms, with or without -.\" modification, are permitted provided that the following conditions -.\" are met: -.\" 1. Redistributions of source code must retain the above copyright -.\" notice, this list of conditions and the following disclaimer. -.\" 2. Redistributions in binary form must reproduce the above copyright -.\" notice, this list of conditions and the following disclaimer in the -.\" documentation and/or other materials provided with the distribution. -.\" 3. The name of the author may not be used to endorse or promote -.\" products derived from this software without specific prior written -.\" permission. -.\" -.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND -.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE -.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS -.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY -.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -.\" SUCH DAMAGE. -.\" -.\" $Id$ -.\" -.Dd May 26, 2012 +.\" Generated from openpam_borrow_cred.c by gendoc.pl +.\" $Id: openpam_borrow_cred.c 649 2013-03-05 17:58:33Z des $ +.Dd September 7, 2013 .Dt OPENPAM_BORROW_CRED 3 .Os .Sh NAME @@ -94,3 +60,6 @@ Security Research Division of Network Associates, Inc.\& under DARPA/SPAWAR contract N66001-01-C-8035 .Pq Dq CBOSS , as part of the DARPA CHATS research program. +.Pp +The OpenPAM library is maintained by +.An Dag-Erling Sm\(/orgrav Aq des@des.no . diff --git a/contrib/openpam/doc/man/openpam_free_data.3 b/contrib/openpam/doc/man/openpam_free_data.3 index 4d9e0eeed065..a0d72468063f 100644 --- a/contrib/openpam/doc/man/openpam_free_data.3 +++ b/contrib/openpam/doc/man/openpam_free_data.3 @@ -1,40 +1,6 @@ -.\"- -.\" Copyright (c) 2001-2003 Networks Associates Technology, Inc. -.\" Copyright (c) 2004-2011 Dag-Erling Smørgrav -.\" All rights reserved. -.\" -.\" This software was developed for the FreeBSD Project by ThinkSec AS and -.\" Network Associates Laboratories, the Security Research Division of -.\" Network Associates, Inc. under DARPA/SPAWAR contract N66001-01-C-8035 -.\" ("CBOSS"), as part of the DARPA CHATS research program. -.\" -.\" Redistribution and use in source and binary forms, with or without -.\" modification, are permitted provided that the following conditions -.\" are met: -.\" 1. Redistributions of source code must retain the above copyright -.\" notice, this list of conditions and the following disclaimer. -.\" 2. Redistributions in binary form must reproduce the above copyright -.\" notice, this list of conditions and the following disclaimer in the -.\" documentation and/or other materials provided with the distribution. -.\" 3. The name of the author may not be used to endorse or promote -.\" products derived from this software without specific prior written -.\" permission. -.\" -.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND -.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE -.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS -.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY -.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -.\" SUCH DAMAGE. -.\" -.\" $Id$ -.\" -.Dd May 26, 2012 +.\" Generated from openpam_free_data.c by gendoc.pl +.\" $Id: openpam_free_data.c 648 2013-03-05 17:54:27Z des $ +.Dd September 7, 2013 .Dt OPENPAM_FREE_DATA 3 .Os .Sh NAME @@ -77,3 +43,6 @@ Security Research Division of Network Associates, Inc.\& under DARPA/SPAWAR contract N66001-01-C-8035 .Pq Dq CBOSS , as part of the DARPA CHATS research program. +.Pp +The OpenPAM library is maintained by +.An Dag-Erling Sm\(/orgrav Aq des@des.no . diff --git a/contrib/openpam/doc/man/openpam_free_envlist.3 b/contrib/openpam/doc/man/openpam_free_envlist.3 index cf8c585539d8..f417278b3ed1 100644 --- a/contrib/openpam/doc/man/openpam_free_envlist.3 +++ b/contrib/openpam/doc/man/openpam_free_envlist.3 @@ -1,40 +1,6 @@ -.\"- -.\" Copyright (c) 2001-2003 Networks Associates Technology, Inc. -.\" Copyright (c) 2004-2011 Dag-Erling Smørgrav -.\" All rights reserved. -.\" -.\" This software was developed for the FreeBSD Project by ThinkSec AS and -.\" Network Associates Laboratories, the Security Research Division of -.\" Network Associates, Inc. under DARPA/SPAWAR contract N66001-01-C-8035 -.\" ("CBOSS"), as part of the DARPA CHATS research program. -.\" -.\" Redistribution and use in source and binary forms, with or without -.\" modification, are permitted provided that the following conditions -.\" are met: -.\" 1. Redistributions of source code must retain the above copyright -.\" notice, this list of conditions and the following disclaimer. -.\" 2. Redistributions in binary form must reproduce the above copyright -.\" notice, this list of conditions and the following disclaimer in the -.\" documentation and/or other materials provided with the distribution. -.\" 3. The name of the author may not be used to endorse or promote -.\" products derived from this software without specific prior written -.\" permission. -.\" -.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND -.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE -.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS -.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY -.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -.\" SUCH DAMAGE. -.\" -.\" $Id$ -.\" -.Dd May 26, 2012 +.\" Generated from openpam_free_envlist.c by gendoc.pl +.\" $Id: openpam_free_envlist.c 648 2013-03-05 17:54:27Z des $ +.Dd September 7, 2013 .Dt OPENPAM_FREE_ENVLIST 3 .Os .Sh NAME diff --git a/contrib/openpam/doc/man/openpam_get_feature.3 b/contrib/openpam/doc/man/openpam_get_feature.3 index e63ef0cd6af8..83e64e24557d 100644 --- a/contrib/openpam/doc/man/openpam_get_feature.3 +++ b/contrib/openpam/doc/man/openpam_get_feature.3 @@ -1,40 +1,6 @@ -.\"- -.\" Copyright (c) 2001-2003 Networks Associates Technology, Inc. -.\" Copyright (c) 2004-2011 Dag-Erling Smørgrav -.\" All rights reserved. -.\" -.\" This software was developed for the FreeBSD Project by ThinkSec AS and -.\" Network Associates Laboratories, the Security Research Division of -.\" Network Associates, Inc. under DARPA/SPAWAR contract N66001-01-C-8035 -.\" ("CBOSS"), as part of the DARPA CHATS research program. -.\" -.\" Redistribution and use in source and binary forms, with or without -.\" modification, are permitted provided that the following conditions -.\" are met: -.\" 1. Redistributions of source code must retain the above copyright -.\" notice, this list of conditions and the following disclaimer. -.\" 2. Redistributions in binary form must reproduce the above copyright -.\" notice, this list of conditions and the following disclaimer in the -.\" documentation and/or other materials provided with the distribution. -.\" 3. The name of the author may not be used to endorse or promote -.\" products derived from this software without specific prior written -.\" permission. -.\" -.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND -.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE -.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS -.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY -.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -.\" SUCH DAMAGE. -.\" -.\" $Id$ -.\" -.Dd May 26, 2012 +.\" Generated from openpam_get_feature.c by gendoc.pl +.\" $Id: openpam_get_feature.c 648 2013-03-05 17:54:27Z des $ +.Dd September 7, 2013 .Dt OPENPAM_GET_FEATURE 3 .Os .Sh NAME @@ -50,7 +16,7 @@ .Fn openpam_get_feature "int feature" "int *onoff" .Sh DESCRIPTION .Bf Sy -This function is experimental and may be modified or removed in a future release without further warning. +This function is experimental and may be modified or removed in a future release without prior warning. .Ef .Pp The diff --git a/contrib/openpam/doc/man/openpam_get_option.3 b/contrib/openpam/doc/man/openpam_get_option.3 index 68a6b2e77756..e986e7dc2487 100644 --- a/contrib/openpam/doc/man/openpam_get_option.3 +++ b/contrib/openpam/doc/man/openpam_get_option.3 @@ -1,40 +1,6 @@ -.\"- -.\" Copyright (c) 2001-2003 Networks Associates Technology, Inc. -.\" Copyright (c) 2004-2011 Dag-Erling Smørgrav -.\" All rights reserved. -.\" -.\" This software was developed for the FreeBSD Project by ThinkSec AS and -.\" Network Associates Laboratories, the Security Research Division of -.\" Network Associates, Inc. under DARPA/SPAWAR contract N66001-01-C-8035 -.\" ("CBOSS"), as part of the DARPA CHATS research program. -.\" -.\" Redistribution and use in source and binary forms, with or without -.\" modification, are permitted provided that the following conditions -.\" are met: -.\" 1. Redistributions of source code must retain the above copyright -.\" notice, this list of conditions and the following disclaimer. -.\" 2. Redistributions in binary form must reproduce the above copyright -.\" notice, this list of conditions and the following disclaimer in the -.\" documentation and/or other materials provided with the distribution. -.\" 3. The name of the author may not be used to endorse or promote -.\" products derived from this software without specific prior written -.\" permission. -.\" -.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND -.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE -.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS -.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY -.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -.\" SUCH DAMAGE. -.\" -.\" $Id$ -.\" -.Dd May 26, 2012 +.\" Generated from openpam_get_option.c by gendoc.pl +.\" $Id: openpam_get_option.c 648 2013-03-05 17:54:27Z des $ +.Dd September 7, 2013 .Dt OPENPAM_GET_OPTION 3 .Os .Sh NAME @@ -80,3 +46,6 @@ Security Research Division of Network Associates, Inc.\& under DARPA/SPAWAR contract N66001-01-C-8035 .Pq Dq CBOSS , as part of the DARPA CHATS research program. +.Pp +The OpenPAM library is maintained by +.An Dag-Erling Sm\(/orgrav Aq des@des.no . diff --git a/contrib/openpam/doc/man/openpam_log.3 b/contrib/openpam/doc/man/openpam_log.3 index e5e3192c8ae8..0ab721e7fcf5 100644 --- a/contrib/openpam/doc/man/openpam_log.3 +++ b/contrib/openpam/doc/man/openpam_log.3 @@ -1,40 +1,6 @@ -.\"- -.\" Copyright (c) 2001-2003 Networks Associates Technology, Inc. -.\" Copyright (c) 2004-2011 Dag-Erling Smørgrav -.\" All rights reserved. -.\" -.\" This software was developed for the FreeBSD Project by ThinkSec AS and -.\" Network Associates Laboratories, the Security Research Division of -.\" Network Associates, Inc. under DARPA/SPAWAR contract N66001-01-C-8035 -.\" ("CBOSS"), as part of the DARPA CHATS research program. -.\" -.\" Redistribution and use in source and binary forms, with or without -.\" modification, are permitted provided that the following conditions -.\" are met: -.\" 1. Redistributions of source code must retain the above copyright -.\" notice, this list of conditions and the following disclaimer. -.\" 2. Redistributions in binary form must reproduce the above copyright -.\" notice, this list of conditions and the following disclaimer in the -.\" documentation and/or other materials provided with the distribution. -.\" 3. The name of the author may not be used to endorse or promote -.\" products derived from this software without specific prior written -.\" permission. -.\" -.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND -.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE -.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS -.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY -.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -.\" SUCH DAMAGE. -.\" -.\" $Id$ -.\" -.Dd May 26, 2012 +.\" Generated from openpam_log.c by gendoc.pl +.\" $Id: openpam_log.c 686 2013-07-11 16:36:02Z des $ +.Dd September 7, 2013 .Dt OPENPAM_LOG 3 .Os .Sh NAME @@ -98,6 +64,11 @@ The remaining arguments are a .Xr printf 3 format string and the corresponding arguments. +.Pp +The +.Fn openpam_log +function does not modify the value of +.Va errno . .Sh SEE ALSO .Xr pam 3 , .Xr printf 3 , @@ -117,3 +88,6 @@ Security Research Division of Network Associates, Inc.\& under DARPA/SPAWAR contract N66001-01-C-8035 .Pq Dq CBOSS , as part of the DARPA CHATS research program. +.Pp +The OpenPAM library is maintained by +.An Dag-Erling Sm\(/orgrav Aq des@des.no . diff --git a/contrib/openpam/doc/man/openpam_nullconv.3 b/contrib/openpam/doc/man/openpam_nullconv.3 index f5194d38fff2..03cfe53b8408 100644 --- a/contrib/openpam/doc/man/openpam_nullconv.3 +++ b/contrib/openpam/doc/man/openpam_nullconv.3 @@ -1,40 +1,6 @@ -.\"- -.\" Copyright (c) 2001-2003 Networks Associates Technology, Inc. -.\" Copyright (c) 2004-2011 Dag-Erling Smørgrav -.\" All rights reserved. -.\" -.\" This software was developed for the FreeBSD Project by ThinkSec AS and -.\" Network Associates Laboratories, the Security Research Division of -.\" Network Associates, Inc. under DARPA/SPAWAR contract N66001-01-C-8035 -.\" ("CBOSS"), as part of the DARPA CHATS research program. -.\" -.\" Redistribution and use in source and binary forms, with or without -.\" modification, are permitted provided that the following conditions -.\" are met: -.\" 1. Redistributions of source code must retain the above copyright -.\" notice, this list of conditions and the following disclaimer. -.\" 2. Redistributions in binary form must reproduce the above copyright -.\" notice, this list of conditions and the following disclaimer in the -.\" documentation and/or other materials provided with the distribution. -.\" 3. The name of the author may not be used to endorse or promote -.\" products derived from this software without specific prior written -.\" permission. -.\" -.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND -.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE -.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS -.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY -.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -.\" SUCH DAMAGE. -.\" -.\" $Id$ -.\" -.Dd May 26, 2012 +.\" Generated from openpam_nullconv.c by gendoc.pl +.\" $Id: openpam_nullconv.c 648 2013-03-05 17:54:27Z des $ +.Dd September 7, 2013 .Dt OPENPAM_NULLCONV 3 .Os .Sh NAME @@ -101,3 +67,6 @@ Security Research Division of Network Associates, Inc.\& under DARPA/SPAWAR contract N66001-01-C-8035 .Pq Dq CBOSS , as part of the DARPA CHATS research program. +.Pp +The OpenPAM library is maintained by +.An Dag-Erling Sm\(/orgrav Aq des@des.no . diff --git a/contrib/openpam/doc/man/openpam_readline.3 b/contrib/openpam/doc/man/openpam_readline.3 index 32dd55b19f43..8916911fec37 100644 --- a/contrib/openpam/doc/man/openpam_readline.3 +++ b/contrib/openpam/doc/man/openpam_readline.3 @@ -1,40 +1,6 @@ -.\"- -.\" Copyright (c) 2001-2003 Networks Associates Technology, Inc. -.\" Copyright (c) 2004-2011 Dag-Erling Smørgrav -.\" All rights reserved. -.\" -.\" This software was developed for the FreeBSD Project by ThinkSec AS and -.\" Network Associates Laboratories, the Security Research Division of -.\" Network Associates, Inc. under DARPA/SPAWAR contract N66001-01-C-8035 -.\" ("CBOSS"), as part of the DARPA CHATS research program. -.\" -.\" Redistribution and use in source and binary forms, with or without -.\" modification, are permitted provided that the following conditions -.\" are met: -.\" 1. Redistributions of source code must retain the above copyright -.\" notice, this list of conditions and the following disclaimer. -.\" 2. Redistributions in binary form must reproduce the above copyright -.\" notice, this list of conditions and the following disclaimer in the -.\" documentation and/or other materials provided with the distribution. -.\" 3. The name of the author may not be used to endorse or promote -.\" products derived from this software without specific prior written -.\" permission. -.\" -.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND -.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE -.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS -.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY -.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -.\" SUCH DAMAGE. -.\" -.\" $Id$ -.\" -.Dd May 26, 2012 +.\" Generated from openpam_readline.c by gendoc.pl +.\" $Id: openpam_readline.c 703 2013-08-16 11:57:54Z des $ +.Dd September 7, 2013 .Dt OPENPAM_READLINE 3 .Os .Sh NAME @@ -120,3 +86,6 @@ Security Research Division of Network Associates, Inc.\& under DARPA/SPAWAR contract N66001-01-C-8035 .Pq Dq CBOSS , as part of the DARPA CHATS research program. +.Pp +The OpenPAM library is maintained by +.An Dag-Erling Sm\(/orgrav Aq des@des.no . diff --git a/contrib/openpam/doc/man/openpam_readlinev.3 b/contrib/openpam/doc/man/openpam_readlinev.3 index f2ba1a6b775a..1ffe8afe9445 100644 --- a/contrib/openpam/doc/man/openpam_readlinev.3 +++ b/contrib/openpam/doc/man/openpam_readlinev.3 @@ -1,40 +1,6 @@ -.\"- -.\" Copyright (c) 2001-2003 Networks Associates Technology, Inc. -.\" Copyright (c) 2004-2011 Dag-Erling Smørgrav -.\" All rights reserved. -.\" -.\" This software was developed for the FreeBSD Project by ThinkSec AS and -.\" Network Associates Laboratories, the Security Research Division of -.\" Network Associates, Inc. under DARPA/SPAWAR contract N66001-01-C-8035 -.\" ("CBOSS"), as part of the DARPA CHATS research program. -.\" -.\" Redistribution and use in source and binary forms, with or without -.\" modification, are permitted provided that the following conditions -.\" are met: -.\" 1. Redistributions of source code must retain the above copyright -.\" notice, this list of conditions and the following disclaimer. -.\" 2. Redistributions in binary form must reproduce the above copyright -.\" notice, this list of conditions and the following disclaimer in the -.\" documentation and/or other materials provided with the distribution. -.\" 3. The name of the author may not be used to endorse or promote -.\" products derived from this software without specific prior written -.\" permission. -.\" -.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND -.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE -.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS -.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY -.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -.\" SUCH DAMAGE. -.\" -.\" $Id$ -.\" -.Dd May 26, 2012 +.\" Generated from openpam_readlinev.c by gendoc.pl +.\" $Id: openpam_readlinev.c 648 2013-03-05 17:54:27Z des $ +.Dd September 7, 2013 .Dt OPENPAM_READLINEV 3 .Os .Sh NAME diff --git a/contrib/openpam/doc/man/openpam_readword.3 b/contrib/openpam/doc/man/openpam_readword.3 index 6f5f58d34b7c..d680e15049cf 100644 --- a/contrib/openpam/doc/man/openpam_readword.3 +++ b/contrib/openpam/doc/man/openpam_readword.3 @@ -1,40 +1,6 @@ -.\"- -.\" Copyright (c) 2001-2003 Networks Associates Technology, Inc. -.\" Copyright (c) 2004-2011 Dag-Erling Smørgrav -.\" All rights reserved. -.\" -.\" This software was developed for the FreeBSD Project by ThinkSec AS and -.\" Network Associates Laboratories, the Security Research Division of -.\" Network Associates, Inc. under DARPA/SPAWAR contract N66001-01-C-8035 -.\" ("CBOSS"), as part of the DARPA CHATS research program. -.\" -.\" Redistribution and use in source and binary forms, with or without -.\" modification, are permitted provided that the following conditions -.\" are met: -.\" 1. Redistributions of source code must retain the above copyright -.\" notice, this list of conditions and the following disclaimer. -.\" 2. Redistributions in binary form must reproduce the above copyright -.\" notice, this list of conditions and the following disclaimer in the -.\" documentation and/or other materials provided with the distribution. -.\" 3. The name of the author may not be used to endorse or promote -.\" products derived from this software without specific prior written -.\" permission. -.\" -.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND -.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE -.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS -.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY -.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -.\" SUCH DAMAGE. -.\" -.\" $Id$ -.\" -.Dd May 26, 2012 +.\" Generated from openpam_readword.c by gendoc.pl +.\" $Id: openpam_readword.c 648 2013-03-05 17:54:27Z des $ +.Dd September 7, 2013 .Dt OPENPAM_READWORD 3 .Os .Sh NAME diff --git a/contrib/openpam/doc/man/openpam_restore_cred.3 b/contrib/openpam/doc/man/openpam_restore_cred.3 index d088ded59180..313626cc95aa 100644 --- a/contrib/openpam/doc/man/openpam_restore_cred.3 +++ b/contrib/openpam/doc/man/openpam_restore_cred.3 @@ -1,40 +1,6 @@ -.\"- -.\" Copyright (c) 2001-2003 Networks Associates Technology, Inc. -.\" Copyright (c) 2004-2011 Dag-Erling Smørgrav -.\" All rights reserved. -.\" -.\" This software was developed for the FreeBSD Project by ThinkSec AS and -.\" Network Associates Laboratories, the Security Research Division of -.\" Network Associates, Inc. under DARPA/SPAWAR contract N66001-01-C-8035 -.\" ("CBOSS"), as part of the DARPA CHATS research program. -.\" -.\" Redistribution and use in source and binary forms, with or without -.\" modification, are permitted provided that the following conditions -.\" are met: -.\" 1. Redistributions of source code must retain the above copyright -.\" notice, this list of conditions and the following disclaimer. -.\" 2. Redistributions in binary form must reproduce the above copyright -.\" notice, this list of conditions and the following disclaimer in the -.\" documentation and/or other materials provided with the distribution. -.\" 3. The name of the author may not be used to endorse or promote -.\" products derived from this software without specific prior written -.\" permission. -.\" -.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND -.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE -.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS -.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY -.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -.\" SUCH DAMAGE. -.\" -.\" $Id$ -.\" -.Dd May 26, 2012 +.\" Generated from openpam_restore_cred.c by gendoc.pl +.\" $Id: openpam_restore_cred.c 648 2013-03-05 17:54:27Z des $ +.Dd September 7, 2013 .Dt OPENPAM_RESTORE_CRED 3 .Os .Sh NAME @@ -86,3 +52,6 @@ Security Research Division of Network Associates, Inc.\& under DARPA/SPAWAR contract N66001-01-C-8035 .Pq Dq CBOSS , as part of the DARPA CHATS research program. +.Pp +The OpenPAM library is maintained by +.An Dag-Erling Sm\(/orgrav Aq des@des.no . diff --git a/contrib/openpam/doc/man/openpam_set_feature.3 b/contrib/openpam/doc/man/openpam_set_feature.3 index 8356dec6118f..68eafa092ded 100644 --- a/contrib/openpam/doc/man/openpam_set_feature.3 +++ b/contrib/openpam/doc/man/openpam_set_feature.3 @@ -1,40 +1,6 @@ -.\"- -.\" Copyright (c) 2001-2003 Networks Associates Technology, Inc. -.\" Copyright (c) 2004-2011 Dag-Erling Smørgrav -.\" All rights reserved. -.\" -.\" This software was developed for the FreeBSD Project by ThinkSec AS and -.\" Network Associates Laboratories, the Security Research Division of -.\" Network Associates, Inc. under DARPA/SPAWAR contract N66001-01-C-8035 -.\" ("CBOSS"), as part of the DARPA CHATS research program. -.\" -.\" Redistribution and use in source and binary forms, with or without -.\" modification, are permitted provided that the following conditions -.\" are met: -.\" 1. Redistributions of source code must retain the above copyright -.\" notice, this list of conditions and the following disclaimer. -.\" 2. Redistributions in binary form must reproduce the above copyright -.\" notice, this list of conditions and the following disclaimer in the -.\" documentation and/or other materials provided with the distribution. -.\" 3. The name of the author may not be used to endorse or promote -.\" products derived from this software without specific prior written -.\" permission. -.\" -.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND -.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE -.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS -.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY -.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -.\" SUCH DAMAGE. -.\" -.\" $Id$ -.\" -.Dd May 26, 2012 +.\" Generated from openpam_set_feature.c by gendoc.pl +.\" $Id: openpam_set_feature.c 648 2013-03-05 17:54:27Z des $ +.Dd September 7, 2013 .Dt OPENPAM_SET_FEATURE 3 .Os .Sh NAME @@ -50,7 +16,7 @@ .Fn openpam_set_feature "int feature" "int onoff" .Sh DESCRIPTION .Bf Sy -This function is experimental and may be modified or removed in a future release without further warning. +This function is experimental and may be modified or removed in a future release without prior warning. .Ef .Pp The diff --git a/contrib/openpam/doc/man/openpam_set_option.3 b/contrib/openpam/doc/man/openpam_set_option.3 index b1e2267c99b3..cee2540c0e83 100644 --- a/contrib/openpam/doc/man/openpam_set_option.3 +++ b/contrib/openpam/doc/man/openpam_set_option.3 @@ -1,40 +1,6 @@ -.\"- -.\" Copyright (c) 2001-2003 Networks Associates Technology, Inc. -.\" Copyright (c) 2004-2011 Dag-Erling Smørgrav -.\" All rights reserved. -.\" -.\" This software was developed for the FreeBSD Project by ThinkSec AS and -.\" Network Associates Laboratories, the Security Research Division of -.\" Network Associates, Inc. under DARPA/SPAWAR contract N66001-01-C-8035 -.\" ("CBOSS"), as part of the DARPA CHATS research program. -.\" -.\" Redistribution and use in source and binary forms, with or without -.\" modification, are permitted provided that the following conditions -.\" are met: -.\" 1. Redistributions of source code must retain the above copyright -.\" notice, this list of conditions and the following disclaimer. -.\" 2. Redistributions in binary form must reproduce the above copyright -.\" notice, this list of conditions and the following disclaimer in the -.\" documentation and/or other materials provided with the distribution. -.\" 3. The name of the author may not be used to endorse or promote -.\" products derived from this software without specific prior written -.\" permission. -.\" -.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND -.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE -.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS -.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY -.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -.\" SUCH DAMAGE. -.\" -.\" $Id$ -.\" -.Dd May 26, 2012 +.\" Generated from openpam_set_option.c by gendoc.pl +.\" $Id: openpam_set_option.c 648 2013-03-05 17:54:27Z des $ +.Dd September 7, 2013 .Dt OPENPAM_SET_OPTION 3 .Os .Sh NAME @@ -83,3 +49,6 @@ Security Research Division of Network Associates, Inc.\& under DARPA/SPAWAR contract N66001-01-C-8035 .Pq Dq CBOSS , as part of the DARPA CHATS research program. +.Pp +The OpenPAM library is maintained by +.An Dag-Erling Sm\(/orgrav Aq des@des.no . diff --git a/contrib/openpam/doc/man/openpam_straddch.3 b/contrib/openpam/doc/man/openpam_straddch.3 index ea11c93b540b..ec4f607a667c 100644 --- a/contrib/openpam/doc/man/openpam_straddch.3 +++ b/contrib/openpam/doc/man/openpam_straddch.3 @@ -1,40 +1,6 @@ -.\"- -.\" Copyright (c) 2001-2003 Networks Associates Technology, Inc. -.\" Copyright (c) 2004-2011 Dag-Erling Smørgrav -.\" All rights reserved. -.\" -.\" This software was developed for the FreeBSD Project by ThinkSec AS and -.\" Network Associates Laboratories, the Security Research Division of -.\" Network Associates, Inc. under DARPA/SPAWAR contract N66001-01-C-8035 -.\" ("CBOSS"), as part of the DARPA CHATS research program. -.\" -.\" Redistribution and use in source and binary forms, with or without -.\" modification, are permitted provided that the following conditions -.\" are met: -.\" 1. Redistributions of source code must retain the above copyright -.\" notice, this list of conditions and the following disclaimer. -.\" 2. Redistributions in binary form must reproduce the above copyright -.\" notice, this list of conditions and the following disclaimer in the -.\" documentation and/or other materials provided with the distribution. -.\" 3. The name of the author may not be used to endorse or promote -.\" products derived from this software without specific prior written -.\" permission. -.\" -.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND -.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE -.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS -.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY -.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -.\" SUCH DAMAGE. -.\" -.\" $Id$ -.\" -.Dd March 3, 2013 +.\" Generated from openpam_straddch.c by gendoc.pl +.\" $Id: openpam_straddch.c 648 2013-03-05 17:54:27Z des $ +.Dd September 7, 2013 .Dt OPENPAM_STRADDCH 3 .Os .Sh NAME diff --git a/contrib/openpam/doc/man/openpam_subst.3 b/contrib/openpam/doc/man/openpam_subst.3 index 47297c92ccec..2ae0e27c2469 100644 --- a/contrib/openpam/doc/man/openpam_subst.3 +++ b/contrib/openpam/doc/man/openpam_subst.3 @@ -1,40 +1,6 @@ -.\"- -.\" Copyright (c) 2001-2003 Networks Associates Technology, Inc. -.\" Copyright (c) 2004-2011 Dag-Erling Smørgrav -.\" All rights reserved. -.\" -.\" This software was developed for the FreeBSD Project by ThinkSec AS and -.\" Network Associates Laboratories, the Security Research Division of -.\" Network Associates, Inc. under DARPA/SPAWAR contract N66001-01-C-8035 -.\" ("CBOSS"), as part of the DARPA CHATS research program. -.\" -.\" Redistribution and use in source and binary forms, with or without -.\" modification, are permitted provided that the following conditions -.\" are met: -.\" 1. Redistributions of source code must retain the above copyright -.\" notice, this list of conditions and the following disclaimer. -.\" 2. Redistributions in binary form must reproduce the above copyright -.\" notice, this list of conditions and the following disclaimer in the -.\" documentation and/or other materials provided with the distribution. -.\" 3. The name of the author may not be used to endorse or promote -.\" products derived from this software without specific prior written -.\" permission. -.\" -.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND -.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE -.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS -.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY -.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -.\" SUCH DAMAGE. -.\" -.\" $Id$ -.\" -.Dd May 26, 2012 +.\" Generated from openpam_subst.c by gendoc.pl +.\" $Id: openpam_subst.c 648 2013-03-05 17:54:27Z des $ +.Dd September 7, 2013 .Dt OPENPAM_SUBST 3 .Os .Sh NAME diff --git a/contrib/openpam/doc/man/openpam_ttyconv.3 b/contrib/openpam/doc/man/openpam_ttyconv.3 index 3e97cb4b3d68..f3ef85c8ec70 100644 --- a/contrib/openpam/doc/man/openpam_ttyconv.3 +++ b/contrib/openpam/doc/man/openpam_ttyconv.3 @@ -1,40 +1,6 @@ -.\"- -.\" Copyright (c) 2001-2003 Networks Associates Technology, Inc. -.\" Copyright (c) 2004-2011 Dag-Erling Smørgrav -.\" All rights reserved. -.\" -.\" This software was developed for the FreeBSD Project by ThinkSec AS and -.\" Network Associates Laboratories, the Security Research Division of -.\" Network Associates, Inc. under DARPA/SPAWAR contract N66001-01-C-8035 -.\" ("CBOSS"), as part of the DARPA CHATS research program. -.\" -.\" Redistribution and use in source and binary forms, with or without -.\" modification, are permitted provided that the following conditions -.\" are met: -.\" 1. Redistributions of source code must retain the above copyright -.\" notice, this list of conditions and the following disclaimer. -.\" 2. Redistributions in binary form must reproduce the above copyright -.\" notice, this list of conditions and the following disclaimer in the -.\" documentation and/or other materials provided with the distribution. -.\" 3. The name of the author may not be used to endorse or promote -.\" products derived from this software without specific prior written -.\" permission. -.\" -.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND -.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE -.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS -.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY -.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -.\" SUCH DAMAGE. -.\" -.\" $Id$ -.\" -.Dd May 26, 2012 +.\" Generated from openpam_ttyconv.c by gendoc.pl +.\" $Id: openpam_ttyconv.c 688 2013-07-11 16:40:08Z des $ +.Dd September 7, 2013 .Dt OPENPAM_TTYCONV 3 .Os .Sh NAME @@ -96,3 +62,6 @@ Security Research Division of Network Associates, Inc.\& under DARPA/SPAWAR contract N66001-01-C-8035 .Pq Dq CBOSS , as part of the DARPA CHATS research program. +.Pp +The OpenPAM library is maintained by +.An Dag-Erling Sm\(/orgrav Aq des@des.no . diff --git a/contrib/openpam/doc/man/pam.3 b/contrib/openpam/doc/man/pam.3 index 196a3c75cb90..9ee08d17c309 100644 --- a/contrib/openpam/doc/man/pam.3 +++ b/contrib/openpam/doc/man/pam.3 @@ -1,101 +1,15 @@ -.\"- -.\" Copyright (c) 2001-2003 Networks Associates Technology, Inc. -.\" Copyright (c) 2004-2011 Dag-Erling Smørgrav -.\" All rights reserved. -.\" -.\" This software was developed for the FreeBSD Project by ThinkSec AS and -.\" Network Associates Laboratories, the Security Research Division of -.\" Network Associates, Inc. under DARPA/SPAWAR contract N66001-01-C-8035 -.\" ("CBOSS"), as part of the DARPA CHATS research program. -.\" -.\" Redistribution and use in source and binary forms, with or without -.\" modification, are permitted provided that the following conditions -.\" are met: -.\" 1. Redistributions of source code must retain the above copyright -.\" notice, this list of conditions and the following disclaimer. -.\" 2. Redistributions in binary form must reproduce the above copyright -.\" notice, this list of conditions and the following disclaimer in the -.\" documentation and/or other materials provided with the distribution. -.\" 3. The name of the author may not be used to endorse or promote -.\" products derived from this software without specific prior written -.\" permission. -.\" -.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND -.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE -.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS -.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY -.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -.\" SUCH DAMAGE. -.\" -.\" $Id$ -.\" -.Dd May 26, 2012 +.\" Generated by gendoc.pl +.Dd September 7, 2013 .Dt PAM 3 .Os .Sh NAME -.Nm pam_acct_mgmt , -.Nm pam_authenticate , -.Nm pam_chauthtok , -.Nm pam_close_session , -.Nm pam_end , -.Nm pam_get_data , -.Nm pam_get_item , -.Nm pam_get_user , -.Nm pam_getenv , -.Nm pam_getenvlist , -.Nm pam_open_session , -.Nm pam_putenv , -.Nm pam_set_data , -.Nm pam_set_item , -.Nm pam_setcred , -.Nm pam_start , -.Nm pam_strerror .Nd Pluggable Authentication Modules Library .Sh LIBRARY .Lb libpam .Sh SYNOPSIS .In security/pam_appl.h -.Ft "int" -.Fn pam_acct_mgmt "pam_handle_t *pamh" "int flags" -.Ft "int" -.Fn pam_authenticate "pam_handle_t *pamh" "int flags" -.Ft "int" -.Fn pam_chauthtok "pam_handle_t *pamh" "int flags" -.Ft "int" -.Fn pam_close_session "pam_handle_t *pamh" "int flags" -.Ft "int" -.Fn pam_end "pam_handle_t *pamh" "int status" -.Ft "int" -.Fn pam_get_data "const pam_handle_t *pamh" "const char *module_data_name" "const void **data" -.Ft "int" -.Fn pam_get_item "const pam_handle_t *pamh" "int item_type" "const void **item" -.Ft "int" -.Fn pam_get_user "pam_handle_t *pamh" "const char **user" "const char *prompt" -.Ft "const char *" -.Fn pam_getenv "pam_handle_t *pamh" "const char *name" -.Ft "char **" -.Fn pam_getenvlist "pam_handle_t *pamh" -.Ft "int" -.Fn pam_open_session "pam_handle_t *pamh" "int flags" -.Ft "int" -.Fn pam_putenv "pam_handle_t *pamh" "const char *namevalue" -.Ft "int" -.Fn pam_set_data "pam_handle_t *pamh" "const char *module_data_name" "void *data" "void (*cleanup)(pam_handle_t *pamh, void *data, int pam_end_status)" -.Ft "int" -.Fn pam_set_item "pam_handle_t *pamh" "int item_type" "const void *item" -.Ft "int" -.Fn pam_setcred "pam_handle_t *pamh" "int flags" -.Ft "int" -.Fn pam_start "const char *service" "const char *user" "const struct pam_conv *pam_conv" "pam_handle_t **pamh" -.Ft "const char *" -.Fn pam_strerror "const pam_handle_t *pamh" "int error_number" .\" -.\" $Id: pam.man 320 2006-02-16 20:33:19Z des $ +.\" $Id: pam.man 648 2013-03-05 17:54:27Z des $ .\" .Sh DESCRIPTION The Pluggable Authentication Modules (PAM) library abstracts a number @@ -260,24 +174,7 @@ Unknown user. .El .Sh SEE ALSO .Xr openpam 3 , -.Xr pam_acct_mgmt 3 , -.Xr pam_authenticate 3 , -.Xr pam_chauthtok 3 , -.Xr pam_close_session 3 , -.Xr pam_conv 3 , -.Xr pam_end 3 , -.Xr pam_get_data 3 , -.Xr pam_getenv 3 , -.Xr pam_getenvlist 3 , -.Xr pam_get_item 3 , -.Xr pam_get_user 3 , -.Xr pam_open_session 3 , -.Xr pam_putenv 3 , -.Xr pam_setcred 3 , -.Xr pam_set_data 3 , -.Xr pam_set_item 3 , -.Xr pam_start 3 , -.Xr pam_strerror 3 +.Xr pam_conv 3 .Sh STANDARDS .Rs .%T "X/Open Single Sign-On Service (XSSO) - Pluggable Authentication Modules" diff --git a/contrib/openpam/doc/man/pam.conf.5 b/contrib/openpam/doc/man/pam.conf.5 index d5f80d57a181..9b4f4ce285d7 100644 --- a/contrib/openpam/doc/man/pam.conf.5 +++ b/contrib/openpam/doc/man/pam.conf.5 @@ -26,9 +26,9 @@ .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" SUCH DAMAGE. .\" -.\" $Id: pam.conf.5 610 2012-05-26 14:03:45Z des $ +.\" $Id: pam.conf.5 741 2013-09-07 13:34:02Z des $ .\" -.Dd May 26, 2012 +.Dd September 7, 2013 .Dt PAM.CONF 5 .Os .Sh NAME @@ -65,15 +65,16 @@ Entries in policy files are of the same form, but are prefixed by an additional field specifying the name of the service they apply to. .Pp -In both types of policy files, blank lines are ignored, as is anything -to the right of a +In both cases, blank lines and comments introduced by a .Ql # -sign. +sign are ignored, and the normal shell quoting rules apply. +The precise details of how the file is tokenized are described in +.Xr openpam_readword 3 . .Pp The .Ar facility field specifies the facility the entry applies to, and is one of: -.Bl -tag -width ".Cm password" +.Bl -tag -width 12n .It Cm auth Authentication functions .Po @@ -99,7 +100,7 @@ The field determines how the result returned by the module affects the flow of control through (and the final result of) the rest of the chain, and is one of: -.Bl -tag -width ".Cm sufficient" +.Bl -tag -width 12n .It Cm required If this module succeeds, the result of the chain will be success unless a later module fails. @@ -141,16 +142,18 @@ phase of .Pp The .Ar module-path -field specifies the name, or optionally the full path, of the module -to call. +field specifies the name or full path of the module to call. +If only the name is specified, the PAM library will search for it in +the following locations: +.Bl -enum +.It +.Pa /usr/lib +.It +.Pa /usr/local/lib +.El .Pp -The remaining fields are passed as arguments to the module if and when -it is invoked. -As a special case, if an argument is of the form ``name=value'' and -the right-hand side is surrounded by single or double quotes, any -whitespace between the quote characters will be considered part of the -same argument rather than a separator between this argument and the -next. +The remaining fields, if any, are passed unmodified to the module if +and when it is invoked. .Pp The .Cm include @@ -161,6 +164,37 @@ This allows one to define system-wide policies which are then included into service-specific policies. The system-wide policy can then be modified without having to also modify each and every service-specific policy. +.Pp +.Bf -symbolic +Take care not to introduce loops when using +.Cm include +rules, as there is currently no loop detection in place. +.Ef +.Sh MODULE OPTIONS +Some PAM library functions may alter their behavior when called by a +service module if certain module options were specified, regardless of +whether the module itself accords them any importance. +One such option is +.Cm debug , +which causes the dispatcher to enable debugging messages before +calling each service function, and disable them afterwards (unless +they were already enabled). +Other special options include: +.Bl -tag -width 12n +.It Cm authtok_prompt Ns = Ns Ar prompt , Cm oldauthtok_prompt Ns = Ns Ar prompt , Cm user_prompt Ns = Ns Ar prompt +These options can be used to override the prompts used by +.Xr pam_get_authtok 3 +and +.Xr pam_get_user 3 . +.It Cm echo_pass +This option controls whether +.Xr pam_get_authtok 3 +will allow the user to see what they are typing. +.It Cm try_first_pass , Cm use_first_pass +These options control +.Xr pam_get_authtok 3 Ns 's +use of cached authentication tokens. +.El .Sh SEE ALSO .Xr pam 3 .Sh STANDARDS diff --git a/contrib/openpam/doc/man/pam.man b/contrib/openpam/doc/man/pam.man index d268ce4bb52d..24c5d3242499 100644 --- a/contrib/openpam/doc/man/pam.man +++ b/contrib/openpam/doc/man/pam.man @@ -1,5 +1,5 @@ .\" -.\" $Id: pam.man 320 2006-02-16 20:33:19Z des $ +.\" $Id: pam.man 648 2013-03-05 17:54:27Z des $ .\" .Sh DESCRIPTION The Pluggable Authentication Modules (PAM) library abstracts a number diff --git a/contrib/openpam/doc/man/pam_acct_mgmt.3 b/contrib/openpam/doc/man/pam_acct_mgmt.3 index f79c4646c4c5..08cde6bcaa75 100644 --- a/contrib/openpam/doc/man/pam_acct_mgmt.3 +++ b/contrib/openpam/doc/man/pam_acct_mgmt.3 @@ -1,40 +1,6 @@ -.\"- -.\" Copyright (c) 2001-2003 Networks Associates Technology, Inc. -.\" Copyright (c) 2004-2011 Dag-Erling Smørgrav -.\" All rights reserved. -.\" -.\" This software was developed for the FreeBSD Project by ThinkSec AS and -.\" Network Associates Laboratories, the Security Research Division of -.\" Network Associates, Inc. under DARPA/SPAWAR contract N66001-01-C-8035 -.\" ("CBOSS"), as part of the DARPA CHATS research program. -.\" -.\" Redistribution and use in source and binary forms, with or without -.\" modification, are permitted provided that the following conditions -.\" are met: -.\" 1. Redistributions of source code must retain the above copyright -.\" notice, this list of conditions and the following disclaimer. -.\" 2. Redistributions in binary form must reproduce the above copyright -.\" notice, this list of conditions and the following disclaimer in the -.\" documentation and/or other materials provided with the distribution. -.\" 3. The name of the author may not be used to endorse or promote -.\" products derived from this software without specific prior written -.\" permission. -.\" -.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND -.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE -.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS -.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY -.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -.\" SUCH DAMAGE. -.\" -.\" $Id$ -.\" -.Dd May 26, 2012 +.\" Generated from pam_acct_mgmt.c by gendoc.pl +.\" $Id: pam_acct_mgmt.c 648 2013-03-05 17:54:27Z des $ +.Dd September 7, 2013 .Dt PAM_ACCT_MGMT 3 .Os .Sh NAME @@ -113,3 +79,6 @@ Security Research Division of Network Associates, Inc.\& under DARPA/SPAWAR contract N66001-01-C-8035 .Pq Dq CBOSS , as part of the DARPA CHATS research program. +.Pp +The OpenPAM library is maintained by +.An Dag-Erling Sm\(/orgrav Aq des@des.no . diff --git a/contrib/openpam/doc/man/pam_authenticate.3 b/contrib/openpam/doc/man/pam_authenticate.3 index c521a388ba26..6e5a4c39a259 100644 --- a/contrib/openpam/doc/man/pam_authenticate.3 +++ b/contrib/openpam/doc/man/pam_authenticate.3 @@ -1,40 +1,6 @@ -.\"- -.\" Copyright (c) 2001-2003 Networks Associates Technology, Inc. -.\" Copyright (c) 2004-2011 Dag-Erling Smørgrav -.\" All rights reserved. -.\" -.\" This software was developed for the FreeBSD Project by ThinkSec AS and -.\" Network Associates Laboratories, the Security Research Division of -.\" Network Associates, Inc. under DARPA/SPAWAR contract N66001-01-C-8035 -.\" ("CBOSS"), as part of the DARPA CHATS research program. -.\" -.\" Redistribution and use in source and binary forms, with or without -.\" modification, are permitted provided that the following conditions -.\" are met: -.\" 1. Redistributions of source code must retain the above copyright -.\" notice, this list of conditions and the following disclaimer. -.\" 2. Redistributions in binary form must reproduce the above copyright -.\" notice, this list of conditions and the following disclaimer in the -.\" documentation and/or other materials provided with the distribution. -.\" 3. The name of the author may not be used to endorse or promote -.\" products derived from this software without specific prior written -.\" permission. -.\" -.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND -.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE -.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS -.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY -.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -.\" SUCH DAMAGE. -.\" -.\" $Id$ -.\" -.Dd May 26, 2012 +.\" Generated from pam_authenticate.c by gendoc.pl +.\" $Id: pam_authenticate.c 648 2013-03-05 17:54:27Z des $ +.Dd September 7, 2013 .Dt PAM_AUTHENTICATE 3 .Os .Sh NAME @@ -127,3 +93,6 @@ Security Research Division of Network Associates, Inc.\& under DARPA/SPAWAR contract N66001-01-C-8035 .Pq Dq CBOSS , as part of the DARPA CHATS research program. +.Pp +The OpenPAM library is maintained by +.An Dag-Erling Sm\(/orgrav Aq des@des.no . diff --git a/contrib/openpam/doc/man/pam_chauthtok.3 b/contrib/openpam/doc/man/pam_chauthtok.3 index 11647e7ad0b2..11cf878754aa 100644 --- a/contrib/openpam/doc/man/pam_chauthtok.3 +++ b/contrib/openpam/doc/man/pam_chauthtok.3 @@ -1,40 +1,6 @@ -.\"- -.\" Copyright (c) 2001-2003 Networks Associates Technology, Inc. -.\" Copyright (c) 2004-2011 Dag-Erling Smørgrav -.\" All rights reserved. -.\" -.\" This software was developed for the FreeBSD Project by ThinkSec AS and -.\" Network Associates Laboratories, the Security Research Division of -.\" Network Associates, Inc. under DARPA/SPAWAR contract N66001-01-C-8035 -.\" ("CBOSS"), as part of the DARPA CHATS research program. -.\" -.\" Redistribution and use in source and binary forms, with or without -.\" modification, are permitted provided that the following conditions -.\" are met: -.\" 1. Redistributions of source code must retain the above copyright -.\" notice, this list of conditions and the following disclaimer. -.\" 2. Redistributions in binary form must reproduce the above copyright -.\" notice, this list of conditions and the following disclaimer in the -.\" documentation and/or other materials provided with the distribution. -.\" 3. The name of the author may not be used to endorse or promote -.\" products derived from this software without specific prior written -.\" permission. -.\" -.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND -.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE -.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS -.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY -.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -.\" SUCH DAMAGE. -.\" -.\" $Id$ -.\" -.Dd May 26, 2012 +.\" Generated from pam_chauthtok.c by gendoc.pl +.\" $Id: pam_chauthtok.c 648 2013-03-05 17:54:27Z des $ +.Dd September 7, 2013 .Dt PAM_CHAUTHTOK 3 .Os .Sh NAME @@ -119,3 +85,6 @@ Security Research Division of Network Associates, Inc.\& under DARPA/SPAWAR contract N66001-01-C-8035 .Pq Dq CBOSS , as part of the DARPA CHATS research program. +.Pp +The OpenPAM library is maintained by +.An Dag-Erling Sm\(/orgrav Aq des@des.no . diff --git a/contrib/openpam/doc/man/pam_close_session.3 b/contrib/openpam/doc/man/pam_close_session.3 index dba62e816afe..de922db177ab 100644 --- a/contrib/openpam/doc/man/pam_close_session.3 +++ b/contrib/openpam/doc/man/pam_close_session.3 @@ -1,40 +1,6 @@ -.\"- -.\" Copyright (c) 2001-2003 Networks Associates Technology, Inc. -.\" Copyright (c) 2004-2011 Dag-Erling Smørgrav -.\" All rights reserved. -.\" -.\" This software was developed for the FreeBSD Project by ThinkSec AS and -.\" Network Associates Laboratories, the Security Research Division of -.\" Network Associates, Inc. under DARPA/SPAWAR contract N66001-01-C-8035 -.\" ("CBOSS"), as part of the DARPA CHATS research program. -.\" -.\" Redistribution and use in source and binary forms, with or without -.\" modification, are permitted provided that the following conditions -.\" are met: -.\" 1. Redistributions of source code must retain the above copyright -.\" notice, this list of conditions and the following disclaimer. -.\" 2. Redistributions in binary form must reproduce the above copyright -.\" notice, this list of conditions and the following disclaimer in the -.\" documentation and/or other materials provided with the distribution. -.\" 3. The name of the author may not be used to endorse or promote -.\" products derived from this software without specific prior written -.\" permission. -.\" -.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND -.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE -.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS -.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY -.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -.\" SUCH DAMAGE. -.\" -.\" $Id$ -.\" -.Dd May 26, 2012 +.\" Generated from pam_close_session.c by gendoc.pl +.\" $Id: pam_close_session.c 648 2013-03-05 17:54:27Z des $ +.Dd September 7, 2013 .Dt PAM_CLOSE_SESSION 3 .Os .Sh NAME @@ -109,3 +75,6 @@ Security Research Division of Network Associates, Inc.\& under DARPA/SPAWAR contract N66001-01-C-8035 .Pq Dq CBOSS , as part of the DARPA CHATS research program. +.Pp +The OpenPAM library is maintained by +.An Dag-Erling Sm\(/orgrav Aq des@des.no . diff --git a/contrib/openpam/doc/man/pam_conv.3 b/contrib/openpam/doc/man/pam_conv.3 index a1b121b101c1..bb77e74d8c9b 100644 --- a/contrib/openpam/doc/man/pam_conv.3 +++ b/contrib/openpam/doc/man/pam_conv.3 @@ -32,9 +32,9 @@ .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" SUCH DAMAGE. .\" -.\" $Id: pam_conv.3 610 2012-05-26 14:03:45Z des $ +.\" $Id: pam_conv.3 741 2013-09-07 13:34:02Z des $ .\" -.Dd May 26, 2012 +.Dd September 7, 2013 .Dt PAM_CONV 3 .Os .Sh NAME diff --git a/contrib/openpam/doc/man/pam_end.3 b/contrib/openpam/doc/man/pam_end.3 index 0d669125beab..a7f408bf6afa 100644 --- a/contrib/openpam/doc/man/pam_end.3 +++ b/contrib/openpam/doc/man/pam_end.3 @@ -1,40 +1,6 @@ -.\"- -.\" Copyright (c) 2001-2003 Networks Associates Technology, Inc. -.\" Copyright (c) 2004-2011 Dag-Erling Smørgrav -.\" All rights reserved. -.\" -.\" This software was developed for the FreeBSD Project by ThinkSec AS and -.\" Network Associates Laboratories, the Security Research Division of -.\" Network Associates, Inc. under DARPA/SPAWAR contract N66001-01-C-8035 -.\" ("CBOSS"), as part of the DARPA CHATS research program. -.\" -.\" Redistribution and use in source and binary forms, with or without -.\" modification, are permitted provided that the following conditions -.\" are met: -.\" 1. Redistributions of source code must retain the above copyright -.\" notice, this list of conditions and the following disclaimer. -.\" 2. Redistributions in binary form must reproduce the above copyright -.\" notice, this list of conditions and the following disclaimer in the -.\" documentation and/or other materials provided with the distribution. -.\" 3. The name of the author may not be used to endorse or promote -.\" products derived from this software without specific prior written -.\" permission. -.\" -.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND -.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE -.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS -.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY -.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -.\" SUCH DAMAGE. -.\" -.\" $Id$ -.\" -.Dd May 26, 2012 +.\" Generated from pam_end.c by gendoc.pl +.\" $Id: pam_end.c 648 2013-03-05 17:54:27Z des $ +.Dd September 7, 2013 .Dt PAM_END 3 .Os .Sh NAME @@ -85,3 +51,6 @@ Security Research Division of Network Associates, Inc.\& under DARPA/SPAWAR contract N66001-01-C-8035 .Pq Dq CBOSS , as part of the DARPA CHATS research program. +.Pp +The OpenPAM library is maintained by +.An Dag-Erling Sm\(/orgrav Aq des@des.no . diff --git a/contrib/openpam/doc/man/pam_error.3 b/contrib/openpam/doc/man/pam_error.3 index 6767772b574b..5f9163ca769d 100644 --- a/contrib/openpam/doc/man/pam_error.3 +++ b/contrib/openpam/doc/man/pam_error.3 @@ -1,40 +1,6 @@ -.\"- -.\" Copyright (c) 2001-2003 Networks Associates Technology, Inc. -.\" Copyright (c) 2004-2011 Dag-Erling Smørgrav -.\" All rights reserved. -.\" -.\" This software was developed for the FreeBSD Project by ThinkSec AS and -.\" Network Associates Laboratories, the Security Research Division of -.\" Network Associates, Inc. under DARPA/SPAWAR contract N66001-01-C-8035 -.\" ("CBOSS"), as part of the DARPA CHATS research program. -.\" -.\" Redistribution and use in source and binary forms, with or without -.\" modification, are permitted provided that the following conditions -.\" are met: -.\" 1. Redistributions of source code must retain the above copyright -.\" notice, this list of conditions and the following disclaimer. -.\" 2. Redistributions in binary form must reproduce the above copyright -.\" notice, this list of conditions and the following disclaimer in the -.\" documentation and/or other materials provided with the distribution. -.\" 3. The name of the author may not be used to endorse or promote -.\" products derived from this software without specific prior written -.\" permission. -.\" -.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND -.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE -.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS -.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY -.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -.\" SUCH DAMAGE. -.\" -.\" $Id$ -.\" -.Dd May 26, 2012 +.\" Generated from pam_error.c by gendoc.pl +.\" $Id: pam_error.c 648 2013-03-05 17:54:27Z des $ +.Dd September 7, 2013 .Dt PAM_ERROR 3 .Os .Sh NAME @@ -86,3 +52,6 @@ Security Research Division of Network Associates, Inc.\& under DARPA/SPAWAR contract N66001-01-C-8035 .Pq Dq CBOSS , as part of the DARPA CHATS research program. +.Pp +The OpenPAM library is maintained by +.An Dag-Erling Sm\(/orgrav Aq des@des.no . diff --git a/contrib/openpam/doc/man/pam_get_authtok.3 b/contrib/openpam/doc/man/pam_get_authtok.3 index 84c133dd52a3..64c98d4c1dcc 100644 --- a/contrib/openpam/doc/man/pam_get_authtok.3 +++ b/contrib/openpam/doc/man/pam_get_authtok.3 @@ -1,40 +1,6 @@ -.\"- -.\" Copyright (c) 2001-2003 Networks Associates Technology, Inc. -.\" Copyright (c) 2004-2011 Dag-Erling Smørgrav -.\" All rights reserved. -.\" -.\" This software was developed for the FreeBSD Project by ThinkSec AS and -.\" Network Associates Laboratories, the Security Research Division of -.\" Network Associates, Inc. under DARPA/SPAWAR contract N66001-01-C-8035 -.\" ("CBOSS"), as part of the DARPA CHATS research program. -.\" -.\" Redistribution and use in source and binary forms, with or without -.\" modification, are permitted provided that the following conditions -.\" are met: -.\" 1. Redistributions of source code must retain the above copyright -.\" notice, this list of conditions and the following disclaimer. -.\" 2. Redistributions in binary form must reproduce the above copyright -.\" notice, this list of conditions and the following disclaimer in the -.\" documentation and/or other materials provided with the distribution. -.\" 3. The name of the author may not be used to endorse or promote -.\" products derived from this software without specific prior written -.\" permission. -.\" -.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND -.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE -.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS -.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY -.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -.\" SUCH DAMAGE. -.\" -.\" $Id$ -.\" -.Dd May 26, 2012 +.\" Generated from pam_get_authtok.c by gendoc.pl +.\" $Id: pam_get_authtok.c 670 2013-03-17 19:26:07Z des $ +.Dd September 7, 2013 .Dt PAM_GET_AUTHTOK 3 .Os .Sh NAME @@ -50,12 +16,14 @@ .Sh DESCRIPTION The .Fn pam_get_authtok -function returns the cached authentication token, -or prompts the user if no token is currently cached. +function either prompts the user for an +authentication token or retrieves a cached authentication token, +depending on circumstances. Either way, a pointer to the authentication token is stored in the location pointed to by the .Fa authtok -argument. +argument, and the corresponding PAM +item is updated. .Pp The .Fa item @@ -83,25 +51,14 @@ as appropriate, will be used. If that item is also .Dv NULL , a hardcoded default prompt will be used. -Either way, the prompt is expanded using -.Xr openpam_subst 3 -before it is -passed to the conversation function. -.Pp -If +Additionally, when .Fn pam_get_authtok -is called from a module and the -.Dv authtok_prompt -/ -.Dv oldauthtok_prompt -option is set in the policy file, the value of that -option takes precedence over both the -.Fa prompt -argument and the -.Dv PAM_AUTHTOK_PROMPT -/ -.Dv PAM_OLDAUTHTOK_PROMPT -item. +is called from a service module, +the prompt may be affected by module options as described below. +The prompt is then expanded using +.Xr openpam_subst 3 +before it is passed to +the conversation function. .Pp If .Fa item @@ -117,7 +74,50 @@ If there is a mismatch, .Fn pam_get_authtok will return .Dv PAM_TRY_AGAIN . -.Pp +.Sh MODULE OPTIONS +When called by a service module, +.Fn pam_get_authtok +will recognize the +following module options: +.Bl -tag -width 18n +.It Dv authtok_prompt +Prompt to use when +.Fa item +is set to +.Dv PAM_AUTHTOK . +This option overrides both the +.Fa prompt +argument and the +.Dv PAM_AUTHTOK_PROMPT +item. +.It Dv echo_pass +If the application's conversation function allows it, this +lets the user see what they are typing. +This should only be used for non-reusable authentication +tokens. +.It Dv oldauthtok_prompt +Prompt to use when +.Fa item +is set to +.Dv PAM_OLDAUTHTOK . +This option overrides both the +.Fa prompt +argument and the +.Dv PAM_OLDAUTHTOK_PROMPT +item. +.It Dv try_first_pass +If the requested item is non-null, return it without +prompting the user. +Typically, the service module will verify the token, and +if it does not match, clear the item before calling +.Fn pam_get_authtok +a second time. +.It Dv use_first_pass +Do not prompt the user at all; just return the cached +value, or +.Dv PAM_AUTH_ERR +if there is none. +.El .Sh RETURN VALUES The .Fn pam_get_authtok @@ -133,8 +133,10 @@ System error. Try again. .El .Sh SEE ALSO +.Xr openpam_get_option 3 , .Xr openpam_subst 3 , .Xr pam 3 , +.Xr pam_conv 3 , .Xr pam_get_item 3 , .Xr pam_get_user 3 , .Xr pam_strerror 3 @@ -153,3 +155,6 @@ Security Research Division of Network Associates, Inc.\& under DARPA/SPAWAR contract N66001-01-C-8035 .Pq Dq CBOSS , as part of the DARPA CHATS research program. +.Pp +The OpenPAM library is maintained by +.An Dag-Erling Sm\(/orgrav Aq des@des.no . diff --git a/contrib/openpam/doc/man/pam_get_data.3 b/contrib/openpam/doc/man/pam_get_data.3 index db4b723cf7aa..f76213daeee7 100644 --- a/contrib/openpam/doc/man/pam_get_data.3 +++ b/contrib/openpam/doc/man/pam_get_data.3 @@ -1,40 +1,6 @@ -.\"- -.\" Copyright (c) 2001-2003 Networks Associates Technology, Inc. -.\" Copyright (c) 2004-2011 Dag-Erling Smørgrav -.\" All rights reserved. -.\" -.\" This software was developed for the FreeBSD Project by ThinkSec AS and -.\" Network Associates Laboratories, the Security Research Division of -.\" Network Associates, Inc. under DARPA/SPAWAR contract N66001-01-C-8035 -.\" ("CBOSS"), as part of the DARPA CHATS research program. -.\" -.\" Redistribution and use in source and binary forms, with or without -.\" modification, are permitted provided that the following conditions -.\" are met: -.\" 1. Redistributions of source code must retain the above copyright -.\" notice, this list of conditions and the following disclaimer. -.\" 2. Redistributions in binary form must reproduce the above copyright -.\" notice, this list of conditions and the following disclaimer in the -.\" documentation and/or other materials provided with the distribution. -.\" 3. The name of the author may not be used to endorse or promote -.\" products derived from this software without specific prior written -.\" permission. -.\" -.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND -.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE -.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS -.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY -.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -.\" SUCH DAMAGE. -.\" -.\" $Id$ -.\" -.Dd May 26, 2012 +.\" Generated from pam_get_data.c by gendoc.pl +.\" $Id: pam_get_data.c 648 2013-03-05 17:54:27Z des $ +.Dd September 7, 2013 .Dt PAM_GET_DATA 3 .Os .Sh NAME @@ -100,3 +66,6 @@ Security Research Division of Network Associates, Inc.\& under DARPA/SPAWAR contract N66001-01-C-8035 .Pq Dq CBOSS , as part of the DARPA CHATS research program. +.Pp +The OpenPAM library is maintained by +.An Dag-Erling Sm\(/orgrav Aq des@des.no . diff --git a/contrib/openpam/doc/man/pam_get_item.3 b/contrib/openpam/doc/man/pam_get_item.3 index aaa1badd7f7f..7ee6f0ba65a8 100644 --- a/contrib/openpam/doc/man/pam_get_item.3 +++ b/contrib/openpam/doc/man/pam_get_item.3 @@ -1,40 +1,6 @@ -.\"- -.\" Copyright (c) 2001-2003 Networks Associates Technology, Inc. -.\" Copyright (c) 2004-2011 Dag-Erling Smørgrav -.\" All rights reserved. -.\" -.\" This software was developed for the FreeBSD Project by ThinkSec AS and -.\" Network Associates Laboratories, the Security Research Division of -.\" Network Associates, Inc. under DARPA/SPAWAR contract N66001-01-C-8035 -.\" ("CBOSS"), as part of the DARPA CHATS research program. -.\" -.\" Redistribution and use in source and binary forms, with or without -.\" modification, are permitted provided that the following conditions -.\" are met: -.\" 1. Redistributions of source code must retain the above copyright -.\" notice, this list of conditions and the following disclaimer. -.\" 2. Redistributions in binary form must reproduce the above copyright -.\" notice, this list of conditions and the following disclaimer in the -.\" documentation and/or other materials provided with the distribution. -.\" 3. The name of the author may not be used to endorse or promote -.\" products derived from this software without specific prior written -.\" permission. -.\" -.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND -.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE -.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS -.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY -.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -.\" SUCH DAMAGE. -.\" -.\" $Id$ -.\" -.Dd May 26, 2012 +.\" Generated from pam_get_item.c by gendoc.pl +.\" $Id: pam_get_item.c 648 2013-03-05 17:54:27Z des $ +.Dd September 7, 2013 .Dt PAM_GET_ITEM 3 .Os .Sh NAME @@ -136,3 +102,6 @@ Security Research Division of Network Associates, Inc.\& under DARPA/SPAWAR contract N66001-01-C-8035 .Pq Dq CBOSS , as part of the DARPA CHATS research program. +.Pp +The OpenPAM library is maintained by +.An Dag-Erling Sm\(/orgrav Aq des@des.no . diff --git a/contrib/openpam/doc/man/pam_get_user.3 b/contrib/openpam/doc/man/pam_get_user.3 index 448f41898b86..beed4a96aba9 100644 --- a/contrib/openpam/doc/man/pam_get_user.3 +++ b/contrib/openpam/doc/man/pam_get_user.3 @@ -1,40 +1,6 @@ -.\"- -.\" Copyright (c) 2001-2003 Networks Associates Technology, Inc. -.\" Copyright (c) 2004-2011 Dag-Erling Smørgrav -.\" All rights reserved. -.\" -.\" This software was developed for the FreeBSD Project by ThinkSec AS and -.\" Network Associates Laboratories, the Security Research Division of -.\" Network Associates, Inc. under DARPA/SPAWAR contract N66001-01-C-8035 -.\" ("CBOSS"), as part of the DARPA CHATS research program. -.\" -.\" Redistribution and use in source and binary forms, with or without -.\" modification, are permitted provided that the following conditions -.\" are met: -.\" 1. Redistributions of source code must retain the above copyright -.\" notice, this list of conditions and the following disclaimer. -.\" 2. Redistributions in binary form must reproduce the above copyright -.\" notice, this list of conditions and the following disclaimer in the -.\" documentation and/or other materials provided with the distribution. -.\" 3. The name of the author may not be used to endorse or promote -.\" products derived from this software without specific prior written -.\" permission. -.\" -.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND -.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE -.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS -.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY -.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -.\" SUCH DAMAGE. -.\" -.\" $Id$ -.\" -.Dd May 26, 2012 +.\" Generated from pam_get_user.c by gendoc.pl +.\" $Id: pam_get_user.c 670 2013-03-17 19:26:07Z des $ +.Dd September 7, 2013 .Dt PAM_GET_USER 3 .Os .Sh NAME @@ -60,7 +26,8 @@ will prompt for a user name. Either way, a pointer to the user name is stored in the location pointed to by the .Fa user -argument. +argument, and the corresponding PAM item is +updated. .Pp The .Fa prompt @@ -74,23 +41,28 @@ item will be used. If that item is also .Dv NULL , a hardcoded default prompt will be used. -Either way, the prompt is expanded using -.Xr openpam_subst 3 -before it is -passed to the conversation function. -.Pp -If +Additionally, when .Fn pam_get_user -is called from a module and the -.Dv user_prompt -option is -set in the policy file, the value of that option takes precedence over -both the +is called from a service module, the +prompt may be affected by module options as described below. +The prompt is then expanded using +.Xr openpam_subst 3 +before it is passed to +the conversation function. +.Sh MODULE OPTIONS +When called by a service module, +.Fn pam_get_user +will recognize the +following module options: +.Bl -tag -width 18n +.It Dv user_prompt +Prompt to use when asking for the user name. +This option overrides both the .Fa prompt argument and the .Dv PAM_USER_PROMPT item. -.Pp +.El .Sh RETURN VALUES The .Fn pam_get_user @@ -104,8 +76,10 @@ Conversation failure. System error. .El .Sh SEE ALSO +.Xr openpam_get_option 3 , .Xr openpam_subst 3 , .Xr pam 3 , +.Xr pam_conv 3 , .Xr pam_get_authtok 3 , .Xr pam_get_item 3 , .Xr pam_set_item 3 , @@ -127,3 +101,6 @@ Security Research Division of Network Associates, Inc.\& under DARPA/SPAWAR contract N66001-01-C-8035 .Pq Dq CBOSS , as part of the DARPA CHATS research program. +.Pp +The OpenPAM library is maintained by +.An Dag-Erling Sm\(/orgrav Aq des@des.no . diff --git a/contrib/openpam/doc/man/pam_getenv.3 b/contrib/openpam/doc/man/pam_getenv.3 index 1f0df73f2db2..f26cb81802e6 100644 --- a/contrib/openpam/doc/man/pam_getenv.3 +++ b/contrib/openpam/doc/man/pam_getenv.3 @@ -1,40 +1,6 @@ -.\"- -.\" Copyright (c) 2001-2003 Networks Associates Technology, Inc. -.\" Copyright (c) 2004-2011 Dag-Erling Smørgrav -.\" All rights reserved. -.\" -.\" This software was developed for the FreeBSD Project by ThinkSec AS and -.\" Network Associates Laboratories, the Security Research Division of -.\" Network Associates, Inc. under DARPA/SPAWAR contract N66001-01-C-8035 -.\" ("CBOSS"), as part of the DARPA CHATS research program. -.\" -.\" Redistribution and use in source and binary forms, with or without -.\" modification, are permitted provided that the following conditions -.\" are met: -.\" 1. Redistributions of source code must retain the above copyright -.\" notice, this list of conditions and the following disclaimer. -.\" 2. Redistributions in binary form must reproduce the above copyright -.\" notice, this list of conditions and the following disclaimer in the -.\" documentation and/or other materials provided with the distribution. -.\" 3. The name of the author may not be used to endorse or promote -.\" products derived from this software without specific prior written -.\" permission. -.\" -.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND -.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE -.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS -.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY -.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -.\" SUCH DAMAGE. -.\" -.\" $Id$ -.\" -.Dd May 26, 2012 +.\" Generated from pam_getenv.c by gendoc.pl +.\" $Id: pam_getenv.c 648 2013-03-05 17:54:27Z des $ +.Dd September 7, 2013 .Dt PAM_GETENV 3 .Os .Sh NAME @@ -84,3 +50,6 @@ Security Research Division of Network Associates, Inc.\& under DARPA/SPAWAR contract N66001-01-C-8035 .Pq Dq CBOSS , as part of the DARPA CHATS research program. +.Pp +The OpenPAM library is maintained by +.An Dag-Erling Sm\(/orgrav Aq des@des.no . diff --git a/contrib/openpam/doc/man/pam_getenvlist.3 b/contrib/openpam/doc/man/pam_getenvlist.3 index 9af378459b44..dd01d2928011 100644 --- a/contrib/openpam/doc/man/pam_getenvlist.3 +++ b/contrib/openpam/doc/man/pam_getenvlist.3 @@ -1,40 +1,6 @@ -.\"- -.\" Copyright (c) 2001-2003 Networks Associates Technology, Inc. -.\" Copyright (c) 2004-2011 Dag-Erling Smørgrav -.\" All rights reserved. -.\" -.\" This software was developed for the FreeBSD Project by ThinkSec AS and -.\" Network Associates Laboratories, the Security Research Division of -.\" Network Associates, Inc. under DARPA/SPAWAR contract N66001-01-C-8035 -.\" ("CBOSS"), as part of the DARPA CHATS research program. -.\" -.\" Redistribution and use in source and binary forms, with or without -.\" modification, are permitted provided that the following conditions -.\" are met: -.\" 1. Redistributions of source code must retain the above copyright -.\" notice, this list of conditions and the following disclaimer. -.\" 2. Redistributions in binary form must reproduce the above copyright -.\" notice, this list of conditions and the following disclaimer in the -.\" documentation and/or other materials provided with the distribution. -.\" 3. The name of the author may not be used to endorse or promote -.\" products derived from this software without specific prior written -.\" permission. -.\" -.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND -.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE -.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS -.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY -.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -.\" SUCH DAMAGE. -.\" -.\" $Id$ -.\" -.Dd May 26, 2012 +.\" Generated from pam_getenvlist.c by gendoc.pl +.\" $Id: pam_getenvlist.c 648 2013-03-05 17:54:27Z des $ +.Dd September 7, 2013 .Dt PAM_GETENVLIST 3 .Os .Sh NAME @@ -105,3 +71,6 @@ Security Research Division of Network Associates, Inc.\& under DARPA/SPAWAR contract N66001-01-C-8035 .Pq Dq CBOSS , as part of the DARPA CHATS research program. +.Pp +The OpenPAM library is maintained by +.An Dag-Erling Sm\(/orgrav Aq des@des.no . diff --git a/contrib/openpam/doc/man/pam_info.3 b/contrib/openpam/doc/man/pam_info.3 index c08b5748c6e2..1d14ec141a9c 100644 --- a/contrib/openpam/doc/man/pam_info.3 +++ b/contrib/openpam/doc/man/pam_info.3 @@ -1,40 +1,6 @@ -.\"- -.\" Copyright (c) 2001-2003 Networks Associates Technology, Inc. -.\" Copyright (c) 2004-2011 Dag-Erling Smørgrav -.\" All rights reserved. -.\" -.\" This software was developed for the FreeBSD Project by ThinkSec AS and -.\" Network Associates Laboratories, the Security Research Division of -.\" Network Associates, Inc. under DARPA/SPAWAR contract N66001-01-C-8035 -.\" ("CBOSS"), as part of the DARPA CHATS research program. -.\" -.\" Redistribution and use in source and binary forms, with or without -.\" modification, are permitted provided that the following conditions -.\" are met: -.\" 1. Redistributions of source code must retain the above copyright -.\" notice, this list of conditions and the following disclaimer. -.\" 2. Redistributions in binary form must reproduce the above copyright -.\" notice, this list of conditions and the following disclaimer in the -.\" documentation and/or other materials provided with the distribution. -.\" 3. The name of the author may not be used to endorse or promote -.\" products derived from this software without specific prior written -.\" permission. -.\" -.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND -.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE -.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS -.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY -.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -.\" SUCH DAMAGE. -.\" -.\" $Id$ -.\" -.Dd May 26, 2012 +.\" Generated from pam_info.c by gendoc.pl +.\" $Id: pam_info.c 648 2013-03-05 17:54:27Z des $ +.Dd September 7, 2013 .Dt PAM_INFO 3 .Os .Sh NAME @@ -86,3 +52,6 @@ Security Research Division of Network Associates, Inc.\& under DARPA/SPAWAR contract N66001-01-C-8035 .Pq Dq CBOSS , as part of the DARPA CHATS research program. +.Pp +The OpenPAM library is maintained by +.An Dag-Erling Sm\(/orgrav Aq des@des.no . diff --git a/contrib/openpam/doc/man/pam_open_session.3 b/contrib/openpam/doc/man/pam_open_session.3 index 1cde0e43712d..768629d1f612 100644 --- a/contrib/openpam/doc/man/pam_open_session.3 +++ b/contrib/openpam/doc/man/pam_open_session.3 @@ -1,40 +1,6 @@ -.\"- -.\" Copyright (c) 2001-2003 Networks Associates Technology, Inc. -.\" Copyright (c) 2004-2011 Dag-Erling Smørgrav -.\" All rights reserved. -.\" -.\" This software was developed for the FreeBSD Project by ThinkSec AS and -.\" Network Associates Laboratories, the Security Research Division of -.\" Network Associates, Inc. under DARPA/SPAWAR contract N66001-01-C-8035 -.\" ("CBOSS"), as part of the DARPA CHATS research program. -.\" -.\" Redistribution and use in source and binary forms, with or without -.\" modification, are permitted provided that the following conditions -.\" are met: -.\" 1. Redistributions of source code must retain the above copyright -.\" notice, this list of conditions and the following disclaimer. -.\" 2. Redistributions in binary form must reproduce the above copyright -.\" notice, this list of conditions and the following disclaimer in the -.\" documentation and/or other materials provided with the distribution. -.\" 3. The name of the author may not be used to endorse or promote -.\" products derived from this software without specific prior written -.\" permission. -.\" -.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND -.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE -.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS -.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY -.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -.\" SUCH DAMAGE. -.\" -.\" $Id$ -.\" -.Dd May 26, 2012 +.\" Generated from pam_open_session.c by gendoc.pl +.\" $Id: pam_open_session.c 648 2013-03-05 17:54:27Z des $ +.Dd September 7, 2013 .Dt PAM_OPEN_SESSION 3 .Os .Sh NAME @@ -110,3 +76,6 @@ Security Research Division of Network Associates, Inc.\& under DARPA/SPAWAR contract N66001-01-C-8035 .Pq Dq CBOSS , as part of the DARPA CHATS research program. +.Pp +The OpenPAM library is maintained by +.An Dag-Erling Sm\(/orgrav Aq des@des.no . diff --git a/contrib/openpam/doc/man/pam_prompt.3 b/contrib/openpam/doc/man/pam_prompt.3 index 0ff7742b7fc7..231e3b6ce6dd 100644 --- a/contrib/openpam/doc/man/pam_prompt.3 +++ b/contrib/openpam/doc/man/pam_prompt.3 @@ -1,40 +1,6 @@ -.\"- -.\" Copyright (c) 2001-2003 Networks Associates Technology, Inc. -.\" Copyright (c) 2004-2011 Dag-Erling Smørgrav -.\" All rights reserved. -.\" -.\" This software was developed for the FreeBSD Project by ThinkSec AS and -.\" Network Associates Laboratories, the Security Research Division of -.\" Network Associates, Inc. under DARPA/SPAWAR contract N66001-01-C-8035 -.\" ("CBOSS"), as part of the DARPA CHATS research program. -.\" -.\" Redistribution and use in source and binary forms, with or without -.\" modification, are permitted provided that the following conditions -.\" are met: -.\" 1. Redistributions of source code must retain the above copyright -.\" notice, this list of conditions and the following disclaimer. -.\" 2. Redistributions in binary form must reproduce the above copyright -.\" notice, this list of conditions and the following disclaimer in the -.\" documentation and/or other materials provided with the distribution. -.\" 3. The name of the author may not be used to endorse or promote -.\" products derived from this software without specific prior written -.\" permission. -.\" -.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND -.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE -.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS -.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY -.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -.\" SUCH DAMAGE. -.\" -.\" $Id$ -.\" -.Dd May 26, 2012 +.\" Generated from pam_prompt.c by gendoc.pl +.\" $Id: pam_prompt.c 648 2013-03-05 17:54:27Z des $ +.Dd September 7, 2013 .Dt PAM_PROMPT 3 .Os .Sh NAME @@ -98,3 +64,6 @@ Security Research Division of Network Associates, Inc.\& under DARPA/SPAWAR contract N66001-01-C-8035 .Pq Dq CBOSS , as part of the DARPA CHATS research program. +.Pp +The OpenPAM library is maintained by +.An Dag-Erling Sm\(/orgrav Aq des@des.no . diff --git a/contrib/openpam/doc/man/pam_putenv.3 b/contrib/openpam/doc/man/pam_putenv.3 index 4e9c6938e69e..02f60155cf55 100644 --- a/contrib/openpam/doc/man/pam_putenv.3 +++ b/contrib/openpam/doc/man/pam_putenv.3 @@ -1,40 +1,6 @@ -.\"- -.\" Copyright (c) 2001-2003 Networks Associates Technology, Inc. -.\" Copyright (c) 2004-2011 Dag-Erling Smørgrav -.\" All rights reserved. -.\" -.\" This software was developed for the FreeBSD Project by ThinkSec AS and -.\" Network Associates Laboratories, the Security Research Division of -.\" Network Associates, Inc. under DARPA/SPAWAR contract N66001-01-C-8035 -.\" ("CBOSS"), as part of the DARPA CHATS research program. -.\" -.\" Redistribution and use in source and binary forms, with or without -.\" modification, are permitted provided that the following conditions -.\" are met: -.\" 1. Redistributions of source code must retain the above copyright -.\" notice, this list of conditions and the following disclaimer. -.\" 2. Redistributions in binary form must reproduce the above copyright -.\" notice, this list of conditions and the following disclaimer in the -.\" documentation and/or other materials provided with the distribution. -.\" 3. The name of the author may not be used to endorse or promote -.\" products derived from this software without specific prior written -.\" permission. -.\" -.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND -.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE -.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS -.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY -.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -.\" SUCH DAMAGE. -.\" -.\" $Id$ -.\" -.Dd May 26, 2012 +.\" Generated from pam_putenv.c by gendoc.pl +.\" $Id: pam_putenv.c 648 2013-03-05 17:54:27Z des $ +.Dd September 7, 2013 .Dt PAM_PUTENV 3 .Os .Sh NAME @@ -89,3 +55,6 @@ Security Research Division of Network Associates, Inc.\& under DARPA/SPAWAR contract N66001-01-C-8035 .Pq Dq CBOSS , as part of the DARPA CHATS research program. +.Pp +The OpenPAM library is maintained by +.An Dag-Erling Sm\(/orgrav Aq des@des.no . diff --git a/contrib/openpam/doc/man/pam_set_data.3 b/contrib/openpam/doc/man/pam_set_data.3 index c02ae2ef6ee4..29e4bf21e27d 100644 --- a/contrib/openpam/doc/man/pam_set_data.3 +++ b/contrib/openpam/doc/man/pam_set_data.3 @@ -1,40 +1,6 @@ -.\"- -.\" Copyright (c) 2001-2003 Networks Associates Technology, Inc. -.\" Copyright (c) 2004-2011 Dag-Erling Smørgrav -.\" All rights reserved. -.\" -.\" This software was developed for the FreeBSD Project by ThinkSec AS and -.\" Network Associates Laboratories, the Security Research Division of -.\" Network Associates, Inc. under DARPA/SPAWAR contract N66001-01-C-8035 -.\" ("CBOSS"), as part of the DARPA CHATS research program. -.\" -.\" Redistribution and use in source and binary forms, with or without -.\" modification, are permitted provided that the following conditions -.\" are met: -.\" 1. Redistributions of source code must retain the above copyright -.\" notice, this list of conditions and the following disclaimer. -.\" 2. Redistributions in binary form must reproduce the above copyright -.\" notice, this list of conditions and the following disclaimer in the -.\" documentation and/or other materials provided with the distribution. -.\" 3. The name of the author may not be used to endorse or promote -.\" products derived from this software without specific prior written -.\" permission. -.\" -.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND -.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE -.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS -.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY -.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -.\" SUCH DAMAGE. -.\" -.\" $Id$ -.\" -.Dd May 26, 2012 +.\" Generated from pam_set_data.c by gendoc.pl +.\" $Id: pam_set_data.c 648 2013-03-05 17:54:27Z des $ +.Dd September 7, 2013 .Dt PAM_SET_DATA 3 .Os .Sh NAME @@ -99,3 +65,6 @@ Security Research Division of Network Associates, Inc.\& under DARPA/SPAWAR contract N66001-01-C-8035 .Pq Dq CBOSS , as part of the DARPA CHATS research program. +.Pp +The OpenPAM library is maintained by +.An Dag-Erling Sm\(/orgrav Aq des@des.no . diff --git a/contrib/openpam/doc/man/pam_set_item.3 b/contrib/openpam/doc/man/pam_set_item.3 index 668c4f39ff0c..b29e3a18a686 100644 --- a/contrib/openpam/doc/man/pam_set_item.3 +++ b/contrib/openpam/doc/man/pam_set_item.3 @@ -1,40 +1,6 @@ -.\"- -.\" Copyright (c) 2001-2003 Networks Associates Technology, Inc. -.\" Copyright (c) 2004-2011 Dag-Erling Smørgrav -.\" All rights reserved. -.\" -.\" This software was developed for the FreeBSD Project by ThinkSec AS and -.\" Network Associates Laboratories, the Security Research Division of -.\" Network Associates, Inc. under DARPA/SPAWAR contract N66001-01-C-8035 -.\" ("CBOSS"), as part of the DARPA CHATS research program. -.\" -.\" Redistribution and use in source and binary forms, with or without -.\" modification, are permitted provided that the following conditions -.\" are met: -.\" 1. Redistributions of source code must retain the above copyright -.\" notice, this list of conditions and the following disclaimer. -.\" 2. Redistributions in binary form must reproduce the above copyright -.\" notice, this list of conditions and the following disclaimer in the -.\" documentation and/or other materials provided with the distribution. -.\" 3. The name of the author may not be used to endorse or promote -.\" products derived from this software without specific prior written -.\" permission. -.\" -.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND -.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE -.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS -.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY -.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -.\" SUCH DAMAGE. -.\" -.\" $Id$ -.\" -.Dd May 26, 2012 +.\" Generated from pam_set_item.c by gendoc.pl +.\" $Id: pam_set_item.c 648 2013-03-05 17:54:27Z des $ +.Dd September 7, 2013 .Dt PAM_SET_ITEM 3 .Os .Sh NAME @@ -93,3 +59,6 @@ Security Research Division of Network Associates, Inc.\& under DARPA/SPAWAR contract N66001-01-C-8035 .Pq Dq CBOSS , as part of the DARPA CHATS research program. +.Pp +The OpenPAM library is maintained by +.An Dag-Erling Sm\(/orgrav Aq des@des.no . diff --git a/contrib/openpam/doc/man/pam_setcred.3 b/contrib/openpam/doc/man/pam_setcred.3 index a4f82493f7c6..5c9a57ed73b0 100644 --- a/contrib/openpam/doc/man/pam_setcred.3 +++ b/contrib/openpam/doc/man/pam_setcred.3 @@ -1,40 +1,6 @@ -.\"- -.\" Copyright (c) 2001-2003 Networks Associates Technology, Inc. -.\" Copyright (c) 2004-2011 Dag-Erling Smørgrav -.\" All rights reserved. -.\" -.\" This software was developed for the FreeBSD Project by ThinkSec AS and -.\" Network Associates Laboratories, the Security Research Division of -.\" Network Associates, Inc. under DARPA/SPAWAR contract N66001-01-C-8035 -.\" ("CBOSS"), as part of the DARPA CHATS research program. -.\" -.\" Redistribution and use in source and binary forms, with or without -.\" modification, are permitted provided that the following conditions -.\" are met: -.\" 1. Redistributions of source code must retain the above copyright -.\" notice, this list of conditions and the following disclaimer. -.\" 2. Redistributions in binary form must reproduce the above copyright -.\" notice, this list of conditions and the following disclaimer in the -.\" documentation and/or other materials provided with the distribution. -.\" 3. The name of the author may not be used to endorse or promote -.\" products derived from this software without specific prior written -.\" permission. -.\" -.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND -.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE -.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS -.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY -.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -.\" SUCH DAMAGE. -.\" -.\" $Id$ -.\" -.Dd May 26, 2012 +.\" Generated from pam_setcred.c by gendoc.pl +.\" $Id: pam_setcred.c 648 2013-03-05 17:54:27Z des $ +.Dd September 7, 2013 .Dt PAM_SETCRED 3 .Os .Sh NAME @@ -122,3 +88,6 @@ Security Research Division of Network Associates, Inc.\& under DARPA/SPAWAR contract N66001-01-C-8035 .Pq Dq CBOSS , as part of the DARPA CHATS research program. +.Pp +The OpenPAM library is maintained by +.An Dag-Erling Sm\(/orgrav Aq des@des.no . diff --git a/contrib/openpam/doc/man/pam_setenv.3 b/contrib/openpam/doc/man/pam_setenv.3 index e3b9c131e280..2991e09d7fc9 100644 --- a/contrib/openpam/doc/man/pam_setenv.3 +++ b/contrib/openpam/doc/man/pam_setenv.3 @@ -1,40 +1,6 @@ -.\"- -.\" Copyright (c) 2001-2003 Networks Associates Technology, Inc. -.\" Copyright (c) 2004-2011 Dag-Erling Smørgrav -.\" All rights reserved. -.\" -.\" This software was developed for the FreeBSD Project by ThinkSec AS and -.\" Network Associates Laboratories, the Security Research Division of -.\" Network Associates, Inc. under DARPA/SPAWAR contract N66001-01-C-8035 -.\" ("CBOSS"), as part of the DARPA CHATS research program. -.\" -.\" Redistribution and use in source and binary forms, with or without -.\" modification, are permitted provided that the following conditions -.\" are met: -.\" 1. Redistributions of source code must retain the above copyright -.\" notice, this list of conditions and the following disclaimer. -.\" 2. Redistributions in binary form must reproduce the above copyright -.\" notice, this list of conditions and the following disclaimer in the -.\" documentation and/or other materials provided with the distribution. -.\" 3. The name of the author may not be used to endorse or promote -.\" products derived from this software without specific prior written -.\" permission. -.\" -.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND -.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE -.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS -.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY -.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -.\" SUCH DAMAGE. -.\" -.\" $Id$ -.\" -.Dd May 26, 2012 +.\" Generated from pam_setenv.c by gendoc.pl +.\" $Id: pam_setenv.c 648 2013-03-05 17:54:27Z des $ +.Dd September 7, 2013 .Dt PAM_SETENV 3 .Os .Sh NAME @@ -88,3 +54,6 @@ Security Research Division of Network Associates, Inc.\& under DARPA/SPAWAR contract N66001-01-C-8035 .Pq Dq CBOSS , as part of the DARPA CHATS research program. +.Pp +The OpenPAM library is maintained by +.An Dag-Erling Sm\(/orgrav Aq des@des.no . diff --git a/contrib/openpam/doc/man/pam_sm_acct_mgmt.3 b/contrib/openpam/doc/man/pam_sm_acct_mgmt.3 index 35dd05bb5c0f..f5c04da672b3 100644 --- a/contrib/openpam/doc/man/pam_sm_acct_mgmt.3 +++ b/contrib/openpam/doc/man/pam_sm_acct_mgmt.3 @@ -1,40 +1,6 @@ -.\"- -.\" Copyright (c) 2001-2003 Networks Associates Technology, Inc. -.\" Copyright (c) 2004-2011 Dag-Erling Smørgrav -.\" All rights reserved. -.\" -.\" This software was developed for the FreeBSD Project by ThinkSec AS and -.\" Network Associates Laboratories, the Security Research Division of -.\" Network Associates, Inc. under DARPA/SPAWAR contract N66001-01-C-8035 -.\" ("CBOSS"), as part of the DARPA CHATS research program. -.\" -.\" Redistribution and use in source and binary forms, with or without -.\" modification, are permitted provided that the following conditions -.\" are met: -.\" 1. Redistributions of source code must retain the above copyright -.\" notice, this list of conditions and the following disclaimer. -.\" 2. Redistributions in binary form must reproduce the above copyright -.\" notice, this list of conditions and the following disclaimer in the -.\" documentation and/or other materials provided with the distribution. -.\" 3. The name of the author may not be used to endorse or promote -.\" products derived from this software without specific prior written -.\" permission. -.\" -.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND -.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE -.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS -.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY -.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -.\" SUCH DAMAGE. -.\" -.\" $Id$ -.\" -.Dd May 26, 2012 +.\" Generated from pam_sm_acct_mgmt.c by gendoc.pl +.\" $Id: pam_sm_acct_mgmt.c 648 2013-03-05 17:54:27Z des $ +.Dd September 7, 2013 .Dt PAM_SM_ACCT_MGMT 3 .Os .Sh NAME @@ -103,3 +69,6 @@ Security Research Division of Network Associates, Inc.\& under DARPA/SPAWAR contract N66001-01-C-8035 .Pq Dq CBOSS , as part of the DARPA CHATS research program. +.Pp +The OpenPAM library is maintained by +.An Dag-Erling Sm\(/orgrav Aq des@des.no . diff --git a/contrib/openpam/doc/man/pam_sm_authenticate.3 b/contrib/openpam/doc/man/pam_sm_authenticate.3 index 4c27bb76019e..d49936922b43 100644 --- a/contrib/openpam/doc/man/pam_sm_authenticate.3 +++ b/contrib/openpam/doc/man/pam_sm_authenticate.3 @@ -1,40 +1,6 @@ -.\"- -.\" Copyright (c) 2001-2003 Networks Associates Technology, Inc. -.\" Copyright (c) 2004-2011 Dag-Erling Smørgrav -.\" All rights reserved. -.\" -.\" This software was developed for the FreeBSD Project by ThinkSec AS and -.\" Network Associates Laboratories, the Security Research Division of -.\" Network Associates, Inc. under DARPA/SPAWAR contract N66001-01-C-8035 -.\" ("CBOSS"), as part of the DARPA CHATS research program. -.\" -.\" Redistribution and use in source and binary forms, with or without -.\" modification, are permitted provided that the following conditions -.\" are met: -.\" 1. Redistributions of source code must retain the above copyright -.\" notice, this list of conditions and the following disclaimer. -.\" 2. Redistributions in binary form must reproduce the above copyright -.\" notice, this list of conditions and the following disclaimer in the -.\" documentation and/or other materials provided with the distribution. -.\" 3. The name of the author may not be used to endorse or promote -.\" products derived from this software without specific prior written -.\" permission. -.\" -.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND -.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE -.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS -.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY -.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -.\" SUCH DAMAGE. -.\" -.\" $Id$ -.\" -.Dd May 26, 2012 +.\" Generated from pam_sm_authenticate.c by gendoc.pl +.\" $Id: pam_sm_authenticate.c 648 2013-03-05 17:54:27Z des $ +.Dd September 7, 2013 .Dt PAM_SM_AUTHENTICATE 3 .Os .Sh NAME @@ -105,3 +71,6 @@ Security Research Division of Network Associates, Inc.\& under DARPA/SPAWAR contract N66001-01-C-8035 .Pq Dq CBOSS , as part of the DARPA CHATS research program. +.Pp +The OpenPAM library is maintained by +.An Dag-Erling Sm\(/orgrav Aq des@des.no . diff --git a/contrib/openpam/doc/man/pam_sm_chauthtok.3 b/contrib/openpam/doc/man/pam_sm_chauthtok.3 index 8e28b05f9919..289c34582e6d 100644 --- a/contrib/openpam/doc/man/pam_sm_chauthtok.3 +++ b/contrib/openpam/doc/man/pam_sm_chauthtok.3 @@ -1,40 +1,6 @@ -.\"- -.\" Copyright (c) 2001-2003 Networks Associates Technology, Inc. -.\" Copyright (c) 2004-2011 Dag-Erling Smørgrav -.\" All rights reserved. -.\" -.\" This software was developed for the FreeBSD Project by ThinkSec AS and -.\" Network Associates Laboratories, the Security Research Division of -.\" Network Associates, Inc. under DARPA/SPAWAR contract N66001-01-C-8035 -.\" ("CBOSS"), as part of the DARPA CHATS research program. -.\" -.\" Redistribution and use in source and binary forms, with or without -.\" modification, are permitted provided that the following conditions -.\" are met: -.\" 1. Redistributions of source code must retain the above copyright -.\" notice, this list of conditions and the following disclaimer. -.\" 2. Redistributions in binary form must reproduce the above copyright -.\" notice, this list of conditions and the following disclaimer in the -.\" documentation and/or other materials provided with the distribution. -.\" 3. The name of the author may not be used to endorse or promote -.\" products derived from this software without specific prior written -.\" permission. -.\" -.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND -.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE -.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS -.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY -.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -.\" SUCH DAMAGE. -.\" -.\" $Id$ -.\" -.Dd May 26, 2012 +.\" Generated from pam_sm_chauthtok.c by gendoc.pl +.\" $Id: pam_sm_chauthtok.c 648 2013-03-05 17:54:27Z des $ +.Dd September 7, 2013 .Dt PAM_SM_CHAUTHTOK 3 .Os .Sh NAME @@ -115,3 +81,6 @@ Security Research Division of Network Associates, Inc.\& under DARPA/SPAWAR contract N66001-01-C-8035 .Pq Dq CBOSS , as part of the DARPA CHATS research program. +.Pp +The OpenPAM library is maintained by +.An Dag-Erling Sm\(/orgrav Aq des@des.no . diff --git a/contrib/openpam/doc/man/pam_sm_close_session.3 b/contrib/openpam/doc/man/pam_sm_close_session.3 index bfb5d87ee323..3072ffe5c0df 100644 --- a/contrib/openpam/doc/man/pam_sm_close_session.3 +++ b/contrib/openpam/doc/man/pam_sm_close_session.3 @@ -1,40 +1,6 @@ -.\"- -.\" Copyright (c) 2001-2003 Networks Associates Technology, Inc. -.\" Copyright (c) 2004-2011 Dag-Erling Smørgrav -.\" All rights reserved. -.\" -.\" This software was developed for the FreeBSD Project by ThinkSec AS and -.\" Network Associates Laboratories, the Security Research Division of -.\" Network Associates, Inc. under DARPA/SPAWAR contract N66001-01-C-8035 -.\" ("CBOSS"), as part of the DARPA CHATS research program. -.\" -.\" Redistribution and use in source and binary forms, with or without -.\" modification, are permitted provided that the following conditions -.\" are met: -.\" 1. Redistributions of source code must retain the above copyright -.\" notice, this list of conditions and the following disclaimer. -.\" 2. Redistributions in binary form must reproduce the above copyright -.\" notice, this list of conditions and the following disclaimer in the -.\" documentation and/or other materials provided with the distribution. -.\" 3. The name of the author may not be used to endorse or promote -.\" products derived from this software without specific prior written -.\" permission. -.\" -.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND -.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE -.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS -.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY -.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -.\" SUCH DAMAGE. -.\" -.\" $Id$ -.\" -.Dd May 26, 2012 +.\" Generated from pam_sm_close_session.c by gendoc.pl +.\" $Id: pam_sm_close_session.c 648 2013-03-05 17:54:27Z des $ +.Dd September 7, 2013 .Dt PAM_SM_CLOSE_SESSION 3 .Os .Sh NAME @@ -97,3 +63,6 @@ Security Research Division of Network Associates, Inc.\& under DARPA/SPAWAR contract N66001-01-C-8035 .Pq Dq CBOSS , as part of the DARPA CHATS research program. +.Pp +The OpenPAM library is maintained by +.An Dag-Erling Sm\(/orgrav Aq des@des.no . diff --git a/contrib/openpam/doc/man/pam_sm_open_session.3 b/contrib/openpam/doc/man/pam_sm_open_session.3 index b92fb45b1b10..1da278674534 100644 --- a/contrib/openpam/doc/man/pam_sm_open_session.3 +++ b/contrib/openpam/doc/man/pam_sm_open_session.3 @@ -1,40 +1,6 @@ -.\"- -.\" Copyright (c) 2001-2003 Networks Associates Technology, Inc. -.\" Copyright (c) 2004-2011 Dag-Erling Smørgrav -.\" All rights reserved. -.\" -.\" This software was developed for the FreeBSD Project by ThinkSec AS and -.\" Network Associates Laboratories, the Security Research Division of -.\" Network Associates, Inc. under DARPA/SPAWAR contract N66001-01-C-8035 -.\" ("CBOSS"), as part of the DARPA CHATS research program. -.\" -.\" Redistribution and use in source and binary forms, with or without -.\" modification, are permitted provided that the following conditions -.\" are met: -.\" 1. Redistributions of source code must retain the above copyright -.\" notice, this list of conditions and the following disclaimer. -.\" 2. Redistributions in binary form must reproduce the above copyright -.\" notice, this list of conditions and the following disclaimer in the -.\" documentation and/or other materials provided with the distribution. -.\" 3. The name of the author may not be used to endorse or promote -.\" products derived from this software without specific prior written -.\" permission. -.\" -.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND -.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE -.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS -.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY -.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -.\" SUCH DAMAGE. -.\" -.\" $Id$ -.\" -.Dd May 26, 2012 +.\" Generated from pam_sm_open_session.c by gendoc.pl +.\" $Id: pam_sm_open_session.c 648 2013-03-05 17:54:27Z des $ +.Dd September 7, 2013 .Dt PAM_SM_OPEN_SESSION 3 .Os .Sh NAME @@ -97,3 +63,6 @@ Security Research Division of Network Associates, Inc.\& under DARPA/SPAWAR contract N66001-01-C-8035 .Pq Dq CBOSS , as part of the DARPA CHATS research program. +.Pp +The OpenPAM library is maintained by +.An Dag-Erling Sm\(/orgrav Aq des@des.no . diff --git a/contrib/openpam/doc/man/pam_sm_setcred.3 b/contrib/openpam/doc/man/pam_sm_setcred.3 index 19b192e21785..e4689d4e542f 100644 --- a/contrib/openpam/doc/man/pam_sm_setcred.3 +++ b/contrib/openpam/doc/man/pam_sm_setcred.3 @@ -1,40 +1,6 @@ -.\"- -.\" Copyright (c) 2001-2003 Networks Associates Technology, Inc. -.\" Copyright (c) 2004-2011 Dag-Erling Smørgrav -.\" All rights reserved. -.\" -.\" This software was developed for the FreeBSD Project by ThinkSec AS and -.\" Network Associates Laboratories, the Security Research Division of -.\" Network Associates, Inc. under DARPA/SPAWAR contract N66001-01-C-8035 -.\" ("CBOSS"), as part of the DARPA CHATS research program. -.\" -.\" Redistribution and use in source and binary forms, with or without -.\" modification, are permitted provided that the following conditions -.\" are met: -.\" 1. Redistributions of source code must retain the above copyright -.\" notice, this list of conditions and the following disclaimer. -.\" 2. Redistributions in binary form must reproduce the above copyright -.\" notice, this list of conditions and the following disclaimer in the -.\" documentation and/or other materials provided with the distribution. -.\" 3. The name of the author may not be used to endorse or promote -.\" products derived from this software without specific prior written -.\" permission. -.\" -.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND -.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE -.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS -.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY -.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -.\" SUCH DAMAGE. -.\" -.\" $Id$ -.\" -.Dd May 26, 2012 +.\" Generated from pam_sm_setcred.c by gendoc.pl +.\" $Id: pam_sm_setcred.c 648 2013-03-05 17:54:27Z des $ +.Dd September 7, 2013 .Dt PAM_SM_SETCRED 3 .Os .Sh NAME @@ -103,3 +69,6 @@ Security Research Division of Network Associates, Inc.\& under DARPA/SPAWAR contract N66001-01-C-8035 .Pq Dq CBOSS , as part of the DARPA CHATS research program. +.Pp +The OpenPAM library is maintained by +.An Dag-Erling Sm\(/orgrav Aq des@des.no . diff --git a/contrib/openpam/doc/man/pam_start.3 b/contrib/openpam/doc/man/pam_start.3 index 4e28d3e57bf4..3d5a9d911852 100644 --- a/contrib/openpam/doc/man/pam_start.3 +++ b/contrib/openpam/doc/man/pam_start.3 @@ -1,40 +1,6 @@ -.\"- -.\" Copyright (c) 2001-2003 Networks Associates Technology, Inc. -.\" Copyright (c) 2004-2011 Dag-Erling Smørgrav -.\" All rights reserved. -.\" -.\" This software was developed for the FreeBSD Project by ThinkSec AS and -.\" Network Associates Laboratories, the Security Research Division of -.\" Network Associates, Inc. under DARPA/SPAWAR contract N66001-01-C-8035 -.\" ("CBOSS"), as part of the DARPA CHATS research program. -.\" -.\" Redistribution and use in source and binary forms, with or without -.\" modification, are permitted provided that the following conditions -.\" are met: -.\" 1. Redistributions of source code must retain the above copyright -.\" notice, this list of conditions and the following disclaimer. -.\" 2. Redistributions in binary form must reproduce the above copyright -.\" notice, this list of conditions and the following disclaimer in the -.\" documentation and/or other materials provided with the distribution. -.\" 3. The name of the author may not be used to endorse or promote -.\" products derived from this software without specific prior written -.\" permission. -.\" -.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND -.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE -.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS -.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY -.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -.\" SUCH DAMAGE. -.\" -.\" $Id$ -.\" -.Dd May 26, 2012 +.\" Generated from pam_start.c by gendoc.pl +.\" $Id: pam_start.c 648 2013-03-05 17:54:27Z des $ +.Dd September 7, 2013 .Dt PAM_START 3 .Os .Sh NAME @@ -108,3 +74,6 @@ Security Research Division of Network Associates, Inc.\& under DARPA/SPAWAR contract N66001-01-C-8035 .Pq Dq CBOSS , as part of the DARPA CHATS research program. +.Pp +The OpenPAM library is maintained by +.An Dag-Erling Sm\(/orgrav Aq des@des.no . diff --git a/contrib/openpam/doc/man/pam_strerror.3 b/contrib/openpam/doc/man/pam_strerror.3 index 5b24b68e8a07..2e16d8e8fa2a 100644 --- a/contrib/openpam/doc/man/pam_strerror.3 +++ b/contrib/openpam/doc/man/pam_strerror.3 @@ -1,40 +1,6 @@ -.\"- -.\" Copyright (c) 2001-2003 Networks Associates Technology, Inc. -.\" Copyright (c) 2004-2011 Dag-Erling Smørgrav -.\" All rights reserved. -.\" -.\" This software was developed for the FreeBSD Project by ThinkSec AS and -.\" Network Associates Laboratories, the Security Research Division of -.\" Network Associates, Inc. under DARPA/SPAWAR contract N66001-01-C-8035 -.\" ("CBOSS"), as part of the DARPA CHATS research program. -.\" -.\" Redistribution and use in source and binary forms, with or without -.\" modification, are permitted provided that the following conditions -.\" are met: -.\" 1. Redistributions of source code must retain the above copyright -.\" notice, this list of conditions and the following disclaimer. -.\" 2. Redistributions in binary form must reproduce the above copyright -.\" notice, this list of conditions and the following disclaimer in the -.\" documentation and/or other materials provided with the distribution. -.\" 3. The name of the author may not be used to endorse or promote -.\" products derived from this software without specific prior written -.\" permission. -.\" -.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND -.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE -.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS -.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY -.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -.\" SUCH DAMAGE. -.\" -.\" $Id$ -.\" -.Dd May 26, 2012 +.\" Generated from pam_strerror.c by gendoc.pl +.\" $Id: pam_strerror.c 648 2013-03-05 17:54:27Z des $ +.Dd September 7, 2013 .Dt PAM_STRERROR 3 .Os .Sh NAME @@ -87,3 +53,6 @@ Security Research Division of Network Associates, Inc.\& under DARPA/SPAWAR contract N66001-01-C-8035 .Pq Dq CBOSS , as part of the DARPA CHATS research program. +.Pp +The OpenPAM library is maintained by +.An Dag-Erling Sm\(/orgrav Aq des@des.no . diff --git a/contrib/openpam/doc/man/pam_verror.3 b/contrib/openpam/doc/man/pam_verror.3 index d4a8cc54862e..6634cd16cc96 100644 --- a/contrib/openpam/doc/man/pam_verror.3 +++ b/contrib/openpam/doc/man/pam_verror.3 @@ -1,40 +1,6 @@ -.\"- -.\" Copyright (c) 2001-2003 Networks Associates Technology, Inc. -.\" Copyright (c) 2004-2011 Dag-Erling Smørgrav -.\" All rights reserved. -.\" -.\" This software was developed for the FreeBSD Project by ThinkSec AS and -.\" Network Associates Laboratories, the Security Research Division of -.\" Network Associates, Inc. under DARPA/SPAWAR contract N66001-01-C-8035 -.\" ("CBOSS"), as part of the DARPA CHATS research program. -.\" -.\" Redistribution and use in source and binary forms, with or without -.\" modification, are permitted provided that the following conditions -.\" are met: -.\" 1. Redistributions of source code must retain the above copyright -.\" notice, this list of conditions and the following disclaimer. -.\" 2. Redistributions in binary form must reproduce the above copyright -.\" notice, this list of conditions and the following disclaimer in the -.\" documentation and/or other materials provided with the distribution. -.\" 3. The name of the author may not be used to endorse or promote -.\" products derived from this software without specific prior written -.\" permission. -.\" -.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND -.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE -.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS -.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY -.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -.\" SUCH DAMAGE. -.\" -.\" $Id$ -.\" -.Dd May 26, 2012 +.\" Generated from pam_verror.c by gendoc.pl +.\" $Id: pam_verror.c 648 2013-03-05 17:54:27Z des $ +.Dd September 7, 2013 .Dt PAM_VERROR 3 .Os .Sh NAME @@ -90,3 +56,6 @@ Security Research Division of Network Associates, Inc.\& under DARPA/SPAWAR contract N66001-01-C-8035 .Pq Dq CBOSS , as part of the DARPA CHATS research program. +.Pp +The OpenPAM library is maintained by +.An Dag-Erling Sm\(/orgrav Aq des@des.no . diff --git a/contrib/openpam/doc/man/pam_vinfo.3 b/contrib/openpam/doc/man/pam_vinfo.3 index 3e10b508a9c1..e0e08e0ed8d7 100644 --- a/contrib/openpam/doc/man/pam_vinfo.3 +++ b/contrib/openpam/doc/man/pam_vinfo.3 @@ -1,40 +1,6 @@ -.\"- -.\" Copyright (c) 2001-2003 Networks Associates Technology, Inc. -.\" Copyright (c) 2004-2011 Dag-Erling Smørgrav -.\" All rights reserved. -.\" -.\" This software was developed for the FreeBSD Project by ThinkSec AS and -.\" Network Associates Laboratories, the Security Research Division of -.\" Network Associates, Inc. under DARPA/SPAWAR contract N66001-01-C-8035 -.\" ("CBOSS"), as part of the DARPA CHATS research program. -.\" -.\" Redistribution and use in source and binary forms, with or without -.\" modification, are permitted provided that the following conditions -.\" are met: -.\" 1. Redistributions of source code must retain the above copyright -.\" notice, this list of conditions and the following disclaimer. -.\" 2. Redistributions in binary form must reproduce the above copyright -.\" notice, this list of conditions and the following disclaimer in the -.\" documentation and/or other materials provided with the distribution. -.\" 3. The name of the author may not be used to endorse or promote -.\" products derived from this software without specific prior written -.\" permission. -.\" -.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND -.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE -.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS -.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY -.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -.\" SUCH DAMAGE. -.\" -.\" $Id$ -.\" -.Dd May 26, 2012 +.\" Generated from pam_vinfo.c by gendoc.pl +.\" $Id: pam_vinfo.c 648 2013-03-05 17:54:27Z des $ +.Dd September 7, 2013 .Dt PAM_VINFO 3 .Os .Sh NAME @@ -90,3 +56,6 @@ Security Research Division of Network Associates, Inc.\& under DARPA/SPAWAR contract N66001-01-C-8035 .Pq Dq CBOSS , as part of the DARPA CHATS research program. +.Pp +The OpenPAM library is maintained by +.An Dag-Erling Sm\(/orgrav Aq des@des.no . diff --git a/contrib/openpam/doc/man/pam_vprompt.3 b/contrib/openpam/doc/man/pam_vprompt.3 index c3d8b325827b..ae9801cc264b 100644 --- a/contrib/openpam/doc/man/pam_vprompt.3 +++ b/contrib/openpam/doc/man/pam_vprompt.3 @@ -1,40 +1,6 @@ -.\"- -.\" Copyright (c) 2001-2003 Networks Associates Technology, Inc. -.\" Copyright (c) 2004-2011 Dag-Erling Smørgrav -.\" All rights reserved. -.\" -.\" This software was developed for the FreeBSD Project by ThinkSec AS and -.\" Network Associates Laboratories, the Security Research Division of -.\" Network Associates, Inc. under DARPA/SPAWAR contract N66001-01-C-8035 -.\" ("CBOSS"), as part of the DARPA CHATS research program. -.\" -.\" Redistribution and use in source and binary forms, with or without -.\" modification, are permitted provided that the following conditions -.\" are met: -.\" 1. Redistributions of source code must retain the above copyright -.\" notice, this list of conditions and the following disclaimer. -.\" 2. Redistributions in binary form must reproduce the above copyright -.\" notice, this list of conditions and the following disclaimer in the -.\" documentation and/or other materials provided with the distribution. -.\" 3. The name of the author may not be used to endorse or promote -.\" products derived from this software without specific prior written -.\" permission. -.\" -.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND -.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE -.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS -.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY -.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -.\" SUCH DAMAGE. -.\" -.\" $Id$ -.\" -.Dd May 26, 2012 +.\" Generated from pam_vprompt.c by gendoc.pl +.\" $Id: pam_vprompt.c 648 2013-03-05 17:54:27Z des $ +.Dd September 7, 2013 .Dt PAM_VPROMPT 3 .Os .Sh NAME @@ -127,3 +93,6 @@ Security Research Division of Network Associates, Inc.\& under DARPA/SPAWAR contract N66001-01-C-8035 .Pq Dq CBOSS , as part of the DARPA CHATS research program. +.Pp +The OpenPAM library is maintained by +.An Dag-Erling Sm\(/orgrav Aq des@des.no . diff --git a/contrib/openpam/include/Makefile.am b/contrib/openpam/include/Makefile.am index 2a140095fc4f..8a2755a7c88e 100644 --- a/contrib/openpam/include/Makefile.am +++ b/contrib/openpam/include/Makefile.am @@ -1,3 +1,3 @@ -# $Id: Makefile.am 320 2006-02-16 20:33:19Z des $ +# $Id: Makefile.am 648 2013-03-05 17:54:27Z des $ SUBDIRS = security diff --git a/contrib/openpam/include/Makefile.in b/contrib/openpam/include/Makefile.in index 3a348e29650a..a8d4fa31ef8a 100644 --- a/contrib/openpam/include/Makefile.in +++ b/contrib/openpam/include/Makefile.in @@ -1,9 +1,8 @@ -# Makefile.in generated by automake 1.11.1 from Makefile.am. +# Makefile.in generated by automake 1.14 from Makefile.am. # @configure_input@ -# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, -# 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation, -# Inc. +# Copyright (C) 1994-2013 Free Software Foundation, Inc. + # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. @@ -15,8 +14,53 @@ @SET_MAKE@ -# $Id: Makefile.am 320 2006-02-16 20:33:19Z des $ +# $Id: Makefile.am 648 2013-03-05 17:54:27Z des $ VPATH = @srcdir@ +am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)' +am__make_running_with_option = \ + case $${target_option-} in \ + ?) ;; \ + *) echo "am__make_running_with_option: internal error: invalid" \ + "target option '$${target_option-}' specified" >&2; \ + exit 1;; \ + esac; \ + has_opt=no; \ + sane_makeflags=$$MAKEFLAGS; \ + if $(am__is_gnu_make); then \ + sane_makeflags=$$MFLAGS; \ + else \ + case $$MAKEFLAGS in \ + *\\[\ \ ]*) \ + bs=\\; \ + sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ + | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ + esac; \ + fi; \ + skip_next=no; \ + strip_trailopt () \ + { \ + flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ + }; \ + for flg in $$sane_makeflags; do \ + test $$skip_next = yes && { skip_next=no; continue; }; \ + case $$flg in \ + *=*|--*) continue;; \ + -*I) strip_trailopt 'I'; skip_next=yes;; \ + -*I?*) strip_trailopt 'I';; \ + -*O) strip_trailopt 'O'; skip_next=yes;; \ + -*O?*) strip_trailopt 'O';; \ + -*l) strip_trailopt 'l'; skip_next=yes;; \ + -*l?*) strip_trailopt 'l';; \ + -[dEDm]) skip_next=yes;; \ + -[JT]) skip_next=yes;; \ + esac; \ + case $$flg in \ + *$$target_option*) has_opt=yes; break;; \ + esac; \ + done; \ + test $$has_opt = yes +am__make_dryrun = (target_option=n; $(am__make_running_with_option)) +am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ @@ -36,29 +80,70 @@ POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = include -DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in +DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 -am__aclocal_m4_deps = $(top_srcdir)/configure.ac +am__aclocal_m4_deps = $(top_srcdir)/m4/libtool.m4 \ + $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \ + $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \ + $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = +AM_V_P = $(am__v_P_@AM_V@) +am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) +am__v_P_0 = false +am__v_P_1 = : +AM_V_GEN = $(am__v_GEN_@AM_V@) +am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) +am__v_GEN_0 = @echo " GEN " $@; +am__v_GEN_1 = +AM_V_at = $(am__v_at_@AM_V@) +am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) +am__v_at_0 = @ +am__v_at_1 = SOURCES = DIST_SOURCES = -RECURSIVE_TARGETS = all-recursive check-recursive dvi-recursive \ - html-recursive info-recursive install-data-recursive \ - install-dvi-recursive install-exec-recursive \ - install-html-recursive install-info-recursive \ - install-pdf-recursive install-ps-recursive install-recursive \ - installcheck-recursive installdirs-recursive pdf-recursive \ - ps-recursive uninstall-recursive +RECURSIVE_TARGETS = all-recursive check-recursive cscopelist-recursive \ + ctags-recursive dvi-recursive html-recursive info-recursive \ + install-data-recursive install-dvi-recursive \ + install-exec-recursive install-html-recursive \ + install-info-recursive install-pdf-recursive \ + install-ps-recursive install-recursive installcheck-recursive \ + installdirs-recursive pdf-recursive ps-recursive \ + tags-recursive uninstall-recursive +am__can_run_installinfo = \ + case $$AM_UPDATE_INFO_DIR in \ + n|no|NO) false;; \ + *) (install-info --version) >/dev/null 2>&1;; \ + esac RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \ distclean-recursive maintainer-clean-recursive -AM_RECURSIVE_TARGETS = $(RECURSIVE_TARGETS:-recursive=) \ - $(RECURSIVE_CLEAN_TARGETS:-recursive=) tags TAGS ctags CTAGS \ +am__recursive_targets = \ + $(RECURSIVE_TARGETS) \ + $(RECURSIVE_CLEAN_TARGETS) \ + $(am__extra_recursive_targets) +AM_RECURSIVE_TARGETS = $(am__recursive_targets:-recursive=) TAGS CTAGS \ distdir +am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) +# Read a list of newline-separated strings from the standard input, +# and print each of them once, without duplicates. Input order is +# *not* preserved. +am__uniquify_input = $(AWK) '\ + BEGIN { nonempty = 0; } \ + { items[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in items) print i; }; } \ +' +# Make sure the list of sources is unique. This is necessary because, +# e.g., the same source file might be shared among _SOURCES variables +# for different programs/libraries. +am__define_uniq_tagged_files = \ + list='$(am__tagged_files)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | $(am__uniquify_input)` ETAGS = etags CTAGS = ctags DIST_SUBDIRS = $(SUBDIRS) @@ -90,6 +175,7 @@ am__relativize = \ reldir="$$dir2" ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ +AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ @@ -100,6 +186,7 @@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ +CRYPTO_LIBS = @CRYPTO_LIBS@ CRYPT_LIBS = @CRYPT_LIBS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ @@ -247,22 +334,25 @@ clean-libtool: -rm -rf .libs _libs # This directory's subdirectories are mostly independent; you can cd -# into them and run `make' without going through this Makefile. -# To change the values of `make' variables: instead of editing Makefiles, -# (1) if the variable is set in `config.status', edit `config.status' -# (which will cause the Makefiles to be regenerated when you run `make'); -# (2) otherwise, pass the desired values on the `make' command line. -$(RECURSIVE_TARGETS): - @fail= failcom='exit 1'; \ - for f in x $$MAKEFLAGS; do \ - case $$f in \ - *=* | --[!k]*);; \ - *k*) failcom='fail=yes';; \ - esac; \ - done; \ +# into them and run 'make' without going through this Makefile. +# To change the values of 'make' variables: instead of editing Makefiles, +# (1) if the variable is set in 'config.status', edit 'config.status' +# (which will cause the Makefiles to be regenerated when you run 'make'); +# (2) otherwise, pass the desired values on the 'make' command line. +$(am__recursive_targets): + @fail=; \ + if $(am__make_keepgoing); then \ + failcom='fail=yes'; \ + else \ + failcom='exit 1'; \ + fi; \ dot_seen=no; \ target=`echo $@ | sed s/-recursive//`; \ - list='$(SUBDIRS)'; for subdir in $$list; do \ + case "$@" in \ + distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ + *) list='$(SUBDIRS)' ;; \ + esac; \ + for subdir in $$list; do \ echo "Making $$target in $$subdir"; \ if test "$$subdir" = "."; then \ dot_seen=yes; \ @@ -277,57 +367,12 @@ $(RECURSIVE_TARGETS): $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ fi; test -z "$$fail" -$(RECURSIVE_CLEAN_TARGETS): - @fail= failcom='exit 1'; \ - for f in x $$MAKEFLAGS; do \ - case $$f in \ - *=* | --[!k]*);; \ - *k*) failcom='fail=yes';; \ - esac; \ - done; \ - dot_seen=no; \ - case "$@" in \ - distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ - *) list='$(SUBDIRS)' ;; \ - esac; \ - rev=''; for subdir in $$list; do \ - if test "$$subdir" = "."; then :; else \ - rev="$$subdir $$rev"; \ - fi; \ - done; \ - rev="$$rev ."; \ - target=`echo $@ | sed s/-recursive//`; \ - for subdir in $$rev; do \ - echo "Making $$target in $$subdir"; \ - if test "$$subdir" = "."; then \ - local_target="$$target-am"; \ - else \ - local_target="$$target"; \ - fi; \ - ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ - || eval $$failcom; \ - done && test -z "$$fail" -tags-recursive: - list='$(SUBDIRS)'; for subdir in $$list; do \ - test "$$subdir" = . || ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) tags); \ - done -ctags-recursive: - list='$(SUBDIRS)'; for subdir in $$list; do \ - test "$$subdir" = . || ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) ctags); \ - done +ID: $(am__tagged_files) + $(am__define_uniq_tagged_files); mkid -fID $$unique +tags: tags-recursive +TAGS: tags -ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) - list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ - unique=`for i in $$list; do \ - if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ - done | \ - $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ - END { if (nonempty) { for (i in files) print i; }; }'`; \ - mkid -fID $$unique -tags: TAGS - -TAGS: tags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ - $(TAGS_FILES) $(LISP) +tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \ @@ -343,12 +388,7 @@ TAGS: tags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \ fi; \ done; \ - list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ - unique=`for i in $$list; do \ - if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ - done | \ - $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ - END { if (nonempty) { for (i in files) print i; }; }'`; \ + $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ @@ -360,15 +400,11 @@ TAGS: tags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $$unique; \ fi; \ fi -ctags: CTAGS -CTAGS: ctags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ - $(TAGS_FILES) $(LISP) - list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ - unique=`for i in $$list; do \ - if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ - done | \ - $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ - END { if (nonempty) { for (i in files) print i; }; }'`; \ +ctags: ctags-recursive + +CTAGS: ctags +ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique @@ -377,6 +413,21 @@ GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" +cscopelist: cscopelist-recursive + +cscopelist-am: $(am__tagged_files) + list='$(am__tagged_files)'; \ + case "$(srcdir)" in \ + [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ + *) sdir=$(subdir)/$(srcdir) ;; \ + esac; \ + for i in $$list; do \ + if test -f "$$i"; then \ + echo "$(subdir)/$$i"; \ + else \ + echo "$$sdir/$$i"; \ + fi; \ + done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags @@ -413,13 +464,10 @@ distdir: $(DISTFILES) done @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ - test -d "$(distdir)/$$subdir" \ - || $(MKDIR_P) "$(distdir)/$$subdir" \ - || exit 1; \ - fi; \ - done - @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ - if test "$$subdir" = .; then :; else \ + $(am__make_dryrun) \ + || test -d "$(distdir)/$$subdir" \ + || $(MKDIR_P) "$(distdir)/$$subdir" \ + || exit 1; \ dir1=$$subdir; dir2="$(distdir)/$$subdir"; \ $(am__relativize); \ new_distdir=$$reldir; \ @@ -454,10 +502,15 @@ install-am: all-am installcheck: installcheck-recursive install-strip: - $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ - install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ - `test -z '$(STRIP)' || \ - echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install + if test -z '$(STRIP)'; then \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + install; \ + else \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ + fi mostlyclean-generic: clean-generic: @@ -535,22 +588,20 @@ ps-am: uninstall-am: -.MAKE: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) ctags-recursive \ - install-am install-strip tags-recursive +.MAKE: $(am__recursive_targets) install-am install-strip -.PHONY: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) CTAGS GTAGS \ - all all-am check check-am clean clean-generic clean-libtool \ - ctags ctags-recursive distclean distclean-generic \ - distclean-libtool distclean-tags distdir dvi dvi-am html \ - html-am info info-am install install-am install-data \ - install-data-am install-dvi install-dvi-am install-exec \ - install-exec-am install-html install-html-am install-info \ - install-info-am install-man install-pdf install-pdf-am \ - install-ps install-ps-am install-strip installcheck \ - installcheck-am installdirs installdirs-am maintainer-clean \ - maintainer-clean-generic mostlyclean mostlyclean-generic \ - mostlyclean-libtool pdf pdf-am ps ps-am tags tags-recursive \ - uninstall uninstall-am +.PHONY: $(am__recursive_targets) CTAGS GTAGS TAGS all all-am check \ + check-am clean clean-generic clean-libtool cscopelist-am ctags \ + ctags-am distclean distclean-generic distclean-libtool \ + distclean-tags distdir dvi dvi-am html html-am info info-am \ + install install-am install-data install-data-am install-dvi \ + install-dvi-am install-exec install-exec-am install-html \ + install-html-am install-info install-info-am install-man \ + install-pdf install-pdf-am install-ps install-ps-am \ + install-strip installcheck installcheck-am installdirs \ + installdirs-am maintainer-clean maintainer-clean-generic \ + mostlyclean mostlyclean-generic mostlyclean-libtool pdf pdf-am \ + ps ps-am tags tags-am uninstall uninstall-am # Tell versions [3.59,3.63) of GNU make to not export all variables. diff --git a/contrib/openpam/include/security/Makefile.am b/contrib/openpam/include/security/Makefile.am index f31b3a0ded59..74d63736ad6e 100644 --- a/contrib/openpam/include/security/Makefile.am +++ b/contrib/openpam/include/security/Makefile.am @@ -1,8 +1,8 @@ -# $Id: Makefile.am 405 2007-12-19 11:38:27Z des $ +# $Id: Makefile.am 714 2013-08-19 15:30:21Z des $ -openpamdir = $(includedir)/security +securitydir = $(includedir)/security -openpam_HEADERS = \ +security_HEADERS = \ openpam.h \ openpam_attr.h \ openpam_version.h \ diff --git a/contrib/openpam/include/security/Makefile.in b/contrib/openpam/include/security/Makefile.in index 928fb6456616..b9e446127b99 100644 --- a/contrib/openpam/include/security/Makefile.in +++ b/contrib/openpam/include/security/Makefile.in @@ -1,9 +1,8 @@ -# Makefile.in generated by automake 1.11.1 from Makefile.am. +# Makefile.in generated by automake 1.14 from Makefile.am. # @configure_input@ -# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, -# 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation, -# Inc. +# Copyright (C) 1994-2013 Free Software Foundation, Inc. + # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. @@ -15,9 +14,54 @@ @SET_MAKE@ -# $Id: Makefile.am 405 2007-12-19 11:38:27Z des $ +# $Id: Makefile.am 714 2013-08-19 15:30:21Z des $ VPATH = @srcdir@ +am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)' +am__make_running_with_option = \ + case $${target_option-} in \ + ?) ;; \ + *) echo "am__make_running_with_option: internal error: invalid" \ + "target option '$${target_option-}' specified" >&2; \ + exit 1;; \ + esac; \ + has_opt=no; \ + sane_makeflags=$$MAKEFLAGS; \ + if $(am__is_gnu_make); then \ + sane_makeflags=$$MFLAGS; \ + else \ + case $$MAKEFLAGS in \ + *\\[\ \ ]*) \ + bs=\\; \ + sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ + | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ + esac; \ + fi; \ + skip_next=no; \ + strip_trailopt () \ + { \ + flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ + }; \ + for flg in $$sane_makeflags; do \ + test $$skip_next = yes && { skip_next=no; continue; }; \ + case $$flg in \ + *=*|--*) continue;; \ + -*I) strip_trailopt 'I'; skip_next=yes;; \ + -*I?*) strip_trailopt 'I';; \ + -*O) strip_trailopt 'O'; skip_next=yes;; \ + -*O?*) strip_trailopt 'O';; \ + -*l) strip_trailopt 'l'; skip_next=yes;; \ + -*l?*) strip_trailopt 'l';; \ + -[dEDm]) skip_next=yes;; \ + -[JT]) skip_next=yes;; \ + esac; \ + case $$flg in \ + *$$target_option*) has_opt=yes; break;; \ + esac; \ + done; \ + test $$has_opt = yes +am__make_dryrun = (target_option=n; $(am__make_running_with_option)) +am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ @@ -37,18 +81,38 @@ POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = include/security -DIST_COMMON = $(openpam_HEADERS) $(srcdir)/Makefile.am \ - $(srcdir)/Makefile.in +DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \ + $(security_HEADERS) ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 -am__aclocal_m4_deps = $(top_srcdir)/configure.ac +am__aclocal_m4_deps = $(top_srcdir)/m4/libtool.m4 \ + $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \ + $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \ + $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = +AM_V_P = $(am__v_P_@AM_V@) +am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) +am__v_P_0 = false +am__v_P_1 = : +AM_V_GEN = $(am__v_GEN_@AM_V@) +am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) +am__v_GEN_0 = @echo " GEN " $@; +am__v_GEN_1 = +AM_V_at = $(am__v_at_@AM_V@) +am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) +am__v_at_0 = @ +am__v_at_1 = SOURCES = DIST_SOURCES = +am__can_run_installinfo = \ + case $$AM_UPDATE_INFO_DIR in \ + n|no|NO) false;; \ + *) (install-info --version) >/dev/null 2>&1;; \ + esac am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; am__vpath_adj = case $$p in \ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ @@ -70,13 +134,37 @@ am__nobase_list = $(am__nobase_strip_setup); \ am__base_list = \ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' -am__installdirs = "$(DESTDIR)$(openpamdir)" -HEADERS = $(openpam_HEADERS) +am__uninstall_files_from_dir = { \ + test -z "$$files" \ + || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ + || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ + $(am__cd) "$$dir" && rm -f $$files; }; \ + } +am__installdirs = "$(DESTDIR)$(securitydir)" +HEADERS = $(security_HEADERS) +am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) +# Read a list of newline-separated strings from the standard input, +# and print each of them once, without duplicates. Input order is +# *not* preserved. +am__uniquify_input = $(AWK) '\ + BEGIN { nonempty = 0; } \ + { items[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in items) print i; }; } \ +' +# Make sure the list of sources is unique. This is necessary because, +# e.g., the same source file might be shared among _SOURCES variables +# for different programs/libraries. +am__define_uniq_tagged_files = \ + list='$(am__tagged_files)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | $(am__uniquify_input)` ETAGS = etags CTAGS = ctags DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ +AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ @@ -87,6 +175,7 @@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ +CRYPTO_LIBS = @CRYPTO_LIBS@ CRYPT_LIBS = @CRYPT_LIBS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ @@ -192,8 +281,8 @@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ -openpamdir = $(includedir)/security -openpam_HEADERS = \ +securitydir = $(includedir)/security +security_HEADERS = \ openpam.h \ openpam_attr.h \ openpam_version.h \ @@ -241,47 +330,37 @@ mostlyclean-libtool: clean-libtool: -rm -rf .libs _libs -install-openpamHEADERS: $(openpam_HEADERS) +install-securityHEADERS: $(security_HEADERS) @$(NORMAL_INSTALL) - test -z "$(openpamdir)" || $(MKDIR_P) "$(DESTDIR)$(openpamdir)" - @list='$(openpam_HEADERS)'; test -n "$(openpamdir)" || list=; \ + @list='$(security_HEADERS)'; test -n "$(securitydir)" || list=; \ + if test -n "$$list"; then \ + echo " $(MKDIR_P) '$(DESTDIR)$(securitydir)'"; \ + $(MKDIR_P) "$(DESTDIR)$(securitydir)" || exit 1; \ + fi; \ for p in $$list; do \ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ echo "$$d$$p"; \ done | $(am__base_list) | \ while read files; do \ - echo " $(INSTALL_HEADER) $$files '$(DESTDIR)$(openpamdir)'"; \ - $(INSTALL_HEADER) $$files "$(DESTDIR)$(openpamdir)" || exit $$?; \ + echo " $(INSTALL_HEADER) $$files '$(DESTDIR)$(securitydir)'"; \ + $(INSTALL_HEADER) $$files "$(DESTDIR)$(securitydir)" || exit $$?; \ done -uninstall-openpamHEADERS: +uninstall-securityHEADERS: @$(NORMAL_UNINSTALL) - @list='$(openpam_HEADERS)'; test -n "$(openpamdir)" || list=; \ + @list='$(security_HEADERS)'; test -n "$(securitydir)" || list=; \ files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ - test -n "$$files" || exit 0; \ - echo " ( cd '$(DESTDIR)$(openpamdir)' && rm -f" $$files ")"; \ - cd "$(DESTDIR)$(openpamdir)" && rm -f $$files + dir='$(DESTDIR)$(securitydir)'; $(am__uninstall_files_from_dir) -ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) - list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ - unique=`for i in $$list; do \ - if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ - done | \ - $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ - END { if (nonempty) { for (i in files) print i; }; }'`; \ - mkid -fID $$unique -tags: TAGS +ID: $(am__tagged_files) + $(am__define_uniq_tagged_files); mkid -fID $$unique +tags: tags-am +TAGS: tags -TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ - $(TAGS_FILES) $(LISP) +tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ - list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ - unique=`for i in $$list; do \ - if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ - done | \ - $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ - END { if (nonempty) { for (i in files) print i; }; }'`; \ + $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ @@ -293,15 +372,11 @@ TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $$unique; \ fi; \ fi -ctags: CTAGS -CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ - $(TAGS_FILES) $(LISP) - list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ - unique=`for i in $$list; do \ - if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ - done | \ - $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ - END { if (nonempty) { for (i in files) print i; }; }'`; \ +ctags: ctags-am + +CTAGS: ctags +ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique @@ -310,6 +385,21 @@ GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" +cscopelist: cscopelist-am + +cscopelist-am: $(am__tagged_files) + list='$(am__tagged_files)'; \ + case "$(srcdir)" in \ + [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ + *) sdir=$(subdir)/$(srcdir) ;; \ + esac; \ + for i in $$list; do \ + if test -f "$$i"; then \ + echo "$(subdir)/$$i"; \ + else \ + echo "$$sdir/$$i"; \ + fi; \ + done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags @@ -348,7 +438,7 @@ check-am: all-am check: check-am all-am: Makefile $(HEADERS) installdirs: - for dir in "$(DESTDIR)$(openpamdir)"; do \ + for dir in "$(DESTDIR)$(securitydir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ done install: install-am @@ -361,10 +451,15 @@ install-am: all-am installcheck: installcheck-am install-strip: - $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ - install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ - `test -z '$(STRIP)' || \ - echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install + if test -z '$(STRIP)'; then \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + install; \ + else \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ + fi mostlyclean-generic: clean-generic: @@ -396,7 +491,7 @@ info: info-am info-am: -install-data-am: install-openpamHEADERS +install-data-am: install-securityHEADERS install-dvi: install-dvi-am @@ -440,22 +535,23 @@ ps: ps-am ps-am: -uninstall-am: uninstall-openpamHEADERS +uninstall-am: uninstall-securityHEADERS .MAKE: install-am install-strip -.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \ - clean-libtool ctags distclean distclean-generic \ - distclean-libtool distclean-tags distdir dvi dvi-am html \ - html-am info info-am install install-am install-data \ - install-data-am install-dvi install-dvi-am install-exec \ - install-exec-am install-html install-html-am install-info \ - install-info-am install-man install-openpamHEADERS install-pdf \ - install-pdf-am install-ps install-ps-am install-strip \ - installcheck installcheck-am installdirs maintainer-clean \ +.PHONY: CTAGS GTAGS TAGS all all-am check check-am clean clean-generic \ + clean-libtool cscopelist-am ctags ctags-am distclean \ + distclean-generic distclean-libtool distclean-tags distdir dvi \ + dvi-am html html-am info info-am install install-am \ + install-data install-data-am install-dvi install-dvi-am \ + install-exec install-exec-am install-html install-html-am \ + install-info install-info-am install-man install-pdf \ + install-pdf-am install-ps install-ps-am \ + install-securityHEADERS install-strip installcheck \ + installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-generic \ - mostlyclean-libtool pdf pdf-am ps ps-am tags uninstall \ - uninstall-am uninstall-openpamHEADERS + mostlyclean-libtool pdf pdf-am ps ps-am tags tags-am uninstall \ + uninstall-am uninstall-securityHEADERS # Tell versions [3.59,3.63) of GNU make to not export all variables. diff --git a/contrib/openpam/include/security/openpam.h b/contrib/openpam/include/security/openpam.h index 4ba8b95fa0fc..0956997d9a0d 100644 --- a/contrib/openpam/include/security/openpam.h +++ b/contrib/openpam/include/security/openpam.h @@ -32,7 +32,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: openpam.h 605 2012-04-20 11:05:10Z des $ + * $Id: openpam.h 648 2013-03-05 17:54:27Z des $ */ #ifndef SECURITY_OPENPAM_H_INCLUDED diff --git a/contrib/openpam/include/security/openpam_attr.h b/contrib/openpam/include/security/openpam_attr.h index aada5cc8832c..2d88ae5f25a3 100644 --- a/contrib/openpam/include/security/openpam_attr.h +++ b/contrib/openpam/include/security/openpam_attr.h @@ -1,9 +1,9 @@ /* - * $Id: openpam_attr.h 405 2007-12-19 11:38:27Z des $ + * $Id: openpam_attr.h 656 2013-03-06 22:58:45Z des $ */ -#ifndef SECURITY_PAM_ATTRIBUTES_H_INCLUDED -#define SECURITY_PAM_ATTRIBUTES_H_INCLUDED +#ifndef SECURITY_OPENPAM_ATTR_H_INCLUDED +#define SECURITY_OPENPAM_ATTR_H_INCLUDED /* GCC attributes */ #if defined(__GNUC__) && defined(__GNUC_MINOR__) && !defined(__STRICT_ANSI__) @@ -25,4 +25,10 @@ # define OPENPAM_NONNULL(params) #endif -#endif /* !SECURITY_PAM_ATTRIBUTES_H_INCLUDED */ +#if OPENPAM_GNUC_PREREQ(2,7) +# define OPENPAM_UNUSED(var) var __attribute__((__unused__)) +#else +# define OPENPAM_UNUSED(var) var +#endif + +#endif /* !SECURITY_OPENPAM_ATTR_H_INCLUDED */ diff --git a/contrib/openpam/include/security/openpam_version.h b/contrib/openpam/include/security/openpam_version.h index d50d91368954..8f1adc26651f 100644 --- a/contrib/openpam/include/security/openpam_version.h +++ b/contrib/openpam/include/security/openpam_version.h @@ -32,14 +32,14 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: openpam_version.h 609 2012-05-26 13:57:45Z des $ + * $Id: openpam_version.h 737 2013-09-07 12:53:55Z des $ */ #ifndef SECURITY_OPENPAM_VERSION_H_INCLUDED #define SECURITY_OPENPAM_VERSION_H_INCLUDED #define OPENPAM -#define OPENPAM_VERSION 20120526 -#define OPENPAM_RELEASE "Micrampelis" +#define OPENPAM_VERSION 20130907 +#define OPENPAM_RELEASE "Nummularia" #endif /* !SECURITY_OPENPAM_VERSION_H_INCLUDED */ diff --git a/contrib/openpam/include/security/pam_appl.h b/contrib/openpam/include/security/pam_appl.h index b8f0536590a7..755409a77eb4 100644 --- a/contrib/openpam/include/security/pam_appl.h +++ b/contrib/openpam/include/security/pam_appl.h @@ -32,7 +32,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: pam_appl.h 437 2011-09-13 12:00:13Z des $ + * $Id: pam_appl.h 648 2013-03-05 17:54:27Z des $ */ #ifndef SECURITY_PAM_APPL_H_INCLUDED diff --git a/contrib/openpam/include/security/pam_constants.h b/contrib/openpam/include/security/pam_constants.h index 69add34b66e9..ddd87ade41f6 100644 --- a/contrib/openpam/include/security/pam_constants.h +++ b/contrib/openpam/include/security/pam_constants.h @@ -32,7 +32,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: pam_constants.h 443 2011-10-22 01:01:39Z des $ + * $Id: pam_constants.h 648 2013-03-05 17:54:27Z des $ */ #ifndef SECURITY_PAM_CONSTANTS_H_INCLUDED diff --git a/contrib/openpam/include/security/pam_modules.h b/contrib/openpam/include/security/pam_modules.h index 6242b3809235..7f1db465f039 100644 --- a/contrib/openpam/include/security/pam_modules.h +++ b/contrib/openpam/include/security/pam_modules.h @@ -32,7 +32,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: pam_modules.h 437 2011-09-13 12:00:13Z des $ + * $Id: pam_modules.h 648 2013-03-05 17:54:27Z des $ */ #ifndef SECURITY_PAM_MODULES_H_INCLUDED diff --git a/contrib/openpam/include/security/pam_types.h b/contrib/openpam/include/security/pam_types.h index d0d5b00ce5a7..fc834682a70c 100644 --- a/contrib/openpam/include/security/pam_types.h +++ b/contrib/openpam/include/security/pam_types.h @@ -32,7 +32,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: pam_types.h 437 2011-09-13 12:00:13Z des $ + * $Id: pam_types.h 648 2013-03-05 17:54:27Z des $ */ #ifndef SECURITY_PAM_TYPES_H_INCLUDED diff --git a/contrib/openpam/install-sh b/contrib/openpam/install-sh index 6781b987bdbc..377bb8687ffe 100755 --- a/contrib/openpam/install-sh +++ b/contrib/openpam/install-sh @@ -1,7 +1,7 @@ #!/bin/sh # install - install a program, script, or datafile -scriptversion=2009-04-28.21; # UTC +scriptversion=2011-11-20.07; # UTC # This originates from X11R5 (mit/util/scripts/install.sh), which was # later released in X11R6 (xc/config/util/install.sh) with the @@ -35,7 +35,7 @@ scriptversion=2009-04-28.21; # UTC # FSF changes to this file are in the public domain. # # Calling this script install-sh is preferred over install.sh, to prevent -# `make' implicit rules from creating a file called install from it +# 'make' implicit rules from creating a file called install from it # when there is no Makefile. # # This script is compatible with the BSD install script, but was written @@ -156,6 +156,10 @@ while test $# -ne 0; do -s) stripcmd=$stripprog;; -t) dst_arg=$2 + # Protect names problematic for 'test' and other utilities. + case $dst_arg in + -* | [=\(\)!]) dst_arg=./$dst_arg;; + esac shift;; -T) no_target_directory=true;; @@ -186,6 +190,10 @@ if test $# -ne 0 && test -z "$dir_arg$dst_arg"; then fi shift # arg dst_arg=$arg + # Protect names problematic for 'test' and other utilities. + case $dst_arg in + -* | [=\(\)!]) dst_arg=./$dst_arg;; + esac done fi @@ -194,13 +202,17 @@ if test $# -eq 0; then echo "$0: no input file specified." >&2 exit 1 fi - # It's OK to call `install-sh -d' without argument. + # It's OK to call 'install-sh -d' without argument. # This can happen when creating conditional directories. exit 0 fi if test -z "$dir_arg"; then - trap '(exit $?); exit' 1 2 13 15 + do_exit='(exit $ret); exit $ret' + trap "ret=129; $do_exit" 1 + trap "ret=130; $do_exit" 2 + trap "ret=141; $do_exit" 13 + trap "ret=143; $do_exit" 15 # Set umask so as not to create temps with too-generous modes. # However, 'strip' requires both read and write access to temps. @@ -228,9 +240,9 @@ fi for src do - # Protect names starting with `-'. + # Protect names problematic for 'test' and other utilities. case $src in - -*) src=./$src;; + -* | [=\(\)!]) src=./$src;; esac if test -n "$dir_arg"; then @@ -252,12 +264,7 @@ do echo "$0: no destination specified." >&2 exit 1 fi - dst=$dst_arg - # Protect names starting with `-'. - case $dst in - -*) dst=./$dst;; - esac # If destination is a directory, append the input filename; won't work # if double slashes aren't ignored. @@ -347,7 +354,7 @@ do if test -z "$dir_arg" || { # Check for POSIX incompatibilities with -m. # HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or - # other-writeable bit of parent directory when it shouldn't. + # other-writable bit of parent directory when it shouldn't. # FreeBSD 6.1 mkdir -m -p sets mode of existing directory. ls_ld_tmpdir=`ls -ld "$tmpdir"` case $ls_ld_tmpdir in @@ -385,7 +392,7 @@ do case $dstdir in /*) prefix='/';; - -*) prefix='./';; + [-=\(\)!]*) prefix='./';; *) prefix='';; esac @@ -403,7 +410,7 @@ do for d do - test -z "$d" && continue + test X"$d" = X && continue prefix=$prefix$d if test -d "$prefix"; then diff --git a/contrib/openpam/lib/Makefile.am b/contrib/openpam/lib/Makefile.am index 9ce2d2f5bc1e..4cd38c2e5cf9 100644 --- a/contrib/openpam/lib/Makefile.am +++ b/contrib/openpam/lib/Makefile.am @@ -1,92 +1,3 @@ -# $Id: Makefile.am 602 2012-04-15 17:31:15Z des $ +# $Id: Makefile.am 255376 2013-09-07 19:43:39Z des $ -NULL = - -INCLUDES = -I$(top_srcdir)/include - -lib_LTLIBRARIES = libpam.la - -noinst_HEADERS = \ - openpam_constants.h \ - openpam_ctype.h \ - openpam_debug.h \ - openpam_features.h \ - openpam_impl.h \ - openpam_strlcat.h \ - openpam_strlcmp.h \ - openpam_strlcpy.h - -libpam_la_SOURCES = \ - openpam_borrow_cred.c \ - openpam_check_owner_perms.c \ - openpam_configure.c \ - openpam_constants.c \ - openpam_dispatch.c \ - openpam_dynamic.c \ - openpam_features.c \ - openpam_findenv.c \ - openpam_free_data.c \ - openpam_free_envlist.c \ - openpam_get_feature.c \ - openpam_get_option.c \ - openpam_load.c \ - openpam_log.c \ - openpam_nullconv.c \ - openpam_readline.c \ - openpam_readlinev.c \ - openpam_readword.c \ - openpam_restore_cred.c \ - openpam_set_option.c \ - openpam_set_feature.c \ - openpam_static.c \ - openpam_straddch.c \ - openpam_subst.c \ - openpam_ttyconv.c \ - pam_acct_mgmt.c \ - pam_authenticate.c \ - pam_chauthtok.c \ - pam_close_session.c \ - pam_end.c \ - pam_error.c \ - pam_get_authtok.c \ - pam_get_data.c \ - pam_get_item.c \ - pam_get_user.c \ - pam_getenv.c \ - pam_getenvlist.c \ - pam_info.c \ - pam_open_session.c \ - pam_prompt.c \ - pam_putenv.c \ - pam_set_data.c \ - pam_set_item.c \ - pam_setcred.c \ - pam_setenv.c \ - pam_start.c \ - pam_strerror.c \ - pam_verror.c \ - pam_vinfo.c \ - pam_vprompt.c \ - $(NULL) - -libpam_la_LDFLAGS = -no-undefined -version-info @LIB_MAJ@ -libpam_la_LIBADD = @DL_LIBS@ - -EXTRA_DIST = \ - pam_authenticate_secondary.c \ - pam_get_mapped_authtok.c \ - pam_get_mapped_username.c \ - pam_set_mapped_authtok.c \ - pam_set_mapped_username.c \ - \ - pam_sm_acct_mgmt.c \ - pam_sm_authenticate.c \ - pam_sm_authenticate_secondary.c \ - pam_sm_chauthtok.c \ - pam_sm_close_session.c \ - pam_sm_get_mapped_authtok.c \ - pam_sm_get_mapped_username.c \ - pam_sm_open_session.c \ - pam_sm_set_mapped_authtok.c \ - pam_sm_set_mapped_username.c \ - pam_sm_setcred.c +SUBDIRS = libpam diff --git a/contrib/openpam/lib/Makefile.in b/contrib/openpam/lib/Makefile.in index 353fbaba9b64..3ea0f711e7d3 100644 --- a/contrib/openpam/lib/Makefile.in +++ b/contrib/openpam/lib/Makefile.in @@ -1,9 +1,8 @@ -# Makefile.in generated by automake 1.11.1 from Makefile.am. +# Makefile.in generated by automake 1.14 from Makefile.am. # @configure_input@ -# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, -# 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation, -# Inc. +# Copyright (C) 1994-2013 Free Software Foundation, Inc. + # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. @@ -15,10 +14,53 @@ @SET_MAKE@ -# $Id: Makefile.am 602 2012-04-15 17:31:15Z des $ - - +# $Id: Makefile.am 714 2013-08-19 15:30:21Z des $ VPATH = @srcdir@ +am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)' +am__make_running_with_option = \ + case $${target_option-} in \ + ?) ;; \ + *) echo "am__make_running_with_option: internal error: invalid" \ + "target option '$${target_option-}' specified" >&2; \ + exit 1;; \ + esac; \ + has_opt=no; \ + sane_makeflags=$$MAKEFLAGS; \ + if $(am__is_gnu_make); then \ + sane_makeflags=$$MFLAGS; \ + else \ + case $$MAKEFLAGS in \ + *\\[\ \ ]*) \ + bs=\\; \ + sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ + | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ + esac; \ + fi; \ + skip_next=no; \ + strip_trailopt () \ + { \ + flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ + }; \ + for flg in $$sane_makeflags; do \ + test $$skip_next = yes && { skip_next=no; continue; }; \ + case $$flg in \ + *=*|--*) continue;; \ + -*I) strip_trailopt 'I'; skip_next=yes;; \ + -*I?*) strip_trailopt 'I';; \ + -*O) strip_trailopt 'O'; skip_next=yes;; \ + -*O?*) strip_trailopt 'O';; \ + -*l) strip_trailopt 'l'; skip_next=yes;; \ + -*l?*) strip_trailopt 'l';; \ + -[dEDm]) skip_next=yes;; \ + -[JT]) skip_next=yes;; \ + esac; \ + case $$flg in \ + *$$target_option*) has_opt=yes; break;; \ + esac; \ + done; \ + test $$has_opt = yes +am__make_dryrun = (target_option=n; $(am__make_running_with_option)) +am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ @@ -38,84 +80,102 @@ POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = lib -DIST_COMMON = $(noinst_HEADERS) $(srcdir)/Makefile.am \ - $(srcdir)/Makefile.in +DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 -am__aclocal_m4_deps = $(top_srcdir)/configure.ac +am__aclocal_m4_deps = $(top_srcdir)/m4/libtool.m4 \ + $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \ + $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \ + $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = -am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; -am__vpath_adj = case $$p in \ - $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ - *) f=$$p;; \ - esac; -am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; -am__install_max = 40 -am__nobase_strip_setup = \ - srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` -am__nobase_strip = \ - for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" -am__nobase_list = $(am__nobase_strip_setup); \ - for p in $$list; do echo "$$p $$p"; done | \ - sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ - $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ - if (++n[$$2] == $(am__install_max)) \ - { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ - END { for (dir in files) print dir, files[dir] }' -am__base_list = \ - sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ - sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' -am__installdirs = "$(DESTDIR)$(libdir)" -LTLIBRARIES = $(lib_LTLIBRARIES) -libpam_la_DEPENDENCIES = -am__objects_1 = -am_libpam_la_OBJECTS = openpam_borrow_cred.lo \ - openpam_check_owner_perms.lo openpam_configure.lo \ - openpam_constants.lo openpam_dispatch.lo openpam_dynamic.lo \ - openpam_features.lo openpam_findenv.lo openpam_free_data.lo \ - openpam_free_envlist.lo openpam_get_feature.lo \ - openpam_get_option.lo openpam_load.lo openpam_log.lo \ - openpam_nullconv.lo openpam_readline.lo openpam_readlinev.lo \ - openpam_readword.lo openpam_restore_cred.lo \ - openpam_set_option.lo openpam_set_feature.lo openpam_static.lo \ - openpam_straddch.lo openpam_subst.lo openpam_ttyconv.lo \ - pam_acct_mgmt.lo pam_authenticate.lo pam_chauthtok.lo \ - pam_close_session.lo pam_end.lo pam_error.lo \ - pam_get_authtok.lo pam_get_data.lo pam_get_item.lo \ - pam_get_user.lo pam_getenv.lo pam_getenvlist.lo pam_info.lo \ - pam_open_session.lo pam_prompt.lo pam_putenv.lo \ - pam_set_data.lo pam_set_item.lo pam_setcred.lo pam_setenv.lo \ - pam_start.lo pam_strerror.lo pam_verror.lo pam_vinfo.lo \ - pam_vprompt.lo $(am__objects_1) -libpam_la_OBJECTS = $(am_libpam_la_OBJECTS) -libpam_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \ - $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ - $(libpam_la_LDFLAGS) $(LDFLAGS) -o $@ -DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) -depcomp = $(SHELL) $(top_srcdir)/depcomp -am__depfiles_maybe = depfiles -am__mv = mv -f -COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ - $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -LTCOMPILE = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ - --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ - $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -CCLD = $(CC) -LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ - --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \ - $(LDFLAGS) -o $@ -SOURCES = $(libpam_la_SOURCES) -DIST_SOURCES = $(libpam_la_SOURCES) -HEADERS = $(noinst_HEADERS) +AM_V_P = $(am__v_P_@AM_V@) +am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) +am__v_P_0 = false +am__v_P_1 = : +AM_V_GEN = $(am__v_GEN_@AM_V@) +am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) +am__v_GEN_0 = @echo " GEN " $@; +am__v_GEN_1 = +AM_V_at = $(am__v_at_@AM_V@) +am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) +am__v_at_0 = @ +am__v_at_1 = +SOURCES = +DIST_SOURCES = +RECURSIVE_TARGETS = all-recursive check-recursive cscopelist-recursive \ + ctags-recursive dvi-recursive html-recursive info-recursive \ + install-data-recursive install-dvi-recursive \ + install-exec-recursive install-html-recursive \ + install-info-recursive install-pdf-recursive \ + install-ps-recursive install-recursive installcheck-recursive \ + installdirs-recursive pdf-recursive ps-recursive \ + tags-recursive uninstall-recursive +am__can_run_installinfo = \ + case $$AM_UPDATE_INFO_DIR in \ + n|no|NO) false;; \ + *) (install-info --version) >/dev/null 2>&1;; \ + esac +RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \ + distclean-recursive maintainer-clean-recursive +am__recursive_targets = \ + $(RECURSIVE_TARGETS) \ + $(RECURSIVE_CLEAN_TARGETS) \ + $(am__extra_recursive_targets) +AM_RECURSIVE_TARGETS = $(am__recursive_targets:-recursive=) TAGS CTAGS \ + distdir +am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) +# Read a list of newline-separated strings from the standard input, +# and print each of them once, without duplicates. Input order is +# *not* preserved. +am__uniquify_input = $(AWK) '\ + BEGIN { nonempty = 0; } \ + { items[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in items) print i; }; } \ +' +# Make sure the list of sources is unique. This is necessary because, +# e.g., the same source file might be shared among _SOURCES variables +# for different programs/libraries. +am__define_uniq_tagged_files = \ + list='$(am__tagged_files)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | $(am__uniquify_input)` ETAGS = etags CTAGS = ctags +DIST_SUBDIRS = $(SUBDIRS) DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +am__relativize = \ + dir0=`pwd`; \ + sed_first='s,^\([^/]*\)/.*$$,\1,'; \ + sed_rest='s,^[^/]*/*,,'; \ + sed_last='s,^.*/\([^/]*\)$$,\1,'; \ + sed_butlast='s,/*[^/]*$$,,'; \ + while test -n "$$dir1"; do \ + first=`echo "$$dir1" | sed -e "$$sed_first"`; \ + if test "$$first" != "."; then \ + if test "$$first" = ".."; then \ + dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \ + dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \ + else \ + first2=`echo "$$dir2" | sed -e "$$sed_first"`; \ + if test "$$first2" = "$$first"; then \ + dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \ + else \ + dir2="../$$dir2"; \ + fi; \ + dir0="$$dir0"/"$$first"; \ + fi; \ + fi; \ + dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \ + done; \ + reldir="$$dir2" ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ +AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ @@ -126,6 +186,7 @@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ +CRYPTO_LIBS = @CRYPTO_LIBS@ CRYPT_LIBS = @CRYPT_LIBS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ @@ -231,97 +292,10 @@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ -NULL = -INCLUDES = -I$(top_srcdir)/include -lib_LTLIBRARIES = libpam.la -noinst_HEADERS = \ - openpam_constants.h \ - openpam_ctype.h \ - openpam_debug.h \ - openpam_features.h \ - openpam_impl.h \ - openpam_strlcat.h \ - openpam_strlcmp.h \ - openpam_strlcpy.h - -libpam_la_SOURCES = \ - openpam_borrow_cred.c \ - openpam_check_owner_perms.c \ - openpam_configure.c \ - openpam_constants.c \ - openpam_dispatch.c \ - openpam_dynamic.c \ - openpam_features.c \ - openpam_findenv.c \ - openpam_free_data.c \ - openpam_free_envlist.c \ - openpam_get_feature.c \ - openpam_get_option.c \ - openpam_load.c \ - openpam_log.c \ - openpam_nullconv.c \ - openpam_readline.c \ - openpam_readlinev.c \ - openpam_readword.c \ - openpam_restore_cred.c \ - openpam_set_option.c \ - openpam_set_feature.c \ - openpam_static.c \ - openpam_straddch.c \ - openpam_subst.c \ - openpam_ttyconv.c \ - pam_acct_mgmt.c \ - pam_authenticate.c \ - pam_chauthtok.c \ - pam_close_session.c \ - pam_end.c \ - pam_error.c \ - pam_get_authtok.c \ - pam_get_data.c \ - pam_get_item.c \ - pam_get_user.c \ - pam_getenv.c \ - pam_getenvlist.c \ - pam_info.c \ - pam_open_session.c \ - pam_prompt.c \ - pam_putenv.c \ - pam_set_data.c \ - pam_set_item.c \ - pam_setcred.c \ - pam_setenv.c \ - pam_start.c \ - pam_strerror.c \ - pam_verror.c \ - pam_vinfo.c \ - pam_vprompt.c \ - $(NULL) - -libpam_la_LDFLAGS = -no-undefined -version-info @LIB_MAJ@ -libpam_la_LIBADD = @DL_LIBS@ -EXTRA_DIST = \ - pam_authenticate_secondary.c \ - pam_get_mapped_authtok.c \ - pam_get_mapped_username.c \ - pam_set_mapped_authtok.c \ - pam_set_mapped_username.c \ - \ - pam_sm_acct_mgmt.c \ - pam_sm_authenticate.c \ - pam_sm_authenticate_secondary.c \ - pam_sm_chauthtok.c \ - pam_sm_close_session.c \ - pam_sm_get_mapped_authtok.c \ - pam_sm_get_mapped_username.c \ - pam_sm_open_session.c \ - pam_sm_set_mapped_authtok.c \ - pam_sm_set_mapped_username.c \ - pam_sm_setcred.c - -all: all-am +SUBDIRS = libpam +all: all-recursive .SUFFIXES: -.SUFFIXES: .c .lo .o .obj $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ @@ -352,117 +326,6 @@ $(top_srcdir)/configure: $(am__configure_deps) $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): -install-libLTLIBRARIES: $(lib_LTLIBRARIES) - @$(NORMAL_INSTALL) - test -z "$(libdir)" || $(MKDIR_P) "$(DESTDIR)$(libdir)" - @list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \ - list2=; for p in $$list; do \ - if test -f $$p; then \ - list2="$$list2 $$p"; \ - else :; fi; \ - done; \ - test -z "$$list2" || { \ - echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(libdir)'"; \ - $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(libdir)"; \ - } - -uninstall-libLTLIBRARIES: - @$(NORMAL_UNINSTALL) - @list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \ - for p in $$list; do \ - $(am__strip_dir) \ - echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(libdir)/$$f'"; \ - $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(libdir)/$$f"; \ - done - -clean-libLTLIBRARIES: - -test -z "$(lib_LTLIBRARIES)" || rm -f $(lib_LTLIBRARIES) - @list='$(lib_LTLIBRARIES)'; for p in $$list; do \ - dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \ - test "$$dir" != "$$p" || dir=.; \ - echo "rm -f \"$${dir}/so_locations\""; \ - rm -f "$${dir}/so_locations"; \ - done -libpam.la: $(libpam_la_OBJECTS) $(libpam_la_DEPENDENCIES) - $(libpam_la_LINK) -rpath $(libdir) $(libpam_la_OBJECTS) $(libpam_la_LIBADD) $(LIBS) - -mostlyclean-compile: - -rm -f *.$(OBJEXT) - -distclean-compile: - -rm -f *.tab.c - -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/openpam_borrow_cred.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/openpam_check_owner_perms.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/openpam_configure.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/openpam_constants.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/openpam_dispatch.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/openpam_dynamic.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/openpam_features.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/openpam_findenv.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/openpam_free_data.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/openpam_free_envlist.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/openpam_get_feature.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/openpam_get_option.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/openpam_load.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/openpam_log.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/openpam_nullconv.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/openpam_readline.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/openpam_readlinev.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/openpam_readword.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/openpam_restore_cred.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/openpam_set_feature.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/openpam_set_option.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/openpam_static.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/openpam_straddch.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/openpam_subst.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/openpam_ttyconv.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pam_acct_mgmt.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pam_authenticate.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pam_chauthtok.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pam_close_session.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pam_end.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pam_error.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pam_get_authtok.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pam_get_data.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pam_get_item.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pam_get_user.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pam_getenv.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pam_getenvlist.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pam_info.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pam_open_session.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pam_prompt.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pam_putenv.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pam_set_data.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pam_set_item.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pam_setcred.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pam_setenv.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pam_start.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pam_strerror.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pam_verror.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pam_vinfo.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pam_vprompt.Plo@am__quote@ - -.c.o: -@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(COMPILE) -c $< - -.c.obj: -@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'` - -.c.lo: -@am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $< mostlyclean-libtool: -rm -f *.lo @@ -470,26 +333,62 @@ mostlyclean-libtool: clean-libtool: -rm -rf .libs _libs -ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) - list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ - unique=`for i in $$list; do \ - if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ - done | \ - $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ - END { if (nonempty) { for (i in files) print i; }; }'`; \ - mkid -fID $$unique -tags: TAGS +# This directory's subdirectories are mostly independent; you can cd +# into them and run 'make' without going through this Makefile. +# To change the values of 'make' variables: instead of editing Makefiles, +# (1) if the variable is set in 'config.status', edit 'config.status' +# (which will cause the Makefiles to be regenerated when you run 'make'); +# (2) otherwise, pass the desired values on the 'make' command line. +$(am__recursive_targets): + @fail=; \ + if $(am__make_keepgoing); then \ + failcom='fail=yes'; \ + else \ + failcom='exit 1'; \ + fi; \ + dot_seen=no; \ + target=`echo $@ | sed s/-recursive//`; \ + case "$@" in \ + distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ + *) list='$(SUBDIRS)' ;; \ + esac; \ + for subdir in $$list; do \ + echo "Making $$target in $$subdir"; \ + if test "$$subdir" = "."; then \ + dot_seen=yes; \ + local_target="$$target-am"; \ + else \ + local_target="$$target"; \ + fi; \ + ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ + || eval $$failcom; \ + done; \ + if test "$$dot_seen" = "no"; then \ + $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ + fi; test -z "$$fail" -TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ - $(TAGS_FILES) $(LISP) +ID: $(am__tagged_files) + $(am__define_uniq_tagged_files); mkid -fID $$unique +tags: tags-recursive +TAGS: tags + +tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ - list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ - unique=`for i in $$list; do \ - if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ - done | \ - $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ - END { if (nonempty) { for (i in files) print i; }; }'`; \ + if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \ + include_option=--etags-include; \ + empty_fix=.; \ + else \ + include_option=--include; \ + empty_fix=; \ + fi; \ + list='$(SUBDIRS)'; for subdir in $$list; do \ + if test "$$subdir" = .; then :; else \ + test ! -f $$subdir/TAGS || \ + set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \ + fi; \ + done; \ + $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ @@ -501,15 +400,11 @@ TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $$unique; \ fi; \ fi -ctags: CTAGS -CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ - $(TAGS_FILES) $(LISP) - list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ - unique=`for i in $$list; do \ - if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ - done | \ - $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ - END { if (nonempty) { for (i in files) print i; }; }'`; \ +ctags: ctags-recursive + +CTAGS: ctags +ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique @@ -518,6 +413,21 @@ GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" +cscopelist: cscopelist-recursive + +cscopelist-am: $(am__tagged_files) + list='$(am__tagged_files)'; \ + case "$(srcdir)" in \ + [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ + *) sdir=$(subdir)/$(srcdir) ;; \ + esac; \ + for i in $$list; do \ + if test -f "$$i"; then \ + echo "$(subdir)/$$i"; \ + else \ + echo "$$sdir/$$i"; \ + fi; \ + done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags @@ -552,27 +462,55 @@ distdir: $(DISTFILES) || exit 1; \ fi; \ done -check-am: all-am -check: check-am -all-am: Makefile $(LTLIBRARIES) $(HEADERS) -installdirs: - for dir in "$(DESTDIR)$(libdir)"; do \ - test -z "$$dir" || $(MKDIR_P) "$$dir"; \ + @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ + if test "$$subdir" = .; then :; else \ + $(am__make_dryrun) \ + || test -d "$(distdir)/$$subdir" \ + || $(MKDIR_P) "$(distdir)/$$subdir" \ + || exit 1; \ + dir1=$$subdir; dir2="$(distdir)/$$subdir"; \ + $(am__relativize); \ + new_distdir=$$reldir; \ + dir1=$$subdir; dir2="$(top_distdir)"; \ + $(am__relativize); \ + new_top_distdir=$$reldir; \ + echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \ + echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \ + ($(am__cd) $$subdir && \ + $(MAKE) $(AM_MAKEFLAGS) \ + top_distdir="$$new_top_distdir" \ + distdir="$$new_distdir" \ + am__remove_distdir=: \ + am__skip_length_check=: \ + am__skip_mode_fix=: \ + distdir) \ + || exit 1; \ + fi; \ done -install: install-am -install-exec: install-exec-am -install-data: install-data-am -uninstall: uninstall-am +check-am: all-am +check: check-recursive +all-am: Makefile +installdirs: installdirs-recursive +installdirs-am: +install: install-recursive +install-exec: install-exec-recursive +install-data: install-data-recursive +uninstall: uninstall-recursive install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am -installcheck: installcheck-am +installcheck: installcheck-recursive install-strip: - $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ - install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ - `test -z '$(STRIP)' || \ - echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install + if test -z '$(STRIP)'; then \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + install; \ + else \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ + fi mostlyclean-generic: clean-generic: @@ -584,92 +522,86 @@ distclean-generic: maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." -clean: clean-am +clean: clean-recursive -clean-am: clean-generic clean-libLTLIBRARIES clean-libtool \ - mostlyclean-am +clean-am: clean-generic clean-libtool mostlyclean-am -distclean: distclean-am - -rm -rf ./$(DEPDIR) +distclean: distclean-recursive -rm -f Makefile -distclean-am: clean-am distclean-compile distclean-generic \ - distclean-tags +distclean-am: clean-am distclean-generic distclean-tags -dvi: dvi-am +dvi: dvi-recursive dvi-am: -html: html-am +html: html-recursive html-am: -info: info-am +info: info-recursive info-am: install-data-am: -install-dvi: install-dvi-am +install-dvi: install-dvi-recursive install-dvi-am: -install-exec-am: install-libLTLIBRARIES +install-exec-am: -install-html: install-html-am +install-html: install-html-recursive install-html-am: -install-info: install-info-am +install-info: install-info-recursive install-info-am: install-man: -install-pdf: install-pdf-am +install-pdf: install-pdf-recursive install-pdf-am: -install-ps: install-ps-am +install-ps: install-ps-recursive install-ps-am: installcheck-am: -maintainer-clean: maintainer-clean-am - -rm -rf ./$(DEPDIR) +maintainer-clean: maintainer-clean-recursive -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic -mostlyclean: mostlyclean-am +mostlyclean: mostlyclean-recursive -mostlyclean-am: mostlyclean-compile mostlyclean-generic \ - mostlyclean-libtool +mostlyclean-am: mostlyclean-generic mostlyclean-libtool -pdf: pdf-am +pdf: pdf-recursive pdf-am: -ps: ps-am +ps: ps-recursive ps-am: -uninstall-am: uninstall-libLTLIBRARIES +uninstall-am: -.MAKE: install-am install-strip +.MAKE: $(am__recursive_targets) install-am install-strip -.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \ - clean-libLTLIBRARIES clean-libtool ctags distclean \ - distclean-compile distclean-generic distclean-libtool \ +.PHONY: $(am__recursive_targets) CTAGS GTAGS TAGS all all-am check \ + check-am clean clean-generic clean-libtool cscopelist-am ctags \ + ctags-am distclean distclean-generic distclean-libtool \ distclean-tags distdir dvi dvi-am html html-am info info-am \ install install-am install-data install-data-am install-dvi \ install-dvi-am install-exec install-exec-am install-html \ - install-html-am install-info install-info-am \ - install-libLTLIBRARIES install-man install-pdf install-pdf-am \ - install-ps install-ps-am install-strip installcheck \ - installcheck-am installdirs maintainer-clean \ - maintainer-clean-generic mostlyclean mostlyclean-compile \ - mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ - tags uninstall uninstall-am uninstall-libLTLIBRARIES + install-html-am install-info install-info-am install-man \ + install-pdf install-pdf-am install-ps install-ps-am \ + install-strip installcheck installcheck-am installdirs \ + installdirs-am maintainer-clean maintainer-clean-generic \ + mostlyclean mostlyclean-generic mostlyclean-libtool pdf pdf-am \ + ps ps-am tags tags-am uninstall uninstall-am # Tell versions [3.59,3.63) of GNU make to not export all variables. diff --git a/contrib/openpam/lib/libpam/Makefile.am b/contrib/openpam/lib/libpam/Makefile.am new file mode 100644 index 000000000000..99c37f00ee6b --- /dev/null +++ b/contrib/openpam/lib/libpam/Makefile.am @@ -0,0 +1,100 @@ +# $Id: Makefile.am 660 2013-03-11 15:08:52Z des $ + +NULL = + +AM_CPPFLAGS = -I$(top_srcdir)/include + +lib_LTLIBRARIES = libpam.la + +noinst_HEADERS = \ + openpam_asprintf.h \ + openpam_constants.h \ + openpam_cred.h \ + openpam_ctype.h \ + openpam_debug.h \ + openpam_dlfunc.h \ + openpam_features.h \ + openpam_impl.h \ + openpam_strlcat.h \ + openpam_strlcmp.h \ + openpam_strlcpy.h \ + openpam_vasprintf.h + +libpam_la_SOURCES = \ + openpam_asprintf.c \ + openpam_borrow_cred.c \ + openpam_check_owner_perms.c \ + openpam_configure.c \ + openpam_constants.c \ + openpam_dispatch.c \ + openpam_dynamic.c \ + openpam_features.c \ + openpam_findenv.c \ + openpam_free_data.c \ + openpam_free_envlist.c \ + openpam_get_feature.c \ + openpam_get_option.c \ + openpam_load.c \ + openpam_log.c \ + openpam_nullconv.c \ + openpam_readline.c \ + openpam_readlinev.c \ + openpam_readword.c \ + openpam_restore_cred.c \ + openpam_set_option.c \ + openpam_set_feature.c \ + openpam_static.c \ + openpam_strlcat.c \ + openpam_strlcpy.c \ + openpam_straddch.c \ + openpam_subst.c \ + openpam_vasprintf.c \ + openpam_ttyconv.c \ + pam_acct_mgmt.c \ + pam_authenticate.c \ + pam_chauthtok.c \ + pam_close_session.c \ + pam_end.c \ + pam_error.c \ + pam_get_authtok.c \ + pam_get_data.c \ + pam_get_item.c \ + pam_get_user.c \ + pam_getenv.c \ + pam_getenvlist.c \ + pam_info.c \ + pam_open_session.c \ + pam_prompt.c \ + pam_putenv.c \ + pam_set_data.c \ + pam_set_item.c \ + pam_setcred.c \ + pam_setenv.c \ + pam_start.c \ + pam_strerror.c \ + pam_verror.c \ + pam_vinfo.c \ + pam_vprompt.c \ + $(NULL) + +libpam_la_LDFLAGS = -no-undefined -version-info @LIB_MAJ@ +libpam_la_LIBADD = @DL_LIBS@ + +EXTRA_DIST = \ + pam_authenticate_secondary.c \ + pam_get_mapped_authtok.c \ + pam_get_mapped_username.c \ + pam_set_mapped_authtok.c \ + pam_set_mapped_username.c \ + \ + pam_sm_acct_mgmt.c \ + pam_sm_authenticate.c \ + pam_sm_authenticate_secondary.c \ + pam_sm_chauthtok.c \ + pam_sm_close_session.c \ + pam_sm_get_mapped_authtok.c \ + pam_sm_get_mapped_username.c \ + pam_sm_open_session.c \ + pam_sm_set_mapped_authtok.c \ + pam_sm_set_mapped_username.c \ + pam_sm_setcred.c diff --git a/contrib/openpam/lib/libpam/Makefile.in b/contrib/openpam/lib/libpam/Makefile.in new file mode 100644 index 000000000000..b84d4793f05c --- /dev/null +++ b/contrib/openpam/lib/libpam/Makefile.in @@ -0,0 +1,802 @@ +# Makefile.in generated by automake 1.14 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994-2013 Free Software Foundation, Inc. + +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ + +# $Id: Makefile.am 660 2013-03-11 15:08:52Z des $ + + +VPATH = @srcdir@ +am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)' +am__make_running_with_option = \ + case $${target_option-} in \ + ?) ;; \ + *) echo "am__make_running_with_option: internal error: invalid" \ + "target option '$${target_option-}' specified" >&2; \ + exit 1;; \ + esac; \ + has_opt=no; \ + sane_makeflags=$$MAKEFLAGS; \ + if $(am__is_gnu_make); then \ + sane_makeflags=$$MFLAGS; \ + else \ + case $$MAKEFLAGS in \ + *\\[\ \ ]*) \ + bs=\\; \ + sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ + | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ + esac; \ + fi; \ + skip_next=no; \ + strip_trailopt () \ + { \ + flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ + }; \ + for flg in $$sane_makeflags; do \ + test $$skip_next = yes && { skip_next=no; continue; }; \ + case $$flg in \ + *=*|--*) continue;; \ + -*I) strip_trailopt 'I'; skip_next=yes;; \ + -*I?*) strip_trailopt 'I';; \ + -*O) strip_trailopt 'O'; skip_next=yes;; \ + -*O?*) strip_trailopt 'O';; \ + -*l) strip_trailopt 'l'; skip_next=yes;; \ + -*l?*) strip_trailopt 'l';; \ + -[dEDm]) skip_next=yes;; \ + -[JT]) skip_next=yes;; \ + esac; \ + case $$flg in \ + *$$target_option*) has_opt=yes; break;; \ + esac; \ + done; \ + test $$has_opt = yes +am__make_dryrun = (target_option=n; $(am__make_running_with_option)) +am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +subdir = lib/libpam +DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \ + $(top_srcdir)/depcomp $(noinst_HEADERS) +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/m4/libtool.m4 \ + $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \ + $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \ + $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = $(top_builddir)/config.h +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; +am__vpath_adj = case $$p in \ + $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ + *) f=$$p;; \ + esac; +am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; +am__install_max = 40 +am__nobase_strip_setup = \ + srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` +am__nobase_strip = \ + for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" +am__nobase_list = $(am__nobase_strip_setup); \ + for p in $$list; do echo "$$p $$p"; done | \ + sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ + $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ + if (++n[$$2] == $(am__install_max)) \ + { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ + END { for (dir in files) print dir, files[dir] }' +am__base_list = \ + sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ + sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' +am__uninstall_files_from_dir = { \ + test -z "$$files" \ + || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ + || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ + $(am__cd) "$$dir" && rm -f $$files; }; \ + } +am__installdirs = "$(DESTDIR)$(libdir)" +LTLIBRARIES = $(lib_LTLIBRARIES) +libpam_la_DEPENDENCIES = +am__objects_1 = +am_libpam_la_OBJECTS = openpam_asprintf.lo openpam_borrow_cred.lo \ + openpam_check_owner_perms.lo openpam_configure.lo \ + openpam_constants.lo openpam_dispatch.lo openpam_dynamic.lo \ + openpam_features.lo openpam_findenv.lo openpam_free_data.lo \ + openpam_free_envlist.lo openpam_get_feature.lo \ + openpam_get_option.lo openpam_load.lo openpam_log.lo \ + openpam_nullconv.lo openpam_readline.lo openpam_readlinev.lo \ + openpam_readword.lo openpam_restore_cred.lo \ + openpam_set_option.lo openpam_set_feature.lo openpam_static.lo \ + openpam_strlcat.lo openpam_strlcpy.lo openpam_straddch.lo \ + openpam_subst.lo openpam_vasprintf.lo openpam_ttyconv.lo \ + pam_acct_mgmt.lo pam_authenticate.lo pam_chauthtok.lo \ + pam_close_session.lo pam_end.lo pam_error.lo \ + pam_get_authtok.lo pam_get_data.lo pam_get_item.lo \ + pam_get_user.lo pam_getenv.lo pam_getenvlist.lo pam_info.lo \ + pam_open_session.lo pam_prompt.lo pam_putenv.lo \ + pam_set_data.lo pam_set_item.lo pam_setcred.lo pam_setenv.lo \ + pam_start.lo pam_strerror.lo pam_verror.lo pam_vinfo.lo \ + pam_vprompt.lo $(am__objects_1) +libpam_la_OBJECTS = $(am_libpam_la_OBJECTS) +AM_V_lt = $(am__v_lt_@AM_V@) +am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) +am__v_lt_0 = --silent +am__v_lt_1 = +libpam_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(libpam_la_LDFLAGS) $(LDFLAGS) -o $@ +AM_V_P = $(am__v_P_@AM_V@) +am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) +am__v_P_0 = false +am__v_P_1 = : +AM_V_GEN = $(am__v_GEN_@AM_V@) +am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) +am__v_GEN_0 = @echo " GEN " $@; +am__v_GEN_1 = +AM_V_at = $(am__v_at_@AM_V@) +am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) +am__v_at_0 = @ +am__v_at_1 = +DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) +depcomp = $(SHELL) $(top_srcdir)/depcomp +am__depfiles_maybe = depfiles +am__mv = mv -f +COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ + $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ + $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ + $(AM_CFLAGS) $(CFLAGS) +AM_V_CC = $(am__v_CC_@AM_V@) +am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) +am__v_CC_0 = @echo " CC " $@; +am__v_CC_1 = +CCLD = $(CC) +LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(AM_LDFLAGS) $(LDFLAGS) -o $@ +AM_V_CCLD = $(am__v_CCLD_@AM_V@) +am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) +am__v_CCLD_0 = @echo " CCLD " $@; +am__v_CCLD_1 = +SOURCES = $(libpam_la_SOURCES) +DIST_SOURCES = $(libpam_la_SOURCES) +am__can_run_installinfo = \ + case $$AM_UPDATE_INFO_DIR in \ + n|no|NO) false;; \ + *) (install-info --version) >/dev/null 2>&1;; \ + esac +HEADERS = $(noinst_HEADERS) +am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) +# Read a list of newline-separated strings from the standard input, +# and print each of them once, without duplicates. Input order is +# *not* preserved. +am__uniquify_input = $(AWK) '\ + BEGIN { nonempty = 0; } \ + { items[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in items) print i; }; } \ +' +# Make sure the list of sources is unique. This is necessary because, +# e.g., the same source file might be shared among _SOURCES variables +# for different programs/libraries. +am__define_uniq_tagged_files = \ + list='$(am__tagged_files)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | $(am__uniquify_input)` +ETAGS = etags +CTAGS = ctags +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +AMTAR = @AMTAR@ +AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ +AR = @AR@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CRYPTO_LIBS = @CRYPTO_LIBS@ +CRYPT_LIBS = @CRYPT_LIBS@ +CYGPATH_W = @CYGPATH_W@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DLLTOOL = @DLLTOOL@ +DL_LIBS = @DL_LIBS@ +DSYMUTIL = @DSYMUTIL@ +DUMPBIN = @DUMPBIN@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +FGREP = @FGREP@ +GREP = @GREP@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +LD = @LD@ +LDFLAGS = @LDFLAGS@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBTOOL = @LIBTOOL@ +LIB_MAJ = @LIB_MAJ@ +LIPO = @LIPO@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +MAKEINFO = @MAKEINFO@ +MANIFEST_TOOL = @MANIFEST_TOOL@ +MKDIR_P = @MKDIR_P@ +NM = @NM@ +NMEDIT = @NMEDIT@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +OPENPAM_MODULES_DIR = @OPENPAM_MODULES_DIR@ +OTOOL = @OTOOL@ +OTOOL64 = @OTOOL64@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_URL = @PACKAGE_URL@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +RANLIB = @RANLIB@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRIP = @STRIP@ +VERSION = @VERSION@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_AR = @ac_ct_AR@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +sysconfdir = @sysconfdir@ +target_alias = @target_alias@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +NULL = +AM_CPPFLAGS = -I$(top_srcdir)/include +lib_LTLIBRARIES = libpam.la +noinst_HEADERS = \ + openpam_asprintf.h \ + openpam_constants.h \ + openpam_cred.h \ + openpam_ctype.h \ + openpam_debug.h \ + openpam_dlfunc.h \ + openpam_features.h \ + openpam_impl.h \ + openpam_strlcat.h \ + openpam_strlcmp.h \ + openpam_strlcpy.h \ + openpam_vasprintf.h + +libpam_la_SOURCES = \ + openpam_asprintf.c \ + openpam_borrow_cred.c \ + openpam_check_owner_perms.c \ + openpam_configure.c \ + openpam_constants.c \ + openpam_dispatch.c \ + openpam_dynamic.c \ + openpam_features.c \ + openpam_findenv.c \ + openpam_free_data.c \ + openpam_free_envlist.c \ + openpam_get_feature.c \ + openpam_get_option.c \ + openpam_load.c \ + openpam_log.c \ + openpam_nullconv.c \ + openpam_readline.c \ + openpam_readlinev.c \ + openpam_readword.c \ + openpam_restore_cred.c \ + openpam_set_option.c \ + openpam_set_feature.c \ + openpam_static.c \ + openpam_strlcat.c \ + openpam_strlcpy.c \ + openpam_straddch.c \ + openpam_subst.c \ + openpam_vasprintf.c \ + openpam_ttyconv.c \ + pam_acct_mgmt.c \ + pam_authenticate.c \ + pam_chauthtok.c \ + pam_close_session.c \ + pam_end.c \ + pam_error.c \ + pam_get_authtok.c \ + pam_get_data.c \ + pam_get_item.c \ + pam_get_user.c \ + pam_getenv.c \ + pam_getenvlist.c \ + pam_info.c \ + pam_open_session.c \ + pam_prompt.c \ + pam_putenv.c \ + pam_set_data.c \ + pam_set_item.c \ + pam_setcred.c \ + pam_setenv.c \ + pam_start.c \ + pam_strerror.c \ + pam_verror.c \ + pam_vinfo.c \ + pam_vprompt.c \ + $(NULL) + +libpam_la_LDFLAGS = -no-undefined -version-info @LIB_MAJ@ +libpam_la_LIBADD = @DL_LIBS@ +EXTRA_DIST = \ + pam_authenticate_secondary.c \ + pam_get_mapped_authtok.c \ + pam_get_mapped_username.c \ + pam_set_mapped_authtok.c \ + pam_set_mapped_username.c \ + \ + pam_sm_acct_mgmt.c \ + pam_sm_authenticate.c \ + pam_sm_authenticate_secondary.c \ + pam_sm_chauthtok.c \ + pam_sm_close_session.c \ + pam_sm_get_mapped_authtok.c \ + pam_sm_get_mapped_username.c \ + pam_sm_open_session.c \ + pam_sm_set_mapped_authtok.c \ + pam_sm_set_mapped_username.c \ + pam_sm_setcred.c + +all: all-am + +.SUFFIXES: +.SUFFIXES: .c .lo .o .obj +$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ + && { if test -f $@; then exit 0; else break; fi; }; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign lib/libpam/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --foreign lib/libpam/Makefile +.PRECIOUS: Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(am__aclocal_m4_deps): + +install-libLTLIBRARIES: $(lib_LTLIBRARIES) + @$(NORMAL_INSTALL) + @list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \ + list2=; for p in $$list; do \ + if test -f $$p; then \ + list2="$$list2 $$p"; \ + else :; fi; \ + done; \ + test -z "$$list2" || { \ + echo " $(MKDIR_P) '$(DESTDIR)$(libdir)'"; \ + $(MKDIR_P) "$(DESTDIR)$(libdir)" || exit 1; \ + echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(libdir)'"; \ + $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(libdir)"; \ + } + +uninstall-libLTLIBRARIES: + @$(NORMAL_UNINSTALL) + @list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \ + for p in $$list; do \ + $(am__strip_dir) \ + echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(libdir)/$$f'"; \ + $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(libdir)/$$f"; \ + done + +clean-libLTLIBRARIES: + -test -z "$(lib_LTLIBRARIES)" || rm -f $(lib_LTLIBRARIES) + @list='$(lib_LTLIBRARIES)'; \ + locs=`for p in $$list; do echo $$p; done | \ + sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ + sort -u`; \ + test -z "$$locs" || { \ + echo rm -f $${locs}; \ + rm -f $${locs}; \ + } + +libpam.la: $(libpam_la_OBJECTS) $(libpam_la_DEPENDENCIES) $(EXTRA_libpam_la_DEPENDENCIES) + $(AM_V_CCLD)$(libpam_la_LINK) -rpath $(libdir) $(libpam_la_OBJECTS) $(libpam_la_LIBADD) $(LIBS) + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/openpam_asprintf.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/openpam_borrow_cred.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/openpam_check_owner_perms.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/openpam_configure.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/openpam_constants.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/openpam_dispatch.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/openpam_dynamic.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/openpam_features.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/openpam_findenv.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/openpam_free_data.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/openpam_free_envlist.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/openpam_get_feature.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/openpam_get_option.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/openpam_load.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/openpam_log.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/openpam_nullconv.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/openpam_readline.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/openpam_readlinev.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/openpam_readword.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/openpam_restore_cred.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/openpam_set_feature.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/openpam_set_option.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/openpam_static.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/openpam_straddch.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/openpam_strlcat.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/openpam_strlcpy.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/openpam_subst.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/openpam_ttyconv.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/openpam_vasprintf.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pam_acct_mgmt.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pam_authenticate.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pam_chauthtok.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pam_close_session.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pam_end.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pam_error.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pam_get_authtok.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pam_get_data.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pam_get_item.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pam_get_user.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pam_getenv.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pam_getenvlist.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pam_info.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pam_open_session.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pam_prompt.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pam_putenv.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pam_set_data.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pam_set_item.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pam_setcred.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pam_setenv.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pam_start.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pam_strerror.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pam_verror.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pam_vinfo.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pam_vprompt.Plo@am__quote@ + +.c.o: +@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< + +.c.obj: +@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` + +.c.lo: +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + +ID: $(am__tagged_files) + $(am__define_uniq_tagged_files); mkid -fID $$unique +tags: tags-am +TAGS: tags + +tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + set x; \ + here=`pwd`; \ + $(am__define_uniq_tagged_files); \ + shift; \ + if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + if test $$# -gt 0; then \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + "$$@" $$unique; \ + else \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$unique; \ + fi; \ + fi +ctags: ctags-am + +CTAGS: ctags +ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + $(am__define_uniq_tagged_files); \ + test -z "$(CTAGS_ARGS)$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && $(am__cd) $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) "$$here" +cscopelist: cscopelist-am + +cscopelist-am: $(am__tagged_files) + list='$(am__tagged_files)'; \ + case "$(srcdir)" in \ + [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ + *) sdir=$(subdir)/$(srcdir) ;; \ + esac; \ + for i in $$list; do \ + if test -f "$$i"; then \ + echo "$(subdir)/$$i"; \ + else \ + echo "$$sdir/$$i"; \ + fi; \ + done >> $(top_builddir)/cscope.files + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + +distdir: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ + else \ + test -f "$(distdir)/$$file" \ + || cp -p $$d/$$file "$(distdir)/$$file" \ + || exit 1; \ + fi; \ + done +check-am: all-am +check: check-am +all-am: Makefile $(LTLIBRARIES) $(HEADERS) +installdirs: + for dir in "$(DESTDIR)$(libdir)"; do \ + test -z "$$dir" || $(MKDIR_P) "$$dir"; \ + done +install: install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + if test -z '$(STRIP)'; then \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + install; \ + else \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ + fi +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-am + +clean-am: clean-generic clean-libLTLIBRARIES clean-libtool \ + mostlyclean-am + +distclean: distclean-am + -rm -rf ./$(DEPDIR) + -rm -f Makefile +distclean-am: clean-am distclean-compile distclean-generic \ + distclean-tags + +dvi: dvi-am + +dvi-am: + +html: html-am + +html-am: + +info: info-am + +info-am: + +install-data-am: + +install-dvi: install-dvi-am + +install-dvi-am: + +install-exec-am: install-libLTLIBRARIES + +install-html: install-html-am + +install-html-am: + +install-info: install-info-am + +install-info-am: + +install-man: + +install-pdf: install-pdf-am + +install-pdf-am: + +install-ps: install-ps-am + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -rf ./$(DEPDIR) + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-compile mostlyclean-generic \ + mostlyclean-libtool + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: uninstall-libLTLIBRARIES + +.MAKE: install-am install-strip + +.PHONY: CTAGS GTAGS TAGS all all-am check check-am clean clean-generic \ + clean-libLTLIBRARIES clean-libtool cscopelist-am ctags \ + ctags-am distclean distclean-compile distclean-generic \ + distclean-libtool distclean-tags distdir dvi dvi-am html \ + html-am info info-am install install-am install-data \ + install-data-am install-dvi install-dvi-am install-exec \ + install-exec-am install-html install-html-am install-info \ + install-info-am install-libLTLIBRARIES install-man install-pdf \ + install-pdf-am install-ps install-ps-am install-strip \ + installcheck installcheck-am installdirs maintainer-clean \ + maintainer-clean-generic mostlyclean mostlyclean-compile \ + mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ + tags tags-am uninstall uninstall-am uninstall-libLTLIBRARIES + + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/contrib/openpam/lib/libpam/openpam_asprintf.c b/contrib/openpam/lib/libpam/openpam_asprintf.c new file mode 100644 index 000000000000..3169f4baa497 --- /dev/null +++ b/contrib/openpam/lib/libpam/openpam_asprintf.c @@ -0,0 +1,57 @@ +/*- + * Copyright (c) 2012 Dag-Erling Smørgrav + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote + * products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $Id: openpam_asprintf.c 648 2013-03-05 17:54:27Z des $ + */ + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#ifndef HAVE_ASPRINTF + +#include +#include + +#include "openpam_asprintf.h" +#include "openpam_vasprintf.h" + +/* like sprintf(3), but allocates memory for the result. */ +int +openpam_asprintf(char **str, const char *fmt, ...) +{ + va_list ap; + int ret; + + va_start(ap, fmt); + ret = vasprintf(str, fmt, ap); + va_end(ap); + return (ret); +} + +#endif diff --git a/contrib/openpam/lib/libpam/openpam_asprintf.h b/contrib/openpam/lib/libpam/openpam_asprintf.h new file mode 100644 index 000000000000..6d9e4e39826b --- /dev/null +++ b/contrib/openpam/lib/libpam/openpam_asprintf.h @@ -0,0 +1,41 @@ +/*- + * Copyright (c) 2012 Dag-Erling Smørgrav + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote + * products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $Id: openpam_asprintf.h 648 2013-03-05 17:54:27Z des $ + */ + +#ifndef OPENPAM_ASPRINTF_H_INCLUDED +#define OPENPAM_ASPRINTF_H_INCLUDED + +#ifndef HAVE_ASPRINTF +int openpam_asprintf(char **, const char *, ...); +#undef asprintf +#define asprintf(arg, ...) openpam_asprintf(arg, __VA_ARGS__) +#endif + +#endif diff --git a/contrib/openpam/lib/openpam_borrow_cred.c b/contrib/openpam/lib/libpam/openpam_borrow_cred.c similarity index 95% rename from contrib/openpam/lib/openpam_borrow_cred.c rename to contrib/openpam/lib/libpam/openpam_borrow_cred.c index e0dfc555758f..1b407bdfd27b 100644 --- a/contrib/openpam/lib/openpam_borrow_cred.c +++ b/contrib/openpam/lib/libpam/openpam_borrow_cred.c @@ -32,7 +32,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: openpam_borrow_cred.c 437 2011-09-13 12:00:13Z des $ + * $Id: openpam_borrow_cred.c 649 2013-03-05 17:58:33Z des $ */ #ifdef HAVE_CONFIG_H @@ -50,6 +50,7 @@ #include #include "openpam_impl.h" +#include "openpam_cred.h" /* * OpenPAM extension @@ -68,12 +69,12 @@ openpam_borrow_cred(pam_handle_t *pamh, ENTERI(pwd->pw_uid); r = pam_get_data(pamh, PAM_SAVED_CRED, &scredp); if (r == PAM_SUCCESS && scredp != NULL) { - openpam_log(PAM_LOG_DEBUG, + openpam_log(PAM_LOG_LIBDEBUG, "already operating under borrowed credentials"); RETURNC(PAM_SYSTEM_ERR); } if (geteuid() != 0 && geteuid() != pwd->pw_uid) { - openpam_log(PAM_LOG_DEBUG, "called with non-zero euid: %d", + openpam_log(PAM_LOG_LIBDEBUG, "called with non-zero euid: %d", (int)geteuid()); RETURNC(PAM_PERM_DENIED); } diff --git a/contrib/openpam/lib/openpam_check_owner_perms.c b/contrib/openpam/lib/libpam/openpam_check_owner_perms.c similarity index 97% rename from contrib/openpam/lib/openpam_check_owner_perms.c rename to contrib/openpam/lib/libpam/openpam_check_owner_perms.c index d3b2ca98596b..c8a598a9d448 100644 --- a/contrib/openpam/lib/openpam_check_owner_perms.c +++ b/contrib/openpam/lib/libpam/openpam_check_owner_perms.c @@ -6,8 +6,7 @@ * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer - * in this position and unchanged. + * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. @@ -27,7 +26,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: openpam_check_owner_perms.c 543 2012-03-31 22:11:34Z des $ + * $Id: openpam_check_owner_perms.c 648 2013-03-05 17:54:27Z des $ */ #ifdef HAVE_CONFIG_H diff --git a/contrib/openpam/lib/openpam_configure.c b/contrib/openpam/lib/libpam/openpam_configure.c similarity index 98% rename from contrib/openpam/lib/openpam_configure.c rename to contrib/openpam/lib/libpam/openpam_configure.c index 8172a6fdf11c..1a43dc799da1 100644 --- a/contrib/openpam/lib/openpam_configure.c +++ b/contrib/openpam/lib/libpam/openpam_configure.c @@ -32,7 +32,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: openpam_configure.c 612 2012-05-26 23:02:55Z des $ + * $Id: openpam_configure.c 667 2013-03-17 14:24:00Z des $ */ #ifdef HAVE_CONFIG_H @@ -41,7 +41,6 @@ #include -#include #include #include #include @@ -308,14 +307,6 @@ openpam_parse_chain(pam_handle_t *pamh, return (-1); } -static const char *openpam_policy_path[] = { - "/etc/pam.d/", - "/etc/pam.conf", - "/usr/local/etc/pam.d/", - "/usr/local/etc/pam.conf", - NULL -}; - /* * Read the specified chains from the specified file. * diff --git a/contrib/openpam/lib/openpam_constants.c b/contrib/openpam/lib/libpam/openpam_constants.c similarity index 91% rename from contrib/openpam/lib/openpam_constants.c rename to contrib/openpam/lib/libpam/openpam_constants.c index 833e81f28020..1cdd8101a88a 100644 --- a/contrib/openpam/lib/openpam_constants.c +++ b/contrib/openpam/lib/libpam/openpam_constants.c @@ -32,7 +32,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: openpam_constants.c 491 2011-11-12 00:12:32Z des $ + * $Id: openpam_constants.c 690 2013-08-15 13:22:51Z des $ */ #ifdef HAVE_CONFIG_H @@ -125,3 +125,21 @@ const char *pam_sm_func_name[PAM_NUM_PRIMITIVES] = { "pam_sm_close_session", "pam_sm_chauthtok" }; + +const char *openpam_policy_path[] = { + "/etc/pam.d/", + "/etc/pam.conf", + "/usr/local/etc/pam.d/", + "/usr/local/etc/pam.conf", + NULL +}; + +const char *openpam_module_path[] = { +#ifdef OPENPAM_MODULES_DIRECTORY + OPENPAM_MODULES_DIRECTORY, +#else + "/usr/lib", + "/usr/local/lib", +#endif + NULL +}; diff --git a/contrib/openpam/lib/openpam_constants.h b/contrib/openpam/lib/libpam/openpam_constants.h similarity index 92% rename from contrib/openpam/lib/openpam_constants.h rename to contrib/openpam/lib/libpam/openpam_constants.h index a7d6ce8dd7d7..a42b4fa76f5b 100644 --- a/contrib/openpam/lib/openpam_constants.h +++ b/contrib/openpam/lib/libpam/openpam_constants.h @@ -6,8 +6,7 @@ * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer - * in this position and unchanged. + * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. @@ -27,7 +26,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: openpam_constants.h 606 2012-04-20 11:06:38Z des $ + * $Id: openpam_constants.h 659 2013-03-11 14:10:13Z des $ */ #ifndef OPENPAM_CONSTANTS_H_INCLUDED @@ -40,4 +39,7 @@ extern const char *pam_control_flag_name[PAM_NUM_CONTROL_FLAGS]; extern const char *pam_func_name[PAM_NUM_PRIMITIVES]; extern const char *pam_sm_func_name[PAM_NUM_PRIMITIVES]; +extern const char *openpam_policy_path[]; +extern const char *openpam_module_path[]; + #endif diff --git a/contrib/openpam/lib/libpam/openpam_cred.h b/contrib/openpam/lib/libpam/openpam_cred.h new file mode 100644 index 000000000000..68e2fd9d1c09 --- /dev/null +++ b/contrib/openpam/lib/libpam/openpam_cred.h @@ -0,0 +1,52 @@ +/*- + * Copyright (c) 2001-2003 Networks Associates Technology, Inc. + * Copyright (c) 2004-2011 Dag-Erling Smørgrav + * All rights reserved. + * + * This software was developed for the FreeBSD Project by ThinkSec AS and + * Network Associates Laboratories, the Security Research Division of + * Network Associates, Inc. under DARPA/SPAWAR contract N66001-01-C-8035 + * ("CBOSS"), as part of the DARPA CHATS research program. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote + * products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $Id: openpam_cred.h 648 2013-03-05 17:54:27Z des $ + */ + +#ifndef OPENPAM_CRED_H_INCLUDED +#define OPENPAM_CRED_H_INCLUDED + +/* + * Saved credentials + */ +#define PAM_SAVED_CRED "pam_saved_cred" +struct pam_saved_cred { + uid_t euid; + gid_t egid; + gid_t groups[NGROUPS_MAX]; + int ngroups; +}; + +#endif diff --git a/contrib/openpam/lib/openpam_ctype.h b/contrib/openpam/lib/libpam/openpam_ctype.h similarity index 80% rename from contrib/openpam/lib/openpam_ctype.h rename to contrib/openpam/lib/libpam/openpam_ctype.h index b3ec84689970..4f5888d09024 100644 --- a/contrib/openpam/lib/openpam_ctype.h +++ b/contrib/openpam/lib/libpam/openpam_ctype.h @@ -6,8 +6,7 @@ * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer - * in this position and unchanged. + * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. @@ -27,12 +26,36 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: openpam_ctype.h 578 2012-04-06 00:45:59Z des $ + * $Id: openpam_ctype.h 666 2013-03-17 14:22:17Z des $ */ #ifndef OPENPAM_CTYPE_H_INCLUDED #define OPENPAM_CTYPE_H_INCLUDED +/* + * Evaluates to non-zero if the argument is a digit. + */ +#define is_digit(ch) \ + (ch >= '0' && ch <= '9') + +/* + * Evaluates to non-zero if the argument is an uppercase letter. + */ +#define is_upper(ch) \ + (ch >= 'A' && ch <= 'A') + +/* + * Evaluates to non-zero if the argument is a lowercase letter. + */ +#define is_lower(ch) \ + (ch >= 'a' && ch <= 'z') + +/* + * Evaluates to non-zero if the argument is a letter. + */ +#define is_letter(ch) \ + (is_upper(ch) || is_lower(ch)) + /* * Evaluates to non-zero if the argument is a linear whitespace character. * For the purposes of this macro, the definition of linear whitespace is @@ -60,9 +83,7 @@ * of ASCII. */ #define is_pfcs(ch) \ - ((ch >= '0' && ch <= '9') || \ - (ch >= 'A' && ch <= 'Z') || \ - (ch >= 'a' && ch <= 'z') || \ + (is_digit(ch) || is_letter(ch) || \ ch == '.' || ch == '_' || ch == '-') #endif diff --git a/contrib/openpam/lib/openpam_debug.h b/contrib/openpam/lib/libpam/openpam_debug.h similarity index 98% rename from contrib/openpam/lib/openpam_debug.h rename to contrib/openpam/lib/libpam/openpam_debug.h index 050783e49369..1fe8346cca8c 100644 --- a/contrib/openpam/lib/openpam_debug.h +++ b/contrib/openpam/lib/libpam/openpam_debug.h @@ -32,7 +32,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: openpam_debug.h 606 2012-04-20 11:06:38Z des $ + * $Id: openpam_debug.h 648 2013-03-05 17:54:27Z des $ */ #ifndef OPENPAM_DEBUG_H_INCLUDED diff --git a/contrib/openpam/lib/openpam_dispatch.c b/contrib/openpam/lib/libpam/openpam_dispatch.c similarity index 95% rename from contrib/openpam/lib/openpam_dispatch.c rename to contrib/openpam/lib/libpam/openpam_dispatch.c index 54dfd3bdc8f3..0dcc73223ce3 100644 --- a/contrib/openpam/lib/openpam_dispatch.c +++ b/contrib/openpam/lib/libpam/openpam_dispatch.c @@ -32,7 +32,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: openpam_dispatch.c 501 2011-12-07 01:28:05Z des $ + * $Id: openpam_dispatch.c 649 2013-03-05 17:58:33Z des $ */ #ifdef HAVE_CONFIG_H @@ -112,12 +112,12 @@ openpam_dispatch(pam_handle_t *pamh, debug = (openpam_get_option(pamh, "debug") != NULL); if (debug) ++openpam_debug; - openpam_log(PAM_LOG_DEBUG, "calling %s() in %s", + openpam_log(PAM_LOG_LIBDEBUG, "calling %s() in %s", pam_sm_func_name[primitive], chain->module->path); r = (chain->module->func[primitive])(pamh, flags, chain->optc, (const char **)chain->optv); pamh->current = NULL; - openpam_log(PAM_LOG_DEBUG, "%s: %s(): %s", + openpam_log(PAM_LOG_LIBDEBUG, "%s: %s(): %s", chain->module->path, pam_sm_func_name[primitive], pam_strerror(pamh, r)); if (debug) @@ -152,7 +152,7 @@ openpam_dispatch(pam_handle_t *pamh, err = r; if ((chain->flag == PAM_REQUIRED || chain->flag == PAM_BINDING) && !fail) { - openpam_log(PAM_LOG_DEBUG, "required module failed"); + openpam_log(PAM_LOG_LIBDEBUG, "required module failed"); fail = 1; err = r; } @@ -162,7 +162,7 @@ openpam_dispatch(pam_handle_t *pamh, * immediately. */ if (chain->flag == PAM_REQUISITE) { - openpam_log(PAM_LOG_DEBUG, "requisite module failed"); + openpam_log(PAM_LOG_LIBDEBUG, "requisite module failed"); fail = 1; break; } @@ -179,6 +179,7 @@ openpam_check_error_code(int primitive, int r) { /* common error codes */ if (r == PAM_SUCCESS || + r == PAM_SYSTEM_ERR || r == PAM_SERVICE_ERR || r == PAM_BUF_ERR || r == PAM_CONV_ERR || diff --git a/contrib/openpam/lib/libpam/openpam_dlfunc.h b/contrib/openpam/lib/libpam/openpam_dlfunc.h new file mode 100644 index 000000000000..a92ab9cd368d --- /dev/null +++ b/contrib/openpam/lib/libpam/openpam_dlfunc.h @@ -0,0 +1,43 @@ +/*- + * Copyright (c) 2013 Dag-Erling Smørgrav + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $Id: openpam_dlfunc.h 660 2013-03-11 15:08:52Z des $ + */ + +#ifndef OPENPAM_DLFCN_H_INCLUDED +#define OPENPAM_DLFCN_H_INCLUDED + +#ifndef HAVE_DLFUNC +typedef void (*dlfunc_t)(); + +static inline dlfunc_t +dlfunc(void *handle, const char *symbol) +{ + + return ((dlfunc_t)dlsym(handle, symbol)); +} +#endif + +#endif diff --git a/contrib/openpam/lib/openpam_dynamic.c b/contrib/openpam/lib/libpam/openpam_dynamic.c similarity index 53% rename from contrib/openpam/lib/openpam_dynamic.c rename to contrib/openpam/lib/libpam/openpam_dynamic.c index 1dfc1ac43eb8..27cd4e6776da 100644 --- a/contrib/openpam/lib/openpam_dynamic.c +++ b/contrib/openpam/lib/libpam/openpam_dynamic.c @@ -32,16 +32,18 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: openpam_dynamic.c 607 2012-04-20 11:09:37Z des $ + * $Id: openpam_dynamic.c 683 2013-04-14 14:49:59Z des $ */ #ifdef HAVE_CONFIG_H # include "config.h" #endif +#include + #include -#include #include +#include #include #include #include @@ -50,6 +52,9 @@ #include #include "openpam_impl.h" +#include "openpam_asprintf.h" +#include "openpam_ctype.h" +#include "openpam_dlfunc.h" #ifndef RTLD_NOW #define RTLD_NOW RTLD_LAZY @@ -68,8 +73,12 @@ try_dlopen(const char *modfn) void *dlh; int fd; - if ((fd = open(modfn, O_RDONLY)) < 0) + openpam_log(PAM_LOG_LIBDEBUG, "dlopen(%s)", modfn); + if ((fd = open(modfn, O_RDONLY)) < 0) { + if (errno != ENOENT) + openpam_log(PAM_LOG_ERROR, "%s: %m", modfn); return (NULL); + } if (OPENPAM_FEATURE(VERIFY_MODULE_FILE) && openpam_check_desc_owner_perms(modfn, fd) != 0) { close(fd); @@ -91,6 +100,7 @@ try_dlopen(const char *modfn) int check_module_file; void *dlh; + openpam_log(PAM_LOG_LIBDEBUG, "dlopen(%s)", modfn); openpam_get_feature(OPENPAM_VERIFY_MODULE_FILE, &check_module_file); if (check_module_file && @@ -106,80 +116,144 @@ try_dlopen(const char *modfn) #endif /* - * OpenPAM internal - * - * Locate a dynamically linked module + * Try to load a module from the suggested location. */ - -pam_module_t * -openpam_dynamic(const char *path) +static pam_module_t * +try_module(const char *modpath) { const pam_module_t *dlmodule; pam_module_t *module; - const char *prefix; - char *vpath; - void *dlh; int i, serrno; - dlh = NULL; - - /* Prepend the standard prefix if not an absolute pathname. */ - if (path[0] != '/') - prefix = OPENPAM_MODULES_DIR; - else - prefix = ""; - - /* try versioned module first, then unversioned module */ - if (asprintf(&vpath, "%s%s.%d", prefix, path, LIB_MAJ) < 0) + if ((module = calloc(1, sizeof *module)) == NULL || + (module->path = strdup(modpath)) == NULL || + (module->dlh = try_dlopen(modpath)) == NULL) goto err; - if ((dlh = try_dlopen(vpath)) == NULL && errno == ENOENT) { - *strrchr(vpath, '.') = '\0'; - dlh = try_dlopen(vpath); - } - if (dlh == NULL) - goto err; - if ((module = calloc(1, sizeof *module)) == NULL) - goto buf_err; - if ((module->path = strdup(path)) == NULL) - goto buf_err; - module->dlh = dlh; - dlmodule = dlsym(dlh, "_pam_module"); + dlmodule = dlsym(module->dlh, "_pam_module"); for (i = 0; i < PAM_NUM_PRIMITIVES; ++i) { if (dlmodule) { module->func[i] = dlmodule->func[i]; } else { - module->func[i] = - (pam_func_t)dlsym(dlh, pam_sm_func_name[i]); + module->func[i] = (pam_func_t)dlfunc(module->dlh, + pam_sm_func_name[i]); /* * This openpam_log() call is a major source of * log spam, and the cases that matter are caught * and logged in openpam_dispatch(). This would * be less problematic if dlerror() returned an * error code so we could log an error only when - * dlsym() failed for a reason other than "no such - * symbol". + * dlfunc() failed for a reason other than "no + * such symbol". */ #if 0 if (module->func[i] == NULL) - openpam_log(PAM_LOG_DEBUG, "%s: %s(): %s", - path, pam_sm_func_name[i], dlerror()); + openpam_log(PAM_LOG_LIBDEBUG, "%s: %s(): %s", + modpath, pam_sm_func_name[i], dlerror()); #endif } } - FREE(vpath); return (module); -buf_err: - serrno = errno; - if (dlh != NULL) - dlclose(dlh); - FREE(module); - errno = serrno; err: serrno = errno; - if (errno != 0) - openpam_log(PAM_LOG_ERROR, "%s: %m", vpath); - FREE(vpath); + if (module != NULL) { + if (module->dlh != NULL) + dlclose(module->dlh); + if (module->path != NULL) + FREE(module->path); + FREE(module); + } errno = serrno; + if (serrno != 0 && serrno != ENOENT) + openpam_log(PAM_LOG_ERROR, "%s: %m", modpath); + errno = serrno; + return (NULL); +} + +/* + * OpenPAM internal + * + * Locate a dynamically linked module + */ + +pam_module_t * +openpam_dynamic(const char *modname) +{ + pam_module_t *module; + char modpath[PATH_MAX]; + const char **path, *p; + int has_so, has_ver; + int dot, len; + + /* + * Simple case: module name contains path separator(s) + */ + if (strchr(modname, '/') != NULL) { + /* + * Absolute paths are not allowed if RESTRICT_MODULE_NAME + * is in effect (default off). Relative paths are never + * allowed. + */ + if (OPENPAM_FEATURE(RESTRICT_MODULE_NAME) || + modname[0] != '/') { + openpam_log(PAM_LOG_ERROR, + "invalid module name: %s", modname); + return (NULL); + } + return (try_module(modname)); + } + + /* + * Check for .so and version sufixes + */ + p = strchr(modname, '\0'); + has_ver = has_so = 0; + while (is_digit(*p)) + --p; + if (*p == '.' && *++p != '\0') { + /* found a numeric suffix */ + has_ver = 1; + /* assume that .so is either present or unneeded */ + has_so = 1; + } else if (*p == '\0' && p >= modname + sizeof PAM_SOEXT && + strcmp(p - sizeof PAM_SOEXT + 1, PAM_SOEXT) == 0) { + /* found .so suffix */ + has_so = 1; + } + + /* + * Complicated case: search for the module in the usual places. + */ + for (path = openpam_module_path; *path != NULL; ++path) { + /* + * Assemble the full path, including the version suffix. Take + * note of where the suffix begins so we can cut it off later. + */ + if (has_ver) + len = snprintf(modpath, sizeof modpath, "%s/%s%n", + *path, modname, &dot); + else if (has_so) + len = snprintf(modpath, sizeof modpath, "%s/%s%n.%d", + *path, modname, &dot, LIB_MAJ); + else + len = snprintf(modpath, sizeof modpath, "%s/%s%s%n.%d", + *path, modname, PAM_SOEXT, &dot, LIB_MAJ); + /* check for overflow */ + if (len < 0 || (unsigned int)len >= sizeof modpath) { + errno = ENOENT; + continue; + } + /* try the versioned path */ + if ((module = try_module(modpath)) != NULL) + return (module); + if (errno == ENOENT && modpath[dot] != '\0') { + /* no luck, try the unversioned path */ + modpath[dot] = '\0'; + if ((module = try_module(modpath)) != NULL) + return (module); + } + } + + /* :( */ return (NULL); } diff --git a/contrib/openpam/lib/openpam_features.c b/contrib/openpam/lib/libpam/openpam_features.c similarity index 95% rename from contrib/openpam/lib/openpam_features.c rename to contrib/openpam/lib/libpam/openpam_features.c index 586fc2a57305..8ca8828058be 100644 --- a/contrib/openpam/lib/openpam_features.c +++ b/contrib/openpam/lib/libpam/openpam_features.c @@ -6,8 +6,7 @@ * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer - * in this position and unchanged. + * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. @@ -27,7 +26,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: openpam_features.c 608 2012-05-17 16:00:13Z des $ + * $Id: openpam_features.c 648 2013-03-05 17:54:27Z des $ */ #ifdef HAVE_CONFIG_H diff --git a/contrib/openpam/lib/openpam_features.h b/contrib/openpam/lib/libpam/openpam_features.h similarity index 96% rename from contrib/openpam/lib/openpam_features.h rename to contrib/openpam/lib/libpam/openpam_features.h index 227b1a9f729c..00cac1c4b66f 100644 --- a/contrib/openpam/lib/openpam_features.h +++ b/contrib/openpam/lib/libpam/openpam_features.h @@ -6,8 +6,7 @@ * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer - * in this position and unchanged. + * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. @@ -27,7 +26,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id$ + * $Id: openpam_features.h 648 2013-03-05 17:54:27Z des $ */ #ifndef OPENPAM_FEATURES_H_INCLUDED diff --git a/contrib/openpam/lib/openpam_findenv.c b/contrib/openpam/lib/libpam/openpam_findenv.c similarity index 97% rename from contrib/openpam/lib/openpam_findenv.c rename to contrib/openpam/lib/libpam/openpam_findenv.c index b833ec9229c0..3512c3f3c96d 100644 --- a/contrib/openpam/lib/openpam_findenv.c +++ b/contrib/openpam/lib/libpam/openpam_findenv.c @@ -32,7 +32,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: openpam_findenv.c 437 2011-09-13 12:00:13Z des $ + * $Id: openpam_findenv.c 648 2013-03-05 17:54:27Z des $ */ #ifdef HAVE_CONFIG_H diff --git a/contrib/openpam/lib/openpam_free_data.c b/contrib/openpam/lib/libpam/openpam_free_data.c similarity index 97% rename from contrib/openpam/lib/openpam_free_data.c rename to contrib/openpam/lib/libpam/openpam_free_data.c index 561687c7ec2e..8f3d852b4905 100644 --- a/contrib/openpam/lib/openpam_free_data.c +++ b/contrib/openpam/lib/libpam/openpam_free_data.c @@ -32,7 +32,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: openpam_free_data.c 437 2011-09-13 12:00:13Z des $ + * $Id: openpam_free_data.c 648 2013-03-05 17:54:27Z des $ */ #ifdef HAVE_CONFIG_H diff --git a/contrib/openpam/lib/openpam_free_envlist.c b/contrib/openpam/lib/libpam/openpam_free_envlist.c similarity index 95% rename from contrib/openpam/lib/openpam_free_envlist.c rename to contrib/openpam/lib/libpam/openpam_free_envlist.c index 14754dc4031b..dda06153205b 100644 --- a/contrib/openpam/lib/openpam_free_envlist.c +++ b/contrib/openpam/lib/libpam/openpam_free_envlist.c @@ -6,8 +6,7 @@ * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer - * in this position and unchanged. + * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. @@ -25,7 +24,7 @@ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * - * $Id: openpam_free_envlist.c 447 2011-10-22 02:47:36Z des $ + * $Id: openpam_free_envlist.c 648 2013-03-05 17:54:27Z des $ */ #ifdef HAVE_CONFIG_H diff --git a/contrib/openpam/lib/openpam_get_feature.c b/contrib/openpam/lib/libpam/openpam_get_feature.c similarity index 96% rename from contrib/openpam/lib/openpam_get_feature.c rename to contrib/openpam/lib/libpam/openpam_get_feature.c index b552357c58d4..ad3d9b3ade0f 100644 --- a/contrib/openpam/lib/openpam_get_feature.c +++ b/contrib/openpam/lib/libpam/openpam_get_feature.c @@ -6,8 +6,7 @@ * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer - * in this position and unchanged. + * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. @@ -27,7 +26,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: openpam_get_feature.c 608 2012-05-17 16:00:13Z des $ + * $Id: openpam_get_feature.c 648 2013-03-05 17:54:27Z des $ */ #ifdef HAVE_CONFIG_H diff --git a/contrib/openpam/lib/openpam_get_option.c b/contrib/openpam/lib/libpam/openpam_get_option.c similarity index 97% rename from contrib/openpam/lib/openpam_get_option.c rename to contrib/openpam/lib/libpam/openpam_get_option.c index 1f62d218ebfc..2cf5e87f3f40 100644 --- a/contrib/openpam/lib/openpam_get_option.c +++ b/contrib/openpam/lib/libpam/openpam_get_option.c @@ -32,7 +32,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: openpam_get_option.c 531 2012-03-31 14:24:37Z des $ + * $Id: openpam_get_option.c 648 2013-03-05 17:54:27Z des $ */ #ifdef HAVE_CONFIG_H diff --git a/contrib/openpam/lib/openpam_impl.h b/contrib/openpam/lib/libpam/openpam_impl.h similarity index 94% rename from contrib/openpam/lib/openpam_impl.h rename to contrib/openpam/lib/libpam/openpam_impl.h index 9e8b45f6d55c..c533acb77572 100644 --- a/contrib/openpam/lib/openpam_impl.h +++ b/contrib/openpam/lib/libpam/openpam_impl.h @@ -32,7 +32,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: openpam_impl.h 594 2012-04-14 14:18:41Z des $ + * $Id: openpam_impl.h 648 2013-03-05 17:54:27Z des $ */ #ifndef OPENPAM_IMPL_H_INCLUDED @@ -122,19 +122,6 @@ struct pam_handle { int env_size; }; -#ifdef NGROUPS_MAX -/* - * Saved credentials - */ -#define PAM_SAVED_CRED "pam_saved_cred" -struct pam_saved_cred { - uid_t euid; - gid_t egid; - gid_t groups[NGROUPS_MAX]; - int ngroups; -}; -#endif - /* * Default policy */ diff --git a/contrib/openpam/lib/openpam_load.c b/contrib/openpam/lib/libpam/openpam_load.c similarity index 89% rename from contrib/openpam/lib/openpam_load.c rename to contrib/openpam/lib/libpam/openpam_load.c index 871d1a8c057c..a926dbd1288e 100644 --- a/contrib/openpam/lib/openpam_load.c +++ b/contrib/openpam/lib/libpam/openpam_load.c @@ -32,7 +32,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: openpam_load.c 547 2012-04-01 15:01:21Z des $ + * $Id: openpam_load.c 664 2013-03-17 10:56:15Z des $ */ #ifdef HAVE_CONFIG_H @@ -52,24 +52,24 @@ */ pam_module_t * -openpam_load_module(const char *path) +openpam_load_module(const char *modulename) { pam_module_t *module; - module = openpam_dynamic(path); + module = openpam_dynamic(modulename); openpam_log(PAM_LOG_DEBUG, "%s dynamic %s", - (module == NULL) ? "no" : "using", path); + (module == NULL) ? "no" : "using", modulename); #ifdef OPENPAM_STATIC_MODULES /* look for a static module */ - if (module == NULL && strchr(path, '/') == NULL) { - module = openpam_static(path); + if (module == NULL && strchr(modulename, '/') == NULL) { + module = openpam_static(modulename); openpam_log(PAM_LOG_DEBUG, "%s static %s", - (module == NULL) ? "no" : "using", path); + (module == NULL) ? "no" : "using", modulename); } #endif if (module == NULL) { - openpam_log(PAM_LOG_ERROR, "no %s found", path); + openpam_log(PAM_LOG_ERROR, "no %s found", modulename); return (NULL); } return (module); diff --git a/contrib/openpam/lib/openpam_log.c b/contrib/openpam/lib/libpam/openpam_log.c similarity index 95% rename from contrib/openpam/lib/openpam_log.c rename to contrib/openpam/lib/libpam/openpam_log.c index 39c277038c49..e52ca95b210c 100644 --- a/contrib/openpam/lib/openpam_log.c +++ b/contrib/openpam/lib/libpam/openpam_log.c @@ -32,7 +32,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: openpam_log.c 544 2012-03-31 22:47:15Z des $ + * $Id: openpam_log.c 686 2013-07-11 16:36:02Z des $ */ #ifdef HAVE_CONFIG_H @@ -48,6 +48,7 @@ #include #include "openpam_impl.h" +#include "openpam_asprintf.h" int openpam_debug = 0; @@ -64,6 +65,7 @@ openpam_log(int level, const char *fmt, ...) { va_list ap; int priority; + int serrno; switch (level) { case PAM_LOG_LIBDEBUG: @@ -83,9 +85,11 @@ openpam_log(int level, const char *fmt, ...) priority = LOG_ERR; break; } + serrno = errno; va_start(ap, fmt); vsyslog(priority, fmt, ap); va_end(ap); + errno = serrno; } #else @@ -116,8 +120,8 @@ _openpam_log(int level, const char *func, const char *fmt, ...) priority = LOG_ERR; break; } - va_start(ap, fmt); serrno = errno; + va_start(ap, fmt); if (asprintf(&format, "in %s(): %s", func, fmt) > 0) { errno = serrno; vsyslog(priority, format, ap); @@ -127,6 +131,7 @@ _openpam_log(int level, const char *func, const char *fmt, ...) vsyslog(priority, fmt, ap); } va_end(ap); + errno = serrno; } #endif @@ -163,4 +168,6 @@ _openpam_log(int level, const char *func, const char *fmt, ...) * * The remaining arguments are a =printf format string and the * corresponding arguments. + * + * The =openpam_log function does not modify the value of :errno. */ diff --git a/contrib/openpam/lib/openpam_nullconv.c b/contrib/openpam/lib/libpam/openpam_nullconv.c similarity index 98% rename from contrib/openpam/lib/openpam_nullconv.c rename to contrib/openpam/lib/libpam/openpam_nullconv.c index a95b1e0c50f8..49c71ba22d82 100644 --- a/contrib/openpam/lib/openpam_nullconv.c +++ b/contrib/openpam/lib/libpam/openpam_nullconv.c @@ -32,7 +32,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: openpam_nullconv.c 437 2011-09-13 12:00:13Z des $ + * $Id: openpam_nullconv.c 648 2013-03-05 17:54:27Z des $ */ #ifdef HAVE_CONFIG_H diff --git a/contrib/openpam/lib/openpam_readline.c b/contrib/openpam/lib/libpam/openpam_readline.c similarity index 96% rename from contrib/openpam/lib/openpam_readline.c rename to contrib/openpam/lib/libpam/openpam_readline.c index 047ab836910a..e3ed9b0a4f01 100644 --- a/contrib/openpam/lib/openpam_readline.c +++ b/contrib/openpam/lib/libpam/openpam_readline.c @@ -32,14 +32,13 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: openpam_readline.c 596 2012-04-14 14:52:40Z des $ + * $Id: openpam_readline.c 703 2013-08-16 11:57:54Z des $ */ #ifdef HAVE_CONFIG_H # include "config.h" #endif -#include #include #include @@ -101,7 +100,6 @@ openpam_readline(FILE *f, int *lineno, size_t *lenp) goto fail; if (lenp != NULL) *lenp = len; - openpam_log(PAM_LOG_LIBDEBUG, "returning '%s'", line); return (line); fail: FREE(line); diff --git a/contrib/openpam/lib/openpam_readlinev.c b/contrib/openpam/lib/libpam/openpam_readlinev.c similarity index 98% rename from contrib/openpam/lib/openpam_readlinev.c rename to contrib/openpam/lib/libpam/openpam_readlinev.c index 5a43b61f36f2..5edc368fd356 100644 --- a/contrib/openpam/lib/openpam_readlinev.c +++ b/contrib/openpam/lib/libpam/openpam_readlinev.c @@ -6,8 +6,7 @@ * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer - * in this position and unchanged. + * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. @@ -27,7 +26,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: openpam_readlinev.c 588 2012-04-08 11:52:25Z des $ + * $Id: openpam_readlinev.c 648 2013-03-05 17:54:27Z des $ */ #ifdef HAVE_CONFIG_H diff --git a/contrib/openpam/lib/openpam_readword.c b/contrib/openpam/lib/libpam/openpam_readword.c similarity index 98% rename from contrib/openpam/lib/openpam_readword.c rename to contrib/openpam/lib/libpam/openpam_readword.c index 1c0e9b68149c..5a4330c6c75d 100644 --- a/contrib/openpam/lib/openpam_readword.c +++ b/contrib/openpam/lib/libpam/openpam_readword.c @@ -6,8 +6,7 @@ * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer - * in this position and unchanged. + * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. @@ -27,7 +26,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: openpam_readword.c 588 2012-04-08 11:52:25Z des $ + * $Id: openpam_readword.c 648 2013-03-05 17:54:27Z des $ */ #ifdef HAVE_CONFIG_H diff --git a/contrib/openpam/lib/openpam_restore_cred.c b/contrib/openpam/lib/libpam/openpam_restore_cred.c similarity index 97% rename from contrib/openpam/lib/openpam_restore_cred.c rename to contrib/openpam/lib/libpam/openpam_restore_cred.c index 41d44d024d5c..8a150cc604e8 100644 --- a/contrib/openpam/lib/openpam_restore_cred.c +++ b/contrib/openpam/lib/libpam/openpam_restore_cred.c @@ -32,7 +32,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: openpam_restore_cred.c 437 2011-09-13 12:00:13Z des $ + * $Id: openpam_restore_cred.c 648 2013-03-05 17:54:27Z des $ */ #ifdef HAVE_CONFIG_H @@ -50,6 +50,7 @@ #include #include "openpam_impl.h" +#include "openpam_cred.h" /* * OpenPAM extension diff --git a/contrib/openpam/lib/openpam_set_feature.c b/contrib/openpam/lib/libpam/openpam_set_feature.c similarity index 95% rename from contrib/openpam/lib/openpam_set_feature.c rename to contrib/openpam/lib/libpam/openpam_set_feature.c index 4f6a4a5c92c7..8e95f3eb057d 100644 --- a/contrib/openpam/lib/openpam_set_feature.c +++ b/contrib/openpam/lib/libpam/openpam_set_feature.c @@ -6,8 +6,7 @@ * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer - * in this position and unchanged. + * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. @@ -27,7 +26,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: openpam_set_feature.c 608 2012-05-17 16:00:13Z des $ + * $Id: openpam_set_feature.c 648 2013-03-05 17:54:27Z des $ */ #ifdef HAVE_CONFIG_H diff --git a/contrib/openpam/lib/openpam_set_option.c b/contrib/openpam/lib/libpam/openpam_set_option.c similarity index 97% rename from contrib/openpam/lib/openpam_set_option.c rename to contrib/openpam/lib/libpam/openpam_set_option.c index 1712a718ec4c..1c06d61d3cc9 100644 --- a/contrib/openpam/lib/openpam_set_option.c +++ b/contrib/openpam/lib/libpam/openpam_set_option.c @@ -32,7 +32,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: openpam_set_option.c 532 2012-03-31 14:24:53Z des $ + * $Id: openpam_set_option.c 648 2013-03-05 17:54:27Z des $ */ #ifdef HAVE_CONFIG_H @@ -48,6 +48,7 @@ #include #include "openpam_impl.h" +#include "openpam_asprintf.h" /* * OpenPAM extension diff --git a/contrib/openpam/lib/openpam_static.c b/contrib/openpam/lib/libpam/openpam_static.c similarity index 97% rename from contrib/openpam/lib/openpam_static.c rename to contrib/openpam/lib/libpam/openpam_static.c index 40b807cb3698..302b3f4c4a86 100644 --- a/contrib/openpam/lib/openpam_static.c +++ b/contrib/openpam/lib/libpam/openpam_static.c @@ -32,7 +32,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: openpam_static.c 437 2011-09-13 12:00:13Z des $ + * $Id: openpam_static.c 648 2013-03-05 17:54:27Z des $ */ #ifdef HAVE_CONFIG_H diff --git a/contrib/openpam/lib/openpam_straddch.c b/contrib/openpam/lib/libpam/openpam_straddch.c similarity index 88% rename from contrib/openpam/lib/openpam_straddch.c rename to contrib/openpam/lib/libpam/openpam_straddch.c index 9845cc610a93..522405c0e23b 100644 --- a/contrib/openpam/lib/openpam_straddch.c +++ b/contrib/openpam/lib/libpam/openpam_straddch.c @@ -6,8 +6,7 @@ * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer - * in this position and unchanged. + * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. @@ -27,7 +26,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: openpam_straddch.c 568 2012-04-05 14:35:53Z des $ + * $Id: openpam_straddch.c 648 2013-03-05 17:54:27Z des $ */ #ifdef HAVE_CONFIG_H @@ -66,7 +65,7 @@ openpam_straddch(char **str, size_t *size, size_t *len, int ch) *str = tmpstr; *size = tmpsize; *len = 0; - } else if (*len + 1 >= *size) { + } else if (ch != 0 && *len + 1 >= *size) { /* additional space required */ tmpsize = *size * 2; if ((tmpstr = realloc(*str, tmpsize)) == NULL) { @@ -77,8 +76,10 @@ openpam_straddch(char **str, size_t *size, size_t *len, int ch) *size = tmpsize; *str = tmpstr; } - (*str)[*len] = ch; - ++*len; + if (ch != 0) { + (*str)[*len] = ch; + ++*len; + } (*str)[*len] = '\0'; return (0); } @@ -95,6 +96,11 @@ openpam_straddch(char **str, size_t *size, size_t *len, int ch) * The =size and =len argument point to variables used to hold the size * of the buffer and the length of the string it contains, respectively. * + * The final argument, =ch, is the character that should be appended to + * the string. If =ch is 0, nothing is appended, but a new buffer is + * still allocated if =str is NULL. This can be used to "bootstrap" the + * string. + * * If a new buffer is allocated or an existing buffer is reallocated to * make room for the additional character, =str and =size are updated * accordingly. @@ -103,7 +109,7 @@ openpam_straddch(char **str, size_t *size, size_t *len, int ch) * NUL-terminated. * * If the =openpam_straddch function is successful, it increments the - * integer variable pointed to by =len and returns 0. + * integer variable pointed to by =len (unless =ch was 0) and returns 0. * Otherwise, it leaves the variables pointed to by =str, =size and =len * unmodified, sets :errno to =ENOMEM and returns -1. * diff --git a/contrib/openpam/lib/libpam/openpam_strlcat.c b/contrib/openpam/lib/libpam/openpam_strlcat.c new file mode 100644 index 000000000000..64ba9ab00986 --- /dev/null +++ b/contrib/openpam/lib/libpam/openpam_strlcat.c @@ -0,0 +1,58 @@ +/*- + * Copyright (c) 2011-2012 Dag-Erling Smørgrav + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote + * products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $Id: openpam_strlcat.c 648 2013-03-05 17:54:27Z des $ + */ + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#ifndef HAVE_STRLCAT + +#include + +#include "openpam_strlcat.h" + +/* like strcat(3), but always NUL-terminates; returns strlen(src) */ +size_t +openpam_strlcat(char *dst, const char *src, size_t size) +{ + size_t len; + + for (len = 0; *dst && size > 1; ++len, --size) + dst++; + for (; *src && size > 1; ++len, --size) + *dst++ = *src++; + *dst = '\0'; + while (*src) + ++len, ++src; + return (len); +} + +#endif diff --git a/contrib/openpam/lib/openpam_strlcat.h b/contrib/openpam/lib/libpam/openpam_strlcat.h similarity index 79% rename from contrib/openpam/lib/openpam_strlcat.h rename to contrib/openpam/lib/libpam/openpam_strlcat.h index 1f266936be43..d09934687970 100644 --- a/contrib/openpam/lib/openpam_strlcat.h +++ b/contrib/openpam/lib/libpam/openpam_strlcat.h @@ -6,8 +6,7 @@ * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer - * in this position and unchanged. + * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. @@ -27,28 +26,16 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: openpam_strlcat.h 578 2012-04-06 00:45:59Z des $ + * $Id: openpam_strlcat.h 648 2013-03-05 17:54:27Z des $ */ #ifndef OPENPAM_STRLCAT_H_INCLUDED #define OPENPAM_STRLCAT_H_INCLUDED #ifndef HAVE_STRLCAT -/* like strcat(3), but always NUL-terminates; returns strlen(src) */ -static size_t -strlcat(char *dst, const char *src, size_t size) -{ - size_t len; - - for (len = 0; *dst && size > 1; ++len, --size) - dst++; - for (; *src && size > 1; ++len, --size) - *dst++ = *src++; - *dst = '\0'; - while (*src) - ++len, ++src; - return (len); -} +size_t openpam_strlcat(char *, const char *, size_t); +#undef strlcat +#define strlcat(arg, ...) openpam_strlcat(arg, __VA_ARGS__) #endif #endif diff --git a/contrib/openpam/lib/openpam_strlcmp.h b/contrib/openpam/lib/libpam/openpam_strlcmp.h similarity index 95% rename from contrib/openpam/lib/openpam_strlcmp.h rename to contrib/openpam/lib/libpam/openpam_strlcmp.h index 2a78e0f67666..d00383870e2c 100644 --- a/contrib/openpam/lib/openpam_strlcmp.h +++ b/contrib/openpam/lib/libpam/openpam_strlcmp.h @@ -6,8 +6,7 @@ * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer - * in this position and unchanged. + * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. @@ -27,7 +26,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: openpam_strlcmp.h 578 2012-04-06 00:45:59Z des $ + * $Id: openpam_strlcmp.h 648 2013-03-05 17:54:27Z des $ */ #ifndef OPENPAM_STRLCMP_H_INCLUDED diff --git a/contrib/openpam/lib/libpam/openpam_strlcpy.c b/contrib/openpam/lib/libpam/openpam_strlcpy.c new file mode 100644 index 000000000000..7a3d142bbcd1 --- /dev/null +++ b/contrib/openpam/lib/libpam/openpam_strlcpy.c @@ -0,0 +1,56 @@ +/*- + * Copyright (c) 2011-2012 Dag-Erling Smørgrav + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote + * products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $Id: openpam_strlcpy.c 648 2013-03-05 17:54:27Z des $ + */ + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#ifndef HAVE_STRLCPY + +#include + +#include "openpam_strlcpy.h" + +/* like strcpy(3), but always NUL-terminates; returns strlen(src) */ +size_t +openpam_strlcpy(char *dst, const char *src, size_t size) +{ + size_t len; + + for (len = 0; *src && size > 1; ++len, --size) + *dst++ = *src++; + *dst = '\0'; + while (*src) + ++len, ++src; + return (len); +} + +#endif diff --git a/contrib/openpam/lib/openpam_strlcpy.h b/contrib/openpam/lib/libpam/openpam_strlcpy.h similarity index 81% rename from contrib/openpam/lib/openpam_strlcpy.h rename to contrib/openpam/lib/libpam/openpam_strlcpy.h index 9c6554834830..8260c5627e0d 100644 --- a/contrib/openpam/lib/openpam_strlcpy.h +++ b/contrib/openpam/lib/libpam/openpam_strlcpy.h @@ -6,8 +6,7 @@ * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer - * in this position and unchanged. + * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. @@ -27,26 +26,16 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: openpam_strlcpy.h 578 2012-04-06 00:45:59Z des $ + * $Id: openpam_strlcpy.h 648 2013-03-05 17:54:27Z des $ */ #ifndef OPENPAM_STRLCPY_H_INCLUDED #define OPENPAM_STRLCPY_H_INCLUDED #ifndef HAVE_STRLCPY -/* like strcpy(3), but always NUL-terminates; returns strlen(src) */ -static size_t -strlcpy(char *dst, const char *src, size_t size) -{ - size_t len; - - for (len = 0; *src && size > 1; ++len, --size) - *dst++ = *src++; - *dst = '\0'; - while (*src) - ++len, ++src; - return (len); -} +size_t openpam_strlcpy(char *, const char *, size_t); +#undef strlcpy +#define strlcpy(arg, ...) openpam_strlcpy(arg, __VA_ARGS__) #endif #endif diff --git a/contrib/openpam/lib/openpam_subst.c b/contrib/openpam/lib/libpam/openpam_subst.c similarity index 97% rename from contrib/openpam/lib/openpam_subst.c rename to contrib/openpam/lib/libpam/openpam_subst.c index bab7a785faa9..1a4973477dfb 100644 --- a/contrib/openpam/lib/openpam_subst.c +++ b/contrib/openpam/lib/libpam/openpam_subst.c @@ -6,8 +6,7 @@ * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer - * in this position and unchanged. + * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. @@ -27,7 +26,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: openpam_subst.c 543 2012-03-31 22:11:34Z des $ + * $Id: openpam_subst.c 648 2013-03-05 17:54:27Z des $ */ #ifdef HAVE_CONFIG_H diff --git a/contrib/openpam/lib/libpam/openpam_ttyconv.c b/contrib/openpam/lib/libpam/openpam_ttyconv.c new file mode 100644 index 000000000000..01e61810ccff --- /dev/null +++ b/contrib/openpam/lib/libpam/openpam_ttyconv.c @@ -0,0 +1,401 @@ +/*- + * Copyright (c) 2002-2003 Networks Associates Technology, Inc. + * Copyright (c) 2004-2011 Dag-Erling Smørgrav + * All rights reserved. + * + * This software was developed for the FreeBSD Project by ThinkSec AS and + * Network Associates Laboratories, the Security Research Division of + * Network Associates, Inc. under DARPA/SPAWAR contract N66001-01-C-8035 + * ("CBOSS"), as part of the DARPA CHATS research program. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote + * products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $Id: openpam_ttyconv.c 688 2013-07-11 16:40:08Z des $ + */ + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "openpam_impl.h" + +int openpam_ttyconv_timeout = 0; + +static volatile sig_atomic_t caught_signal; + +/* + * Handle incoming signals during tty conversation + */ +static void +catch_signal(int signo) +{ + + switch (signo) { + case SIGINT: + case SIGQUIT: + case SIGTERM: + caught_signal = signo; + break; + } +} + +/* + * Accept a response from the user on a tty + */ +static int +prompt_tty(int ifd, int ofd, const char *message, char *response, int echo) +{ + struct sigaction action; + struct sigaction saction_sigint, saction_sigquit, saction_sigterm; + struct termios tcattr; + struct timeval now, target, remaining; + int remaining_ms; + tcflag_t slflag; + struct pollfd pfd; + int serrno; + int pos, ret; + char ch; + + /* write prompt */ + if (write(ofd, message, strlen(message)) < 0) { + openpam_log(PAM_LOG_ERROR, "write(): %m"); + return (-1); + } + + /* turn echo off if requested */ + slflag = 0; /* prevent bogus uninitialized variable warning */ + if (!echo) { + if (tcgetattr(ifd, &tcattr) != 0) { + openpam_log(PAM_LOG_ERROR, "tcgetattr(): %m"); + return (-1); + } + slflag = tcattr.c_lflag; + tcattr.c_lflag &= ~ECHO; + if (tcsetattr(ifd, TCSAFLUSH, &tcattr) != 0) { + openpam_log(PAM_LOG_ERROR, "tcsetattr(): %m"); + return (-1); + } + } + + /* install signal handlers */ + caught_signal = 0; + action.sa_handler = &catch_signal; + action.sa_flags = 0; + sigfillset(&action.sa_mask); + sigaction(SIGINT, &action, &saction_sigint); + sigaction(SIGQUIT, &action, &saction_sigquit); + sigaction(SIGTERM, &action, &saction_sigterm); + + /* compute timeout */ + if (openpam_ttyconv_timeout > 0) { + (void)gettimeofday(&now, NULL); + remaining.tv_sec = openpam_ttyconv_timeout; + remaining.tv_usec = 0; + timeradd(&now, &remaining, &target); + } else { + /* prevent bogus uninitialized variable warning */ + now.tv_sec = now.tv_usec = 0; + remaining.tv_sec = remaining.tv_usec = 0; + target.tv_sec = target.tv_usec = 0; + } + + /* input loop */ + pos = 0; + ret = -1; + serrno = 0; + while (!caught_signal) { + pfd.fd = ifd; + pfd.events = POLLIN; + pfd.revents = 0; + if (openpam_ttyconv_timeout > 0) { + gettimeofday(&now, NULL); + if (timercmp(&now, &target, >)) + break; + timersub(&target, &now, &remaining); + remaining_ms = remaining.tv_sec * 1000 + + remaining.tv_usec / 1000; + } else { + remaining_ms = -1; + } + if ((ret = poll(&pfd, 1, remaining_ms)) < 0) { + serrno = errno; + if (errno == EINTR) + continue; + openpam_log(PAM_LOG_ERROR, "poll(): %m"); + break; + } else if (ret == 0) { + /* timeout */ + write(ofd, " timed out", 10); + openpam_log(PAM_LOG_NOTICE, "timed out"); + break; + } + if ((ret = read(ifd, &ch, 1)) < 0) { + serrno = errno; + openpam_log(PAM_LOG_ERROR, "read(): %m"); + break; + } else if (ret == 0 || ch == '\n') { + response[pos] = '\0'; + ret = pos; + break; + } + if (pos + 1 < PAM_MAX_RESP_SIZE) + response[pos++] = ch; + /* overflow is discarded */ + } + + /* restore tty state */ + if (!echo) { + tcattr.c_lflag = slflag; + if (tcsetattr(ifd, 0, &tcattr) != 0) { + /* treat as non-fatal, since we have our answer */ + openpam_log(PAM_LOG_NOTICE, "tcsetattr(): %m"); + } + } + + /* restore signal handlers and re-post caught signal*/ + sigaction(SIGINT, &saction_sigint, NULL); + sigaction(SIGQUIT, &saction_sigquit, NULL); + sigaction(SIGTERM, &saction_sigterm, NULL); + if (caught_signal != 0) { + openpam_log(PAM_LOG_ERROR, "caught signal %d", + (int)caught_signal); + raise((int)caught_signal); + /* if raise() had no effect... */ + serrno = EINTR; + ret = -1; + } + + /* done */ + write(ofd, "\n", 1); + errno = serrno; + return (ret); +} + +/* + * Accept a response from the user on a non-tty stdin. + */ +static int +prompt_notty(const char *message, char *response) +{ + struct timeval now, target, remaining; + int remaining_ms; + struct pollfd pfd; + int ch, pos, ret; + + /* show prompt */ + fputs(message, stdout); + fflush(stdout); + + /* compute timeout */ + if (openpam_ttyconv_timeout > 0) { + (void)gettimeofday(&now, NULL); + remaining.tv_sec = openpam_ttyconv_timeout; + remaining.tv_usec = 0; + timeradd(&now, &remaining, &target); + } else { + /* prevent bogus uninitialized variable warning */ + now.tv_sec = now.tv_usec = 0; + remaining.tv_sec = remaining.tv_usec = 0; + target.tv_sec = target.tv_usec = 0; + } + + /* input loop */ + pos = 0; + for (;;) { + pfd.fd = STDIN_FILENO; + pfd.events = POLLIN; + pfd.revents = 0; + if (openpam_ttyconv_timeout > 0) { + gettimeofday(&now, NULL); + if (timercmp(&now, &target, >)) + break; + timersub(&target, &now, &remaining); + remaining_ms = remaining.tv_sec * 1000 + + remaining.tv_usec / 1000; + } else { + remaining_ms = -1; + } + if ((ret = poll(&pfd, 1, remaining_ms)) < 0) { + /* interrupt is ok, everything else -> bail */ + if (errno == EINTR) + continue; + perror("\nopenpam_ttyconv"); + return (-1); + } else if (ret == 0) { + /* timeout */ + break; + } else { + /* input */ + if ((ch = getchar()) == EOF && ferror(stdin)) { + perror("\nopenpam_ttyconv"); + return (-1); + } + if (ch == EOF || ch == '\n') { + response[pos] = '\0'; + return (pos); + } + if (pos + 1 < PAM_MAX_RESP_SIZE) + response[pos++] = ch; + /* overflow is discarded */ + } + } + fputs("\nopenpam_ttyconv: timeout\n", stderr); + return (-1); +} + +/* + * Determine whether stdin is a tty; if not, try to open the tty; in + * either case, call the appropriate method. + */ +static int +prompt(const char *message, char *response, int echo) +{ + int ifd, ofd, ret; + + if (isatty(STDIN_FILENO)) { + fflush(stdout); +#ifdef HAVE_FPURGE + fpurge(stdin); +#endif + ifd = STDIN_FILENO; + ofd = STDOUT_FILENO; + } else { + if ((ifd = open("/dev/tty", O_RDWR)) < 0) + /* no way to prevent echo */ + return (prompt_notty(message, response)); + ofd = ifd; + } + ret = prompt_tty(ifd, ofd, message, response, echo); + if (ifd != STDIN_FILENO) + close(ifd); + return (ret); +} + +/* + * OpenPAM extension + * + * Simple tty-based conversation function + */ + +int +openpam_ttyconv(int n, + const struct pam_message **msg, + struct pam_response **resp, + void *data) +{ + char respbuf[PAM_MAX_RESP_SIZE]; + struct pam_response *aresp; + int i; + + ENTER(); + (void)data; + if (n <= 0 || n > PAM_MAX_NUM_MSG) + RETURNC(PAM_CONV_ERR); + if ((aresp = calloc(n, sizeof *aresp)) == NULL) + RETURNC(PAM_BUF_ERR); + for (i = 0; i < n; ++i) { + aresp[i].resp_retcode = 0; + aresp[i].resp = NULL; + switch (msg[i]->msg_style) { + case PAM_PROMPT_ECHO_OFF: + if (prompt(msg[i]->msg, respbuf, 0) < 0 || + (aresp[i].resp = strdup(respbuf)) == NULL) + goto fail; + break; + case PAM_PROMPT_ECHO_ON: + if (prompt(msg[i]->msg, respbuf, 1) < 0 || + (aresp[i].resp = strdup(respbuf)) == NULL) + goto fail; + break; + case PAM_ERROR_MSG: + fputs(msg[i]->msg, stderr); + if (strlen(msg[i]->msg) > 0 && + msg[i]->msg[strlen(msg[i]->msg) - 1] != '\n') + fputc('\n', stderr); + break; + case PAM_TEXT_INFO: + fputs(msg[i]->msg, stdout); + if (strlen(msg[i]->msg) > 0 && + msg[i]->msg[strlen(msg[i]->msg) - 1] != '\n') + fputc('\n', stdout); + break; + default: + goto fail; + } + } + *resp = aresp; + memset(respbuf, 0, sizeof respbuf); + RETURNC(PAM_SUCCESS); +fail: + for (i = 0; i < n; ++i) { + if (aresp[i].resp != NULL) { + memset(aresp[i].resp, 0, strlen(aresp[i].resp)); + FREE(aresp[i].resp); + } + } + memset(aresp, 0, n * sizeof *aresp); + FREE(aresp); + *resp = NULL; + memset(respbuf, 0, sizeof respbuf); + RETURNC(PAM_CONV_ERR); +} + +/* + * Error codes: + * + * PAM_SYSTEM_ERR + * PAM_BUF_ERR + * PAM_CONV_ERR + */ + +/** + * The =openpam_ttyconv function is a standard conversation function + * suitable for use on TTY devices. + * It should be adequate for the needs of most text-based interactive + * programs. + * + * The =openpam_ttyconv function allows the application to specify a + * timeout for user input by setting the global integer variable + * :openpam_ttyconv_timeout to the length of the timeout in seconds. + * + * >openpam_nullconv + * >pam_prompt + * >pam_vprompt + */ diff --git a/contrib/openpam/lib/libpam/openpam_vasprintf.c b/contrib/openpam/lib/libpam/openpam_vasprintf.c new file mode 100644 index 000000000000..bedabf4fbd3d --- /dev/null +++ b/contrib/openpam/lib/libpam/openpam_vasprintf.c @@ -0,0 +1,60 @@ +/*- + * Copyright (c) 2011-2012 Dag-Erling Smørgrav + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote + * products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $Id: openpam_vasprintf.c 648 2013-03-05 17:54:27Z des $ + */ + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#ifndef HAVE_VASPRINTF + +#include +#include +#include + +#include "openpam_vasprintf.h" + +/* like vsprintf(3), but allocates memory for the result. */ +int +openpam_vasprintf(char **str, const char *fmt, va_list ap) +{ + va_list apcopy; + int len, ret; + + va_copy(apcopy, ap); + len = vsnprintf(NULL, 0, fmt, ap); + if ((*str = malloc(len + 1)) == NULL) + return (-1); + ret = vsnprintf(*str, len + 1, fmt, apcopy); + va_end(apcopy); + return (ret); +} + +#endif diff --git a/contrib/openpam/lib/libpam/openpam_vasprintf.h b/contrib/openpam/lib/libpam/openpam_vasprintf.h new file mode 100644 index 000000000000..e92ad0d2ce6f --- /dev/null +++ b/contrib/openpam/lib/libpam/openpam_vasprintf.h @@ -0,0 +1,41 @@ +/*- + * Copyright (c) 2012 Dag-Erling Smørgrav + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote + * products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $Id: openpam_vasprintf.h 648 2013-03-05 17:54:27Z des $ + */ + +#ifndef OPENPAM_VASPRINTF_H_INCLUDED +#define OPENPAM_VASPRINTF_H_INCLUDED + +#ifndef HAVE_VASPRINTF +int openpam_vasprintf(char **, const char *, va_list); +#undef vasprintf +#define vasprintf(arg, ...) openpam_vasprintf(arg, __VA_ARGS__) +#endif + +#endif diff --git a/contrib/openpam/lib/pam_acct_mgmt.c b/contrib/openpam/lib/libpam/pam_acct_mgmt.c similarity index 98% rename from contrib/openpam/lib/pam_acct_mgmt.c rename to contrib/openpam/lib/libpam/pam_acct_mgmt.c index 49c34ab3ea65..87337a80ae6f 100644 --- a/contrib/openpam/lib/pam_acct_mgmt.c +++ b/contrib/openpam/lib/libpam/pam_acct_mgmt.c @@ -32,7 +32,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: pam_acct_mgmt.c 437 2011-09-13 12:00:13Z des $ + * $Id: pam_acct_mgmt.c 648 2013-03-05 17:54:27Z des $ */ #ifdef HAVE_CONFIG_H diff --git a/contrib/openpam/lib/pam_authenticate.c b/contrib/openpam/lib/libpam/pam_authenticate.c similarity index 98% rename from contrib/openpam/lib/pam_authenticate.c rename to contrib/openpam/lib/libpam/pam_authenticate.c index fc6c20f394dc..b24e39685d7e 100644 --- a/contrib/openpam/lib/pam_authenticate.c +++ b/contrib/openpam/lib/libpam/pam_authenticate.c @@ -32,7 +32,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: pam_authenticate.c 437 2011-09-13 12:00:13Z des $ + * $Id: pam_authenticate.c 648 2013-03-05 17:54:27Z des $ */ #ifdef HAVE_CONFIG_H diff --git a/contrib/openpam/lib/pam_authenticate_secondary.c b/contrib/openpam/lib/libpam/pam_authenticate_secondary.c similarity index 97% rename from contrib/openpam/lib/pam_authenticate_secondary.c rename to contrib/openpam/lib/libpam/pam_authenticate_secondary.c index 1a5731358970..9167867833de 100644 --- a/contrib/openpam/lib/pam_authenticate_secondary.c +++ b/contrib/openpam/lib/libpam/pam_authenticate_secondary.c @@ -32,7 +32,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: pam_authenticate_secondary.c 437 2011-09-13 12:00:13Z des $ + * $Id: pam_authenticate_secondary.c 648 2013-03-05 17:54:27Z des $ */ #ifdef HAVE_CONFIG_H diff --git a/contrib/openpam/lib/pam_chauthtok.c b/contrib/openpam/lib/libpam/pam_chauthtok.c similarity index 98% rename from contrib/openpam/lib/pam_chauthtok.c rename to contrib/openpam/lib/libpam/pam_chauthtok.c index 1750b0f5fdd7..163fec7cf42f 100644 --- a/contrib/openpam/lib/pam_chauthtok.c +++ b/contrib/openpam/lib/libpam/pam_chauthtok.c @@ -32,7 +32,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: pam_chauthtok.c 437 2011-09-13 12:00:13Z des $ + * $Id: pam_chauthtok.c 648 2013-03-05 17:54:27Z des $ */ #ifdef HAVE_CONFIG_H diff --git a/contrib/openpam/lib/pam_close_session.c b/contrib/openpam/lib/libpam/pam_close_session.c similarity index 97% rename from contrib/openpam/lib/pam_close_session.c rename to contrib/openpam/lib/libpam/pam_close_session.c index 9e63a1dc965f..8bc1efaebaae 100644 --- a/contrib/openpam/lib/pam_close_session.c +++ b/contrib/openpam/lib/libpam/pam_close_session.c @@ -32,7 +32,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: pam_close_session.c 437 2011-09-13 12:00:13Z des $ + * $Id: pam_close_session.c 648 2013-03-05 17:54:27Z des $ */ #ifdef HAVE_CONFIG_H diff --git a/contrib/openpam/lib/pam_end.c b/contrib/openpam/lib/libpam/pam_end.c similarity index 98% rename from contrib/openpam/lib/pam_end.c rename to contrib/openpam/lib/libpam/pam_end.c index 09cde350ea6a..f7ece50e535f 100644 --- a/contrib/openpam/lib/pam_end.c +++ b/contrib/openpam/lib/libpam/pam_end.c @@ -32,7 +32,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: pam_end.c 437 2011-09-13 12:00:13Z des $ + * $Id: pam_end.c 648 2013-03-05 17:54:27Z des $ */ #ifdef HAVE_CONFIG_H diff --git a/contrib/openpam/lib/pam_error.c b/contrib/openpam/lib/libpam/pam_error.c similarity index 98% rename from contrib/openpam/lib/pam_error.c rename to contrib/openpam/lib/libpam/pam_error.c index 1e0de5b267b4..cd018f5389e5 100644 --- a/contrib/openpam/lib/pam_error.c +++ b/contrib/openpam/lib/libpam/pam_error.c @@ -32,7 +32,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: pam_error.c 437 2011-09-13 12:00:13Z des $ + * $Id: pam_error.c 648 2013-03-05 17:54:27Z des $ */ #ifdef HAVE_CONFIG_H diff --git a/contrib/openpam/lib/pam_get_authtok.c b/contrib/openpam/lib/libpam/pam_get_authtok.c similarity index 78% rename from contrib/openpam/lib/pam_get_authtok.c rename to contrib/openpam/lib/libpam/pam_get_authtok.c index 1a3aebc81093..a0629341c22a 100644 --- a/contrib/openpam/lib/pam_get_authtok.c +++ b/contrib/openpam/lib/libpam/pam_get_authtok.c @@ -32,7 +32,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: pam_get_authtok.c 510 2011-12-31 13:14:23Z des $ + * $Id: pam_get_authtok.c 670 2013-03-17 19:26:07Z des $ */ #ifdef HAVE_CONFIG_H @@ -113,9 +113,9 @@ pam_get_authtok(pam_handle_t *pamh, if (r == PAM_SUCCESS && prevauthtok != NULL) { *authtok = prevauthtok; RETURNC(PAM_SUCCESS); - } - else if (openpam_get_option(pamh, "use_first_pass")) + } else if (openpam_get_option(pamh, "use_first_pass")) { RETURNC(r == PAM_SUCCESS ? PAM_AUTH_ERR : r); + } } /* pam policy overrides the module's choice */ if ((promptp = openpam_get_option(pamh, prompt_option)) != NULL) @@ -168,10 +168,12 @@ pam_get_authtok(pam_handle_t *pamh, */ /** - * The =pam_get_authtok function returns the cached authentication token, - * or prompts the user if no token is currently cached. + * The =pam_get_authtok function either prompts the user for an + * authentication token or retrieves a cached authentication token, + * depending on circumstances. * Either way, a pointer to the authentication token is stored in the - * location pointed to by the =authtok argument. + * location pointed to by the =authtok argument, and the corresponding PAM + * item is updated. * * The =item argument must have one of the following values: * @@ -186,20 +188,47 @@ pam_get_authtok(pam_handle_t *pamh, * If it is =NULL, the =PAM_AUTHTOK_PROMPT or =PAM_OLDAUTHTOK_PROMPT item, * as appropriate, will be used. * If that item is also =NULL, a hardcoded default prompt will be used. - * Either way, the prompt is expanded using =openpam_subst before it is - * passed to the conversation function. - * - * If =pam_get_authtok is called from a module and the ;authtok_prompt / - * ;oldauthtok_prompt option is set in the policy file, the value of that - * option takes precedence over both the =prompt argument and the - * =PAM_AUTHTOK_PROMPT / =PAM_OLDAUTHTOK_PROMPT item. + * Additionally, when =pam_get_authtok is called from a service module, + * the prompt may be affected by module options as described below. + * The prompt is then expanded using =openpam_subst before it is passed to + * the conversation function. * * If =item is set to =PAM_AUTHTOK and there is a non-null =PAM_OLDAUTHTOK * item, =pam_get_authtok will ask the user to confirm the new token by * retyping it. * If there is a mismatch, =pam_get_authtok will return =PAM_TRY_AGAIN. * + * MODULE OPTIONS + * + * When called by a service module, =pam_get_authtok will recognize the + * following module options: + * + * ;authtok_prompt: + * Prompt to use when =item is set to =PAM_AUTHTOK. + * This option overrides both the =prompt argument and the + * =PAM_AUTHTOK_PROMPT item. + * ;echo_pass: + * If the application's conversation function allows it, this + * lets the user see what they are typing. + * This should only be used for non-reusable authentication + * tokens. + * ;oldauthtok_prompt: + * Prompt to use when =item is set to =PAM_OLDAUTHTOK. + * This option overrides both the =prompt argument and the + * =PAM_OLDAUTHTOK_PROMPT item. + * ;try_first_pass: + * If the requested item is non-null, return it without + * prompting the user. + * Typically, the service module will verify the token, and + * if it does not match, clear the item before calling + * =pam_get_authtok a second time. + * ;use_first_pass: + * Do not prompt the user at all; just return the cached + * value, or =PAM_AUTH_ERR if there is none. + * + * >pam_conv * >pam_get_item * >pam_get_user + * >openpam_get_option * >openpam_subst */ diff --git a/contrib/openpam/lib/pam_get_data.c b/contrib/openpam/lib/libpam/pam_get_data.c similarity index 98% rename from contrib/openpam/lib/pam_get_data.c rename to contrib/openpam/lib/libpam/pam_get_data.c index 1a8ba1de8df5..de31d7013f4c 100644 --- a/contrib/openpam/lib/pam_get_data.c +++ b/contrib/openpam/lib/libpam/pam_get_data.c @@ -32,7 +32,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: pam_get_data.c 444 2011-10-22 01:03:23Z des $ + * $Id: pam_get_data.c 648 2013-03-05 17:54:27Z des $ */ #ifdef HAVE_CONFIG_H diff --git a/contrib/openpam/lib/pam_get_item.c b/contrib/openpam/lib/libpam/pam_get_item.c similarity index 98% rename from contrib/openpam/lib/pam_get_item.c rename to contrib/openpam/lib/libpam/pam_get_item.c index 95b9df6d02bd..9dc3dc33b202 100644 --- a/contrib/openpam/lib/pam_get_item.c +++ b/contrib/openpam/lib/libpam/pam_get_item.c @@ -32,7 +32,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: pam_get_item.c 491 2011-11-12 00:12:32Z des $ + * $Id: pam_get_item.c 648 2013-03-05 17:54:27Z des $ */ #ifdef HAVE_CONFIG_H diff --git a/contrib/openpam/lib/pam_get_mapped_authtok.c b/contrib/openpam/lib/libpam/pam_get_mapped_authtok.c similarity index 97% rename from contrib/openpam/lib/pam_get_mapped_authtok.c rename to contrib/openpam/lib/libpam/pam_get_mapped_authtok.c index 54ff6c3e7e89..871405efb5dc 100644 --- a/contrib/openpam/lib/pam_get_mapped_authtok.c +++ b/contrib/openpam/lib/libpam/pam_get_mapped_authtok.c @@ -32,7 +32,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: pam_get_mapped_authtok.c 437 2011-09-13 12:00:13Z des $ + * $Id: pam_get_mapped_authtok.c 648 2013-03-05 17:54:27Z des $ */ #ifdef HAVE_CONFIG_H diff --git a/contrib/openpam/lib/pam_get_mapped_username.c b/contrib/openpam/lib/libpam/pam_get_mapped_username.c similarity index 97% rename from contrib/openpam/lib/pam_get_mapped_username.c rename to contrib/openpam/lib/libpam/pam_get_mapped_username.c index 4f8ac17fd131..25305d2ac55c 100644 --- a/contrib/openpam/lib/pam_get_mapped_username.c +++ b/contrib/openpam/lib/libpam/pam_get_mapped_username.c @@ -32,7 +32,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: pam_get_mapped_username.c 437 2011-09-13 12:00:13Z des $ + * $Id: pam_get_mapped_username.c 648 2013-03-05 17:54:27Z des $ */ #ifdef HAVE_CONFIG_H diff --git a/contrib/openpam/lib/pam_get_user.c b/contrib/openpam/lib/libpam/pam_get_user.c similarity index 85% rename from contrib/openpam/lib/pam_get_user.c rename to contrib/openpam/lib/libpam/pam_get_user.c index 53245b99e57d..2e22e0ec0364 100644 --- a/contrib/openpam/lib/pam_get_user.c +++ b/contrib/openpam/lib/libpam/pam_get_user.c @@ -32,7 +32,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: pam_get_user.c 455 2011-10-29 18:31:11Z des $ + * $Id: pam_get_user.c 670 2013-03-17 19:26:07Z des $ */ #ifdef HAVE_CONFIG_H @@ -116,20 +116,31 @@ pam_get_user(pam_handle_t *pamh, * If no user was specified, nor set using =pam_set_item, =pam_get_user * will prompt for a user name. * Either way, a pointer to the user name is stored in the location - * pointed to by the =user argument. + * pointed to by the =user argument, and the corresponding PAM item is + * updated. * * The =prompt argument specifies a prompt to use if no user name is * cached. * If it is =NULL, the =PAM_USER_PROMPT item will be used. * If that item is also =NULL, a hardcoded default prompt will be used. - * Either way, the prompt is expanded using =openpam_subst before it is - * passed to the conversation function. + * Additionally, when =pam_get_user is called from a service module, the + * prompt may be affected by module options as described below. + * The prompt is then expanded using =openpam_subst before it is passed to + * the conversation function. * - * If =pam_get_user is called from a module and the ;user_prompt option is - * set in the policy file, the value of that option takes precedence over - * both the =prompt argument and the =PAM_USER_PROMPT item. + * MODULE OPTIONS * + * When called by a service module, =pam_get_user will recognize the + * following module options: + * + * ;user_prompt: + * Prompt to use when asking for the user name. + * This option overrides both the =prompt argument and the + * =PAM_USER_PROMPT item. + * + * >pam_conv * >pam_get_item * >pam_get_authtok + * >openpam_get_option * >openpam_subst */ diff --git a/contrib/openpam/lib/pam_getenv.c b/contrib/openpam/lib/libpam/pam_getenv.c similarity index 98% rename from contrib/openpam/lib/pam_getenv.c rename to contrib/openpam/lib/libpam/pam_getenv.c index e2ebf579edaa..666903549454 100644 --- a/contrib/openpam/lib/pam_getenv.c +++ b/contrib/openpam/lib/libpam/pam_getenv.c @@ -32,7 +32,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: pam_getenv.c 437 2011-09-13 12:00:13Z des $ + * $Id: pam_getenv.c 648 2013-03-05 17:54:27Z des $ */ #ifdef HAVE_CONFIG_H diff --git a/contrib/openpam/lib/pam_getenvlist.c b/contrib/openpam/lib/libpam/pam_getenvlist.c similarity index 98% rename from contrib/openpam/lib/pam_getenvlist.c rename to contrib/openpam/lib/libpam/pam_getenvlist.c index 06c003f02ef6..9dcded0e79b9 100644 --- a/contrib/openpam/lib/pam_getenvlist.c +++ b/contrib/openpam/lib/libpam/pam_getenvlist.c @@ -32,7 +32,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: pam_getenvlist.c 437 2011-09-13 12:00:13Z des $ + * $Id: pam_getenvlist.c 648 2013-03-05 17:54:27Z des $ */ #ifdef HAVE_CONFIG_H diff --git a/contrib/openpam/lib/pam_info.c b/contrib/openpam/lib/libpam/pam_info.c similarity index 98% rename from contrib/openpam/lib/pam_info.c rename to contrib/openpam/lib/libpam/pam_info.c index 7e51dbf6b889..550bb76c9594 100644 --- a/contrib/openpam/lib/pam_info.c +++ b/contrib/openpam/lib/libpam/pam_info.c @@ -32,7 +32,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: pam_info.c 437 2011-09-13 12:00:13Z des $ + * $Id: pam_info.c 648 2013-03-05 17:54:27Z des $ */ #ifdef HAVE_CONFIG_H diff --git a/contrib/openpam/lib/pam_open_session.c b/contrib/openpam/lib/libpam/pam_open_session.c similarity index 97% rename from contrib/openpam/lib/pam_open_session.c rename to contrib/openpam/lib/libpam/pam_open_session.c index 36c59b049e2a..de12705088eb 100644 --- a/contrib/openpam/lib/pam_open_session.c +++ b/contrib/openpam/lib/libpam/pam_open_session.c @@ -32,7 +32,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: pam_open_session.c 437 2011-09-13 12:00:13Z des $ + * $Id: pam_open_session.c 648 2013-03-05 17:54:27Z des $ */ #ifdef HAVE_CONFIG_H diff --git a/contrib/openpam/lib/pam_prompt.c b/contrib/openpam/lib/libpam/pam_prompt.c similarity index 98% rename from contrib/openpam/lib/pam_prompt.c rename to contrib/openpam/lib/libpam/pam_prompt.c index 194e7655237f..e3ba0f2b90e7 100644 --- a/contrib/openpam/lib/pam_prompt.c +++ b/contrib/openpam/lib/libpam/pam_prompt.c @@ -32,7 +32,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: pam_prompt.c 437 2011-09-13 12:00:13Z des $ + * $Id: pam_prompt.c 648 2013-03-05 17:54:27Z des $ */ #ifdef HAVE_CONFIG_H diff --git a/contrib/openpam/lib/pam_putenv.c b/contrib/openpam/lib/libpam/pam_putenv.c similarity index 98% rename from contrib/openpam/lib/pam_putenv.c rename to contrib/openpam/lib/libpam/pam_putenv.c index e1f0bc35e29c..0d4d71036cf5 100644 --- a/contrib/openpam/lib/pam_putenv.c +++ b/contrib/openpam/lib/libpam/pam_putenv.c @@ -32,7 +32,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: pam_putenv.c 539 2012-03-31 20:53:22Z des $ + * $Id: pam_putenv.c 648 2013-03-05 17:54:27Z des $ */ #ifdef HAVE_CONFIG_H diff --git a/contrib/openpam/lib/pam_set_data.c b/contrib/openpam/lib/libpam/pam_set_data.c similarity index 98% rename from contrib/openpam/lib/pam_set_data.c rename to contrib/openpam/lib/libpam/pam_set_data.c index a8de632f7bf7..344f4ef30fae 100644 --- a/contrib/openpam/lib/pam_set_data.c +++ b/contrib/openpam/lib/libpam/pam_set_data.c @@ -32,7 +32,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: pam_set_data.c 437 2011-09-13 12:00:13Z des $ + * $Id: pam_set_data.c 648 2013-03-05 17:54:27Z des $ */ #ifdef HAVE_CONFIG_H diff --git a/contrib/openpam/lib/pam_set_item.c b/contrib/openpam/lib/libpam/pam_set_item.c similarity index 98% rename from contrib/openpam/lib/pam_set_item.c rename to contrib/openpam/lib/libpam/pam_set_item.c index 05d538f7bdca..10c855aa9e10 100644 --- a/contrib/openpam/lib/pam_set_item.c +++ b/contrib/openpam/lib/libpam/pam_set_item.c @@ -32,7 +32,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: pam_set_item.c 496 2011-11-21 16:20:45Z des $ + * $Id: pam_set_item.c 648 2013-03-05 17:54:27Z des $ */ #ifdef HAVE_CONFIG_H diff --git a/contrib/openpam/lib/pam_set_mapped_authtok.c b/contrib/openpam/lib/libpam/pam_set_mapped_authtok.c similarity index 97% rename from contrib/openpam/lib/pam_set_mapped_authtok.c rename to contrib/openpam/lib/libpam/pam_set_mapped_authtok.c index d8db84fd34fa..c8fbd91b4aac 100644 --- a/contrib/openpam/lib/pam_set_mapped_authtok.c +++ b/contrib/openpam/lib/libpam/pam_set_mapped_authtok.c @@ -32,7 +32,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: pam_set_mapped_authtok.c 437 2011-09-13 12:00:13Z des $ + * $Id: pam_set_mapped_authtok.c 648 2013-03-05 17:54:27Z des $ */ #ifdef HAVE_CONFIG_H diff --git a/contrib/openpam/lib/pam_set_mapped_username.c b/contrib/openpam/lib/libpam/pam_set_mapped_username.c similarity index 97% rename from contrib/openpam/lib/pam_set_mapped_username.c rename to contrib/openpam/lib/libpam/pam_set_mapped_username.c index 4b8f8153916d..8f62f53d235d 100644 --- a/contrib/openpam/lib/pam_set_mapped_username.c +++ b/contrib/openpam/lib/libpam/pam_set_mapped_username.c @@ -32,7 +32,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: pam_set_mapped_username.c 437 2011-09-13 12:00:13Z des $ + * $Id: pam_set_mapped_username.c 648 2013-03-05 17:54:27Z des $ */ #ifdef HAVE_CONFIG_H diff --git a/contrib/openpam/lib/pam_setcred.c b/contrib/openpam/lib/libpam/pam_setcred.c similarity index 98% rename from contrib/openpam/lib/pam_setcred.c rename to contrib/openpam/lib/libpam/pam_setcred.c index 51fb0816b6d8..7a691765573b 100644 --- a/contrib/openpam/lib/pam_setcred.c +++ b/contrib/openpam/lib/libpam/pam_setcred.c @@ -32,7 +32,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: pam_setcred.c 437 2011-09-13 12:00:13Z des $ + * $Id: pam_setcred.c 648 2013-03-05 17:54:27Z des $ */ #ifdef HAVE_CONFIG_H diff --git a/contrib/openpam/lib/pam_setenv.c b/contrib/openpam/lib/libpam/pam_setenv.c similarity index 97% rename from contrib/openpam/lib/pam_setenv.c rename to contrib/openpam/lib/libpam/pam_setenv.c index 6fd4c1001e83..070a185e6019 100644 --- a/contrib/openpam/lib/pam_setenv.c +++ b/contrib/openpam/lib/libpam/pam_setenv.c @@ -32,7 +32,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: pam_setenv.c 539 2012-03-31 20:53:22Z des $ + * $Id: pam_setenv.c 648 2013-03-05 17:54:27Z des $ */ #ifdef HAVE_CONFIG_H @@ -46,6 +46,7 @@ #include #include "openpam_impl.h" +#include "openpam_asprintf.h" /* * OpenPAM extension diff --git a/contrib/openpam/lib/pam_sm_acct_mgmt.c b/contrib/openpam/lib/libpam/pam_sm_acct_mgmt.c similarity index 97% rename from contrib/openpam/lib/pam_sm_acct_mgmt.c rename to contrib/openpam/lib/libpam/pam_sm_acct_mgmt.c index f5c14cf99a7a..6420fbac0fb2 100644 --- a/contrib/openpam/lib/pam_sm_acct_mgmt.c +++ b/contrib/openpam/lib/libpam/pam_sm_acct_mgmt.c @@ -32,7 +32,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: pam_sm_acct_mgmt.c 437 2011-09-13 12:00:13Z des $ + * $Id: pam_sm_acct_mgmt.c 648 2013-03-05 17:54:27Z des $ */ #ifdef HAVE_CONFIG_H diff --git a/contrib/openpam/lib/pam_sm_authenticate.c b/contrib/openpam/lib/libpam/pam_sm_authenticate.c similarity index 97% rename from contrib/openpam/lib/pam_sm_authenticate.c rename to contrib/openpam/lib/libpam/pam_sm_authenticate.c index 97851af43e69..f31b6ac2db24 100644 --- a/contrib/openpam/lib/pam_sm_authenticate.c +++ b/contrib/openpam/lib/libpam/pam_sm_authenticate.c @@ -32,7 +32,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: pam_sm_authenticate.c 437 2011-09-13 12:00:13Z des $ + * $Id: pam_sm_authenticate.c 648 2013-03-05 17:54:27Z des $ */ #ifdef HAVE_CONFIG_H diff --git a/contrib/openpam/lib/pam_sm_authenticate_secondary.c b/contrib/openpam/lib/libpam/pam_sm_authenticate_secondary.c similarity index 97% rename from contrib/openpam/lib/pam_sm_authenticate_secondary.c rename to contrib/openpam/lib/libpam/pam_sm_authenticate_secondary.c index 3f3f6bdf4705..4a232fbd0fcb 100644 --- a/contrib/openpam/lib/pam_sm_authenticate_secondary.c +++ b/contrib/openpam/lib/libpam/pam_sm_authenticate_secondary.c @@ -32,7 +32,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: pam_sm_authenticate_secondary.c 437 2011-09-13 12:00:13Z des $ + * $Id: pam_sm_authenticate_secondary.c 648 2013-03-05 17:54:27Z des $ */ #ifdef HAVE_CONFIG_H diff --git a/contrib/openpam/lib/pam_sm_chauthtok.c b/contrib/openpam/lib/libpam/pam_sm_chauthtok.c similarity index 97% rename from contrib/openpam/lib/pam_sm_chauthtok.c rename to contrib/openpam/lib/libpam/pam_sm_chauthtok.c index 593344cca222..4f17562af288 100644 --- a/contrib/openpam/lib/pam_sm_chauthtok.c +++ b/contrib/openpam/lib/libpam/pam_sm_chauthtok.c @@ -32,7 +32,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: pam_sm_chauthtok.c 466 2011-11-02 23:33:43Z des $ + * $Id: pam_sm_chauthtok.c 648 2013-03-05 17:54:27Z des $ */ #ifdef HAVE_CONFIG_H diff --git a/contrib/openpam/lib/pam_sm_close_session.c b/contrib/openpam/lib/libpam/pam_sm_close_session.c similarity index 97% rename from contrib/openpam/lib/pam_sm_close_session.c rename to contrib/openpam/lib/libpam/pam_sm_close_session.c index 290f497b1cd5..9247d8f5b1fc 100644 --- a/contrib/openpam/lib/pam_sm_close_session.c +++ b/contrib/openpam/lib/libpam/pam_sm_close_session.c @@ -32,7 +32,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: pam_sm_close_session.c 437 2011-09-13 12:00:13Z des $ + * $Id: pam_sm_close_session.c 648 2013-03-05 17:54:27Z des $ */ #ifdef HAVE_CONFIG_H diff --git a/contrib/openpam/lib/pam_sm_get_mapped_authtok.c b/contrib/openpam/lib/libpam/pam_sm_get_mapped_authtok.c similarity index 97% rename from contrib/openpam/lib/pam_sm_get_mapped_authtok.c rename to contrib/openpam/lib/libpam/pam_sm_get_mapped_authtok.c index e86e6e5d3624..473a52e7742e 100644 --- a/contrib/openpam/lib/pam_sm_get_mapped_authtok.c +++ b/contrib/openpam/lib/libpam/pam_sm_get_mapped_authtok.c @@ -32,7 +32,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: pam_sm_get_mapped_authtok.c 437 2011-09-13 12:00:13Z des $ + * $Id: pam_sm_get_mapped_authtok.c 648 2013-03-05 17:54:27Z des $ */ #ifdef HAVE_CONFIG_H diff --git a/contrib/openpam/lib/pam_sm_get_mapped_username.c b/contrib/openpam/lib/libpam/pam_sm_get_mapped_username.c similarity index 97% rename from contrib/openpam/lib/pam_sm_get_mapped_username.c rename to contrib/openpam/lib/libpam/pam_sm_get_mapped_username.c index 596ca6cb1aba..6de9fdb46437 100644 --- a/contrib/openpam/lib/pam_sm_get_mapped_username.c +++ b/contrib/openpam/lib/libpam/pam_sm_get_mapped_username.c @@ -32,7 +32,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: pam_sm_get_mapped_username.c 437 2011-09-13 12:00:13Z des $ + * $Id: pam_sm_get_mapped_username.c 648 2013-03-05 17:54:27Z des $ */ #ifdef HAVE_CONFIG_H diff --git a/contrib/openpam/lib/pam_sm_open_session.c b/contrib/openpam/lib/libpam/pam_sm_open_session.c similarity index 97% rename from contrib/openpam/lib/pam_sm_open_session.c rename to contrib/openpam/lib/libpam/pam_sm_open_session.c index acb401ab3da7..a576a00b1af9 100644 --- a/contrib/openpam/lib/pam_sm_open_session.c +++ b/contrib/openpam/lib/libpam/pam_sm_open_session.c @@ -32,7 +32,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: pam_sm_open_session.c 437 2011-09-13 12:00:13Z des $ + * $Id: pam_sm_open_session.c 648 2013-03-05 17:54:27Z des $ */ #ifdef HAVE_CONFIG_H diff --git a/contrib/openpam/lib/pam_sm_set_mapped_authtok.c b/contrib/openpam/lib/libpam/pam_sm_set_mapped_authtok.c similarity index 97% rename from contrib/openpam/lib/pam_sm_set_mapped_authtok.c rename to contrib/openpam/lib/libpam/pam_sm_set_mapped_authtok.c index dab40fd9d001..de0e91f86e5d 100644 --- a/contrib/openpam/lib/pam_sm_set_mapped_authtok.c +++ b/contrib/openpam/lib/libpam/pam_sm_set_mapped_authtok.c @@ -32,7 +32,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: pam_sm_set_mapped_authtok.c 437 2011-09-13 12:00:13Z des $ + * $Id: pam_sm_set_mapped_authtok.c 648 2013-03-05 17:54:27Z des $ */ #ifdef HAVE_CONFIG_H diff --git a/contrib/openpam/lib/pam_sm_set_mapped_username.c b/contrib/openpam/lib/libpam/pam_sm_set_mapped_username.c similarity index 97% rename from contrib/openpam/lib/pam_sm_set_mapped_username.c rename to contrib/openpam/lib/libpam/pam_sm_set_mapped_username.c index 3011016b4b41..2696d3e182ec 100644 --- a/contrib/openpam/lib/pam_sm_set_mapped_username.c +++ b/contrib/openpam/lib/libpam/pam_sm_set_mapped_username.c @@ -32,7 +32,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: pam_sm_set_mapped_username.c 437 2011-09-13 12:00:13Z des $ + * $Id: pam_sm_set_mapped_username.c 648 2013-03-05 17:54:27Z des $ */ #ifdef HAVE_CONFIG_H diff --git a/contrib/openpam/lib/pam_sm_setcred.c b/contrib/openpam/lib/libpam/pam_sm_setcred.c similarity index 97% rename from contrib/openpam/lib/pam_sm_setcred.c rename to contrib/openpam/lib/libpam/pam_sm_setcred.c index 0d306838bc1b..0836adc54f8e 100644 --- a/contrib/openpam/lib/pam_sm_setcred.c +++ b/contrib/openpam/lib/libpam/pam_sm_setcred.c @@ -32,7 +32,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: pam_sm_setcred.c 437 2011-09-13 12:00:13Z des $ + * $Id: pam_sm_setcred.c 648 2013-03-05 17:54:27Z des $ */ #ifdef HAVE_CONFIG_H diff --git a/contrib/openpam/lib/pam_start.c b/contrib/openpam/lib/libpam/pam_start.c similarity index 98% rename from contrib/openpam/lib/pam_start.c rename to contrib/openpam/lib/libpam/pam_start.c index 84e0085b30b7..03fae416cad6 100644 --- a/contrib/openpam/lib/pam_start.c +++ b/contrib/openpam/lib/libpam/pam_start.c @@ -32,7 +32,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: pam_start.c 503 2011-12-18 14:00:33Z des $ + * $Id: pam_start.c 648 2013-03-05 17:54:27Z des $ */ #ifdef HAVE_CONFIG_H diff --git a/contrib/openpam/lib/pam_strerror.c b/contrib/openpam/lib/libpam/pam_strerror.c similarity index 98% rename from contrib/openpam/lib/pam_strerror.c rename to contrib/openpam/lib/libpam/pam_strerror.c index e29219d8472d..8621ad6c3dd4 100644 --- a/contrib/openpam/lib/pam_strerror.c +++ b/contrib/openpam/lib/libpam/pam_strerror.c @@ -32,7 +32,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: pam_strerror.c 491 2011-11-12 00:12:32Z des $ + * $Id: pam_strerror.c 648 2013-03-05 17:54:27Z des $ */ #ifdef HAVE_CONFIG_H diff --git a/contrib/openpam/lib/pam_verror.c b/contrib/openpam/lib/libpam/pam_verror.c similarity index 98% rename from contrib/openpam/lib/pam_verror.c rename to contrib/openpam/lib/libpam/pam_verror.c index 9ed85b688a08..683abbc0b2fb 100644 --- a/contrib/openpam/lib/pam_verror.c +++ b/contrib/openpam/lib/libpam/pam_verror.c @@ -32,7 +32,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: pam_verror.c 437 2011-09-13 12:00:13Z des $ + * $Id: pam_verror.c 648 2013-03-05 17:54:27Z des $ */ #ifdef HAVE_CONFIG_H diff --git a/contrib/openpam/lib/pam_vinfo.c b/contrib/openpam/lib/libpam/pam_vinfo.c similarity index 98% rename from contrib/openpam/lib/pam_vinfo.c rename to contrib/openpam/lib/libpam/pam_vinfo.c index 95f45f4d2062..3ae2c7faa19a 100644 --- a/contrib/openpam/lib/pam_vinfo.c +++ b/contrib/openpam/lib/libpam/pam_vinfo.c @@ -32,7 +32,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: pam_vinfo.c 437 2011-09-13 12:00:13Z des $ + * $Id: pam_vinfo.c 648 2013-03-05 17:54:27Z des $ */ #ifdef HAVE_CONFIG_H diff --git a/contrib/openpam/lib/pam_vprompt.c b/contrib/openpam/lib/libpam/pam_vprompt.c similarity index 98% rename from contrib/openpam/lib/pam_vprompt.c rename to contrib/openpam/lib/libpam/pam_vprompt.c index 1e390e09c36b..eb337af0dc06 100644 --- a/contrib/openpam/lib/pam_vprompt.c +++ b/contrib/openpam/lib/libpam/pam_vprompt.c @@ -32,7 +32,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: pam_vprompt.c 437 2011-09-13 12:00:13Z des $ + * $Id: pam_vprompt.c 648 2013-03-05 17:54:27Z des $ */ #ifdef HAVE_CONFIG_H diff --git a/contrib/openpam/lib/openpam_ttyconv.c b/contrib/openpam/lib/openpam_ttyconv.c deleted file mode 100644 index 14a324d59ed3..000000000000 --- a/contrib/openpam/lib/openpam_ttyconv.c +++ /dev/null @@ -1,252 +0,0 @@ -/*- - * Copyright (c) 2002-2003 Networks Associates Technology, Inc. - * Copyright (c) 2004-2011 Dag-Erling Smørgrav - * All rights reserved. - * - * This software was developed for the FreeBSD Project by ThinkSec AS and - * Network Associates Laboratories, the Security Research Division of - * Network Associates, Inc. under DARPA/SPAWAR contract N66001-01-C-8035 - * ("CBOSS"), as part of the DARPA CHATS research program. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote - * products derived from this software without specific prior written - * permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * $Id: openpam_ttyconv.c 527 2012-02-26 03:23:59Z des $ - */ - -#ifdef HAVE_CONFIG_H -# include "config.h" -#endif - -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#include "openpam_impl.h" - -int openpam_ttyconv_timeout = 0; - -static void -timeout(int sig) -{ - - (void)sig; -} - -static char * -prompt(const char *msg) -{ - char buf[PAM_MAX_RESP_SIZE]; - struct sigaction action, saved_action; - sigset_t saved_sigset, the_sigset; - unsigned int saved_alarm; - int eof, error, fd; - size_t len; - char *retval; - char ch; - - sigemptyset(&the_sigset); - sigaddset(&the_sigset, SIGINT); - sigaddset(&the_sigset, SIGTSTP); - sigprocmask(SIG_SETMASK, &the_sigset, &saved_sigset); - action.sa_handler = &timeout; - action.sa_flags = 0; - sigemptyset(&action.sa_mask); - sigaction(SIGALRM, &action, &saved_action); - fputs(msg, stdout); - fflush(stdout); -#ifdef HAVE_FPURGE - fpurge(stdin); -#endif - fd = fileno(stdin); - buf[0] = '\0'; - eof = error = 0; - saved_alarm = 0; - if (openpam_ttyconv_timeout >= 0) - saved_alarm = alarm(openpam_ttyconv_timeout); - ch = '\0'; - for (len = 0; ch != '\n' && !eof && !error; ++len) { - switch (read(fd, &ch, 1)) { - case 1: - if (len < PAM_MAX_RESP_SIZE - 1) { - buf[len + 1] = '\0'; - buf[len] = ch; - } - break; - case 0: - eof = 1; - break; - default: - error = errno; - break; - } - } - if (openpam_ttyconv_timeout >= 0) - alarm(0); - sigaction(SIGALRM, &saved_action, NULL); - sigprocmask(SIG_SETMASK, &saved_sigset, NULL); - if (saved_alarm > 0) - alarm(saved_alarm); - if (error == EINTR) - fputs(" timeout!", stderr); - if (error || eof) { - fputs("\n", stderr); - memset(buf, 0, sizeof(buf)); - return (NULL); - } - /* trim trailing whitespace */ - for (len = strlen(buf); len > 0; --len) - if (buf[len - 1] != '\r' && buf[len - 1] != '\n') - break; - buf[len] = '\0'; - retval = strdup(buf); - memset(buf, 0, sizeof(buf)); - return (retval); -} - -static char * -prompt_echo_off(const char *msg) -{ - struct termios tattr; - tcflag_t lflag; - char *ret; - int fd; - - fd = fileno(stdin); - if (tcgetattr(fd, &tattr) != 0) { - openpam_log(PAM_LOG_ERROR, "tcgetattr(): %m"); - return (NULL); - } - lflag = tattr.c_lflag; - tattr.c_lflag &= ~ECHO; - if (tcsetattr(fd, TCSAFLUSH, &tattr) != 0) { - openpam_log(PAM_LOG_ERROR, "tcsetattr(): %m"); - return (NULL); - } - ret = prompt(msg); - tattr.c_lflag = lflag; - (void)tcsetattr(fd, TCSANOW, &tattr); - if (ret != NULL) - fputs("\n", stdout); - return (ret); -} - -/* - * OpenPAM extension - * - * Simple tty-based conversation function - */ - -int -openpam_ttyconv(int n, - const struct pam_message **msg, - struct pam_response **resp, - void *data) -{ - struct pam_response *aresp; - int i; - - ENTER(); - (void)data; - if (n <= 0 || n > PAM_MAX_NUM_MSG) - RETURNC(PAM_CONV_ERR); - if ((aresp = calloc(n, sizeof *aresp)) == NULL) - RETURNC(PAM_BUF_ERR); - for (i = 0; i < n; ++i) { - aresp[i].resp_retcode = 0; - aresp[i].resp = NULL; - switch (msg[i]->msg_style) { - case PAM_PROMPT_ECHO_OFF: - aresp[i].resp = prompt_echo_off(msg[i]->msg); - if (aresp[i].resp == NULL) - goto fail; - break; - case PAM_PROMPT_ECHO_ON: - aresp[i].resp = prompt(msg[i]->msg); - if (aresp[i].resp == NULL) - goto fail; - break; - case PAM_ERROR_MSG: - fputs(msg[i]->msg, stderr); - if (strlen(msg[i]->msg) > 0 && - msg[i]->msg[strlen(msg[i]->msg) - 1] != '\n') - fputc('\n', stderr); - break; - case PAM_TEXT_INFO: - fputs(msg[i]->msg, stdout); - if (strlen(msg[i]->msg) > 0 && - msg[i]->msg[strlen(msg[i]->msg) - 1] != '\n') - fputc('\n', stdout); - break; - default: - goto fail; - } - } - *resp = aresp; - RETURNC(PAM_SUCCESS); -fail: - for (i = 0; i < n; ++i) { - if (aresp[i].resp != NULL) { - memset(aresp[i].resp, 0, strlen(aresp[i].resp)); - FREE(aresp[i].resp); - } - } - memset(aresp, 0, n * sizeof *aresp); - FREE(aresp); - *resp = NULL; - RETURNC(PAM_CONV_ERR); -} - -/* - * Error codes: - * - * PAM_SYSTEM_ERR - * PAM_BUF_ERR - * PAM_CONV_ERR - */ - -/** - * The =openpam_ttyconv function is a standard conversation function - * suitable for use on TTY devices. - * It should be adequate for the needs of most text-based interactive - * programs. - * - * The =openpam_ttyconv function allows the application to specify a - * timeout for user input by setting the global integer variable - * :openpam_ttyconv_timeout to the length of the timeout in seconds. - * - * >openpam_nullconv - * >pam_prompt - * >pam_vprompt - */ diff --git a/contrib/openpam/m4/libtool.m4 b/contrib/openpam/m4/libtool.m4 new file mode 100644 index 000000000000..44e0ecff11e3 --- /dev/null +++ b/contrib/openpam/m4/libtool.m4 @@ -0,0 +1,7982 @@ +# libtool.m4 - Configure libtool for the host system. -*-Autoconf-*- +# +# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005, +# 2006, 2007, 2008, 2009, 2010, 2011 Free Software +# Foundation, Inc. +# Written by Gordon Matzigkeit, 1996 +# +# This file is free software; the Free Software Foundation gives +# unlimited permission to copy and/or distribute it, with or without +# modifications, as long as this notice is preserved. + +m4_define([_LT_COPYING], [dnl +# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005, +# 2006, 2007, 2008, 2009, 2010, 2011 Free Software +# Foundation, Inc. +# Written by Gordon Matzigkeit, 1996 +# +# This file is part of GNU Libtool. +# +# GNU Libtool is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 2 of +# the License, or (at your option) any later version. +# +# As a special exception to the GNU General Public License, +# if you distribute this file as part of a program or library that +# is built using GNU Libtool, you may include this file under the +# same distribution terms that you use for the rest of that program. +# +# GNU Libtool is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with GNU Libtool; see the file COPYING. If not, a copy +# can be downloaded from http://www.gnu.org/licenses/gpl.html, or +# obtained by writing to the Free Software Foundation, Inc., +# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +]) + +# serial 57 LT_INIT + + +# LT_PREREQ(VERSION) +# ------------------ +# Complain and exit if this libtool version is less that VERSION. +m4_defun([LT_PREREQ], +[m4_if(m4_version_compare(m4_defn([LT_PACKAGE_VERSION]), [$1]), -1, + [m4_default([$3], + [m4_fatal([Libtool version $1 or higher is required], + 63)])], + [$2])]) + + +# _LT_CHECK_BUILDDIR +# ------------------ +# Complain if the absolute build directory name contains unusual characters +m4_defun([_LT_CHECK_BUILDDIR], +[case `pwd` in + *\ * | *\ *) + AC_MSG_WARN([Libtool does not cope well with whitespace in `pwd`]) ;; +esac +]) + + +# LT_INIT([OPTIONS]) +# ------------------ +AC_DEFUN([LT_INIT], +[AC_PREREQ([2.58])dnl We use AC_INCLUDES_DEFAULT +AC_REQUIRE([AC_CONFIG_AUX_DIR_DEFAULT])dnl +AC_BEFORE([$0], [LT_LANG])dnl +AC_BEFORE([$0], [LT_OUTPUT])dnl +AC_BEFORE([$0], [LTDL_INIT])dnl +m4_require([_LT_CHECK_BUILDDIR])dnl + +dnl Autoconf doesn't catch unexpanded LT_ macros by default: +m4_pattern_forbid([^_?LT_[A-Z_]+$])dnl +m4_pattern_allow([^(_LT_EOF|LT_DLGLOBAL|LT_DLLAZY_OR_NOW|LT_MULTI_MODULE)$])dnl +dnl aclocal doesn't pull ltoptions.m4, ltsugar.m4, or ltversion.m4 +dnl unless we require an AC_DEFUNed macro: +AC_REQUIRE([LTOPTIONS_VERSION])dnl +AC_REQUIRE([LTSUGAR_VERSION])dnl +AC_REQUIRE([LTVERSION_VERSION])dnl +AC_REQUIRE([LTOBSOLETE_VERSION])dnl +m4_require([_LT_PROG_LTMAIN])dnl + +_LT_SHELL_INIT([SHELL=${CONFIG_SHELL-/bin/sh}]) + +dnl Parse OPTIONS +_LT_SET_OPTIONS([$0], [$1]) + +# This can be used to rebuild libtool when needed +LIBTOOL_DEPS="$ltmain" + +# Always use our own libtool. +LIBTOOL='$(SHELL) $(top_builddir)/libtool' +AC_SUBST(LIBTOOL)dnl + +_LT_SETUP + +# Only expand once: +m4_define([LT_INIT]) +])# LT_INIT + +# Old names: +AU_ALIAS([AC_PROG_LIBTOOL], [LT_INIT]) +AU_ALIAS([AM_PROG_LIBTOOL], [LT_INIT]) +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AC_PROG_LIBTOOL], []) +dnl AC_DEFUN([AM_PROG_LIBTOOL], []) + + +# _LT_CC_BASENAME(CC) +# ------------------- +# Calculate cc_basename. Skip known compiler wrappers and cross-prefix. +m4_defun([_LT_CC_BASENAME], +[for cc_temp in $1""; do + case $cc_temp in + compile | *[[\\/]]compile | ccache | *[[\\/]]ccache ) ;; + distcc | *[[\\/]]distcc | purify | *[[\\/]]purify ) ;; + \-*) ;; + *) break;; + esac +done +cc_basename=`$ECHO "$cc_temp" | $SED "s%.*/%%; s%^$host_alias-%%"` +]) + + +# _LT_FILEUTILS_DEFAULTS +# ---------------------- +# It is okay to use these file commands and assume they have been set +# sensibly after `m4_require([_LT_FILEUTILS_DEFAULTS])'. +m4_defun([_LT_FILEUTILS_DEFAULTS], +[: ${CP="cp -f"} +: ${MV="mv -f"} +: ${RM="rm -f"} +])# _LT_FILEUTILS_DEFAULTS + + +# _LT_SETUP +# --------- +m4_defun([_LT_SETUP], +[AC_REQUIRE([AC_CANONICAL_HOST])dnl +AC_REQUIRE([AC_CANONICAL_BUILD])dnl +AC_REQUIRE([_LT_PREPARE_SED_QUOTE_VARS])dnl +AC_REQUIRE([_LT_PROG_ECHO_BACKSLASH])dnl + +_LT_DECL([], [PATH_SEPARATOR], [1], [The PATH separator for the build system])dnl +dnl +_LT_DECL([], [host_alias], [0], [The host system])dnl +_LT_DECL([], [host], [0])dnl +_LT_DECL([], [host_os], [0])dnl +dnl +_LT_DECL([], [build_alias], [0], [The build system])dnl +_LT_DECL([], [build], [0])dnl +_LT_DECL([], [build_os], [0])dnl +dnl +AC_REQUIRE([AC_PROG_CC])dnl +AC_REQUIRE([LT_PATH_LD])dnl +AC_REQUIRE([LT_PATH_NM])dnl +dnl +AC_REQUIRE([AC_PROG_LN_S])dnl +test -z "$LN_S" && LN_S="ln -s" +_LT_DECL([], [LN_S], [1], [Whether we need soft or hard links])dnl +dnl +AC_REQUIRE([LT_CMD_MAX_LEN])dnl +_LT_DECL([objext], [ac_objext], [0], [Object file suffix (normally "o")])dnl +_LT_DECL([], [exeext], [0], [Executable file suffix (normally "")])dnl +dnl +m4_require([_LT_FILEUTILS_DEFAULTS])dnl +m4_require([_LT_CHECK_SHELL_FEATURES])dnl +m4_require([_LT_PATH_CONVERSION_FUNCTIONS])dnl +m4_require([_LT_CMD_RELOAD])dnl +m4_require([_LT_CHECK_MAGIC_METHOD])dnl +m4_require([_LT_CHECK_SHAREDLIB_FROM_LINKLIB])dnl +m4_require([_LT_CMD_OLD_ARCHIVE])dnl +m4_require([_LT_CMD_GLOBAL_SYMBOLS])dnl +m4_require([_LT_WITH_SYSROOT])dnl + +_LT_CONFIG_LIBTOOL_INIT([ +# See if we are running on zsh, and set the options which allow our +# commands through without removal of \ escapes INIT. +if test -n "\${ZSH_VERSION+set}" ; then + setopt NO_GLOB_SUBST +fi +]) +if test -n "${ZSH_VERSION+set}" ; then + setopt NO_GLOB_SUBST +fi + +_LT_CHECK_OBJDIR + +m4_require([_LT_TAG_COMPILER])dnl + +case $host_os in +aix3*) + # AIX sometimes has problems with the GCC collect2 program. For some + # reason, if we set the COLLECT_NAMES environment variable, the problems + # vanish in a puff of smoke. + if test "X${COLLECT_NAMES+set}" != Xset; then + COLLECT_NAMES= + export COLLECT_NAMES + fi + ;; +esac + +# Global variables: +ofile=libtool +can_build_shared=yes + +# All known linkers require a `.a' archive for static linking (except MSVC, +# which needs '.lib'). +libext=a + +with_gnu_ld="$lt_cv_prog_gnu_ld" + +old_CC="$CC" +old_CFLAGS="$CFLAGS" + +# Set sane defaults for various variables +test -z "$CC" && CC=cc +test -z "$LTCC" && LTCC=$CC +test -z "$LTCFLAGS" && LTCFLAGS=$CFLAGS +test -z "$LD" && LD=ld +test -z "$ac_objext" && ac_objext=o + +_LT_CC_BASENAME([$compiler]) + +# Only perform the check for file, if the check method requires it +test -z "$MAGIC_CMD" && MAGIC_CMD=file +case $deplibs_check_method in +file_magic*) + if test "$file_magic_cmd" = '$MAGIC_CMD'; then + _LT_PATH_MAGIC + fi + ;; +esac + +# Use C for the default configuration in the libtool script +LT_SUPPORTED_TAG([CC]) +_LT_LANG_C_CONFIG +_LT_LANG_DEFAULT_CONFIG +_LT_CONFIG_COMMANDS +])# _LT_SETUP + + +# _LT_PREPARE_SED_QUOTE_VARS +# -------------------------- +# Define a few sed substitution that help us do robust quoting. +m4_defun([_LT_PREPARE_SED_QUOTE_VARS], +[# Backslashify metacharacters that are still active within +# double-quoted strings. +sed_quote_subst='s/\([["`$\\]]\)/\\\1/g' + +# Same as above, but do not quote variable references. +double_quote_subst='s/\([["`\\]]\)/\\\1/g' + +# Sed substitution to delay expansion of an escaped shell variable in a +# double_quote_subst'ed string. +delay_variable_subst='s/\\\\\\\\\\\$/\\\\\\$/g' + +# Sed substitution to delay expansion of an escaped single quote. +delay_single_quote_subst='s/'\''/'\'\\\\\\\'\''/g' + +# Sed substitution to avoid accidental globbing in evaled expressions +no_glob_subst='s/\*/\\\*/g' +]) + +# _LT_PROG_LTMAIN +# --------------- +# Note that this code is called both from `configure', and `config.status' +# now that we use AC_CONFIG_COMMANDS to generate libtool. Notably, +# `config.status' has no value for ac_aux_dir unless we are using Automake, +# so we pass a copy along to make sure it has a sensible value anyway. +m4_defun([_LT_PROG_LTMAIN], +[m4_ifdef([AC_REQUIRE_AUX_FILE], [AC_REQUIRE_AUX_FILE([ltmain.sh])])dnl +_LT_CONFIG_LIBTOOL_INIT([ac_aux_dir='$ac_aux_dir']) +ltmain="$ac_aux_dir/ltmain.sh" +])# _LT_PROG_LTMAIN + + +## ------------------------------------- ## +## Accumulate code for creating libtool. ## +## ------------------------------------- ## + +# So that we can recreate a full libtool script including additional +# tags, we accumulate the chunks of code to send to AC_CONFIG_COMMANDS +# in macros and then make a single call at the end using the `libtool' +# label. + + +# _LT_CONFIG_LIBTOOL_INIT([INIT-COMMANDS]) +# ---------------------------------------- +# Register INIT-COMMANDS to be passed to AC_CONFIG_COMMANDS later. +m4_define([_LT_CONFIG_LIBTOOL_INIT], +[m4_ifval([$1], + [m4_append([_LT_OUTPUT_LIBTOOL_INIT], + [$1 +])])]) + +# Initialize. +m4_define([_LT_OUTPUT_LIBTOOL_INIT]) + + +# _LT_CONFIG_LIBTOOL([COMMANDS]) +# ------------------------------ +# Register COMMANDS to be passed to AC_CONFIG_COMMANDS later. +m4_define([_LT_CONFIG_LIBTOOL], +[m4_ifval([$1], + [m4_append([_LT_OUTPUT_LIBTOOL_COMMANDS], + [$1 +])])]) + +# Initialize. +m4_define([_LT_OUTPUT_LIBTOOL_COMMANDS]) + + +# _LT_CONFIG_SAVE_COMMANDS([COMMANDS], [INIT_COMMANDS]) +# ----------------------------------------------------- +m4_defun([_LT_CONFIG_SAVE_COMMANDS], +[_LT_CONFIG_LIBTOOL([$1]) +_LT_CONFIG_LIBTOOL_INIT([$2]) +]) + + +# _LT_FORMAT_COMMENT([COMMENT]) +# ----------------------------- +# Add leading comment marks to the start of each line, and a trailing +# full-stop to the whole comment if one is not present already. +m4_define([_LT_FORMAT_COMMENT], +[m4_ifval([$1], [ +m4_bpatsubst([m4_bpatsubst([$1], [^ *], [# ])], + [['`$\]], [\\\&])]m4_bmatch([$1], [[!?.]$], [], [.]) +)]) + + + +## ------------------------ ## +## FIXME: Eliminate VARNAME ## +## ------------------------ ## + + +# _LT_DECL([CONFIGNAME], VARNAME, VALUE, [DESCRIPTION], [IS-TAGGED?]) +# ------------------------------------------------------------------- +# CONFIGNAME is the name given to the value in the libtool script. +# VARNAME is the (base) name used in the configure script. +# VALUE may be 0, 1 or 2 for a computed quote escaped value based on +# VARNAME. Any other value will be used directly. +m4_define([_LT_DECL], +[lt_if_append_uniq([lt_decl_varnames], [$2], [, ], + [lt_dict_add_subkey([lt_decl_dict], [$2], [libtool_name], + [m4_ifval([$1], [$1], [$2])]) + lt_dict_add_subkey([lt_decl_dict], [$2], [value], [$3]) + m4_ifval([$4], + [lt_dict_add_subkey([lt_decl_dict], [$2], [description], [$4])]) + lt_dict_add_subkey([lt_decl_dict], [$2], + [tagged?], [m4_ifval([$5], [yes], [no])])]) +]) + + +# _LT_TAGDECL([CONFIGNAME], VARNAME, VALUE, [DESCRIPTION]) +# -------------------------------------------------------- +m4_define([_LT_TAGDECL], [_LT_DECL([$1], [$2], [$3], [$4], [yes])]) + + +# lt_decl_tag_varnames([SEPARATOR], [VARNAME1...]) +# ------------------------------------------------ +m4_define([lt_decl_tag_varnames], +[_lt_decl_filter([tagged?], [yes], $@)]) + + +# _lt_decl_filter(SUBKEY, VALUE, [SEPARATOR], [VARNAME1..]) +# --------------------------------------------------------- +m4_define([_lt_decl_filter], +[m4_case([$#], + [0], [m4_fatal([$0: too few arguments: $#])], + [1], [m4_fatal([$0: too few arguments: $#: $1])], + [2], [lt_dict_filter([lt_decl_dict], [$1], [$2], [], lt_decl_varnames)], + [3], [lt_dict_filter([lt_decl_dict], [$1], [$2], [$3], lt_decl_varnames)], + [lt_dict_filter([lt_decl_dict], $@)])[]dnl +]) + + +# lt_decl_quote_varnames([SEPARATOR], [VARNAME1...]) +# -------------------------------------------------- +m4_define([lt_decl_quote_varnames], +[_lt_decl_filter([value], [1], $@)]) + + +# lt_decl_dquote_varnames([SEPARATOR], [VARNAME1...]) +# --------------------------------------------------- +m4_define([lt_decl_dquote_varnames], +[_lt_decl_filter([value], [2], $@)]) + + +# lt_decl_varnames_tagged([SEPARATOR], [VARNAME1...]) +# --------------------------------------------------- +m4_define([lt_decl_varnames_tagged], +[m4_assert([$# <= 2])dnl +_$0(m4_quote(m4_default([$1], [[, ]])), + m4_ifval([$2], [[$2]], [m4_dquote(lt_decl_tag_varnames)]), + m4_split(m4_normalize(m4_quote(_LT_TAGS)), [ ]))]) +m4_define([_lt_decl_varnames_tagged], +[m4_ifval([$3], [lt_combine([$1], [$2], [_], $3)])]) + + +# lt_decl_all_varnames([SEPARATOR], [VARNAME1...]) +# ------------------------------------------------ +m4_define([lt_decl_all_varnames], +[_$0(m4_quote(m4_default([$1], [[, ]])), + m4_if([$2], [], + m4_quote(lt_decl_varnames), + m4_quote(m4_shift($@))))[]dnl +]) +m4_define([_lt_decl_all_varnames], +[lt_join($@, lt_decl_varnames_tagged([$1], + lt_decl_tag_varnames([[, ]], m4_shift($@))))dnl +]) + + +# _LT_CONFIG_STATUS_DECLARE([VARNAME]) +# ------------------------------------ +# Quote a variable value, and forward it to `config.status' so that its +# declaration there will have the same value as in `configure'. VARNAME +# must have a single quote delimited value for this to work. +m4_define([_LT_CONFIG_STATUS_DECLARE], +[$1='`$ECHO "$][$1" | $SED "$delay_single_quote_subst"`']) + + +# _LT_CONFIG_STATUS_DECLARATIONS +# ------------------------------ +# We delimit libtool config variables with single quotes, so when +# we write them to config.status, we have to be sure to quote all +# embedded single quotes properly. In configure, this macro expands +# each variable declared with _LT_DECL (and _LT_TAGDECL) into: +# +# ='`$ECHO "$" | $SED "$delay_single_quote_subst"`' +m4_defun([_LT_CONFIG_STATUS_DECLARATIONS], +[m4_foreach([_lt_var], m4_quote(lt_decl_all_varnames), + [m4_n([_LT_CONFIG_STATUS_DECLARE(_lt_var)])])]) + + +# _LT_LIBTOOL_TAGS +# ---------------- +# Output comment and list of tags supported by the script +m4_defun([_LT_LIBTOOL_TAGS], +[_LT_FORMAT_COMMENT([The names of the tagged configurations supported by this script])dnl +available_tags="_LT_TAGS"dnl +]) + + +# _LT_LIBTOOL_DECLARE(VARNAME, [TAG]) +# ----------------------------------- +# Extract the dictionary values for VARNAME (optionally with TAG) and +# expand to a commented shell variable setting: +# +# # Some comment about what VAR is for. +# visible_name=$lt_internal_name +m4_define([_LT_LIBTOOL_DECLARE], +[_LT_FORMAT_COMMENT(m4_quote(lt_dict_fetch([lt_decl_dict], [$1], + [description])))[]dnl +m4_pushdef([_libtool_name], + m4_quote(lt_dict_fetch([lt_decl_dict], [$1], [libtool_name])))[]dnl +m4_case(m4_quote(lt_dict_fetch([lt_decl_dict], [$1], [value])), + [0], [_libtool_name=[$]$1], + [1], [_libtool_name=$lt_[]$1], + [2], [_libtool_name=$lt_[]$1], + [_libtool_name=lt_dict_fetch([lt_decl_dict], [$1], [value])])[]dnl +m4_ifval([$2], [_$2])[]m4_popdef([_libtool_name])[]dnl +]) + + +# _LT_LIBTOOL_CONFIG_VARS +# ----------------------- +# Produce commented declarations of non-tagged libtool config variables +# suitable for insertion in the LIBTOOL CONFIG section of the `libtool' +# script. Tagged libtool config variables (even for the LIBTOOL CONFIG +# section) are produced by _LT_LIBTOOL_TAG_VARS. +m4_defun([_LT_LIBTOOL_CONFIG_VARS], +[m4_foreach([_lt_var], + m4_quote(_lt_decl_filter([tagged?], [no], [], lt_decl_varnames)), + [m4_n([_LT_LIBTOOL_DECLARE(_lt_var)])])]) + + +# _LT_LIBTOOL_TAG_VARS(TAG) +# ------------------------- +m4_define([_LT_LIBTOOL_TAG_VARS], +[m4_foreach([_lt_var], m4_quote(lt_decl_tag_varnames), + [m4_n([_LT_LIBTOOL_DECLARE(_lt_var, [$1])])])]) + + +# _LT_TAGVAR(VARNAME, [TAGNAME]) +# ------------------------------ +m4_define([_LT_TAGVAR], [m4_ifval([$2], [$1_$2], [$1])]) + + +# _LT_CONFIG_COMMANDS +# ------------------- +# Send accumulated output to $CONFIG_STATUS. Thanks to the lists of +# variables for single and double quote escaping we saved from calls +# to _LT_DECL, we can put quote escaped variables declarations +# into `config.status', and then the shell code to quote escape them in +# for loops in `config.status'. Finally, any additional code accumulated +# from calls to _LT_CONFIG_LIBTOOL_INIT is expanded. +m4_defun([_LT_CONFIG_COMMANDS], +[AC_PROVIDE_IFELSE([LT_OUTPUT], + dnl If the libtool generation code has been placed in $CONFIG_LT, + dnl instead of duplicating it all over again into config.status, + dnl then we will have config.status run $CONFIG_LT later, so it + dnl needs to know what name is stored there: + [AC_CONFIG_COMMANDS([libtool], + [$SHELL $CONFIG_LT || AS_EXIT(1)], [CONFIG_LT='$CONFIG_LT'])], + dnl If the libtool generation code is destined for config.status, + dnl expand the accumulated commands and init code now: + [AC_CONFIG_COMMANDS([libtool], + [_LT_OUTPUT_LIBTOOL_COMMANDS], [_LT_OUTPUT_LIBTOOL_COMMANDS_INIT])]) +])#_LT_CONFIG_COMMANDS + + +# Initialize. +m4_define([_LT_OUTPUT_LIBTOOL_COMMANDS_INIT], +[ + +# The HP-UX ksh and POSIX shell print the target directory to stdout +# if CDPATH is set. +(unset CDPATH) >/dev/null 2>&1 && unset CDPATH + +sed_quote_subst='$sed_quote_subst' +double_quote_subst='$double_quote_subst' +delay_variable_subst='$delay_variable_subst' +_LT_CONFIG_STATUS_DECLARATIONS +LTCC='$LTCC' +LTCFLAGS='$LTCFLAGS' +compiler='$compiler_DEFAULT' + +# A function that is used when there is no print builtin or printf. +func_fallback_echo () +{ + eval 'cat <<_LTECHO_EOF +\$[]1 +_LTECHO_EOF' +} + +# Quote evaled strings. +for var in lt_decl_all_varnames([[ \ +]], lt_decl_quote_varnames); do + case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in + *[[\\\\\\\`\\"\\\$]]*) + eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED \\"\\\$sed_quote_subst\\"\\\`\\\\\\"" + ;; + *) + eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\"" + ;; + esac +done + +# Double-quote double-evaled strings. +for var in lt_decl_all_varnames([[ \ +]], lt_decl_dquote_varnames); do + case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in + *[[\\\\\\\`\\"\\\$]]*) + eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED -e \\"\\\$double_quote_subst\\" -e \\"\\\$sed_quote_subst\\" -e \\"\\\$delay_variable_subst\\"\\\`\\\\\\"" + ;; + *) + eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\"" + ;; + esac +done + +_LT_OUTPUT_LIBTOOL_INIT +]) + +# _LT_GENERATED_FILE_INIT(FILE, [COMMENT]) +# ------------------------------------ +# Generate a child script FILE with all initialization necessary to +# reuse the environment learned by the parent script, and make the +# file executable. If COMMENT is supplied, it is inserted after the +# `#!' sequence but before initialization text begins. After this +# macro, additional text can be appended to FILE to form the body of +# the child script. The macro ends with non-zero status if the +# file could not be fully written (such as if the disk is full). +m4_ifdef([AS_INIT_GENERATED], +[m4_defun([_LT_GENERATED_FILE_INIT],[AS_INIT_GENERATED($@)])], +[m4_defun([_LT_GENERATED_FILE_INIT], +[m4_require([AS_PREPARE])]dnl +[m4_pushdef([AS_MESSAGE_LOG_FD])]dnl +[lt_write_fail=0 +cat >$1 <<_ASEOF || lt_write_fail=1 +#! $SHELL +# Generated by $as_me. +$2 +SHELL=\${CONFIG_SHELL-$SHELL} +export SHELL +_ASEOF +cat >>$1 <<\_ASEOF || lt_write_fail=1 +AS_SHELL_SANITIZE +_AS_PREPARE +exec AS_MESSAGE_FD>&1 +_ASEOF +test $lt_write_fail = 0 && chmod +x $1[]dnl +m4_popdef([AS_MESSAGE_LOG_FD])])])# _LT_GENERATED_FILE_INIT + +# LT_OUTPUT +# --------- +# This macro allows early generation of the libtool script (before +# AC_OUTPUT is called), incase it is used in configure for compilation +# tests. +AC_DEFUN([LT_OUTPUT], +[: ${CONFIG_LT=./config.lt} +AC_MSG_NOTICE([creating $CONFIG_LT]) +_LT_GENERATED_FILE_INIT(["$CONFIG_LT"], +[# Run this file to recreate a libtool stub with the current configuration.]) + +cat >>"$CONFIG_LT" <<\_LTEOF +lt_cl_silent=false +exec AS_MESSAGE_LOG_FD>>config.log +{ + echo + AS_BOX([Running $as_me.]) +} >&AS_MESSAGE_LOG_FD + +lt_cl_help="\ +\`$as_me' creates a local libtool stub from the current configuration, +for use in further configure time tests before the real libtool is +generated. + +Usage: $[0] [[OPTIONS]] + + -h, --help print this help, then exit + -V, --version print version number, then exit + -q, --quiet do not print progress messages + -d, --debug don't remove temporary files + +Report bugs to ." + +lt_cl_version="\ +m4_ifset([AC_PACKAGE_NAME], [AC_PACKAGE_NAME ])config.lt[]dnl +m4_ifset([AC_PACKAGE_VERSION], [ AC_PACKAGE_VERSION]) +configured by $[0], generated by m4_PACKAGE_STRING. + +Copyright (C) 2011 Free Software Foundation, Inc. +This config.lt script is free software; the Free Software Foundation +gives unlimited permision to copy, distribute and modify it." + +while test $[#] != 0 +do + case $[1] in + --version | --v* | -V ) + echo "$lt_cl_version"; exit 0 ;; + --help | --h* | -h ) + echo "$lt_cl_help"; exit 0 ;; + --debug | --d* | -d ) + debug=: ;; + --quiet | --q* | --silent | --s* | -q ) + lt_cl_silent=: ;; + + -*) AC_MSG_ERROR([unrecognized option: $[1] +Try \`$[0] --help' for more information.]) ;; + + *) AC_MSG_ERROR([unrecognized argument: $[1] +Try \`$[0] --help' for more information.]) ;; + esac + shift +done + +if $lt_cl_silent; then + exec AS_MESSAGE_FD>/dev/null +fi +_LTEOF + +cat >>"$CONFIG_LT" <<_LTEOF +_LT_OUTPUT_LIBTOOL_COMMANDS_INIT +_LTEOF + +cat >>"$CONFIG_LT" <<\_LTEOF +AC_MSG_NOTICE([creating $ofile]) +_LT_OUTPUT_LIBTOOL_COMMANDS +AS_EXIT(0) +_LTEOF +chmod +x "$CONFIG_LT" + +# configure is writing to config.log, but config.lt does its own redirection, +# appending to config.log, which fails on DOS, as config.log is still kept +# open by configure. Here we exec the FD to /dev/null, effectively closing +# config.log, so it can be properly (re)opened and appended to by config.lt. +lt_cl_success=: +test "$silent" = yes && + lt_config_lt_args="$lt_config_lt_args --quiet" +exec AS_MESSAGE_LOG_FD>/dev/null +$SHELL "$CONFIG_LT" $lt_config_lt_args || lt_cl_success=false +exec AS_MESSAGE_LOG_FD>>config.log +$lt_cl_success || AS_EXIT(1) +])# LT_OUTPUT + + +# _LT_CONFIG(TAG) +# --------------- +# If TAG is the built-in tag, create an initial libtool script with a +# default configuration from the untagged config vars. Otherwise add code +# to config.status for appending the configuration named by TAG from the +# matching tagged config vars. +m4_defun([_LT_CONFIG], +[m4_require([_LT_FILEUTILS_DEFAULTS])dnl +_LT_CONFIG_SAVE_COMMANDS([ + m4_define([_LT_TAG], m4_if([$1], [], [C], [$1]))dnl + m4_if(_LT_TAG, [C], [ + # See if we are running on zsh, and set the options which allow our + # commands through without removal of \ escapes. + if test -n "${ZSH_VERSION+set}" ; then + setopt NO_GLOB_SUBST + fi + + cfgfile="${ofile}T" + trap "$RM \"$cfgfile\"; exit 1" 1 2 15 + $RM "$cfgfile" + + cat <<_LT_EOF >> "$cfgfile" +#! $SHELL + +# `$ECHO "$ofile" | sed 's%^.*/%%'` - Provide generalized library-building support services. +# Generated automatically by $as_me ($PACKAGE$TIMESTAMP) $VERSION +# Libtool was configured on host `(hostname || uname -n) 2>/dev/null | sed 1q`: +# NOTE: Changes made to this file will be lost: look at ltmain.sh. +# +_LT_COPYING +_LT_LIBTOOL_TAGS + +# ### BEGIN LIBTOOL CONFIG +_LT_LIBTOOL_CONFIG_VARS +_LT_LIBTOOL_TAG_VARS +# ### END LIBTOOL CONFIG + +_LT_EOF + + case $host_os in + aix3*) + cat <<\_LT_EOF >> "$cfgfile" +# AIX sometimes has problems with the GCC collect2 program. For some +# reason, if we set the COLLECT_NAMES environment variable, the problems +# vanish in a puff of smoke. +if test "X${COLLECT_NAMES+set}" != Xset; then + COLLECT_NAMES= + export COLLECT_NAMES +fi +_LT_EOF + ;; + esac + + _LT_PROG_LTMAIN + + # We use sed instead of cat because bash on DJGPP gets confused if + # if finds mixed CR/LF and LF-only lines. Since sed operates in + # text mode, it properly converts lines to CR/LF. This bash problem + # is reportedly fixed, but why not run on old versions too? + sed '$q' "$ltmain" >> "$cfgfile" \ + || (rm -f "$cfgfile"; exit 1) + + _LT_PROG_REPLACE_SHELLFNS + + mv -f "$cfgfile" "$ofile" || + (rm -f "$ofile" && cp "$cfgfile" "$ofile" && rm -f "$cfgfile") + chmod +x "$ofile" +], +[cat <<_LT_EOF >> "$ofile" + +dnl Unfortunately we have to use $1 here, since _LT_TAG is not expanded +dnl in a comment (ie after a #). +# ### BEGIN LIBTOOL TAG CONFIG: $1 +_LT_LIBTOOL_TAG_VARS(_LT_TAG) +# ### END LIBTOOL TAG CONFIG: $1 +_LT_EOF +])dnl /m4_if +], +[m4_if([$1], [], [ + PACKAGE='$PACKAGE' + VERSION='$VERSION' + TIMESTAMP='$TIMESTAMP' + RM='$RM' + ofile='$ofile'], []) +])dnl /_LT_CONFIG_SAVE_COMMANDS +])# _LT_CONFIG + + +# LT_SUPPORTED_TAG(TAG) +# --------------------- +# Trace this macro to discover what tags are supported by the libtool +# --tag option, using: +# autoconf --trace 'LT_SUPPORTED_TAG:$1' +AC_DEFUN([LT_SUPPORTED_TAG], []) + + +# C support is built-in for now +m4_define([_LT_LANG_C_enabled], []) +m4_define([_LT_TAGS], []) + + +# LT_LANG(LANG) +# ------------- +# Enable libtool support for the given language if not already enabled. +AC_DEFUN([LT_LANG], +[AC_BEFORE([$0], [LT_OUTPUT])dnl +m4_case([$1], + [C], [_LT_LANG(C)], + [C++], [_LT_LANG(CXX)], + [Go], [_LT_LANG(GO)], + [Java], [_LT_LANG(GCJ)], + [Fortran 77], [_LT_LANG(F77)], + [Fortran], [_LT_LANG(FC)], + [Windows Resource], [_LT_LANG(RC)], + [m4_ifdef([_LT_LANG_]$1[_CONFIG], + [_LT_LANG($1)], + [m4_fatal([$0: unsupported language: "$1"])])])dnl +])# LT_LANG + + +# _LT_LANG(LANGNAME) +# ------------------ +m4_defun([_LT_LANG], +[m4_ifdef([_LT_LANG_]$1[_enabled], [], + [LT_SUPPORTED_TAG([$1])dnl + m4_append([_LT_TAGS], [$1 ])dnl + m4_define([_LT_LANG_]$1[_enabled], [])dnl + _LT_LANG_$1_CONFIG($1)])dnl +])# _LT_LANG + + +m4_ifndef([AC_PROG_GO], [ +############################################################ +# NOTE: This macro has been submitted for inclusion into # +# GNU Autoconf as AC_PROG_GO. When it is available in # +# a released version of Autoconf we should remove this # +# macro and use it instead. # +############################################################ +m4_defun([AC_PROG_GO], +[AC_LANG_PUSH(Go)dnl +AC_ARG_VAR([GOC], [Go compiler command])dnl +AC_ARG_VAR([GOFLAGS], [Go compiler flags])dnl +_AC_ARG_VAR_LDFLAGS()dnl +AC_CHECK_TOOL(GOC, gccgo) +if test -z "$GOC"; then + if test -n "$ac_tool_prefix"; then + AC_CHECK_PROG(GOC, [${ac_tool_prefix}gccgo], [${ac_tool_prefix}gccgo]) + fi +fi +if test -z "$GOC"; then + AC_CHECK_PROG(GOC, gccgo, gccgo, false) +fi +])#m4_defun +])#m4_ifndef + + +# _LT_LANG_DEFAULT_CONFIG +# ----------------------- +m4_defun([_LT_LANG_DEFAULT_CONFIG], +[AC_PROVIDE_IFELSE([AC_PROG_CXX], + [LT_LANG(CXX)], + [m4_define([AC_PROG_CXX], defn([AC_PROG_CXX])[LT_LANG(CXX)])]) + +AC_PROVIDE_IFELSE([AC_PROG_F77], + [LT_LANG(F77)], + [m4_define([AC_PROG_F77], defn([AC_PROG_F77])[LT_LANG(F77)])]) + +AC_PROVIDE_IFELSE([AC_PROG_FC], + [LT_LANG(FC)], + [m4_define([AC_PROG_FC], defn([AC_PROG_FC])[LT_LANG(FC)])]) + +dnl The call to [A][M_PROG_GCJ] is quoted like that to stop aclocal +dnl pulling things in needlessly. +AC_PROVIDE_IFELSE([AC_PROG_GCJ], + [LT_LANG(GCJ)], + [AC_PROVIDE_IFELSE([A][M_PROG_GCJ], + [LT_LANG(GCJ)], + [AC_PROVIDE_IFELSE([LT_PROG_GCJ], + [LT_LANG(GCJ)], + [m4_ifdef([AC_PROG_GCJ], + [m4_define([AC_PROG_GCJ], defn([AC_PROG_GCJ])[LT_LANG(GCJ)])]) + m4_ifdef([A][M_PROG_GCJ], + [m4_define([A][M_PROG_GCJ], defn([A][M_PROG_GCJ])[LT_LANG(GCJ)])]) + m4_ifdef([LT_PROG_GCJ], + [m4_define([LT_PROG_GCJ], defn([LT_PROG_GCJ])[LT_LANG(GCJ)])])])])]) + +AC_PROVIDE_IFELSE([AC_PROG_GO], + [LT_LANG(GO)], + [m4_define([AC_PROG_GO], defn([AC_PROG_GO])[LT_LANG(GO)])]) + +AC_PROVIDE_IFELSE([LT_PROG_RC], + [LT_LANG(RC)], + [m4_define([LT_PROG_RC], defn([LT_PROG_RC])[LT_LANG(RC)])]) +])# _LT_LANG_DEFAULT_CONFIG + +# Obsolete macros: +AU_DEFUN([AC_LIBTOOL_CXX], [LT_LANG(C++)]) +AU_DEFUN([AC_LIBTOOL_F77], [LT_LANG(Fortran 77)]) +AU_DEFUN([AC_LIBTOOL_FC], [LT_LANG(Fortran)]) +AU_DEFUN([AC_LIBTOOL_GCJ], [LT_LANG(Java)]) +AU_DEFUN([AC_LIBTOOL_RC], [LT_LANG(Windows Resource)]) +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AC_LIBTOOL_CXX], []) +dnl AC_DEFUN([AC_LIBTOOL_F77], []) +dnl AC_DEFUN([AC_LIBTOOL_FC], []) +dnl AC_DEFUN([AC_LIBTOOL_GCJ], []) +dnl AC_DEFUN([AC_LIBTOOL_RC], []) + + +# _LT_TAG_COMPILER +# ---------------- +m4_defun([_LT_TAG_COMPILER], +[AC_REQUIRE([AC_PROG_CC])dnl + +_LT_DECL([LTCC], [CC], [1], [A C compiler])dnl +_LT_DECL([LTCFLAGS], [CFLAGS], [1], [LTCC compiler flags])dnl +_LT_TAGDECL([CC], [compiler], [1], [A language specific compiler])dnl +_LT_TAGDECL([with_gcc], [GCC], [0], [Is the compiler the GNU compiler?])dnl + +# If no C compiler was specified, use CC. +LTCC=${LTCC-"$CC"} + +# If no C compiler flags were specified, use CFLAGS. +LTCFLAGS=${LTCFLAGS-"$CFLAGS"} + +# Allow CC to be a program name with arguments. +compiler=$CC +])# _LT_TAG_COMPILER + + +# _LT_COMPILER_BOILERPLATE +# ------------------------ +# Check for compiler boilerplate output or warnings with +# the simple compiler test code. +m4_defun([_LT_COMPILER_BOILERPLATE], +[m4_require([_LT_DECL_SED])dnl +ac_outfile=conftest.$ac_objext +echo "$lt_simple_compile_test_code" >conftest.$ac_ext +eval "$ac_compile" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err +_lt_compiler_boilerplate=`cat conftest.err` +$RM conftest* +])# _LT_COMPILER_BOILERPLATE + + +# _LT_LINKER_BOILERPLATE +# ---------------------- +# Check for linker boilerplate output or warnings with +# the simple link test code. +m4_defun([_LT_LINKER_BOILERPLATE], +[m4_require([_LT_DECL_SED])dnl +ac_outfile=conftest.$ac_objext +echo "$lt_simple_link_test_code" >conftest.$ac_ext +eval "$ac_link" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err +_lt_linker_boilerplate=`cat conftest.err` +$RM -r conftest* +])# _LT_LINKER_BOILERPLATE + +# _LT_REQUIRED_DARWIN_CHECKS +# ------------------------- +m4_defun_once([_LT_REQUIRED_DARWIN_CHECKS],[ + case $host_os in + rhapsody* | darwin*) + AC_CHECK_TOOL([DSYMUTIL], [dsymutil], [:]) + AC_CHECK_TOOL([NMEDIT], [nmedit], [:]) + AC_CHECK_TOOL([LIPO], [lipo], [:]) + AC_CHECK_TOOL([OTOOL], [otool], [:]) + AC_CHECK_TOOL([OTOOL64], [otool64], [:]) + _LT_DECL([], [DSYMUTIL], [1], + [Tool to manipulate archived DWARF debug symbol files on Mac OS X]) + _LT_DECL([], [NMEDIT], [1], + [Tool to change global to local symbols on Mac OS X]) + _LT_DECL([], [LIPO], [1], + [Tool to manipulate fat objects and archives on Mac OS X]) + _LT_DECL([], [OTOOL], [1], + [ldd/readelf like tool for Mach-O binaries on Mac OS X]) + _LT_DECL([], [OTOOL64], [1], + [ldd/readelf like tool for 64 bit Mach-O binaries on Mac OS X 10.4]) + + AC_CACHE_CHECK([for -single_module linker flag],[lt_cv_apple_cc_single_mod], + [lt_cv_apple_cc_single_mod=no + if test -z "${LT_MULTI_MODULE}"; then + # By default we will add the -single_module flag. You can override + # by either setting the environment variable LT_MULTI_MODULE + # non-empty at configure time, or by adding -multi_module to the + # link flags. + rm -rf libconftest.dylib* + echo "int foo(void){return 1;}" > conftest.c + echo "$LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \ +-dynamiclib -Wl,-single_module conftest.c" >&AS_MESSAGE_LOG_FD + $LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \ + -dynamiclib -Wl,-single_module conftest.c 2>conftest.err + _lt_result=$? + # If there is a non-empty error log, and "single_module" + # appears in it, assume the flag caused a linker warning + if test -s conftest.err && $GREP single_module conftest.err; then + cat conftest.err >&AS_MESSAGE_LOG_FD + # Otherwise, if the output was created with a 0 exit code from + # the compiler, it worked. + elif test -f libconftest.dylib && test $_lt_result -eq 0; then + lt_cv_apple_cc_single_mod=yes + else + cat conftest.err >&AS_MESSAGE_LOG_FD + fi + rm -rf libconftest.dylib* + rm -f conftest.* + fi]) + + AC_CACHE_CHECK([for -exported_symbols_list linker flag], + [lt_cv_ld_exported_symbols_list], + [lt_cv_ld_exported_symbols_list=no + save_LDFLAGS=$LDFLAGS + echo "_main" > conftest.sym + LDFLAGS="$LDFLAGS -Wl,-exported_symbols_list,conftest.sym" + AC_LINK_IFELSE([AC_LANG_PROGRAM([],[])], + [lt_cv_ld_exported_symbols_list=yes], + [lt_cv_ld_exported_symbols_list=no]) + LDFLAGS="$save_LDFLAGS" + ]) + + AC_CACHE_CHECK([for -force_load linker flag],[lt_cv_ld_force_load], + [lt_cv_ld_force_load=no + cat > conftest.c << _LT_EOF +int forced_loaded() { return 2;} +_LT_EOF + echo "$LTCC $LTCFLAGS -c -o conftest.o conftest.c" >&AS_MESSAGE_LOG_FD + $LTCC $LTCFLAGS -c -o conftest.o conftest.c 2>&AS_MESSAGE_LOG_FD + echo "$AR cru libconftest.a conftest.o" >&AS_MESSAGE_LOG_FD + $AR cru libconftest.a conftest.o 2>&AS_MESSAGE_LOG_FD + echo "$RANLIB libconftest.a" >&AS_MESSAGE_LOG_FD + $RANLIB libconftest.a 2>&AS_MESSAGE_LOG_FD + cat > conftest.c << _LT_EOF +int main() { return 0;} +_LT_EOF + echo "$LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a" >&AS_MESSAGE_LOG_FD + $LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a 2>conftest.err + _lt_result=$? + if test -s conftest.err && $GREP force_load conftest.err; then + cat conftest.err >&AS_MESSAGE_LOG_FD + elif test -f conftest && test $_lt_result -eq 0 && $GREP forced_load conftest >/dev/null 2>&1 ; then + lt_cv_ld_force_load=yes + else + cat conftest.err >&AS_MESSAGE_LOG_FD + fi + rm -f conftest.err libconftest.a conftest conftest.c + rm -rf conftest.dSYM + ]) + case $host_os in + rhapsody* | darwin1.[[012]]) + _lt_dar_allow_undefined='${wl}-undefined ${wl}suppress' ;; + darwin1.*) + _lt_dar_allow_undefined='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' ;; + darwin*) # darwin 5.x on + # if running on 10.5 or later, the deployment target defaults + # to the OS version, if on x86, and 10.4, the deployment + # target defaults to 10.4. Don't you love it? + case ${MACOSX_DEPLOYMENT_TARGET-10.0},$host in + 10.0,*86*-darwin8*|10.0,*-darwin[[91]]*) + _lt_dar_allow_undefined='${wl}-undefined ${wl}dynamic_lookup' ;; + 10.[[012]]*) + _lt_dar_allow_undefined='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' ;; + 10.*) + _lt_dar_allow_undefined='${wl}-undefined ${wl}dynamic_lookup' ;; + esac + ;; + esac + if test "$lt_cv_apple_cc_single_mod" = "yes"; then + _lt_dar_single_mod='$single_module' + fi + if test "$lt_cv_ld_exported_symbols_list" = "yes"; then + _lt_dar_export_syms=' ${wl}-exported_symbols_list,$output_objdir/${libname}-symbols.expsym' + else + _lt_dar_export_syms='~$NMEDIT -s $output_objdir/${libname}-symbols.expsym ${lib}' + fi + if test "$DSYMUTIL" != ":" && test "$lt_cv_ld_force_load" = "no"; then + _lt_dsymutil='~$DSYMUTIL $lib || :' + else + _lt_dsymutil= + fi + ;; + esac +]) + + +# _LT_DARWIN_LINKER_FEATURES([TAG]) +# --------------------------------- +# Checks for linker and compiler features on darwin +m4_defun([_LT_DARWIN_LINKER_FEATURES], +[ + m4_require([_LT_REQUIRED_DARWIN_CHECKS]) + _LT_TAGVAR(archive_cmds_need_lc, $1)=no + _LT_TAGVAR(hardcode_direct, $1)=no + _LT_TAGVAR(hardcode_automatic, $1)=yes + _LT_TAGVAR(hardcode_shlibpath_var, $1)=unsupported + if test "$lt_cv_ld_force_load" = "yes"; then + _LT_TAGVAR(whole_archive_flag_spec, $1)='`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience ${wl}-force_load,$conv\"; done; func_echo_all \"$new_convenience\"`' + m4_case([$1], [F77], [_LT_TAGVAR(compiler_needs_object, $1)=yes], + [FC], [_LT_TAGVAR(compiler_needs_object, $1)=yes]) + else + _LT_TAGVAR(whole_archive_flag_spec, $1)='' + fi + _LT_TAGVAR(link_all_deplibs, $1)=yes + _LT_TAGVAR(allow_undefined_flag, $1)="$_lt_dar_allow_undefined" + case $cc_basename in + ifort*) _lt_dar_can_shared=yes ;; + *) _lt_dar_can_shared=$GCC ;; + esac + if test "$_lt_dar_can_shared" = "yes"; then + output_verbose_link_cmd=func_echo_all + _LT_TAGVAR(archive_cmds, $1)="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod${_lt_dsymutil}" + _LT_TAGVAR(module_cmds, $1)="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dsymutil}" + _LT_TAGVAR(archive_expsym_cmds, $1)="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring ${_lt_dar_single_mod}${_lt_dar_export_syms}${_lt_dsymutil}" + _LT_TAGVAR(module_expsym_cmds, $1)="sed -e 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dar_export_syms}${_lt_dsymutil}" + m4_if([$1], [CXX], +[ if test "$lt_cv_apple_cc_single_mod" != "yes"; then + _LT_TAGVAR(archive_cmds, $1)="\$CC -r -keep_private_externs -nostdlib -o \${lib}-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \${lib}-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring${_lt_dsymutil}" + _LT_TAGVAR(archive_expsym_cmds, $1)="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -r -keep_private_externs -nostdlib -o \${lib}-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \${lib}-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring${_lt_dar_export_syms}${_lt_dsymutil}" + fi +],[]) + else + _LT_TAGVAR(ld_shlibs, $1)=no + fi +]) + +# _LT_SYS_MODULE_PATH_AIX([TAGNAME]) +# ---------------------------------- +# Links a minimal program and checks the executable +# for the system default hardcoded library path. In most cases, +# this is /usr/lib:/lib, but when the MPI compilers are used +# the location of the communication and MPI libs are included too. +# If we don't find anything, use the default library path according +# to the aix ld manual. +# Store the results from the different compilers for each TAGNAME. +# Allow to override them for all tags through lt_cv_aix_libpath. +m4_defun([_LT_SYS_MODULE_PATH_AIX], +[m4_require([_LT_DECL_SED])dnl +if test "${lt_cv_aix_libpath+set}" = set; then + aix_libpath=$lt_cv_aix_libpath +else + AC_CACHE_VAL([_LT_TAGVAR([lt_cv_aix_libpath_], [$1])], + [AC_LINK_IFELSE([AC_LANG_PROGRAM],[ + lt_aix_libpath_sed='[ + /Import File Strings/,/^$/ { + /^0/ { + s/^0 *\([^ ]*\) *$/\1/ + p + } + }]' + _LT_TAGVAR([lt_cv_aix_libpath_], [$1])=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` + # Check for a 64-bit object if we didn't find anything. + if test -z "$_LT_TAGVAR([lt_cv_aix_libpath_], [$1])"; then + _LT_TAGVAR([lt_cv_aix_libpath_], [$1])=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` + fi],[]) + if test -z "$_LT_TAGVAR([lt_cv_aix_libpath_], [$1])"; then + _LT_TAGVAR([lt_cv_aix_libpath_], [$1])="/usr/lib:/lib" + fi + ]) + aix_libpath=$_LT_TAGVAR([lt_cv_aix_libpath_], [$1]) +fi +])# _LT_SYS_MODULE_PATH_AIX + + +# _LT_SHELL_INIT(ARG) +# ------------------- +m4_define([_LT_SHELL_INIT], +[m4_divert_text([M4SH-INIT], [$1 +])])# _LT_SHELL_INIT + + + +# _LT_PROG_ECHO_BACKSLASH +# ----------------------- +# Find how we can fake an echo command that does not interpret backslash. +# In particular, with Autoconf 2.60 or later we add some code to the start +# of the generated configure script which will find a shell with a builtin +# printf (which we can use as an echo command). +m4_defun([_LT_PROG_ECHO_BACKSLASH], +[ECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' +ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO +ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO$ECHO + +AC_MSG_CHECKING([how to print strings]) +# Test print first, because it will be a builtin if present. +if test "X`( print -r -- -n ) 2>/dev/null`" = X-n && \ + test "X`print -r -- $ECHO 2>/dev/null`" = "X$ECHO"; then + ECHO='print -r --' +elif test "X`printf %s $ECHO 2>/dev/null`" = "X$ECHO"; then + ECHO='printf %s\n' +else + # Use this function as a fallback that always works. + func_fallback_echo () + { + eval 'cat <<_LTECHO_EOF +$[]1 +_LTECHO_EOF' + } + ECHO='func_fallback_echo' +fi + +# func_echo_all arg... +# Invoke $ECHO with all args, space-separated. +func_echo_all () +{ + $ECHO "$*" +} + +case "$ECHO" in + printf*) AC_MSG_RESULT([printf]) ;; + print*) AC_MSG_RESULT([print -r]) ;; + *) AC_MSG_RESULT([cat]) ;; +esac + +m4_ifdef([_AS_DETECT_SUGGESTED], +[_AS_DETECT_SUGGESTED([ + test -n "${ZSH_VERSION+set}${BASH_VERSION+set}" || ( + ECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' + ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO + ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO$ECHO + PATH=/empty FPATH=/empty; export PATH FPATH + test "X`printf %s $ECHO`" = "X$ECHO" \ + || test "X`print -r -- $ECHO`" = "X$ECHO" )])]) + +_LT_DECL([], [SHELL], [1], [Shell to use when invoking shell scripts]) +_LT_DECL([], [ECHO], [1], [An echo program that protects backslashes]) +])# _LT_PROG_ECHO_BACKSLASH + + +# _LT_WITH_SYSROOT +# ---------------- +AC_DEFUN([_LT_WITH_SYSROOT], +[AC_MSG_CHECKING([for sysroot]) +AC_ARG_WITH([sysroot], +[ --with-sysroot[=DIR] Search for dependent libraries within DIR + (or the compiler's sysroot if not specified).], +[], [with_sysroot=no]) + +dnl lt_sysroot will always be passed unquoted. We quote it here +dnl in case the user passed a directory name. +lt_sysroot= +case ${with_sysroot} in #( + yes) + if test "$GCC" = yes; then + lt_sysroot=`$CC --print-sysroot 2>/dev/null` + fi + ;; #( + /*) + lt_sysroot=`echo "$with_sysroot" | sed -e "$sed_quote_subst"` + ;; #( + no|'') + ;; #( + *) + AC_MSG_RESULT([${with_sysroot}]) + AC_MSG_ERROR([The sysroot must be an absolute path.]) + ;; +esac + + AC_MSG_RESULT([${lt_sysroot:-no}]) +_LT_DECL([], [lt_sysroot], [0], [The root where to search for ]dnl +[dependent libraries, and in which our libraries should be installed.])]) + +# _LT_ENABLE_LOCK +# --------------- +m4_defun([_LT_ENABLE_LOCK], +[AC_ARG_ENABLE([libtool-lock], + [AS_HELP_STRING([--disable-libtool-lock], + [avoid locking (might break parallel builds)])]) +test "x$enable_libtool_lock" != xno && enable_libtool_lock=yes + +# Some flags need to be propagated to the compiler or linker for good +# libtool support. +case $host in +ia64-*-hpux*) + # Find out which ABI we are using. + echo 'int i;' > conftest.$ac_ext + if AC_TRY_EVAL(ac_compile); then + case `/usr/bin/file conftest.$ac_objext` in + *ELF-32*) + HPUX_IA64_MODE="32" + ;; + *ELF-64*) + HPUX_IA64_MODE="64" + ;; + esac + fi + rm -rf conftest* + ;; +*-*-irix6*) + # Find out which ABI we are using. + echo '[#]line '$LINENO' "configure"' > conftest.$ac_ext + if AC_TRY_EVAL(ac_compile); then + if test "$lt_cv_prog_gnu_ld" = yes; then + case `/usr/bin/file conftest.$ac_objext` in + *32-bit*) + LD="${LD-ld} -melf32bsmip" + ;; + *N32*) + LD="${LD-ld} -melf32bmipn32" + ;; + *64-bit*) + LD="${LD-ld} -melf64bmip" + ;; + esac + else + case `/usr/bin/file conftest.$ac_objext` in + *32-bit*) + LD="${LD-ld} -32" + ;; + *N32*) + LD="${LD-ld} -n32" + ;; + *64-bit*) + LD="${LD-ld} -64" + ;; + esac + fi + fi + rm -rf conftest* + ;; + +x86_64-*kfreebsd*-gnu|x86_64-*linux*|ppc*-*linux*|powerpc*-*linux*| \ +s390*-*linux*|s390*-*tpf*|sparc*-*linux*) + # Find out which ABI we are using. + echo 'int i;' > conftest.$ac_ext + if AC_TRY_EVAL(ac_compile); then + case `/usr/bin/file conftest.o` in + *32-bit*) + case $host in + x86_64-*kfreebsd*-gnu) + LD="${LD-ld} -m elf_i386_fbsd" + ;; + x86_64-*linux*) + LD="${LD-ld} -m elf_i386" + ;; + ppc64-*linux*|powerpc64-*linux*) + LD="${LD-ld} -m elf32ppclinux" + ;; + s390x-*linux*) + LD="${LD-ld} -m elf_s390" + ;; + sparc64-*linux*) + LD="${LD-ld} -m elf32_sparc" + ;; + esac + ;; + *64-bit*) + case $host in + x86_64-*kfreebsd*-gnu) + LD="${LD-ld} -m elf_x86_64_fbsd" + ;; + x86_64-*linux*) + LD="${LD-ld} -m elf_x86_64" + ;; + ppc*-*linux*|powerpc*-*linux*) + LD="${LD-ld} -m elf64ppc" + ;; + s390*-*linux*|s390*-*tpf*) + LD="${LD-ld} -m elf64_s390" + ;; + sparc*-*linux*) + LD="${LD-ld} -m elf64_sparc" + ;; + esac + ;; + esac + fi + rm -rf conftest* + ;; + +*-*-sco3.2v5*) + # On SCO OpenServer 5, we need -belf to get full-featured binaries. + SAVE_CFLAGS="$CFLAGS" + CFLAGS="$CFLAGS -belf" + AC_CACHE_CHECK([whether the C compiler needs -belf], lt_cv_cc_needs_belf, + [AC_LANG_PUSH(C) + AC_LINK_IFELSE([AC_LANG_PROGRAM([[]],[[]])],[lt_cv_cc_needs_belf=yes],[lt_cv_cc_needs_belf=no]) + AC_LANG_POP]) + if test x"$lt_cv_cc_needs_belf" != x"yes"; then + # this is probably gcc 2.8.0, egcs 1.0 or newer; no need for -belf + CFLAGS="$SAVE_CFLAGS" + fi + ;; +*-*solaris*) + # Find out which ABI we are using. + echo 'int i;' > conftest.$ac_ext + if AC_TRY_EVAL(ac_compile); then + case `/usr/bin/file conftest.o` in + *64-bit*) + case $lt_cv_prog_gnu_ld in + yes*) + case $host in + i?86-*-solaris*) + LD="${LD-ld} -m elf_x86_64" + ;; + sparc*-*-solaris*) + LD="${LD-ld} -m elf64_sparc" + ;; + esac + # GNU ld 2.21 introduced _sol2 emulations. Use them if available. + if ${LD-ld} -V | grep _sol2 >/dev/null 2>&1; then + LD="${LD-ld}_sol2" + fi + ;; + *) + if ${LD-ld} -64 -r -o conftest2.o conftest.o >/dev/null 2>&1; then + LD="${LD-ld} -64" + fi + ;; + esac + ;; + esac + fi + rm -rf conftest* + ;; +esac + +need_locks="$enable_libtool_lock" +])# _LT_ENABLE_LOCK + + +# _LT_PROG_AR +# ----------- +m4_defun([_LT_PROG_AR], +[AC_CHECK_TOOLS(AR, [ar], false) +: ${AR=ar} +: ${AR_FLAGS=cru} +_LT_DECL([], [AR], [1], [The archiver]) +_LT_DECL([], [AR_FLAGS], [1], [Flags to create an archive]) + +AC_CACHE_CHECK([for archiver @FILE support], [lt_cv_ar_at_file], + [lt_cv_ar_at_file=no + AC_COMPILE_IFELSE([AC_LANG_PROGRAM], + [echo conftest.$ac_objext > conftest.lst + lt_ar_try='$AR $AR_FLAGS libconftest.a @conftest.lst >&AS_MESSAGE_LOG_FD' + AC_TRY_EVAL([lt_ar_try]) + if test "$ac_status" -eq 0; then + # Ensure the archiver fails upon bogus file names. + rm -f conftest.$ac_objext libconftest.a + AC_TRY_EVAL([lt_ar_try]) + if test "$ac_status" -ne 0; then + lt_cv_ar_at_file=@ + fi + fi + rm -f conftest.* libconftest.a + ]) + ]) + +if test "x$lt_cv_ar_at_file" = xno; then + archiver_list_spec= +else + archiver_list_spec=$lt_cv_ar_at_file +fi +_LT_DECL([], [archiver_list_spec], [1], + [How to feed a file listing to the archiver]) +])# _LT_PROG_AR + + +# _LT_CMD_OLD_ARCHIVE +# ------------------- +m4_defun([_LT_CMD_OLD_ARCHIVE], +[_LT_PROG_AR + +AC_CHECK_TOOL(STRIP, strip, :) +test -z "$STRIP" && STRIP=: +_LT_DECL([], [STRIP], [1], [A symbol stripping program]) + +AC_CHECK_TOOL(RANLIB, ranlib, :) +test -z "$RANLIB" && RANLIB=: +_LT_DECL([], [RANLIB], [1], + [Commands used to install an old-style archive]) + +# Determine commands to create old-style static archives. +old_archive_cmds='$AR $AR_FLAGS $oldlib$oldobjs' +old_postinstall_cmds='chmod 644 $oldlib' +old_postuninstall_cmds= + +if test -n "$RANLIB"; then + case $host_os in + openbsd*) + old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB -t \$tool_oldlib" + ;; + *) + old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB \$tool_oldlib" + ;; + esac + old_archive_cmds="$old_archive_cmds~\$RANLIB \$tool_oldlib" +fi + +case $host_os in + darwin*) + lock_old_archive_extraction=yes ;; + *) + lock_old_archive_extraction=no ;; +esac +_LT_DECL([], [old_postinstall_cmds], [2]) +_LT_DECL([], [old_postuninstall_cmds], [2]) +_LT_TAGDECL([], [old_archive_cmds], [2], + [Commands used to build an old-style archive]) +_LT_DECL([], [lock_old_archive_extraction], [0], + [Whether to use a lock for old archive extraction]) +])# _LT_CMD_OLD_ARCHIVE + + +# _LT_COMPILER_OPTION(MESSAGE, VARIABLE-NAME, FLAGS, +# [OUTPUT-FILE], [ACTION-SUCCESS], [ACTION-FAILURE]) +# ---------------------------------------------------------------- +# Check whether the given compiler option works +AC_DEFUN([_LT_COMPILER_OPTION], +[m4_require([_LT_FILEUTILS_DEFAULTS])dnl +m4_require([_LT_DECL_SED])dnl +AC_CACHE_CHECK([$1], [$2], + [$2=no + m4_if([$4], , [ac_outfile=conftest.$ac_objext], [ac_outfile=$4]) + echo "$lt_simple_compile_test_code" > conftest.$ac_ext + lt_compiler_flag="$3" + # Insert the option either (1) after the last *FLAGS variable, or + # (2) before a word containing "conftest.", or (3) at the end. + # Note that $ac_compile itself does not contain backslashes and begins + # with a dollar sign (not a hyphen), so the echo should work correctly. + # The option is referenced via a variable to avoid confusing sed. + lt_compile=`echo "$ac_compile" | $SED \ + -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ + -e 's: [[^ ]]*conftest\.: $lt_compiler_flag&:; t' \ + -e 's:$: $lt_compiler_flag:'` + (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&AS_MESSAGE_LOG_FD) + (eval "$lt_compile" 2>conftest.err) + ac_status=$? + cat conftest.err >&AS_MESSAGE_LOG_FD + echo "$as_me:$LINENO: \$? = $ac_status" >&AS_MESSAGE_LOG_FD + if (exit $ac_status) && test -s "$ac_outfile"; then + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings other than the usual output. + $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' >conftest.exp + $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 + if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then + $2=yes + fi + fi + $RM conftest* +]) + +if test x"[$]$2" = xyes; then + m4_if([$5], , :, [$5]) +else + m4_if([$6], , :, [$6]) +fi +])# _LT_COMPILER_OPTION + +# Old name: +AU_ALIAS([AC_LIBTOOL_COMPILER_OPTION], [_LT_COMPILER_OPTION]) +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AC_LIBTOOL_COMPILER_OPTION], []) + + +# _LT_LINKER_OPTION(MESSAGE, VARIABLE-NAME, FLAGS, +# [ACTION-SUCCESS], [ACTION-FAILURE]) +# ---------------------------------------------------- +# Check whether the given linker option works +AC_DEFUN([_LT_LINKER_OPTION], +[m4_require([_LT_FILEUTILS_DEFAULTS])dnl +m4_require([_LT_DECL_SED])dnl +AC_CACHE_CHECK([$1], [$2], + [$2=no + save_LDFLAGS="$LDFLAGS" + LDFLAGS="$LDFLAGS $3" + echo "$lt_simple_link_test_code" > conftest.$ac_ext + if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then + # The linker can only warn and ignore the option if not recognized + # So say no if there are warnings + if test -s conftest.err; then + # Append any errors to the config.log. + cat conftest.err 1>&AS_MESSAGE_LOG_FD + $ECHO "$_lt_linker_boilerplate" | $SED '/^$/d' > conftest.exp + $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 + if diff conftest.exp conftest.er2 >/dev/null; then + $2=yes + fi + else + $2=yes + fi + fi + $RM -r conftest* + LDFLAGS="$save_LDFLAGS" +]) + +if test x"[$]$2" = xyes; then + m4_if([$4], , :, [$4]) +else + m4_if([$5], , :, [$5]) +fi +])# _LT_LINKER_OPTION + +# Old name: +AU_ALIAS([AC_LIBTOOL_LINKER_OPTION], [_LT_LINKER_OPTION]) +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AC_LIBTOOL_LINKER_OPTION], []) + + +# LT_CMD_MAX_LEN +#--------------- +AC_DEFUN([LT_CMD_MAX_LEN], +[AC_REQUIRE([AC_CANONICAL_HOST])dnl +# find the maximum length of command line arguments +AC_MSG_CHECKING([the maximum length of command line arguments]) +AC_CACHE_VAL([lt_cv_sys_max_cmd_len], [dnl + i=0 + teststring="ABCD" + + case $build_os in + msdosdjgpp*) + # On DJGPP, this test can blow up pretty badly due to problems in libc + # (any single argument exceeding 2000 bytes causes a buffer overrun + # during glob expansion). Even if it were fixed, the result of this + # check would be larger than it should be. + lt_cv_sys_max_cmd_len=12288; # 12K is about right + ;; + + gnu*) + # Under GNU Hurd, this test is not required because there is + # no limit to the length of command line arguments. + # Libtool will interpret -1 as no limit whatsoever + lt_cv_sys_max_cmd_len=-1; + ;; + + cygwin* | mingw* | cegcc*) + # On Win9x/ME, this test blows up -- it succeeds, but takes + # about 5 minutes as the teststring grows exponentially. + # Worse, since 9x/ME are not pre-emptively multitasking, + # you end up with a "frozen" computer, even though with patience + # the test eventually succeeds (with a max line length of 256k). + # Instead, let's just punt: use the minimum linelength reported by + # all of the supported platforms: 8192 (on NT/2K/XP). + lt_cv_sys_max_cmd_len=8192; + ;; + + mint*) + # On MiNT this can take a long time and run out of memory. + lt_cv_sys_max_cmd_len=8192; + ;; + + amigaos*) + # On AmigaOS with pdksh, this test takes hours, literally. + # So we just punt and use a minimum line length of 8192. + lt_cv_sys_max_cmd_len=8192; + ;; + + netbsd* | freebsd* | openbsd* | darwin* | dragonfly*) + # This has been around since 386BSD, at least. Likely further. + if test -x /sbin/sysctl; then + lt_cv_sys_max_cmd_len=`/sbin/sysctl -n kern.argmax` + elif test -x /usr/sbin/sysctl; then + lt_cv_sys_max_cmd_len=`/usr/sbin/sysctl -n kern.argmax` + else + lt_cv_sys_max_cmd_len=65536 # usable default for all BSDs + fi + # And add a safety zone + lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4` + lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3` + ;; + + interix*) + # We know the value 262144 and hardcode it with a safety zone (like BSD) + lt_cv_sys_max_cmd_len=196608 + ;; + + os2*) + # The test takes a long time on OS/2. + lt_cv_sys_max_cmd_len=8192 + ;; + + osf*) + # Dr. Hans Ekkehard Plesser reports seeing a kernel panic running configure + # due to this test when exec_disable_arg_limit is 1 on Tru64. It is not + # nice to cause kernel panics so lets avoid the loop below. + # First set a reasonable default. + lt_cv_sys_max_cmd_len=16384 + # + if test -x /sbin/sysconfig; then + case `/sbin/sysconfig -q proc exec_disable_arg_limit` in + *1*) lt_cv_sys_max_cmd_len=-1 ;; + esac + fi + ;; + sco3.2v5*) + lt_cv_sys_max_cmd_len=102400 + ;; + sysv5* | sco5v6* | sysv4.2uw2*) + kargmax=`grep ARG_MAX /etc/conf/cf.d/stune 2>/dev/null` + if test -n "$kargmax"; then + lt_cv_sys_max_cmd_len=`echo $kargmax | sed 's/.*[[ ]]//'` + else + lt_cv_sys_max_cmd_len=32768 + fi + ;; + *) + lt_cv_sys_max_cmd_len=`(getconf ARG_MAX) 2> /dev/null` + if test -n "$lt_cv_sys_max_cmd_len"; then + lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4` + lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3` + else + # Make teststring a little bigger before we do anything with it. + # a 1K string should be a reasonable start. + for i in 1 2 3 4 5 6 7 8 ; do + teststring=$teststring$teststring + done + SHELL=${SHELL-${CONFIG_SHELL-/bin/sh}} + # If test is not a shell built-in, we'll probably end up computing a + # maximum length that is only half of the actual maximum length, but + # we can't tell. + while { test "X"`env echo "$teststring$teststring" 2>/dev/null` \ + = "X$teststring$teststring"; } >/dev/null 2>&1 && + test $i != 17 # 1/2 MB should be enough + do + i=`expr $i + 1` + teststring=$teststring$teststring + done + # Only check the string length outside the loop. + lt_cv_sys_max_cmd_len=`expr "X$teststring" : ".*" 2>&1` + teststring= + # Add a significant safety factor because C++ compilers can tack on + # massive amounts of additional arguments before passing them to the + # linker. It appears as though 1/2 is a usable value. + lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 2` + fi + ;; + esac +]) +if test -n $lt_cv_sys_max_cmd_len ; then + AC_MSG_RESULT($lt_cv_sys_max_cmd_len) +else + AC_MSG_RESULT(none) +fi +max_cmd_len=$lt_cv_sys_max_cmd_len +_LT_DECL([], [max_cmd_len], [0], + [What is the maximum length of a command?]) +])# LT_CMD_MAX_LEN + +# Old name: +AU_ALIAS([AC_LIBTOOL_SYS_MAX_CMD_LEN], [LT_CMD_MAX_LEN]) +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AC_LIBTOOL_SYS_MAX_CMD_LEN], []) + + +# _LT_HEADER_DLFCN +# ---------------- +m4_defun([_LT_HEADER_DLFCN], +[AC_CHECK_HEADERS([dlfcn.h], [], [], [AC_INCLUDES_DEFAULT])dnl +])# _LT_HEADER_DLFCN + + +# _LT_TRY_DLOPEN_SELF (ACTION-IF-TRUE, ACTION-IF-TRUE-W-USCORE, +# ACTION-IF-FALSE, ACTION-IF-CROSS-COMPILING) +# ---------------------------------------------------------------- +m4_defun([_LT_TRY_DLOPEN_SELF], +[m4_require([_LT_HEADER_DLFCN])dnl +if test "$cross_compiling" = yes; then : + [$4] +else + lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 + lt_status=$lt_dlunknown + cat > conftest.$ac_ext <<_LT_EOF +[#line $LINENO "configure" +#include "confdefs.h" + +#if HAVE_DLFCN_H +#include +#endif + +#include + +#ifdef RTLD_GLOBAL +# define LT_DLGLOBAL RTLD_GLOBAL +#else +# ifdef DL_GLOBAL +# define LT_DLGLOBAL DL_GLOBAL +# else +# define LT_DLGLOBAL 0 +# endif +#endif + +/* We may have to define LT_DLLAZY_OR_NOW in the command line if we + find out it does not work in some platform. */ +#ifndef LT_DLLAZY_OR_NOW +# ifdef RTLD_LAZY +# define LT_DLLAZY_OR_NOW RTLD_LAZY +# else +# ifdef DL_LAZY +# define LT_DLLAZY_OR_NOW DL_LAZY +# else +# ifdef RTLD_NOW +# define LT_DLLAZY_OR_NOW RTLD_NOW +# else +# ifdef DL_NOW +# define LT_DLLAZY_OR_NOW DL_NOW +# else +# define LT_DLLAZY_OR_NOW 0 +# endif +# endif +# endif +# endif +#endif + +/* When -fvisbility=hidden is used, assume the code has been annotated + correspondingly for the symbols needed. */ +#if defined(__GNUC__) && (((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 3)) +int fnord () __attribute__((visibility("default"))); +#endif + +int fnord () { return 42; } +int main () +{ + void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW); + int status = $lt_dlunknown; + + if (self) + { + if (dlsym (self,"fnord")) status = $lt_dlno_uscore; + else + { + if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore; + else puts (dlerror ()); + } + /* dlclose (self); */ + } + else + puts (dlerror ()); + + return status; +}] +_LT_EOF + if AC_TRY_EVAL(ac_link) && test -s conftest${ac_exeext} 2>/dev/null; then + (./conftest; exit; ) >&AS_MESSAGE_LOG_FD 2>/dev/null + lt_status=$? + case x$lt_status in + x$lt_dlno_uscore) $1 ;; + x$lt_dlneed_uscore) $2 ;; + x$lt_dlunknown|x*) $3 ;; + esac + else : + # compilation failed + $3 + fi +fi +rm -fr conftest* +])# _LT_TRY_DLOPEN_SELF + + +# LT_SYS_DLOPEN_SELF +# ------------------ +AC_DEFUN([LT_SYS_DLOPEN_SELF], +[m4_require([_LT_HEADER_DLFCN])dnl +if test "x$enable_dlopen" != xyes; then + enable_dlopen=unknown + enable_dlopen_self=unknown + enable_dlopen_self_static=unknown +else + lt_cv_dlopen=no + lt_cv_dlopen_libs= + + case $host_os in + beos*) + lt_cv_dlopen="load_add_on" + lt_cv_dlopen_libs= + lt_cv_dlopen_self=yes + ;; + + mingw* | pw32* | cegcc*) + lt_cv_dlopen="LoadLibrary" + lt_cv_dlopen_libs= + ;; + + cygwin*) + lt_cv_dlopen="dlopen" + lt_cv_dlopen_libs= + ;; + + darwin*) + # if libdl is installed we need to link against it + AC_CHECK_LIB([dl], [dlopen], + [lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl"],[ + lt_cv_dlopen="dyld" + lt_cv_dlopen_libs= + lt_cv_dlopen_self=yes + ]) + ;; + + *) + AC_CHECK_FUNC([shl_load], + [lt_cv_dlopen="shl_load"], + [AC_CHECK_LIB([dld], [shl_load], + [lt_cv_dlopen="shl_load" lt_cv_dlopen_libs="-ldld"], + [AC_CHECK_FUNC([dlopen], + [lt_cv_dlopen="dlopen"], + [AC_CHECK_LIB([dl], [dlopen], + [lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl"], + [AC_CHECK_LIB([svld], [dlopen], + [lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-lsvld"], + [AC_CHECK_LIB([dld], [dld_link], + [lt_cv_dlopen="dld_link" lt_cv_dlopen_libs="-ldld"]) + ]) + ]) + ]) + ]) + ]) + ;; + esac + + if test "x$lt_cv_dlopen" != xno; then + enable_dlopen=yes + else + enable_dlopen=no + fi + + case $lt_cv_dlopen in + dlopen) + save_CPPFLAGS="$CPPFLAGS" + test "x$ac_cv_header_dlfcn_h" = xyes && CPPFLAGS="$CPPFLAGS -DHAVE_DLFCN_H" + + save_LDFLAGS="$LDFLAGS" + wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $export_dynamic_flag_spec\" + + save_LIBS="$LIBS" + LIBS="$lt_cv_dlopen_libs $LIBS" + + AC_CACHE_CHECK([whether a program can dlopen itself], + lt_cv_dlopen_self, [dnl + _LT_TRY_DLOPEN_SELF( + lt_cv_dlopen_self=yes, lt_cv_dlopen_self=yes, + lt_cv_dlopen_self=no, lt_cv_dlopen_self=cross) + ]) + + if test "x$lt_cv_dlopen_self" = xyes; then + wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $lt_prog_compiler_static\" + AC_CACHE_CHECK([whether a statically linked program can dlopen itself], + lt_cv_dlopen_self_static, [dnl + _LT_TRY_DLOPEN_SELF( + lt_cv_dlopen_self_static=yes, lt_cv_dlopen_self_static=yes, + lt_cv_dlopen_self_static=no, lt_cv_dlopen_self_static=cross) + ]) + fi + + CPPFLAGS="$save_CPPFLAGS" + LDFLAGS="$save_LDFLAGS" + LIBS="$save_LIBS" + ;; + esac + + case $lt_cv_dlopen_self in + yes|no) enable_dlopen_self=$lt_cv_dlopen_self ;; + *) enable_dlopen_self=unknown ;; + esac + + case $lt_cv_dlopen_self_static in + yes|no) enable_dlopen_self_static=$lt_cv_dlopen_self_static ;; + *) enable_dlopen_self_static=unknown ;; + esac +fi +_LT_DECL([dlopen_support], [enable_dlopen], [0], + [Whether dlopen is supported]) +_LT_DECL([dlopen_self], [enable_dlopen_self], [0], + [Whether dlopen of programs is supported]) +_LT_DECL([dlopen_self_static], [enable_dlopen_self_static], [0], + [Whether dlopen of statically linked programs is supported]) +])# LT_SYS_DLOPEN_SELF + +# Old name: +AU_ALIAS([AC_LIBTOOL_DLOPEN_SELF], [LT_SYS_DLOPEN_SELF]) +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AC_LIBTOOL_DLOPEN_SELF], []) + + +# _LT_COMPILER_C_O([TAGNAME]) +# --------------------------- +# Check to see if options -c and -o are simultaneously supported by compiler. +# This macro does not hard code the compiler like AC_PROG_CC_C_O. +m4_defun([_LT_COMPILER_C_O], +[m4_require([_LT_DECL_SED])dnl +m4_require([_LT_FILEUTILS_DEFAULTS])dnl +m4_require([_LT_TAG_COMPILER])dnl +AC_CACHE_CHECK([if $compiler supports -c -o file.$ac_objext], + [_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)], + [_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)=no + $RM -r conftest 2>/dev/null + mkdir conftest + cd conftest + mkdir out + echo "$lt_simple_compile_test_code" > conftest.$ac_ext + + lt_compiler_flag="-o out/conftest2.$ac_objext" + # Insert the option either (1) after the last *FLAGS variable, or + # (2) before a word containing "conftest.", or (3) at the end. + # Note that $ac_compile itself does not contain backslashes and begins + # with a dollar sign (not a hyphen), so the echo should work correctly. + lt_compile=`echo "$ac_compile" | $SED \ + -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ + -e 's: [[^ ]]*conftest\.: $lt_compiler_flag&:; t' \ + -e 's:$: $lt_compiler_flag:'` + (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&AS_MESSAGE_LOG_FD) + (eval "$lt_compile" 2>out/conftest.err) + ac_status=$? + cat out/conftest.err >&AS_MESSAGE_LOG_FD + echo "$as_me:$LINENO: \$? = $ac_status" >&AS_MESSAGE_LOG_FD + if (exit $ac_status) && test -s out/conftest2.$ac_objext + then + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings + $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' > out/conftest.exp + $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2 + if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then + _LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)=yes + fi + fi + chmod u+w . 2>&AS_MESSAGE_LOG_FD + $RM conftest* + # SGI C++ compiler will create directory out/ii_files/ for + # template instantiation + test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files + $RM out/* && rmdir out + cd .. + $RM -r conftest + $RM conftest* +]) +_LT_TAGDECL([compiler_c_o], [lt_cv_prog_compiler_c_o], [1], + [Does compiler simultaneously support -c and -o options?]) +])# _LT_COMPILER_C_O + + +# _LT_COMPILER_FILE_LOCKS([TAGNAME]) +# ---------------------------------- +# Check to see if we can do hard links to lock some files if needed +m4_defun([_LT_COMPILER_FILE_LOCKS], +[m4_require([_LT_ENABLE_LOCK])dnl +m4_require([_LT_FILEUTILS_DEFAULTS])dnl +_LT_COMPILER_C_O([$1]) + +hard_links="nottested" +if test "$_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)" = no && test "$need_locks" != no; then + # do not overwrite the value of need_locks provided by the user + AC_MSG_CHECKING([if we can lock with hard links]) + hard_links=yes + $RM conftest* + ln conftest.a conftest.b 2>/dev/null && hard_links=no + touch conftest.a + ln conftest.a conftest.b 2>&5 || hard_links=no + ln conftest.a conftest.b 2>/dev/null && hard_links=no + AC_MSG_RESULT([$hard_links]) + if test "$hard_links" = no; then + AC_MSG_WARN([`$CC' does not support `-c -o', so `make -j' may be unsafe]) + need_locks=warn + fi +else + need_locks=no +fi +_LT_DECL([], [need_locks], [1], [Must we lock files when doing compilation?]) +])# _LT_COMPILER_FILE_LOCKS + + +# _LT_CHECK_OBJDIR +# ---------------- +m4_defun([_LT_CHECK_OBJDIR], +[AC_CACHE_CHECK([for objdir], [lt_cv_objdir], +[rm -f .libs 2>/dev/null +mkdir .libs 2>/dev/null +if test -d .libs; then + lt_cv_objdir=.libs +else + # MS-DOS does not allow filenames that begin with a dot. + lt_cv_objdir=_libs +fi +rmdir .libs 2>/dev/null]) +objdir=$lt_cv_objdir +_LT_DECL([], [objdir], [0], + [The name of the directory that contains temporary libtool files])dnl +m4_pattern_allow([LT_OBJDIR])dnl +AC_DEFINE_UNQUOTED(LT_OBJDIR, "$lt_cv_objdir/", + [Define to the sub-directory in which libtool stores uninstalled libraries.]) +])# _LT_CHECK_OBJDIR + + +# _LT_LINKER_HARDCODE_LIBPATH([TAGNAME]) +# -------------------------------------- +# Check hardcoding attributes. +m4_defun([_LT_LINKER_HARDCODE_LIBPATH], +[AC_MSG_CHECKING([how to hardcode library paths into programs]) +_LT_TAGVAR(hardcode_action, $1)= +if test -n "$_LT_TAGVAR(hardcode_libdir_flag_spec, $1)" || + test -n "$_LT_TAGVAR(runpath_var, $1)" || + test "X$_LT_TAGVAR(hardcode_automatic, $1)" = "Xyes" ; then + + # We can hardcode non-existent directories. + if test "$_LT_TAGVAR(hardcode_direct, $1)" != no && + # If the only mechanism to avoid hardcoding is shlibpath_var, we + # have to relink, otherwise we might link with an installed library + # when we should be linking with a yet-to-be-installed one + ## test "$_LT_TAGVAR(hardcode_shlibpath_var, $1)" != no && + test "$_LT_TAGVAR(hardcode_minus_L, $1)" != no; then + # Linking always hardcodes the temporary library directory. + _LT_TAGVAR(hardcode_action, $1)=relink + else + # We can link without hardcoding, and we can hardcode nonexisting dirs. + _LT_TAGVAR(hardcode_action, $1)=immediate + fi +else + # We cannot hardcode anything, or else we can only hardcode existing + # directories. + _LT_TAGVAR(hardcode_action, $1)=unsupported +fi +AC_MSG_RESULT([$_LT_TAGVAR(hardcode_action, $1)]) + +if test "$_LT_TAGVAR(hardcode_action, $1)" = relink || + test "$_LT_TAGVAR(inherit_rpath, $1)" = yes; then + # Fast installation is not supported + enable_fast_install=no +elif test "$shlibpath_overrides_runpath" = yes || + test "$enable_shared" = no; then + # Fast installation is not necessary + enable_fast_install=needless +fi +_LT_TAGDECL([], [hardcode_action], [0], + [How to hardcode a shared library path into an executable]) +])# _LT_LINKER_HARDCODE_LIBPATH + + +# _LT_CMD_STRIPLIB +# ---------------- +m4_defun([_LT_CMD_STRIPLIB], +[m4_require([_LT_DECL_EGREP]) +striplib= +old_striplib= +AC_MSG_CHECKING([whether stripping libraries is possible]) +if test -n "$STRIP" && $STRIP -V 2>&1 | $GREP "GNU strip" >/dev/null; then + test -z "$old_striplib" && old_striplib="$STRIP --strip-debug" + test -z "$striplib" && striplib="$STRIP --strip-unneeded" + AC_MSG_RESULT([yes]) +else +# FIXME - insert some real tests, host_os isn't really good enough + case $host_os in + darwin*) + if test -n "$STRIP" ; then + striplib="$STRIP -x" + old_striplib="$STRIP -S" + AC_MSG_RESULT([yes]) + else + AC_MSG_RESULT([no]) + fi + ;; + *) + AC_MSG_RESULT([no]) + ;; + esac +fi +_LT_DECL([], [old_striplib], [1], [Commands to strip libraries]) +_LT_DECL([], [striplib], [1]) +])# _LT_CMD_STRIPLIB + + +# _LT_SYS_DYNAMIC_LINKER([TAG]) +# ----------------------------- +# PORTME Fill in your ld.so characteristics +m4_defun([_LT_SYS_DYNAMIC_LINKER], +[AC_REQUIRE([AC_CANONICAL_HOST])dnl +m4_require([_LT_DECL_EGREP])dnl +m4_require([_LT_FILEUTILS_DEFAULTS])dnl +m4_require([_LT_DECL_OBJDUMP])dnl +m4_require([_LT_DECL_SED])dnl +m4_require([_LT_CHECK_SHELL_FEATURES])dnl +AC_MSG_CHECKING([dynamic linker characteristics]) +m4_if([$1], + [], [ +if test "$GCC" = yes; then + case $host_os in + darwin*) lt_awk_arg="/^libraries:/,/LR/" ;; + *) lt_awk_arg="/^libraries:/" ;; + esac + case $host_os in + mingw* | cegcc*) lt_sed_strip_eq="s,=\([[A-Za-z]]:\),\1,g" ;; + *) lt_sed_strip_eq="s,=/,/,g" ;; + esac + lt_search_path_spec=`$CC -print-search-dirs | awk $lt_awk_arg | $SED -e "s/^libraries://" -e $lt_sed_strip_eq` + case $lt_search_path_spec in + *\;*) + # if the path contains ";" then we assume it to be the separator + # otherwise default to the standard path separator (i.e. ":") - it is + # assumed that no part of a normal pathname contains ";" but that should + # okay in the real world where ";" in dirpaths is itself problematic. + lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED 's/;/ /g'` + ;; + *) + lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED "s/$PATH_SEPARATOR/ /g"` + ;; + esac + # Ok, now we have the path, separated by spaces, we can step through it + # and add multilib dir if necessary. + lt_tmp_lt_search_path_spec= + lt_multi_os_dir=`$CC $CPPFLAGS $CFLAGS $LDFLAGS -print-multi-os-directory 2>/dev/null` + for lt_sys_path in $lt_search_path_spec; do + if test -d "$lt_sys_path/$lt_multi_os_dir"; then + lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path/$lt_multi_os_dir" + else + test -d "$lt_sys_path" && \ + lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path" + fi + done + lt_search_path_spec=`$ECHO "$lt_tmp_lt_search_path_spec" | awk ' +BEGIN {RS=" "; FS="/|\n";} { + lt_foo=""; + lt_count=0; + for (lt_i = NF; lt_i > 0; lt_i--) { + if ($lt_i != "" && $lt_i != ".") { + if ($lt_i == "..") { + lt_count++; + } else { + if (lt_count == 0) { + lt_foo="/" $lt_i lt_foo; + } else { + lt_count--; + } + } + } + } + if (lt_foo != "") { lt_freq[[lt_foo]]++; } + if (lt_freq[[lt_foo]] == 1) { print lt_foo; } +}'` + # AWK program above erroneously prepends '/' to C:/dos/paths + # for these hosts. + case $host_os in + mingw* | cegcc*) lt_search_path_spec=`$ECHO "$lt_search_path_spec" |\ + $SED 's,/\([[A-Za-z]]:\),\1,g'` ;; + esac + sys_lib_search_path_spec=`$ECHO "$lt_search_path_spec" | $lt_NL2SP` +else + sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib" +fi]) +library_names_spec= +libname_spec='lib$name' +soname_spec= +shrext_cmds=".so" +postinstall_cmds= +postuninstall_cmds= +finish_cmds= +finish_eval= +shlibpath_var= +shlibpath_overrides_runpath=unknown +version_type=none +dynamic_linker="$host_os ld.so" +sys_lib_dlsearch_path_spec="/lib /usr/lib" +need_lib_prefix=unknown +hardcode_into_libs=no + +# when you set need_version to no, make sure it does not cause -set_version +# flags to be left without arguments +need_version=unknown + +case $host_os in +aix3*) + version_type=linux # correct to gnu/linux during the next big refactor + library_names_spec='${libname}${release}${shared_ext}$versuffix $libname.a' + shlibpath_var=LIBPATH + + # AIX 3 has no versioning support, so we append a major version to the name. + soname_spec='${libname}${release}${shared_ext}$major' + ;; + +aix[[4-9]]*) + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + hardcode_into_libs=yes + if test "$host_cpu" = ia64; then + # AIX 5 supports IA64 + library_names_spec='${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext}$versuffix $libname${shared_ext}' + shlibpath_var=LD_LIBRARY_PATH + else + # With GCC up to 2.95.x, collect2 would create an import file + # for dependence libraries. The import file would start with + # the line `#! .'. This would cause the generated library to + # depend on `.', always an invalid library. This was fixed in + # development snapshots of GCC prior to 3.0. + case $host_os in + aix4 | aix4.[[01]] | aix4.[[01]].*) + if { echo '#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 97)' + echo ' yes ' + echo '#endif'; } | ${CC} -E - | $GREP yes > /dev/null; then + : + else + can_build_shared=no + fi + ;; + esac + # AIX (on Power*) has no versioning support, so currently we can not hardcode correct + # soname into executable. Probably we can add versioning support to + # collect2, so additional links can be useful in future. + if test "$aix_use_runtimelinking" = yes; then + # If using run time linking (on AIX 4.2 or later) use lib.so + # instead of lib.a to let people know that these are not + # typical AIX shared libraries. + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + else + # We preserve .a as extension for shared libraries through AIX4.2 + # and later when we are not doing run time linking. + library_names_spec='${libname}${release}.a $libname.a' + soname_spec='${libname}${release}${shared_ext}$major' + fi + shlibpath_var=LIBPATH + fi + ;; + +amigaos*) + case $host_cpu in + powerpc) + # Since July 2007 AmigaOS4 officially supports .so libraries. + # When compiling the executable, add -use-dynld -Lsobjs: to the compileline. + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + ;; + m68k) + library_names_spec='$libname.ixlibrary $libname.a' + # Create ${libname}_ixlibrary.a entries in /sys/libs. + finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`func_echo_all "$lib" | $SED '\''s%^.*/\([[^/]]*\)\.ixlibrary$%\1%'\''`; test $RM /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done' + ;; + esac + ;; + +beos*) + library_names_spec='${libname}${shared_ext}' + dynamic_linker="$host_os ld.so" + shlibpath_var=LIBRARY_PATH + ;; + +bsdi[[45]]*) + version_type=linux # correct to gnu/linux during the next big refactor + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir' + shlibpath_var=LD_LIBRARY_PATH + sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib" + sys_lib_dlsearch_path_spec="/shlib /usr/lib /usr/local/lib" + # the default ld.so.conf also contains /usr/contrib/lib and + # /usr/X11R6/lib (/usr/X11 is a link to /usr/X11R6), but let us allow + # libtool to hard-code these into programs + ;; + +cygwin* | mingw* | pw32* | cegcc*) + version_type=windows + shrext_cmds=".dll" + need_version=no + need_lib_prefix=no + + case $GCC,$cc_basename in + yes,*) + # gcc + library_names_spec='$libname.dll.a' + # DLL is installed to $(libdir)/../bin by postinstall_cmds + postinstall_cmds='base_file=`basename \${file}`~ + dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i; echo \$dlname'\''`~ + dldir=$destdir/`dirname \$dlpath`~ + test -d \$dldir || mkdir -p \$dldir~ + $install_prog $dir/$dlname \$dldir/$dlname~ + chmod a+x \$dldir/$dlname~ + if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then + eval '\''$striplib \$dldir/$dlname'\'' || exit \$?; + fi' + postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ + dlpath=$dir/\$dldll~ + $RM \$dlpath' + shlibpath_overrides_runpath=yes + + case $host_os in + cygwin*) + # Cygwin DLLs use 'cyg' prefix rather than 'lib' + soname_spec='`echo ${libname} | sed -e 's/^lib/cyg/'``echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext}' +m4_if([$1], [],[ + sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/lib/w32api"]) + ;; + mingw* | cegcc*) + # MinGW DLLs use traditional 'lib' prefix + soname_spec='${libname}`echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext}' + ;; + pw32*) + # pw32 DLLs use 'pw' prefix rather than 'lib' + library_names_spec='`echo ${libname} | sed -e 's/^lib/pw/'``echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext}' + ;; + esac + dynamic_linker='Win32 ld.exe' + ;; + + *,cl*) + # Native MSVC + libname_spec='$name' + soname_spec='${libname}`echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext}' + library_names_spec='${libname}.dll.lib' + + case $build_os in + mingw*) + sys_lib_search_path_spec= + lt_save_ifs=$IFS + IFS=';' + for lt_path in $LIB + do + IFS=$lt_save_ifs + # Let DOS variable expansion print the short 8.3 style file name. + lt_path=`cd "$lt_path" 2>/dev/null && cmd //C "for %i in (".") do @echo %~si"` + sys_lib_search_path_spec="$sys_lib_search_path_spec $lt_path" + done + IFS=$lt_save_ifs + # Convert to MSYS style. + sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | sed -e 's|\\\\|/|g' -e 's| \\([[a-zA-Z]]\\):| /\\1|g' -e 's|^ ||'` + ;; + cygwin*) + # Convert to unix form, then to dos form, then back to unix form + # but this time dos style (no spaces!) so that the unix form looks + # like /cygdrive/c/PROGRA~1:/cygdr... + sys_lib_search_path_spec=`cygpath --path --unix "$LIB"` + sys_lib_search_path_spec=`cygpath --path --dos "$sys_lib_search_path_spec" 2>/dev/null` + sys_lib_search_path_spec=`cygpath --path --unix "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` + ;; + *) + sys_lib_search_path_spec="$LIB" + if $ECHO "$sys_lib_search_path_spec" | [$GREP ';[c-zC-Z]:/' >/dev/null]; then + # It is most probably a Windows format PATH. + sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'` + else + sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` + fi + # FIXME: find the short name or the path components, as spaces are + # common. (e.g. "Program Files" -> "PROGRA~1") + ;; + esac + + # DLL is installed to $(libdir)/../bin by postinstall_cmds + postinstall_cmds='base_file=`basename \${file}`~ + dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i; echo \$dlname'\''`~ + dldir=$destdir/`dirname \$dlpath`~ + test -d \$dldir || mkdir -p \$dldir~ + $install_prog $dir/$dlname \$dldir/$dlname' + postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ + dlpath=$dir/\$dldll~ + $RM \$dlpath' + shlibpath_overrides_runpath=yes + dynamic_linker='Win32 link.exe' + ;; + + *) + # Assume MSVC wrapper + library_names_spec='${libname}`echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext} $libname.lib' + dynamic_linker='Win32 ld.exe' + ;; + esac + # FIXME: first we should search . and the directory the executable is in + shlibpath_var=PATH + ;; + +darwin* | rhapsody*) + dynamic_linker="$host_os dyld" + version_type=darwin + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${major}$shared_ext ${libname}$shared_ext' + soname_spec='${libname}${release}${major}$shared_ext' + shlibpath_overrides_runpath=yes + shlibpath_var=DYLD_LIBRARY_PATH + shrext_cmds='`test .$module = .yes && echo .so || echo .dylib`' +m4_if([$1], [],[ + sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/local/lib"]) + sys_lib_dlsearch_path_spec='/usr/local/lib /lib /usr/lib' + ;; + +dgux*) + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname$shared_ext' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + ;; + +freebsd* | dragonfly*) + # DragonFly does not have aout. When/if they implement a new + # versioning mechanism, adjust this. + if test -x /usr/bin/objformat; then + objformat=`/usr/bin/objformat` + else + case $host_os in + freebsd[[23]].*) objformat=aout ;; + *) objformat=elf ;; + esac + fi + version_type=freebsd-$objformat + case $version_type in + freebsd-elf*) + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}' + need_version=no + need_lib_prefix=no + ;; + freebsd-*) + library_names_spec='${libname}${release}${shared_ext}$versuffix $libname${shared_ext}$versuffix' + need_version=yes + ;; + esac + shlibpath_var=LD_LIBRARY_PATH + case $host_os in + freebsd2.*) + shlibpath_overrides_runpath=yes + ;; + freebsd3.[[01]]* | freebsdelf3.[[01]]*) + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + ;; + freebsd3.[[2-9]]* | freebsdelf3.[[2-9]]* | \ + freebsd4.[[0-5]] | freebsdelf4.[[0-5]] | freebsd4.1.1 | freebsdelf4.1.1) + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + ;; + *) # from 4.6 on, and DragonFly + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + ;; + esac + ;; + +gnu*) + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + ;; + +haiku*) + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + dynamic_linker="$host_os runtime_loader" + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LIBRARY_PATH + shlibpath_overrides_runpath=yes + sys_lib_dlsearch_path_spec='/boot/home/config/lib /boot/common/lib /boot/system/lib' + hardcode_into_libs=yes + ;; + +hpux9* | hpux10* | hpux11*) + # Give a soname corresponding to the major version so that dld.sl refuses to + # link against other versions. + version_type=sunos + need_lib_prefix=no + need_version=no + case $host_cpu in + ia64*) + shrext_cmds='.so' + hardcode_into_libs=yes + dynamic_linker="$host_os dld.so" + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + if test "X$HPUX_IA64_MODE" = X32; then + sys_lib_search_path_spec="/usr/lib/hpux32 /usr/local/lib/hpux32 /usr/local/lib" + else + sys_lib_search_path_spec="/usr/lib/hpux64 /usr/local/lib/hpux64" + fi + sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec + ;; + hppa*64*) + shrext_cmds='.sl' + hardcode_into_libs=yes + dynamic_linker="$host_os dld.sl" + shlibpath_var=LD_LIBRARY_PATH # How should we handle SHLIB_PATH + shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + sys_lib_search_path_spec="/usr/lib/pa20_64 /usr/ccs/lib/pa20_64" + sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec + ;; + *) + shrext_cmds='.sl' + dynamic_linker="$host_os dld.sl" + shlibpath_var=SHLIB_PATH + shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + ;; + esac + # HP-UX runs *really* slowly unless shared libraries are mode 555, ... + postinstall_cmds='chmod 555 $lib' + # or fails outright, so override atomically: + install_override_mode=555 + ;; + +interix[[3-9]]*) + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + dynamic_linker='Interix 3.x ld.so.1 (PE, like ELF)' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + ;; + +irix5* | irix6* | nonstopux*) + case $host_os in + nonstopux*) version_type=nonstopux ;; + *) + if test "$lt_cv_prog_gnu_ld" = yes; then + version_type=linux # correct to gnu/linux during the next big refactor + else + version_type=irix + fi ;; + esac + need_lib_prefix=no + need_version=no + soname_spec='${libname}${release}${shared_ext}$major' + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext} $libname${shared_ext}' + case $host_os in + irix5* | nonstopux*) + libsuff= shlibsuff= + ;; + *) + case $LD in # libtool.m4 will add one of these switches to LD + *-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ") + libsuff= shlibsuff= libmagic=32-bit;; + *-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ") + libsuff=32 shlibsuff=N32 libmagic=N32;; + *-64|*"-64 "|*-melf64bmip|*"-melf64bmip ") + libsuff=64 shlibsuff=64 libmagic=64-bit;; + *) libsuff= shlibsuff= libmagic=never-match;; + esac + ;; + esac + shlibpath_var=LD_LIBRARY${shlibsuff}_PATH + shlibpath_overrides_runpath=no + sys_lib_search_path_spec="/usr/lib${libsuff} /lib${libsuff} /usr/local/lib${libsuff}" + sys_lib_dlsearch_path_spec="/usr/lib${libsuff} /lib${libsuff}" + hardcode_into_libs=yes + ;; + +# No shared lib support for Linux oldld, aout, or coff. +linux*oldld* | linux*aout* | linux*coff*) + dynamic_linker=no + ;; + +# This must be glibc/ELF. +linux* | k*bsd*-gnu | kopensolaris*-gnu) + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + + # Some binutils ld are patched to set DT_RUNPATH + AC_CACHE_VAL([lt_cv_shlibpath_overrides_runpath], + [lt_cv_shlibpath_overrides_runpath=no + save_LDFLAGS=$LDFLAGS + save_libdir=$libdir + eval "libdir=/foo; wl=\"$_LT_TAGVAR(lt_prog_compiler_wl, $1)\"; \ + LDFLAGS=\"\$LDFLAGS $_LT_TAGVAR(hardcode_libdir_flag_spec, $1)\"" + AC_LINK_IFELSE([AC_LANG_PROGRAM([],[])], + [AS_IF([ ($OBJDUMP -p conftest$ac_exeext) 2>/dev/null | grep "RUNPATH.*$libdir" >/dev/null], + [lt_cv_shlibpath_overrides_runpath=yes])]) + LDFLAGS=$save_LDFLAGS + libdir=$save_libdir + ]) + shlibpath_overrides_runpath=$lt_cv_shlibpath_overrides_runpath + + # This implies no fast_install, which is unacceptable. + # Some rework will be needed to allow for fast_install + # before this can be enabled. + hardcode_into_libs=yes + + # Append ld.so.conf contents to the search path + if test -f /etc/ld.so.conf; then + lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s 2>/dev/null", \[$]2)); skip = 1; } { if (!skip) print \[$]0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;/^[ ]*hwcap[ ]/d;s/[:, ]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;s/"//g;/^$/d' | tr '\n' ' '` + sys_lib_dlsearch_path_spec="/lib /usr/lib $lt_ld_extra" + fi + + # We used to test for /lib/ld.so.1 and disable shared libraries on + # powerpc, because MkLinux only supported shared libraries with the + # GNU dynamic linker. Since this was broken with cross compilers, + # most powerpc-linux boxes support dynamic linking these days and + # people can always --disable-shared, the test was removed, and we + # assume the GNU/Linux dynamic linker is in use. + dynamic_linker='GNU/Linux ld.so' + ;; + +netbsd*) + version_type=sunos + need_lib_prefix=no + need_version=no + if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' + finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' + dynamic_linker='NetBSD (a.out) ld.so' + else + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + dynamic_linker='NetBSD ld.elf_so' + fi + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + ;; + +newsos6) + version_type=linux # correct to gnu/linux during the next big refactor + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + ;; + +*nto* | *qnx*) + version_type=qnx + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + dynamic_linker='ldqnx.so' + ;; + +openbsd*) + version_type=sunos + sys_lib_dlsearch_path_spec="/usr/lib" + need_lib_prefix=no + # Some older versions of OpenBSD (3.3 at least) *do* need versioned libs. + case $host_os in + openbsd3.3 | openbsd3.3.*) need_version=yes ;; + *) need_version=no ;; + esac + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' + finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' + shlibpath_var=LD_LIBRARY_PATH + if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then + case $host_os in + openbsd2.[[89]] | openbsd2.[[89]].*) + shlibpath_overrides_runpath=no + ;; + *) + shlibpath_overrides_runpath=yes + ;; + esac + else + shlibpath_overrides_runpath=yes + fi + ;; + +os2*) + libname_spec='$name' + shrext_cmds=".dll" + need_lib_prefix=no + library_names_spec='$libname${shared_ext} $libname.a' + dynamic_linker='OS/2 ld.exe' + shlibpath_var=LIBPATH + ;; + +osf3* | osf4* | osf5*) + version_type=osf + need_lib_prefix=no + need_version=no + soname_spec='${libname}${release}${shared_ext}$major' + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + shlibpath_var=LD_LIBRARY_PATH + sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib" + sys_lib_dlsearch_path_spec="$sys_lib_search_path_spec" + ;; + +rdos*) + dynamic_linker=no + ;; + +solaris*) + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + # ldd complains unless libraries are executable + postinstall_cmds='chmod +x $lib' + ;; + +sunos4*) + version_type=sunos + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' + finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + if test "$with_gnu_ld" = yes; then + need_lib_prefix=no + fi + need_version=yes + ;; + +sysv4 | sysv4.3*) + version_type=linux # correct to gnu/linux during the next big refactor + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + case $host_vendor in + sni) + shlibpath_overrides_runpath=no + need_lib_prefix=no + runpath_var=LD_RUN_PATH + ;; + siemens) + need_lib_prefix=no + ;; + motorola) + need_lib_prefix=no + need_version=no + shlibpath_overrides_runpath=no + sys_lib_search_path_spec='/lib /usr/lib /usr/ccs/lib' + ;; + esac + ;; + +sysv4*MP*) + if test -d /usr/nec ;then + version_type=linux # correct to gnu/linux during the next big refactor + library_names_spec='$libname${shared_ext}.$versuffix $libname${shared_ext}.$major $libname${shared_ext}' + soname_spec='$libname${shared_ext}.$major' + shlibpath_var=LD_LIBRARY_PATH + fi + ;; + +sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) + version_type=freebsd-elf + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + if test "$with_gnu_ld" = yes; then + sys_lib_search_path_spec='/usr/local/lib /usr/gnu/lib /usr/ccs/lib /usr/lib /lib' + else + sys_lib_search_path_spec='/usr/ccs/lib /usr/lib' + case $host_os in + sco3.2v5*) + sys_lib_search_path_spec="$sys_lib_search_path_spec /lib" + ;; + esac + fi + sys_lib_dlsearch_path_spec='/usr/lib' + ;; + +tpf*) + # TPF is a cross-target only. Preferred cross-host = GNU/Linux. + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + ;; + +uts4*) + version_type=linux # correct to gnu/linux during the next big refactor + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + ;; + +*) + dynamic_linker=no + ;; +esac +AC_MSG_RESULT([$dynamic_linker]) +test "$dynamic_linker" = no && can_build_shared=no + +variables_saved_for_relink="PATH $shlibpath_var $runpath_var" +if test "$GCC" = yes; then + variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH" +fi + +if test "${lt_cv_sys_lib_search_path_spec+set}" = set; then + sys_lib_search_path_spec="$lt_cv_sys_lib_search_path_spec" +fi +if test "${lt_cv_sys_lib_dlsearch_path_spec+set}" = set; then + sys_lib_dlsearch_path_spec="$lt_cv_sys_lib_dlsearch_path_spec" +fi + +_LT_DECL([], [variables_saved_for_relink], [1], + [Variables whose values should be saved in libtool wrapper scripts and + restored at link time]) +_LT_DECL([], [need_lib_prefix], [0], + [Do we need the "lib" prefix for modules?]) +_LT_DECL([], [need_version], [0], [Do we need a version for libraries?]) +_LT_DECL([], [version_type], [0], [Library versioning type]) +_LT_DECL([], [runpath_var], [0], [Shared library runtime path variable]) +_LT_DECL([], [shlibpath_var], [0],[Shared library path variable]) +_LT_DECL([], [shlibpath_overrides_runpath], [0], + [Is shlibpath searched before the hard-coded library search path?]) +_LT_DECL([], [libname_spec], [1], [Format of library name prefix]) +_LT_DECL([], [library_names_spec], [1], + [[List of archive names. First name is the real one, the rest are links. + The last name is the one that the linker finds with -lNAME]]) +_LT_DECL([], [soname_spec], [1], + [[The coded name of the library, if different from the real name]]) +_LT_DECL([], [install_override_mode], [1], + [Permission mode override for installation of shared libraries]) +_LT_DECL([], [postinstall_cmds], [2], + [Command to use after installation of a shared archive]) +_LT_DECL([], [postuninstall_cmds], [2], + [Command to use after uninstallation of a shared archive]) +_LT_DECL([], [finish_cmds], [2], + [Commands used to finish a libtool library installation in a directory]) +_LT_DECL([], [finish_eval], [1], + [[As "finish_cmds", except a single script fragment to be evaled but + not shown]]) +_LT_DECL([], [hardcode_into_libs], [0], + [Whether we should hardcode library paths into libraries]) +_LT_DECL([], [sys_lib_search_path_spec], [2], + [Compile-time system search path for libraries]) +_LT_DECL([], [sys_lib_dlsearch_path_spec], [2], + [Run-time system search path for libraries]) +])# _LT_SYS_DYNAMIC_LINKER + + +# _LT_PATH_TOOL_PREFIX(TOOL) +# -------------------------- +# find a file program which can recognize shared library +AC_DEFUN([_LT_PATH_TOOL_PREFIX], +[m4_require([_LT_DECL_EGREP])dnl +AC_MSG_CHECKING([for $1]) +AC_CACHE_VAL(lt_cv_path_MAGIC_CMD, +[case $MAGIC_CMD in +[[\\/*] | ?:[\\/]*]) + lt_cv_path_MAGIC_CMD="$MAGIC_CMD" # Let the user override the test with a path. + ;; +*) + lt_save_MAGIC_CMD="$MAGIC_CMD" + lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR +dnl $ac_dummy forces splitting on constant user-supplied paths. +dnl POSIX.2 word splitting is done only on the output of word expansions, +dnl not every word. This closes a longstanding sh security hole. + ac_dummy="m4_if([$2], , $PATH, [$2])" + for ac_dir in $ac_dummy; do + IFS="$lt_save_ifs" + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$1; then + lt_cv_path_MAGIC_CMD="$ac_dir/$1" + if test -n "$file_magic_test_file"; then + case $deplibs_check_method in + "file_magic "*) + file_magic_regex=`expr "$deplibs_check_method" : "file_magic \(.*\)"` + MAGIC_CMD="$lt_cv_path_MAGIC_CMD" + if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null | + $EGREP "$file_magic_regex" > /dev/null; then + : + else + cat <<_LT_EOF 1>&2 + +*** Warning: the command libtool uses to detect shared libraries, +*** $file_magic_cmd, produces output that libtool cannot recognize. +*** The result is that libtool may fail to recognize shared libraries +*** as such. This will affect the creation of libtool libraries that +*** depend on shared libraries, but programs linked with such libtool +*** libraries will work regardless of this problem. Nevertheless, you +*** may want to report the problem to your system manager and/or to +*** bug-libtool@gnu.org + +_LT_EOF + fi ;; + esac + fi + break + fi + done + IFS="$lt_save_ifs" + MAGIC_CMD="$lt_save_MAGIC_CMD" + ;; +esac]) +MAGIC_CMD="$lt_cv_path_MAGIC_CMD" +if test -n "$MAGIC_CMD"; then + AC_MSG_RESULT($MAGIC_CMD) +else + AC_MSG_RESULT(no) +fi +_LT_DECL([], [MAGIC_CMD], [0], + [Used to examine libraries when file_magic_cmd begins with "file"])dnl +])# _LT_PATH_TOOL_PREFIX + +# Old name: +AU_ALIAS([AC_PATH_TOOL_PREFIX], [_LT_PATH_TOOL_PREFIX]) +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AC_PATH_TOOL_PREFIX], []) + + +# _LT_PATH_MAGIC +# -------------- +# find a file program which can recognize a shared library +m4_defun([_LT_PATH_MAGIC], +[_LT_PATH_TOOL_PREFIX(${ac_tool_prefix}file, /usr/bin$PATH_SEPARATOR$PATH) +if test -z "$lt_cv_path_MAGIC_CMD"; then + if test -n "$ac_tool_prefix"; then + _LT_PATH_TOOL_PREFIX(file, /usr/bin$PATH_SEPARATOR$PATH) + else + MAGIC_CMD=: + fi +fi +])# _LT_PATH_MAGIC + + +# LT_PATH_LD +# ---------- +# find the pathname to the GNU or non-GNU linker +AC_DEFUN([LT_PATH_LD], +[AC_REQUIRE([AC_PROG_CC])dnl +AC_REQUIRE([AC_CANONICAL_HOST])dnl +AC_REQUIRE([AC_CANONICAL_BUILD])dnl +m4_require([_LT_DECL_SED])dnl +m4_require([_LT_DECL_EGREP])dnl +m4_require([_LT_PROG_ECHO_BACKSLASH])dnl + +AC_ARG_WITH([gnu-ld], + [AS_HELP_STRING([--with-gnu-ld], + [assume the C compiler uses GNU ld @<:@default=no@:>@])], + [test "$withval" = no || with_gnu_ld=yes], + [with_gnu_ld=no])dnl + +ac_prog=ld +if test "$GCC" = yes; then + # Check if gcc -print-prog-name=ld gives a path. + AC_MSG_CHECKING([for ld used by $CC]) + case $host in + *-*-mingw*) + # gcc leaves a trailing carriage return which upsets mingw + ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;; + *) + ac_prog=`($CC -print-prog-name=ld) 2>&5` ;; + esac + case $ac_prog in + # Accept absolute paths. + [[\\/]]* | ?:[[\\/]]*) + re_direlt='/[[^/]][[^/]]*/\.\./' + # Canonicalize the pathname of ld + ac_prog=`$ECHO "$ac_prog"| $SED 's%\\\\%/%g'` + while $ECHO "$ac_prog" | $GREP "$re_direlt" > /dev/null 2>&1; do + ac_prog=`$ECHO $ac_prog| $SED "s%$re_direlt%/%"` + done + test -z "$LD" && LD="$ac_prog" + ;; + "") + # If it fails, then pretend we aren't using GCC. + ac_prog=ld + ;; + *) + # If it is relative, then search for the first ld in PATH. + with_gnu_ld=unknown + ;; + esac +elif test "$with_gnu_ld" = yes; then + AC_MSG_CHECKING([for GNU ld]) +else + AC_MSG_CHECKING([for non-GNU ld]) +fi +AC_CACHE_VAL(lt_cv_path_LD, +[if test -z "$LD"; then + lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR + for ac_dir in $PATH; do + IFS="$lt_save_ifs" + test -z "$ac_dir" && ac_dir=. + if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then + lt_cv_path_LD="$ac_dir/$ac_prog" + # Check to see if the program is GNU ld. I'd rather use --version, + # but apparently some variants of GNU ld only accept -v. + # Break only if it was the GNU/non-GNU ld that we prefer. + case `"$lt_cv_path_LD" -v 2>&1 &1 /dev/null 2>&1; then + lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL' + lt_cv_file_magic_cmd='func_win32_libid' + else + # Keep this pattern in sync with the one in func_win32_libid. + lt_cv_deplibs_check_method='file_magic file format (pei*-i386(.*architecture: i386)?|pe-arm-wince|pe-x86-64)' + lt_cv_file_magic_cmd='$OBJDUMP -f' + fi + ;; + +cegcc*) + # use the weaker test based on 'objdump'. See mingw*. + lt_cv_deplibs_check_method='file_magic file format pe-arm-.*little(.*architecture: arm)?' + lt_cv_file_magic_cmd='$OBJDUMP -f' + ;; + +darwin* | rhapsody*) + lt_cv_deplibs_check_method=pass_all + ;; + +freebsd* | dragonfly*) + if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then + case $host_cpu in + i*86 ) + # Not sure whether the presence of OpenBSD here was a mistake. + # Let's accept both of them until this is cleared up. + lt_cv_deplibs_check_method='file_magic (FreeBSD|OpenBSD|DragonFly)/i[[3-9]]86 (compact )?demand paged shared library' + lt_cv_file_magic_cmd=/usr/bin/file + lt_cv_file_magic_test_file=`echo /usr/lib/libc.so.*` + ;; + esac + else + lt_cv_deplibs_check_method=pass_all + fi + ;; + +gnu*) + lt_cv_deplibs_check_method=pass_all + ;; + +haiku*) + lt_cv_deplibs_check_method=pass_all + ;; + +hpux10.20* | hpux11*) + lt_cv_file_magic_cmd=/usr/bin/file + case $host_cpu in + ia64*) + lt_cv_deplibs_check_method='file_magic (s[[0-9]][[0-9]][[0-9]]|ELF-[[0-9]][[0-9]]) shared object file - IA64' + lt_cv_file_magic_test_file=/usr/lib/hpux32/libc.so + ;; + hppa*64*) + [lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF[ -][0-9][0-9])(-bit)?( [LM]SB)? shared object( file)?[, -]* PA-RISC [0-9]\.[0-9]'] + lt_cv_file_magic_test_file=/usr/lib/pa20_64/libc.sl + ;; + *) + lt_cv_deplibs_check_method='file_magic (s[[0-9]][[0-9]][[0-9]]|PA-RISC[[0-9]]\.[[0-9]]) shared library' + lt_cv_file_magic_test_file=/usr/lib/libc.sl + ;; + esac + ;; + +interix[[3-9]]*) + # PIC code is broken on Interix 3.x, that's why |\.a not |_pic\.a here + lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so|\.a)$' + ;; + +irix5* | irix6* | nonstopux*) + case $LD in + *-32|*"-32 ") libmagic=32-bit;; + *-n32|*"-n32 ") libmagic=N32;; + *-64|*"-64 ") libmagic=64-bit;; + *) libmagic=never-match;; + esac + lt_cv_deplibs_check_method=pass_all + ;; + +# This must be glibc/ELF. +linux* | k*bsd*-gnu | kopensolaris*-gnu) + lt_cv_deplibs_check_method=pass_all + ;; + +netbsd*) + if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then + lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|_pic\.a)$' + else + lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so|_pic\.a)$' + fi + ;; + +newos6*) + lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[ML]]SB (executable|dynamic lib)' + lt_cv_file_magic_cmd=/usr/bin/file + lt_cv_file_magic_test_file=/usr/lib/libnls.so + ;; + +*nto* | *qnx*) + lt_cv_deplibs_check_method=pass_all + ;; + +openbsd*) + if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then + lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|\.so|_pic\.a)$' + else + lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|_pic\.a)$' + fi + ;; + +osf3* | osf4* | osf5*) + lt_cv_deplibs_check_method=pass_all + ;; + +rdos*) + lt_cv_deplibs_check_method=pass_all + ;; + +solaris*) + lt_cv_deplibs_check_method=pass_all + ;; + +sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) + lt_cv_deplibs_check_method=pass_all + ;; + +sysv4 | sysv4.3*) + case $host_vendor in + motorola) + lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[ML]]SB (shared object|dynamic lib) M[[0-9]][[0-9]]* Version [[0-9]]' + lt_cv_file_magic_test_file=`echo /usr/lib/libc.so*` + ;; + ncr) + lt_cv_deplibs_check_method=pass_all + ;; + sequent) + lt_cv_file_magic_cmd='/bin/file' + lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[LM]]SB (shared object|dynamic lib )' + ;; + sni) + lt_cv_file_magic_cmd='/bin/file' + lt_cv_deplibs_check_method="file_magic ELF [[0-9]][[0-9]]*-bit [[LM]]SB dynamic lib" + lt_cv_file_magic_test_file=/lib/libc.so + ;; + siemens) + lt_cv_deplibs_check_method=pass_all + ;; + pc) + lt_cv_deplibs_check_method=pass_all + ;; + esac + ;; + +tpf*) + lt_cv_deplibs_check_method=pass_all + ;; +esac +]) + +file_magic_glob= +want_nocaseglob=no +if test "$build" = "$host"; then + case $host_os in + mingw* | pw32*) + if ( shopt | grep nocaseglob ) >/dev/null 2>&1; then + want_nocaseglob=yes + else + file_magic_glob=`echo aAbBcCdDeEfFgGhHiIjJkKlLmMnNoOpPqQrRsStTuUvVwWxXyYzZ | $SED -e "s/\(..\)/s\/[[\1]]\/[[\1]]\/g;/g"` + fi + ;; + esac +fi + +file_magic_cmd=$lt_cv_file_magic_cmd +deplibs_check_method=$lt_cv_deplibs_check_method +test -z "$deplibs_check_method" && deplibs_check_method=unknown + +_LT_DECL([], [deplibs_check_method], [1], + [Method to check whether dependent libraries are shared objects]) +_LT_DECL([], [file_magic_cmd], [1], + [Command to use when deplibs_check_method = "file_magic"]) +_LT_DECL([], [file_magic_glob], [1], + [How to find potential files when deplibs_check_method = "file_magic"]) +_LT_DECL([], [want_nocaseglob], [1], + [Find potential files using nocaseglob when deplibs_check_method = "file_magic"]) +])# _LT_CHECK_MAGIC_METHOD + + +# LT_PATH_NM +# ---------- +# find the pathname to a BSD- or MS-compatible name lister +AC_DEFUN([LT_PATH_NM], +[AC_REQUIRE([AC_PROG_CC])dnl +AC_CACHE_CHECK([for BSD- or MS-compatible name lister (nm)], lt_cv_path_NM, +[if test -n "$NM"; then + # Let the user override the test. + lt_cv_path_NM="$NM" +else + lt_nm_to_check="${ac_tool_prefix}nm" + if test -n "$ac_tool_prefix" && test "$build" = "$host"; then + lt_nm_to_check="$lt_nm_to_check nm" + fi + for lt_tmp_nm in $lt_nm_to_check; do + lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR + for ac_dir in $PATH /usr/ccs/bin/elf /usr/ccs/bin /usr/ucb /bin; do + IFS="$lt_save_ifs" + test -z "$ac_dir" && ac_dir=. + tmp_nm="$ac_dir/$lt_tmp_nm" + if test -f "$tmp_nm" || test -f "$tmp_nm$ac_exeext" ; then + # Check to see if the nm accepts a BSD-compat flag. + # Adding the `sed 1q' prevents false positives on HP-UX, which says: + # nm: unknown option "B" ignored + # Tru64's nm complains that /dev/null is an invalid object file + case `"$tmp_nm" -B /dev/null 2>&1 | sed '1q'` in + */dev/null* | *'Invalid file or object type'*) + lt_cv_path_NM="$tmp_nm -B" + break + ;; + *) + case `"$tmp_nm" -p /dev/null 2>&1 | sed '1q'` in + */dev/null*) + lt_cv_path_NM="$tmp_nm -p" + break + ;; + *) + lt_cv_path_NM=${lt_cv_path_NM="$tmp_nm"} # keep the first match, but + continue # so that we can try to find one that supports BSD flags + ;; + esac + ;; + esac + fi + done + IFS="$lt_save_ifs" + done + : ${lt_cv_path_NM=no} +fi]) +if test "$lt_cv_path_NM" != "no"; then + NM="$lt_cv_path_NM" +else + # Didn't find any BSD compatible name lister, look for dumpbin. + if test -n "$DUMPBIN"; then : + # Let the user override the test. + else + AC_CHECK_TOOLS(DUMPBIN, [dumpbin "link -dump"], :) + case `$DUMPBIN -symbols /dev/null 2>&1 | sed '1q'` in + *COFF*) + DUMPBIN="$DUMPBIN -symbols" + ;; + *) + DUMPBIN=: + ;; + esac + fi + AC_SUBST([DUMPBIN]) + if test "$DUMPBIN" != ":"; then + NM="$DUMPBIN" + fi +fi +test -z "$NM" && NM=nm +AC_SUBST([NM]) +_LT_DECL([], [NM], [1], [A BSD- or MS-compatible name lister])dnl + +AC_CACHE_CHECK([the name lister ($NM) interface], [lt_cv_nm_interface], + [lt_cv_nm_interface="BSD nm" + echo "int some_variable = 0;" > conftest.$ac_ext + (eval echo "\"\$as_me:$LINENO: $ac_compile\"" >&AS_MESSAGE_LOG_FD) + (eval "$ac_compile" 2>conftest.err) + cat conftest.err >&AS_MESSAGE_LOG_FD + (eval echo "\"\$as_me:$LINENO: $NM \\\"conftest.$ac_objext\\\"\"" >&AS_MESSAGE_LOG_FD) + (eval "$NM \"conftest.$ac_objext\"" 2>conftest.err > conftest.out) + cat conftest.err >&AS_MESSAGE_LOG_FD + (eval echo "\"\$as_me:$LINENO: output\"" >&AS_MESSAGE_LOG_FD) + cat conftest.out >&AS_MESSAGE_LOG_FD + if $GREP 'External.*some_variable' conftest.out > /dev/null; then + lt_cv_nm_interface="MS dumpbin" + fi + rm -f conftest*]) +])# LT_PATH_NM + +# Old names: +AU_ALIAS([AM_PROG_NM], [LT_PATH_NM]) +AU_ALIAS([AC_PROG_NM], [LT_PATH_NM]) +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AM_PROG_NM], []) +dnl AC_DEFUN([AC_PROG_NM], []) + +# _LT_CHECK_SHAREDLIB_FROM_LINKLIB +# -------------------------------- +# how to determine the name of the shared library +# associated with a specific link library. +# -- PORTME fill in with the dynamic library characteristics +m4_defun([_LT_CHECK_SHAREDLIB_FROM_LINKLIB], +[m4_require([_LT_DECL_EGREP]) +m4_require([_LT_DECL_OBJDUMP]) +m4_require([_LT_DECL_DLLTOOL]) +AC_CACHE_CHECK([how to associate runtime and link libraries], +lt_cv_sharedlib_from_linklib_cmd, +[lt_cv_sharedlib_from_linklib_cmd='unknown' + +case $host_os in +cygwin* | mingw* | pw32* | cegcc*) + # two different shell functions defined in ltmain.sh + # decide which to use based on capabilities of $DLLTOOL + case `$DLLTOOL --help 2>&1` in + *--identify-strict*) + lt_cv_sharedlib_from_linklib_cmd=func_cygming_dll_for_implib + ;; + *) + lt_cv_sharedlib_from_linklib_cmd=func_cygming_dll_for_implib_fallback + ;; + esac + ;; +*) + # fallback: assume linklib IS sharedlib + lt_cv_sharedlib_from_linklib_cmd="$ECHO" + ;; +esac +]) +sharedlib_from_linklib_cmd=$lt_cv_sharedlib_from_linklib_cmd +test -z "$sharedlib_from_linklib_cmd" && sharedlib_from_linklib_cmd=$ECHO + +_LT_DECL([], [sharedlib_from_linklib_cmd], [1], + [Command to associate shared and link libraries]) +])# _LT_CHECK_SHAREDLIB_FROM_LINKLIB + + +# _LT_PATH_MANIFEST_TOOL +# ---------------------- +# locate the manifest tool +m4_defun([_LT_PATH_MANIFEST_TOOL], +[AC_CHECK_TOOL(MANIFEST_TOOL, mt, :) +test -z "$MANIFEST_TOOL" && MANIFEST_TOOL=mt +AC_CACHE_CHECK([if $MANIFEST_TOOL is a manifest tool], [lt_cv_path_mainfest_tool], + [lt_cv_path_mainfest_tool=no + echo "$as_me:$LINENO: $MANIFEST_TOOL '-?'" >&AS_MESSAGE_LOG_FD + $MANIFEST_TOOL '-?' 2>conftest.err > conftest.out + cat conftest.err >&AS_MESSAGE_LOG_FD + if $GREP 'Manifest Tool' conftest.out > /dev/null; then + lt_cv_path_mainfest_tool=yes + fi + rm -f conftest*]) +if test "x$lt_cv_path_mainfest_tool" != xyes; then + MANIFEST_TOOL=: +fi +_LT_DECL([], [MANIFEST_TOOL], [1], [Manifest tool])dnl +])# _LT_PATH_MANIFEST_TOOL + + +# LT_LIB_M +# -------- +# check for math library +AC_DEFUN([LT_LIB_M], +[AC_REQUIRE([AC_CANONICAL_HOST])dnl +LIBM= +case $host in +*-*-beos* | *-*-cegcc* | *-*-cygwin* | *-*-haiku* | *-*-pw32* | *-*-darwin*) + # These system don't have libm, or don't need it + ;; +*-ncr-sysv4.3*) + AC_CHECK_LIB(mw, _mwvalidcheckl, LIBM="-lmw") + AC_CHECK_LIB(m, cos, LIBM="$LIBM -lm") + ;; +*) + AC_CHECK_LIB(m, cos, LIBM="-lm") + ;; +esac +AC_SUBST([LIBM]) +])# LT_LIB_M + +# Old name: +AU_ALIAS([AC_CHECK_LIBM], [LT_LIB_M]) +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AC_CHECK_LIBM], []) + + +# _LT_COMPILER_NO_RTTI([TAGNAME]) +# ------------------------------- +m4_defun([_LT_COMPILER_NO_RTTI], +[m4_require([_LT_TAG_COMPILER])dnl + +_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)= + +if test "$GCC" = yes; then + case $cc_basename in + nvcc*) + _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=' -Xcompiler -fno-builtin' ;; + *) + _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=' -fno-builtin' ;; + esac + + _LT_COMPILER_OPTION([if $compiler supports -fno-rtti -fno-exceptions], + lt_cv_prog_compiler_rtti_exceptions, + [-fno-rtti -fno-exceptions], [], + [_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)="$_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1) -fno-rtti -fno-exceptions"]) +fi +_LT_TAGDECL([no_builtin_flag], [lt_prog_compiler_no_builtin_flag], [1], + [Compiler flag to turn off builtin functions]) +])# _LT_COMPILER_NO_RTTI + + +# _LT_CMD_GLOBAL_SYMBOLS +# ---------------------- +m4_defun([_LT_CMD_GLOBAL_SYMBOLS], +[AC_REQUIRE([AC_CANONICAL_HOST])dnl +AC_REQUIRE([AC_PROG_CC])dnl +AC_REQUIRE([AC_PROG_AWK])dnl +AC_REQUIRE([LT_PATH_NM])dnl +AC_REQUIRE([LT_PATH_LD])dnl +m4_require([_LT_DECL_SED])dnl +m4_require([_LT_DECL_EGREP])dnl +m4_require([_LT_TAG_COMPILER])dnl + +# Check for command to grab the raw symbol name followed by C symbol from nm. +AC_MSG_CHECKING([command to parse $NM output from $compiler object]) +AC_CACHE_VAL([lt_cv_sys_global_symbol_pipe], +[ +# These are sane defaults that work on at least a few old systems. +# [They come from Ultrix. What could be older than Ultrix?!! ;)] + +# Character class describing NM global symbol codes. +symcode='[[BCDEGRST]]' + +# Regexp to match symbols that can be accessed directly from C. +sympat='\([[_A-Za-z]][[_A-Za-z0-9]]*\)' + +# Define system-specific variables. +case $host_os in +aix*) + symcode='[[BCDT]]' + ;; +cygwin* | mingw* | pw32* | cegcc*) + symcode='[[ABCDGISTW]]' + ;; +hpux*) + if test "$host_cpu" = ia64; then + symcode='[[ABCDEGRST]]' + fi + ;; +irix* | nonstopux*) + symcode='[[BCDEGRST]]' + ;; +osf*) + symcode='[[BCDEGQRST]]' + ;; +solaris*) + symcode='[[BDRT]]' + ;; +sco3.2v5*) + symcode='[[DT]]' + ;; +sysv4.2uw2*) + symcode='[[DT]]' + ;; +sysv5* | sco5v6* | unixware* | OpenUNIX*) + symcode='[[ABDT]]' + ;; +sysv4) + symcode='[[DFNSTU]]' + ;; +esac + +# If we're using GNU nm, then use its standard symbol codes. +case `$NM -V 2>&1` in +*GNU* | *'with BFD'*) + symcode='[[ABCDGIRSTW]]' ;; +esac + +# Transform an extracted symbol line into a proper C declaration. +# Some systems (esp. on ia64) link data and code symbols differently, +# so use this general approach. +lt_cv_sys_global_symbol_to_cdecl="sed -n -e 's/^T .* \(.*\)$/extern int \1();/p' -e 's/^$symcode* .* \(.*\)$/extern char \1;/p'" + +# Transform an extracted symbol line into symbol name and symbol address +lt_cv_sys_global_symbol_to_c_name_address="sed -n -e 's/^: \([[^ ]]*\)[[ ]]*$/ {\\\"\1\\\", (void *) 0},/p' -e 's/^$symcode* \([[^ ]]*\) \([[^ ]]*\)$/ {\"\2\", (void *) \&\2},/p'" +lt_cv_sys_global_symbol_to_c_name_address_lib_prefix="sed -n -e 's/^: \([[^ ]]*\)[[ ]]*$/ {\\\"\1\\\", (void *) 0},/p' -e 's/^$symcode* \([[^ ]]*\) \(lib[[^ ]]*\)$/ {\"\2\", (void *) \&\2},/p' -e 's/^$symcode* \([[^ ]]*\) \([[^ ]]*\)$/ {\"lib\2\", (void *) \&\2},/p'" + +# Handle CRLF in mingw tool chain +opt_cr= +case $build_os in +mingw*) + opt_cr=`$ECHO 'x\{0,1\}' | tr x '\015'` # option cr in regexp + ;; +esac + +# Try without a prefix underscore, then with it. +for ac_symprfx in "" "_"; do + + # Transform symcode, sympat, and symprfx into a raw symbol and a C symbol. + symxfrm="\\1 $ac_symprfx\\2 \\2" + + # Write the raw and C identifiers. + if test "$lt_cv_nm_interface" = "MS dumpbin"; then + # Fake it for dumpbin and say T for any non-static function + # and D for any global variable. + # Also find C++ and __fastcall symbols from MSVC++, + # which start with @ or ?. + lt_cv_sys_global_symbol_pipe="$AWK ['"\ +" {last_section=section; section=\$ 3};"\ +" /^COFF SYMBOL TABLE/{for(i in hide) delete hide[i]};"\ +" /Section length .*#relocs.*(pick any)/{hide[last_section]=1};"\ +" \$ 0!~/External *\|/{next};"\ +" / 0+ UNDEF /{next}; / UNDEF \([^|]\)*()/{next};"\ +" {if(hide[section]) next};"\ +" {f=0}; \$ 0~/\(\).*\|/{f=1}; {printf f ? \"T \" : \"D \"};"\ +" {split(\$ 0, a, /\||\r/); split(a[2], s)};"\ +" s[1]~/^[@?]/{print s[1], s[1]; next};"\ +" s[1]~prfx {split(s[1],t,\"@\"); print t[1], substr(t[1],length(prfx))}"\ +" ' prfx=^$ac_symprfx]" + else + lt_cv_sys_global_symbol_pipe="sed -n -e 's/^.*[[ ]]\($symcode$symcode*\)[[ ]][[ ]]*$ac_symprfx$sympat$opt_cr$/$symxfrm/p'" + fi + lt_cv_sys_global_symbol_pipe="$lt_cv_sys_global_symbol_pipe | sed '/ __gnu_lto/d'" + + # Check to see that the pipe works correctly. + pipe_works=no + + rm -f conftest* + cat > conftest.$ac_ext <<_LT_EOF +#ifdef __cplusplus +extern "C" { +#endif +char nm_test_var; +void nm_test_func(void); +void nm_test_func(void){} +#ifdef __cplusplus +} +#endif +int main(){nm_test_var='a';nm_test_func();return(0);} +_LT_EOF + + if AC_TRY_EVAL(ac_compile); then + # Now try to grab the symbols. + nlist=conftest.nm + if AC_TRY_EVAL(NM conftest.$ac_objext \| "$lt_cv_sys_global_symbol_pipe" \> $nlist) && test -s "$nlist"; then + # Try sorting and uniquifying the output. + if sort "$nlist" | uniq > "$nlist"T; then + mv -f "$nlist"T "$nlist" + else + rm -f "$nlist"T + fi + + # Make sure that we snagged all the symbols we need. + if $GREP ' nm_test_var$' "$nlist" >/dev/null; then + if $GREP ' nm_test_func$' "$nlist" >/dev/null; then + cat <<_LT_EOF > conftest.$ac_ext +/* Keep this code in sync between libtool.m4, ltmain, lt_system.h, and tests. */ +#if defined(_WIN32) || defined(__CYGWIN__) || defined(_WIN32_WCE) +/* DATA imports from DLLs on WIN32 con't be const, because runtime + relocations are performed -- see ld's documentation on pseudo-relocs. */ +# define LT@&t@_DLSYM_CONST +#elif defined(__osf__) +/* This system does not cope well with relocations in const data. */ +# define LT@&t@_DLSYM_CONST +#else +# define LT@&t@_DLSYM_CONST const +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +_LT_EOF + # Now generate the symbol file. + eval "$lt_cv_sys_global_symbol_to_cdecl"' < "$nlist" | $GREP -v main >> conftest.$ac_ext' + + cat <<_LT_EOF >> conftest.$ac_ext + +/* The mapping between symbol names and symbols. */ +LT@&t@_DLSYM_CONST struct { + const char *name; + void *address; +} +lt__PROGRAM__LTX_preloaded_symbols[[]] = +{ + { "@PROGRAM@", (void *) 0 }, +_LT_EOF + $SED "s/^$symcode$symcode* \(.*\) \(.*\)$/ {\"\2\", (void *) \&\2},/" < "$nlist" | $GREP -v main >> conftest.$ac_ext + cat <<\_LT_EOF >> conftest.$ac_ext + {0, (void *) 0} +}; + +/* This works around a problem in FreeBSD linker */ +#ifdef FREEBSD_WORKAROUND +static const void *lt_preloaded_setup() { + return lt__PROGRAM__LTX_preloaded_symbols; +} +#endif + +#ifdef __cplusplus +} +#endif +_LT_EOF + # Now try linking the two files. + mv conftest.$ac_objext conftstm.$ac_objext + lt_globsym_save_LIBS=$LIBS + lt_globsym_save_CFLAGS=$CFLAGS + LIBS="conftstm.$ac_objext" + CFLAGS="$CFLAGS$_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)" + if AC_TRY_EVAL(ac_link) && test -s conftest${ac_exeext}; then + pipe_works=yes + fi + LIBS=$lt_globsym_save_LIBS + CFLAGS=$lt_globsym_save_CFLAGS + else + echo "cannot find nm_test_func in $nlist" >&AS_MESSAGE_LOG_FD + fi + else + echo "cannot find nm_test_var in $nlist" >&AS_MESSAGE_LOG_FD + fi + else + echo "cannot run $lt_cv_sys_global_symbol_pipe" >&AS_MESSAGE_LOG_FD + fi + else + echo "$progname: failed program was:" >&AS_MESSAGE_LOG_FD + cat conftest.$ac_ext >&5 + fi + rm -rf conftest* conftst* + + # Do not use the global_symbol_pipe unless it works. + if test "$pipe_works" = yes; then + break + else + lt_cv_sys_global_symbol_pipe= + fi +done +]) +if test -z "$lt_cv_sys_global_symbol_pipe"; then + lt_cv_sys_global_symbol_to_cdecl= +fi +if test -z "$lt_cv_sys_global_symbol_pipe$lt_cv_sys_global_symbol_to_cdecl"; then + AC_MSG_RESULT(failed) +else + AC_MSG_RESULT(ok) +fi + +# Response file support. +if test "$lt_cv_nm_interface" = "MS dumpbin"; then + nm_file_list_spec='@' +elif $NM --help 2>/dev/null | grep '[[@]]FILE' >/dev/null; then + nm_file_list_spec='@' +fi + +_LT_DECL([global_symbol_pipe], [lt_cv_sys_global_symbol_pipe], [1], + [Take the output of nm and produce a listing of raw symbols and C names]) +_LT_DECL([global_symbol_to_cdecl], [lt_cv_sys_global_symbol_to_cdecl], [1], + [Transform the output of nm in a proper C declaration]) +_LT_DECL([global_symbol_to_c_name_address], + [lt_cv_sys_global_symbol_to_c_name_address], [1], + [Transform the output of nm in a C name address pair]) +_LT_DECL([global_symbol_to_c_name_address_lib_prefix], + [lt_cv_sys_global_symbol_to_c_name_address_lib_prefix], [1], + [Transform the output of nm in a C name address pair when lib prefix is needed]) +_LT_DECL([], [nm_file_list_spec], [1], + [Specify filename containing input files for $NM]) +]) # _LT_CMD_GLOBAL_SYMBOLS + + +# _LT_COMPILER_PIC([TAGNAME]) +# --------------------------- +m4_defun([_LT_COMPILER_PIC], +[m4_require([_LT_TAG_COMPILER])dnl +_LT_TAGVAR(lt_prog_compiler_wl, $1)= +_LT_TAGVAR(lt_prog_compiler_pic, $1)= +_LT_TAGVAR(lt_prog_compiler_static, $1)= + +m4_if([$1], [CXX], [ + # C++ specific cases for pic, static, wl, etc. + if test "$GXX" = yes; then + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' + + case $host_os in + aix*) + # All AIX code is PIC. + if test "$host_cpu" = ia64; then + # AIX 5 now supports IA64 processor + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + fi + ;; + + amigaos*) + case $host_cpu in + powerpc) + # see comment about AmigaOS4 .so support + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' + ;; + m68k) + # FIXME: we need at least 68020 code to build shared libraries, but + # adding the `-m68020' flag to GCC prevents building anything better, + # like `-m68040'. + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-m68020 -resident32 -malways-restore-a4' + ;; + esac + ;; + + beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*) + # PIC is the default for these OSes. + ;; + mingw* | cygwin* | os2* | pw32* | cegcc*) + # This hack is so that the source file can tell whether it is being + # built for inclusion in a dll (and should export symbols for example). + # Although the cygwin gcc ignores -fPIC, still need this for old-style + # (--disable-auto-import) libraries + m4_if([$1], [GCJ], [], + [_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT']) + ;; + darwin* | rhapsody*) + # PIC is the default on this platform + # Common symbols not allowed in MH_DYLIB files + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fno-common' + ;; + *djgpp*) + # DJGPP does not support shared libraries at all + _LT_TAGVAR(lt_prog_compiler_pic, $1)= + ;; + haiku*) + # PIC is the default for Haiku. + # The "-static" flag exists, but is broken. + _LT_TAGVAR(lt_prog_compiler_static, $1)= + ;; + interix[[3-9]]*) + # Interix 3.x gcc -fpic/-fPIC options generate broken code. + # Instead, we relocate shared libraries at runtime. + ;; + sysv4*MP*) + if test -d /usr/nec; then + _LT_TAGVAR(lt_prog_compiler_pic, $1)=-Kconform_pic + fi + ;; + hpux*) + # PIC is the default for 64-bit PA HP-UX, but not for 32-bit + # PA HP-UX. On IA64 HP-UX, PIC is the default but the pic flag + # sets the default TLS model and affects inlining. + case $host_cpu in + hppa*64*) + ;; + *) + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' + ;; + esac + ;; + *qnx* | *nto*) + # QNX uses GNU C++, but need to define -shared option too, otherwise + # it will coredump. + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared' + ;; + *) + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' + ;; + esac + else + case $host_os in + aix[[4-9]]*) + # All AIX code is PIC. + if test "$host_cpu" = ia64; then + # AIX 5 now supports IA64 processor + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + else + _LT_TAGVAR(lt_prog_compiler_static, $1)='-bnso -bI:/lib/syscalls.exp' + fi + ;; + chorus*) + case $cc_basename in + cxch68*) + # Green Hills C++ Compiler + # _LT_TAGVAR(lt_prog_compiler_static, $1)="--no_auto_instantiation -u __main -u __premain -u _abort -r $COOL_DIR/lib/libOrb.a $MVME_DIR/lib/CC/libC.a $MVME_DIR/lib/classix/libcx.s.a" + ;; + esac + ;; + mingw* | cygwin* | os2* | pw32* | cegcc*) + # This hack is so that the source file can tell whether it is being + # built for inclusion in a dll (and should export symbols for example). + m4_if([$1], [GCJ], [], + [_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT']) + ;; + dgux*) + case $cc_basename in + ec++*) + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + ;; + ghcx*) + # Green Hills C++ Compiler + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic' + ;; + *) + ;; + esac + ;; + freebsd* | dragonfly*) + # FreeBSD uses GNU C++ + ;; + hpux9* | hpux10* | hpux11*) + case $cc_basename in + CC*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_static, $1)='${wl}-a ${wl}archive' + if test "$host_cpu" != ia64; then + _LT_TAGVAR(lt_prog_compiler_pic, $1)='+Z' + fi + ;; + aCC*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_static, $1)='${wl}-a ${wl}archive' + case $host_cpu in + hppa*64*|ia64*) + # +Z the default + ;; + *) + _LT_TAGVAR(lt_prog_compiler_pic, $1)='+Z' + ;; + esac + ;; + *) + ;; + esac + ;; + interix*) + # This is c89, which is MS Visual C++ (no shared libs) + # Anyone wants to do a port? + ;; + irix5* | irix6* | nonstopux*) + case $cc_basename in + CC*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' + # CC pic flag -KPIC is the default. + ;; + *) + ;; + esac + ;; + linux* | k*bsd*-gnu | kopensolaris*-gnu) + case $cc_basename in + KCC*) + # KAI C++ Compiler + _LT_TAGVAR(lt_prog_compiler_wl, $1)='--backend -Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' + ;; + ecpc* ) + # old Intel C++ for x86_64 which still supported -KPIC. + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' + ;; + icpc* ) + # Intel C++, used to be incompatible with GCC. + # ICC 10 doesn't accept -KPIC any more. + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' + ;; + pgCC* | pgcpp*) + # Portland Group C++ compiler + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fpic' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + cxx*) + # Compaq C++ + # Make sure the PIC flag is empty. It appears that all Alpha + # Linux and Compaq Tru64 Unix objects are PIC. + _LT_TAGVAR(lt_prog_compiler_pic, $1)= + _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' + ;; + xlc* | xlC* | bgxl[[cC]]* | mpixl[[cC]]*) + # IBM XL 8.0, 9.0 on PPC and BlueGene + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-qpic' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-qstaticlink' + ;; + *) + case `$CC -V 2>&1 | sed 5q` in + *Sun\ C*) + # Sun C++ 5.9 + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ' + ;; + esac + ;; + esac + ;; + lynxos*) + ;; + m88k*) + ;; + mvs*) + case $cc_basename in + cxx*) + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-W c,exportall' + ;; + *) + ;; + esac + ;; + netbsd*) + ;; + *qnx* | *nto*) + # QNX uses GNU C++, but need to define -shared option too, otherwise + # it will coredump. + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared' + ;; + osf3* | osf4* | osf5*) + case $cc_basename in + KCC*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='--backend -Wl,' + ;; + RCC*) + # Rational C++ 2.4.1 + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic' + ;; + cxx*) + # Digital/Compaq C++ + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + # Make sure the PIC flag is empty. It appears that all Alpha + # Linux and Compaq Tru64 Unix objects are PIC. + _LT_TAGVAR(lt_prog_compiler_pic, $1)= + _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' + ;; + *) + ;; + esac + ;; + psos*) + ;; + solaris*) + case $cc_basename in + CC* | sunCC*) + # Sun C++ 4.2, 5.x and Centerline C++ + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ' + ;; + gcx*) + # Green Hills C++ Compiler + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-PIC' + ;; + *) + ;; + esac + ;; + sunos4*) + case $cc_basename in + CC*) + # Sun C++ 4.x + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + lcc*) + # Lucid + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic' + ;; + *) + ;; + esac + ;; + sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*) + case $cc_basename in + CC*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + esac + ;; + tandem*) + case $cc_basename in + NCC*) + # NonStop-UX NCC 3.20 + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + ;; + *) + ;; + esac + ;; + vxworks*) + ;; + *) + _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no + ;; + esac + fi +], +[ + if test "$GCC" = yes; then + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' + + case $host_os in + aix*) + # All AIX code is PIC. + if test "$host_cpu" = ia64; then + # AIX 5 now supports IA64 processor + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + fi + ;; + + amigaos*) + case $host_cpu in + powerpc) + # see comment about AmigaOS4 .so support + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' + ;; + m68k) + # FIXME: we need at least 68020 code to build shared libraries, but + # adding the `-m68020' flag to GCC prevents building anything better, + # like `-m68040'. + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-m68020 -resident32 -malways-restore-a4' + ;; + esac + ;; + + beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*) + # PIC is the default for these OSes. + ;; + + mingw* | cygwin* | pw32* | os2* | cegcc*) + # This hack is so that the source file can tell whether it is being + # built for inclusion in a dll (and should export symbols for example). + # Although the cygwin gcc ignores -fPIC, still need this for old-style + # (--disable-auto-import) libraries + m4_if([$1], [GCJ], [], + [_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT']) + ;; + + darwin* | rhapsody*) + # PIC is the default on this platform + # Common symbols not allowed in MH_DYLIB files + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fno-common' + ;; + + haiku*) + # PIC is the default for Haiku. + # The "-static" flag exists, but is broken. + _LT_TAGVAR(lt_prog_compiler_static, $1)= + ;; + + hpux*) + # PIC is the default for 64-bit PA HP-UX, but not for 32-bit + # PA HP-UX. On IA64 HP-UX, PIC is the default but the pic flag + # sets the default TLS model and affects inlining. + case $host_cpu in + hppa*64*) + # +Z the default + ;; + *) + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' + ;; + esac + ;; + + interix[[3-9]]*) + # Interix 3.x gcc -fpic/-fPIC options generate broken code. + # Instead, we relocate shared libraries at runtime. + ;; + + msdosdjgpp*) + # Just because we use GCC doesn't mean we suddenly get shared libraries + # on systems that don't support them. + _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no + enable_shared=no + ;; + + *nto* | *qnx*) + # QNX uses GNU C++, but need to define -shared option too, otherwise + # it will coredump. + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared' + ;; + + sysv4*MP*) + if test -d /usr/nec; then + _LT_TAGVAR(lt_prog_compiler_pic, $1)=-Kconform_pic + fi + ;; + + *) + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' + ;; + esac + + case $cc_basename in + nvcc*) # Cuda Compiler Driver 2.2 + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Xlinker ' + if test -n "$_LT_TAGVAR(lt_prog_compiler_pic, $1)"; then + _LT_TAGVAR(lt_prog_compiler_pic, $1)="-Xcompiler $_LT_TAGVAR(lt_prog_compiler_pic, $1)" + fi + ;; + esac + else + # PORTME Check for flag to pass linker flags through the system compiler. + case $host_os in + aix*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + if test "$host_cpu" = ia64; then + # AIX 5 now supports IA64 processor + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + else + _LT_TAGVAR(lt_prog_compiler_static, $1)='-bnso -bI:/lib/syscalls.exp' + fi + ;; + + mingw* | cygwin* | pw32* | os2* | cegcc*) + # This hack is so that the source file can tell whether it is being + # built for inclusion in a dll (and should export symbols for example). + m4_if([$1], [GCJ], [], + [_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT']) + ;; + + hpux9* | hpux10* | hpux11*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but + # not for PA HP-UX. + case $host_cpu in + hppa*64*|ia64*) + # +Z the default + ;; + *) + _LT_TAGVAR(lt_prog_compiler_pic, $1)='+Z' + ;; + esac + # Is there a better lt_prog_compiler_static that works with the bundled CC? + _LT_TAGVAR(lt_prog_compiler_static, $1)='${wl}-a ${wl}archive' + ;; + + irix5* | irix6* | nonstopux*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + # PIC (with -KPIC) is the default. + _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' + ;; + + linux* | k*bsd*-gnu | kopensolaris*-gnu) + case $cc_basename in + # old Intel for x86_64 which still supported -KPIC. + ecc*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' + ;; + # icc used to be incompatible with GCC. + # ICC 10 doesn't accept -KPIC any more. + icc* | ifort*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' + ;; + # Lahey Fortran 8.1. + lf95*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='--shared' + _LT_TAGVAR(lt_prog_compiler_static, $1)='--static' + ;; + nagfor*) + # NAG Fortran compiler + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,-Wl,,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-PIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + pgcc* | pgf77* | pgf90* | pgf95* | pgfortran*) + # Portland Group compilers (*not* the Pentium gcc compiler, + # which looks to be a dead project) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fpic' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + ccc*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + # All Alpha code is PIC. + _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' + ;; + xl* | bgxl* | bgf* | mpixl*) + # IBM XL C 8.0/Fortran 10.1, 11.1 on PPC and BlueGene + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-qpic' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-qstaticlink' + ;; + *) + case `$CC -V 2>&1 | sed 5q` in + *Sun\ Ceres\ Fortran* | *Sun*Fortran*\ [[1-7]].* | *Sun*Fortran*\ 8.[[0-3]]*) + # Sun Fortran 8.3 passes all unrecognized flags to the linker + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + _LT_TAGVAR(lt_prog_compiler_wl, $1)='' + ;; + *Sun\ F* | *Sun*Fortran*) + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ' + ;; + *Sun\ C*) + # Sun C 5.9 + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + ;; + *Intel*\ [[CF]]*Compiler*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' + ;; + *Portland\ Group*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fpic' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + esac + ;; + esac + ;; + + newsos6) + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + + *nto* | *qnx*) + # QNX uses GNU C++, but need to define -shared option too, otherwise + # it will coredump. + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared' + ;; + + osf3* | osf4* | osf5*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + # All OSF/1 code is PIC. + _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' + ;; + + rdos*) + _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' + ;; + + solaris*) + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + case $cc_basename in + f77* | f90* | f95* | sunf77* | sunf90* | sunf95*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ';; + *) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,';; + esac + ;; + + sunos4*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-PIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + + sysv4 | sysv4.2uw2* | sysv4.3*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + + sysv4*MP*) + if test -d /usr/nec ;then + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-Kconform_pic' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + fi + ;; + + sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + + unicos*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no + ;; + + uts4*) + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + + *) + _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no + ;; + esac + fi +]) +case $host_os in + # For platforms which do not support PIC, -DPIC is meaningless: + *djgpp*) + _LT_TAGVAR(lt_prog_compiler_pic, $1)= + ;; + *) + _LT_TAGVAR(lt_prog_compiler_pic, $1)="$_LT_TAGVAR(lt_prog_compiler_pic, $1)@&t@m4_if([$1],[],[ -DPIC],[m4_if([$1],[CXX],[ -DPIC],[])])" + ;; +esac + +AC_CACHE_CHECK([for $compiler option to produce PIC], + [_LT_TAGVAR(lt_cv_prog_compiler_pic, $1)], + [_LT_TAGVAR(lt_cv_prog_compiler_pic, $1)=$_LT_TAGVAR(lt_prog_compiler_pic, $1)]) +_LT_TAGVAR(lt_prog_compiler_pic, $1)=$_LT_TAGVAR(lt_cv_prog_compiler_pic, $1) + +# +# Check to make sure the PIC flag actually works. +# +if test -n "$_LT_TAGVAR(lt_prog_compiler_pic, $1)"; then + _LT_COMPILER_OPTION([if $compiler PIC flag $_LT_TAGVAR(lt_prog_compiler_pic, $1) works], + [_LT_TAGVAR(lt_cv_prog_compiler_pic_works, $1)], + [$_LT_TAGVAR(lt_prog_compiler_pic, $1)@&t@m4_if([$1],[],[ -DPIC],[m4_if([$1],[CXX],[ -DPIC],[])])], [], + [case $_LT_TAGVAR(lt_prog_compiler_pic, $1) in + "" | " "*) ;; + *) _LT_TAGVAR(lt_prog_compiler_pic, $1)=" $_LT_TAGVAR(lt_prog_compiler_pic, $1)" ;; + esac], + [_LT_TAGVAR(lt_prog_compiler_pic, $1)= + _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no]) +fi +_LT_TAGDECL([pic_flag], [lt_prog_compiler_pic], [1], + [Additional compiler flags for building library objects]) + +_LT_TAGDECL([wl], [lt_prog_compiler_wl], [1], + [How to pass a linker flag through the compiler]) +# +# Check to make sure the static flag actually works. +# +wl=$_LT_TAGVAR(lt_prog_compiler_wl, $1) eval lt_tmp_static_flag=\"$_LT_TAGVAR(lt_prog_compiler_static, $1)\" +_LT_LINKER_OPTION([if $compiler static flag $lt_tmp_static_flag works], + _LT_TAGVAR(lt_cv_prog_compiler_static_works, $1), + $lt_tmp_static_flag, + [], + [_LT_TAGVAR(lt_prog_compiler_static, $1)=]) +_LT_TAGDECL([link_static_flag], [lt_prog_compiler_static], [1], + [Compiler flag to prevent dynamic linking]) +])# _LT_COMPILER_PIC + + +# _LT_LINKER_SHLIBS([TAGNAME]) +# ---------------------------- +# See if the linker supports building shared libraries. +m4_defun([_LT_LINKER_SHLIBS], +[AC_REQUIRE([LT_PATH_LD])dnl +AC_REQUIRE([LT_PATH_NM])dnl +m4_require([_LT_PATH_MANIFEST_TOOL])dnl +m4_require([_LT_FILEUTILS_DEFAULTS])dnl +m4_require([_LT_DECL_EGREP])dnl +m4_require([_LT_DECL_SED])dnl +m4_require([_LT_CMD_GLOBAL_SYMBOLS])dnl +m4_require([_LT_TAG_COMPILER])dnl +AC_MSG_CHECKING([whether the $compiler linker ($LD) supports shared libraries]) +m4_if([$1], [CXX], [ + _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' + _LT_TAGVAR(exclude_expsyms, $1)=['_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*'] + case $host_os in + aix[[4-9]]*) + # If we're using GNU nm, then we don't want the "-C" option. + # -C means demangle to AIX nm, but means don't demangle with GNU nm + # Also, AIX nm treats weak defined symbols like other global defined + # symbols, whereas GNU nm marks them as "W". + if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then + _LT_TAGVAR(export_symbols_cmds, $1)='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W")) && ([substr](\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols' + else + _LT_TAGVAR(export_symbols_cmds, $1)='$NM -BCpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B")) && ([substr](\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols' + fi + ;; + pw32*) + _LT_TAGVAR(export_symbols_cmds, $1)="$ltdll_cmds" + ;; + cygwin* | mingw* | cegcc*) + case $cc_basename in + cl*) + _LT_TAGVAR(exclude_expsyms, $1)='_NULL_IMPORT_DESCRIPTOR|_IMPORT_DESCRIPTOR_.*' + ;; + *) + _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[[BCDGRS]][[ ]]/s/.*[[ ]]\([[^ ]]*\)/\1 DATA/;s/^.*[[ ]]__nm__\([[^ ]]*\)[[ ]][[^ ]]*/\1 DATA/;/^I[[ ]]/d;/^[[AITW]][[ ]]/s/.* //'\'' | sort | uniq > $export_symbols' + _LT_TAGVAR(exclude_expsyms, $1)=['[_]+GLOBAL_OFFSET_TABLE_|[_]+GLOBAL__[FID]_.*|[_]+head_[A-Za-z0-9_]+_dll|[A-Za-z0-9_]+_dll_iname'] + ;; + esac + ;; + *) + _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' + ;; + esac +], [ + runpath_var= + _LT_TAGVAR(allow_undefined_flag, $1)= + _LT_TAGVAR(always_export_symbols, $1)=no + _LT_TAGVAR(archive_cmds, $1)= + _LT_TAGVAR(archive_expsym_cmds, $1)= + _LT_TAGVAR(compiler_needs_object, $1)=no + _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no + _LT_TAGVAR(export_dynamic_flag_spec, $1)= + _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' + _LT_TAGVAR(hardcode_automatic, $1)=no + _LT_TAGVAR(hardcode_direct, $1)=no + _LT_TAGVAR(hardcode_direct_absolute, $1)=no + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)= + _LT_TAGVAR(hardcode_libdir_separator, $1)= + _LT_TAGVAR(hardcode_minus_L, $1)=no + _LT_TAGVAR(hardcode_shlibpath_var, $1)=unsupported + _LT_TAGVAR(inherit_rpath, $1)=no + _LT_TAGVAR(link_all_deplibs, $1)=unknown + _LT_TAGVAR(module_cmds, $1)= + _LT_TAGVAR(module_expsym_cmds, $1)= + _LT_TAGVAR(old_archive_from_new_cmds, $1)= + _LT_TAGVAR(old_archive_from_expsyms_cmds, $1)= + _LT_TAGVAR(thread_safe_flag_spec, $1)= + _LT_TAGVAR(whole_archive_flag_spec, $1)= + # include_expsyms should be a list of space-separated symbols to be *always* + # included in the symbol list + _LT_TAGVAR(include_expsyms, $1)= + # exclude_expsyms can be an extended regexp of symbols to exclude + # it will be wrapped by ` (' and `)$', so one must not match beginning or + # end of line. Example: `a|bc|.*d.*' will exclude the symbols `a' and `bc', + # as well as any symbol that contains `d'. + _LT_TAGVAR(exclude_expsyms, $1)=['_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*'] + # Although _GLOBAL_OFFSET_TABLE_ is a valid symbol C name, most a.out + # platforms (ab)use it in PIC code, but their linkers get confused if + # the symbol is explicitly referenced. Since portable code cannot + # rely on this symbol name, it's probably fine to never include it in + # preloaded symbol tables. + # Exclude shared library initialization/finalization symbols. +dnl Note also adjust exclude_expsyms for C++ above. + extract_expsyms_cmds= + + case $host_os in + cygwin* | mingw* | pw32* | cegcc*) + # FIXME: the MSVC++ port hasn't been tested in a loooong time + # When not using gcc, we currently assume that we are using + # Microsoft Visual C++. + if test "$GCC" != yes; then + with_gnu_ld=no + fi + ;; + interix*) + # we just hope/assume this is gcc and not c89 (= MSVC++) + with_gnu_ld=yes + ;; + openbsd*) + with_gnu_ld=no + ;; + esac + + _LT_TAGVAR(ld_shlibs, $1)=yes + + # On some targets, GNU ld is compatible enough with the native linker + # that we're better off using the native interface for both. + lt_use_gnu_ld_interface=no + if test "$with_gnu_ld" = yes; then + case $host_os in + aix*) + # The AIX port of GNU ld has always aspired to compatibility + # with the native linker. However, as the warning in the GNU ld + # block says, versions before 2.19.5* couldn't really create working + # shared libraries, regardless of the interface used. + case `$LD -v 2>&1` in + *\ \(GNU\ Binutils\)\ 2.19.5*) ;; + *\ \(GNU\ Binutils\)\ 2.[[2-9]]*) ;; + *\ \(GNU\ Binutils\)\ [[3-9]]*) ;; + *) + lt_use_gnu_ld_interface=yes + ;; + esac + ;; + *) + lt_use_gnu_ld_interface=yes + ;; + esac + fi + + if test "$lt_use_gnu_ld_interface" = yes; then + # If archive_cmds runs LD, not CC, wlarc should be empty + wlarc='${wl}' + + # Set some defaults for GNU ld with shared library support. These + # are reset later if shared libraries are not supported. Putting them + # here allows them to be overridden if necessary. + runpath_var=LD_RUN_PATH + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic' + # ancient GNU ld didn't support --whole-archive et. al. + if $LD --help 2>&1 | $GREP 'no-whole-archive' > /dev/null; then + _LT_TAGVAR(whole_archive_flag_spec, $1)="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive' + else + _LT_TAGVAR(whole_archive_flag_spec, $1)= + fi + supports_anon_versioning=no + case `$LD -v 2>&1` in + *GNU\ gold*) supports_anon_versioning=yes ;; + *\ [[01]].* | *\ 2.[[0-9]].* | *\ 2.10.*) ;; # catch versions < 2.11 + *\ 2.11.93.0.2\ *) supports_anon_versioning=yes ;; # RH7.3 ... + *\ 2.11.92.0.12\ *) supports_anon_versioning=yes ;; # Mandrake 8.2 ... + *\ 2.11.*) ;; # other 2.11 versions + *) supports_anon_versioning=yes ;; + esac + + # See if GNU ld supports shared libraries. + case $host_os in + aix[[3-9]]*) + # On AIX/PPC, the GNU linker is very broken + if test "$host_cpu" != ia64; then + _LT_TAGVAR(ld_shlibs, $1)=no + cat <<_LT_EOF 1>&2 + +*** Warning: the GNU linker, at least up to release 2.19, is reported +*** to be unable to reliably create shared libraries on AIX. +*** Therefore, libtool is disabling shared libraries support. If you +*** really care for shared libraries, you may want to install binutils +*** 2.20 or above, or modify your PATH so that a non-GNU linker is found. +*** You will then need to restart the configuration process. + +_LT_EOF + fi + ;; + + amigaos*) + case $host_cpu in + powerpc) + # see comment about AmigaOS4 .so support + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='' + ;; + m68k) + _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_TAGVAR(hardcode_minus_L, $1)=yes + ;; + esac + ;; + + beos*) + if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then + _LT_TAGVAR(allow_undefined_flag, $1)=unsupported + # Joseph Beckenbach says some releases of gcc + # support --undefined. This deserves some investigation. FIXME + _LT_TAGVAR(archive_cmds, $1)='$CC -nostart $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + else + _LT_TAGVAR(ld_shlibs, $1)=no + fi + ;; + + cygwin* | mingw* | pw32* | cegcc*) + # _LT_TAGVAR(hardcode_libdir_flag_spec, $1) is actually meaningless, + # as there is no search path for DLLs. + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-all-symbols' + _LT_TAGVAR(allow_undefined_flag, $1)=unsupported + _LT_TAGVAR(always_export_symbols, $1)=no + _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes + _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[[BCDGRS]][[ ]]/s/.*[[ ]]\([[^ ]]*\)/\1 DATA/;s/^.*[[ ]]__nm__\([[^ ]]*\)[[ ]][[^ ]]*/\1 DATA/;/^I[[ ]]/d;/^[[AITW]][[ ]]/s/.* //'\'' | sort | uniq > $export_symbols' + _LT_TAGVAR(exclude_expsyms, $1)=['[_]+GLOBAL_OFFSET_TABLE_|[_]+GLOBAL__[FID]_.*|[_]+head_[A-Za-z0-9_]+_dll|[A-Za-z0-9_]+_dll_iname'] + + if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' + # If the export-symbols file already is a .def file (1st line + # is EXPORTS), use it as is; otherwise, prepend... + _LT_TAGVAR(archive_expsym_cmds, $1)='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then + cp $export_symbols $output_objdir/$soname.def; + else + echo EXPORTS > $output_objdir/$soname.def; + cat $export_symbols >> $output_objdir/$soname.def; + fi~ + $CC -shared $output_objdir/$soname.def $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' + else + _LT_TAGVAR(ld_shlibs, $1)=no + fi + ;; + + haiku*) + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + _LT_TAGVAR(link_all_deplibs, $1)=yes + ;; + + interix[[3-9]]*) + _LT_TAGVAR(hardcode_direct, $1)=no + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' + # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc. + # Instead, shared libraries are loaded at an image base (0x10000000 by + # default) and relocated if they conflict, which is a slow very memory + # consuming and fragmenting process. To avoid this, we pick a random, + # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link + # time. Moving up from 0x10000000 also allows more sbrk(2) space. + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='sed "s,^,_," $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--retain-symbols-file,$output_objdir/$soname.expsym ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' + ;; + + gnu* | linux* | tpf* | k*bsd*-gnu | kopensolaris*-gnu) + tmp_diet=no + if test "$host_os" = linux-dietlibc; then + case $cc_basename in + diet\ *) tmp_diet=yes;; # linux-dietlibc with static linking (!diet-dyn) + esac + fi + if $LD --help 2>&1 | $EGREP ': supported targets:.* elf' > /dev/null \ + && test "$tmp_diet" = no + then + tmp_addflag=' $pic_flag' + tmp_sharedflag='-shared' + case $cc_basename,$host_cpu in + pgcc*) # Portland Group C compiler + _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' + tmp_addflag=' $pic_flag' + ;; + pgf77* | pgf90* | pgf95* | pgfortran*) + # Portland Group f77 and f90 compilers + _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' + tmp_addflag=' $pic_flag -Mnomain' ;; + ecc*,ia64* | icc*,ia64*) # Intel C compiler on ia64 + tmp_addflag=' -i_dynamic' ;; + efc*,ia64* | ifort*,ia64*) # Intel Fortran compiler on ia64 + tmp_addflag=' -i_dynamic -nofor_main' ;; + ifc* | ifort*) # Intel Fortran compiler + tmp_addflag=' -nofor_main' ;; + lf95*) # Lahey Fortran 8.1 + _LT_TAGVAR(whole_archive_flag_spec, $1)= + tmp_sharedflag='--shared' ;; + xl[[cC]]* | bgxl[[cC]]* | mpixl[[cC]]*) # IBM XL C 8.0 on PPC (deal with xlf below) + tmp_sharedflag='-qmkshrobj' + tmp_addflag= ;; + nvcc*) # Cuda Compiler Driver 2.2 + _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' + _LT_TAGVAR(compiler_needs_object, $1)=yes + ;; + esac + case `$CC -V 2>&1 | sed 5q` in + *Sun\ C*) # Sun C 5.9 + _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' + _LT_TAGVAR(compiler_needs_object, $1)=yes + tmp_sharedflag='-G' ;; + *Sun\ F*) # Sun Fortran 8.3 + tmp_sharedflag='-G' ;; + esac + _LT_TAGVAR(archive_cmds, $1)='$CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + + if test "x$supports_anon_versioning" = xyes; then + _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $output_objdir/$libname.ver~ + cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ + echo "local: *; };" >> $output_objdir/$libname.ver~ + $CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-version-script ${wl}$output_objdir/$libname.ver -o $lib' + fi + + case $cc_basename in + xlf* | bgf* | bgxlf* | mpixlf*) + # IBM XL Fortran 10.1 on PPC cannot create shared libs itself + _LT_TAGVAR(whole_archive_flag_spec, $1)='--whole-archive$convenience --no-whole-archive' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' + _LT_TAGVAR(archive_cmds, $1)='$LD -shared $libobjs $deplibs $linker_flags -soname $soname -o $lib' + if test "x$supports_anon_versioning" = xyes; then + _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $output_objdir/$libname.ver~ + cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ + echo "local: *; };" >> $output_objdir/$libname.ver~ + $LD -shared $libobjs $deplibs $linker_flags -soname $soname -version-script $output_objdir/$libname.ver -o $lib' + fi + ;; + esac + else + _LT_TAGVAR(ld_shlibs, $1)=no + fi + ;; + + netbsd*) + if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then + _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable $libobjs $deplibs $linker_flags -o $lib' + wlarc= + else + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + fi + ;; + + solaris*) + if $LD -v 2>&1 | $GREP 'BFD 2\.8' > /dev/null; then + _LT_TAGVAR(ld_shlibs, $1)=no + cat <<_LT_EOF 1>&2 + +*** Warning: The releases 2.8.* of the GNU linker cannot reliably +*** create shared libraries on Solaris systems. Therefore, libtool +*** is disabling shared libraries support. We urge you to upgrade GNU +*** binutils to release 2.9.1 or newer. Another option is to modify +*** your PATH or compiler configuration so that the native linker is +*** used, and then restart. + +_LT_EOF + elif $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + else + _LT_TAGVAR(ld_shlibs, $1)=no + fi + ;; + + sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX*) + case `$LD -v 2>&1` in + *\ [[01]].* | *\ 2.[[0-9]].* | *\ 2.1[[0-5]].*) + _LT_TAGVAR(ld_shlibs, $1)=no + cat <<_LT_EOF 1>&2 + +*** Warning: Releases of the GNU linker prior to 2.16.91.0.3 can not +*** reliably create shared libraries on SCO systems. Therefore, libtool +*** is disabling shared libraries support. We urge you to upgrade GNU +*** binutils to release 2.16.91.0.3 or newer. Another option is to modify +*** your PATH or compiler configuration so that the native linker is +*** used, and then restart. + +_LT_EOF + ;; + *) + # For security reasons, it is highly recommended that you always + # use absolute paths for naming shared libraries, and exclude the + # DT_RUNPATH tag from executables and libraries. But doing so + # requires that you compile everything twice, which is a pain. + if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + else + _LT_TAGVAR(ld_shlibs, $1)=no + fi + ;; + esac + ;; + + sunos4*) + _LT_TAGVAR(archive_cmds, $1)='$LD -assert pure-text -Bshareable -o $lib $libobjs $deplibs $linker_flags' + wlarc= + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + *) + if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + else + _LT_TAGVAR(ld_shlibs, $1)=no + fi + ;; + esac + + if test "$_LT_TAGVAR(ld_shlibs, $1)" = no; then + runpath_var= + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)= + _LT_TAGVAR(export_dynamic_flag_spec, $1)= + _LT_TAGVAR(whole_archive_flag_spec, $1)= + fi + else + # PORTME fill in a description of your system's linker (not GNU ld) + case $host_os in + aix3*) + _LT_TAGVAR(allow_undefined_flag, $1)=unsupported + _LT_TAGVAR(always_export_symbols, $1)=yes + _LT_TAGVAR(archive_expsym_cmds, $1)='$LD -o $output_objdir/$soname $libobjs $deplibs $linker_flags -bE:$export_symbols -T512 -H512 -bM:SRE~$AR $AR_FLAGS $lib $output_objdir/$soname' + # Note: this linker hardcodes the directories in LIBPATH if there + # are no directories specified by -L. + _LT_TAGVAR(hardcode_minus_L, $1)=yes + if test "$GCC" = yes && test -z "$lt_prog_compiler_static"; then + # Neither direct hardcoding nor static linking is supported with a + # broken collect2. + _LT_TAGVAR(hardcode_direct, $1)=unsupported + fi + ;; + + aix[[4-9]]*) + if test "$host_cpu" = ia64; then + # On IA64, the linker does run time linking by default, so we don't + # have to do anything special. + aix_use_runtimelinking=no + exp_sym_flag='-Bexport' + no_entry_flag="" + else + # If we're using GNU nm, then we don't want the "-C" option. + # -C means demangle to AIX nm, but means don't demangle with GNU nm + # Also, AIX nm treats weak defined symbols like other global + # defined symbols, whereas GNU nm marks them as "W". + if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then + _LT_TAGVAR(export_symbols_cmds, $1)='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W")) && ([substr](\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols' + else + _LT_TAGVAR(export_symbols_cmds, $1)='$NM -BCpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B")) && ([substr](\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols' + fi + aix_use_runtimelinking=no + + # Test if we are trying to use run time linking or normal + # AIX style linking. If -brtl is somewhere in LDFLAGS, we + # need to do runtime linking. + case $host_os in aix4.[[23]]|aix4.[[23]].*|aix[[5-9]]*) + for ld_flag in $LDFLAGS; do + if (test $ld_flag = "-brtl" || test $ld_flag = "-Wl,-brtl"); then + aix_use_runtimelinking=yes + break + fi + done + ;; + esac + + exp_sym_flag='-bexport' + no_entry_flag='-bnoentry' + fi + + # When large executables or shared objects are built, AIX ld can + # have problems creating the table of contents. If linking a library + # or program results in "error TOC overflow" add -mminimal-toc to + # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not + # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS. + + _LT_TAGVAR(archive_cmds, $1)='' + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_direct_absolute, $1)=yes + _LT_TAGVAR(hardcode_libdir_separator, $1)=':' + _LT_TAGVAR(link_all_deplibs, $1)=yes + _LT_TAGVAR(file_list_spec, $1)='${wl}-f,' + + if test "$GCC" = yes; then + case $host_os in aix4.[[012]]|aix4.[[012]].*) + # We only want to do this on AIX 4.2 and lower, the check + # below for broken collect2 doesn't work under 4.3+ + collect2name=`${CC} -print-prog-name=collect2` + if test -f "$collect2name" && + strings "$collect2name" | $GREP resolve_lib_name >/dev/null + then + # We have reworked collect2 + : + else + # We have old collect2 + _LT_TAGVAR(hardcode_direct, $1)=unsupported + # It fails to find uninstalled libraries when the uninstalled + # path is not listed in the libpath. Setting hardcode_minus_L + # to unsupported forces relinking + _LT_TAGVAR(hardcode_minus_L, $1)=yes + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)= + fi + ;; + esac + shared_flag='-shared' + if test "$aix_use_runtimelinking" = yes; then + shared_flag="$shared_flag "'${wl}-G' + fi + else + # not using gcc + if test "$host_cpu" = ia64; then + # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release + # chokes on -Wl,-G. The following line is correct: + shared_flag='-G' + else + if test "$aix_use_runtimelinking" = yes; then + shared_flag='${wl}-G' + else + shared_flag='${wl}-bM:SRE' + fi + fi + fi + + _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-bexpall' + # It seems that -bexpall does not export symbols beginning with + # underscore (_), so it is better to generate a list of symbols to export. + _LT_TAGVAR(always_export_symbols, $1)=yes + if test "$aix_use_runtimelinking" = yes; then + # Warning - without using the other runtime loading flags (-brtl), + # -berok will link without error, but may produce a broken library. + _LT_TAGVAR(allow_undefined_flag, $1)='-berok' + # Determine the default libpath from the value encoded in an + # empty executable. + _LT_SYS_MODULE_PATH_AIX([$1]) + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath" + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then func_echo_all "${wl}${allow_undefined_flag}"; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag" + else + if test "$host_cpu" = ia64; then + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R $libdir:/usr/lib:/lib' + _LT_TAGVAR(allow_undefined_flag, $1)="-z nodefs" + _LT_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$exp_sym_flag:\$export_symbols" + else + # Determine the default libpath from the value encoded in an + # empty executable. + _LT_SYS_MODULE_PATH_AIX([$1]) + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath" + # Warning - without using the other run time loading flags, + # -berok will link without error, but may produce a broken library. + _LT_TAGVAR(no_undefined_flag, $1)=' ${wl}-bernotok' + _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-berok' + if test "$with_gnu_ld" = yes; then + # We only use this code for GNU lds that support --whole-archive. + _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive$convenience ${wl}--no-whole-archive' + else + # Exported symbols can be pulled into shared objects from archives + _LT_TAGVAR(whole_archive_flag_spec, $1)='$convenience' + fi + _LT_TAGVAR(archive_cmds_need_lc, $1)=yes + # This is similar to how AIX traditionally builds its shared libraries. + _LT_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs ${wl}-bnoentry $compiler_flags ${wl}-bE:$export_symbols${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname' + fi + fi + ;; + + amigaos*) + case $host_cpu in + powerpc) + # see comment about AmigaOS4 .so support + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='' + ;; + m68k) + _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_TAGVAR(hardcode_minus_L, $1)=yes + ;; + esac + ;; + + bsdi[[45]]*) + _LT_TAGVAR(export_dynamic_flag_spec, $1)=-rdynamic + ;; + + cygwin* | mingw* | pw32* | cegcc*) + # When not using gcc, we currently assume that we are using + # Microsoft Visual C++. + # hardcode_libdir_flag_spec is actually meaningless, as there is + # no search path for DLLs. + case $cc_basename in + cl*) + # Native MSVC + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)=' ' + _LT_TAGVAR(allow_undefined_flag, $1)=unsupported + _LT_TAGVAR(always_export_symbols, $1)=yes + _LT_TAGVAR(file_list_spec, $1)='@' + # Tell ltmain to make .lib files, not .a files. + libext=lib + # Tell ltmain to make .dll files, not .so files. + shrext_cmds=".dll" + # FIXME: Setting linknames here is a bad hack. + _LT_TAGVAR(archive_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $compiler_flags $deplibs -Wl,-dll~linknames=' + _LT_TAGVAR(archive_expsym_cmds, $1)='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then + sed -n -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' -e '1\\\!p' < $export_symbols > $output_objdir/$soname.exp; + else + sed -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' < $export_symbols > $output_objdir/$soname.exp; + fi~ + $CC -o $tool_output_objdir$soname $libobjs $compiler_flags $deplibs "@$tool_output_objdir$soname.exp" -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~ + linknames=' + # The linker will not automatically build a static lib if we build a DLL. + # _LT_TAGVAR(old_archive_from_new_cmds, $1)='true' + _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes + _LT_TAGVAR(exclude_expsyms, $1)='_NULL_IMPORT_DESCRIPTOR|_IMPORT_DESCRIPTOR_.*' + _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[[BCDGRS]][[ ]]/s/.*[[ ]]\([[^ ]]*\)/\1,DATA/'\'' | $SED -e '\''/^[[AITW]][[ ]]/s/.*[[ ]]//'\'' | sort | uniq > $export_symbols' + # Don't use ranlib + _LT_TAGVAR(old_postinstall_cmds, $1)='chmod 644 $oldlib' + _LT_TAGVAR(postlink_cmds, $1)='lt_outputfile="@OUTPUT@"~ + lt_tool_outputfile="@TOOL_OUTPUT@"~ + case $lt_outputfile in + *.exe|*.EXE) ;; + *) + lt_outputfile="$lt_outputfile.exe" + lt_tool_outputfile="$lt_tool_outputfile.exe" + ;; + esac~ + if test "$MANIFEST_TOOL" != ":" && test -f "$lt_outputfile.manifest"; then + $MANIFEST_TOOL -manifest "$lt_tool_outputfile.manifest" -outputresource:"$lt_tool_outputfile" || exit 1; + $RM "$lt_outputfile.manifest"; + fi' + ;; + *) + # Assume MSVC wrapper + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)=' ' + _LT_TAGVAR(allow_undefined_flag, $1)=unsupported + # Tell ltmain to make .lib files, not .a files. + libext=lib + # Tell ltmain to make .dll files, not .so files. + shrext_cmds=".dll" + # FIXME: Setting linknames here is a bad hack. + _LT_TAGVAR(archive_cmds, $1)='$CC -o $lib $libobjs $compiler_flags `func_echo_all "$deplibs" | $SED '\''s/ -lc$//'\''` -link -dll~linknames=' + # The linker will automatically build a .lib file if we build a DLL. + _LT_TAGVAR(old_archive_from_new_cmds, $1)='true' + # FIXME: Should let the user specify the lib program. + _LT_TAGVAR(old_archive_cmds, $1)='lib -OUT:$oldlib$oldobjs$old_deplibs' + _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes + ;; + esac + ;; + + darwin* | rhapsody*) + _LT_DARWIN_LINKER_FEATURES($1) + ;; + + dgux*) + _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + # FreeBSD 2.2.[012] allows us to include c++rt0.o to get C++ constructor + # support. Future versions do this automatically, but an explicit c++rt0.o + # does not break anything, and helps significantly (at the cost of a little + # extra space). + freebsd2.2*) + _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags /usr/lib/c++rt0.o' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + # Unfortunately, older versions of FreeBSD 2 do not have this feature. + freebsd2.*) + _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_minus_L, $1)=yes + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + # FreeBSD 3 and greater uses gcc -shared to do shared libraries. + freebsd* | dragonfly*) + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + hpux9*) + if test "$GCC" = yes; then + _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$CC -shared $pic_flag ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $libobjs $deplibs $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' + else + _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$LD -b +b $install_libdir -o $output_objdir/$soname $libobjs $deplibs $linker_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' + fi + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)=: + _LT_TAGVAR(hardcode_direct, $1)=yes + + # hardcode_minus_L: Not really in the search PATH, + # but as the default location of the library. + _LT_TAGVAR(hardcode_minus_L, $1)=yes + _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' + ;; + + hpux10*) + if test "$GCC" = yes && test "$with_gnu_ld" = no; then + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' + else + _LT_TAGVAR(archive_cmds, $1)='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags' + fi + if test "$with_gnu_ld" = no; then + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)=: + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_direct_absolute, $1)=yes + _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' + # hardcode_minus_L: Not really in the search PATH, + # but as the default location of the library. + _LT_TAGVAR(hardcode_minus_L, $1)=yes + fi + ;; + + hpux11*) + if test "$GCC" = yes && test "$with_gnu_ld" = no; then + case $host_cpu in + hppa*64*) + _LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' + ;; + ia64*) + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' + ;; + *) + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' + ;; + esac + else + case $host_cpu in + hppa*64*) + _LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' + ;; + ia64*) + _LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' + ;; + *) + m4_if($1, [], [ + # Older versions of the 11.00 compiler do not understand -b yet + # (HP92453-01 A.11.01.20 doesn't, HP92453-01 B.11.X.35175-35176.GP does) + _LT_LINKER_OPTION([if $CC understands -b], + _LT_TAGVAR(lt_cv_prog_compiler__b, $1), [-b], + [_LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags'], + [_LT_TAGVAR(archive_cmds, $1)='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags'])], + [_LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags']) + ;; + esac + fi + if test "$with_gnu_ld" = no; then + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)=: + + case $host_cpu in + hppa*64*|ia64*) + _LT_TAGVAR(hardcode_direct, $1)=no + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + *) + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_direct_absolute, $1)=yes + _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' + + # hardcode_minus_L: Not really in the search PATH, + # but as the default location of the library. + _LT_TAGVAR(hardcode_minus_L, $1)=yes + ;; + esac + fi + ;; + + irix5* | irix6* | nonstopux*) + if test "$GCC" = yes; then + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' + # Try to use the -exported_symbol ld option, if it does not + # work, assume that -exports_file does not work either and + # implicitly export all symbols. + # This should be the same for all languages, so no per-tag cache variable. + AC_CACHE_CHECK([whether the $host_os linker accepts -exported_symbol], + [lt_cv_irix_exported_symbol], + [save_LDFLAGS="$LDFLAGS" + LDFLAGS="$LDFLAGS -shared ${wl}-exported_symbol ${wl}foo ${wl}-update_registry ${wl}/dev/null" + AC_LINK_IFELSE( + [AC_LANG_SOURCE( + [AC_LANG_CASE([C], [[int foo (void) { return 0; }]], + [C++], [[int foo (void) { return 0; }]], + [Fortran 77], [[ + subroutine foo + end]], + [Fortran], [[ + subroutine foo + end]])])], + [lt_cv_irix_exported_symbol=yes], + [lt_cv_irix_exported_symbol=no]) + LDFLAGS="$save_LDFLAGS"]) + if test "$lt_cv_irix_exported_symbol" = yes; then + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations ${wl}-exports_file ${wl}$export_symbols -o $lib' + fi + else + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -exports_file $export_symbols -o $lib' + fi + _LT_TAGVAR(archive_cmds_need_lc, $1)='no' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)=: + _LT_TAGVAR(inherit_rpath, $1)=yes + _LT_TAGVAR(link_all_deplibs, $1)=yes + ;; + + netbsd*) + if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then + _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' # a.out + else + _LT_TAGVAR(archive_cmds, $1)='$LD -shared -o $lib $libobjs $deplibs $linker_flags' # ELF + fi + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + newsos6) + _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)=: + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + *nto* | *qnx*) + ;; + + openbsd*) + if test -f /usr/libexec/ld.so; then + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + _LT_TAGVAR(hardcode_direct_absolute, $1)=yes + if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-retain-symbols-file,$export_symbols' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' + else + case $host_os in + openbsd[[01]].* | openbsd2.[[0-7]] | openbsd2.[[0-7]].*) + _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' + ;; + *) + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' + ;; + esac + fi + else + _LT_TAGVAR(ld_shlibs, $1)=no + fi + ;; + + os2*) + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_TAGVAR(hardcode_minus_L, $1)=yes + _LT_TAGVAR(allow_undefined_flag, $1)=unsupported + _LT_TAGVAR(archive_cmds, $1)='$ECHO "LIBRARY $libname INITINSTANCE" > $output_objdir/$libname.def~$ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~echo DATA >> $output_objdir/$libname.def~echo " SINGLE NONSHARED" >> $output_objdir/$libname.def~echo EXPORTS >> $output_objdir/$libname.def~emxexp $libobjs >> $output_objdir/$libname.def~$CC -Zdll -Zcrtdll -o $lib $libobjs $deplibs $compiler_flags $output_objdir/$libname.def' + _LT_TAGVAR(old_archive_from_new_cmds, $1)='emximp -o $output_objdir/$libname.a $output_objdir/$libname.def' + ;; + + osf3*) + if test "$GCC" = yes; then + _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*' + _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' + else + _LT_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*' + _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib' + fi + _LT_TAGVAR(archive_cmds_need_lc, $1)='no' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)=: + ;; + + osf4* | osf5*) # as osf3* with the addition of -msym flag + if test "$GCC" = yes; then + _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*' + _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $pic_flag $libobjs $deplibs $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' + else + _LT_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*' + _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags -msym -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done; printf "%s\\n" "-hidden">> $lib.exp~ + $CC -shared${allow_undefined_flag} ${wl}-input ${wl}$lib.exp $compiler_flags $libobjs $deplibs -soname $soname `test -n "$verstring" && $ECHO "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib~$RM $lib.exp' + + # Both c and cxx compiler support -rpath directly + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir' + fi + _LT_TAGVAR(archive_cmds_need_lc, $1)='no' + _LT_TAGVAR(hardcode_libdir_separator, $1)=: + ;; + + solaris*) + _LT_TAGVAR(no_undefined_flag, $1)=' -z defs' + if test "$GCC" = yes; then + wlarc='${wl}' + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag ${wl}-z ${wl}text ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ + $CC -shared $pic_flag ${wl}-z ${wl}text ${wl}-M ${wl}$lib.exp ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp' + else + case `$CC -V 2>&1` in + *"Compilers 5.0"*) + wlarc='' + _LT_TAGVAR(archive_cmds, $1)='$LD -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $linker_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ + $LD -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$RM $lib.exp' + ;; + *) + wlarc='${wl}' + _LT_TAGVAR(archive_cmds, $1)='$CC -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ + $CC -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp' + ;; + esac + fi + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + case $host_os in + solaris2.[[0-5]] | solaris2.[[0-5]].*) ;; + *) + # The compiler driver will combine and reorder linker options, + # but understands `-z linker_flag'. GCC discards it without `$wl', + # but is careful enough not to reorder. + # Supported since Solaris 2.6 (maybe 2.5.1?) + if test "$GCC" = yes; then + _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}-z ${wl}allextract$convenience ${wl}-z ${wl}defaultextract' + else + _LT_TAGVAR(whole_archive_flag_spec, $1)='-z allextract$convenience -z defaultextract' + fi + ;; + esac + _LT_TAGVAR(link_all_deplibs, $1)=yes + ;; + + sunos4*) + if test "x$host_vendor" = xsequent; then + # Use $CC to link under sequent, because it throws in some extra .o + # files that make .init and .fini sections work. + _LT_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h $soname -o $lib $libobjs $deplibs $compiler_flags' + else + _LT_TAGVAR(archive_cmds, $1)='$LD -assert pure-text -Bstatic -o $lib $libobjs $deplibs $linker_flags' + fi + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_minus_L, $1)=yes + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + sysv4) + case $host_vendor in + sni) + _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + _LT_TAGVAR(hardcode_direct, $1)=yes # is this really true??? + ;; + siemens) + ## LD is ld it makes a PLAMLIB + ## CC just makes a GrossModule. + _LT_TAGVAR(archive_cmds, $1)='$LD -G -o $lib $libobjs $deplibs $linker_flags' + _LT_TAGVAR(reload_cmds, $1)='$CC -r -o $output$reload_objs' + _LT_TAGVAR(hardcode_direct, $1)=no + ;; + motorola) + _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + _LT_TAGVAR(hardcode_direct, $1)=no #Motorola manual says yes, but my tests say they lie + ;; + esac + runpath_var='LD_RUN_PATH' + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + sysv4.3*) + _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + _LT_TAGVAR(export_dynamic_flag_spec, $1)='-Bexport' + ;; + + sysv4*MP*) + if test -d /usr/nec; then + _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + runpath_var=LD_RUN_PATH + hardcode_runpath_var=yes + _LT_TAGVAR(ld_shlibs, $1)=yes + fi + ;; + + sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[[01]].[[10]]* | unixware7* | sco3.2v5.0.[[024]]*) + _LT_TAGVAR(no_undefined_flag, $1)='${wl}-z,text' + _LT_TAGVAR(archive_cmds_need_lc, $1)=no + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + runpath_var='LD_RUN_PATH' + + if test "$GCC" = yes; then + _LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + else + _LT_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + fi + ;; + + sysv5* | sco3.2v5* | sco5v6*) + # Note: We can NOT use -z defs as we might desire, because we do not + # link with -lc, and that would cause any symbols used from libc to + # always be unresolved, which means just about no library would + # ever link correctly. If we're not using GNU ld we use -z text + # though, which does catch some bad symbols but isn't as heavy-handed + # as -z defs. + _LT_TAGVAR(no_undefined_flag, $1)='${wl}-z,text' + _LT_TAGVAR(allow_undefined_flag, $1)='${wl}-z,nodefs' + _LT_TAGVAR(archive_cmds_need_lc, $1)=no + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R,$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)=':' + _LT_TAGVAR(link_all_deplibs, $1)=yes + _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-Bexport' + runpath_var='LD_RUN_PATH' + + if test "$GCC" = yes; then + _LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + else + _LT_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + fi + ;; + + uts4*) + _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + *) + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + esac + + if test x$host_vendor = xsni; then + case $host in + sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*) + _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-Blargedynsym' + ;; + esac + fi + fi +]) +AC_MSG_RESULT([$_LT_TAGVAR(ld_shlibs, $1)]) +test "$_LT_TAGVAR(ld_shlibs, $1)" = no && can_build_shared=no + +_LT_TAGVAR(with_gnu_ld, $1)=$with_gnu_ld + +_LT_DECL([], [libext], [0], [Old archive suffix (normally "a")])dnl +_LT_DECL([], [shrext_cmds], [1], [Shared library suffix (normally ".so")])dnl +_LT_DECL([], [extract_expsyms_cmds], [2], + [The commands to extract the exported symbol list from a shared archive]) + +# +# Do we need to explicitly link libc? +# +case "x$_LT_TAGVAR(archive_cmds_need_lc, $1)" in +x|xyes) + # Assume -lc should be added + _LT_TAGVAR(archive_cmds_need_lc, $1)=yes + + if test "$enable_shared" = yes && test "$GCC" = yes; then + case $_LT_TAGVAR(archive_cmds, $1) in + *'~'*) + # FIXME: we may have to deal with multi-command sequences. + ;; + '$CC '*) + # Test whether the compiler implicitly links with -lc since on some + # systems, -lgcc has to come before -lc. If gcc already passes -lc + # to ld, don't add -lc before -lgcc. + AC_CACHE_CHECK([whether -lc should be explicitly linked in], + [lt_cv_]_LT_TAGVAR(archive_cmds_need_lc, $1), + [$RM conftest* + echo "$lt_simple_compile_test_code" > conftest.$ac_ext + + if AC_TRY_EVAL(ac_compile) 2>conftest.err; then + soname=conftest + lib=conftest + libobjs=conftest.$ac_objext + deplibs= + wl=$_LT_TAGVAR(lt_prog_compiler_wl, $1) + pic_flag=$_LT_TAGVAR(lt_prog_compiler_pic, $1) + compiler_flags=-v + linker_flags=-v + verstring= + output_objdir=. + libname=conftest + lt_save_allow_undefined_flag=$_LT_TAGVAR(allow_undefined_flag, $1) + _LT_TAGVAR(allow_undefined_flag, $1)= + if AC_TRY_EVAL(_LT_TAGVAR(archive_cmds, $1) 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1) + then + lt_cv_[]_LT_TAGVAR(archive_cmds_need_lc, $1)=no + else + lt_cv_[]_LT_TAGVAR(archive_cmds_need_lc, $1)=yes + fi + _LT_TAGVAR(allow_undefined_flag, $1)=$lt_save_allow_undefined_flag + else + cat conftest.err 1>&5 + fi + $RM conftest* + ]) + _LT_TAGVAR(archive_cmds_need_lc, $1)=$lt_cv_[]_LT_TAGVAR(archive_cmds_need_lc, $1) + ;; + esac + fi + ;; +esac + +_LT_TAGDECL([build_libtool_need_lc], [archive_cmds_need_lc], [0], + [Whether or not to add -lc for building shared libraries]) +_LT_TAGDECL([allow_libtool_libs_with_static_runtimes], + [enable_shared_with_static_runtimes], [0], + [Whether or not to disallow shared libs when runtime libs are static]) +_LT_TAGDECL([], [export_dynamic_flag_spec], [1], + [Compiler flag to allow reflexive dlopens]) +_LT_TAGDECL([], [whole_archive_flag_spec], [1], + [Compiler flag to generate shared objects directly from archives]) +_LT_TAGDECL([], [compiler_needs_object], [1], + [Whether the compiler copes with passing no objects directly]) +_LT_TAGDECL([], [old_archive_from_new_cmds], [2], + [Create an old-style archive from a shared archive]) +_LT_TAGDECL([], [old_archive_from_expsyms_cmds], [2], + [Create a temporary old-style archive to link instead of a shared archive]) +_LT_TAGDECL([], [archive_cmds], [2], [Commands used to build a shared archive]) +_LT_TAGDECL([], [archive_expsym_cmds], [2]) +_LT_TAGDECL([], [module_cmds], [2], + [Commands used to build a loadable module if different from building + a shared archive.]) +_LT_TAGDECL([], [module_expsym_cmds], [2]) +_LT_TAGDECL([], [with_gnu_ld], [1], + [Whether we are building with GNU ld or not]) +_LT_TAGDECL([], [allow_undefined_flag], [1], + [Flag that allows shared libraries with undefined symbols to be built]) +_LT_TAGDECL([], [no_undefined_flag], [1], + [Flag that enforces no undefined symbols]) +_LT_TAGDECL([], [hardcode_libdir_flag_spec], [1], + [Flag to hardcode $libdir into a binary during linking. + This must work even if $libdir does not exist]) +_LT_TAGDECL([], [hardcode_libdir_separator], [1], + [Whether we need a single "-rpath" flag with a separated argument]) +_LT_TAGDECL([], [hardcode_direct], [0], + [Set to "yes" if using DIR/libNAME${shared_ext} during linking hardcodes + DIR into the resulting binary]) +_LT_TAGDECL([], [hardcode_direct_absolute], [0], + [Set to "yes" if using DIR/libNAME${shared_ext} during linking hardcodes + DIR into the resulting binary and the resulting library dependency is + "absolute", i.e impossible to change by setting ${shlibpath_var} if the + library is relocated]) +_LT_TAGDECL([], [hardcode_minus_L], [0], + [Set to "yes" if using the -LDIR flag during linking hardcodes DIR + into the resulting binary]) +_LT_TAGDECL([], [hardcode_shlibpath_var], [0], + [Set to "yes" if using SHLIBPATH_VAR=DIR during linking hardcodes DIR + into the resulting binary]) +_LT_TAGDECL([], [hardcode_automatic], [0], + [Set to "yes" if building a shared library automatically hardcodes DIR + into the library and all subsequent libraries and executables linked + against it]) +_LT_TAGDECL([], [inherit_rpath], [0], + [Set to yes if linker adds runtime paths of dependent libraries + to runtime path list]) +_LT_TAGDECL([], [link_all_deplibs], [0], + [Whether libtool must link a program against all its dependency libraries]) +_LT_TAGDECL([], [always_export_symbols], [0], + [Set to "yes" if exported symbols are required]) +_LT_TAGDECL([], [export_symbols_cmds], [2], + [The commands to list exported symbols]) +_LT_TAGDECL([], [exclude_expsyms], [1], + [Symbols that should not be listed in the preloaded symbols]) +_LT_TAGDECL([], [include_expsyms], [1], + [Symbols that must always be exported]) +_LT_TAGDECL([], [prelink_cmds], [2], + [Commands necessary for linking programs (against libraries) with templates]) +_LT_TAGDECL([], [postlink_cmds], [2], + [Commands necessary for finishing linking programs]) +_LT_TAGDECL([], [file_list_spec], [1], + [Specify filename containing input files]) +dnl FIXME: Not yet implemented +dnl _LT_TAGDECL([], [thread_safe_flag_spec], [1], +dnl [Compiler flag to generate thread safe objects]) +])# _LT_LINKER_SHLIBS + + +# _LT_LANG_C_CONFIG([TAG]) +# ------------------------ +# Ensure that the configuration variables for a C compiler are suitably +# defined. These variables are subsequently used by _LT_CONFIG to write +# the compiler configuration to `libtool'. +m4_defun([_LT_LANG_C_CONFIG], +[m4_require([_LT_DECL_EGREP])dnl +lt_save_CC="$CC" +AC_LANG_PUSH(C) + +# Source file extension for C test sources. +ac_ext=c + +# Object file extension for compiled C test sources. +objext=o +_LT_TAGVAR(objext, $1)=$objext + +# Code to be used in simple compile tests +lt_simple_compile_test_code="int some_variable = 0;" + +# Code to be used in simple link tests +lt_simple_link_test_code='int main(){return(0);}' + +_LT_TAG_COMPILER +# Save the default compiler, since it gets overwritten when the other +# tags are being tested, and _LT_TAGVAR(compiler, []) is a NOP. +compiler_DEFAULT=$CC + +# save warnings/boilerplate of simple test code +_LT_COMPILER_BOILERPLATE +_LT_LINKER_BOILERPLATE + +## CAVEAT EMPTOR: +## There is no encapsulation within the following macros, do not change +## the running order or otherwise move them around unless you know exactly +## what you are doing... +if test -n "$compiler"; then + _LT_COMPILER_NO_RTTI($1) + _LT_COMPILER_PIC($1) + _LT_COMPILER_C_O($1) + _LT_COMPILER_FILE_LOCKS($1) + _LT_LINKER_SHLIBS($1) + _LT_SYS_DYNAMIC_LINKER($1) + _LT_LINKER_HARDCODE_LIBPATH($1) + LT_SYS_DLOPEN_SELF + _LT_CMD_STRIPLIB + + # Report which library types will actually be built + AC_MSG_CHECKING([if libtool supports shared libraries]) + AC_MSG_RESULT([$can_build_shared]) + + AC_MSG_CHECKING([whether to build shared libraries]) + test "$can_build_shared" = "no" && enable_shared=no + + # On AIX, shared libraries and static libraries use the same namespace, and + # are all built from PIC. + case $host_os in + aix3*) + test "$enable_shared" = yes && enable_static=no + if test -n "$RANLIB"; then + archive_cmds="$archive_cmds~\$RANLIB \$lib" + postinstall_cmds='$RANLIB $lib' + fi + ;; + + aix[[4-9]]*) + if test "$host_cpu" != ia64 && test "$aix_use_runtimelinking" = no ; then + test "$enable_shared" = yes && enable_static=no + fi + ;; + esac + AC_MSG_RESULT([$enable_shared]) + + AC_MSG_CHECKING([whether to build static libraries]) + # Make sure either enable_shared or enable_static is yes. + test "$enable_shared" = yes || enable_static=yes + AC_MSG_RESULT([$enable_static]) + + _LT_CONFIG($1) +fi +AC_LANG_POP +CC="$lt_save_CC" +])# _LT_LANG_C_CONFIG + + +# _LT_LANG_CXX_CONFIG([TAG]) +# -------------------------- +# Ensure that the configuration variables for a C++ compiler are suitably +# defined. These variables are subsequently used by _LT_CONFIG to write +# the compiler configuration to `libtool'. +m4_defun([_LT_LANG_CXX_CONFIG], +[m4_require([_LT_FILEUTILS_DEFAULTS])dnl +m4_require([_LT_DECL_EGREP])dnl +m4_require([_LT_PATH_MANIFEST_TOOL])dnl +if test -n "$CXX" && ( test "X$CXX" != "Xno" && + ( (test "X$CXX" = "Xg++" && `g++ -v >/dev/null 2>&1` ) || + (test "X$CXX" != "Xg++"))) ; then + AC_PROG_CXXCPP +else + _lt_caught_CXX_error=yes +fi + +AC_LANG_PUSH(C++) +_LT_TAGVAR(archive_cmds_need_lc, $1)=no +_LT_TAGVAR(allow_undefined_flag, $1)= +_LT_TAGVAR(always_export_symbols, $1)=no +_LT_TAGVAR(archive_expsym_cmds, $1)= +_LT_TAGVAR(compiler_needs_object, $1)=no +_LT_TAGVAR(export_dynamic_flag_spec, $1)= +_LT_TAGVAR(hardcode_direct, $1)=no +_LT_TAGVAR(hardcode_direct_absolute, $1)=no +_LT_TAGVAR(hardcode_libdir_flag_spec, $1)= +_LT_TAGVAR(hardcode_libdir_separator, $1)= +_LT_TAGVAR(hardcode_minus_L, $1)=no +_LT_TAGVAR(hardcode_shlibpath_var, $1)=unsupported +_LT_TAGVAR(hardcode_automatic, $1)=no +_LT_TAGVAR(inherit_rpath, $1)=no +_LT_TAGVAR(module_cmds, $1)= +_LT_TAGVAR(module_expsym_cmds, $1)= +_LT_TAGVAR(link_all_deplibs, $1)=unknown +_LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds +_LT_TAGVAR(reload_flag, $1)=$reload_flag +_LT_TAGVAR(reload_cmds, $1)=$reload_cmds +_LT_TAGVAR(no_undefined_flag, $1)= +_LT_TAGVAR(whole_archive_flag_spec, $1)= +_LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no + +# Source file extension for C++ test sources. +ac_ext=cpp + +# Object file extension for compiled C++ test sources. +objext=o +_LT_TAGVAR(objext, $1)=$objext + +# No sense in running all these tests if we already determined that +# the CXX compiler isn't working. Some variables (like enable_shared) +# are currently assumed to apply to all compilers on this platform, +# and will be corrupted by setting them based on a non-working compiler. +if test "$_lt_caught_CXX_error" != yes; then + # Code to be used in simple compile tests + lt_simple_compile_test_code="int some_variable = 0;" + + # Code to be used in simple link tests + lt_simple_link_test_code='int main(int, char *[[]]) { return(0); }' + + # ltmain only uses $CC for tagged configurations so make sure $CC is set. + _LT_TAG_COMPILER + + # save warnings/boilerplate of simple test code + _LT_COMPILER_BOILERPLATE + _LT_LINKER_BOILERPLATE + + # Allow CC to be a program name with arguments. + lt_save_CC=$CC + lt_save_CFLAGS=$CFLAGS + lt_save_LD=$LD + lt_save_GCC=$GCC + GCC=$GXX + lt_save_with_gnu_ld=$with_gnu_ld + lt_save_path_LD=$lt_cv_path_LD + if test -n "${lt_cv_prog_gnu_ldcxx+set}"; then + lt_cv_prog_gnu_ld=$lt_cv_prog_gnu_ldcxx + else + $as_unset lt_cv_prog_gnu_ld + fi + if test -n "${lt_cv_path_LDCXX+set}"; then + lt_cv_path_LD=$lt_cv_path_LDCXX + else + $as_unset lt_cv_path_LD + fi + test -z "${LDCXX+set}" || LD=$LDCXX + CC=${CXX-"c++"} + CFLAGS=$CXXFLAGS + compiler=$CC + _LT_TAGVAR(compiler, $1)=$CC + _LT_CC_BASENAME([$compiler]) + + if test -n "$compiler"; then + # We don't want -fno-exception when compiling C++ code, so set the + # no_builtin_flag separately + if test "$GXX" = yes; then + _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=' -fno-builtin' + else + _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)= + fi + + if test "$GXX" = yes; then + # Set up default GNU C++ configuration + + LT_PATH_LD + + # Check if GNU C++ uses GNU ld as the underlying linker, since the + # archiving commands below assume that GNU ld is being used. + if test "$with_gnu_ld" = yes; then + _LT_TAGVAR(archive_cmds, $1)='$CC $pic_flag -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC $pic_flag -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic' + + # If archive_cmds runs LD, not CC, wlarc should be empty + # XXX I think wlarc can be eliminated in ltcf-cxx, but I need to + # investigate it a little bit more. (MM) + wlarc='${wl}' + + # ancient GNU ld didn't support --whole-archive et. al. + if eval "`$CC -print-prog-name=ld` --help 2>&1" | + $GREP 'no-whole-archive' > /dev/null; then + _LT_TAGVAR(whole_archive_flag_spec, $1)="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive' + else + _LT_TAGVAR(whole_archive_flag_spec, $1)= + fi + else + with_gnu_ld=no + wlarc= + + # A generic and very simple default shared library creation + # command for GNU C++ for the case where it uses the native + # linker, instead of GNU ld. If possible, this setting should + # overridden to take advantage of the native linker features on + # the platform it is being used on. + _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib' + fi + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"' + + else + GXX=no + with_gnu_ld=no + wlarc= + fi + + # PORTME: fill in a description of your system's C++ link characteristics + AC_MSG_CHECKING([whether the $compiler linker ($LD) supports shared libraries]) + _LT_TAGVAR(ld_shlibs, $1)=yes + case $host_os in + aix3*) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + aix[[4-9]]*) + if test "$host_cpu" = ia64; then + # On IA64, the linker does run time linking by default, so we don't + # have to do anything special. + aix_use_runtimelinking=no + exp_sym_flag='-Bexport' + no_entry_flag="" + else + aix_use_runtimelinking=no + + # Test if we are trying to use run time linking or normal + # AIX style linking. If -brtl is somewhere in LDFLAGS, we + # need to do runtime linking. + case $host_os in aix4.[[23]]|aix4.[[23]].*|aix[[5-9]]*) + for ld_flag in $LDFLAGS; do + case $ld_flag in + *-brtl*) + aix_use_runtimelinking=yes + break + ;; + esac + done + ;; + esac + + exp_sym_flag='-bexport' + no_entry_flag='-bnoentry' + fi + + # When large executables or shared objects are built, AIX ld can + # have problems creating the table of contents. If linking a library + # or program results in "error TOC overflow" add -mminimal-toc to + # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not + # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS. + + _LT_TAGVAR(archive_cmds, $1)='' + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_direct_absolute, $1)=yes + _LT_TAGVAR(hardcode_libdir_separator, $1)=':' + _LT_TAGVAR(link_all_deplibs, $1)=yes + _LT_TAGVAR(file_list_spec, $1)='${wl}-f,' + + if test "$GXX" = yes; then + case $host_os in aix4.[[012]]|aix4.[[012]].*) + # We only want to do this on AIX 4.2 and lower, the check + # below for broken collect2 doesn't work under 4.3+ + collect2name=`${CC} -print-prog-name=collect2` + if test -f "$collect2name" && + strings "$collect2name" | $GREP resolve_lib_name >/dev/null + then + # We have reworked collect2 + : + else + # We have old collect2 + _LT_TAGVAR(hardcode_direct, $1)=unsupported + # It fails to find uninstalled libraries when the uninstalled + # path is not listed in the libpath. Setting hardcode_minus_L + # to unsupported forces relinking + _LT_TAGVAR(hardcode_minus_L, $1)=yes + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)= + fi + esac + shared_flag='-shared' + if test "$aix_use_runtimelinking" = yes; then + shared_flag="$shared_flag "'${wl}-G' + fi + else + # not using gcc + if test "$host_cpu" = ia64; then + # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release + # chokes on -Wl,-G. The following line is correct: + shared_flag='-G' + else + if test "$aix_use_runtimelinking" = yes; then + shared_flag='${wl}-G' + else + shared_flag='${wl}-bM:SRE' + fi + fi + fi + + _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-bexpall' + # It seems that -bexpall does not export symbols beginning with + # underscore (_), so it is better to generate a list of symbols to + # export. + _LT_TAGVAR(always_export_symbols, $1)=yes + if test "$aix_use_runtimelinking" = yes; then + # Warning - without using the other runtime loading flags (-brtl), + # -berok will link without error, but may produce a broken library. + _LT_TAGVAR(allow_undefined_flag, $1)='-berok' + # Determine the default libpath from the value encoded in an empty + # executable. + _LT_SYS_MODULE_PATH_AIX([$1]) + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath" + + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then func_echo_all "${wl}${allow_undefined_flag}"; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag" + else + if test "$host_cpu" = ia64; then + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R $libdir:/usr/lib:/lib' + _LT_TAGVAR(allow_undefined_flag, $1)="-z nodefs" + _LT_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$exp_sym_flag:\$export_symbols" + else + # Determine the default libpath from the value encoded in an + # empty executable. + _LT_SYS_MODULE_PATH_AIX([$1]) + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath" + # Warning - without using the other run time loading flags, + # -berok will link without error, but may produce a broken library. + _LT_TAGVAR(no_undefined_flag, $1)=' ${wl}-bernotok' + _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-berok' + if test "$with_gnu_ld" = yes; then + # We only use this code for GNU lds that support --whole-archive. + _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive$convenience ${wl}--no-whole-archive' + else + # Exported symbols can be pulled into shared objects from archives + _LT_TAGVAR(whole_archive_flag_spec, $1)='$convenience' + fi + _LT_TAGVAR(archive_cmds_need_lc, $1)=yes + # This is similar to how AIX traditionally builds its shared + # libraries. + _LT_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs ${wl}-bnoentry $compiler_flags ${wl}-bE:$export_symbols${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname' + fi + fi + ;; + + beos*) + if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then + _LT_TAGVAR(allow_undefined_flag, $1)=unsupported + # Joseph Beckenbach says some releases of gcc + # support --undefined. This deserves some investigation. FIXME + _LT_TAGVAR(archive_cmds, $1)='$CC -nostart $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + else + _LT_TAGVAR(ld_shlibs, $1)=no + fi + ;; + + chorus*) + case $cc_basename in + *) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + esac + ;; + + cygwin* | mingw* | pw32* | cegcc*) + case $GXX,$cc_basename in + ,cl* | no,cl*) + # Native MSVC + # hardcode_libdir_flag_spec is actually meaningless, as there is + # no search path for DLLs. + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)=' ' + _LT_TAGVAR(allow_undefined_flag, $1)=unsupported + _LT_TAGVAR(always_export_symbols, $1)=yes + _LT_TAGVAR(file_list_spec, $1)='@' + # Tell ltmain to make .lib files, not .a files. + libext=lib + # Tell ltmain to make .dll files, not .so files. + shrext_cmds=".dll" + # FIXME: Setting linknames here is a bad hack. + _LT_TAGVAR(archive_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $compiler_flags $deplibs -Wl,-dll~linknames=' + _LT_TAGVAR(archive_expsym_cmds, $1)='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then + $SED -n -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' -e '1\\\!p' < $export_symbols > $output_objdir/$soname.exp; + else + $SED -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' < $export_symbols > $output_objdir/$soname.exp; + fi~ + $CC -o $tool_output_objdir$soname $libobjs $compiler_flags $deplibs "@$tool_output_objdir$soname.exp" -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~ + linknames=' + # The linker will not automatically build a static lib if we build a DLL. + # _LT_TAGVAR(old_archive_from_new_cmds, $1)='true' + _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes + # Don't use ranlib + _LT_TAGVAR(old_postinstall_cmds, $1)='chmod 644 $oldlib' + _LT_TAGVAR(postlink_cmds, $1)='lt_outputfile="@OUTPUT@"~ + lt_tool_outputfile="@TOOL_OUTPUT@"~ + case $lt_outputfile in + *.exe|*.EXE) ;; + *) + lt_outputfile="$lt_outputfile.exe" + lt_tool_outputfile="$lt_tool_outputfile.exe" + ;; + esac~ + func_to_tool_file "$lt_outputfile"~ + if test "$MANIFEST_TOOL" != ":" && test -f "$lt_outputfile.manifest"; then + $MANIFEST_TOOL -manifest "$lt_tool_outputfile.manifest" -outputresource:"$lt_tool_outputfile" || exit 1; + $RM "$lt_outputfile.manifest"; + fi' + ;; + *) + # g++ + # _LT_TAGVAR(hardcode_libdir_flag_spec, $1) is actually meaningless, + # as there is no search path for DLLs. + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-all-symbols' + _LT_TAGVAR(allow_undefined_flag, $1)=unsupported + _LT_TAGVAR(always_export_symbols, $1)=no + _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes + + if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then + _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' + # If the export-symbols file already is a .def file (1st line + # is EXPORTS), use it as is; otherwise, prepend... + _LT_TAGVAR(archive_expsym_cmds, $1)='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then + cp $export_symbols $output_objdir/$soname.def; + else + echo EXPORTS > $output_objdir/$soname.def; + cat $export_symbols >> $output_objdir/$soname.def; + fi~ + $CC -shared -nostdlib $output_objdir/$soname.def $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' + else + _LT_TAGVAR(ld_shlibs, $1)=no + fi + ;; + esac + ;; + darwin* | rhapsody*) + _LT_DARWIN_LINKER_FEATURES($1) + ;; + + dgux*) + case $cc_basename in + ec++*) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + ghcx*) + # Green Hills C++ Compiler + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + *) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + esac + ;; + + freebsd2.*) + # C++ shared libraries reported to be fairly broken before + # switch to ELF + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + + freebsd-elf*) + _LT_TAGVAR(archive_cmds_need_lc, $1)=no + ;; + + freebsd* | dragonfly*) + # FreeBSD 3 and later use GNU C++ and GNU ld with standard ELF + # conventions + _LT_TAGVAR(ld_shlibs, $1)=yes + ;; + + gnu*) + ;; + + haiku*) + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + _LT_TAGVAR(link_all_deplibs, $1)=yes + ;; + + hpux9*) + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)=: + _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_minus_L, $1)=yes # Not in the search PATH, + # but as the default + # location of the library. + + case $cc_basename in + CC*) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + aCC*) + _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$CC -b ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + # + # There doesn't appear to be a way to prevent this compiler from + # explicitly linking system object files so we need to strip them + # from the output so that they don't get included in the library + # dependencies. + output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $EGREP "\-L"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' + ;; + *) + if test "$GXX" = yes; then + _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$CC -shared -nostdlib $pic_flag ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' + else + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + fi + ;; + esac + ;; + + hpux10*|hpux11*) + if test $with_gnu_ld = no; then + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)=: + + case $host_cpu in + hppa*64*|ia64*) + ;; + *) + _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' + ;; + esac + fi + case $host_cpu in + hppa*64*|ia64*) + _LT_TAGVAR(hardcode_direct, $1)=no + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + *) + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_direct_absolute, $1)=yes + _LT_TAGVAR(hardcode_minus_L, $1)=yes # Not in the search PATH, + # but as the default + # location of the library. + ;; + esac + + case $cc_basename in + CC*) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + aCC*) + case $host_cpu in + hppa*64*) + _LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + ;; + ia64*) + _LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + ;; + *) + _LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + ;; + esac + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + # + # There doesn't appear to be a way to prevent this compiler from + # explicitly linking system object files so we need to strip them + # from the output so that they don't get included in the library + # dependencies. + output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $GREP "\-L"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' + ;; + *) + if test "$GXX" = yes; then + if test $with_gnu_ld = no; then + case $host_cpu in + hppa*64*) + _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib -fPIC ${wl}+h ${wl}$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + ;; + ia64*) + _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $pic_flag ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + ;; + *) + _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $pic_flag ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + ;; + esac + fi + else + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + fi + ;; + esac + ;; + + interix[[3-9]]*) + _LT_TAGVAR(hardcode_direct, $1)=no + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' + # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc. + # Instead, shared libraries are loaded at an image base (0x10000000 by + # default) and relocated if they conflict, which is a slow very memory + # consuming and fragmenting process. To avoid this, we pick a random, + # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link + # time. Moving up from 0x10000000 also allows more sbrk(2) space. + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='sed "s,^,_," $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--retain-symbols-file,$output_objdir/$soname.expsym ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' + ;; + irix5* | irix6*) + case $cc_basename in + CC*) + # SGI C++ + _LT_TAGVAR(archive_cmds, $1)='$CC -shared -all -multigot $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib' + + # Archives containing C++ object files must be created using + # "CC -ar", where "CC" is the IRIX C++ compiler. This is + # necessary to make sure instantiated templates are included + # in the archive. + _LT_TAGVAR(old_archive_cmds, $1)='$CC -ar -WR,-u -o $oldlib $oldobjs' + ;; + *) + if test "$GXX" = yes; then + if test "$with_gnu_ld" = no; then + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' + else + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` -o $lib' + fi + fi + _LT_TAGVAR(link_all_deplibs, $1)=yes + ;; + esac + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)=: + _LT_TAGVAR(inherit_rpath, $1)=yes + ;; + + linux* | k*bsd*-gnu | kopensolaris*-gnu) + case $cc_basename in + KCC*) + # Kuck and Associates, Inc. (KAI) C++ Compiler + + # KCC will only create a shared library if the output file + # ends with ".so" (or ".sl" for HP-UX), so rename the library + # to its proper name (with version) after linking. + _LT_TAGVAR(archive_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib ${wl}-retain-symbols-file,$export_symbols; mv \$templib $lib' + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + # + # There doesn't appear to be a way to prevent this compiler from + # explicitly linking system object files so we need to strip them + # from the output so that they don't get included in the library + # dependencies. + output_verbose_link_cmd='templist=`$CC $CFLAGS -v conftest.$objext -o libconftest$shared_ext 2>&1 | $GREP "ld"`; rm -f libconftest$shared_ext; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' + + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic' + + # Archives containing C++ object files must be created using + # "CC -Bstatic", where "CC" is the KAI C++ compiler. + _LT_TAGVAR(old_archive_cmds, $1)='$CC -Bstatic -o $oldlib $oldobjs' + ;; + icpc* | ecpc* ) + # Intel C++ + with_gnu_ld=yes + # version 8.0 and above of icpc choke on multiply defined symbols + # if we add $predep_objects and $postdep_objects, however 7.1 and + # earlier do not add the objects themselves. + case `$CC -V 2>&1` in + *"Version 7."*) + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + ;; + *) # Version 8.0 or newer + tmp_idyn= + case $host_cpu in + ia64*) tmp_idyn=' -i_dynamic';; + esac + _LT_TAGVAR(archive_cmds, $1)='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + ;; + esac + _LT_TAGVAR(archive_cmds_need_lc, $1)=no + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic' + _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive$convenience ${wl}--no-whole-archive' + ;; + pgCC* | pgcpp*) + # Portland Group C++ compiler + case `$CC -V` in + *pgCC\ [[1-5]].* | *pgcpp\ [[1-5]].*) + _LT_TAGVAR(prelink_cmds, $1)='tpldir=Template.dir~ + rm -rf $tpldir~ + $CC --prelink_objects --instantiation_dir $tpldir $objs $libobjs $compile_deplibs~ + compile_command="$compile_command `find $tpldir -name \*.o | sort | $NL2SP`"' + _LT_TAGVAR(old_archive_cmds, $1)='tpldir=Template.dir~ + rm -rf $tpldir~ + $CC --prelink_objects --instantiation_dir $tpldir $oldobjs$old_deplibs~ + $AR $AR_FLAGS $oldlib$oldobjs$old_deplibs `find $tpldir -name \*.o | sort | $NL2SP`~ + $RANLIB $oldlib' + _LT_TAGVAR(archive_cmds, $1)='tpldir=Template.dir~ + rm -rf $tpldir~ + $CC --prelink_objects --instantiation_dir $tpldir $predep_objects $libobjs $deplibs $convenience $postdep_objects~ + $CC -shared $pic_flag $predep_objects $libobjs $deplibs `find $tpldir -name \*.o | sort | $NL2SP` $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='tpldir=Template.dir~ + rm -rf $tpldir~ + $CC --prelink_objects --instantiation_dir $tpldir $predep_objects $libobjs $deplibs $convenience $postdep_objects~ + $CC -shared $pic_flag $predep_objects $libobjs $deplibs `find $tpldir -name \*.o | sort | $NL2SP` $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname ${wl}-retain-symbols-file ${wl}$export_symbols -o $lib' + ;; + *) # Version 6 and above use weak symbols + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname ${wl}-retain-symbols-file ${wl}$export_symbols -o $lib' + ;; + esac + + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}--rpath ${wl}$libdir' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic' + _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' + ;; + cxx*) + # Compaq C++ + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib ${wl}-retain-symbols-file $wl$export_symbols' + + runpath_var=LD_RUN_PATH + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)=: + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + # + # There doesn't appear to be a way to prevent this compiler from + # explicitly linking system object files so we need to strip them + # from the output so that they don't get included in the library + # dependencies. + output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "ld"`; templist=`func_echo_all "$templist" | $SED "s/\(^.*ld.*\)\( .*ld .*$\)/\1/"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "X$list" | $Xsed' + ;; + xl* | mpixl* | bgxl*) + # IBM XL 8.0 on PPC, with GNU ld + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic' + _LT_TAGVAR(archive_cmds, $1)='$CC -qmkshrobj $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + if test "x$supports_anon_versioning" = xyes; then + _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $output_objdir/$libname.ver~ + cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ + echo "local: *; };" >> $output_objdir/$libname.ver~ + $CC -qmkshrobj $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-version-script ${wl}$output_objdir/$libname.ver -o $lib' + fi + ;; + *) + case `$CC -V 2>&1 | sed 5q` in + *Sun\ C*) + # Sun C++ 5.9 + _LT_TAGVAR(no_undefined_flag, $1)=' -zdefs' + _LT_TAGVAR(archive_cmds, $1)='$CC -G${allow_undefined_flag} -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G${allow_undefined_flag} -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-retain-symbols-file ${wl}$export_symbols' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' + _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' + _LT_TAGVAR(compiler_needs_object, $1)=yes + + # Not sure whether something based on + # $CC $CFLAGS -v conftest.$objext -o libconftest$shared_ext 2>&1 + # would be better. + output_verbose_link_cmd='func_echo_all' + + # Archives containing C++ object files must be created using + # "CC -xar", where "CC" is the Sun C++ compiler. This is + # necessary to make sure instantiated templates are included + # in the archive. + _LT_TAGVAR(old_archive_cmds, $1)='$CC -xar -o $oldlib $oldobjs' + ;; + esac + ;; + esac + ;; + + lynxos*) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + + m88k*) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + + mvs*) + case $cc_basename in + cxx*) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + *) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + esac + ;; + + netbsd*) + if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then + _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $predep_objects $libobjs $deplibs $postdep_objects $linker_flags' + wlarc= + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + fi + # Workaround some broken pre-1.5 toolchains + output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP conftest.$objext | $SED -e "s:-lgcc -lc -lgcc::"' + ;; + + *nto* | *qnx*) + _LT_TAGVAR(ld_shlibs, $1)=yes + ;; + + openbsd2*) + # C++ shared libraries are fairly broken + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + + openbsd*) + if test -f /usr/libexec/ld.so; then + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + _LT_TAGVAR(hardcode_direct_absolute, $1)=yes + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' + if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-retain-symbols-file,$export_symbols -o $lib' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' + _LT_TAGVAR(whole_archive_flag_spec, $1)="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive' + fi + output_verbose_link_cmd=func_echo_all + else + _LT_TAGVAR(ld_shlibs, $1)=no + fi + ;; + + osf3* | osf4* | osf5*) + case $cc_basename in + KCC*) + # Kuck and Associates, Inc. (KAI) C++ Compiler + + # KCC will only create a shared library if the output file + # ends with ".so" (or ".sl" for HP-UX), so rename the library + # to its proper name (with version) after linking. + _LT_TAGVAR(archive_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo "$lib" | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib' + + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)=: + + # Archives containing C++ object files must be created using + # the KAI C++ compiler. + case $host in + osf3*) _LT_TAGVAR(old_archive_cmds, $1)='$CC -Bstatic -o $oldlib $oldobjs' ;; + *) _LT_TAGVAR(old_archive_cmds, $1)='$CC -o $oldlib $oldobjs' ;; + esac + ;; + RCC*) + # Rational C++ 2.4.1 + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + cxx*) + case $host in + osf3*) + _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*' + _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $soname `test -n "$verstring" && func_echo_all "${wl}-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' + ;; + *) + _LT_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*' + _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done~ + echo "-hidden">> $lib.exp~ + $CC -shared$allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname ${wl}-input ${wl}$lib.exp `test -n "$verstring" && $ECHO "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib~ + $RM $lib.exp' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir' + ;; + esac + + _LT_TAGVAR(hardcode_libdir_separator, $1)=: + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + # + # There doesn't appear to be a way to prevent this compiler from + # explicitly linking system object files so we need to strip them + # from the output so that they don't get included in the library + # dependencies. + output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "ld" | $GREP -v "ld:"`; templist=`func_echo_all "$templist" | $SED "s/\(^.*ld.*\)\( .*ld.*$\)/\1/"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' + ;; + *) + if test "$GXX" = yes && test "$with_gnu_ld" = no; then + _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*' + case $host in + osf3*) + _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib ${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' + ;; + *) + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib ${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' + ;; + esac + + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)=: + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"' + + else + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + fi + ;; + esac + ;; + + psos*) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + + sunos4*) + case $cc_basename in + CC*) + # Sun C++ 4.x + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + lcc*) + # Lucid + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + *) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + esac + ;; + + solaris*) + case $cc_basename in + CC* | sunCC*) + # Sun C++ 4.2, 5.x and Centerline C++ + _LT_TAGVAR(archive_cmds_need_lc,$1)=yes + _LT_TAGVAR(no_undefined_flag, $1)=' -zdefs' + _LT_TAGVAR(archive_cmds, $1)='$CC -G${allow_undefined_flag} -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ + $CC -G${allow_undefined_flag} ${wl}-M ${wl}$lib.exp -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp' + + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + case $host_os in + solaris2.[[0-5]] | solaris2.[[0-5]].*) ;; + *) + # The compiler driver will combine and reorder linker options, + # but understands `-z linker_flag'. + # Supported since Solaris 2.6 (maybe 2.5.1?) + _LT_TAGVAR(whole_archive_flag_spec, $1)='-z allextract$convenience -z defaultextract' + ;; + esac + _LT_TAGVAR(link_all_deplibs, $1)=yes + + output_verbose_link_cmd='func_echo_all' + + # Archives containing C++ object files must be created using + # "CC -xar", where "CC" is the Sun C++ compiler. This is + # necessary to make sure instantiated templates are included + # in the archive. + _LT_TAGVAR(old_archive_cmds, $1)='$CC -xar -o $oldlib $oldobjs' + ;; + gcx*) + # Green Hills C++ Compiler + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib' + + # The C++ compiler must be used to create the archive. + _LT_TAGVAR(old_archive_cmds, $1)='$CC $LDFLAGS -archive -o $oldlib $oldobjs' + ;; + *) + # GNU C++ compiler with Solaris linker + if test "$GXX" = yes && test "$with_gnu_ld" = no; then + _LT_TAGVAR(no_undefined_flag, $1)=' ${wl}-z ${wl}defs' + if $CC --version | $GREP -v '^2\.7' > /dev/null; then + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib $LDFLAGS $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ + $CC -shared $pic_flag -nostdlib ${wl}-M $wl$lib.exp -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp' + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"' + else + # g++ 2.7 appears to require `-G' NOT `-shared' on this + # platform. + _LT_TAGVAR(archive_cmds, $1)='$CC -G -nostdlib $LDFLAGS $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ + $CC -G -nostdlib ${wl}-M $wl$lib.exp -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp' + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + output_verbose_link_cmd='$CC -G $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"' + fi + + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R $wl$libdir' + case $host_os in + solaris2.[[0-5]] | solaris2.[[0-5]].*) ;; + *) + _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}-z ${wl}allextract$convenience ${wl}-z ${wl}defaultextract' + ;; + esac + fi + ;; + esac + ;; + + sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[[01]].[[10]]* | unixware7* | sco3.2v5.0.[[024]]*) + _LT_TAGVAR(no_undefined_flag, $1)='${wl}-z,text' + _LT_TAGVAR(archive_cmds_need_lc, $1)=no + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + runpath_var='LD_RUN_PATH' + + case $cc_basename in + CC*) + _LT_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + ;; + *) + _LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + ;; + esac + ;; + + sysv5* | sco3.2v5* | sco5v6*) + # Note: We can NOT use -z defs as we might desire, because we do not + # link with -lc, and that would cause any symbols used from libc to + # always be unresolved, which means just about no library would + # ever link correctly. If we're not using GNU ld we use -z text + # though, which does catch some bad symbols but isn't as heavy-handed + # as -z defs. + _LT_TAGVAR(no_undefined_flag, $1)='${wl}-z,text' + _LT_TAGVAR(allow_undefined_flag, $1)='${wl}-z,nodefs' + _LT_TAGVAR(archive_cmds_need_lc, $1)=no + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R,$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)=':' + _LT_TAGVAR(link_all_deplibs, $1)=yes + _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-Bexport' + runpath_var='LD_RUN_PATH' + + case $cc_basename in + CC*) + _LT_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(old_archive_cmds, $1)='$CC -Tprelink_objects $oldobjs~ + '"$_LT_TAGVAR(old_archive_cmds, $1)" + _LT_TAGVAR(reload_cmds, $1)='$CC -Tprelink_objects $reload_objs~ + '"$_LT_TAGVAR(reload_cmds, $1)" + ;; + *) + _LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + ;; + esac + ;; + + tandem*) + case $cc_basename in + NCC*) + # NonStop-UX NCC 3.20 + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + *) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + esac + ;; + + vxworks*) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + + *) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + esac + + AC_MSG_RESULT([$_LT_TAGVAR(ld_shlibs, $1)]) + test "$_LT_TAGVAR(ld_shlibs, $1)" = no && can_build_shared=no + + _LT_TAGVAR(GCC, $1)="$GXX" + _LT_TAGVAR(LD, $1)="$LD" + + ## CAVEAT EMPTOR: + ## There is no encapsulation within the following macros, do not change + ## the running order or otherwise move them around unless you know exactly + ## what you are doing... + _LT_SYS_HIDDEN_LIBDEPS($1) + _LT_COMPILER_PIC($1) + _LT_COMPILER_C_O($1) + _LT_COMPILER_FILE_LOCKS($1) + _LT_LINKER_SHLIBS($1) + _LT_SYS_DYNAMIC_LINKER($1) + _LT_LINKER_HARDCODE_LIBPATH($1) + + _LT_CONFIG($1) + fi # test -n "$compiler" + + CC=$lt_save_CC + CFLAGS=$lt_save_CFLAGS + LDCXX=$LD + LD=$lt_save_LD + GCC=$lt_save_GCC + with_gnu_ld=$lt_save_with_gnu_ld + lt_cv_path_LDCXX=$lt_cv_path_LD + lt_cv_path_LD=$lt_save_path_LD + lt_cv_prog_gnu_ldcxx=$lt_cv_prog_gnu_ld + lt_cv_prog_gnu_ld=$lt_save_with_gnu_ld +fi # test "$_lt_caught_CXX_error" != yes + +AC_LANG_POP +])# _LT_LANG_CXX_CONFIG + + +# _LT_FUNC_STRIPNAME_CNF +# ---------------------- +# func_stripname_cnf prefix suffix name +# strip PREFIX and SUFFIX off of NAME. +# PREFIX and SUFFIX must not contain globbing or regex special +# characters, hashes, percent signs, but SUFFIX may contain a leading +# dot (in which case that matches only a dot). +# +# This function is identical to the (non-XSI) version of func_stripname, +# except this one can be used by m4 code that may be executed by configure, +# rather than the libtool script. +m4_defun([_LT_FUNC_STRIPNAME_CNF],[dnl +AC_REQUIRE([_LT_DECL_SED]) +AC_REQUIRE([_LT_PROG_ECHO_BACKSLASH]) +func_stripname_cnf () +{ + case ${2} in + .*) func_stripname_result=`$ECHO "${3}" | $SED "s%^${1}%%; s%\\\\${2}\$%%"`;; + *) func_stripname_result=`$ECHO "${3}" | $SED "s%^${1}%%; s%${2}\$%%"`;; + esac +} # func_stripname_cnf +])# _LT_FUNC_STRIPNAME_CNF + +# _LT_SYS_HIDDEN_LIBDEPS([TAGNAME]) +# --------------------------------- +# Figure out "hidden" library dependencies from verbose +# compiler output when linking a shared library. +# Parse the compiler output and extract the necessary +# objects, libraries and library flags. +m4_defun([_LT_SYS_HIDDEN_LIBDEPS], +[m4_require([_LT_FILEUTILS_DEFAULTS])dnl +AC_REQUIRE([_LT_FUNC_STRIPNAME_CNF])dnl +# Dependencies to place before and after the object being linked: +_LT_TAGVAR(predep_objects, $1)= +_LT_TAGVAR(postdep_objects, $1)= +_LT_TAGVAR(predeps, $1)= +_LT_TAGVAR(postdeps, $1)= +_LT_TAGVAR(compiler_lib_search_path, $1)= + +dnl we can't use the lt_simple_compile_test_code here, +dnl because it contains code intended for an executable, +dnl not a library. It's possible we should let each +dnl tag define a new lt_????_link_test_code variable, +dnl but it's only used here... +m4_if([$1], [], [cat > conftest.$ac_ext <<_LT_EOF +int a; +void foo (void) { a = 0; } +_LT_EOF +], [$1], [CXX], [cat > conftest.$ac_ext <<_LT_EOF +class Foo +{ +public: + Foo (void) { a = 0; } +private: + int a; +}; +_LT_EOF +], [$1], [F77], [cat > conftest.$ac_ext <<_LT_EOF + subroutine foo + implicit none + integer*4 a + a=0 + return + end +_LT_EOF +], [$1], [FC], [cat > conftest.$ac_ext <<_LT_EOF + subroutine foo + implicit none + integer a + a=0 + return + end +_LT_EOF +], [$1], [GCJ], [cat > conftest.$ac_ext <<_LT_EOF +public class foo { + private int a; + public void bar (void) { + a = 0; + } +}; +_LT_EOF +], [$1], [GO], [cat > conftest.$ac_ext <<_LT_EOF +package foo +func foo() { +} +_LT_EOF +]) + +_lt_libdeps_save_CFLAGS=$CFLAGS +case "$CC $CFLAGS " in #( +*\ -flto*\ *) CFLAGS="$CFLAGS -fno-lto" ;; +*\ -fwhopr*\ *) CFLAGS="$CFLAGS -fno-whopr" ;; +*\ -fuse-linker-plugin*\ *) CFLAGS="$CFLAGS -fno-use-linker-plugin" ;; +esac + +dnl Parse the compiler output and extract the necessary +dnl objects, libraries and library flags. +if AC_TRY_EVAL(ac_compile); then + # Parse the compiler output and extract the necessary + # objects, libraries and library flags. + + # Sentinel used to keep track of whether or not we are before + # the conftest object file. + pre_test_object_deps_done=no + + for p in `eval "$output_verbose_link_cmd"`; do + case ${prev}${p} in + + -L* | -R* | -l*) + # Some compilers place space between "-{L,R}" and the path. + # Remove the space. + if test $p = "-L" || + test $p = "-R"; then + prev=$p + continue + fi + + # Expand the sysroot to ease extracting the directories later. + if test -z "$prev"; then + case $p in + -L*) func_stripname_cnf '-L' '' "$p"; prev=-L; p=$func_stripname_result ;; + -R*) func_stripname_cnf '-R' '' "$p"; prev=-R; p=$func_stripname_result ;; + -l*) func_stripname_cnf '-l' '' "$p"; prev=-l; p=$func_stripname_result ;; + esac + fi + case $p in + =*) func_stripname_cnf '=' '' "$p"; p=$lt_sysroot$func_stripname_result ;; + esac + if test "$pre_test_object_deps_done" = no; then + case ${prev} in + -L | -R) + # Internal compiler library paths should come after those + # provided the user. The postdeps already come after the + # user supplied libs so there is no need to process them. + if test -z "$_LT_TAGVAR(compiler_lib_search_path, $1)"; then + _LT_TAGVAR(compiler_lib_search_path, $1)="${prev}${p}" + else + _LT_TAGVAR(compiler_lib_search_path, $1)="${_LT_TAGVAR(compiler_lib_search_path, $1)} ${prev}${p}" + fi + ;; + # The "-l" case would never come before the object being + # linked, so don't bother handling this case. + esac + else + if test -z "$_LT_TAGVAR(postdeps, $1)"; then + _LT_TAGVAR(postdeps, $1)="${prev}${p}" + else + _LT_TAGVAR(postdeps, $1)="${_LT_TAGVAR(postdeps, $1)} ${prev}${p}" + fi + fi + prev= + ;; + + *.lto.$objext) ;; # Ignore GCC LTO objects + *.$objext) + # This assumes that the test object file only shows up + # once in the compiler output. + if test "$p" = "conftest.$objext"; then + pre_test_object_deps_done=yes + continue + fi + + if test "$pre_test_object_deps_done" = no; then + if test -z "$_LT_TAGVAR(predep_objects, $1)"; then + _LT_TAGVAR(predep_objects, $1)="$p" + else + _LT_TAGVAR(predep_objects, $1)="$_LT_TAGVAR(predep_objects, $1) $p" + fi + else + if test -z "$_LT_TAGVAR(postdep_objects, $1)"; then + _LT_TAGVAR(postdep_objects, $1)="$p" + else + _LT_TAGVAR(postdep_objects, $1)="$_LT_TAGVAR(postdep_objects, $1) $p" + fi + fi + ;; + + *) ;; # Ignore the rest. + + esac + done + + # Clean up. + rm -f a.out a.exe +else + echo "libtool.m4: error: problem compiling $1 test program" +fi + +$RM -f confest.$objext +CFLAGS=$_lt_libdeps_save_CFLAGS + +# PORTME: override above test on systems where it is broken +m4_if([$1], [CXX], +[case $host_os in +interix[[3-9]]*) + # Interix 3.5 installs completely hosed .la files for C++, so rather than + # hack all around it, let's just trust "g++" to DTRT. + _LT_TAGVAR(predep_objects,$1)= + _LT_TAGVAR(postdep_objects,$1)= + _LT_TAGVAR(postdeps,$1)= + ;; + +linux*) + case `$CC -V 2>&1 | sed 5q` in + *Sun\ C*) + # Sun C++ 5.9 + + # The more standards-conforming stlport4 library is + # incompatible with the Cstd library. Avoid specifying + # it if it's in CXXFLAGS. Ignore libCrun as + # -library=stlport4 depends on it. + case " $CXX $CXXFLAGS " in + *" -library=stlport4 "*) + solaris_use_stlport4=yes + ;; + esac + + if test "$solaris_use_stlport4" != yes; then + _LT_TAGVAR(postdeps,$1)='-library=Cstd -library=Crun' + fi + ;; + esac + ;; + +solaris*) + case $cc_basename in + CC* | sunCC*) + # The more standards-conforming stlport4 library is + # incompatible with the Cstd library. Avoid specifying + # it if it's in CXXFLAGS. Ignore libCrun as + # -library=stlport4 depends on it. + case " $CXX $CXXFLAGS " in + *" -library=stlport4 "*) + solaris_use_stlport4=yes + ;; + esac + + # Adding this requires a known-good setup of shared libraries for + # Sun compiler versions before 5.6, else PIC objects from an old + # archive will be linked into the output, leading to subtle bugs. + if test "$solaris_use_stlport4" != yes; then + _LT_TAGVAR(postdeps,$1)='-library=Cstd -library=Crun' + fi + ;; + esac + ;; +esac +]) + +case " $_LT_TAGVAR(postdeps, $1) " in +*" -lc "*) _LT_TAGVAR(archive_cmds_need_lc, $1)=no ;; +esac + _LT_TAGVAR(compiler_lib_search_dirs, $1)= +if test -n "${_LT_TAGVAR(compiler_lib_search_path, $1)}"; then + _LT_TAGVAR(compiler_lib_search_dirs, $1)=`echo " ${_LT_TAGVAR(compiler_lib_search_path, $1)}" | ${SED} -e 's! -L! !g' -e 's!^ !!'` +fi +_LT_TAGDECL([], [compiler_lib_search_dirs], [1], + [The directories searched by this compiler when creating a shared library]) +_LT_TAGDECL([], [predep_objects], [1], + [Dependencies to place before and after the objects being linked to + create a shared library]) +_LT_TAGDECL([], [postdep_objects], [1]) +_LT_TAGDECL([], [predeps], [1]) +_LT_TAGDECL([], [postdeps], [1]) +_LT_TAGDECL([], [compiler_lib_search_path], [1], + [The library search path used internally by the compiler when linking + a shared library]) +])# _LT_SYS_HIDDEN_LIBDEPS + + +# _LT_LANG_F77_CONFIG([TAG]) +# -------------------------- +# Ensure that the configuration variables for a Fortran 77 compiler are +# suitably defined. These variables are subsequently used by _LT_CONFIG +# to write the compiler configuration to `libtool'. +m4_defun([_LT_LANG_F77_CONFIG], +[AC_LANG_PUSH(Fortran 77) +if test -z "$F77" || test "X$F77" = "Xno"; then + _lt_disable_F77=yes +fi + +_LT_TAGVAR(archive_cmds_need_lc, $1)=no +_LT_TAGVAR(allow_undefined_flag, $1)= +_LT_TAGVAR(always_export_symbols, $1)=no +_LT_TAGVAR(archive_expsym_cmds, $1)= +_LT_TAGVAR(export_dynamic_flag_spec, $1)= +_LT_TAGVAR(hardcode_direct, $1)=no +_LT_TAGVAR(hardcode_direct_absolute, $1)=no +_LT_TAGVAR(hardcode_libdir_flag_spec, $1)= +_LT_TAGVAR(hardcode_libdir_separator, $1)= +_LT_TAGVAR(hardcode_minus_L, $1)=no +_LT_TAGVAR(hardcode_automatic, $1)=no +_LT_TAGVAR(inherit_rpath, $1)=no +_LT_TAGVAR(module_cmds, $1)= +_LT_TAGVAR(module_expsym_cmds, $1)= +_LT_TAGVAR(link_all_deplibs, $1)=unknown +_LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds +_LT_TAGVAR(reload_flag, $1)=$reload_flag +_LT_TAGVAR(reload_cmds, $1)=$reload_cmds +_LT_TAGVAR(no_undefined_flag, $1)= +_LT_TAGVAR(whole_archive_flag_spec, $1)= +_LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no + +# Source file extension for f77 test sources. +ac_ext=f + +# Object file extension for compiled f77 test sources. +objext=o +_LT_TAGVAR(objext, $1)=$objext + +# No sense in running all these tests if we already determined that +# the F77 compiler isn't working. Some variables (like enable_shared) +# are currently assumed to apply to all compilers on this platform, +# and will be corrupted by setting them based on a non-working compiler. +if test "$_lt_disable_F77" != yes; then + # Code to be used in simple compile tests + lt_simple_compile_test_code="\ + subroutine t + return + end +" + + # Code to be used in simple link tests + lt_simple_link_test_code="\ + program t + end +" + + # ltmain only uses $CC for tagged configurations so make sure $CC is set. + _LT_TAG_COMPILER + + # save warnings/boilerplate of simple test code + _LT_COMPILER_BOILERPLATE + _LT_LINKER_BOILERPLATE + + # Allow CC to be a program name with arguments. + lt_save_CC="$CC" + lt_save_GCC=$GCC + lt_save_CFLAGS=$CFLAGS + CC=${F77-"f77"} + CFLAGS=$FFLAGS + compiler=$CC + _LT_TAGVAR(compiler, $1)=$CC + _LT_CC_BASENAME([$compiler]) + GCC=$G77 + if test -n "$compiler"; then + AC_MSG_CHECKING([if libtool supports shared libraries]) + AC_MSG_RESULT([$can_build_shared]) + + AC_MSG_CHECKING([whether to build shared libraries]) + test "$can_build_shared" = "no" && enable_shared=no + + # On AIX, shared libraries and static libraries use the same namespace, and + # are all built from PIC. + case $host_os in + aix3*) + test "$enable_shared" = yes && enable_static=no + if test -n "$RANLIB"; then + archive_cmds="$archive_cmds~\$RANLIB \$lib" + postinstall_cmds='$RANLIB $lib' + fi + ;; + aix[[4-9]]*) + if test "$host_cpu" != ia64 && test "$aix_use_runtimelinking" = no ; then + test "$enable_shared" = yes && enable_static=no + fi + ;; + esac + AC_MSG_RESULT([$enable_shared]) + + AC_MSG_CHECKING([whether to build static libraries]) + # Make sure either enable_shared or enable_static is yes. + test "$enable_shared" = yes || enable_static=yes + AC_MSG_RESULT([$enable_static]) + + _LT_TAGVAR(GCC, $1)="$G77" + _LT_TAGVAR(LD, $1)="$LD" + + ## CAVEAT EMPTOR: + ## There is no encapsulation within the following macros, do not change + ## the running order or otherwise move them around unless you know exactly + ## what you are doing... + _LT_COMPILER_PIC($1) + _LT_COMPILER_C_O($1) + _LT_COMPILER_FILE_LOCKS($1) + _LT_LINKER_SHLIBS($1) + _LT_SYS_DYNAMIC_LINKER($1) + _LT_LINKER_HARDCODE_LIBPATH($1) + + _LT_CONFIG($1) + fi # test -n "$compiler" + + GCC=$lt_save_GCC + CC="$lt_save_CC" + CFLAGS="$lt_save_CFLAGS" +fi # test "$_lt_disable_F77" != yes + +AC_LANG_POP +])# _LT_LANG_F77_CONFIG + + +# _LT_LANG_FC_CONFIG([TAG]) +# ------------------------- +# Ensure that the configuration variables for a Fortran compiler are +# suitably defined. These variables are subsequently used by _LT_CONFIG +# to write the compiler configuration to `libtool'. +m4_defun([_LT_LANG_FC_CONFIG], +[AC_LANG_PUSH(Fortran) + +if test -z "$FC" || test "X$FC" = "Xno"; then + _lt_disable_FC=yes +fi + +_LT_TAGVAR(archive_cmds_need_lc, $1)=no +_LT_TAGVAR(allow_undefined_flag, $1)= +_LT_TAGVAR(always_export_symbols, $1)=no +_LT_TAGVAR(archive_expsym_cmds, $1)= +_LT_TAGVAR(export_dynamic_flag_spec, $1)= +_LT_TAGVAR(hardcode_direct, $1)=no +_LT_TAGVAR(hardcode_direct_absolute, $1)=no +_LT_TAGVAR(hardcode_libdir_flag_spec, $1)= +_LT_TAGVAR(hardcode_libdir_separator, $1)= +_LT_TAGVAR(hardcode_minus_L, $1)=no +_LT_TAGVAR(hardcode_automatic, $1)=no +_LT_TAGVAR(inherit_rpath, $1)=no +_LT_TAGVAR(module_cmds, $1)= +_LT_TAGVAR(module_expsym_cmds, $1)= +_LT_TAGVAR(link_all_deplibs, $1)=unknown +_LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds +_LT_TAGVAR(reload_flag, $1)=$reload_flag +_LT_TAGVAR(reload_cmds, $1)=$reload_cmds +_LT_TAGVAR(no_undefined_flag, $1)= +_LT_TAGVAR(whole_archive_flag_spec, $1)= +_LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no + +# Source file extension for fc test sources. +ac_ext=${ac_fc_srcext-f} + +# Object file extension for compiled fc test sources. +objext=o +_LT_TAGVAR(objext, $1)=$objext + +# No sense in running all these tests if we already determined that +# the FC compiler isn't working. Some variables (like enable_shared) +# are currently assumed to apply to all compilers on this platform, +# and will be corrupted by setting them based on a non-working compiler. +if test "$_lt_disable_FC" != yes; then + # Code to be used in simple compile tests + lt_simple_compile_test_code="\ + subroutine t + return + end +" + + # Code to be used in simple link tests + lt_simple_link_test_code="\ + program t + end +" + + # ltmain only uses $CC for tagged configurations so make sure $CC is set. + _LT_TAG_COMPILER + + # save warnings/boilerplate of simple test code + _LT_COMPILER_BOILERPLATE + _LT_LINKER_BOILERPLATE + + # Allow CC to be a program name with arguments. + lt_save_CC="$CC" + lt_save_GCC=$GCC + lt_save_CFLAGS=$CFLAGS + CC=${FC-"f95"} + CFLAGS=$FCFLAGS + compiler=$CC + GCC=$ac_cv_fc_compiler_gnu + + _LT_TAGVAR(compiler, $1)=$CC + _LT_CC_BASENAME([$compiler]) + + if test -n "$compiler"; then + AC_MSG_CHECKING([if libtool supports shared libraries]) + AC_MSG_RESULT([$can_build_shared]) + + AC_MSG_CHECKING([whether to build shared libraries]) + test "$can_build_shared" = "no" && enable_shared=no + + # On AIX, shared libraries and static libraries use the same namespace, and + # are all built from PIC. + case $host_os in + aix3*) + test "$enable_shared" = yes && enable_static=no + if test -n "$RANLIB"; then + archive_cmds="$archive_cmds~\$RANLIB \$lib" + postinstall_cmds='$RANLIB $lib' + fi + ;; + aix[[4-9]]*) + if test "$host_cpu" != ia64 && test "$aix_use_runtimelinking" = no ; then + test "$enable_shared" = yes && enable_static=no + fi + ;; + esac + AC_MSG_RESULT([$enable_shared]) + + AC_MSG_CHECKING([whether to build static libraries]) + # Make sure either enable_shared or enable_static is yes. + test "$enable_shared" = yes || enable_static=yes + AC_MSG_RESULT([$enable_static]) + + _LT_TAGVAR(GCC, $1)="$ac_cv_fc_compiler_gnu" + _LT_TAGVAR(LD, $1)="$LD" + + ## CAVEAT EMPTOR: + ## There is no encapsulation within the following macros, do not change + ## the running order or otherwise move them around unless you know exactly + ## what you are doing... + _LT_SYS_HIDDEN_LIBDEPS($1) + _LT_COMPILER_PIC($1) + _LT_COMPILER_C_O($1) + _LT_COMPILER_FILE_LOCKS($1) + _LT_LINKER_SHLIBS($1) + _LT_SYS_DYNAMIC_LINKER($1) + _LT_LINKER_HARDCODE_LIBPATH($1) + + _LT_CONFIG($1) + fi # test -n "$compiler" + + GCC=$lt_save_GCC + CC=$lt_save_CC + CFLAGS=$lt_save_CFLAGS +fi # test "$_lt_disable_FC" != yes + +AC_LANG_POP +])# _LT_LANG_FC_CONFIG + + +# _LT_LANG_GCJ_CONFIG([TAG]) +# -------------------------- +# Ensure that the configuration variables for the GNU Java Compiler compiler +# are suitably defined. These variables are subsequently used by _LT_CONFIG +# to write the compiler configuration to `libtool'. +m4_defun([_LT_LANG_GCJ_CONFIG], +[AC_REQUIRE([LT_PROG_GCJ])dnl +AC_LANG_SAVE + +# Source file extension for Java test sources. +ac_ext=java + +# Object file extension for compiled Java test sources. +objext=o +_LT_TAGVAR(objext, $1)=$objext + +# Code to be used in simple compile tests +lt_simple_compile_test_code="class foo {}" + +# Code to be used in simple link tests +lt_simple_link_test_code='public class conftest { public static void main(String[[]] argv) {}; }' + +# ltmain only uses $CC for tagged configurations so make sure $CC is set. +_LT_TAG_COMPILER + +# save warnings/boilerplate of simple test code +_LT_COMPILER_BOILERPLATE +_LT_LINKER_BOILERPLATE + +# Allow CC to be a program name with arguments. +lt_save_CC=$CC +lt_save_CFLAGS=$CFLAGS +lt_save_GCC=$GCC +GCC=yes +CC=${GCJ-"gcj"} +CFLAGS=$GCJFLAGS +compiler=$CC +_LT_TAGVAR(compiler, $1)=$CC +_LT_TAGVAR(LD, $1)="$LD" +_LT_CC_BASENAME([$compiler]) + +# GCJ did not exist at the time GCC didn't implicitly link libc in. +_LT_TAGVAR(archive_cmds_need_lc, $1)=no + +_LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds +_LT_TAGVAR(reload_flag, $1)=$reload_flag +_LT_TAGVAR(reload_cmds, $1)=$reload_cmds + +## CAVEAT EMPTOR: +## There is no encapsulation within the following macros, do not change +## the running order or otherwise move them around unless you know exactly +## what you are doing... +if test -n "$compiler"; then + _LT_COMPILER_NO_RTTI($1) + _LT_COMPILER_PIC($1) + _LT_COMPILER_C_O($1) + _LT_COMPILER_FILE_LOCKS($1) + _LT_LINKER_SHLIBS($1) + _LT_LINKER_HARDCODE_LIBPATH($1) + + _LT_CONFIG($1) +fi + +AC_LANG_RESTORE + +GCC=$lt_save_GCC +CC=$lt_save_CC +CFLAGS=$lt_save_CFLAGS +])# _LT_LANG_GCJ_CONFIG + + +# _LT_LANG_GO_CONFIG([TAG]) +# -------------------------- +# Ensure that the configuration variables for the GNU Go compiler +# are suitably defined. These variables are subsequently used by _LT_CONFIG +# to write the compiler configuration to `libtool'. +m4_defun([_LT_LANG_GO_CONFIG], +[AC_REQUIRE([LT_PROG_GO])dnl +AC_LANG_SAVE + +# Source file extension for Go test sources. +ac_ext=go + +# Object file extension for compiled Go test sources. +objext=o +_LT_TAGVAR(objext, $1)=$objext + +# Code to be used in simple compile tests +lt_simple_compile_test_code="package main; func main() { }" + +# Code to be used in simple link tests +lt_simple_link_test_code='package main; func main() { }' + +# ltmain only uses $CC for tagged configurations so make sure $CC is set. +_LT_TAG_COMPILER + +# save warnings/boilerplate of simple test code +_LT_COMPILER_BOILERPLATE +_LT_LINKER_BOILERPLATE + +# Allow CC to be a program name with arguments. +lt_save_CC=$CC +lt_save_CFLAGS=$CFLAGS +lt_save_GCC=$GCC +GCC=yes +CC=${GOC-"gccgo"} +CFLAGS=$GOFLAGS +compiler=$CC +_LT_TAGVAR(compiler, $1)=$CC +_LT_TAGVAR(LD, $1)="$LD" +_LT_CC_BASENAME([$compiler]) + +# Go did not exist at the time GCC didn't implicitly link libc in. +_LT_TAGVAR(archive_cmds_need_lc, $1)=no + +_LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds +_LT_TAGVAR(reload_flag, $1)=$reload_flag +_LT_TAGVAR(reload_cmds, $1)=$reload_cmds + +## CAVEAT EMPTOR: +## There is no encapsulation within the following macros, do not change +## the running order or otherwise move them around unless you know exactly +## what you are doing... +if test -n "$compiler"; then + _LT_COMPILER_NO_RTTI($1) + _LT_COMPILER_PIC($1) + _LT_COMPILER_C_O($1) + _LT_COMPILER_FILE_LOCKS($1) + _LT_LINKER_SHLIBS($1) + _LT_LINKER_HARDCODE_LIBPATH($1) + + _LT_CONFIG($1) +fi + +AC_LANG_RESTORE + +GCC=$lt_save_GCC +CC=$lt_save_CC +CFLAGS=$lt_save_CFLAGS +])# _LT_LANG_GO_CONFIG + + +# _LT_LANG_RC_CONFIG([TAG]) +# ------------------------- +# Ensure that the configuration variables for the Windows resource compiler +# are suitably defined. These variables are subsequently used by _LT_CONFIG +# to write the compiler configuration to `libtool'. +m4_defun([_LT_LANG_RC_CONFIG], +[AC_REQUIRE([LT_PROG_RC])dnl +AC_LANG_SAVE + +# Source file extension for RC test sources. +ac_ext=rc + +# Object file extension for compiled RC test sources. +objext=o +_LT_TAGVAR(objext, $1)=$objext + +# Code to be used in simple compile tests +lt_simple_compile_test_code='sample MENU { MENUITEM "&Soup", 100, CHECKED }' + +# Code to be used in simple link tests +lt_simple_link_test_code="$lt_simple_compile_test_code" + +# ltmain only uses $CC for tagged configurations so make sure $CC is set. +_LT_TAG_COMPILER + +# save warnings/boilerplate of simple test code +_LT_COMPILER_BOILERPLATE +_LT_LINKER_BOILERPLATE + +# Allow CC to be a program name with arguments. +lt_save_CC="$CC" +lt_save_CFLAGS=$CFLAGS +lt_save_GCC=$GCC +GCC= +CC=${RC-"windres"} +CFLAGS= +compiler=$CC +_LT_TAGVAR(compiler, $1)=$CC +_LT_CC_BASENAME([$compiler]) +_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)=yes + +if test -n "$compiler"; then + : + _LT_CONFIG($1) +fi + +GCC=$lt_save_GCC +AC_LANG_RESTORE +CC=$lt_save_CC +CFLAGS=$lt_save_CFLAGS +])# _LT_LANG_RC_CONFIG + + +# LT_PROG_GCJ +# ----------- +AC_DEFUN([LT_PROG_GCJ], +[m4_ifdef([AC_PROG_GCJ], [AC_PROG_GCJ], + [m4_ifdef([A][M_PROG_GCJ], [A][M_PROG_GCJ], + [AC_CHECK_TOOL(GCJ, gcj,) + test "x${GCJFLAGS+set}" = xset || GCJFLAGS="-g -O2" + AC_SUBST(GCJFLAGS)])])[]dnl +]) + +# Old name: +AU_ALIAS([LT_AC_PROG_GCJ], [LT_PROG_GCJ]) +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([LT_AC_PROG_GCJ], []) + + +# LT_PROG_GO +# ---------- +AC_DEFUN([LT_PROG_GO], +[AC_CHECK_TOOL(GOC, gccgo,) +]) + + +# LT_PROG_RC +# ---------- +AC_DEFUN([LT_PROG_RC], +[AC_CHECK_TOOL(RC, windres,) +]) + +# Old name: +AU_ALIAS([LT_AC_PROG_RC], [LT_PROG_RC]) +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([LT_AC_PROG_RC], []) + + +# _LT_DECL_EGREP +# -------------- +# If we don't have a new enough Autoconf to choose the best grep +# available, choose the one first in the user's PATH. +m4_defun([_LT_DECL_EGREP], +[AC_REQUIRE([AC_PROG_EGREP])dnl +AC_REQUIRE([AC_PROG_FGREP])dnl +test -z "$GREP" && GREP=grep +_LT_DECL([], [GREP], [1], [A grep program that handles long lines]) +_LT_DECL([], [EGREP], [1], [An ERE matcher]) +_LT_DECL([], [FGREP], [1], [A literal string matcher]) +dnl Non-bleeding-edge autoconf doesn't subst GREP, so do it here too +AC_SUBST([GREP]) +]) + + +# _LT_DECL_OBJDUMP +# -------------- +# If we don't have a new enough Autoconf to choose the best objdump +# available, choose the one first in the user's PATH. +m4_defun([_LT_DECL_OBJDUMP], +[AC_CHECK_TOOL(OBJDUMP, objdump, false) +test -z "$OBJDUMP" && OBJDUMP=objdump +_LT_DECL([], [OBJDUMP], [1], [An object symbol dumper]) +AC_SUBST([OBJDUMP]) +]) + +# _LT_DECL_DLLTOOL +# ---------------- +# Ensure DLLTOOL variable is set. +m4_defun([_LT_DECL_DLLTOOL], +[AC_CHECK_TOOL(DLLTOOL, dlltool, false) +test -z "$DLLTOOL" && DLLTOOL=dlltool +_LT_DECL([], [DLLTOOL], [1], [DLL creation program]) +AC_SUBST([DLLTOOL]) +]) + +# _LT_DECL_SED +# ------------ +# Check for a fully-functional sed program, that truncates +# as few characters as possible. Prefer GNU sed if found. +m4_defun([_LT_DECL_SED], +[AC_PROG_SED +test -z "$SED" && SED=sed +Xsed="$SED -e 1s/^X//" +_LT_DECL([], [SED], [1], [A sed program that does not truncate output]) +_LT_DECL([], [Xsed], ["\$SED -e 1s/^X//"], + [Sed that helps us avoid accidentally triggering echo(1) options like -n]) +])# _LT_DECL_SED + +m4_ifndef([AC_PROG_SED], [ +############################################################ +# NOTE: This macro has been submitted for inclusion into # +# GNU Autoconf as AC_PROG_SED. When it is available in # +# a released version of Autoconf we should remove this # +# macro and use it instead. # +############################################################ + +m4_defun([AC_PROG_SED], +[AC_MSG_CHECKING([for a sed that does not truncate output]) +AC_CACHE_VAL(lt_cv_path_SED, +[# Loop through the user's path and test for sed and gsed. +# Then use that list of sed's as ones to test for truncation. +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for lt_ac_prog in sed gsed; do + for ac_exec_ext in '' $ac_executable_extensions; do + if $as_executable_p "$as_dir/$lt_ac_prog$ac_exec_ext"; then + lt_ac_sed_list="$lt_ac_sed_list $as_dir/$lt_ac_prog$ac_exec_ext" + fi + done + done +done +IFS=$as_save_IFS +lt_ac_max=0 +lt_ac_count=0 +# Add /usr/xpg4/bin/sed as it is typically found on Solaris +# along with /bin/sed that truncates output. +for lt_ac_sed in $lt_ac_sed_list /usr/xpg4/bin/sed; do + test ! -f $lt_ac_sed && continue + cat /dev/null > conftest.in + lt_ac_count=0 + echo $ECHO_N "0123456789$ECHO_C" >conftest.in + # Check for GNU sed and select it if it is found. + if "$lt_ac_sed" --version 2>&1 < /dev/null | grep 'GNU' > /dev/null; then + lt_cv_path_SED=$lt_ac_sed + break + fi + while true; do + cat conftest.in conftest.in >conftest.tmp + mv conftest.tmp conftest.in + cp conftest.in conftest.nl + echo >>conftest.nl + $lt_ac_sed -e 's/a$//' < conftest.nl >conftest.out || break + cmp -s conftest.out conftest.nl || break + # 10000 chars as input seems more than enough + test $lt_ac_count -gt 10 && break + lt_ac_count=`expr $lt_ac_count + 1` + if test $lt_ac_count -gt $lt_ac_max; then + lt_ac_max=$lt_ac_count + lt_cv_path_SED=$lt_ac_sed + fi + done +done +]) +SED=$lt_cv_path_SED +AC_SUBST([SED]) +AC_MSG_RESULT([$SED]) +])#AC_PROG_SED +])#m4_ifndef + +# Old name: +AU_ALIAS([LT_AC_PROG_SED], [AC_PROG_SED]) +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([LT_AC_PROG_SED], []) + + +# _LT_CHECK_SHELL_FEATURES +# ------------------------ +# Find out whether the shell is Bourne or XSI compatible, +# or has some other useful features. +m4_defun([_LT_CHECK_SHELL_FEATURES], +[AC_MSG_CHECKING([whether the shell understands some XSI constructs]) +# Try some XSI features +xsi_shell=no +( _lt_dummy="a/b/c" + test "${_lt_dummy##*/},${_lt_dummy%/*},${_lt_dummy#??}"${_lt_dummy%"$_lt_dummy"}, \ + = c,a/b,b/c, \ + && eval 'test $(( 1 + 1 )) -eq 2 \ + && test "${#_lt_dummy}" -eq 5' ) >/dev/null 2>&1 \ + && xsi_shell=yes +AC_MSG_RESULT([$xsi_shell]) +_LT_CONFIG_LIBTOOL_INIT([xsi_shell='$xsi_shell']) + +AC_MSG_CHECKING([whether the shell understands "+="]) +lt_shell_append=no +( foo=bar; set foo baz; eval "$[1]+=\$[2]" && test "$foo" = barbaz ) \ + >/dev/null 2>&1 \ + && lt_shell_append=yes +AC_MSG_RESULT([$lt_shell_append]) +_LT_CONFIG_LIBTOOL_INIT([lt_shell_append='$lt_shell_append']) + +if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then + lt_unset=unset +else + lt_unset=false +fi +_LT_DECL([], [lt_unset], [0], [whether the shell understands "unset"])dnl + +# test EBCDIC or ASCII +case `echo X|tr X '\101'` in + A) # ASCII based system + # \n is not interpreted correctly by Solaris 8 /usr/ucb/tr + lt_SP2NL='tr \040 \012' + lt_NL2SP='tr \015\012 \040\040' + ;; + *) # EBCDIC based system + lt_SP2NL='tr \100 \n' + lt_NL2SP='tr \r\n \100\100' + ;; +esac +_LT_DECL([SP2NL], [lt_SP2NL], [1], [turn spaces into newlines])dnl +_LT_DECL([NL2SP], [lt_NL2SP], [1], [turn newlines into spaces])dnl +])# _LT_CHECK_SHELL_FEATURES + + +# _LT_PROG_FUNCTION_REPLACE (FUNCNAME, REPLACEMENT-BODY) +# ------------------------------------------------------ +# In `$cfgfile', look for function FUNCNAME delimited by `^FUNCNAME ()$' and +# '^} FUNCNAME ', and replace its body with REPLACEMENT-BODY. +m4_defun([_LT_PROG_FUNCTION_REPLACE], +[dnl { +sed -e '/^$1 ()$/,/^} # $1 /c\ +$1 ()\ +{\ +m4_bpatsubsts([$2], [$], [\\], [^\([ ]\)], [\\\1]) +} # Extended-shell $1 implementation' "$cfgfile" > $cfgfile.tmp \ + && mv -f "$cfgfile.tmp" "$cfgfile" \ + || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") +test 0 -eq $? || _lt_function_replace_fail=: +]) + + +# _LT_PROG_REPLACE_SHELLFNS +# ------------------------- +# Replace existing portable implementations of several shell functions with +# equivalent extended shell implementations where those features are available.. +m4_defun([_LT_PROG_REPLACE_SHELLFNS], +[if test x"$xsi_shell" = xyes; then + _LT_PROG_FUNCTION_REPLACE([func_dirname], [dnl + case ${1} in + */*) func_dirname_result="${1%/*}${2}" ;; + * ) func_dirname_result="${3}" ;; + esac]) + + _LT_PROG_FUNCTION_REPLACE([func_basename], [dnl + func_basename_result="${1##*/}"]) + + _LT_PROG_FUNCTION_REPLACE([func_dirname_and_basename], [dnl + case ${1} in + */*) func_dirname_result="${1%/*}${2}" ;; + * ) func_dirname_result="${3}" ;; + esac + func_basename_result="${1##*/}"]) + + _LT_PROG_FUNCTION_REPLACE([func_stripname], [dnl + # pdksh 5.2.14 does not do ${X%$Y} correctly if both X and Y are + # positional parameters, so assign one to ordinary parameter first. + func_stripname_result=${3} + func_stripname_result=${func_stripname_result#"${1}"} + func_stripname_result=${func_stripname_result%"${2}"}]) + + _LT_PROG_FUNCTION_REPLACE([func_split_long_opt], [dnl + func_split_long_opt_name=${1%%=*} + func_split_long_opt_arg=${1#*=}]) + + _LT_PROG_FUNCTION_REPLACE([func_split_short_opt], [dnl + func_split_short_opt_arg=${1#??} + func_split_short_opt_name=${1%"$func_split_short_opt_arg"}]) + + _LT_PROG_FUNCTION_REPLACE([func_lo2o], [dnl + case ${1} in + *.lo) func_lo2o_result=${1%.lo}.${objext} ;; + *) func_lo2o_result=${1} ;; + esac]) + + _LT_PROG_FUNCTION_REPLACE([func_xform], [ func_xform_result=${1%.*}.lo]) + + _LT_PROG_FUNCTION_REPLACE([func_arith], [ func_arith_result=$(( $[*] ))]) + + _LT_PROG_FUNCTION_REPLACE([func_len], [ func_len_result=${#1}]) +fi + +if test x"$lt_shell_append" = xyes; then + _LT_PROG_FUNCTION_REPLACE([func_append], [ eval "${1}+=\\${2}"]) + + _LT_PROG_FUNCTION_REPLACE([func_append_quoted], [dnl + func_quote_for_eval "${2}" +dnl m4 expansion turns \\\\ into \\, and then the shell eval turns that into \ + eval "${1}+=\\\\ \\$func_quote_for_eval_result"]) + + # Save a `func_append' function call where possible by direct use of '+=' + sed -e 's%func_append \([[a-zA-Z_]]\{1,\}\) "%\1+="%g' $cfgfile > $cfgfile.tmp \ + && mv -f "$cfgfile.tmp" "$cfgfile" \ + || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") + test 0 -eq $? || _lt_function_replace_fail=: +else + # Save a `func_append' function call even when '+=' is not available + sed -e 's%func_append \([[a-zA-Z_]]\{1,\}\) "%\1="$\1%g' $cfgfile > $cfgfile.tmp \ + && mv -f "$cfgfile.tmp" "$cfgfile" \ + || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") + test 0 -eq $? || _lt_function_replace_fail=: +fi + +if test x"$_lt_function_replace_fail" = x":"; then + AC_MSG_WARN([Unable to substitute extended shell functions in $ofile]) +fi +]) + +# _LT_PATH_CONVERSION_FUNCTIONS +# ----------------------------- +# Determine which file name conversion functions should be used by +# func_to_host_file (and, implicitly, by func_to_host_path). These are needed +# for certain cross-compile configurations and native mingw. +m4_defun([_LT_PATH_CONVERSION_FUNCTIONS], +[AC_REQUIRE([AC_CANONICAL_HOST])dnl +AC_REQUIRE([AC_CANONICAL_BUILD])dnl +AC_MSG_CHECKING([how to convert $build file names to $host format]) +AC_CACHE_VAL(lt_cv_to_host_file_cmd, +[case $host in + *-*-mingw* ) + case $build in + *-*-mingw* ) # actually msys + lt_cv_to_host_file_cmd=func_convert_file_msys_to_w32 + ;; + *-*-cygwin* ) + lt_cv_to_host_file_cmd=func_convert_file_cygwin_to_w32 + ;; + * ) # otherwise, assume *nix + lt_cv_to_host_file_cmd=func_convert_file_nix_to_w32 + ;; + esac + ;; + *-*-cygwin* ) + case $build in + *-*-mingw* ) # actually msys + lt_cv_to_host_file_cmd=func_convert_file_msys_to_cygwin + ;; + *-*-cygwin* ) + lt_cv_to_host_file_cmd=func_convert_file_noop + ;; + * ) # otherwise, assume *nix + lt_cv_to_host_file_cmd=func_convert_file_nix_to_cygwin + ;; + esac + ;; + * ) # unhandled hosts (and "normal" native builds) + lt_cv_to_host_file_cmd=func_convert_file_noop + ;; +esac +]) +to_host_file_cmd=$lt_cv_to_host_file_cmd +AC_MSG_RESULT([$lt_cv_to_host_file_cmd]) +_LT_DECL([to_host_file_cmd], [lt_cv_to_host_file_cmd], + [0], [convert $build file names to $host format])dnl + +AC_MSG_CHECKING([how to convert $build file names to toolchain format]) +AC_CACHE_VAL(lt_cv_to_tool_file_cmd, +[#assume ordinary cross tools, or native build. +lt_cv_to_tool_file_cmd=func_convert_file_noop +case $host in + *-*-mingw* ) + case $build in + *-*-mingw* ) # actually msys + lt_cv_to_tool_file_cmd=func_convert_file_msys_to_w32 + ;; + esac + ;; +esac +]) +to_tool_file_cmd=$lt_cv_to_tool_file_cmd +AC_MSG_RESULT([$lt_cv_to_tool_file_cmd]) +_LT_DECL([to_tool_file_cmd], [lt_cv_to_tool_file_cmd], + [0], [convert $build files to toolchain format])dnl +])# _LT_PATH_CONVERSION_FUNCTIONS diff --git a/contrib/openpam/m4/ltoptions.m4 b/contrib/openpam/m4/ltoptions.m4 new file mode 100644 index 000000000000..5d9acd8e23bc --- /dev/null +++ b/contrib/openpam/m4/ltoptions.m4 @@ -0,0 +1,384 @@ +# Helper functions for option handling. -*- Autoconf -*- +# +# Copyright (C) 2004, 2005, 2007, 2008, 2009 Free Software Foundation, +# Inc. +# Written by Gary V. Vaughan, 2004 +# +# This file is free software; the Free Software Foundation gives +# unlimited permission to copy and/or distribute it, with or without +# modifications, as long as this notice is preserved. + +# serial 7 ltoptions.m4 + +# This is to help aclocal find these macros, as it can't see m4_define. +AC_DEFUN([LTOPTIONS_VERSION], [m4_if([1])]) + + +# _LT_MANGLE_OPTION(MACRO-NAME, OPTION-NAME) +# ------------------------------------------ +m4_define([_LT_MANGLE_OPTION], +[[_LT_OPTION_]m4_bpatsubst($1__$2, [[^a-zA-Z0-9_]], [_])]) + + +# _LT_SET_OPTION(MACRO-NAME, OPTION-NAME) +# --------------------------------------- +# Set option OPTION-NAME for macro MACRO-NAME, and if there is a +# matching handler defined, dispatch to it. Other OPTION-NAMEs are +# saved as a flag. +m4_define([_LT_SET_OPTION], +[m4_define(_LT_MANGLE_OPTION([$1], [$2]))dnl +m4_ifdef(_LT_MANGLE_DEFUN([$1], [$2]), + _LT_MANGLE_DEFUN([$1], [$2]), + [m4_warning([Unknown $1 option `$2'])])[]dnl +]) + + +# _LT_IF_OPTION(MACRO-NAME, OPTION-NAME, IF-SET, [IF-NOT-SET]) +# ------------------------------------------------------------ +# Execute IF-SET if OPTION is set, IF-NOT-SET otherwise. +m4_define([_LT_IF_OPTION], +[m4_ifdef(_LT_MANGLE_OPTION([$1], [$2]), [$3], [$4])]) + + +# _LT_UNLESS_OPTIONS(MACRO-NAME, OPTION-LIST, IF-NOT-SET) +# ------------------------------------------------------- +# Execute IF-NOT-SET unless all options in OPTION-LIST for MACRO-NAME +# are set. +m4_define([_LT_UNLESS_OPTIONS], +[m4_foreach([_LT_Option], m4_split(m4_normalize([$2])), + [m4_ifdef(_LT_MANGLE_OPTION([$1], _LT_Option), + [m4_define([$0_found])])])[]dnl +m4_ifdef([$0_found], [m4_undefine([$0_found])], [$3 +])[]dnl +]) + + +# _LT_SET_OPTIONS(MACRO-NAME, OPTION-LIST) +# ---------------------------------------- +# OPTION-LIST is a space-separated list of Libtool options associated +# with MACRO-NAME. If any OPTION has a matching handler declared with +# LT_OPTION_DEFINE, dispatch to that macro; otherwise complain about +# the unknown option and exit. +m4_defun([_LT_SET_OPTIONS], +[# Set options +m4_foreach([_LT_Option], m4_split(m4_normalize([$2])), + [_LT_SET_OPTION([$1], _LT_Option)]) + +m4_if([$1],[LT_INIT],[ + dnl + dnl Simply set some default values (i.e off) if boolean options were not + dnl specified: + _LT_UNLESS_OPTIONS([LT_INIT], [dlopen], [enable_dlopen=no + ]) + _LT_UNLESS_OPTIONS([LT_INIT], [win32-dll], [enable_win32_dll=no + ]) + dnl + dnl If no reference was made to various pairs of opposing options, then + dnl we run the default mode handler for the pair. For example, if neither + dnl `shared' nor `disable-shared' was passed, we enable building of shared + dnl archives by default: + _LT_UNLESS_OPTIONS([LT_INIT], [shared disable-shared], [_LT_ENABLE_SHARED]) + _LT_UNLESS_OPTIONS([LT_INIT], [static disable-static], [_LT_ENABLE_STATIC]) + _LT_UNLESS_OPTIONS([LT_INIT], [pic-only no-pic], [_LT_WITH_PIC]) + _LT_UNLESS_OPTIONS([LT_INIT], [fast-install disable-fast-install], + [_LT_ENABLE_FAST_INSTALL]) + ]) +])# _LT_SET_OPTIONS + + +## --------------------------------- ## +## Macros to handle LT_INIT options. ## +## --------------------------------- ## + +# _LT_MANGLE_DEFUN(MACRO-NAME, OPTION-NAME) +# ----------------------------------------- +m4_define([_LT_MANGLE_DEFUN], +[[_LT_OPTION_DEFUN_]m4_bpatsubst(m4_toupper([$1__$2]), [[^A-Z0-9_]], [_])]) + + +# LT_OPTION_DEFINE(MACRO-NAME, OPTION-NAME, CODE) +# ----------------------------------------------- +m4_define([LT_OPTION_DEFINE], +[m4_define(_LT_MANGLE_DEFUN([$1], [$2]), [$3])[]dnl +])# LT_OPTION_DEFINE + + +# dlopen +# ------ +LT_OPTION_DEFINE([LT_INIT], [dlopen], [enable_dlopen=yes +]) + +AU_DEFUN([AC_LIBTOOL_DLOPEN], +[_LT_SET_OPTION([LT_INIT], [dlopen]) +AC_DIAGNOSE([obsolete], +[$0: Remove this warning and the call to _LT_SET_OPTION when you +put the `dlopen' option into LT_INIT's first parameter.]) +]) + +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AC_LIBTOOL_DLOPEN], []) + + +# win32-dll +# --------- +# Declare package support for building win32 dll's. +LT_OPTION_DEFINE([LT_INIT], [win32-dll], +[enable_win32_dll=yes + +case $host in +*-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-cegcc*) + AC_CHECK_TOOL(AS, as, false) + AC_CHECK_TOOL(DLLTOOL, dlltool, false) + AC_CHECK_TOOL(OBJDUMP, objdump, false) + ;; +esac + +test -z "$AS" && AS=as +_LT_DECL([], [AS], [1], [Assembler program])dnl + +test -z "$DLLTOOL" && DLLTOOL=dlltool +_LT_DECL([], [DLLTOOL], [1], [DLL creation program])dnl + +test -z "$OBJDUMP" && OBJDUMP=objdump +_LT_DECL([], [OBJDUMP], [1], [Object dumper program])dnl +])# win32-dll + +AU_DEFUN([AC_LIBTOOL_WIN32_DLL], +[AC_REQUIRE([AC_CANONICAL_HOST])dnl +_LT_SET_OPTION([LT_INIT], [win32-dll]) +AC_DIAGNOSE([obsolete], +[$0: Remove this warning and the call to _LT_SET_OPTION when you +put the `win32-dll' option into LT_INIT's first parameter.]) +]) + +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AC_LIBTOOL_WIN32_DLL], []) + + +# _LT_ENABLE_SHARED([DEFAULT]) +# ---------------------------- +# implement the --enable-shared flag, and supports the `shared' and +# `disable-shared' LT_INIT options. +# DEFAULT is either `yes' or `no'. If omitted, it defaults to `yes'. +m4_define([_LT_ENABLE_SHARED], +[m4_define([_LT_ENABLE_SHARED_DEFAULT], [m4_if($1, no, no, yes)])dnl +AC_ARG_ENABLE([shared], + [AS_HELP_STRING([--enable-shared@<:@=PKGS@:>@], + [build shared libraries @<:@default=]_LT_ENABLE_SHARED_DEFAULT[@:>@])], + [p=${PACKAGE-default} + case $enableval in + yes) enable_shared=yes ;; + no) enable_shared=no ;; + *) + enable_shared=no + # Look at the argument we got. We use all the common list separators. + lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," + for pkg in $enableval; do + IFS="$lt_save_ifs" + if test "X$pkg" = "X$p"; then + enable_shared=yes + fi + done + IFS="$lt_save_ifs" + ;; + esac], + [enable_shared=]_LT_ENABLE_SHARED_DEFAULT) + + _LT_DECL([build_libtool_libs], [enable_shared], [0], + [Whether or not to build shared libraries]) +])# _LT_ENABLE_SHARED + +LT_OPTION_DEFINE([LT_INIT], [shared], [_LT_ENABLE_SHARED([yes])]) +LT_OPTION_DEFINE([LT_INIT], [disable-shared], [_LT_ENABLE_SHARED([no])]) + +# Old names: +AC_DEFUN([AC_ENABLE_SHARED], +[_LT_SET_OPTION([LT_INIT], m4_if([$1], [no], [disable-])[shared]) +]) + +AC_DEFUN([AC_DISABLE_SHARED], +[_LT_SET_OPTION([LT_INIT], [disable-shared]) +]) + +AU_DEFUN([AM_ENABLE_SHARED], [AC_ENABLE_SHARED($@)]) +AU_DEFUN([AM_DISABLE_SHARED], [AC_DISABLE_SHARED($@)]) + +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AM_ENABLE_SHARED], []) +dnl AC_DEFUN([AM_DISABLE_SHARED], []) + + + +# _LT_ENABLE_STATIC([DEFAULT]) +# ---------------------------- +# implement the --enable-static flag, and support the `static' and +# `disable-static' LT_INIT options. +# DEFAULT is either `yes' or `no'. If omitted, it defaults to `yes'. +m4_define([_LT_ENABLE_STATIC], +[m4_define([_LT_ENABLE_STATIC_DEFAULT], [m4_if($1, no, no, yes)])dnl +AC_ARG_ENABLE([static], + [AS_HELP_STRING([--enable-static@<:@=PKGS@:>@], + [build static libraries @<:@default=]_LT_ENABLE_STATIC_DEFAULT[@:>@])], + [p=${PACKAGE-default} + case $enableval in + yes) enable_static=yes ;; + no) enable_static=no ;; + *) + enable_static=no + # Look at the argument we got. We use all the common list separators. + lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," + for pkg in $enableval; do + IFS="$lt_save_ifs" + if test "X$pkg" = "X$p"; then + enable_static=yes + fi + done + IFS="$lt_save_ifs" + ;; + esac], + [enable_static=]_LT_ENABLE_STATIC_DEFAULT) + + _LT_DECL([build_old_libs], [enable_static], [0], + [Whether or not to build static libraries]) +])# _LT_ENABLE_STATIC + +LT_OPTION_DEFINE([LT_INIT], [static], [_LT_ENABLE_STATIC([yes])]) +LT_OPTION_DEFINE([LT_INIT], [disable-static], [_LT_ENABLE_STATIC([no])]) + +# Old names: +AC_DEFUN([AC_ENABLE_STATIC], +[_LT_SET_OPTION([LT_INIT], m4_if([$1], [no], [disable-])[static]) +]) + +AC_DEFUN([AC_DISABLE_STATIC], +[_LT_SET_OPTION([LT_INIT], [disable-static]) +]) + +AU_DEFUN([AM_ENABLE_STATIC], [AC_ENABLE_STATIC($@)]) +AU_DEFUN([AM_DISABLE_STATIC], [AC_DISABLE_STATIC($@)]) + +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AM_ENABLE_STATIC], []) +dnl AC_DEFUN([AM_DISABLE_STATIC], []) + + + +# _LT_ENABLE_FAST_INSTALL([DEFAULT]) +# ---------------------------------- +# implement the --enable-fast-install flag, and support the `fast-install' +# and `disable-fast-install' LT_INIT options. +# DEFAULT is either `yes' or `no'. If omitted, it defaults to `yes'. +m4_define([_LT_ENABLE_FAST_INSTALL], +[m4_define([_LT_ENABLE_FAST_INSTALL_DEFAULT], [m4_if($1, no, no, yes)])dnl +AC_ARG_ENABLE([fast-install], + [AS_HELP_STRING([--enable-fast-install@<:@=PKGS@:>@], + [optimize for fast installation @<:@default=]_LT_ENABLE_FAST_INSTALL_DEFAULT[@:>@])], + [p=${PACKAGE-default} + case $enableval in + yes) enable_fast_install=yes ;; + no) enable_fast_install=no ;; + *) + enable_fast_install=no + # Look at the argument we got. We use all the common list separators. + lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," + for pkg in $enableval; do + IFS="$lt_save_ifs" + if test "X$pkg" = "X$p"; then + enable_fast_install=yes + fi + done + IFS="$lt_save_ifs" + ;; + esac], + [enable_fast_install=]_LT_ENABLE_FAST_INSTALL_DEFAULT) + +_LT_DECL([fast_install], [enable_fast_install], [0], + [Whether or not to optimize for fast installation])dnl +])# _LT_ENABLE_FAST_INSTALL + +LT_OPTION_DEFINE([LT_INIT], [fast-install], [_LT_ENABLE_FAST_INSTALL([yes])]) +LT_OPTION_DEFINE([LT_INIT], [disable-fast-install], [_LT_ENABLE_FAST_INSTALL([no])]) + +# Old names: +AU_DEFUN([AC_ENABLE_FAST_INSTALL], +[_LT_SET_OPTION([LT_INIT], m4_if([$1], [no], [disable-])[fast-install]) +AC_DIAGNOSE([obsolete], +[$0: Remove this warning and the call to _LT_SET_OPTION when you put +the `fast-install' option into LT_INIT's first parameter.]) +]) + +AU_DEFUN([AC_DISABLE_FAST_INSTALL], +[_LT_SET_OPTION([LT_INIT], [disable-fast-install]) +AC_DIAGNOSE([obsolete], +[$0: Remove this warning and the call to _LT_SET_OPTION when you put +the `disable-fast-install' option into LT_INIT's first parameter.]) +]) + +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AC_ENABLE_FAST_INSTALL], []) +dnl AC_DEFUN([AM_DISABLE_FAST_INSTALL], []) + + +# _LT_WITH_PIC([MODE]) +# -------------------- +# implement the --with-pic flag, and support the `pic-only' and `no-pic' +# LT_INIT options. +# MODE is either `yes' or `no'. If omitted, it defaults to `both'. +m4_define([_LT_WITH_PIC], +[AC_ARG_WITH([pic], + [AS_HELP_STRING([--with-pic@<:@=PKGS@:>@], + [try to use only PIC/non-PIC objects @<:@default=use both@:>@])], + [lt_p=${PACKAGE-default} + case $withval in + yes|no) pic_mode=$withval ;; + *) + pic_mode=default + # Look at the argument we got. We use all the common list separators. + lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," + for lt_pkg in $withval; do + IFS="$lt_save_ifs" + if test "X$lt_pkg" = "X$lt_p"; then + pic_mode=yes + fi + done + IFS="$lt_save_ifs" + ;; + esac], + [pic_mode=default]) + +test -z "$pic_mode" && pic_mode=m4_default([$1], [default]) + +_LT_DECL([], [pic_mode], [0], [What type of objects to build])dnl +])# _LT_WITH_PIC + +LT_OPTION_DEFINE([LT_INIT], [pic-only], [_LT_WITH_PIC([yes])]) +LT_OPTION_DEFINE([LT_INIT], [no-pic], [_LT_WITH_PIC([no])]) + +# Old name: +AU_DEFUN([AC_LIBTOOL_PICMODE], +[_LT_SET_OPTION([LT_INIT], [pic-only]) +AC_DIAGNOSE([obsolete], +[$0: Remove this warning and the call to _LT_SET_OPTION when you +put the `pic-only' option into LT_INIT's first parameter.]) +]) + +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AC_LIBTOOL_PICMODE], []) + +## ----------------- ## +## LTDL_INIT Options ## +## ----------------- ## + +m4_define([_LTDL_MODE], []) +LT_OPTION_DEFINE([LTDL_INIT], [nonrecursive], + [m4_define([_LTDL_MODE], [nonrecursive])]) +LT_OPTION_DEFINE([LTDL_INIT], [recursive], + [m4_define([_LTDL_MODE], [recursive])]) +LT_OPTION_DEFINE([LTDL_INIT], [subproject], + [m4_define([_LTDL_MODE], [subproject])]) + +m4_define([_LTDL_TYPE], []) +LT_OPTION_DEFINE([LTDL_INIT], [installable], + [m4_define([_LTDL_TYPE], [installable])]) +LT_OPTION_DEFINE([LTDL_INIT], [convenience], + [m4_define([_LTDL_TYPE], [convenience])]) diff --git a/contrib/openpam/m4/ltsugar.m4 b/contrib/openpam/m4/ltsugar.m4 new file mode 100644 index 000000000000..9000a057d31d --- /dev/null +++ b/contrib/openpam/m4/ltsugar.m4 @@ -0,0 +1,123 @@ +# ltsugar.m4 -- libtool m4 base layer. -*-Autoconf-*- +# +# Copyright (C) 2004, 2005, 2007, 2008 Free Software Foundation, Inc. +# Written by Gary V. Vaughan, 2004 +# +# This file is free software; the Free Software Foundation gives +# unlimited permission to copy and/or distribute it, with or without +# modifications, as long as this notice is preserved. + +# serial 6 ltsugar.m4 + +# This is to help aclocal find these macros, as it can't see m4_define. +AC_DEFUN([LTSUGAR_VERSION], [m4_if([0.1])]) + + +# lt_join(SEP, ARG1, [ARG2...]) +# ----------------------------- +# Produce ARG1SEPARG2...SEPARGn, omitting [] arguments and their +# associated separator. +# Needed until we can rely on m4_join from Autoconf 2.62, since all earlier +# versions in m4sugar had bugs. +m4_define([lt_join], +[m4_if([$#], [1], [], + [$#], [2], [[$2]], + [m4_if([$2], [], [], [[$2]_])$0([$1], m4_shift(m4_shift($@)))])]) +m4_define([_lt_join], +[m4_if([$#$2], [2], [], + [m4_if([$2], [], [], [[$1$2]])$0([$1], m4_shift(m4_shift($@)))])]) + + +# lt_car(LIST) +# lt_cdr(LIST) +# ------------ +# Manipulate m4 lists. +# These macros are necessary as long as will still need to support +# Autoconf-2.59 which quotes differently. +m4_define([lt_car], [[$1]]) +m4_define([lt_cdr], +[m4_if([$#], 0, [m4_fatal([$0: cannot be called without arguments])], + [$#], 1, [], + [m4_dquote(m4_shift($@))])]) +m4_define([lt_unquote], $1) + + +# lt_append(MACRO-NAME, STRING, [SEPARATOR]) +# ------------------------------------------ +# Redefine MACRO-NAME to hold its former content plus `SEPARATOR'`STRING'. +# Note that neither SEPARATOR nor STRING are expanded; they are appended +# to MACRO-NAME as is (leaving the expansion for when MACRO-NAME is invoked). +# No SEPARATOR is output if MACRO-NAME was previously undefined (different +# than defined and empty). +# +# This macro is needed until we can rely on Autoconf 2.62, since earlier +# versions of m4sugar mistakenly expanded SEPARATOR but not STRING. +m4_define([lt_append], +[m4_define([$1], + m4_ifdef([$1], [m4_defn([$1])[$3]])[$2])]) + + + +# lt_combine(SEP, PREFIX-LIST, INFIX, SUFFIX1, [SUFFIX2...]) +# ---------------------------------------------------------- +# Produce a SEP delimited list of all paired combinations of elements of +# PREFIX-LIST with SUFFIX1 through SUFFIXn. Each element of the list +# has the form PREFIXmINFIXSUFFIXn. +# Needed until we can rely on m4_combine added in Autoconf 2.62. +m4_define([lt_combine], +[m4_if(m4_eval([$# > 3]), [1], + [m4_pushdef([_Lt_sep], [m4_define([_Lt_sep], m4_defn([lt_car]))])]]dnl +[[m4_foreach([_Lt_prefix], [$2], + [m4_foreach([_Lt_suffix], + ]m4_dquote(m4_dquote(m4_shift(m4_shift(m4_shift($@)))))[, + [_Lt_sep([$1])[]m4_defn([_Lt_prefix])[$3]m4_defn([_Lt_suffix])])])])]) + + +# lt_if_append_uniq(MACRO-NAME, VARNAME, [SEPARATOR], [UNIQ], [NOT-UNIQ]) +# ----------------------------------------------------------------------- +# Iff MACRO-NAME does not yet contain VARNAME, then append it (delimited +# by SEPARATOR if supplied) and expand UNIQ, else NOT-UNIQ. +m4_define([lt_if_append_uniq], +[m4_ifdef([$1], + [m4_if(m4_index([$3]m4_defn([$1])[$3], [$3$2$3]), [-1], + [lt_append([$1], [$2], [$3])$4], + [$5])], + [lt_append([$1], [$2], [$3])$4])]) + + +# lt_dict_add(DICT, KEY, VALUE) +# ----------------------------- +m4_define([lt_dict_add], +[m4_define([$1($2)], [$3])]) + + +# lt_dict_add_subkey(DICT, KEY, SUBKEY, VALUE) +# -------------------------------------------- +m4_define([lt_dict_add_subkey], +[m4_define([$1($2:$3)], [$4])]) + + +# lt_dict_fetch(DICT, KEY, [SUBKEY]) +# ---------------------------------- +m4_define([lt_dict_fetch], +[m4_ifval([$3], + m4_ifdef([$1($2:$3)], [m4_defn([$1($2:$3)])]), + m4_ifdef([$1($2)], [m4_defn([$1($2)])]))]) + + +# lt_if_dict_fetch(DICT, KEY, [SUBKEY], VALUE, IF-TRUE, [IF-FALSE]) +# ----------------------------------------------------------------- +m4_define([lt_if_dict_fetch], +[m4_if(lt_dict_fetch([$1], [$2], [$3]), [$4], + [$5], + [$6])]) + + +# lt_dict_filter(DICT, [SUBKEY], VALUE, [SEPARATOR], KEY, [...]) +# -------------------------------------------------------------- +m4_define([lt_dict_filter], +[m4_if([$5], [], [], + [lt_join(m4_quote(m4_default([$4], [[, ]])), + lt_unquote(m4_split(m4_normalize(m4_foreach(_Lt_key, lt_car([m4_shiftn(4, $@)]), + [lt_if_dict_fetch([$1], _Lt_key, [$2], [$3], [_Lt_key ])])))))])[]dnl +]) diff --git a/contrib/openpam/m4/ltversion.m4 b/contrib/openpam/m4/ltversion.m4 new file mode 100644 index 000000000000..07a8602d48d6 --- /dev/null +++ b/contrib/openpam/m4/ltversion.m4 @@ -0,0 +1,23 @@ +# ltversion.m4 -- version numbers -*- Autoconf -*- +# +# Copyright (C) 2004 Free Software Foundation, Inc. +# Written by Scott James Remnant, 2004 +# +# This file is free software; the Free Software Foundation gives +# unlimited permission to copy and/or distribute it, with or without +# modifications, as long as this notice is preserved. + +# @configure_input@ + +# serial 3337 ltversion.m4 +# This file is part of GNU Libtool + +m4_define([LT_PACKAGE_VERSION], [2.4.2]) +m4_define([LT_PACKAGE_REVISION], [1.3337]) + +AC_DEFUN([LTVERSION_VERSION], +[macro_version='2.4.2' +macro_revision='1.3337' +_LT_DECL(, macro_version, 0, [Which release of libtool.m4 was used?]) +_LT_DECL(, macro_revision, 0) +]) diff --git a/contrib/openpam/m4/lt~obsolete.m4 b/contrib/openpam/m4/lt~obsolete.m4 new file mode 100644 index 000000000000..c573da90c5cc --- /dev/null +++ b/contrib/openpam/m4/lt~obsolete.m4 @@ -0,0 +1,98 @@ +# lt~obsolete.m4 -- aclocal satisfying obsolete definitions. -*-Autoconf-*- +# +# Copyright (C) 2004, 2005, 2007, 2009 Free Software Foundation, Inc. +# Written by Scott James Remnant, 2004. +# +# This file is free software; the Free Software Foundation gives +# unlimited permission to copy and/or distribute it, with or without +# modifications, as long as this notice is preserved. + +# serial 5 lt~obsolete.m4 + +# These exist entirely to fool aclocal when bootstrapping libtool. +# +# In the past libtool.m4 has provided macros via AC_DEFUN (or AU_DEFUN) +# which have later been changed to m4_define as they aren't part of the +# exported API, or moved to Autoconf or Automake where they belong. +# +# The trouble is, aclocal is a bit thick. It'll see the old AC_DEFUN +# in /usr/share/aclocal/libtool.m4 and remember it, then when it sees us +# using a macro with the same name in our local m4/libtool.m4 it'll +# pull the old libtool.m4 in (it doesn't see our shiny new m4_define +# and doesn't know about Autoconf macros at all.) +# +# So we provide this file, which has a silly filename so it's always +# included after everything else. This provides aclocal with the +# AC_DEFUNs it wants, but when m4 processes it, it doesn't do anything +# because those macros already exist, or will be overwritten later. +# We use AC_DEFUN over AU_DEFUN for compatibility with aclocal-1.6. +# +# Anytime we withdraw an AC_DEFUN or AU_DEFUN, remember to add it here. +# Yes, that means every name once taken will need to remain here until +# we give up compatibility with versions before 1.7, at which point +# we need to keep only those names which we still refer to. + +# This is to help aclocal find these macros, as it can't see m4_define. +AC_DEFUN([LTOBSOLETE_VERSION], [m4_if([1])]) + +m4_ifndef([AC_LIBTOOL_LINKER_OPTION], [AC_DEFUN([AC_LIBTOOL_LINKER_OPTION])]) +m4_ifndef([AC_PROG_EGREP], [AC_DEFUN([AC_PROG_EGREP])]) +m4_ifndef([_LT_AC_PROG_ECHO_BACKSLASH], [AC_DEFUN([_LT_AC_PROG_ECHO_BACKSLASH])]) +m4_ifndef([_LT_AC_SHELL_INIT], [AC_DEFUN([_LT_AC_SHELL_INIT])]) +m4_ifndef([_LT_AC_SYS_LIBPATH_AIX], [AC_DEFUN([_LT_AC_SYS_LIBPATH_AIX])]) +m4_ifndef([_LT_PROG_LTMAIN], [AC_DEFUN([_LT_PROG_LTMAIN])]) +m4_ifndef([_LT_AC_TAGVAR], [AC_DEFUN([_LT_AC_TAGVAR])]) +m4_ifndef([AC_LTDL_ENABLE_INSTALL], [AC_DEFUN([AC_LTDL_ENABLE_INSTALL])]) +m4_ifndef([AC_LTDL_PREOPEN], [AC_DEFUN([AC_LTDL_PREOPEN])]) +m4_ifndef([_LT_AC_SYS_COMPILER], [AC_DEFUN([_LT_AC_SYS_COMPILER])]) +m4_ifndef([_LT_AC_LOCK], [AC_DEFUN([_LT_AC_LOCK])]) +m4_ifndef([AC_LIBTOOL_SYS_OLD_ARCHIVE], [AC_DEFUN([AC_LIBTOOL_SYS_OLD_ARCHIVE])]) +m4_ifndef([_LT_AC_TRY_DLOPEN_SELF], [AC_DEFUN([_LT_AC_TRY_DLOPEN_SELF])]) +m4_ifndef([AC_LIBTOOL_PROG_CC_C_O], [AC_DEFUN([AC_LIBTOOL_PROG_CC_C_O])]) +m4_ifndef([AC_LIBTOOL_SYS_HARD_LINK_LOCKS], [AC_DEFUN([AC_LIBTOOL_SYS_HARD_LINK_LOCKS])]) +m4_ifndef([AC_LIBTOOL_OBJDIR], [AC_DEFUN([AC_LIBTOOL_OBJDIR])]) +m4_ifndef([AC_LTDL_OBJDIR], [AC_DEFUN([AC_LTDL_OBJDIR])]) +m4_ifndef([AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH], [AC_DEFUN([AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH])]) +m4_ifndef([AC_LIBTOOL_SYS_LIB_STRIP], [AC_DEFUN([AC_LIBTOOL_SYS_LIB_STRIP])]) +m4_ifndef([AC_PATH_MAGIC], [AC_DEFUN([AC_PATH_MAGIC])]) +m4_ifndef([AC_PROG_LD_GNU], [AC_DEFUN([AC_PROG_LD_GNU])]) +m4_ifndef([AC_PROG_LD_RELOAD_FLAG], [AC_DEFUN([AC_PROG_LD_RELOAD_FLAG])]) +m4_ifndef([AC_DEPLIBS_CHECK_METHOD], [AC_DEFUN([AC_DEPLIBS_CHECK_METHOD])]) +m4_ifndef([AC_LIBTOOL_PROG_COMPILER_NO_RTTI], [AC_DEFUN([AC_LIBTOOL_PROG_COMPILER_NO_RTTI])]) +m4_ifndef([AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE], [AC_DEFUN([AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE])]) +m4_ifndef([AC_LIBTOOL_PROG_COMPILER_PIC], [AC_DEFUN([AC_LIBTOOL_PROG_COMPILER_PIC])]) +m4_ifndef([AC_LIBTOOL_PROG_LD_SHLIBS], [AC_DEFUN([AC_LIBTOOL_PROG_LD_SHLIBS])]) +m4_ifndef([AC_LIBTOOL_POSTDEP_PREDEP], [AC_DEFUN([AC_LIBTOOL_POSTDEP_PREDEP])]) +m4_ifndef([LT_AC_PROG_EGREP], [AC_DEFUN([LT_AC_PROG_EGREP])]) +m4_ifndef([LT_AC_PROG_SED], [AC_DEFUN([LT_AC_PROG_SED])]) +m4_ifndef([_LT_CC_BASENAME], [AC_DEFUN([_LT_CC_BASENAME])]) +m4_ifndef([_LT_COMPILER_BOILERPLATE], [AC_DEFUN([_LT_COMPILER_BOILERPLATE])]) +m4_ifndef([_LT_LINKER_BOILERPLATE], [AC_DEFUN([_LT_LINKER_BOILERPLATE])]) +m4_ifndef([_AC_PROG_LIBTOOL], [AC_DEFUN([_AC_PROG_LIBTOOL])]) +m4_ifndef([AC_LIBTOOL_SETUP], [AC_DEFUN([AC_LIBTOOL_SETUP])]) +m4_ifndef([_LT_AC_CHECK_DLFCN], [AC_DEFUN([_LT_AC_CHECK_DLFCN])]) +m4_ifndef([AC_LIBTOOL_SYS_DYNAMIC_LINKER], [AC_DEFUN([AC_LIBTOOL_SYS_DYNAMIC_LINKER])]) +m4_ifndef([_LT_AC_TAGCONFIG], [AC_DEFUN([_LT_AC_TAGCONFIG])]) +m4_ifndef([AC_DISABLE_FAST_INSTALL], [AC_DEFUN([AC_DISABLE_FAST_INSTALL])]) +m4_ifndef([_LT_AC_LANG_CXX], [AC_DEFUN([_LT_AC_LANG_CXX])]) +m4_ifndef([_LT_AC_LANG_F77], [AC_DEFUN([_LT_AC_LANG_F77])]) +m4_ifndef([_LT_AC_LANG_GCJ], [AC_DEFUN([_LT_AC_LANG_GCJ])]) +m4_ifndef([AC_LIBTOOL_LANG_C_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_C_CONFIG])]) +m4_ifndef([_LT_AC_LANG_C_CONFIG], [AC_DEFUN([_LT_AC_LANG_C_CONFIG])]) +m4_ifndef([AC_LIBTOOL_LANG_CXX_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_CXX_CONFIG])]) +m4_ifndef([_LT_AC_LANG_CXX_CONFIG], [AC_DEFUN([_LT_AC_LANG_CXX_CONFIG])]) +m4_ifndef([AC_LIBTOOL_LANG_F77_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_F77_CONFIG])]) +m4_ifndef([_LT_AC_LANG_F77_CONFIG], [AC_DEFUN([_LT_AC_LANG_F77_CONFIG])]) +m4_ifndef([AC_LIBTOOL_LANG_GCJ_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_GCJ_CONFIG])]) +m4_ifndef([_LT_AC_LANG_GCJ_CONFIG], [AC_DEFUN([_LT_AC_LANG_GCJ_CONFIG])]) +m4_ifndef([AC_LIBTOOL_LANG_RC_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_RC_CONFIG])]) +m4_ifndef([_LT_AC_LANG_RC_CONFIG], [AC_DEFUN([_LT_AC_LANG_RC_CONFIG])]) +m4_ifndef([AC_LIBTOOL_CONFIG], [AC_DEFUN([AC_LIBTOOL_CONFIG])]) +m4_ifndef([_LT_AC_FILE_LTDLL_C], [AC_DEFUN([_LT_AC_FILE_LTDLL_C])]) +m4_ifndef([_LT_REQUIRED_DARWIN_CHECKS], [AC_DEFUN([_LT_REQUIRED_DARWIN_CHECKS])]) +m4_ifndef([_LT_AC_PROG_CXXCPP], [AC_DEFUN([_LT_AC_PROG_CXXCPP])]) +m4_ifndef([_LT_PREPARE_SED_QUOTE_VARS], [AC_DEFUN([_LT_PREPARE_SED_QUOTE_VARS])]) +m4_ifndef([_LT_PROG_ECHO_BACKSLASH], [AC_DEFUN([_LT_PROG_ECHO_BACKSLASH])]) +m4_ifndef([_LT_PROG_F77], [AC_DEFUN([_LT_PROG_F77])]) +m4_ifndef([_LT_PROG_FC], [AC_DEFUN([_LT_PROG_FC])]) +m4_ifndef([_LT_PROG_CXX], [AC_DEFUN([_LT_PROG_CXX])]) diff --git a/contrib/openpam/misc/gendoc.pl b/contrib/openpam/misc/gendoc.pl index 4ce2d39fad9e..c09f9076c156 100644 --- a/contrib/openpam/misc/gendoc.pl +++ b/contrib/openpam/misc/gendoc.pl @@ -33,52 +33,17 @@ # OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF # SUCH DAMAGE. # -# $Id: gendoc.pl 599 2012-04-14 15:06:41Z des $ +# $Id: gendoc.pl 736 2013-09-07 12:52:42Z des $ # use strict; -use locale; +use warnings; +use open qw(:utf8); +use utf8; use Fcntl; use Getopt::Std; -use POSIX qw(locale_h strftime); -use vars qw($COPYRIGHT %AUTHORS $TODAY %FUNCTIONS %PAMERR); - -$COPYRIGHT = ".\\\"- -.\\\" Copyright (c) 2001-2003 Networks Associates Technology, Inc. -.\\\" Copyright (c) 2004-2011 Dag-Erling Smørgrav -.\\\" All rights reserved. -.\\\" -.\\\" This software was developed for the FreeBSD Project by ThinkSec AS and -.\\\" Network Associates Laboratories, the Security Research Division of -.\\\" Network Associates, Inc. under DARPA/SPAWAR contract N66001-01-C-8035 -.\\\" (\"CBOSS\"), as part of the DARPA CHATS research program. -.\\\" -.\\\" Redistribution and use in source and binary forms, with or without -.\\\" modification, are permitted provided that the following conditions -.\\\" are met: -.\\\" 1. Redistributions of source code must retain the above copyright -.\\\" notice, this list of conditions and the following disclaimer. -.\\\" 2. Redistributions in binary form must reproduce the above copyright -.\\\" notice, this list of conditions and the following disclaimer in the -.\\\" documentation and/or other materials provided with the distribution. -.\\\" 3. The name of the author may not be used to endorse or promote -.\\\" products derived from this software without specific prior written -.\\\" permission. -.\\\" -.\\\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND -.\\\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -.\\\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -.\\\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE -.\\\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -.\\\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS -.\\\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -.\\\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -.\\\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY -.\\\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -.\\\" SUCH DAMAGE. -.\\\" -.\\\" \$" . "Id" . "\$ -.\\\""; +use POSIX qw(strftime); +use vars qw(%AUTHORS $TODAY %FUNCTIONS %PAMERR); %AUTHORS = ( THINKSEC => "developed for the @@ -87,7 +52,12 @@ Project by ThinkSec AS and Network Associates Laboratories, the Security Research Division of Network Associates, Inc.\\& under DARPA/SPAWAR contract N66001-01-C-8035 .Pq Dq CBOSS , -as part of the DARPA CHATS research program.", +as part of the DARPA CHATS research program. +.Pp +The OpenPAM library is maintained by +.An Dag-Erling Sm\\(/orgrav Aq des\@des.no .", + UIO => "developed for the University of Oslo by +.An Dag-Erling Sm\\(/orgrav Aq des\@des.no .", DES => "developed by .An Dag-Erling Sm\\(/orgrav Aq des\@des.no .", ); @@ -142,6 +112,7 @@ sub parse_source($) { my $customrv; my $deprecated; my $experimental; + my $version; my %xref; my @errors; my $author; @@ -159,6 +130,10 @@ sub parse_source($) { return undef if ($source =~ m/^ \* NOPARSE\s*$/m); + if ($source =~ m/(\$Id:[^\$]+\$)/) { + $version = $1; + } + $author = 'THINKSEC'; if ($source =~ s/^ \* AUTHOR\s+(\w*)\s*$//m) { $author = $1; @@ -196,7 +171,7 @@ sub parse_source($) { next unless (m/^ \*\s+(!?PAM_[A-Z_]+|=[a-z_]+)\s*$/); push(@errors, $1); } - ++$xref{3}->{'pam_strerror'}; + ++$xref{3}->{pam_strerror}; } $argnames = $args; @@ -290,7 +265,7 @@ sub parse_source($) { $man .= ".Bl -tag -width 18n\n"; $intaglist = 1; } - s/^\.It =([A-Z][A-Z_]+)$/.It Dv $1/gs; + s/^\.It [=;]([A-Za-z][0-9A-Za-z_]+)$/.It Dv $1/gs; $man .= "$_\n"; next; } elsif (($inlist || $intaglist) && m/^\S/) { @@ -318,16 +293,16 @@ sub parse_source($) { s/\s*=($func)\b\s*/\n.Fn $1\n/gs; s/\s*=($argnames)\b\s*/\n.Fa $1\n/gs; s/\s*=(struct \w+(?: \*)?)\b\s*/\n.Vt $1\n/gs; - s/\s*:([a-z_]+)\b\s*/\n.Va $1\n/gs; - s/\s*;([a-z_]+)\b\s*/\n.Dv $1\n/gs; - s/\s*=!([a-z_]+)\b\s*/\n.Xr $1 3\n/gs; - while (s/\s*=([a-z_]+)\b\s*/\n.Xr $1 3\n/s) { + s/\s*:([a-z][0-9a-z_]+)\b\s*/\n.Va $1\n/gs; + s/\s*;([a-z][0-9a-z_]+)\b\s*/\n.Dv $1\n/gs; + s/\s*=!([a-z][0-9a-z_]+)\b\s*/\n.Xr $1 3\n/gs; + while (s/\s*=([a-z][0-9a-z_]+)\b\s*/\n.Xr $1 3\n/s) { ++$xref{3}->{$1}; } s/\s*\"(?=\w)/\n.Do\n/gs; s/\"(?!\w)\s*/\n.Dc\n/gs; - s/\s*=([A-Z][A-Z_]+)\b\s*(?![\.,:;])/\n.Dv $1\n/gs; - s/\s*=([A-Z][A-Z_]+)\b([\.,:;]+)\s*/\n.Dv $1 $2\n/gs; + s/\s*=([A-Z][0-9A-Z_]+)\b\s*(?![\.,:;])/\n.Dv $1\n/gs; + s/\s*=([A-Z][0-9A-Z_]+)\b([\.,:;]+)\s*/\n.Dv $1 $2\n/gs; s/\s*{([A-Z][a-z] .*?)}\s*/\n.$1\n/gs; $man .= "$_\n"; } @@ -353,6 +328,7 @@ sub parse_source($) { $FUNCTIONS{$func} = { 'source' => $fn, + 'version' => $version, 'name' => $func, 'descr' => $descr, 'type' => $type, @@ -366,10 +342,10 @@ sub parse_source($) { 'experimental' => $experimental, }; if ($source =~ m/^ \* NODOC\s*$/m) { - $FUNCTIONS{$func}->{'nodoc'} = 1; + $FUNCTIONS{$func}->{nodoc} = 1; } if ($source !~ m/^ \* XSSO \d/m) { - $FUNCTIONS{$func}->{'openpam'} = 1; + $FUNCTIONS{$func}->{openpam} = 1; } expand_errors($FUNCTIONS{$func}); return $FUNCTIONS{$func}; @@ -383,16 +359,16 @@ sub expand_errors($) { my $ref; my $fn; - if (defined($func->{'recursed'})) { - warn("$func->{'name'}(): loop in error spec\n"); + if (defined($$func{recursed})) { + warn("$$func{name}(): loop in error spec\n"); return qw(); } - $func->{'recursed'} = 1; + $$func{recursed} = 1; - foreach (@{$func->{'errors'}}) { + foreach (@{$$func{errors}}) { if (m/^(PAM_[A-Z_]+)$/) { if (!defined($PAMERR{$1})) { - warn("$func->{'name'}(): unrecognized error: $1\n"); + warn("$$func{name}(): unrecognized error: $1\n"); next; } $errors{$1} = 1; @@ -401,28 +377,28 @@ sub expand_errors($) { } elsif (m/^=([a-z_]+)$/) { $ref = $1; if (!defined($FUNCTIONS{$ref})) { - $fn = $func->{'source'}; - $fn =~ s/$func->{'name'}/$ref/; + $fn = $$func{source}; + $fn =~ s/$$func{name}/$ref/; parse_source($fn); } if (!defined($FUNCTIONS{$ref})) { - warn("$func->{'name'}(): reference to unknown $ref()\n"); + warn("$$func{name}(): reference to unknown $ref()\n"); next; } - foreach (@{$FUNCTIONS{$ref}->{'errors'}}) { + foreach (@{$FUNCTIONS{$ref}->{errors}}) { $errors{$_} = 1; } } else { - warn("$func->{'name'}(): invalid error specification: $_\n"); + warn("$$func{name}(): invalid error specification: $_\n"); } } - foreach (@{$func->{'errors'}}) { + foreach (@{$$func{errors}}) { if (m/^!(PAM_[A-Z_]+)$/) { delete($errors{$1}); } } - delete($func->{'recursed'}); - $func->{'errors'} = [ sort(keys(%errors)) ]; + delete($$func{recursed}); + $$func{errors} = [ sort(keys(%errors)) ]; } sub dictionary_order($$) { @@ -457,59 +433,63 @@ sub gendoc($) { my $mdoc; my $fn; - return if defined($func->{'nodoc'}); + return if defined($$func{nodoc}); - $mdoc = "$COPYRIGHT -.Dd $TODAY -.Dt " . uc($func->{'name'}) . " 3 + $$func{source} =~ m/([^\/]+)$/; + $mdoc = ".\\\" Generated from $1 by gendoc.pl\n"; + if ($$func{version}) { + $mdoc .= ".\\\" $$func{version}\n"; + } + $mdoc .= ".Dd $TODAY +.Dt " . uc($$func{name}) . " 3 .Os .Sh NAME -.Nm $func->{'name'} -.Nd $func->{'descr'} +.Nm $$func{name} +.Nd $$func{descr} .Sh LIBRARY .Lb libpam .Sh SYNOPSIS .In sys/types.h "; - if ($func->{'args'} =~ m/\bFILE \*\b/) { + if ($$func{args} =~ m/\bFILE \*\b/) { $mdoc .= ".In stdio.h\n"; } $mdoc .= ".In security/pam_appl.h "; - if ($func->{'name'} =~ m/_sm_/) { + if ($$func{name} =~ m/_sm_/) { $mdoc .= ".In security/pam_modules.h\n"; } - if ($func->{'name'} =~ m/openpam/) { + if ($$func{name} =~ m/openpam/) { $mdoc .= ".In security/openpam.h\n"; } - $mdoc .= ".Ft \"$func->{'type'}\" -.Fn $func->{'name'} $func->{'args'} + $mdoc .= ".Ft \"$$func{type}\" +.Fn $$func{name} $$func{args} .Sh DESCRIPTION "; - if (defined($func->{'deprecated'})) { + if (defined($$func{deprecated})) { $mdoc .= ".Bf Sy\n" . "This function is deprecated and may be removed " . "in a future release without further warning.\n"; - if ($func->{'deprecated'}) { - $mdoc .= "The\n.Fn $func->{'deprecated'}\nfunction " . + if ($$func{deprecated}) { + $mdoc .= "The\n.Fn $$func{deprecated}\nfunction " . "may be used to achieve similar results.\n"; } $mdoc .= ".Ef\n.Pp\n"; } - if ($func->{'experimental'}) { + if ($$func{experimental}) { $mdoc .= ".Bf Sy\n" . "This function is experimental and may be modified or removed " . - "in a future release without further warning.\n"; + "in a future release without prior warning.\n"; $mdoc .= ".Ef\n.Pp\n"; } - $mdoc .= "$func->{'man'}\n"; - my @errors = @{$func->{'errors'}}; - if ($func->{'customrv'}) { + $mdoc .= "$$func{man}\n"; + my @errors = @{$$func{errors}}; + if ($$func{customrv}) { # leave it - } elsif ($func->{'type'} eq "int" && @errors) { + } elsif ($$func{type} eq "int" && @errors) { $mdoc .= ".Sh RETURN VALUES The -.Fn $func->{'name'} +.Fn $$func{name} function returns one of the following values: .Bl -tag -width 18n "; @@ -517,28 +497,28 @@ function returns one of the following values: $mdoc .= ".It Bq Er $_\n$PAMERR{$_}.\n"; } $mdoc .= ".El\n"; - } elsif ($func->{'type'} eq "int") { + } elsif ($$func{type} eq "int") { $mdoc .= ".Sh RETURN VALUES The -.Fn $func->{'name'} +.Fn $$func{name} function returns 0 on success and -1 on failure. "; - } elsif ($func->{'type'} =~ m/\*$/) { + } elsif ($$func{type} =~ m/\*$/) { $mdoc .= ".Sh RETURN VALUES The -.Fn $func->{'name'} +.Fn $$func{name} function returns .Dv NULL on failure. "; - } elsif ($func->{'type'} ne "void") { - warn("$func->{'name'}(): no error specification\n"); + } elsif ($$func{type} ne "void") { + warn("$$func{name}(): no error specification\n"); } - $mdoc .= ".Sh SEE ALSO\n" . genxref($func->{'xref'}); + $mdoc .= ".Sh SEE ALSO\n" . genxref($$func{xref}); $mdoc .= ".Sh STANDARDS\n"; - if ($func->{'openpam'}) { + if ($$func{openpam}) { $mdoc .= "The -.Fn $func->{'name'} +.Fn $$func{name} function is an OpenPAM extension. "; } else { @@ -550,10 +530,10 @@ function is an OpenPAM extension. } $mdoc .= ".Sh AUTHORS The -.Fn $func->{'name'} +.Fn $$func{name} function and this manual page were\n"; - $mdoc .= $AUTHORS{$func->{'author'} // 'THINKSEC_DARPA'} . "\n"; - $fn = "$func->{'name'}.3"; + $mdoc .= $AUTHORS{$$func{author} // 'THINKSEC_DARPA'} . "\n"; + $fn = "$$func{name}.3"; if (open(FILE, ">", $fn)) { print(FILE $mdoc); close(FILE); @@ -572,16 +552,16 @@ sub readproto($) { or die("$fn: open(): $!\n"); while () { if (m/^\.Nm ((?:open)?pam_.*?)\s*$/) { - $func{'Nm'} = $func{'Nm'} || $1; + $func{Nm} = $func{Nm} || $1; } elsif (m/^\.Ft (\S.*?)\s*$/) { - $func{'Ft'} = $func{'Ft'} || $1; + $func{Ft} = $func{Ft} || $1; } elsif (m/^\.Fn (\S.*?)\s*$/) { - $func{'Fn'} = $func{'Fn'} || $1; + $func{Fn} = $func{Fn} || $1; } } close(FILE); - if ($func{'Nm'}) { - $FUNCTIONS{$func{'Nm'}} = \%func; + if ($func{Nm}) { + $FUNCTIONS{$func{Nm}} = \%func; } else { warn("No function found\n"); } @@ -600,7 +580,7 @@ sub gensummary($) { $page =~ m/(\w+)$/; $upage = uc($1); - print FILE "$COPYRIGHT + print FILE ".\\\" Generated by gendoc.pl .Dd $TODAY .Dt $upage 3 .Os @@ -608,7 +588,7 @@ sub gensummary($) { "; my @funcs = sort(keys(%FUNCTIONS)); while ($func = shift(@funcs)) { - print FILE ".Nm $FUNCTIONS{$func}->{'Nm'}"; + print FILE ".Nm $FUNCTIONS{$func}->{Nm}"; print FILE " ," if (@funcs); print FILE "\n"; @@ -623,8 +603,8 @@ sub gensummary($) { print FILE ".In security/openpam.h\n"; } foreach $func (sort(keys(%FUNCTIONS))) { - print FILE ".Ft $FUNCTIONS{$func}->{'Ft'}\n"; - print FILE ".Fn $FUNCTIONS{$func}->{'Fn'}\n"; + print FILE ".Ft $FUNCTIONS{$func}->{Ft}\n"; + print FILE ".Fn $FUNCTIONS{$func}->{Fn}\n"; } while () { if (m/^\.Xr (\S+)\s*(\d)\s*$/) { @@ -647,7 +627,7 @@ The following return codes are defined by print FILE ".Sh SEE ALSO "; if ($page eq 'pam') { - ++$xref{3}->{'openpam'}; + ++$xref{3}->{openpam}; } foreach $func (keys(%FUNCTIONS)) { ++$xref{3}->{$func}; @@ -684,17 +664,16 @@ MAIN:{ usage() unless (@ARGV && getopts("op", \%opts)); - setlocale(LC_ALL, "en_US.UTF-8"); $TODAY = strftime("%B %e, %Y", localtime(time())); $TODAY =~ s,\s+, ,g; - if ($opts{'o'} || $opts{'p'}) { + if ($opts{o} || $opts{p}) { foreach my $fn (@ARGV) { readproto($fn); } gensummary('openpam') - if ($opts{'o'}); + if ($opts{o}); gensummary('pam') - if ($opts{'p'}); + if ($opts{p}); } else { foreach my $fn (@ARGV) { my $func = parse_source($fn); diff --git a/contrib/openpam/missing b/contrib/openpam/missing index 28055d2ae6f2..cdea514931f5 100644 --- a/contrib/openpam/missing +++ b/contrib/openpam/missing @@ -1,11 +1,10 @@ #! /bin/sh -# Common stub for a few missing GNU programs while installing. +# Common wrapper for a few potentially missing GNU programs. -scriptversion=2009-04-28.21; # UTC +scriptversion=2012-06-26.16; # UTC -# Copyright (C) 1996, 1997, 1999, 2000, 2002, 2003, 2004, 2005, 2006, -# 2008, 2009 Free Software Foundation, Inc. -# Originally by Fran,cois Pinard , 1996. +# Copyright (C) 1996-2013 Free Software Foundation, Inc. +# Originally written by Fran,cois Pinard , 1996. # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by @@ -26,69 +25,40 @@ scriptversion=2009-04-28.21; # UTC # the same distribution terms that you use for the rest of that program. if test $# -eq 0; then - echo 1>&2 "Try \`$0 --help' for more information" + echo 1>&2 "Try '$0 --help' for more information" exit 1 fi -run=: -sed_output='s/.* --output[ =]\([^ ]*\).*/\1/p' -sed_minuso='s/.* -o \([^ ]*\).*/\1/p' - -# In the cases where this matters, `missing' is being run in the -# srcdir already. -if test -f configure.ac; then - configure_ac=configure.ac -else - configure_ac=configure.in -fi - -msg="missing on your system" - case $1 in ---run) - # Try to run requested program, and just exit if it succeeds. - run= - shift - "$@" && exit 0 - # Exit code 63 means version mismatch. This often happens - # when the user try to use an ancient version of a tool on - # a file that requires a minimum version. In this case we - # we should proceed has if the program had been absent, or - # if --run hadn't been passed. - if test $? = 63; then - run=: - msg="probably too old" - fi - ;; + + --is-lightweight) + # Used by our autoconf macros to check whether the available missing + # script is modern enough. + exit 0 + ;; + + --run) + # Back-compat with the calling convention used by older automake. + shift + ;; -h|--h|--he|--hel|--help) echo "\ $0 [OPTION]... PROGRAM [ARGUMENT]... -Handle \`PROGRAM [ARGUMENT]...' for when PROGRAM is missing, or return an -error status if there is no known handling for PROGRAM. +Run 'PROGRAM [ARGUMENT]...', returning a proper advice when this fails due +to PROGRAM being missing or too old. Options: -h, --help display this help and exit -v, --version output version information and exit - --run try to run the given command, and emulate it if it fails Supported PROGRAM values: - aclocal touch file \`aclocal.m4' - autoconf touch file \`configure' - autoheader touch file \`config.h.in' - autom4te touch the output file, or create a stub one - automake touch all \`Makefile.in' files - bison create \`y.tab.[ch]', if possible, from existing .[ch] - flex create \`lex.yy.c', if possible, from existing .c - help2man touch the output file - lex create \`lex.yy.c', if possible, from existing .c - makeinfo touch the output file - tar try tar, gnutar, gtar, then tar without non-portable flags - yacc create \`y.tab.[ch]', if possible, from existing .[ch] + aclocal autoconf autoheader autom4te automake makeinfo + bison yacc flex lex help2man -Version suffixes to PROGRAM as well as the prefixes \`gnu-', \`gnu', and -\`g' are ignored when checking the name. +Version suffixes to PROGRAM as well as the prefixes 'gnu-', 'gnu', and +'g' are ignored when checking the name. Send bug reports to ." exit $? @@ -100,272 +70,141 @@ Send bug reports to ." ;; -*) - echo 1>&2 "$0: Unknown \`$1' option" - echo 1>&2 "Try \`$0 --help' for more information" + echo 1>&2 "$0: unknown '$1' option" + echo 1>&2 "Try '$0 --help' for more information" exit 1 ;; esac -# normalize program name to check for. -program=`echo "$1" | sed ' - s/^gnu-//; t - s/^gnu//; t - s/^g//; t'` +# Run the given program, remember its exit status. +"$@"; st=$? -# Now exit if we have it, but it failed. Also exit now if we -# don't have it and --version was passed (most likely to detect -# the program). This is about non-GNU programs, so use $1 not -# $program. -case $1 in - lex*|yacc*) - # Not GNU programs, they don't have --version. +# If it succeeded, we are done. +test $st -eq 0 && exit 0 + +# Also exit now if we it failed (or wasn't found), and '--version' was +# passed; such an option is passed most likely to detect whether the +# program is present and works. +case $2 in --version|--help) exit $st;; esac + +# Exit code 63 means version mismatch. This often happens when the user +# tries to use an ancient version of a tool on a file that requires a +# minimum version. +if test $st -eq 63; then + msg="probably too old" +elif test $st -eq 127; then + # Program was missing. + msg="missing on your system" +else + # Program was found and executed, but failed. Give up. + exit $st +fi + +perl_URL=http://www.perl.org/ +flex_URL=http://flex.sourceforge.net/ +gnu_software_URL=http://www.gnu.org/software + +program_details () +{ + case $1 in + aclocal|automake) + echo "The '$1' program is part of the GNU Automake package:" + echo "<$gnu_software_URL/automake>" + echo "It also requires GNU Autoconf, GNU m4 and Perl in order to run:" + echo "<$gnu_software_URL/autoconf>" + echo "<$gnu_software_URL/m4/>" + echo "<$perl_URL>" + ;; + autoconf|autom4te|autoheader) + echo "The '$1' program is part of the GNU Autoconf package:" + echo "<$gnu_software_URL/autoconf/>" + echo "It also requires GNU m4 and Perl in order to run:" + echo "<$gnu_software_URL/m4/>" + echo "<$perl_URL>" + ;; + esac +} + +give_advice () +{ + # Normalize program name to check for. + normalized_program=`echo "$1" | sed ' + s/^gnu-//; t + s/^gnu//; t + s/^g//; t'` + + printf '%s\n' "'$1' is $msg." + + configure_deps="'configure.ac' or m4 files included by 'configure.ac'" + case $normalized_program in + autoconf*) + echo "You should only need it if you modified 'configure.ac'," + echo "or m4 files included by it." + program_details 'autoconf' + ;; + autoheader*) + echo "You should only need it if you modified 'acconfig.h' or" + echo "$configure_deps." + program_details 'autoheader' + ;; + automake*) + echo "You should only need it if you modified 'Makefile.am' or" + echo "$configure_deps." + program_details 'automake' + ;; + aclocal*) + echo "You should only need it if you modified 'acinclude.m4' or" + echo "$configure_deps." + program_details 'aclocal' + ;; + autom4te*) + echo "You might have modified some maintainer files that require" + echo "the 'automa4te' program to be rebuilt." + program_details 'autom4te' + ;; + bison*|yacc*) + echo "You should only need it if you modified a '.y' file." + echo "You may want to install the GNU Bison package:" + echo "<$gnu_software_URL/bison/>" + ;; + lex*|flex*) + echo "You should only need it if you modified a '.l' file." + echo "You may want to install the Fast Lexical Analyzer package:" + echo "<$flex_URL>" + ;; + help2man*) + echo "You should only need it if you modified a dependency" \ + "of a man page." + echo "You may want to install the GNU Help2man package:" + echo "<$gnu_software_URL/help2man/>" ;; + makeinfo*) + echo "You should only need it if you modified a '.texi' file, or" + echo "any other file indirectly affecting the aspect of the manual." + echo "You might want to install the Texinfo package:" + echo "<$gnu_software_URL/texinfo/>" + echo "The spurious makeinfo call might also be the consequence of" + echo "using a buggy 'make' (AIX, DU, IRIX), in which case you might" + echo "want to install GNU make:" + echo "<$gnu_software_URL/make/>" + ;; + *) + echo "You might have modified some files without having the proper" + echo "tools for further handling them. Check the 'README' file, it" + echo "often tells you about the needed prerequisites for installing" + echo "this package. You may also peek at any GNU archive site, in" + echo "case some other package contains this missing '$1' program." + ;; + esac +} - tar*) - if test -n "$run"; then - echo 1>&2 "ERROR: \`tar' requires --run" - exit 1 - elif test "x$2" = "x--version" || test "x$2" = "x--help"; then - exit 1 - fi - ;; +give_advice "$1" | sed -e '1s/^/WARNING: /' \ + -e '2,$s/^/ /' >&2 - *) - if test -z "$run" && ($1 --version) > /dev/null 2>&1; then - # We have it, but it failed. - exit 1 - elif test "x$2" = "x--version" || test "x$2" = "x--help"; then - # Could not run --version or --help. This is probably someone - # running `$TOOL --version' or `$TOOL --help' to check whether - # $TOOL exists and not knowing $TOOL uses missing. - exit 1 - fi - ;; -esac - -# If it does not exist, or fails to run (possibly an outdated version), -# try to emulate it. -case $program in - aclocal*) - echo 1>&2 "\ -WARNING: \`$1' is $msg. You should only need it if - you modified \`acinclude.m4' or \`${configure_ac}'. You might want - to install the \`Automake' and \`Perl' packages. Grab them from - any GNU archive site." - touch aclocal.m4 - ;; - - autoconf*) - echo 1>&2 "\ -WARNING: \`$1' is $msg. You should only need it if - you modified \`${configure_ac}'. You might want to install the - \`Autoconf' and \`GNU m4' packages. Grab them from any GNU - archive site." - touch configure - ;; - - autoheader*) - echo 1>&2 "\ -WARNING: \`$1' is $msg. You should only need it if - you modified \`acconfig.h' or \`${configure_ac}'. You might want - to install the \`Autoconf' and \`GNU m4' packages. Grab them - from any GNU archive site." - files=`sed -n 's/^[ ]*A[CM]_CONFIG_HEADER(\([^)]*\)).*/\1/p' ${configure_ac}` - test -z "$files" && files="config.h" - touch_files= - for f in $files; do - case $f in - *:*) touch_files="$touch_files "`echo "$f" | - sed -e 's/^[^:]*://' -e 's/:.*//'`;; - *) touch_files="$touch_files $f.in";; - esac - done - touch $touch_files - ;; - - automake*) - echo 1>&2 "\ -WARNING: \`$1' is $msg. You should only need it if - you modified \`Makefile.am', \`acinclude.m4' or \`${configure_ac}'. - You might want to install the \`Automake' and \`Perl' packages. - Grab them from any GNU archive site." - find . -type f -name Makefile.am -print | - sed 's/\.am$/.in/' | - while read f; do touch "$f"; done - ;; - - autom4te*) - echo 1>&2 "\ -WARNING: \`$1' is needed, but is $msg. - You might have modified some files without having the - proper tools for further handling them. - You can get \`$1' as part of \`Autoconf' from any GNU - archive site." - - file=`echo "$*" | sed -n "$sed_output"` - test -z "$file" && file=`echo "$*" | sed -n "$sed_minuso"` - if test -f "$file"; then - touch $file - else - test -z "$file" || exec >$file - echo "#! /bin/sh" - echo "# Created by GNU Automake missing as a replacement of" - echo "# $ $@" - echo "exit 0" - chmod +x $file - exit 1 - fi - ;; - - bison*|yacc*) - echo 1>&2 "\ -WARNING: \`$1' $msg. You should only need it if - you modified a \`.y' file. You may need the \`Bison' package - in order for those modifications to take effect. You can get - \`Bison' from any GNU archive site." - rm -f y.tab.c y.tab.h - if test $# -ne 1; then - eval LASTARG="\${$#}" - case $LASTARG in - *.y) - SRCFILE=`echo "$LASTARG" | sed 's/y$/c/'` - if test -f "$SRCFILE"; then - cp "$SRCFILE" y.tab.c - fi - SRCFILE=`echo "$LASTARG" | sed 's/y$/h/'` - if test -f "$SRCFILE"; then - cp "$SRCFILE" y.tab.h - fi - ;; - esac - fi - if test ! -f y.tab.h; then - echo >y.tab.h - fi - if test ! -f y.tab.c; then - echo 'main() { return 0; }' >y.tab.c - fi - ;; - - lex*|flex*) - echo 1>&2 "\ -WARNING: \`$1' is $msg. You should only need it if - you modified a \`.l' file. You may need the \`Flex' package - in order for those modifications to take effect. You can get - \`Flex' from any GNU archive site." - rm -f lex.yy.c - if test $# -ne 1; then - eval LASTARG="\${$#}" - case $LASTARG in - *.l) - SRCFILE=`echo "$LASTARG" | sed 's/l$/c/'` - if test -f "$SRCFILE"; then - cp "$SRCFILE" lex.yy.c - fi - ;; - esac - fi - if test ! -f lex.yy.c; then - echo 'main() { return 0; }' >lex.yy.c - fi - ;; - - help2man*) - echo 1>&2 "\ -WARNING: \`$1' is $msg. You should only need it if - you modified a dependency of a manual page. You may need the - \`Help2man' package in order for those modifications to take - effect. You can get \`Help2man' from any GNU archive site." - - file=`echo "$*" | sed -n "$sed_output"` - test -z "$file" && file=`echo "$*" | sed -n "$sed_minuso"` - if test -f "$file"; then - touch $file - else - test -z "$file" || exec >$file - echo ".ab help2man is required to generate this page" - exit $? - fi - ;; - - makeinfo*) - echo 1>&2 "\ -WARNING: \`$1' is $msg. You should only need it if - you modified a \`.texi' or \`.texinfo' file, or any other file - indirectly affecting the aspect of the manual. The spurious - call might also be the consequence of using a buggy \`make' (AIX, - DU, IRIX). You might want to install the \`Texinfo' package or - the \`GNU make' package. Grab either from any GNU archive site." - # The file to touch is that specified with -o ... - file=`echo "$*" | sed -n "$sed_output"` - test -z "$file" && file=`echo "$*" | sed -n "$sed_minuso"` - if test -z "$file"; then - # ... or it is the one specified with @setfilename ... - infile=`echo "$*" | sed 's/.* \([^ ]*\) *$/\1/'` - file=`sed -n ' - /^@setfilename/{ - s/.* \([^ ]*\) *$/\1/ - p - q - }' $infile` - # ... or it is derived from the source name (dir/f.texi becomes f.info) - test -z "$file" && file=`echo "$infile" | sed 's,.*/,,;s,.[^.]*$,,'`.info - fi - # If the file does not exist, the user really needs makeinfo; - # let's fail without touching anything. - test -f $file || exit 1 - touch $file - ;; - - tar*) - shift - - # We have already tried tar in the generic part. - # Look for gnutar/gtar before invocation to avoid ugly error - # messages. - if (gnutar --version > /dev/null 2>&1); then - gnutar "$@" && exit 0 - fi - if (gtar --version > /dev/null 2>&1); then - gtar "$@" && exit 0 - fi - firstarg="$1" - if shift; then - case $firstarg in - *o*) - firstarg=`echo "$firstarg" | sed s/o//` - tar "$firstarg" "$@" && exit 0 - ;; - esac - case $firstarg in - *h*) - firstarg=`echo "$firstarg" | sed s/h//` - tar "$firstarg" "$@" && exit 0 - ;; - esac - fi - - echo 1>&2 "\ -WARNING: I can't seem to be able to run \`tar' with the given arguments. - You may want to install GNU tar or Free paxutils, or check the - command line arguments." - exit 1 - ;; - - *) - echo 1>&2 "\ -WARNING: \`$1' is needed, and is $msg. - You might have modified some files without having the - proper tools for further handling them. Check the \`README' file, - it often tells you about the needed prerequisites for installing - this package. You may also peek at any GNU archive site, in case - some other package would contain this missing \`$1' program." - exit 1 - ;; -esac - -exit 0 +# Propagate the correct exit status (expected to be 127 for a program +# not found, 63 for a program that failed due to version mismatch). +exit $st # Local variables: # eval: (add-hook 'write-file-hooks 'time-stamp) diff --git a/contrib/openpam/mkpkgng.in b/contrib/openpam/mkpkgng.in new file mode 100644 index 000000000000..31efc84a6026 --- /dev/null +++ b/contrib/openpam/mkpkgng.in @@ -0,0 +1,166 @@ +#!/bin/sh +#- +# Copyright (c) 2013 Dag-Erling Smørgrav +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# 3. The name of the author may not be used to endorse or promote +# products derived from this software without specific prior written +# permission. +# +# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND +# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE +# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +# SUCH DAMAGE. +# +# $Id: mkpkgng.in 740 2013-09-07 13:03:20Z des $ +# + +# Print an informational message +info() { + echo "mkpkgng: $@" +} + +# Print an error message and exit +error() { + echo "mkpkgng: $@" 1>&2 + exit 1 +} + +# Ask a yes / no question +yesno() { + while :; do + echo -n "mkpkgng: $@ (yes/no) " + read answer + case $answer in + [Yy]|[Yy][Ee][Ss]) + return 0 + ;; + [Nn]|[Nn][Oo]) + return 1 + ;; + esac + done +} + +# +# Locate source and build directory +# +srcdir="@abs_top_srcdir@" +[ -f "$srcdir/include/security/openpam.h" ] || \ + error "Unable to locate source directory." +builddir="@abs_top_builddir@" +cd "$srcdir" + +# +# Determine pkgng version and ABI +# +pkgver=$(pkg -vv | awk '$1 == "Version:" { print $2 }') +[ -n "$pkgver" ] || error "Unable to determine pkgng version." +pkgabi=$(pkg -vv | awk '$1 == "ABI:" { print $2 }') +[ -n "$pkgabi" ] || error "Unable to determine package ABI." + +# +# Determine package name and version +# +package="@PACKAGE@" +version="@PACKAGE_VERSION@" +if ! expr "$version" : "[0-9]{1,}$" >/dev/null ; then + svnversion="$(svnversion 2>&1)" + svnversion=$(expr "$svnversion" : '\([0-9][0-9]*\)[A-Z]\{0,1\}$') + if [ -n "$svnversion" ] ; then + version="$version-r${svnversion}" + fi +fi + +# +# Locate GNU make +# +if which gmake >/dev/null ; then + make=gmake +else + make=make +fi +make="$make --no-print-directory --quiet V=0" + +# +# Create temporary directory +# +info "Creating the temporary directory." +tmproot=$(mktemp -d "${TMPDIR:-/tmp}/$package-$version.XXXXXX") +[ -n "$tmproot" -a -d "$tmproot" ] || \ + error "Unable to create the temporary directory." +trap "exit 1" INT +trap "info Deleting the temporary directory. ; rm -rf '$tmproot'" EXIT +set -e + +# +# Install into tmproot +# +info "Installing into the temporary directory." +$make install DESTDIR="$tmproot" + +# +# Generate stub manifest +# +info "Generating the stub manifest." +manifest="$tmproot/+MANIFEST" +cat >"$manifest" <>"$manifest" + +# +# Create the package +# +info "Creating the package." +pkg create -r "$tmproot" -m "$tmproot" -o "$builddir" + +# +# Done +# +info "Package created for $package-$version." diff --git a/contrib/openpam/modules/Makefile.am b/contrib/openpam/modules/Makefile.am index 2743a10aef13..d534b9f6cd96 100644 --- a/contrib/openpam/modules/Makefile.am +++ b/contrib/openpam/modules/Makefile.am @@ -1,3 +1,7 @@ -# $Id: Makefile.am 320 2006-02-16 20:33:19Z des $ +# $Id: Makefile.am 714 2013-08-19 15:30:21Z des $ -SUBDIRS = pam_unix pam_deny pam_permit +SUBDIRS = pam_deny pam_permit + +if WITH_PAM_UNIX +SUBDIRS += pam_unix +endif diff --git a/contrib/openpam/modules/Makefile.in b/contrib/openpam/modules/Makefile.in index ca117d00a2c4..2b88ac696bf2 100644 --- a/contrib/openpam/modules/Makefile.in +++ b/contrib/openpam/modules/Makefile.in @@ -1,9 +1,8 @@ -# Makefile.in generated by automake 1.11.1 from Makefile.am. +# Makefile.in generated by automake 1.14 from Makefile.am. # @configure_input@ -# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, -# 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation, -# Inc. +# Copyright (C) 1994-2013 Free Software Foundation, Inc. + # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. @@ -15,8 +14,53 @@ @SET_MAKE@ -# $Id: Makefile.am 320 2006-02-16 20:33:19Z des $ +# $Id: Makefile.am 714 2013-08-19 15:30:21Z des $ VPATH = @srcdir@ +am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)' +am__make_running_with_option = \ + case $${target_option-} in \ + ?) ;; \ + *) echo "am__make_running_with_option: internal error: invalid" \ + "target option '$${target_option-}' specified" >&2; \ + exit 1;; \ + esac; \ + has_opt=no; \ + sane_makeflags=$$MAKEFLAGS; \ + if $(am__is_gnu_make); then \ + sane_makeflags=$$MFLAGS; \ + else \ + case $$MAKEFLAGS in \ + *\\[\ \ ]*) \ + bs=\\; \ + sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ + | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ + esac; \ + fi; \ + skip_next=no; \ + strip_trailopt () \ + { \ + flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ + }; \ + for flg in $$sane_makeflags; do \ + test $$skip_next = yes && { skip_next=no; continue; }; \ + case $$flg in \ + *=*|--*) continue;; \ + -*I) strip_trailopt 'I'; skip_next=yes;; \ + -*I?*) strip_trailopt 'I';; \ + -*O) strip_trailopt 'O'; skip_next=yes;; \ + -*O?*) strip_trailopt 'O';; \ + -*l) strip_trailopt 'l'; skip_next=yes;; \ + -*l?*) strip_trailopt 'l';; \ + -[dEDm]) skip_next=yes;; \ + -[JT]) skip_next=yes;; \ + esac; \ + case $$flg in \ + *$$target_option*) has_opt=yes; break;; \ + esac; \ + done; \ + test $$has_opt = yes +am__make_dryrun = (target_option=n; $(am__make_running_with_option)) +am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ @@ -35,33 +79,75 @@ PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ +@WITH_PAM_UNIX_TRUE@am__append_1 = pam_unix subdir = modules -DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in +DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 -am__aclocal_m4_deps = $(top_srcdir)/configure.ac +am__aclocal_m4_deps = $(top_srcdir)/m4/libtool.m4 \ + $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \ + $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \ + $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = +AM_V_P = $(am__v_P_@AM_V@) +am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) +am__v_P_0 = false +am__v_P_1 = : +AM_V_GEN = $(am__v_GEN_@AM_V@) +am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) +am__v_GEN_0 = @echo " GEN " $@; +am__v_GEN_1 = +AM_V_at = $(am__v_at_@AM_V@) +am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) +am__v_at_0 = @ +am__v_at_1 = SOURCES = DIST_SOURCES = -RECURSIVE_TARGETS = all-recursive check-recursive dvi-recursive \ - html-recursive info-recursive install-data-recursive \ - install-dvi-recursive install-exec-recursive \ - install-html-recursive install-info-recursive \ - install-pdf-recursive install-ps-recursive install-recursive \ - installcheck-recursive installdirs-recursive pdf-recursive \ - ps-recursive uninstall-recursive +RECURSIVE_TARGETS = all-recursive check-recursive cscopelist-recursive \ + ctags-recursive dvi-recursive html-recursive info-recursive \ + install-data-recursive install-dvi-recursive \ + install-exec-recursive install-html-recursive \ + install-info-recursive install-pdf-recursive \ + install-ps-recursive install-recursive installcheck-recursive \ + installdirs-recursive pdf-recursive ps-recursive \ + tags-recursive uninstall-recursive +am__can_run_installinfo = \ + case $$AM_UPDATE_INFO_DIR in \ + n|no|NO) false;; \ + *) (install-info --version) >/dev/null 2>&1;; \ + esac RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \ distclean-recursive maintainer-clean-recursive -AM_RECURSIVE_TARGETS = $(RECURSIVE_TARGETS:-recursive=) \ - $(RECURSIVE_CLEAN_TARGETS:-recursive=) tags TAGS ctags CTAGS \ +am__recursive_targets = \ + $(RECURSIVE_TARGETS) \ + $(RECURSIVE_CLEAN_TARGETS) \ + $(am__extra_recursive_targets) +AM_RECURSIVE_TARGETS = $(am__recursive_targets:-recursive=) TAGS CTAGS \ distdir +am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) +# Read a list of newline-separated strings from the standard input, +# and print each of them once, without duplicates. Input order is +# *not* preserved. +am__uniquify_input = $(AWK) '\ + BEGIN { nonempty = 0; } \ + { items[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in items) print i; }; } \ +' +# Make sure the list of sources is unique. This is necessary because, +# e.g., the same source file might be shared among _SOURCES variables +# for different programs/libraries. +am__define_uniq_tagged_files = \ + list='$(am__tagged_files)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | $(am__uniquify_input)` ETAGS = etags CTAGS = ctags -DIST_SUBDIRS = $(SUBDIRS) +DIST_SUBDIRS = pam_deny pam_permit pam_unix DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) am__relativize = \ dir0=`pwd`; \ @@ -90,6 +176,7 @@ am__relativize = \ reldir="$$dir2" ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ +AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ @@ -100,6 +187,7 @@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ +CRYPTO_LIBS = @CRYPTO_LIBS@ CRYPT_LIBS = @CRYPT_LIBS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ @@ -205,7 +293,7 @@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ -SUBDIRS = pam_unix pam_deny pam_permit +SUBDIRS = pam_deny pam_permit $(am__append_1) all: all-recursive .SUFFIXES: @@ -247,22 +335,25 @@ clean-libtool: -rm -rf .libs _libs # This directory's subdirectories are mostly independent; you can cd -# into them and run `make' without going through this Makefile. -# To change the values of `make' variables: instead of editing Makefiles, -# (1) if the variable is set in `config.status', edit `config.status' -# (which will cause the Makefiles to be regenerated when you run `make'); -# (2) otherwise, pass the desired values on the `make' command line. -$(RECURSIVE_TARGETS): - @fail= failcom='exit 1'; \ - for f in x $$MAKEFLAGS; do \ - case $$f in \ - *=* | --[!k]*);; \ - *k*) failcom='fail=yes';; \ - esac; \ - done; \ +# into them and run 'make' without going through this Makefile. +# To change the values of 'make' variables: instead of editing Makefiles, +# (1) if the variable is set in 'config.status', edit 'config.status' +# (which will cause the Makefiles to be regenerated when you run 'make'); +# (2) otherwise, pass the desired values on the 'make' command line. +$(am__recursive_targets): + @fail=; \ + if $(am__make_keepgoing); then \ + failcom='fail=yes'; \ + else \ + failcom='exit 1'; \ + fi; \ dot_seen=no; \ target=`echo $@ | sed s/-recursive//`; \ - list='$(SUBDIRS)'; for subdir in $$list; do \ + case "$@" in \ + distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ + *) list='$(SUBDIRS)' ;; \ + esac; \ + for subdir in $$list; do \ echo "Making $$target in $$subdir"; \ if test "$$subdir" = "."; then \ dot_seen=yes; \ @@ -277,57 +368,12 @@ $(RECURSIVE_TARGETS): $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ fi; test -z "$$fail" -$(RECURSIVE_CLEAN_TARGETS): - @fail= failcom='exit 1'; \ - for f in x $$MAKEFLAGS; do \ - case $$f in \ - *=* | --[!k]*);; \ - *k*) failcom='fail=yes';; \ - esac; \ - done; \ - dot_seen=no; \ - case "$@" in \ - distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ - *) list='$(SUBDIRS)' ;; \ - esac; \ - rev=''; for subdir in $$list; do \ - if test "$$subdir" = "."; then :; else \ - rev="$$subdir $$rev"; \ - fi; \ - done; \ - rev="$$rev ."; \ - target=`echo $@ | sed s/-recursive//`; \ - for subdir in $$rev; do \ - echo "Making $$target in $$subdir"; \ - if test "$$subdir" = "."; then \ - local_target="$$target-am"; \ - else \ - local_target="$$target"; \ - fi; \ - ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ - || eval $$failcom; \ - done && test -z "$$fail" -tags-recursive: - list='$(SUBDIRS)'; for subdir in $$list; do \ - test "$$subdir" = . || ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) tags); \ - done -ctags-recursive: - list='$(SUBDIRS)'; for subdir in $$list; do \ - test "$$subdir" = . || ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) ctags); \ - done +ID: $(am__tagged_files) + $(am__define_uniq_tagged_files); mkid -fID $$unique +tags: tags-recursive +TAGS: tags -ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) - list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ - unique=`for i in $$list; do \ - if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ - done | \ - $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ - END { if (nonempty) { for (i in files) print i; }; }'`; \ - mkid -fID $$unique -tags: TAGS - -TAGS: tags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ - $(TAGS_FILES) $(LISP) +tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \ @@ -343,12 +389,7 @@ TAGS: tags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \ fi; \ done; \ - list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ - unique=`for i in $$list; do \ - if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ - done | \ - $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ - END { if (nonempty) { for (i in files) print i; }; }'`; \ + $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ @@ -360,15 +401,11 @@ TAGS: tags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $$unique; \ fi; \ fi -ctags: CTAGS -CTAGS: ctags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ - $(TAGS_FILES) $(LISP) - list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ - unique=`for i in $$list; do \ - if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ - done | \ - $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ - END { if (nonempty) { for (i in files) print i; }; }'`; \ +ctags: ctags-recursive + +CTAGS: ctags +ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique @@ -377,6 +414,21 @@ GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" +cscopelist: cscopelist-recursive + +cscopelist-am: $(am__tagged_files) + list='$(am__tagged_files)'; \ + case "$(srcdir)" in \ + [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ + *) sdir=$(subdir)/$(srcdir) ;; \ + esac; \ + for i in $$list; do \ + if test -f "$$i"; then \ + echo "$(subdir)/$$i"; \ + else \ + echo "$$sdir/$$i"; \ + fi; \ + done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags @@ -413,13 +465,10 @@ distdir: $(DISTFILES) done @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ - test -d "$(distdir)/$$subdir" \ - || $(MKDIR_P) "$(distdir)/$$subdir" \ - || exit 1; \ - fi; \ - done - @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ - if test "$$subdir" = .; then :; else \ + $(am__make_dryrun) \ + || test -d "$(distdir)/$$subdir" \ + || $(MKDIR_P) "$(distdir)/$$subdir" \ + || exit 1; \ dir1=$$subdir; dir2="$(distdir)/$$subdir"; \ $(am__relativize); \ new_distdir=$$reldir; \ @@ -454,10 +503,15 @@ install-am: all-am installcheck: installcheck-recursive install-strip: - $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ - install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ - `test -z '$(STRIP)' || \ - echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install + if test -z '$(STRIP)'; then \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + install; \ + else \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ + fi mostlyclean-generic: clean-generic: @@ -535,22 +589,20 @@ ps-am: uninstall-am: -.MAKE: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) ctags-recursive \ - install-am install-strip tags-recursive +.MAKE: $(am__recursive_targets) install-am install-strip -.PHONY: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) CTAGS GTAGS \ - all all-am check check-am clean clean-generic clean-libtool \ - ctags ctags-recursive distclean distclean-generic \ - distclean-libtool distclean-tags distdir dvi dvi-am html \ - html-am info info-am install install-am install-data \ - install-data-am install-dvi install-dvi-am install-exec \ - install-exec-am install-html install-html-am install-info \ - install-info-am install-man install-pdf install-pdf-am \ - install-ps install-ps-am install-strip installcheck \ - installcheck-am installdirs installdirs-am maintainer-clean \ - maintainer-clean-generic mostlyclean mostlyclean-generic \ - mostlyclean-libtool pdf pdf-am ps ps-am tags tags-recursive \ - uninstall uninstall-am +.PHONY: $(am__recursive_targets) CTAGS GTAGS TAGS all all-am check \ + check-am clean clean-generic clean-libtool cscopelist-am ctags \ + ctags-am distclean distclean-generic distclean-libtool \ + distclean-tags distdir dvi dvi-am html html-am info info-am \ + install install-am install-data install-data-am install-dvi \ + install-dvi-am install-exec install-exec-am install-html \ + install-html-am install-info install-info-am install-man \ + install-pdf install-pdf-am install-ps install-ps-am \ + install-strip installcheck installcheck-am installdirs \ + installdirs-am maintainer-clean maintainer-clean-generic \ + mostlyclean mostlyclean-generic mostlyclean-libtool pdf pdf-am \ + ps ps-am tags tags-am uninstall uninstall-am # Tell versions [3.59,3.63) of GNU make to not export all variables. diff --git a/contrib/openpam/modules/pam_deny/Makefile.am b/contrib/openpam/modules/pam_deny/Makefile.am index d432915cc50e..c04a38547ec0 100644 --- a/contrib/openpam/modules/pam_deny/Makefile.am +++ b/contrib/openpam/modules/pam_deny/Makefile.am @@ -1,10 +1,15 @@ -# $Id: Makefile.am 320 2006-02-16 20:33:19Z des $ +# $Id: Makefile.am 690 2013-08-15 13:22:51Z des $ -pkglibdir = @OPENPAM_MODULES_DIR@ -INCLUDES = -I$(top_srcdir)/include +if CUSTOM_MODULES_DIR +moduledir = @OPENPAM_MODULES_DIR@ +else +moduledir = $(libdir) +endif +AM_CPPFLAGS = -I$(top_srcdir)/include -pkglib_LTLIBRARIES = pam_deny.la +module_LTLIBRARIES = pam_deny.la pam_deny_la_SOURCES = pam_deny.c -pam_deny_la_LDFLAGS = -no-undefined -module -version-info @LIB_MAJ@ -pam_deny_la_LIBADD = $(top_builddir)/lib/libpam.la +pam_deny_la_LDFLAGS = -no-undefined -module -version-info @LIB_MAJ@ \ + -export-symbols-regex '^pam_sm_' +pam_deny_la_LIBADD = $(top_builddir)/lib/libpam/libpam.la diff --git a/contrib/openpam/modules/pam_deny/Makefile.in b/contrib/openpam/modules/pam_deny/Makefile.in index 7c5855c3d385..7369bdbc0bca 100644 --- a/contrib/openpam/modules/pam_deny/Makefile.in +++ b/contrib/openpam/modules/pam_deny/Makefile.in @@ -1,9 +1,8 @@ -# Makefile.in generated by automake 1.11.1 from Makefile.am. +# Makefile.in generated by automake 1.14 from Makefile.am. # @configure_input@ -# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, -# 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation, -# Inc. +# Copyright (C) 1994-2013 Free Software Foundation, Inc. + # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. @@ -15,11 +14,57 @@ @SET_MAKE@ -# $Id: Makefile.am 320 2006-02-16 20:33:19Z des $ +# $Id: Makefile.am 690 2013-08-15 13:22:51Z des $ VPATH = @srcdir@ +am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)' +am__make_running_with_option = \ + case $${target_option-} in \ + ?) ;; \ + *) echo "am__make_running_with_option: internal error: invalid" \ + "target option '$${target_option-}' specified" >&2; \ + exit 1;; \ + esac; \ + has_opt=no; \ + sane_makeflags=$$MAKEFLAGS; \ + if $(am__is_gnu_make); then \ + sane_makeflags=$$MFLAGS; \ + else \ + case $$MAKEFLAGS in \ + *\\[\ \ ]*) \ + bs=\\; \ + sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ + | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ + esac; \ + fi; \ + skip_next=no; \ + strip_trailopt () \ + { \ + flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ + }; \ + for flg in $$sane_makeflags; do \ + test $$skip_next = yes && { skip_next=no; continue; }; \ + case $$flg in \ + *=*|--*) continue;; \ + -*I) strip_trailopt 'I'; skip_next=yes;; \ + -*I?*) strip_trailopt 'I';; \ + -*O) strip_trailopt 'O'; skip_next=yes;; \ + -*O?*) strip_trailopt 'O';; \ + -*l) strip_trailopt 'l'; skip_next=yes;; \ + -*l?*) strip_trailopt 'l';; \ + -[dEDm]) skip_next=yes;; \ + -[JT]) skip_next=yes;; \ + esac; \ + case $$flg in \ + *$$target_option*) has_opt=yes; break;; \ + esac; \ + done; \ + test $$has_opt = yes +am__make_dryrun = (target_option=n; $(am__make_running_with_option)) +am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 @@ -36,9 +81,13 @@ POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = modules/pam_deny -DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in +DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \ + $(top_srcdir)/depcomp ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 -am__aclocal_m4_deps = $(top_srcdir)/configure.ac +am__aclocal_m4_deps = $(top_srcdir)/m4/libtool.m4 \ + $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \ + $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \ + $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d @@ -66,35 +115,88 @@ am__nobase_list = $(am__nobase_strip_setup); \ am__base_list = \ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' -am__installdirs = "$(DESTDIR)$(pkglibdir)" -LTLIBRARIES = $(pkglib_LTLIBRARIES) -pam_deny_la_DEPENDENCIES = $(top_builddir)/lib/libpam.la +am__uninstall_files_from_dir = { \ + test -z "$$files" \ + || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ + || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ + $(am__cd) "$$dir" && rm -f $$files; }; \ + } +am__installdirs = "$(DESTDIR)$(moduledir)" +LTLIBRARIES = $(module_LTLIBRARIES) +pam_deny_la_DEPENDENCIES = $(top_builddir)/lib/libpam/libpam.la am_pam_deny_la_OBJECTS = pam_deny.lo pam_deny_la_OBJECTS = $(am_pam_deny_la_OBJECTS) -pam_deny_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \ +AM_V_lt = $(am__v_lt_@AM_V@) +am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) +am__v_lt_0 = --silent +am__v_lt_1 = +pam_deny_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(pam_deny_la_LDFLAGS) $(LDFLAGS) -o $@ +AM_V_P = $(am__v_P_@AM_V@) +am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) +am__v_P_0 = false +am__v_P_1 = : +AM_V_GEN = $(am__v_GEN_@AM_V@) +am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) +am__v_GEN_0 = @echo " GEN " $@; +am__v_GEN_1 = +AM_V_at = $(am__v_at_@AM_V@) +am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) +am__v_at_0 = @ +am__v_at_1 = DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) depcomp = $(SHELL) $(top_srcdir)/depcomp am__depfiles_maybe = depfiles am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -LTCOMPILE = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ - --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ - $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ + $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ + $(AM_CFLAGS) $(CFLAGS) +AM_V_CC = $(am__v_CC_@AM_V@) +am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) +am__v_CC_0 = @echo " CC " $@; +am__v_CC_1 = CCLD = $(CC) -LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ - --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \ - $(LDFLAGS) -o $@ +LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(AM_LDFLAGS) $(LDFLAGS) -o $@ +AM_V_CCLD = $(am__v_CCLD_@AM_V@) +am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) +am__v_CCLD_0 = @echo " CCLD " $@; +am__v_CCLD_1 = SOURCES = $(pam_deny_la_SOURCES) DIST_SOURCES = $(pam_deny_la_SOURCES) +am__can_run_installinfo = \ + case $$AM_UPDATE_INFO_DIR in \ + n|no|NO) false;; \ + *) (install-info --version) >/dev/null 2>&1;; \ + esac +am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) +# Read a list of newline-separated strings from the standard input, +# and print each of them once, without duplicates. Input order is +# *not* preserved. +am__uniquify_input = $(AWK) '\ + BEGIN { nonempty = 0; } \ + { items[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in items) print i; }; } \ +' +# Make sure the list of sources is unique. This is necessary because, +# e.g., the same source file might be shared among _SOURCES variables +# for different programs/libraries. +am__define_uniq_tagged_files = \ + list='$(am__tagged_files)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | $(am__uniquify_input)` ETAGS = etags CTAGS = ctags DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) -pkglibdir = @OPENPAM_MODULES_DIR@ ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ +AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ @@ -105,6 +207,7 @@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ +CRYPTO_LIBS = @CRYPTO_LIBS@ CRYPT_LIBS = @CRYPT_LIBS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ @@ -210,11 +313,15 @@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ -INCLUDES = -I$(top_srcdir)/include -pkglib_LTLIBRARIES = pam_deny.la +@CUSTOM_MODULES_DIR_FALSE@moduledir = $(libdir) +@CUSTOM_MODULES_DIR_TRUE@moduledir = @OPENPAM_MODULES_DIR@ +AM_CPPFLAGS = -I$(top_srcdir)/include +module_LTLIBRARIES = pam_deny.la pam_deny_la_SOURCES = pam_deny.c -pam_deny_la_LDFLAGS = -no-undefined -module -version-info @LIB_MAJ@ -pam_deny_la_LIBADD = $(top_builddir)/lib/libpam.la +pam_deny_la_LDFLAGS = -no-undefined -module -version-info @LIB_MAJ@ \ + -export-symbols-regex '^pam_sm_' + +pam_deny_la_LIBADD = $(top_builddir)/lib/libpam/libpam.la all: all-am .SUFFIXES: @@ -249,39 +356,44 @@ $(top_srcdir)/configure: $(am__configure_deps) $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): -install-pkglibLTLIBRARIES: $(pkglib_LTLIBRARIES) + +install-moduleLTLIBRARIES: $(module_LTLIBRARIES) @$(NORMAL_INSTALL) - test -z "$(pkglibdir)" || $(MKDIR_P) "$(DESTDIR)$(pkglibdir)" - @list='$(pkglib_LTLIBRARIES)'; test -n "$(pkglibdir)" || list=; \ + @list='$(module_LTLIBRARIES)'; test -n "$(moduledir)" || list=; \ list2=; for p in $$list; do \ if test -f $$p; then \ list2="$$list2 $$p"; \ else :; fi; \ done; \ test -z "$$list2" || { \ - echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(pkglibdir)'"; \ - $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(pkglibdir)"; \ + echo " $(MKDIR_P) '$(DESTDIR)$(moduledir)'"; \ + $(MKDIR_P) "$(DESTDIR)$(moduledir)" || exit 1; \ + echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(moduledir)'"; \ + $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(moduledir)"; \ } -uninstall-pkglibLTLIBRARIES: +uninstall-moduleLTLIBRARIES: @$(NORMAL_UNINSTALL) - @list='$(pkglib_LTLIBRARIES)'; test -n "$(pkglibdir)" || list=; \ + @list='$(module_LTLIBRARIES)'; test -n "$(moduledir)" || list=; \ for p in $$list; do \ $(am__strip_dir) \ - echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(pkglibdir)/$$f'"; \ - $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(pkglibdir)/$$f"; \ + echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(moduledir)/$$f'"; \ + $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(moduledir)/$$f"; \ done -clean-pkglibLTLIBRARIES: - -test -z "$(pkglib_LTLIBRARIES)" || rm -f $(pkglib_LTLIBRARIES) - @list='$(pkglib_LTLIBRARIES)'; for p in $$list; do \ - dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \ - test "$$dir" != "$$p" || dir=.; \ - echo "rm -f \"$${dir}/so_locations\""; \ - rm -f "$${dir}/so_locations"; \ - done -pam_deny.la: $(pam_deny_la_OBJECTS) $(pam_deny_la_DEPENDENCIES) - $(pam_deny_la_LINK) -rpath $(pkglibdir) $(pam_deny_la_OBJECTS) $(pam_deny_la_LIBADD) $(LIBS) +clean-moduleLTLIBRARIES: + -test -z "$(module_LTLIBRARIES)" || rm -f $(module_LTLIBRARIES) + @list='$(module_LTLIBRARIES)'; \ + locs=`for p in $$list; do echo $$p; done | \ + sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ + sort -u`; \ + test -z "$$locs" || { \ + echo rm -f $${locs}; \ + rm -f $${locs}; \ + } + +pam_deny.la: $(pam_deny_la_OBJECTS) $(pam_deny_la_DEPENDENCIES) $(EXTRA_pam_deny_la_DEPENDENCIES) + $(AM_V_CCLD)$(pam_deny_la_LINK) -rpath $(moduledir) $(pam_deny_la_OBJECTS) $(pam_deny_la_LIBADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) @@ -292,25 +404,25 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pam_deny.Plo@am__quote@ .c.o: -@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(COMPILE) -c $< +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< .c.obj: -@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'` +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` .c.lo: -@am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $< +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< mostlyclean-libtool: -rm -f *.lo @@ -318,26 +430,15 @@ mostlyclean-libtool: clean-libtool: -rm -rf .libs _libs -ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) - list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ - unique=`for i in $$list; do \ - if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ - done | \ - $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ - END { if (nonempty) { for (i in files) print i; }; }'`; \ - mkid -fID $$unique -tags: TAGS +ID: $(am__tagged_files) + $(am__define_uniq_tagged_files); mkid -fID $$unique +tags: tags-am +TAGS: tags -TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ - $(TAGS_FILES) $(LISP) +tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ - list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ - unique=`for i in $$list; do \ - if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ - done | \ - $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ - END { if (nonempty) { for (i in files) print i; }; }'`; \ + $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ @@ -349,15 +450,11 @@ TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $$unique; \ fi; \ fi -ctags: CTAGS -CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ - $(TAGS_FILES) $(LISP) - list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ - unique=`for i in $$list; do \ - if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ - done | \ - $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ - END { if (nonempty) { for (i in files) print i; }; }'`; \ +ctags: ctags-am + +CTAGS: ctags +ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique @@ -366,6 +463,21 @@ GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" +cscopelist: cscopelist-am + +cscopelist-am: $(am__tagged_files) + list='$(am__tagged_files)'; \ + case "$(srcdir)" in \ + [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ + *) sdir=$(subdir)/$(srcdir) ;; \ + esac; \ + for i in $$list; do \ + if test -f "$$i"; then \ + echo "$(subdir)/$$i"; \ + else \ + echo "$$sdir/$$i"; \ + fi; \ + done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags @@ -404,7 +516,7 @@ check-am: all-am check: check-am all-am: Makefile $(LTLIBRARIES) installdirs: - for dir in "$(DESTDIR)$(pkglibdir)"; do \ + for dir in "$(DESTDIR)$(moduledir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ done install: install-am @@ -417,10 +529,15 @@ install-am: all-am installcheck: installcheck-am install-strip: - $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ - install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ - `test -z '$(STRIP)' || \ - echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install + if test -z '$(STRIP)'; then \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + install; \ + else \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ + fi mostlyclean-generic: clean-generic: @@ -434,7 +551,7 @@ maintainer-clean-generic: @echo "it deletes files that may require special tools to rebuild." clean: clean-am -clean-am: clean-generic clean-libtool clean-pkglibLTLIBRARIES \ +clean-am: clean-generic clean-libtool clean-moduleLTLIBRARIES \ mostlyclean-am distclean: distclean-am @@ -455,13 +572,13 @@ info: info-am info-am: -install-data-am: +install-data-am: install-moduleLTLIBRARIES install-dvi: install-dvi-am install-dvi-am: -install-exec-am: install-pkglibLTLIBRARIES +install-exec-am: install-html: install-html-am @@ -501,23 +618,24 @@ ps: ps-am ps-am: -uninstall-am: uninstall-pkglibLTLIBRARIES +uninstall-am: uninstall-moduleLTLIBRARIES .MAKE: install-am install-strip -.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \ - clean-libtool clean-pkglibLTLIBRARIES ctags distclean \ - distclean-compile distclean-generic distclean-libtool \ - distclean-tags distdir dvi dvi-am html html-am info info-am \ - install install-am install-data install-data-am install-dvi \ - install-dvi-am install-exec install-exec-am install-html \ - install-html-am install-info install-info-am install-man \ - install-pdf install-pdf-am install-pkglibLTLIBRARIES \ - install-ps install-ps-am install-strip installcheck \ - installcheck-am installdirs maintainer-clean \ - maintainer-clean-generic mostlyclean mostlyclean-compile \ - mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ - tags uninstall uninstall-am uninstall-pkglibLTLIBRARIES +.PHONY: CTAGS GTAGS TAGS all all-am check check-am clean clean-generic \ + clean-libtool clean-moduleLTLIBRARIES cscopelist-am ctags \ + ctags-am distclean distclean-compile distclean-generic \ + distclean-libtool distclean-tags distdir dvi dvi-am html \ + html-am info info-am install install-am install-data \ + install-data-am install-dvi install-dvi-am install-exec \ + install-exec-am install-html install-html-am install-info \ + install-info-am install-man install-moduleLTLIBRARIES \ + install-pdf install-pdf-am install-ps install-ps-am \ + install-strip installcheck installcheck-am installdirs \ + maintainer-clean maintainer-clean-generic mostlyclean \ + mostlyclean-compile mostlyclean-generic mostlyclean-libtool \ + pdf pdf-am ps ps-am tags tags-am uninstall uninstall-am \ + uninstall-moduleLTLIBRARIES # Tell versions [3.59,3.63) of GNU make to not export all variables. diff --git a/contrib/openpam/modules/pam_deny/pam_deny.c b/contrib/openpam/modules/pam_deny/pam_deny.c index cbd3c4f06e5e..d6983c5a3521 100644 --- a/contrib/openpam/modules/pam_deny/pam_deny.c +++ b/contrib/openpam/modules/pam_deny/pam_deny.c @@ -32,7 +32,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: pam_deny.c 437 2011-09-13 12:00:13Z des $ + * $Id: pam_deny.c 648 2013-03-05 17:54:27Z des $ */ #ifdef HAVE_CONFIG_H diff --git a/contrib/openpam/modules/pam_permit/Makefile.am b/contrib/openpam/modules/pam_permit/Makefile.am index 363ca7cf2293..6b0757d12a24 100644 --- a/contrib/openpam/modules/pam_permit/Makefile.am +++ b/contrib/openpam/modules/pam_permit/Makefile.am @@ -1,10 +1,15 @@ -# $Id: Makefile.am 320 2006-02-16 20:33:19Z des $ +# $Id: Makefile.am 690 2013-08-15 13:22:51Z des $ -pkglibdir = @OPENPAM_MODULES_DIR@ -INCLUDES = -I$(top_srcdir)/include +if CUSTOM_MODULES_DIR +moduledir = @OPENPAM_MODULES_DIR@ +else +moduledir = $(libdir) +endif +AM_CPPFLAGS = -I$(top_srcdir)/include -pkglib_LTLIBRARIES = pam_permit.la +module_LTLIBRARIES = pam_permit.la pam_permit_la_SOURCES = pam_permit.c -pam_permit_la_LDFLAGS = -no-undefined -module -version-info @LIB_MAJ@ -pam_permit_la_LIBADD = $(top_builddir)/lib/libpam.la +pam_permit_la_LDFLAGS = -no-undefined -module -version-info @LIB_MAJ@ \ + -export-symbols-regex '^pam_sm_' +pam_permit_la_LIBADD = $(top_builddir)/lib/libpam/libpam.la diff --git a/contrib/openpam/modules/pam_permit/Makefile.in b/contrib/openpam/modules/pam_permit/Makefile.in index b0eb2736adf2..f84e317dc0dd 100644 --- a/contrib/openpam/modules/pam_permit/Makefile.in +++ b/contrib/openpam/modules/pam_permit/Makefile.in @@ -1,9 +1,8 @@ -# Makefile.in generated by automake 1.11.1 from Makefile.am. +# Makefile.in generated by automake 1.14 from Makefile.am. # @configure_input@ -# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, -# 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation, -# Inc. +# Copyright (C) 1994-2013 Free Software Foundation, Inc. + # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. @@ -15,11 +14,57 @@ @SET_MAKE@ -# $Id: Makefile.am 320 2006-02-16 20:33:19Z des $ +# $Id: Makefile.am 690 2013-08-15 13:22:51Z des $ VPATH = @srcdir@ +am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)' +am__make_running_with_option = \ + case $${target_option-} in \ + ?) ;; \ + *) echo "am__make_running_with_option: internal error: invalid" \ + "target option '$${target_option-}' specified" >&2; \ + exit 1;; \ + esac; \ + has_opt=no; \ + sane_makeflags=$$MAKEFLAGS; \ + if $(am__is_gnu_make); then \ + sane_makeflags=$$MFLAGS; \ + else \ + case $$MAKEFLAGS in \ + *\\[\ \ ]*) \ + bs=\\; \ + sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ + | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ + esac; \ + fi; \ + skip_next=no; \ + strip_trailopt () \ + { \ + flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ + }; \ + for flg in $$sane_makeflags; do \ + test $$skip_next = yes && { skip_next=no; continue; }; \ + case $$flg in \ + *=*|--*) continue;; \ + -*I) strip_trailopt 'I'; skip_next=yes;; \ + -*I?*) strip_trailopt 'I';; \ + -*O) strip_trailopt 'O'; skip_next=yes;; \ + -*O?*) strip_trailopt 'O';; \ + -*l) strip_trailopt 'l'; skip_next=yes;; \ + -*l?*) strip_trailopt 'l';; \ + -[dEDm]) skip_next=yes;; \ + -[JT]) skip_next=yes;; \ + esac; \ + case $$flg in \ + *$$target_option*) has_opt=yes; break;; \ + esac; \ + done; \ + test $$has_opt = yes +am__make_dryrun = (target_option=n; $(am__make_running_with_option)) +am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 @@ -36,9 +81,13 @@ POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = modules/pam_permit -DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in +DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \ + $(top_srcdir)/depcomp ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 -am__aclocal_m4_deps = $(top_srcdir)/configure.ac +am__aclocal_m4_deps = $(top_srcdir)/m4/libtool.m4 \ + $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \ + $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \ + $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d @@ -66,35 +115,88 @@ am__nobase_list = $(am__nobase_strip_setup); \ am__base_list = \ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' -am__installdirs = "$(DESTDIR)$(pkglibdir)" -LTLIBRARIES = $(pkglib_LTLIBRARIES) -pam_permit_la_DEPENDENCIES = $(top_builddir)/lib/libpam.la +am__uninstall_files_from_dir = { \ + test -z "$$files" \ + || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ + || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ + $(am__cd) "$$dir" && rm -f $$files; }; \ + } +am__installdirs = "$(DESTDIR)$(moduledir)" +LTLIBRARIES = $(module_LTLIBRARIES) +pam_permit_la_DEPENDENCIES = $(top_builddir)/lib/libpam/libpam.la am_pam_permit_la_OBJECTS = pam_permit.lo pam_permit_la_OBJECTS = $(am_pam_permit_la_OBJECTS) -pam_permit_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \ +AM_V_lt = $(am__v_lt_@AM_V@) +am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) +am__v_lt_0 = --silent +am__v_lt_1 = +pam_permit_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(pam_permit_la_LDFLAGS) $(LDFLAGS) -o $@ +AM_V_P = $(am__v_P_@AM_V@) +am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) +am__v_P_0 = false +am__v_P_1 = : +AM_V_GEN = $(am__v_GEN_@AM_V@) +am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) +am__v_GEN_0 = @echo " GEN " $@; +am__v_GEN_1 = +AM_V_at = $(am__v_at_@AM_V@) +am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) +am__v_at_0 = @ +am__v_at_1 = DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) depcomp = $(SHELL) $(top_srcdir)/depcomp am__depfiles_maybe = depfiles am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -LTCOMPILE = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ - --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ - $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ + $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ + $(AM_CFLAGS) $(CFLAGS) +AM_V_CC = $(am__v_CC_@AM_V@) +am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) +am__v_CC_0 = @echo " CC " $@; +am__v_CC_1 = CCLD = $(CC) -LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ - --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \ - $(LDFLAGS) -o $@ +LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(AM_LDFLAGS) $(LDFLAGS) -o $@ +AM_V_CCLD = $(am__v_CCLD_@AM_V@) +am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) +am__v_CCLD_0 = @echo " CCLD " $@; +am__v_CCLD_1 = SOURCES = $(pam_permit_la_SOURCES) DIST_SOURCES = $(pam_permit_la_SOURCES) +am__can_run_installinfo = \ + case $$AM_UPDATE_INFO_DIR in \ + n|no|NO) false;; \ + *) (install-info --version) >/dev/null 2>&1;; \ + esac +am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) +# Read a list of newline-separated strings from the standard input, +# and print each of them once, without duplicates. Input order is +# *not* preserved. +am__uniquify_input = $(AWK) '\ + BEGIN { nonempty = 0; } \ + { items[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in items) print i; }; } \ +' +# Make sure the list of sources is unique. This is necessary because, +# e.g., the same source file might be shared among _SOURCES variables +# for different programs/libraries. +am__define_uniq_tagged_files = \ + list='$(am__tagged_files)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | $(am__uniquify_input)` ETAGS = etags CTAGS = ctags DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) -pkglibdir = @OPENPAM_MODULES_DIR@ ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ +AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ @@ -105,6 +207,7 @@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ +CRYPTO_LIBS = @CRYPTO_LIBS@ CRYPT_LIBS = @CRYPT_LIBS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ @@ -210,11 +313,15 @@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ -INCLUDES = -I$(top_srcdir)/include -pkglib_LTLIBRARIES = pam_permit.la +@CUSTOM_MODULES_DIR_FALSE@moduledir = $(libdir) +@CUSTOM_MODULES_DIR_TRUE@moduledir = @OPENPAM_MODULES_DIR@ +AM_CPPFLAGS = -I$(top_srcdir)/include +module_LTLIBRARIES = pam_permit.la pam_permit_la_SOURCES = pam_permit.c -pam_permit_la_LDFLAGS = -no-undefined -module -version-info @LIB_MAJ@ -pam_permit_la_LIBADD = $(top_builddir)/lib/libpam.la +pam_permit_la_LDFLAGS = -no-undefined -module -version-info @LIB_MAJ@ \ + -export-symbols-regex '^pam_sm_' + +pam_permit_la_LIBADD = $(top_builddir)/lib/libpam/libpam.la all: all-am .SUFFIXES: @@ -249,39 +356,44 @@ $(top_srcdir)/configure: $(am__configure_deps) $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): -install-pkglibLTLIBRARIES: $(pkglib_LTLIBRARIES) + +install-moduleLTLIBRARIES: $(module_LTLIBRARIES) @$(NORMAL_INSTALL) - test -z "$(pkglibdir)" || $(MKDIR_P) "$(DESTDIR)$(pkglibdir)" - @list='$(pkglib_LTLIBRARIES)'; test -n "$(pkglibdir)" || list=; \ + @list='$(module_LTLIBRARIES)'; test -n "$(moduledir)" || list=; \ list2=; for p in $$list; do \ if test -f $$p; then \ list2="$$list2 $$p"; \ else :; fi; \ done; \ test -z "$$list2" || { \ - echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(pkglibdir)'"; \ - $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(pkglibdir)"; \ + echo " $(MKDIR_P) '$(DESTDIR)$(moduledir)'"; \ + $(MKDIR_P) "$(DESTDIR)$(moduledir)" || exit 1; \ + echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(moduledir)'"; \ + $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(moduledir)"; \ } -uninstall-pkglibLTLIBRARIES: +uninstall-moduleLTLIBRARIES: @$(NORMAL_UNINSTALL) - @list='$(pkglib_LTLIBRARIES)'; test -n "$(pkglibdir)" || list=; \ + @list='$(module_LTLIBRARIES)'; test -n "$(moduledir)" || list=; \ for p in $$list; do \ $(am__strip_dir) \ - echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(pkglibdir)/$$f'"; \ - $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(pkglibdir)/$$f"; \ + echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(moduledir)/$$f'"; \ + $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(moduledir)/$$f"; \ done -clean-pkglibLTLIBRARIES: - -test -z "$(pkglib_LTLIBRARIES)" || rm -f $(pkglib_LTLIBRARIES) - @list='$(pkglib_LTLIBRARIES)'; for p in $$list; do \ - dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \ - test "$$dir" != "$$p" || dir=.; \ - echo "rm -f \"$${dir}/so_locations\""; \ - rm -f "$${dir}/so_locations"; \ - done -pam_permit.la: $(pam_permit_la_OBJECTS) $(pam_permit_la_DEPENDENCIES) - $(pam_permit_la_LINK) -rpath $(pkglibdir) $(pam_permit_la_OBJECTS) $(pam_permit_la_LIBADD) $(LIBS) +clean-moduleLTLIBRARIES: + -test -z "$(module_LTLIBRARIES)" || rm -f $(module_LTLIBRARIES) + @list='$(module_LTLIBRARIES)'; \ + locs=`for p in $$list; do echo $$p; done | \ + sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ + sort -u`; \ + test -z "$$locs" || { \ + echo rm -f $${locs}; \ + rm -f $${locs}; \ + } + +pam_permit.la: $(pam_permit_la_OBJECTS) $(pam_permit_la_DEPENDENCIES) $(EXTRA_pam_permit_la_DEPENDENCIES) + $(AM_V_CCLD)$(pam_permit_la_LINK) -rpath $(moduledir) $(pam_permit_la_OBJECTS) $(pam_permit_la_LIBADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) @@ -292,25 +404,25 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pam_permit.Plo@am__quote@ .c.o: -@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(COMPILE) -c $< +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< .c.obj: -@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'` +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` .c.lo: -@am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $< +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< mostlyclean-libtool: -rm -f *.lo @@ -318,26 +430,15 @@ mostlyclean-libtool: clean-libtool: -rm -rf .libs _libs -ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) - list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ - unique=`for i in $$list; do \ - if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ - done | \ - $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ - END { if (nonempty) { for (i in files) print i; }; }'`; \ - mkid -fID $$unique -tags: TAGS +ID: $(am__tagged_files) + $(am__define_uniq_tagged_files); mkid -fID $$unique +tags: tags-am +TAGS: tags -TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ - $(TAGS_FILES) $(LISP) +tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ - list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ - unique=`for i in $$list; do \ - if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ - done | \ - $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ - END { if (nonempty) { for (i in files) print i; }; }'`; \ + $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ @@ -349,15 +450,11 @@ TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $$unique; \ fi; \ fi -ctags: CTAGS -CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ - $(TAGS_FILES) $(LISP) - list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ - unique=`for i in $$list; do \ - if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ - done | \ - $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ - END { if (nonempty) { for (i in files) print i; }; }'`; \ +ctags: ctags-am + +CTAGS: ctags +ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique @@ -366,6 +463,21 @@ GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" +cscopelist: cscopelist-am + +cscopelist-am: $(am__tagged_files) + list='$(am__tagged_files)'; \ + case "$(srcdir)" in \ + [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ + *) sdir=$(subdir)/$(srcdir) ;; \ + esac; \ + for i in $$list; do \ + if test -f "$$i"; then \ + echo "$(subdir)/$$i"; \ + else \ + echo "$$sdir/$$i"; \ + fi; \ + done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags @@ -404,7 +516,7 @@ check-am: all-am check: check-am all-am: Makefile $(LTLIBRARIES) installdirs: - for dir in "$(DESTDIR)$(pkglibdir)"; do \ + for dir in "$(DESTDIR)$(moduledir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ done install: install-am @@ -417,10 +529,15 @@ install-am: all-am installcheck: installcheck-am install-strip: - $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ - install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ - `test -z '$(STRIP)' || \ - echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install + if test -z '$(STRIP)'; then \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + install; \ + else \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ + fi mostlyclean-generic: clean-generic: @@ -434,7 +551,7 @@ maintainer-clean-generic: @echo "it deletes files that may require special tools to rebuild." clean: clean-am -clean-am: clean-generic clean-libtool clean-pkglibLTLIBRARIES \ +clean-am: clean-generic clean-libtool clean-moduleLTLIBRARIES \ mostlyclean-am distclean: distclean-am @@ -455,13 +572,13 @@ info: info-am info-am: -install-data-am: +install-data-am: install-moduleLTLIBRARIES install-dvi: install-dvi-am install-dvi-am: -install-exec-am: install-pkglibLTLIBRARIES +install-exec-am: install-html: install-html-am @@ -501,23 +618,24 @@ ps: ps-am ps-am: -uninstall-am: uninstall-pkglibLTLIBRARIES +uninstall-am: uninstall-moduleLTLIBRARIES .MAKE: install-am install-strip -.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \ - clean-libtool clean-pkglibLTLIBRARIES ctags distclean \ - distclean-compile distclean-generic distclean-libtool \ - distclean-tags distdir dvi dvi-am html html-am info info-am \ - install install-am install-data install-data-am install-dvi \ - install-dvi-am install-exec install-exec-am install-html \ - install-html-am install-info install-info-am install-man \ - install-pdf install-pdf-am install-pkglibLTLIBRARIES \ - install-ps install-ps-am install-strip installcheck \ - installcheck-am installdirs maintainer-clean \ - maintainer-clean-generic mostlyclean mostlyclean-compile \ - mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ - tags uninstall uninstall-am uninstall-pkglibLTLIBRARIES +.PHONY: CTAGS GTAGS TAGS all all-am check check-am clean clean-generic \ + clean-libtool clean-moduleLTLIBRARIES cscopelist-am ctags \ + ctags-am distclean distclean-compile distclean-generic \ + distclean-libtool distclean-tags distdir dvi dvi-am html \ + html-am info info-am install install-am install-data \ + install-data-am install-dvi install-dvi-am install-exec \ + install-exec-am install-html install-html-am install-info \ + install-info-am install-man install-moduleLTLIBRARIES \ + install-pdf install-pdf-am install-ps install-ps-am \ + install-strip installcheck installcheck-am installdirs \ + maintainer-clean maintainer-clean-generic mostlyclean \ + mostlyclean-compile mostlyclean-generic mostlyclean-libtool \ + pdf pdf-am ps ps-am tags tags-am uninstall uninstall-am \ + uninstall-moduleLTLIBRARIES # Tell versions [3.59,3.63) of GNU make to not export all variables. diff --git a/contrib/openpam/modules/pam_permit/pam_permit.c b/contrib/openpam/modules/pam_permit/pam_permit.c index b06176d997d0..f42b6c1a95ca 100644 --- a/contrib/openpam/modules/pam_permit/pam_permit.c +++ b/contrib/openpam/modules/pam_permit/pam_permit.c @@ -32,7 +32,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: pam_permit.c 437 2011-09-13 12:00:13Z des $ + * $Id: pam_permit.c 648 2013-03-05 17:54:27Z des $ */ #ifdef HAVE_CONFIG_H diff --git a/contrib/openpam/modules/pam_unix/Makefile.am b/contrib/openpam/modules/pam_unix/Makefile.am index ad1ec67958f6..0189768daf63 100644 --- a/contrib/openpam/modules/pam_unix/Makefile.am +++ b/contrib/openpam/modules/pam_unix/Makefile.am @@ -1,12 +1,15 @@ -# $Id: Makefile.am 429 2010-03-09 17:51:29Z des $ +# $Id: Makefile.am 690 2013-08-15 13:22:51Z des $ -pkglibdir = @OPENPAM_MODULES_DIR@ -INCLUDES = -I$(top_srcdir)/include +if CUSTOM_MODULES_DIR +moduledir = @OPENPAM_MODULES_DIR@ +else +moduledir = $(libdir) +endif +AM_CPPFLAGS = -I$(top_srcdir)/include -if WITH_PAM_UNIX -pkglib_LTLIBRARIES = pam_unix.la +module_LTLIBRARIES = pam_unix.la pam_unix_la_SOURCES = pam_unix.c -pam_unix_la_LDFLAGS = -no-undefined -module -version-info @LIB_MAJ@ -pam_unix_la_LIBADD = $(top_builddir)/lib/libpam.la @CRYPT_LIBS@ -endif +pam_unix_la_LDFLAGS = -no-undefined -module -version-info @LIB_MAJ@ \ + -export-symbols-regex '^pam_sm_' +pam_unix_la_LIBADD = $(top_builddir)/lib/libpam/libpam.la @CRYPT_LIBS@ diff --git a/contrib/openpam/modules/pam_unix/Makefile.in b/contrib/openpam/modules/pam_unix/Makefile.in index 4119fe027895..022e833a3a60 100644 --- a/contrib/openpam/modules/pam_unix/Makefile.in +++ b/contrib/openpam/modules/pam_unix/Makefile.in @@ -1,9 +1,8 @@ -# Makefile.in generated by automake 1.11.1 from Makefile.am. +# Makefile.in generated by automake 1.14 from Makefile.am. # @configure_input@ -# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, -# 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation, -# Inc. +# Copyright (C) 1994-2013 Free Software Foundation, Inc. + # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. @@ -15,11 +14,57 @@ @SET_MAKE@ -# $Id: Makefile.am 429 2010-03-09 17:51:29Z des $ +# $Id: Makefile.am 690 2013-08-15 13:22:51Z des $ VPATH = @srcdir@ +am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)' +am__make_running_with_option = \ + case $${target_option-} in \ + ?) ;; \ + *) echo "am__make_running_with_option: internal error: invalid" \ + "target option '$${target_option-}' specified" >&2; \ + exit 1;; \ + esac; \ + has_opt=no; \ + sane_makeflags=$$MAKEFLAGS; \ + if $(am__is_gnu_make); then \ + sane_makeflags=$$MFLAGS; \ + else \ + case $$MAKEFLAGS in \ + *\\[\ \ ]*) \ + bs=\\; \ + sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ + | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ + esac; \ + fi; \ + skip_next=no; \ + strip_trailopt () \ + { \ + flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ + }; \ + for flg in $$sane_makeflags; do \ + test $$skip_next = yes && { skip_next=no; continue; }; \ + case $$flg in \ + *=*|--*) continue;; \ + -*I) strip_trailopt 'I'; skip_next=yes;; \ + -*I?*) strip_trailopt 'I';; \ + -*O) strip_trailopt 'O'; skip_next=yes;; \ + -*O?*) strip_trailopt 'O';; \ + -*l) strip_trailopt 'l'; skip_next=yes;; \ + -*l?*) strip_trailopt 'l';; \ + -[dEDm]) skip_next=yes;; \ + -[JT]) skip_next=yes;; \ + esac; \ + case $$flg in \ + *$$target_option*) has_opt=yes; break;; \ + esac; \ + done; \ + test $$has_opt = yes +am__make_dryrun = (target_option=n; $(am__make_running_with_option)) +am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 @@ -36,9 +81,13 @@ POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = modules/pam_unix -DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in +DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \ + $(top_srcdir)/depcomp ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 -am__aclocal_m4_deps = $(top_srcdir)/configure.ac +am__aclocal_m4_deps = $(top_srcdir)/m4/libtool.m4 \ + $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \ + $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \ + $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d @@ -66,38 +115,88 @@ am__nobase_list = $(am__nobase_strip_setup); \ am__base_list = \ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' -am__installdirs = "$(DESTDIR)$(pkglibdir)" -LTLIBRARIES = $(pkglib_LTLIBRARIES) -@WITH_PAM_UNIX_TRUE@pam_unix_la_DEPENDENCIES = \ -@WITH_PAM_UNIX_TRUE@ $(top_builddir)/lib/libpam.la -am__pam_unix_la_SOURCES_DIST = pam_unix.c -@WITH_PAM_UNIX_TRUE@am_pam_unix_la_OBJECTS = pam_unix.lo +am__uninstall_files_from_dir = { \ + test -z "$$files" \ + || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ + || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ + $(am__cd) "$$dir" && rm -f $$files; }; \ + } +am__installdirs = "$(DESTDIR)$(moduledir)" +LTLIBRARIES = $(module_LTLIBRARIES) +pam_unix_la_DEPENDENCIES = $(top_builddir)/lib/libpam/libpam.la +am_pam_unix_la_OBJECTS = pam_unix.lo pam_unix_la_OBJECTS = $(am_pam_unix_la_OBJECTS) -pam_unix_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \ +AM_V_lt = $(am__v_lt_@AM_V@) +am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) +am__v_lt_0 = --silent +am__v_lt_1 = +pam_unix_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(pam_unix_la_LDFLAGS) $(LDFLAGS) -o $@ -@WITH_PAM_UNIX_TRUE@am_pam_unix_la_rpath = -rpath $(pkglibdir) +AM_V_P = $(am__v_P_@AM_V@) +am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) +am__v_P_0 = false +am__v_P_1 = : +AM_V_GEN = $(am__v_GEN_@AM_V@) +am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) +am__v_GEN_0 = @echo " GEN " $@; +am__v_GEN_1 = +AM_V_at = $(am__v_at_@AM_V@) +am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) +am__v_at_0 = @ +am__v_at_1 = DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) depcomp = $(SHELL) $(top_srcdir)/depcomp am__depfiles_maybe = depfiles am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -LTCOMPILE = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ - --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ - $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ + $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ + $(AM_CFLAGS) $(CFLAGS) +AM_V_CC = $(am__v_CC_@AM_V@) +am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) +am__v_CC_0 = @echo " CC " $@; +am__v_CC_1 = CCLD = $(CC) -LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ - --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \ - $(LDFLAGS) -o $@ +LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(AM_LDFLAGS) $(LDFLAGS) -o $@ +AM_V_CCLD = $(am__v_CCLD_@AM_V@) +am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) +am__v_CCLD_0 = @echo " CCLD " $@; +am__v_CCLD_1 = SOURCES = $(pam_unix_la_SOURCES) -DIST_SOURCES = $(am__pam_unix_la_SOURCES_DIST) +DIST_SOURCES = $(pam_unix_la_SOURCES) +am__can_run_installinfo = \ + case $$AM_UPDATE_INFO_DIR in \ + n|no|NO) false;; \ + *) (install-info --version) >/dev/null 2>&1;; \ + esac +am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) +# Read a list of newline-separated strings from the standard input, +# and print each of them once, without duplicates. Input order is +# *not* preserved. +am__uniquify_input = $(AWK) '\ + BEGIN { nonempty = 0; } \ + { items[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in items) print i; }; } \ +' +# Make sure the list of sources is unique. This is necessary because, +# e.g., the same source file might be shared among _SOURCES variables +# for different programs/libraries. +am__define_uniq_tagged_files = \ + list='$(am__tagged_files)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | $(am__uniquify_input)` ETAGS = etags CTAGS = ctags DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) -pkglibdir = @OPENPAM_MODULES_DIR@ ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ +AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ @@ -108,6 +207,7 @@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ +CRYPTO_LIBS = @CRYPTO_LIBS@ CRYPT_LIBS = @CRYPT_LIBS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ @@ -213,11 +313,15 @@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ -INCLUDES = -I$(top_srcdir)/include -@WITH_PAM_UNIX_TRUE@pkglib_LTLIBRARIES = pam_unix.la -@WITH_PAM_UNIX_TRUE@pam_unix_la_SOURCES = pam_unix.c -@WITH_PAM_UNIX_TRUE@pam_unix_la_LDFLAGS = -no-undefined -module -version-info @LIB_MAJ@ -@WITH_PAM_UNIX_TRUE@pam_unix_la_LIBADD = $(top_builddir)/lib/libpam.la @CRYPT_LIBS@ +@CUSTOM_MODULES_DIR_FALSE@moduledir = $(libdir) +@CUSTOM_MODULES_DIR_TRUE@moduledir = @OPENPAM_MODULES_DIR@ +AM_CPPFLAGS = -I$(top_srcdir)/include +module_LTLIBRARIES = pam_unix.la +pam_unix_la_SOURCES = pam_unix.c +pam_unix_la_LDFLAGS = -no-undefined -module -version-info @LIB_MAJ@ \ + -export-symbols-regex '^pam_sm_' + +pam_unix_la_LIBADD = $(top_builddir)/lib/libpam/libpam.la @CRYPT_LIBS@ all: all-am .SUFFIXES: @@ -252,39 +356,44 @@ $(top_srcdir)/configure: $(am__configure_deps) $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): -install-pkglibLTLIBRARIES: $(pkglib_LTLIBRARIES) + +install-moduleLTLIBRARIES: $(module_LTLIBRARIES) @$(NORMAL_INSTALL) - test -z "$(pkglibdir)" || $(MKDIR_P) "$(DESTDIR)$(pkglibdir)" - @list='$(pkglib_LTLIBRARIES)'; test -n "$(pkglibdir)" || list=; \ + @list='$(module_LTLIBRARIES)'; test -n "$(moduledir)" || list=; \ list2=; for p in $$list; do \ if test -f $$p; then \ list2="$$list2 $$p"; \ else :; fi; \ done; \ test -z "$$list2" || { \ - echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(pkglibdir)'"; \ - $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(pkglibdir)"; \ + echo " $(MKDIR_P) '$(DESTDIR)$(moduledir)'"; \ + $(MKDIR_P) "$(DESTDIR)$(moduledir)" || exit 1; \ + echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(moduledir)'"; \ + $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(moduledir)"; \ } -uninstall-pkglibLTLIBRARIES: +uninstall-moduleLTLIBRARIES: @$(NORMAL_UNINSTALL) - @list='$(pkglib_LTLIBRARIES)'; test -n "$(pkglibdir)" || list=; \ + @list='$(module_LTLIBRARIES)'; test -n "$(moduledir)" || list=; \ for p in $$list; do \ $(am__strip_dir) \ - echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(pkglibdir)/$$f'"; \ - $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(pkglibdir)/$$f"; \ + echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(moduledir)/$$f'"; \ + $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(moduledir)/$$f"; \ done -clean-pkglibLTLIBRARIES: - -test -z "$(pkglib_LTLIBRARIES)" || rm -f $(pkglib_LTLIBRARIES) - @list='$(pkglib_LTLIBRARIES)'; for p in $$list; do \ - dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \ - test "$$dir" != "$$p" || dir=.; \ - echo "rm -f \"$${dir}/so_locations\""; \ - rm -f "$${dir}/so_locations"; \ - done -pam_unix.la: $(pam_unix_la_OBJECTS) $(pam_unix_la_DEPENDENCIES) - $(pam_unix_la_LINK) $(am_pam_unix_la_rpath) $(pam_unix_la_OBJECTS) $(pam_unix_la_LIBADD) $(LIBS) +clean-moduleLTLIBRARIES: + -test -z "$(module_LTLIBRARIES)" || rm -f $(module_LTLIBRARIES) + @list='$(module_LTLIBRARIES)'; \ + locs=`for p in $$list; do echo $$p; done | \ + sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ + sort -u`; \ + test -z "$$locs" || { \ + echo rm -f $${locs}; \ + rm -f $${locs}; \ + } + +pam_unix.la: $(pam_unix_la_OBJECTS) $(pam_unix_la_DEPENDENCIES) $(EXTRA_pam_unix_la_DEPENDENCIES) + $(AM_V_CCLD)$(pam_unix_la_LINK) -rpath $(moduledir) $(pam_unix_la_OBJECTS) $(pam_unix_la_LIBADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) @@ -295,25 +404,25 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pam_unix.Plo@am__quote@ .c.o: -@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(COMPILE) -c $< +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< .c.obj: -@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'` +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` .c.lo: -@am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $< +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< mostlyclean-libtool: -rm -f *.lo @@ -321,26 +430,15 @@ mostlyclean-libtool: clean-libtool: -rm -rf .libs _libs -ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) - list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ - unique=`for i in $$list; do \ - if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ - done | \ - $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ - END { if (nonempty) { for (i in files) print i; }; }'`; \ - mkid -fID $$unique -tags: TAGS +ID: $(am__tagged_files) + $(am__define_uniq_tagged_files); mkid -fID $$unique +tags: tags-am +TAGS: tags -TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ - $(TAGS_FILES) $(LISP) +tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ - list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ - unique=`for i in $$list; do \ - if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ - done | \ - $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ - END { if (nonempty) { for (i in files) print i; }; }'`; \ + $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ @@ -352,15 +450,11 @@ TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $$unique; \ fi; \ fi -ctags: CTAGS -CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ - $(TAGS_FILES) $(LISP) - list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ - unique=`for i in $$list; do \ - if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ - done | \ - $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ - END { if (nonempty) { for (i in files) print i; }; }'`; \ +ctags: ctags-am + +CTAGS: ctags +ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique @@ -369,6 +463,21 @@ GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" +cscopelist: cscopelist-am + +cscopelist-am: $(am__tagged_files) + list='$(am__tagged_files)'; \ + case "$(srcdir)" in \ + [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ + *) sdir=$(subdir)/$(srcdir) ;; \ + esac; \ + for i in $$list; do \ + if test -f "$$i"; then \ + echo "$(subdir)/$$i"; \ + else \ + echo "$$sdir/$$i"; \ + fi; \ + done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags @@ -407,7 +516,7 @@ check-am: all-am check: check-am all-am: Makefile $(LTLIBRARIES) installdirs: - for dir in "$(DESTDIR)$(pkglibdir)"; do \ + for dir in "$(DESTDIR)$(moduledir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ done install: install-am @@ -420,10 +529,15 @@ install-am: all-am installcheck: installcheck-am install-strip: - $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ - install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ - `test -z '$(STRIP)' || \ - echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install + if test -z '$(STRIP)'; then \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + install; \ + else \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ + fi mostlyclean-generic: clean-generic: @@ -437,7 +551,7 @@ maintainer-clean-generic: @echo "it deletes files that may require special tools to rebuild." clean: clean-am -clean-am: clean-generic clean-libtool clean-pkglibLTLIBRARIES \ +clean-am: clean-generic clean-libtool clean-moduleLTLIBRARIES \ mostlyclean-am distclean: distclean-am @@ -458,13 +572,13 @@ info: info-am info-am: -install-data-am: +install-data-am: install-moduleLTLIBRARIES install-dvi: install-dvi-am install-dvi-am: -install-exec-am: install-pkglibLTLIBRARIES +install-exec-am: install-html: install-html-am @@ -504,23 +618,24 @@ ps: ps-am ps-am: -uninstall-am: uninstall-pkglibLTLIBRARIES +uninstall-am: uninstall-moduleLTLIBRARIES .MAKE: install-am install-strip -.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \ - clean-libtool clean-pkglibLTLIBRARIES ctags distclean \ - distclean-compile distclean-generic distclean-libtool \ - distclean-tags distdir dvi dvi-am html html-am info info-am \ - install install-am install-data install-data-am install-dvi \ - install-dvi-am install-exec install-exec-am install-html \ - install-html-am install-info install-info-am install-man \ - install-pdf install-pdf-am install-pkglibLTLIBRARIES \ - install-ps install-ps-am install-strip installcheck \ - installcheck-am installdirs maintainer-clean \ - maintainer-clean-generic mostlyclean mostlyclean-compile \ - mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ - tags uninstall uninstall-am uninstall-pkglibLTLIBRARIES +.PHONY: CTAGS GTAGS TAGS all all-am check check-am clean clean-generic \ + clean-libtool clean-moduleLTLIBRARIES cscopelist-am ctags \ + ctags-am distclean distclean-compile distclean-generic \ + distclean-libtool distclean-tags distdir dvi dvi-am html \ + html-am info info-am install install-am install-data \ + install-data-am install-dvi install-dvi-am install-exec \ + install-exec-am install-html install-html-am install-info \ + install-info-am install-man install-moduleLTLIBRARIES \ + install-pdf install-pdf-am install-ps install-ps-am \ + install-strip installcheck installcheck-am installdirs \ + maintainer-clean maintainer-clean-generic mostlyclean \ + mostlyclean-compile mostlyclean-generic mostlyclean-libtool \ + pdf pdf-am ps ps-am tags tags-am uninstall uninstall-am \ + uninstall-moduleLTLIBRARIES # Tell versions [3.59,3.63) of GNU make to not export all variables. diff --git a/contrib/openpam/modules/pam_unix/pam_unix.c b/contrib/openpam/modules/pam_unix/pam_unix.c index 6bd35cf627e4..ad7dd1b3a77a 100644 --- a/contrib/openpam/modules/pam_unix/pam_unix.c +++ b/contrib/openpam/modules/pam_unix/pam_unix.c @@ -32,7 +32,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: pam_unix.c 437 2011-09-13 12:00:13Z des $ + * $Id: pam_unix.c 648 2013-03-05 17:54:27Z des $ */ #ifdef HAVE_CONFIG_H diff --git a/contrib/openpam/pamgdb.in b/contrib/openpam/pamgdb.in index 2ec2d65adc4d..5b463900ff08 100644 --- a/contrib/openpam/pamgdb.in +++ b/contrib/openpam/pamgdb.in @@ -1,6 +1,6 @@ #!/bin/sh # -# $Id: pamgdb.in 583 2012-04-07 18:56:13Z des $ +# $Id: pamgdb.in 648 2013-03-05 17:54:27Z des $ # srcdir="@abs_top_srcdir@" diff --git a/contrib/openpam/t/Makefile.am b/contrib/openpam/t/Makefile.am index a3f596d90748..8f9bf1fdde85 100644 --- a/contrib/openpam/t/Makefile.am +++ b/contrib/openpam/t/Makefile.am @@ -1,16 +1,18 @@ -# $Id: Makefile.am 572 2012-04-05 15:41:44Z des $ +# $Id: Makefile.am 714 2013-08-19 15:30:21Z des $ -INCLUDES = -I$(top_srcdir)/include -I$(top_srcdir)/lib +AM_CPPFLAGS = -I$(top_srcdir)/include -I$(top_srcdir)/lib/libpam noinst_HEADERS = t.h # tests -TESTS = t_openpam_readword t_openpam_readlinev +TESTS = +TESTS += t_openpam_readword +TESTS += t_openpam_readlinev check_PROGRAMS = $(TESTS) # libt - common support code check_LIBRARIES = libt.a -libt_a_SOURCES = t_main.c +libt_a_SOURCES = t_main.c t_file.c # link with libpam and libt -LDADD = libt.a $(top_builddir)/lib/libpam.la +LDADD = libt.a $(top_builddir)/lib/libpam/libpam.la diff --git a/contrib/openpam/t/Makefile.in b/contrib/openpam/t/Makefile.in index e71618bd5e83..2e7eda7622d0 100644 --- a/contrib/openpam/t/Makefile.in +++ b/contrib/openpam/t/Makefile.in @@ -1,9 +1,8 @@ -# Makefile.in generated by automake 1.11.1 from Makefile.am. +# Makefile.in generated by automake 1.14 from Makefile.am. # @configure_input@ -# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, -# 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation, -# Inc. +# Copyright (C) 1994-2013 Free Software Foundation, Inc. + # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. @@ -15,9 +14,54 @@ @SET_MAKE@ -# $Id: Makefile.am 572 2012-04-05 15:41:44Z des $ +# $Id: Makefile.am 714 2013-08-19 15:30:21Z des $ VPATH = @srcdir@ +am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)' +am__make_running_with_option = \ + case $${target_option-} in \ + ?) ;; \ + *) echo "am__make_running_with_option: internal error: invalid" \ + "target option '$${target_option-}' specified" >&2; \ + exit 1;; \ + esac; \ + has_opt=no; \ + sane_makeflags=$$MAKEFLAGS; \ + if $(am__is_gnu_make); then \ + sane_makeflags=$$MFLAGS; \ + else \ + case $$MAKEFLAGS in \ + *\\[\ \ ]*) \ + bs=\\; \ + sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ + | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ + esac; \ + fi; \ + skip_next=no; \ + strip_trailopt () \ + { \ + flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ + }; \ + for flg in $$sane_makeflags; do \ + test $$skip_next = yes && { skip_next=no; continue; }; \ + case $$flg in \ + *=*|--*) continue;; \ + -*I) strip_trailopt 'I'; skip_next=yes;; \ + -*I?*) strip_trailopt 'I';; \ + -*O) strip_trailopt 'O'; skip_next=yes;; \ + -*O?*) strip_trailopt 'O';; \ + -*l) strip_trailopt 'l'; skip_next=yes;; \ + -*l?*) strip_trailopt 'l';; \ + -[dEDm]) skip_next=yes;; \ + -[JT]) skip_next=yes;; \ + esac; \ + case $$flg in \ + *$$target_option*) has_opt=yes; break;; \ + esac; \ + done; \ + test $$has_opt = yes +am__make_dryrun = (target_option=n; $(am__make_running_with_option)) +am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ @@ -39,10 +83,14 @@ host_triplet = @host@ TESTS = t_openpam_readword$(EXEEXT) t_openpam_readlinev$(EXEEXT) check_PROGRAMS = $(am__EXEEXT_1) subdir = t -DIST_COMMON = $(noinst_HEADERS) $(srcdir)/Makefile.am \ - $(srcdir)/Makefile.in +DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \ + $(top_srcdir)/depcomp $(noinst_HEADERS) \ + $(top_srcdir)/test-driver ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 -am__aclocal_m4_deps = $(top_srcdir)/configure.ac +am__aclocal_m4_deps = $(top_srcdir)/m4/libtool.m4 \ + $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \ + $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \ + $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d @@ -50,9 +98,13 @@ CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = ARFLAGS = cru +AM_V_AR = $(am__v_AR_@AM_V@) +am__v_AR_ = $(am__v_AR_@AM_DEFAULT_V@) +am__v_AR_0 = @echo " AR " $@; +am__v_AR_1 = libt_a_AR = $(AR) $(ARFLAGS) libt_a_LIBADD = -am_libt_a_OBJECTS = t_main.$(OBJEXT) +am_libt_a_OBJECTS = t_main.$(OBJEXT) t_file.$(OBJEXT) libt_a_OBJECTS = $(am_libt_a_OBJECTS) am__EXEEXT_1 = t_openpam_readword$(EXEEXT) \ t_openpam_readlinev$(EXEEXT) @@ -60,35 +112,286 @@ t_openpam_readlinev_SOURCES = t_openpam_readlinev.c t_openpam_readlinev_OBJECTS = t_openpam_readlinev.$(OBJEXT) t_openpam_readlinev_LDADD = $(LDADD) t_openpam_readlinev_DEPENDENCIES = libt.a \ - $(top_builddir)/lib/libpam.la + $(top_builddir)/lib/libpam/libpam.la +AM_V_lt = $(am__v_lt_@AM_V@) +am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) +am__v_lt_0 = --silent +am__v_lt_1 = t_openpam_readword_SOURCES = t_openpam_readword.c t_openpam_readword_OBJECTS = t_openpam_readword.$(OBJEXT) t_openpam_readword_LDADD = $(LDADD) -t_openpam_readword_DEPENDENCIES = libt.a $(top_builddir)/lib/libpam.la +t_openpam_readword_DEPENDENCIES = libt.a \ + $(top_builddir)/lib/libpam/libpam.la +AM_V_P = $(am__v_P_@AM_V@) +am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) +am__v_P_0 = false +am__v_P_1 = : +AM_V_GEN = $(am__v_GEN_@AM_V@) +am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) +am__v_GEN_0 = @echo " GEN " $@; +am__v_GEN_1 = +AM_V_at = $(am__v_at_@AM_V@) +am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) +am__v_at_0 = @ +am__v_at_1 = DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) depcomp = $(SHELL) $(top_srcdir)/depcomp am__depfiles_maybe = depfiles am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -LTCOMPILE = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ - --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ - $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ + $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ + $(AM_CFLAGS) $(CFLAGS) +AM_V_CC = $(am__v_CC_@AM_V@) +am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) +am__v_CC_0 = @echo " CC " $@; +am__v_CC_1 = CCLD = $(CC) -LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ - --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \ - $(LDFLAGS) -o $@ +LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(AM_LDFLAGS) $(LDFLAGS) -o $@ +AM_V_CCLD = $(am__v_CCLD_@AM_V@) +am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) +am__v_CCLD_0 = @echo " CCLD " $@; +am__v_CCLD_1 = SOURCES = $(libt_a_SOURCES) t_openpam_readlinev.c t_openpam_readword.c DIST_SOURCES = $(libt_a_SOURCES) t_openpam_readlinev.c \ t_openpam_readword.c +am__can_run_installinfo = \ + case $$AM_UPDATE_INFO_DIR in \ + n|no|NO) false;; \ + *) (install-info --version) >/dev/null 2>&1;; \ + esac HEADERS = $(noinst_HEADERS) +am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) +# Read a list of newline-separated strings from the standard input, +# and print each of them once, without duplicates. Input order is +# *not* preserved. +am__uniquify_input = $(AWK) '\ + BEGIN { nonempty = 0; } \ + { items[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in items) print i; }; } \ +' +# Make sure the list of sources is unique. This is necessary because, +# e.g., the same source file might be shared among _SOURCES variables +# for different programs/libraries. +am__define_uniq_tagged_files = \ + list='$(am__tagged_files)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | $(am__uniquify_input)` ETAGS = etags CTAGS = ctags -am__tty_colors = \ -red=; grn=; lgn=; blu=; std= +am__tty_colors_dummy = \ + mgn= red= grn= lgn= blu= brg= std=; \ + am__color_tests=no +am__tty_colors = { \ + $(am__tty_colors_dummy); \ + if test "X$(AM_COLOR_TESTS)" = Xno; then \ + am__color_tests=no; \ + elif test "X$(AM_COLOR_TESTS)" = Xalways; then \ + am__color_tests=yes; \ + elif test "X$$TERM" != Xdumb && { test -t 1; } 2>/dev/null; then \ + am__color_tests=yes; \ + fi; \ + if test $$am__color_tests = yes; then \ + red=''; \ + grn=''; \ + lgn=''; \ + blu=''; \ + mgn=''; \ + brg=''; \ + std=''; \ + fi; \ +} +am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; +am__vpath_adj = case $$p in \ + $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ + *) f=$$p;; \ + esac; +am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; +am__install_max = 40 +am__nobase_strip_setup = \ + srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` +am__nobase_strip = \ + for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" +am__nobase_list = $(am__nobase_strip_setup); \ + for p in $$list; do echo "$$p $$p"; done | \ + sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ + $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ + if (++n[$$2] == $(am__install_max)) \ + { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ + END { for (dir in files) print dir, files[dir] }' +am__base_list = \ + sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ + sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' +am__uninstall_files_from_dir = { \ + test -z "$$files" \ + || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ + || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ + $(am__cd) "$$dir" && rm -f $$files; }; \ + } +am__recheck_rx = ^[ ]*:recheck:[ ]* +am__global_test_result_rx = ^[ ]*:global-test-result:[ ]* +am__copy_in_global_log_rx = ^[ ]*:copy-in-global-log:[ ]* +# A command that, given a newline-separated list of test names on the +# standard input, print the name of the tests that are to be re-run +# upon "make recheck". +am__list_recheck_tests = $(AWK) '{ \ + recheck = 1; \ + while ((rc = (getline line < ($$0 ".trs"))) != 0) \ + { \ + if (rc < 0) \ + { \ + if ((getline line2 < ($$0 ".log")) < 0) \ + recheck = 0; \ + break; \ + } \ + else if (line ~ /$(am__recheck_rx)[nN][Oo]/) \ + { \ + recheck = 0; \ + break; \ + } \ + else if (line ~ /$(am__recheck_rx)[yY][eE][sS]/) \ + { \ + break; \ + } \ + }; \ + if (recheck) \ + print $$0; \ + close ($$0 ".trs"); \ + close ($$0 ".log"); \ +}' +# A command that, given a newline-separated list of test names on the +# standard input, create the global log from their .trs and .log files. +am__create_global_log = $(AWK) ' \ +function fatal(msg) \ +{ \ + print "fatal: making $@: " msg | "cat >&2"; \ + exit 1; \ +} \ +function rst_section(header) \ +{ \ + print header; \ + len = length(header); \ + for (i = 1; i <= len; i = i + 1) \ + printf "="; \ + printf "\n\n"; \ +} \ +{ \ + copy_in_global_log = 1; \ + global_test_result = "RUN"; \ + while ((rc = (getline line < ($$0 ".trs"))) != 0) \ + { \ + if (rc < 0) \ + fatal("failed to read from " $$0 ".trs"); \ + if (line ~ /$(am__global_test_result_rx)/) \ + { \ + sub("$(am__global_test_result_rx)", "", line); \ + sub("[ ]*$$", "", line); \ + global_test_result = line; \ + } \ + else if (line ~ /$(am__copy_in_global_log_rx)[nN][oO]/) \ + copy_in_global_log = 0; \ + }; \ + if (copy_in_global_log) \ + { \ + rst_section(global_test_result ": " $$0); \ + while ((rc = (getline line < ($$0 ".log"))) != 0) \ + { \ + if (rc < 0) \ + fatal("failed to read from " $$0 ".log"); \ + print line; \ + }; \ + printf "\n"; \ + }; \ + close ($$0 ".trs"); \ + close ($$0 ".log"); \ +}' +# Restructured Text title. +am__rst_title = { sed 's/.*/ & /;h;s/./=/g;p;x;s/ *$$//;p;g' && echo; } +# Solaris 10 'make', and several other traditional 'make' implementations, +# pass "-e" to $(SHELL), and POSIX 2008 even requires this. Work around it +# by disabling -e (using the XSI extension "set +e") if it's set. +am__sh_e_setup = case $$- in *e*) set +e;; esac +# Default flags passed to test drivers. +am__common_driver_flags = \ + --color-tests "$$am__color_tests" \ + --enable-hard-errors "$$am__enable_hard_errors" \ + --expect-failure "$$am__expect_failure" +# To be inserted before the command running the test. Creates the +# directory for the log if needed. Stores in $dir the directory +# containing $f, in $tst the test, in $log the log. Executes the +# developer- defined test setup AM_TESTS_ENVIRONMENT (if any), and +# passes TESTS_ENVIRONMENT. Set up options for the wrapper that +# will run the test scripts (or their associated LOG_COMPILER, if +# thy have one). +am__check_pre = \ +$(am__sh_e_setup); \ +$(am__vpath_adj_setup) $(am__vpath_adj) \ +$(am__tty_colors); \ +srcdir=$(srcdir); export srcdir; \ +case "$@" in \ + */*) am__odir=`echo "./$@" | sed 's|/[^/]*$$||'`;; \ + *) am__odir=.;; \ +esac; \ +test "x$$am__odir" = x"." || test -d "$$am__odir" \ + || $(MKDIR_P) "$$am__odir" || exit $$?; \ +if test -f "./$$f"; then dir=./; \ +elif test -f "$$f"; then dir=; \ +else dir="$(srcdir)/"; fi; \ +tst=$$dir$$f; log='$@'; \ +if test -n '$(DISABLE_HARD_ERRORS)'; then \ + am__enable_hard_errors=no; \ +else \ + am__enable_hard_errors=yes; \ +fi; \ +case " $(XFAIL_TESTS) " in \ + *[\ \ ]$$f[\ \ ]* | *[\ \ ]$$dir$$f[\ \ ]*) \ + am__expect_failure=yes;; \ + *) \ + am__expect_failure=no;; \ +esac; \ +$(AM_TESTS_ENVIRONMENT) $(TESTS_ENVIRONMENT) +# A shell command to get the names of the tests scripts with any registered +# extension removed (i.e., equivalently, the names of the test logs, with +# the '.log' extension removed). The result is saved in the shell variable +# '$bases'. This honors runtime overriding of TESTS and TEST_LOGS. Sadly, +# we cannot use something simpler, involving e.g., "$(TEST_LOGS:.log=)", +# since that might cause problem with VPATH rewrites for suffix-less tests. +# See also 'test-harness-vpath-rewrite.sh' and 'test-trs-basic.sh'. +am__set_TESTS_bases = \ + bases='$(TEST_LOGS)'; \ + bases=`for i in $$bases; do echo $$i; done | sed 's/\.log$$//'`; \ + bases=`echo $$bases` +RECHECK_LOGS = $(TEST_LOGS) +AM_RECURSIVE_TARGETS = check recheck +TEST_SUITE_LOG = test-suite.log +TEST_EXTENSIONS = @EXEEXT@ .test +LOG_DRIVER = $(SHELL) $(top_srcdir)/test-driver +LOG_COMPILE = $(LOG_COMPILER) $(AM_LOG_FLAGS) $(LOG_FLAGS) +am__set_b = \ + case '$@' in \ + */*) \ + case '$*' in \ + */*) b='$*';; \ + *) b=`echo '$@' | sed 's/\.log$$//'`; \ + esac;; \ + *) \ + b='$*';; \ + esac +am__test_logs1 = $(TESTS:=.log) +am__test_logs2 = $(am__test_logs1:@EXEEXT@.log=.log) +TEST_LOGS = $(am__test_logs2:.test.log=.log) +TEST_LOG_DRIVER = $(SHELL) $(top_srcdir)/test-driver +TEST_LOG_COMPILE = $(TEST_LOG_COMPILER) $(AM_TEST_LOG_FLAGS) \ + $(TEST_LOG_FLAGS) DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ +AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ @@ -99,6 +402,7 @@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ +CRYPTO_LIBS = @CRYPTO_LIBS@ CRYPT_LIBS = @CRYPT_LIBS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ @@ -204,19 +508,19 @@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ -INCLUDES = -I$(top_srcdir)/include -I$(top_srcdir)/lib +AM_CPPFLAGS = -I$(top_srcdir)/include -I$(top_srcdir)/lib/libpam noinst_HEADERS = t.h # libt - common support code check_LIBRARIES = libt.a -libt_a_SOURCES = t_main.c +libt_a_SOURCES = t_main.c t_file.c # link with libpam and libt -LDADD = libt.a $(top_builddir)/lib/libpam.la +LDADD = libt.a $(top_builddir)/lib/libpam/libpam.la all: all-am .SUFFIXES: -.SUFFIXES: .c .lo .o .obj +.SUFFIXES: .c .lo .log .o .obj .test .test$(EXEEXT) .trs $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ @@ -250,10 +554,11 @@ $(am__aclocal_m4_deps): clean-checkLIBRARIES: -test -z "$(check_LIBRARIES)" || rm -f $(check_LIBRARIES) -libt.a: $(libt_a_OBJECTS) $(libt_a_DEPENDENCIES) - -rm -f libt.a - $(libt_a_AR) libt.a $(libt_a_OBJECTS) $(libt_a_LIBADD) - $(RANLIB) libt.a + +libt.a: $(libt_a_OBJECTS) $(libt_a_DEPENDENCIES) $(EXTRA_libt_a_DEPENDENCIES) + $(AM_V_at)-rm -f libt.a + $(AM_V_AR)$(libt_a_AR) libt.a $(libt_a_OBJECTS) $(libt_a_LIBADD) + $(AM_V_at)$(RANLIB) libt.a clean-checkPROGRAMS: @list='$(check_PROGRAMS)'; test -n "$$list" || exit 0; \ @@ -263,12 +568,14 @@ clean-checkPROGRAMS: list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \ echo " rm -f" $$list; \ rm -f $$list -t_openpam_readlinev$(EXEEXT): $(t_openpam_readlinev_OBJECTS) $(t_openpam_readlinev_DEPENDENCIES) + +t_openpam_readlinev$(EXEEXT): $(t_openpam_readlinev_OBJECTS) $(t_openpam_readlinev_DEPENDENCIES) $(EXTRA_t_openpam_readlinev_DEPENDENCIES) @rm -f t_openpam_readlinev$(EXEEXT) - $(LINK) $(t_openpam_readlinev_OBJECTS) $(t_openpam_readlinev_LDADD) $(LIBS) -t_openpam_readword$(EXEEXT): $(t_openpam_readword_OBJECTS) $(t_openpam_readword_DEPENDENCIES) + $(AM_V_CCLD)$(LINK) $(t_openpam_readlinev_OBJECTS) $(t_openpam_readlinev_LDADD) $(LIBS) + +t_openpam_readword$(EXEEXT): $(t_openpam_readword_OBJECTS) $(t_openpam_readword_DEPENDENCIES) $(EXTRA_t_openpam_readword_DEPENDENCIES) @rm -f t_openpam_readword$(EXEEXT) - $(LINK) $(t_openpam_readword_OBJECTS) $(t_openpam_readword_LDADD) $(LIBS) + $(AM_V_CCLD)$(LINK) $(t_openpam_readword_OBJECTS) $(t_openpam_readword_LDADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) @@ -276,30 +583,31 @@ mostlyclean-compile: distclean-compile: -rm -f *.tab.c +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/t_file.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/t_main.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/t_openpam_readlinev.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/t_openpam_readword.Po@am__quote@ .c.o: -@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(COMPILE) -c $< +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< .c.obj: -@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'` +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` .c.lo: -@am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $< +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< mostlyclean-libtool: -rm -f *.lo @@ -307,26 +615,15 @@ mostlyclean-libtool: clean-libtool: -rm -rf .libs _libs -ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) - list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ - unique=`for i in $$list; do \ - if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ - done | \ - $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ - END { if (nonempty) { for (i in files) print i; }; }'`; \ - mkid -fID $$unique -tags: TAGS +ID: $(am__tagged_files) + $(am__define_uniq_tagged_files); mkid -fID $$unique +tags: tags-am +TAGS: tags -TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ - $(TAGS_FILES) $(LISP) +tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ - list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ - unique=`for i in $$list; do \ - if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ - done | \ - $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ - END { if (nonempty) { for (i in files) print i; }; }'`; \ + $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ @@ -338,15 +635,11 @@ TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $$unique; \ fi; \ fi -ctags: CTAGS -CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ - $(TAGS_FILES) $(LISP) - list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ - unique=`for i in $$list; do \ - if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ - done | \ - $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ - END { if (nonempty) { for (i in files) print i; }; }'`; \ +ctags: ctags-am + +CTAGS: ctags +ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique @@ -355,101 +648,194 @@ GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" +cscopelist: cscopelist-am + +cscopelist-am: $(am__tagged_files) + list='$(am__tagged_files)'; \ + case "$(srcdir)" in \ + [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ + *) sdir=$(subdir)/$(srcdir) ;; \ + esac; \ + for i in $$list; do \ + if test -f "$$i"; then \ + echo "$(subdir)/$$i"; \ + else \ + echo "$$sdir/$$i"; \ + fi; \ + done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags -check-TESTS: $(TESTS) - @failed=0; all=0; xfail=0; xpass=0; skip=0; \ - srcdir=$(srcdir); export srcdir; \ - list=' $(TESTS) '; \ - $(am__tty_colors); \ - if test -n "$$list"; then \ - for tst in $$list; do \ - if test -f ./$$tst; then dir=./; \ - elif test -f $$tst; then dir=; \ - else dir="$(srcdir)/"; fi; \ - if $(TESTS_ENVIRONMENT) $${dir}$$tst; then \ - all=`expr $$all + 1`; \ - case " $(XFAIL_TESTS) " in \ - *[\ \ ]$$tst[\ \ ]*) \ - xpass=`expr $$xpass + 1`; \ - failed=`expr $$failed + 1`; \ - col=$$red; res=XPASS; \ - ;; \ - *) \ - col=$$grn; res=PASS; \ - ;; \ - esac; \ - elif test $$? -ne 77; then \ - all=`expr $$all + 1`; \ - case " $(XFAIL_TESTS) " in \ - *[\ \ ]$$tst[\ \ ]*) \ - xfail=`expr $$xfail + 1`; \ - col=$$lgn; res=XFAIL; \ - ;; \ - *) \ - failed=`expr $$failed + 1`; \ - col=$$red; res=FAIL; \ - ;; \ - esac; \ - else \ - skip=`expr $$skip + 1`; \ - col=$$blu; res=SKIP; \ - fi; \ - echo "$${col}$$res$${std}: $$tst"; \ +# Recover from deleted '.trs' file; this should ensure that +# "rm -f foo.log; make foo.trs" re-run 'foo.test', and re-create +# both 'foo.log' and 'foo.trs'. Break the recipe in two subshells +# to avoid problems with "make -n". +.log.trs: + rm -f $< $@ + $(MAKE) $(AM_MAKEFLAGS) $< + +# Leading 'am--fnord' is there to ensure the list of targets does not +# expand to empty, as could happen e.g. with make check TESTS=''. +am--fnord $(TEST_LOGS) $(TEST_LOGS:.log=.trs): $(am__force_recheck) +am--force-recheck: + @: + +$(TEST_SUITE_LOG): $(TEST_LOGS) + @$(am__set_TESTS_bases); \ + am__f_ok () { test -f "$$1" && test -r "$$1"; }; \ + redo_bases=`for i in $$bases; do \ + am__f_ok $$i.trs && am__f_ok $$i.log || echo $$i; \ + done`; \ + if test -n "$$redo_bases"; then \ + redo_logs=`for i in $$redo_bases; do echo $$i.log; done`; \ + redo_results=`for i in $$redo_bases; do echo $$i.trs; done`; \ + if $(am__make_dryrun); then :; else \ + rm -f $$redo_logs && rm -f $$redo_results || exit 1; \ + fi; \ + fi; \ + if test -n "$$am__remaking_logs"; then \ + echo "fatal: making $(TEST_SUITE_LOG): possible infinite" \ + "recursion detected" >&2; \ + else \ + am__remaking_logs=yes $(MAKE) $(AM_MAKEFLAGS) $$redo_logs; \ + fi; \ + if $(am__make_dryrun); then :; else \ + st=0; \ + errmsg="fatal: making $(TEST_SUITE_LOG): failed to create"; \ + for i in $$redo_bases; do \ + test -f $$i.trs && test -r $$i.trs \ + || { echo "$$errmsg $$i.trs" >&2; st=1; }; \ + test -f $$i.log && test -r $$i.log \ + || { echo "$$errmsg $$i.log" >&2; st=1; }; \ done; \ - if test "$$all" -eq 1; then \ - tests="test"; \ - All=""; \ - else \ - tests="tests"; \ - All="All "; \ - fi; \ - if test "$$failed" -eq 0; then \ - if test "$$xfail" -eq 0; then \ - banner="$$All$$all $$tests passed"; \ + test $$st -eq 0 || exit 1; \ + fi + @$(am__sh_e_setup); $(am__tty_colors); $(am__set_TESTS_bases); \ + ws='[ ]'; \ + results=`for b in $$bases; do echo $$b.trs; done`; \ + test -n "$$results" || results=/dev/null; \ + all=` grep "^$$ws*:test-result:" $$results | wc -l`; \ + pass=` grep "^$$ws*:test-result:$$ws*PASS" $$results | wc -l`; \ + fail=` grep "^$$ws*:test-result:$$ws*FAIL" $$results | wc -l`; \ + skip=` grep "^$$ws*:test-result:$$ws*SKIP" $$results | wc -l`; \ + xfail=`grep "^$$ws*:test-result:$$ws*XFAIL" $$results | wc -l`; \ + xpass=`grep "^$$ws*:test-result:$$ws*XPASS" $$results | wc -l`; \ + error=`grep "^$$ws*:test-result:$$ws*ERROR" $$results | wc -l`; \ + if test `expr $$fail + $$xpass + $$error` -eq 0; then \ + success=true; \ + else \ + success=false; \ + fi; \ + br='==================='; br=$$br$$br$$br$$br; \ + result_count () \ + { \ + if test x"$$1" = x"--maybe-color"; then \ + maybe_colorize=yes; \ + elif test x"$$1" = x"--no-color"; then \ + maybe_colorize=no; \ else \ - if test "$$xfail" -eq 1; then failures=failure; else failures=failures; fi; \ - banner="$$All$$all $$tests behaved as expected ($$xfail expected $$failures)"; \ + echo "$@: invalid 'result_count' usage" >&2; exit 4; \ fi; \ - else \ - if test "$$xpass" -eq 0; then \ - banner="$$failed of $$all $$tests failed"; \ + shift; \ + desc=$$1 count=$$2; \ + if test $$maybe_colorize = yes && test $$count -gt 0; then \ + color_start=$$3 color_end=$$std; \ else \ - if test "$$xpass" -eq 1; then passes=pass; else passes=passes; fi; \ - banner="$$failed of $$all $$tests did not behave as expected ($$xpass unexpected $$passes)"; \ + color_start= color_end=; \ fi; \ - fi; \ - dashes="$$banner"; \ - skipped=""; \ - if test "$$skip" -ne 0; then \ - if test "$$skip" -eq 1; then \ - skipped="($$skip test was not run)"; \ - else \ - skipped="($$skip tests were not run)"; \ - fi; \ - test `echo "$$skipped" | wc -c` -le `echo "$$banner" | wc -c` || \ - dashes="$$skipped"; \ - fi; \ - report=""; \ - if test "$$failed" -ne 0 && test -n "$(PACKAGE_BUGREPORT)"; then \ - report="Please report to $(PACKAGE_BUGREPORT)"; \ - test `echo "$$report" | wc -c` -le `echo "$$banner" | wc -c` || \ - dashes="$$report"; \ - fi; \ - dashes=`echo "$$dashes" | sed s/./=/g`; \ - if test "$$failed" -eq 0; then \ - echo "$$grn$$dashes"; \ - else \ - echo "$$red$$dashes"; \ - fi; \ - echo "$$banner"; \ - test -z "$$skipped" || echo "$$skipped"; \ - test -z "$$report" || echo "$$report"; \ - echo "$$dashes$$std"; \ - test "$$failed" -eq 0; \ - else :; fi + echo "$${color_start}# $$desc $$count$${color_end}"; \ + }; \ + create_testsuite_report () \ + { \ + result_count $$1 "TOTAL:" $$all "$$brg"; \ + result_count $$1 "PASS: " $$pass "$$grn"; \ + result_count $$1 "SKIP: " $$skip "$$blu"; \ + result_count $$1 "XFAIL:" $$xfail "$$lgn"; \ + result_count $$1 "FAIL: " $$fail "$$red"; \ + result_count $$1 "XPASS:" $$xpass "$$red"; \ + result_count $$1 "ERROR:" $$error "$$mgn"; \ + }; \ + { \ + echo "$(PACKAGE_STRING): $(subdir)/$(TEST_SUITE_LOG)" | \ + $(am__rst_title); \ + create_testsuite_report --no-color; \ + echo; \ + echo ".. contents:: :depth: 2"; \ + echo; \ + for b in $$bases; do echo $$b; done \ + | $(am__create_global_log); \ + } >$(TEST_SUITE_LOG).tmp || exit 1; \ + mv $(TEST_SUITE_LOG).tmp $(TEST_SUITE_LOG); \ + if $$success; then \ + col="$$grn"; \ + else \ + col="$$red"; \ + test x"$$VERBOSE" = x || cat $(TEST_SUITE_LOG); \ + fi; \ + echo "$${col}$$br$${std}"; \ + echo "$${col}Testsuite summary for $(PACKAGE_STRING)$${std}"; \ + echo "$${col}$$br$${std}"; \ + create_testsuite_report --maybe-color; \ + echo "$$col$$br$$std"; \ + if $$success; then :; else \ + echo "$${col}See $(subdir)/$(TEST_SUITE_LOG)$${std}"; \ + if test -n "$(PACKAGE_BUGREPORT)"; then \ + echo "$${col}Please report to $(PACKAGE_BUGREPORT)$${std}"; \ + fi; \ + echo "$$col$$br$$std"; \ + fi; \ + $$success || exit 1 + +check-TESTS: + @list='$(RECHECK_LOGS)'; test -z "$$list" || rm -f $$list + @list='$(RECHECK_LOGS:.log=.trs)'; test -z "$$list" || rm -f $$list + @test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG) + @set +e; $(am__set_TESTS_bases); \ + log_list=`for i in $$bases; do echo $$i.log; done`; \ + trs_list=`for i in $$bases; do echo $$i.trs; done`; \ + log_list=`echo $$log_list`; trs_list=`echo $$trs_list`; \ + $(MAKE) $(AM_MAKEFLAGS) $(TEST_SUITE_LOG) TEST_LOGS="$$log_list"; \ + exit $$?; +recheck: all $(check_LIBRARIES) $(check_PROGRAMS) + @test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG) + @set +e; $(am__set_TESTS_bases); \ + bases=`for i in $$bases; do echo $$i; done \ + | $(am__list_recheck_tests)` || exit 1; \ + log_list=`for i in $$bases; do echo $$i.log; done`; \ + log_list=`echo $$log_list`; \ + $(MAKE) $(AM_MAKEFLAGS) $(TEST_SUITE_LOG) \ + am__force_recheck=am--force-recheck \ + TEST_LOGS="$$log_list"; \ + exit $$? +t_openpam_readword.log: t_openpam_readword$(EXEEXT) + @p='t_openpam_readword$(EXEEXT)'; \ + b='t_openpam_readword'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +t_openpam_readlinev.log: t_openpam_readlinev$(EXEEXT) + @p='t_openpam_readlinev$(EXEEXT)'; \ + b='t_openpam_readlinev'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +.test.log: + @p='$<'; \ + $(am__set_b); \ + $(am__check_pre) $(TEST_LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_TEST_LOG_DRIVER_FLAGS) $(TEST_LOG_DRIVER_FLAGS) -- $(TEST_LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +@am__EXEEXT_TRUE@.test$(EXEEXT).log: +@am__EXEEXT_TRUE@ @p='$<'; \ +@am__EXEEXT_TRUE@ $(am__set_b); \ +@am__EXEEXT_TRUE@ $(am__check_pre) $(TEST_LOG_DRIVER) --test-name "$$f" \ +@am__EXEEXT_TRUE@ --log-file $$b.log --trs-file $$b.trs \ +@am__EXEEXT_TRUE@ $(am__common_driver_flags) $(AM_TEST_LOG_DRIVER_FLAGS) $(TEST_LOG_DRIVER_FLAGS) -- $(TEST_LOG_COMPILE) \ +@am__EXEEXT_TRUE@ "$$tst" $(AM_TESTS_FD_REDIRECT) distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ @@ -497,11 +883,19 @@ install-am: all-am installcheck: installcheck-am install-strip: - $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ - install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ - `test -z '$(STRIP)' || \ - echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install + if test -z '$(STRIP)'; then \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + install; \ + else \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ + fi mostlyclean-generic: + -test -z "$(TEST_LOGS)" || rm -f $(TEST_LOGS) + -test -z "$(TEST_LOGS:.log=.trs)" || rm -f $(TEST_LOGS:.log=.trs) + -test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG) clean-generic: @@ -585,19 +979,20 @@ uninstall-am: .MAKE: check-am install-am install-strip -.PHONY: CTAGS GTAGS all all-am check check-TESTS check-am clean \ +.PHONY: CTAGS GTAGS TAGS all all-am check check-TESTS check-am clean \ clean-checkLIBRARIES clean-checkPROGRAMS clean-generic \ - clean-libtool ctags distclean distclean-compile \ - distclean-generic distclean-libtool distclean-tags distdir dvi \ - dvi-am html html-am info info-am install install-am \ - install-data install-data-am install-dvi install-dvi-am \ - install-exec install-exec-am install-html install-html-am \ - install-info install-info-am install-man install-pdf \ - install-pdf-am install-ps install-ps-am install-strip \ - installcheck installcheck-am installdirs maintainer-clean \ - maintainer-clean-generic mostlyclean mostlyclean-compile \ - mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ - tags uninstall uninstall-am + clean-libtool cscopelist-am ctags ctags-am distclean \ + distclean-compile distclean-generic distclean-libtool \ + distclean-tags distdir dvi dvi-am html html-am info info-am \ + install install-am install-data install-data-am install-dvi \ + install-dvi-am install-exec install-exec-am install-html \ + install-html-am install-info install-info-am install-man \ + install-pdf install-pdf-am install-ps install-ps-am \ + install-strip installcheck installcheck-am installdirs \ + maintainer-clean maintainer-clean-generic mostlyclean \ + mostlyclean-compile mostlyclean-generic mostlyclean-libtool \ + pdf pdf-am ps ps-am recheck tags tags-am uninstall \ + uninstall-am # Tell versions [3.59,3.63) of GNU make to not export all variables. diff --git a/contrib/openpam/t/t.h b/contrib/openpam/t/t.h index 4805b76af092..1e156bd03e76 100644 --- a/contrib/openpam/t/t.h +++ b/contrib/openpam/t/t.h @@ -6,8 +6,7 @@ * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer - * in this position and unchanged. + * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. @@ -27,7 +26,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: t.h 578 2012-04-06 00:45:59Z des $ + * $Id: t.h 657 2013-03-06 22:59:05Z des $ */ #ifndef T_H_INCLUDED @@ -36,15 +35,22 @@ #include struct t_test { - int (*func)(void); + int (*func)(void *); const char *desc; + void *arg; }; #define T_FUNC(n, d) \ - static int t_ ## n ## _func(void); \ + static int t_ ## n ## _func(void *); \ static const struct t_test t_ ## n = \ - { t_ ## n ## _func, d }; \ - static int t_ ## n ## _func(void) + { t_ ## n ## _func, d, NULL }; \ + static int t_ ## n ## _func(OPENPAM_UNUSED(void *arg)) + +#define T_FUNC_ARG(n, d, a) \ + static int t_ ## n ## _func(void *); \ + static const struct t_test t_ ## n = \ + { t_ ## n ## _func, d, a }; \ + static int t_ ## n ## _func(void *arg) #define T(n) \ &t_ ## n @@ -57,4 +63,21 @@ void t_cleanup(void); void t_verbose(const char *, ...) OPENPAM_FORMAT((__printf__, 1, 2)); +/* + * Convenience functions for temp files + */ +struct t_file { + char *name; + FILE *file; + struct t_file *prev, *next; +}; + +struct t_file *t_fopen(const char *); +int t_fprintf(struct t_file *, const char *, ...); +int t_ferror(struct t_file *); +int t_feof(struct t_file *); +void t_frewind(struct t_file *); +void t_fclose(struct t_file *); +void t_fcloseall(void); + #endif diff --git a/contrib/openpam/t/t_file.c b/contrib/openpam/t/t_file.c new file mode 100644 index 000000000000..8de4f9786c0d --- /dev/null +++ b/contrib/openpam/t/t_file.c @@ -0,0 +1,160 @@ +/*- + * Copyright (c) 2012 Dag-Erling Smørgrav + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote + * products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $Id: t_file.c 648 2013-03-05 17:54:27Z des $ + */ + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "openpam_asprintf.h" + +#include "t.h" + +static struct t_file *tflist; + +/* + * Open a temp file. + */ +struct t_file * +t_fopen(const char *filename) +{ + struct t_file *tf; + int fd; + + if ((tf = calloc(sizeof *tf, 1)) == NULL) + err(1, "%s(): calloc()", __func__); + if (filename) { + if ((tf->name = strdup(filename)) == NULL) + err(1, "%s(): strdup()", __func__); + } else { + asprintf(&tf->name, "%s.%lu.%p.tmp", + t_progname, (unsigned long)getpid(), (void *)tf); + if (tf->name == NULL) + err(1, "%s(): asprintf()", __func__); + } + if ((fd = open(tf->name, O_RDWR|O_CREAT|O_TRUNC, 0600)) < 0) + err(1, "%s(): %s", __func__, tf->name); + if ((tf->file = fdopen(fd, "r+")) == NULL) + err(1, "%s(): fdopen()", __func__); + if ((tf->next = tflist) != NULL) + tf->next->prev = tf; + tflist = tf; + return (tf); +} + +/* + * Write text to the temp file. + */ +int +t_fprintf(struct t_file *tf, const char *fmt, ...) +{ + va_list ap; + int len; + + va_start(ap, fmt); + len = vfprintf(tf->file, fmt, ap); + va_end(ap); + if (ferror(tf->file)) + err(1, "%s(): vfprintf()", __func__); + return (len); +} + +/* + * Rewind the temp file. + */ +void +t_frewind(struct t_file *tf) +{ + + errno = 0; + rewind(tf->file); + if (errno != 0) + err(1, "%s(): rewind()", __func__); +} + +/* + * Return non-zero if an error occurred. + */ +int +t_ferror(struct t_file *tf) +{ + + return (ferror(tf->file)); +} + +/* + * Return non-zero if the end of the file was reached. + */ +int +t_feof(struct t_file *tf) +{ + + return (feof(tf->file)); +} + +/* + * Close a temp file. + */ +void +t_fclose(struct t_file *tf) +{ + + if (tf == tflist) + tflist = tf->next; + if (tf->prev) + tf->prev->next = tf->next; + if (tf->next) + tf->next->prev = tf->prev; + fclose(tf->file); + if (unlink(tf->name) < 0) + warn("%s(): unlink()", __func__); + free(tf->name); + free(tf); +} + +/* + * atexit() function to close all remaining files. + */ +void +t_fcloseall(void) +{ + + while (tflist) + t_fclose(tflist); +} diff --git a/contrib/openpam/t/t_main.c b/contrib/openpam/t/t_main.c index 6a29b0a4fda6..a0bbdda5713c 100644 --- a/contrib/openpam/t/t_main.c +++ b/contrib/openpam/t/t_main.c @@ -6,8 +6,7 @@ * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer - * in this position and unchanged. + * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. @@ -27,7 +26,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: t_main.c 578 2012-04-06 00:45:59Z des $ + * $Id: t_main.c 651 2013-03-05 18:11:59Z des $ */ #ifdef HAVE_CONFIG_H @@ -39,6 +38,7 @@ #include #include #include +#include #include #include "t.h" @@ -63,7 +63,7 @@ static void usage(void) { - fprintf(stderr, "usage: [-v] %s\n", t_progname); + fprintf(stderr, "usage: %s [-v]\n", t_progname); exit(1); } @@ -75,6 +75,14 @@ main(int argc, char *argv[]) int n, pass, fail; int opt; +#ifdef HAVE_SETLOGMASK + /* suppress openpam_log() */ + setlogmask(LOG_UPTO(0)); +#endif + + /* clean up temp files in case of premature exit */ + atexit(t_fcloseall); + if ((t_progname = strrchr(argv[0], '/')) != NULL) t_progname++; /* one past the slash */ else @@ -104,7 +112,7 @@ main(int argc, char *argv[]) /* run the tests */ for (n = pass = fail = 0; t_plan[n] != NULL; ++n) { desc = t_plan[n]->desc ? t_plan[n]->desc : "no description"; - if ((*t_plan[n]->func)()) { + if ((*t_plan[n]->func)(t_plan[n]->arg)) { printf("ok %d - %s\n", n + 1, desc); ++pass; } else { diff --git a/contrib/openpam/t/t_openpam_readlinev.c b/contrib/openpam/t/t_openpam_readlinev.c index bb0ff90089e1..59f2b1071532 100644 --- a/contrib/openpam/t/t_openpam_readlinev.c +++ b/contrib/openpam/t/t_openpam_readlinev.c @@ -6,8 +6,7 @@ * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer - * in this position and unchanged. + * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. @@ -27,7 +26,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: t_openpam_readlinev.c 581 2012-04-06 01:08:37Z des $ + * $Id: t_openpam_readlinev.c 648 2013-03-05 17:54:27Z des $ */ #ifdef HAVE_CONFIG_H @@ -35,12 +34,9 @@ #endif #include -#include -#include #include #include #include -#include #include #include @@ -48,54 +44,6 @@ #include "openpam_impl.h" #include "t.h" -static char filename[1024]; -static FILE *f; - -/* - * Open the temp file and immediately unlink it so it doesn't leak in case - * of premature exit. - */ -static void -orlv_open(void) -{ - int fd; - - if ((fd = open(filename, O_RDWR|O_CREAT|O_TRUNC, 0600)) < 0) - err(1, "%s(): %s", __func__, filename); - if ((f = fdopen(fd, "r+")) == NULL) - err(1, "%s(): %s", __func__, filename); - if (unlink(filename) < 0) - err(1, "%s(): %s", __func__, filename); -} - -/* - * Write text to the temp file. - */ -static void -orlv_output(const char *fmt, ...) -{ - va_list ap; - - va_start(ap, fmt); - vfprintf(f, fmt, ap); - va_end(ap); - if (ferror(f)) - err(1, "%s", filename); -} - -/* - * Rewind the temp file. - */ -static void -orlv_rewind(void) -{ - - errno = 0; - rewind(f); - if (errno != 0) - err(1, "%s(): %s", __func__, filename); -} - /* * Read a line from the temp file and verify that the result matches our * expectations: whether a line was read at all, how many and which words @@ -103,7 +51,7 @@ orlv_rewind(void) * newlines) and whether we reached the end of the file. */ static int -orlv_expect(const char **expectedv, int lines, int eof) +orlv_expect(struct t_file *tf, const char **expectedv, int lines, int eof) { int expectedc, gotc, i, lineno = 0; char **gotv; @@ -112,9 +60,9 @@ orlv_expect(const char **expectedv, int lines, int eof) if (expectedv != NULL) while (expectedv[expectedc] != NULL) ++expectedc; - gotv = openpam_readlinev(f, &lineno, &gotc); - if (ferror(f)) - err(1, "%s(): %s", __func__, filename); + gotv = openpam_readlinev(tf->file, &lineno, &gotc); + if (t_ferror(tf)) + err(1, "%s(): %s", __func__, tf->name); if (expectedv != NULL && gotv == NULL) { t_verbose("expected %d words, got nothing\n", expectedc); return (0); @@ -146,28 +94,17 @@ orlv_expect(const char **expectedv, int lines, int eof) lines, lineno); return (0); } - if (eof && !feof(f)) { + if (eof && !t_feof(tf)) { t_verbose("expected EOF, but didn't get it\n"); return (0); } - if (!eof && feof(f)) { + if (!eof && t_feof(tf)) { t_verbose("didn't expect EOF, but got it anyway\n"); return (0); } return (1); } -/* - * Close the temp file. - */ -void -orlv_close(void) -{ - - if (fclose(f) != 0) - err(1, "%s(): %s", __func__, filename); - f = NULL; -} /*************************************************************************** * Commonly-used lines @@ -195,71 +132,77 @@ static const char *hello_world[] = { T_FUNC(empty_input, "empty input") { + struct t_file *tf; int ret; - orlv_open(); - ret = orlv_expect(NULL, 0 /*lines*/, 1 /*eof*/); - orlv_close(); + tf = t_fopen(NULL); + ret = orlv_expect(tf, NULL, 0 /*lines*/, 1 /*eof*/); + t_fclose(tf); return (ret); } T_FUNC(empty_line, "empty line") { + struct t_file *tf; int ret; - orlv_open(); - orlv_output("\n"); - orlv_rewind(); - ret = orlv_expect(empty, 1 /*lines*/, 0 /*eof*/); - orlv_close(); + tf = t_fopen(NULL); + t_fprintf(tf, "\n"); + t_frewind(tf); + ret = orlv_expect(tf, empty, 1 /*lines*/, 0 /*eof*/); + t_fclose(tf); return (ret); } T_FUNC(unterminated_empty_line, "unterminated empty line") { + struct t_file *tf; int ret; - orlv_open(); - orlv_output(" "); - orlv_rewind(); - ret = orlv_expect(NULL, 0 /*lines*/, 1 /*eof*/); - orlv_close(); + tf = t_fopen(NULL); + t_fprintf(tf, " "); + t_frewind(tf); + ret = orlv_expect(tf, NULL, 0 /*lines*/, 1 /*eof*/); + t_fclose(tf); return (ret); } T_FUNC(whitespace, "whitespace") { + struct t_file *tf; int ret; - orlv_open(); - orlv_output(" \n"); - orlv_rewind(); - ret = orlv_expect(empty, 1 /*lines*/, 0 /*eof*/); - orlv_close(); + tf = t_fopen(NULL); + t_fprintf(tf, " \n"); + t_frewind(tf); + ret = orlv_expect(tf, empty, 1 /*lines*/, 0 /*eof*/); + t_fclose(tf); return (ret); } T_FUNC(comment, "comment") { + struct t_file *tf; int ret; - orlv_open(); - orlv_output("# comment\n"); - orlv_rewind(); - ret = orlv_expect(empty, 1 /*lines*/, 0 /*eof*/); - orlv_close(); + tf = t_fopen(NULL); + t_fprintf(tf, "# comment\n"); + t_frewind(tf); + ret = orlv_expect(tf, empty, 1 /*lines*/, 0 /*eof*/); + t_fclose(tf); return (ret); } T_FUNC(whitespace_before_comment, "whitespace before comment") { + struct t_file *tf; int ret; - orlv_open(); - orlv_output(" # comment\n"); - orlv_rewind(); - ret = orlv_expect(empty, 1 /*lines*/, 0 /*eof*/); - orlv_close(); + tf = t_fopen(NULL); + t_fprintf(tf, " # comment\n"); + t_frewind(tf); + ret = orlv_expect(tf, empty, 1 /*lines*/, 0 /*eof*/); + t_fclose(tf); return (ret); } @@ -270,37 +213,40 @@ T_FUNC(whitespace_before_comment, "whitespace before comment") T_FUNC(one_word, "one word") { + struct t_file *tf; int ret; - orlv_open(); - orlv_output("hello\n"); - orlv_rewind(); - ret = orlv_expect(hello, 1 /*lines*/, 0 /*eof*/); - orlv_close(); + tf = t_fopen(NULL); + t_fprintf(tf, "hello\n"); + t_frewind(tf); + ret = orlv_expect(tf, hello, 1 /*lines*/, 0 /*eof*/); + t_fclose(tf); return (ret); } T_FUNC(two_words, "two words") { + struct t_file *tf; int ret; - orlv_open(); - orlv_output("hello world\n"); - orlv_rewind(); - ret = orlv_expect(hello_world, 1 /*lines*/, 0 /*eof*/); - orlv_close(); + tf = t_fopen(NULL); + t_fprintf(tf, "hello world\n"); + t_frewind(tf); + ret = orlv_expect(tf, hello_world, 1 /*lines*/, 0 /*eof*/); + t_fclose(tf); return (ret); } T_FUNC(unterminated_line, "unterminated line") { + struct t_file *tf; int ret; - orlv_open(); - orlv_output("hello world"); - orlv_rewind(); - ret = orlv_expect(hello_world, 0 /*lines*/, 1 /*eof*/); - orlv_close(); + tf = t_fopen(NULL); + t_fprintf(tf, "hello world"); + t_frewind(tf); + ret = orlv_expect(tf, hello_world, 0 /*lines*/, 1 /*eof*/); + t_fclose(tf); return (ret); } @@ -330,9 +276,6 @@ t_prepare(int argc, char *argv[]) (void)argc; (void)argv; - snprintf(filename, sizeof filename, "%s.%d.tmp", t_progname, getpid()); - if (filename == NULL) - err(1, "asprintf()"); return (t_plan); } diff --git a/contrib/openpam/t/t_openpam_readword.c b/contrib/openpam/t/t_openpam_readword.c index 2135d8ba2868..d2d6bd5ffd28 100644 --- a/contrib/openpam/t/t_openpam_readword.c +++ b/contrib/openpam/t/t_openpam_readword.c @@ -6,8 +6,7 @@ * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer - * in this position and unchanged. + * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. @@ -27,7 +26,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: t_openpam_readword.c 584 2012-04-07 22:47:16Z des $ + * $Id: t_openpam_readword.c 648 2013-03-05 17:54:27Z des $ */ #ifdef HAVE_CONFIG_H @@ -35,8 +34,6 @@ #endif #include -#include -#include #include #include #include @@ -47,54 +44,6 @@ #include "t.h" -static char filename[1024]; -static FILE *f; - -/* - * Open the temp file and immediately unlink it so it doesn't leak in case - * of premature exit. - */ -static void -orw_open(void) -{ - int fd; - - if ((fd = open(filename, O_RDWR|O_CREAT|O_TRUNC, 0600)) < 0) - err(1, "%s(): %s", __func__, filename); - if ((f = fdopen(fd, "r+")) == NULL) - err(1, "%s(): %s", __func__, filename); - if (unlink(filename) < 0) - err(1, "%s(): %s", __func__, filename); -} - -/* - * Write text to the temp file. - */ -static void -orw_output(const char *fmt, ...) -{ - va_list ap; - - va_start(ap, fmt); - vfprintf(f, fmt, ap); - va_end(ap); - if (ferror(f)) - err(1, "%s", filename); -} - -/* - * Rewind the temp file. - */ -static void -orw_rewind(void) -{ - - errno = 0; - rewind(f); - if (errno != 0) - err(1, "%s(): %s", __func__, filename); -} - /* * Read a word from the temp file and verify that the result matches our * expectations: whether a word was read at all, how many lines were read @@ -102,15 +51,15 @@ orw_rewind(void) * the file and whether we reached the end of the line. */ static int -orw_expect(const char *expected, int lines, int eof, int eol) +orw_expect(struct t_file *tf, const char *expected, int lines, int eof, int eol) { int ch, lineno = 0; char *got; size_t len; - got = openpam_readword(f, &lineno, &len); - if (ferror(f)) - err(1, "%s(): %s", __func__, filename); + got = openpam_readword(tf->file, &lineno, &len); + if (t_ferror(tf)) + err(1, "%s(): %s", __func__, tf->name); if (expected != NULL && got == NULL) { t_verbose("expected <<%s>>, got nothing\n", expected); return (0); @@ -128,17 +77,17 @@ orw_expect(const char *expected, int lines, int eof, int eol) lines, lineno); return (0); } - if (eof && !feof(f)) { + if (eof && !t_feof(tf)) { t_verbose("expected EOF, but didn't get it\n"); return (0); } - if (!eof && feof(f)) { + if (!eof && t_feof(tf)) { t_verbose("didn't expect EOF, but got it anyway\n"); return (0); } - ch = fgetc(f); - if (ferror(f)) - err(1, "%s(): %s", __func__, filename); + ch = fgetc(tf->file); + if (t_ferror(tf)) + err(1, "%s(): %s", __func__, tf->name); if (eol && ch != '\n') { t_verbose("expected EOL, but didn't get it\n"); return (0); @@ -148,22 +97,10 @@ orw_expect(const char *expected, int lines, int eof, int eol) return (0); } if (ch != EOF) - ungetc(ch, f); + ungetc(ch, tf->file); return (1); } -/* - * Close the temp file. - */ -void -orw_close(void) -{ - - if (fclose(f) != 0) - err(1, "%s(): %s", __func__, filename); - f = NULL; -} - /*************************************************************************** * Lines without words @@ -171,83 +108,90 @@ orw_close(void) T_FUNC(empty_input, "empty input") { + struct t_file *tf; int ret; - orw_open(); - ret = orw_expect(NULL, 0 /*lines*/, 1 /*eof*/, 0 /*eol*/); - orw_close(); + tf = t_fopen(NULL); + ret = orw_expect(tf, NULL, 0 /*lines*/, 1 /*eof*/, 0 /*eol*/); + t_fclose(tf); return (ret); } T_FUNC(empty_line, "empty line") { + struct t_file *tf; int ret; - orw_open(); - orw_output("\n"); - orw_rewind(); - ret = orw_expect(NULL, 0 /*lines*/, 0 /*eof*/, 1 /*eol*/); - orw_close(); + tf = t_fopen(NULL); + t_fprintf(tf, "\n"); + t_frewind(tf); + ret = orw_expect(tf, NULL, 0 /*lines*/, 0 /*eof*/, 1 /*eol*/); + t_fclose(tf); return (ret); } T_FUNC(unterminated_line, "unterminated line") { + struct t_file *tf; int ret; - orw_open(); - orw_output(" "); - orw_rewind(); - ret = orw_expect(NULL, 0 /*lines*/, 1 /*eof*/, 0 /*eol*/); - orw_close(); + tf = t_fopen(NULL); + t_fprintf(tf, " "); + t_frewind(tf); + ret = orw_expect(tf, NULL, 0 /*lines*/, 1 /*eof*/, 0 /*eol*/); + t_fclose(tf); return (ret); } T_FUNC(single_whitespace, "single whitespace") { + struct t_file *tf; int ret; - orw_open(); - orw_output(" \n"); - orw_rewind(); - ret = orw_expect(NULL, 0 /*lines*/, 0 /*eof*/, 1 /*eol*/); - orw_close(); + tf = t_fopen(NULL); + t_fprintf(tf, " \n"); + t_frewind(tf); + ret = orw_expect(tf, NULL, 0 /*lines*/, 0 /*eof*/, 1 /*eol*/); + t_fclose(tf); return (ret); } T_FUNC(multiple_whitespace, "multiple whitespace") { + struct t_file *tf; int ret; - orw_open(); - orw_output(" \t\r\n"); - orw_rewind(); - ret = orw_expect(NULL, 0 /*lines*/, 0 /*eof*/, 1 /*eol*/); - orw_close(); + tf = t_fopen(NULL); + t_fprintf(tf, " \t\r\n"); + t_frewind(tf); + ret = orw_expect(tf, NULL, 0 /*lines*/, 0 /*eof*/, 1 /*eol*/); + t_fclose(tf); return (ret); } T_FUNC(comment, "comment") { + struct t_file *tf; int ret; - orw_open(); - orw_output("# comment\n"); - orw_rewind(); - ret = orw_expect(NULL, 0 /*lines*/, 0 /*eof*/, 1 /*eol*/); - orw_close(); + tf = t_fopen(NULL); + t_fprintf(tf, "# comment\n"); + t_frewind(tf); + ret = orw_expect(tf, NULL, 0 /*lines*/, 0 /*eof*/, 1 /*eol*/); + t_fclose(tf); return (ret); } T_FUNC(whitespace_before_comment, "whitespace before comment") { + struct t_file *tf; int ret; - orw_open(); - orw_output(" # comment\n"); - orw_rewind(); - ret = orw_expect(NULL, 0 /*lines*/, 0 /*eof*/, 1 /*eol*/); - orw_close(); + tf = t_fopen(NULL); + t_fprintf(tf, " # comment\n"); + t_frewind(tf); + ret = orw_expect(tf, NULL, 0 /*lines*/, 0 /*eof*/, 1 /*eol*/); + t_fclose(tf); return (ret); } @@ -259,106 +203,114 @@ T_FUNC(whitespace_before_comment, "whitespace before comment") T_FUNC(single_word, "single word") { const char *word = "hello"; + struct t_file *tf; int ret; - orw_open(); - orw_output("%s\n", word); - orw_rewind(); - ret = orw_expect(word, 0 /*lines*/, 0 /*eof*/, 1 /*eol*/); - orw_close(); + tf = t_fopen(NULL); + t_fprintf(tf, "%s\n", word); + t_frewind(tf); + ret = orw_expect(tf, word, 0 /*lines*/, 0 /*eof*/, 1 /*eol*/); + t_fclose(tf); return (ret); } T_FUNC(single_whitespace_before_word, "single whitespace before word") { const char *word = "hello"; + struct t_file *tf; int ret; - orw_open(); - orw_output(" %s\n", word); - orw_rewind(); - ret = orw_expect(word, 0 /*lines*/, 0 /*eof*/, 1 /*eol*/); - orw_close(); + tf = t_fopen(NULL); + t_fprintf(tf, " %s\n", word); + t_frewind(tf); + ret = orw_expect(tf, word, 0 /*lines*/, 0 /*eof*/, 1 /*eol*/); + t_fclose(tf); return (ret); } T_FUNC(double_whitespace_before_word, "double whitespace before word") { const char *word = "hello"; + struct t_file *tf; int ret; - orw_open(); - orw_output(" %s\n", word); - orw_rewind(); - ret = orw_expect(word, 0 /*lines*/, 0 /*eof*/, 1 /*eol*/); - orw_close(); + tf = t_fopen(NULL); + t_fprintf(tf, " %s\n", word); + t_frewind(tf); + ret = orw_expect(tf, word, 0 /*lines*/, 0 /*eof*/, 1 /*eol*/); + t_fclose(tf); return (ret); } T_FUNC(single_whitespace_after_word, "single whitespace after word") { const char *word = "hello"; + struct t_file *tf; int ret; - orw_open(); - orw_output("%s \n", word); - orw_rewind(); - ret = orw_expect(word, 0 /*lines*/, 0 /*eof*/, 0 /*eol*/); - orw_close(); + tf = t_fopen(NULL); + t_fprintf(tf, "%s \n", word); + t_frewind(tf); + ret = orw_expect(tf, word, 0 /*lines*/, 0 /*eof*/, 0 /*eol*/); + t_fclose(tf); return (ret); } T_FUNC(double_whitespace_after_word, "double whitespace after word") { const char *word = "hello"; + struct t_file *tf; int ret; - orw_open(); - orw_output("%s \n", word); - orw_rewind(); - ret = orw_expect(word, 0 /*lines*/, 0 /*eof*/, 0 /*eol*/); - orw_close(); + tf = t_fopen(NULL); + t_fprintf(tf, "%s \n", word); + t_frewind(tf); + ret = orw_expect(tf, word, 0 /*lines*/, 0 /*eof*/, 0 /*eol*/); + t_fclose(tf); return (ret); } T_FUNC(comment_after_word, "comment after word") { const char *word = "hello"; + struct t_file *tf; int ret; - orw_open(); - orw_output("%s # comment\n", word); - orw_rewind(); - ret = orw_expect(word, 0 /*lines*/, 0 /*eof*/, 0 /*eol*/) && - orw_expect(NULL, 0 /*lines*/, 0 /*eof*/, 1 /*eol*/); - orw_close(); + tf = t_fopen(NULL); + t_fprintf(tf, "%s # comment\n", word); + t_frewind(tf); + ret = orw_expect(tf, word, 0 /*lines*/, 0 /*eof*/, 0 /*eol*/) && + orw_expect(tf, NULL, 0 /*lines*/, 0 /*eof*/, 1 /*eol*/); + t_fclose(tf); return (ret); } T_FUNC(word_containing_hash, "word containing hash") { const char *word = "hello#world"; + struct t_file *tf; int ret; - orw_open(); - orw_output("%s\n", word); - orw_rewind(); - ret = orw_expect(word, 0 /*lines*/, 0 /*eof*/, 1 /*eol*/); - orw_close(); + tf = t_fopen(NULL); + t_fprintf(tf, "%s\n", word); + t_frewind(tf); + ret = orw_expect(tf, word, 0 /*lines*/, 0 /*eof*/, 1 /*eol*/); + t_fclose(tf); return (ret); } T_FUNC(two_words, "two words") { const char *word[] = { "hello", "world" }; + struct t_file *tf; int ret; - orw_open(); - orw_output("%s %s\n", word[0], word[1]); - orw_rewind(); - ret = orw_expect(word[0], 0 /*lines*/, 0 /*eof*/, 0 /*eol*/) && - orw_expect(word[1], 0 /*lines*/, 0 /*eof*/, 1 /*eol*/); - orw_close(); + tf = t_fopen(NULL); + t_fprintf(tf, "%s %s\n", word[0], word[1]); + t_frewind(tf); + ret = orw_expect(tf, word[0], 0 /*lines*/, 0 /*eof*/, 0 /*eol*/) && + orw_expect(tf, word[1], 0 /*lines*/, 0 /*eof*/, 1 /*eol*/); + t_fclose(tf); return (ret); } @@ -369,89 +321,96 @@ T_FUNC(two_words, "two words") T_FUNC(naked_escape, "naked escape") { + struct t_file *tf; int ret; - orw_open(); - orw_output("\\"); - orw_rewind(); - ret = orw_expect(NULL, 0 /*lines*/, 1 /*eof*/, 0 /*eol*/); - orw_close(); + tf = t_fopen(NULL); + t_fprintf(tf, "\\"); + t_frewind(tf); + ret = orw_expect(tf, NULL, 0 /*lines*/, 1 /*eof*/, 0 /*eol*/); + t_fclose(tf); return (ret); } T_FUNC(escaped_escape, "escaped escape") { + struct t_file *tf; int ret; - orw_open(); - orw_output("\\\\\n"); - orw_rewind(); - ret = orw_expect("\\", 0 /*lines*/, 0 /*eof*/, 1 /*eol*/); - orw_close(); + tf = t_fopen(NULL); + t_fprintf(tf, "\\\\\n"); + t_frewind(tf); + ret = orw_expect(tf, "\\", 0 /*lines*/, 0 /*eof*/, 1 /*eol*/); + t_fclose(tf); return (ret); } T_FUNC(escaped_whitespace, "escaped whitespace") { + struct t_file *tf; int ret; - orw_open(); - orw_output("\\ \\\t \\\r \\\n\n"); - orw_rewind(); - ret = orw_expect(" ", 0 /*lines*/, 0 /*eof*/, 0 /*eol*/) && - orw_expect("\t", 0 /*lines*/, 0 /*eof*/, 0 /*eol*/) && - orw_expect("\r", 0 /*lines*/, 0 /*eof*/, 0 /*eol*/) && + tf = t_fopen(NULL); + t_fprintf(tf, "\\ \\\t \\\r \\\n\n"); + t_frewind(tf); + ret = orw_expect(tf, " ", 0 /*lines*/, 0 /*eof*/, 0 /*eol*/) && + orw_expect(tf, "\t", 0 /*lines*/, 0 /*eof*/, 0 /*eol*/) && + orw_expect(tf, "\r", 0 /*lines*/, 0 /*eof*/, 0 /*eol*/) && /* this last one is a line continuation */ - orw_expect(NULL, 1 /*lines*/, 0 /*eof*/, 1 /*eol*/); - orw_close(); + orw_expect(tf, NULL, 1 /*lines*/, 0 /*eof*/, 1 /*eol*/); + t_fclose(tf); return (ret); } T_FUNC(escaped_newline_before_word, "escaped newline before word") { + struct t_file *tf; int ret; - orw_open(); - orw_output("\\\nhello world\n"); - orw_rewind(); - ret = orw_expect("hello", 1 /*lines*/, 0 /*eof*/, 0 /*eol*/); - orw_close(); + tf = t_fopen(NULL); + t_fprintf(tf, "\\\nhello world\n"); + t_frewind(tf); + ret = orw_expect(tf, "hello", 1 /*lines*/, 0 /*eof*/, 0 /*eol*/); + t_fclose(tf); return (ret); } T_FUNC(escaped_newline_within_word, "escaped newline within word") { + struct t_file *tf; int ret; - orw_open(); - orw_output("hello\\\nworld\n"); - orw_rewind(); - ret = orw_expect("helloworld", 1 /*lines*/, 0 /*eof*/, 1 /*eol*/); - orw_close(); + tf = t_fopen(NULL); + t_fprintf(tf, "hello\\\nworld\n"); + t_frewind(tf); + ret = orw_expect(tf, "helloworld", 1 /*lines*/, 0 /*eof*/, 1 /*eol*/); + t_fclose(tf); return (ret); } T_FUNC(escaped_newline_after_word, "escaped newline after word") { + struct t_file *tf; int ret; - orw_open(); - orw_output("hello\\\n world\n"); - orw_rewind(); - ret = orw_expect("hello", 1 /*lines*/, 0 /*eof*/, 0 /*eol*/); - orw_close(); + tf = t_fopen(NULL); + t_fprintf(tf, "hello\\\n world\n"); + t_frewind(tf); + ret = orw_expect(tf, "hello", 1 /*lines*/, 0 /*eof*/, 0 /*eol*/); + t_fclose(tf); return (ret); } T_FUNC(escaped_letter, "escaped letter") { + struct t_file *tf; int ret; - orw_open(); - orw_output("\\z\n"); - orw_rewind(); - ret = orw_expect("z", 0 /*lines*/, 0 /*eof*/, 1 /*eol*/); - orw_close(); + tf = t_fopen(NULL); + t_fprintf(tf, "\\z\n"); + t_frewind(tf); + ret = orw_expect(tf, "z", 0 /*lines*/, 0 /*eof*/, 1 /*eol*/); + t_fclose(tf); return (ret); } @@ -462,127 +421,220 @@ T_FUNC(escaped_letter, "escaped letter") T_FUNC(naked_single_quote, "naked single quote") { + struct t_file *tf; int ret; - orw_open(); - orw_output("'"); - orw_rewind(); - ret = orw_expect(NULL, 0 /*lines*/, 1 /*eof*/, 0 /*eol*/); - orw_close(); + tf = t_fopen(NULL); + t_fprintf(tf, "'"); + t_frewind(tf); + ret = orw_expect(tf, NULL, 0 /*lines*/, 1 /*eof*/, 0 /*eol*/); + t_fclose(tf); return (ret); } T_FUNC(naked_double_quote, "naked double quote") { + struct t_file *tf; int ret; - orw_open(); - orw_output("\""); - orw_rewind(); - ret = orw_expect(NULL, 0 /*lines*/, 1 /*eof*/, 0 /*eol*/); - orw_close(); + tf = t_fopen(NULL); + t_fprintf(tf, "\""); + t_frewind(tf); + ret = orw_expect(tf, NULL, 0 /*lines*/, 1 /*eof*/, 0 /*eol*/); + t_fclose(tf); return (ret); } T_FUNC(empty_single_quotes, "empty single quotes") { + struct t_file *tf; int ret; - orw_open(); - orw_output("''\n"); - orw_rewind(); - ret = orw_expect("", 0 /*lines*/, 0 /*eof*/, 1 /*eol*/); - orw_close(); + tf = t_fopen(NULL); + t_fprintf(tf, "''\n"); + t_frewind(tf); + ret = orw_expect(tf, "", 0 /*lines*/, 0 /*eof*/, 1 /*eol*/); + t_fclose(tf); return (ret); } T_FUNC(empty_double_quotes, "empty double quotes") { + struct t_file *tf; int ret; - orw_open(); - orw_output("\"\"\n"); - orw_rewind(); - ret = orw_expect("", 0 /*lines*/, 0 /*eof*/, 1 /*eol*/); - orw_close(); + tf = t_fopen(NULL); + t_fprintf(tf, "\"\"\n"); + t_frewind(tf); + ret = orw_expect(tf, "", 0 /*lines*/, 0 /*eof*/, 1 /*eol*/); + t_fclose(tf); return (ret); } T_FUNC(single_quotes_within_double_quotes, "single quotes within double quotes") { + struct t_file *tf; int ret; - orw_open(); - orw_output("\"' '\"\n"); - orw_rewind(); - ret = orw_expect("' '", 0 /*lines*/, 0 /*eof*/, 1 /*eol*/); - orw_close(); + tf = t_fopen(NULL); + t_fprintf(tf, "\"' '\"\n"); + t_frewind(tf); + ret = orw_expect(tf, "' '", 0 /*lines*/, 0 /*eof*/, 1 /*eol*/); + t_fclose(tf); return (ret); } T_FUNC(double_quotes_within_single_quotes, "double quotes within single quotes") { + struct t_file *tf; int ret; - orw_open(); - orw_output("'\" \"'\n"); - orw_rewind(); - ret = orw_expect("\" \"", 0 /*lines*/, 0 /*eof*/, 1 /*eol*/); - orw_close(); + tf = t_fopen(NULL); + t_fprintf(tf, "'\" \"'\n"); + t_frewind(tf); + ret = orw_expect(tf, "\" \"", 0 /*lines*/, 0 /*eof*/, 1 /*eol*/); + t_fclose(tf); return (ret); } T_FUNC(single_quoted_whitespace, "single-quoted whitespace") { + struct t_file *tf; int ret; - orw_open(); - orw_output("' ' '\t' '\r' '\n'\n"); - orw_rewind(); - ret = orw_expect(" ", 0 /*lines*/, 0 /*eof*/, 0 /*eol*/) && - orw_expect("\t", 0 /*lines*/, 0 /*eof*/, 0 /*eol*/) && - orw_expect("\r", 0 /*lines*/, 0 /*eof*/, 0 /*eol*/) && - orw_expect("\n", 1 /*lines*/, 0 /*eof*/, 1 /*eol*/); - orw_close(); + tf = t_fopen(NULL); + t_fprintf(tf, "' ' '\t' '\r' '\n'\n"); + t_frewind(tf); + ret = orw_expect(tf, " ", 0 /*lines*/, 0 /*eof*/, 0 /*eol*/) && + orw_expect(tf, "\t", 0 /*lines*/, 0 /*eof*/, 0 /*eol*/) && + orw_expect(tf, "\r", 0 /*lines*/, 0 /*eof*/, 0 /*eol*/) && + orw_expect(tf, "\n", 1 /*lines*/, 0 /*eof*/, 1 /*eol*/); + t_fclose(tf); return (ret); } T_FUNC(double_quoted_whitespace, "double-quoted whitespace") { + struct t_file *tf; int ret; - orw_open(); - orw_output("\" \" \"\t\" \"\r\" \"\n\"\n"); - orw_rewind(); - ret = orw_expect(" ", 0 /*lines*/, 0 /*eof*/, 0 /*eol*/) && - orw_expect("\t", 0 /*lines*/, 0 /*eof*/, 0 /*eol*/) && - orw_expect("\r", 0 /*lines*/, 0 /*eof*/, 0 /*eol*/) && - orw_expect("\n", 1 /*lines*/, 0 /*eof*/, 1 /*eol*/); - orw_close(); + tf = t_fopen(NULL); + t_fprintf(tf, "\" \" \"\t\" \"\r\" \"\n\"\n"); + t_frewind(tf); + ret = orw_expect(tf, " ", 0 /*lines*/, 0 /*eof*/, 0 /*eol*/) && + orw_expect(tf, "\t", 0 /*lines*/, 0 /*eof*/, 0 /*eol*/) && + orw_expect(tf, "\r", 0 /*lines*/, 0 /*eof*/, 0 /*eol*/) && + orw_expect(tf, "\n", 1 /*lines*/, 0 /*eof*/, 1 /*eol*/); + t_fclose(tf); return (ret); } T_FUNC(single_quoted_words, "single-quoted words") { + struct t_file *tf; int ret; - orw_open(); - orw_output("'hello world'\n"); - orw_rewind(); - ret = orw_expect("hello world", 0 /*lines*/, 0 /*eof*/, 1 /*eol*/); - orw_close(); + tf = t_fopen(NULL); + t_fprintf(tf, "'hello world'\n"); + t_frewind(tf); + ret = orw_expect(tf, "hello world", 0 /*lines*/, 0 /*eof*/, 1 /*eol*/); + t_fclose(tf); return (ret); } T_FUNC(double_quoted_words, "double-quoted words") { + struct t_file *tf; int ret; - orw_open(); - orw_output("\"hello world\"\n"); - orw_rewind(); - ret = orw_expect("hello world", 0 /*lines*/, 0 /*eof*/, 1 /*eol*/); - orw_close(); + tf = t_fopen(NULL); + t_fprintf(tf, "\"hello world\"\n"); + t_frewind(tf); + ret = orw_expect(tf, "hello world", 0 /*lines*/, 0 /*eof*/, 1 /*eol*/); + t_fclose(tf); + return (ret); +} + + +/*************************************************************************** + * Combinations of quoted and unquoted text + */ + +T_FUNC(single_quote_before_word, "single quote before word") +{ + struct t_file *tf; + int ret; + + tf = t_fopen(NULL); + t_fprintf(tf, "'hello 'world\n"); + t_frewind(tf); + ret = orw_expect(tf, "hello world", 0 /*lines*/, 0 /*eof*/, 1 /*eol*/); + t_fclose(tf); + return (ret); +} + +T_FUNC(double_quote_before_word, "double quote before word") +{ + struct t_file *tf; + int ret; + + tf = t_fopen(NULL); + t_fprintf(tf, "\"hello \"world\n"); + t_frewind(tf); + ret = orw_expect(tf, "hello world", 0 /*lines*/, 0 /*eof*/, 1 /*eol*/); + t_fclose(tf); + return (ret); +} + +T_FUNC(single_quote_within_word, "single quote within word") +{ + struct t_file *tf; + int ret; + + tf = t_fopen(NULL); + t_fprintf(tf, "hello' 'world\n"); + t_frewind(tf); + ret = orw_expect(tf, "hello world", 0 /*lines*/, 0 /*eof*/, 1 /*eol*/); + t_fclose(tf); + return (ret); +} + +T_FUNC(double_quote_within_word, "double quote within word") +{ + struct t_file *tf; + int ret; + + tf = t_fopen(NULL); + t_fprintf(tf, "hello\" \"world\n"); + t_frewind(tf); + ret = orw_expect(tf, "hello world", 0 /*lines*/, 0 /*eof*/, 1 /*eol*/); + t_fclose(tf); + return (ret); +} + +T_FUNC(single_quote_after_word, "single quote after word") +{ + struct t_file *tf; + int ret; + + tf = t_fopen(NULL); + t_fprintf(tf, "hello' world'\n"); + t_frewind(tf); + ret = orw_expect(tf, "hello world", 0 /*lines*/, 0 /*eof*/, 1 /*eol*/); + t_fclose(tf); + return (ret); +} + +T_FUNC(double_quote_after_word, "double quote after word") +{ + struct t_file *tf; + int ret; + + tf = t_fopen(NULL); + t_fprintf(tf, "hello\" world\"\n"); + t_frewind(tf); + ret = orw_expect(tf, "hello world", 0 /*lines*/, 0 /*eof*/, 1 /*eol*/); + t_fclose(tf); return (ret); } @@ -594,163 +646,175 @@ T_FUNC(double_quoted_words, "double-quoted words") T_FUNC(escaped_single_quote, "escaped single quote") { + struct t_file *tf; int ret; - orw_open(); - orw_output("\\'\n"); - orw_rewind(); - ret = orw_expect("'", 0 /*lines*/, 0 /*eof*/, 1 /*eol*/); - orw_close(); + tf = t_fopen(NULL); + t_fprintf(tf, "\\'\n"); + t_frewind(tf); + ret = orw_expect(tf, "'", 0 /*lines*/, 0 /*eof*/, 1 /*eol*/); + t_fclose(tf); return (ret); } T_FUNC(escaped_double_quote, "escaped double quote") { + struct t_file *tf; int ret; - orw_open(); - orw_output("\\\"\n"); - orw_rewind(); - ret = orw_expect("\"", 0 /*lines*/, 0 /*eof*/, 1 /*eol*/); - orw_close(); + tf = t_fopen(NULL); + t_fprintf(tf, "\\\"\n"); + t_frewind(tf); + ret = orw_expect(tf, "\"", 0 /*lines*/, 0 /*eof*/, 1 /*eol*/); + t_fclose(tf); return (ret); } T_FUNC(escaped_whitespace_within_single_quotes, "escaped whitespace within single quotes") { + struct t_file *tf; int ret; - orw_open(); - orw_output("'\\ ' '\\\t' '\\\r' '\\\n'\n"); - orw_rewind(); - ret = orw_expect("\\ ", 0 /*lines*/, 0 /*eof*/, 0 /*eol*/) && - orw_expect("\\\t", 0 /*lines*/, 0 /*eof*/, 0 /*eol*/) && - orw_expect("\\\r", 0 /*lines*/, 0 /*eof*/, 0 /*eol*/) && - orw_expect("\\\n", 1 /*lines*/, 0 /*eof*/, 1 /*eol*/); - orw_close(); + tf = t_fopen(NULL); + t_fprintf(tf, "'\\ ' '\\\t' '\\\r' '\\\n'\n"); + t_frewind(tf); + ret = orw_expect(tf, "\\ ", 0 /*lines*/, 0 /*eof*/, 0 /*eol*/) && + orw_expect(tf, "\\\t", 0 /*lines*/, 0 /*eof*/, 0 /*eol*/) && + orw_expect(tf, "\\\r", 0 /*lines*/, 0 /*eof*/, 0 /*eol*/) && + orw_expect(tf, "\\\n", 1 /*lines*/, 0 /*eof*/, 1 /*eol*/); + t_fclose(tf); return (ret); } T_FUNC(escaped_whitespace_within_double_quotes, "escaped whitespace within double quotes") { + struct t_file *tf; int ret; - orw_open(); - orw_output("\"\\ \" \"\\\t\" \"\\\r\" \"\\\n\"\n"); - orw_rewind(); - ret = orw_expect("\\ ", 0 /*lines*/, 0 /*eof*/, 0 /*eol*/) && - orw_expect("\\\t", 0 /*lines*/, 0 /*eof*/, 0 /*eol*/) && - orw_expect("\\\r", 0 /*lines*/, 0 /*eof*/, 0 /*eol*/) && + tf = t_fopen(NULL); + t_fprintf(tf, "\"\\ \" \"\\\t\" \"\\\r\" \"\\\n\"\n"); + t_frewind(tf); + ret = orw_expect(tf, "\\ ", 0 /*lines*/, 0 /*eof*/, 0 /*eol*/) && + orw_expect(tf, "\\\t", 0 /*lines*/, 0 /*eof*/, 0 /*eol*/) && + orw_expect(tf, "\\\r", 0 /*lines*/, 0 /*eof*/, 0 /*eol*/) && /* this last one is a line continuation */ - orw_expect("", 1 /*lines*/, 0 /*eof*/, 1 /*eol*/); - orw_close(); + orw_expect(tf, "", 1 /*lines*/, 0 /*eof*/, 1 /*eol*/); + t_fclose(tf); return (ret); } T_FUNC(escaped_letter_within_single_quotes, "escaped letter within single quotes") { + struct t_file *tf; int ret; - orw_open(); - orw_output("'\\z'\n"); - orw_rewind(); - ret = orw_expect("\\z", 0 /*lines*/, 0 /*eof*/, 1 /*eol*/); - orw_close(); + tf = t_fopen(NULL); + t_fprintf(tf, "'\\z'\n"); + t_frewind(tf); + ret = orw_expect(tf, "\\z", 0 /*lines*/, 0 /*eof*/, 1 /*eol*/); + t_fclose(tf); return (ret); } T_FUNC(escaped_letter_within_double_quotes, "escaped letter within double quotes") { + struct t_file *tf; int ret; - orw_open(); - orw_output("\"\\z\"\n"); - orw_rewind(); - ret = orw_expect("\\z", 0 /*lines*/, 0 /*eof*/, 1 /*eol*/); - orw_close(); + tf = t_fopen(NULL); + t_fprintf(tf, "\"\\z\"\n"); + t_frewind(tf); + ret = orw_expect(tf, "\\z", 0 /*lines*/, 0 /*eof*/, 1 /*eol*/); + t_fclose(tf); return (ret); } T_FUNC(escaped_escape_within_single_quotes, "escaped escape within single quotes") { + struct t_file *tf; int ret; - orw_open(); - orw_output("'\\\\'\n"); - orw_rewind(); - ret = orw_expect("\\\\", 0 /*lines*/, 0 /*eof*/, 1 /*eol*/); - orw_close(); + tf = t_fopen(NULL); + t_fprintf(tf, "'\\\\'\n"); + t_frewind(tf); + ret = orw_expect(tf, "\\\\", 0 /*lines*/, 0 /*eof*/, 1 /*eol*/); + t_fclose(tf); return (ret); } T_FUNC(escaped_escape_within_double_quotes, "escaped escape within double quotes") { + struct t_file *tf; int ret; - orw_open(); - orw_output("\"\\\\\"\n"); - orw_rewind(); - ret = orw_expect("\\", 0 /*lines*/, 0 /*eof*/, 1 /*eol*/); - orw_close(); + tf = t_fopen(NULL); + t_fprintf(tf, "\"\\\\\"\n"); + t_frewind(tf); + ret = orw_expect(tf, "\\", 0 /*lines*/, 0 /*eof*/, 1 /*eol*/); + t_fclose(tf); return (ret); } T_FUNC(escaped_single_quote_within_single_quotes, "escaped single quote within single quotes") { + struct t_file *tf; int ret; - orw_open(); - orw_output("'\\''\n"); - orw_rewind(); - ret = orw_expect(NULL, 1 /*lines*/, 1 /*eof*/, 0 /*eol*/); - orw_close(); + tf = t_fopen(NULL); + t_fprintf(tf, "'\\''\n"); + t_frewind(tf); + ret = orw_expect(tf, NULL, 1 /*lines*/, 1 /*eof*/, 0 /*eol*/); + t_fclose(tf); return (ret); } T_FUNC(escaped_double_quote_within_single_quotes, "escaped double quote within single quotes") { + struct t_file *tf; int ret; - orw_open(); - orw_output("'\\\"'\n"); - orw_rewind(); - ret = orw_expect("\\\"", 0 /*lines*/, 0 /*eof*/, 1 /*eol*/); - orw_close(); + tf = t_fopen(NULL); + t_fprintf(tf, "'\\\"'\n"); + t_frewind(tf); + ret = orw_expect(tf, "\\\"", 0 /*lines*/, 0 /*eof*/, 1 /*eol*/); + t_fclose(tf); return (ret); } T_FUNC(escaped_single_quote_within_double_quotes, "escaped single quote within double quotes") { + struct t_file *tf; int ret; - orw_open(); - orw_output("\"\\'\"\n"); - orw_rewind(); - ret = orw_expect("\\'", 0 /*lines*/, 0 /*eof*/, 1 /*eol*/); - orw_close(); + tf = t_fopen(NULL); + t_fprintf(tf, "\"\\'\"\n"); + t_frewind(tf); + ret = orw_expect(tf, "\\'", 0 /*lines*/, 0 /*eof*/, 1 /*eol*/); + t_fclose(tf); return (ret); } T_FUNC(escaped_double_quote_within_double_quotes, "escaped double quote within double quotes") { + struct t_file *tf; int ret; - orw_open(); - orw_output("\"\\\"\"\n"); - orw_rewind(); - ret = orw_expect("\"", 0 /*lines*/, 0 /*eof*/, 1 /*eol*/); - orw_close(); + tf = t_fopen(NULL); + t_fprintf(tf, "\"\\\"\"\n"); + t_frewind(tf); + ret = orw_expect(tf, "\"", 0 /*lines*/, 0 /*eof*/, 1 /*eol*/); + t_fclose(tf); return (ret); } @@ -795,6 +859,13 @@ const struct t_test *t_plan[] = { T(single_quoted_words), T(double_quoted_words), + T(single_quote_before_word), + T(double_quote_before_word), + T(single_quote_within_word), + T(double_quote_within_word), + T(single_quote_after_word), + T(double_quote_after_word), + T(escaped_single_quote), T(escaped_double_quote), T(escaped_whitespace_within_single_quotes), @@ -817,9 +888,6 @@ t_prepare(int argc, char *argv[]) (void)argc; (void)argv; - snprintf(filename, sizeof filename, "%s.%d.tmp", t_progname, getpid()); - if (filename == NULL) - err(1, "asprintf()"); return (t_plan); } diff --git a/contrib/openpam/test-driver b/contrib/openpam/test-driver new file mode 100755 index 000000000000..32bf39e83779 --- /dev/null +++ b/contrib/openpam/test-driver @@ -0,0 +1,127 @@ +#! /bin/sh +# test-driver - basic testsuite driver script. + +scriptversion=2012-06-27.10; # UTC + +# Copyright (C) 2011-2013 Free Software Foundation, Inc. +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2, or (at your option) +# any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + +# This file is maintained in Automake, please report +# bugs to or send patches to +# . + +# Make unconditional expansion of undefined variables an error. This +# helps a lot in preventing typo-related bugs. +set -u + +usage_error () +{ + echo "$0: $*" >&2 + print_usage >&2 + exit 2 +} + +print_usage () +{ + cat <$log_file 2>&1 +estatus=$? +if test $enable_hard_errors = no && test $estatus -eq 99; then + estatus=1 +fi + +case $estatus:$expect_failure in + 0:yes) col=$red res=XPASS recheck=yes gcopy=yes;; + 0:*) col=$grn res=PASS recheck=no gcopy=no;; + 77:*) col=$blu res=SKIP recheck=no gcopy=yes;; + 99:*) col=$mgn res=ERROR recheck=yes gcopy=yes;; + *:yes) col=$lgn res=XFAIL recheck=no gcopy=yes;; + *:*) col=$red res=FAIL recheck=yes gcopy=yes;; +esac + +# Report outcome to console. +echo "${col}${res}${std}: $test_name" + +# Register the test result, and other relevant metadata. +echo ":test-result: $res" > $trs_file +echo ":global-test-result: $res" >> $trs_file +echo ":recheck: $recheck" >> $trs_file +echo ":copy-in-global-log: $gcopy" >> $trs_file + +# Local Variables: +# mode: shell-script +# sh-indentation: 2 +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "scriptversion=" +# time-stamp-format: "%:y-%02m-%02d.%02H" +# time-stamp-time-zone: "UTC" +# time-stamp-end: "; # UTC" +# End: diff --git a/contrib/tcpdump/tcpdump.c b/contrib/tcpdump/tcpdump.c index 48b774df686e..afcc152142dd 100644 --- a/contrib/tcpdump/tcpdump.c +++ b/contrib/tcpdump/tcpdump.c @@ -715,8 +715,9 @@ main(int argc, char **argv) int status; FILE *VFile; #ifdef __FreeBSD__ + cap_rights_t rights; int cansandbox; -#endif +#endif /* __FreeBSD__ */ #ifdef WIN32 if(wsockinit() != 0) return 1; @@ -1206,7 +1207,8 @@ main(int argc, char **argv) if (pd == NULL) error("%s", ebuf); #ifdef __FreeBSD__ - if (cap_rights_limit(fileno(pcap_file(pd)), CAP_READ) < 0 && + cap_rights_init(&rights, CAP_READ); + if (cap_rights_limit(fileno(pcap_file(pd)), &rights) < 0 && errno != ENOSYS) { error("unable to limit pcap descriptor"); } @@ -1484,8 +1486,9 @@ main(int argc, char **argv) if (RFileName == NULL && VFileName == NULL) { static const unsigned long cmds[] = { BIOCGSTATS }; - if (cap_rights_limit(pcap_fileno(pd), - CAP_IOCTL | CAP_READ) < 0 && errno != ENOSYS) { + cap_rights_init(&rights, CAP_IOCTL, CAP_READ); + if (cap_rights_limit(pcap_fileno(pd), &rights) < 0 && + errno != ENOSYS) { error("unable to limit pcap descriptor"); } if (cap_ioctls_limit(pcap_fileno(pd), cmds, @@ -1516,8 +1519,9 @@ main(int argc, char **argv) if (p == NULL) error("%s", pcap_geterr(pd)); #ifdef __FreeBSD__ - if (cap_rights_limit(fileno(pcap_dump_file(p)), - CAP_SEEK | CAP_WRITE) < 0 && errno != ENOSYS) { + cap_rights_init(&rights, CAP_SEEK, CAP_WRITE); + if (cap_rights_limit(fileno(pcap_dump_file(p)), &rights) < 0 && + errno != ENOSYS) { error("unable to limit dump descriptor"); } #endif @@ -1530,9 +1534,10 @@ main(int argc, char **argv) error("unable to open directory %s", dirname(WFileName)); } - if (cap_rights_limit(dumpinfo.dirfd, CAP_CREATE | - CAP_FCNTL | CAP_FTRUNCATE | CAP_LOOKUP | CAP_SEEK | - CAP_WRITE) < 0 && errno != ENOSYS) { + cap_rights_init(&rights, CAP_CREATE, CAP_FCNTL, + CAP_FTRUNCATE, CAP_LOOKUP, CAP_SEEK, CAP_WRITE); + if (cap_rights_limit(dumpinfo.dirfd, &rights) < 0 && + errno != ENOSYS) { error("unable to limit directory rights"); } #else /* !__FreeBSD__ */ @@ -1615,7 +1620,7 @@ main(int argc, char **argv) error("unable to enter the capability mode"); if (cap_sandboxed()) fprintf(stderr, "capability mode sandbox enabled\n"); -#endif +#endif /* __FreeBSD__ */ do { status = pcap_loop(pd, cnt, callback, pcap_userdata); @@ -1657,8 +1662,9 @@ main(int argc, char **argv) if (pd == NULL) error("%s", ebuf); #ifdef __FreeBSD__ + cap_rights_init(&rights, CAP_READ); if (cap_rights_limit(fileno(pcap_file(pd)), - CAP_READ) < 0 && errno != ENOSYS) { + &rights) < 0 && errno != ENOSYS) { error("unable to limit pcap descriptor"); } #endif @@ -1830,6 +1836,9 @@ static void dump_packet_and_trunc(u_char *user, const struct pcap_pkthdr *h, const u_char *sp) { struct dump_info *dump_info; +#ifdef __FreeBSD__ + cap_rights_t rights; +#endif ++packets_captured; @@ -1933,8 +1942,9 @@ dump_packet_and_trunc(u_char *user, const struct pcap_pkthdr *h, const u_char *s if (dump_info->p == NULL) error("%s", pcap_geterr(pd)); #ifdef __FreeBSD__ + cap_rights_init(&rights, CAP_SEEK, CAP_WRITE); if (cap_rights_limit(fileno(pcap_dump_file(dump_info->p)), - CAP_SEEK | CAP_WRITE) < 0 && errno != ENOSYS) { + &rights) < 0 && errno != ENOSYS) { error("unable to limit dump descriptor"); } #endif @@ -1993,8 +2003,9 @@ dump_packet_and_trunc(u_char *user, const struct pcap_pkthdr *h, const u_char *s if (dump_info->p == NULL) error("%s", pcap_geterr(pd)); #ifdef __FreeBSD__ + cap_rights_init(&rights, CAP_SEEK, CAP_WRITE); if (cap_rights_limit(fileno(pcap_dump_file(dump_info->p)), - CAP_SEEK | CAP_WRITE) < 0 && errno != ENOSYS) { + &rights) < 0 && errno != ENOSYS) { error("unable to limit dump descriptor"); } #endif diff --git a/crypto/openssh/openbsd-compat/getrrsetbyname-ldns.c b/crypto/openssh/openbsd-compat/getrrsetbyname-ldns.c new file mode 100644 index 000000000000..19666346bdea --- /dev/null +++ b/crypto/openssh/openbsd-compat/getrrsetbyname-ldns.c @@ -0,0 +1,285 @@ +/* $OpenBSD: getrrsetbyname.c,v 1.10 2005/03/30 02:58:28 tedu Exp $ */ + +/* + * Copyright (c) 2007 Simon Vallet / Genoscope + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/* + * Portions Copyright (c) 1999-2001 Internet Software Consortium. + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM + * DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL + * INTERNET SOFTWARE CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, + * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING + * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, + * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION + * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include "includes.h" + +#if !defined (HAVE_GETRRSETBYNAME) && defined (HAVE_LDNS) + +#include +#include + +#include + +#include "getrrsetbyname.h" +#include "log.h" +#include "xmalloc.h" + +#define malloc(x) (xmalloc(x)) +#define calloc(x, y) (xcalloc((x),(y))) +#define free(x) (xfree(x)) + +int +getrrsetbyname(const char *hostname, unsigned int rdclass, + unsigned int rdtype, unsigned int flags, + struct rrsetinfo **res) +{ + int result; + unsigned int i, j, index_ans, index_sig; + struct rrsetinfo *rrset = NULL; + struct rdatainfo *rdata; + size_t len; + ldns_resolver *ldns_res; + ldns_rdf *domain = NULL; + ldns_pkt *pkt = NULL; + ldns_rr_list *rrsigs = NULL, *rrdata = NULL; + ldns_status err; + ldns_rr *rr; + + /* check for invalid class and type */ + if (rdclass > 0xffff || rdtype > 0xffff) { + result = ERRSET_INVAL; + goto fail; + } + + /* don't allow queries of class or type ANY */ + if (rdclass == 0xff || rdtype == 0xff) { + result = ERRSET_INVAL; + goto fail; + } + + /* don't allow flags yet, unimplemented */ + if (flags) { + result = ERRSET_INVAL; + goto fail; + } + + /* Initialize resolver from resolv.conf */ + domain = ldns_dname_new_frm_str(hostname); + if ((err = ldns_resolver_new_frm_file(&ldns_res, NULL)) != \ + LDNS_STATUS_OK) { + result = ERRSET_FAIL; + goto fail; + } + +#ifdef LDNS_DEBUG + ldns_resolver_set_debug(ldns_res, true); +#endif /* LDNS_DEBUG */ + + ldns_resolver_set_dnssec(ldns_res, true); /* Use DNSSEC */ + + /* make query */ + pkt = ldns_resolver_query(ldns_res, domain, rdtype, rdclass, LDNS_RD); + + /*** TODO: finer errcodes -- see original **/ + if (!pkt || ldns_pkt_ancount(pkt) < 1) { + result = ERRSET_FAIL; + goto fail; + } + + /* initialize rrset */ + rrset = calloc(1, sizeof(struct rrsetinfo)); + if (rrset == NULL) { + result = ERRSET_NOMEMORY; + goto fail; + } + + rrdata = ldns_pkt_rr_list_by_type(pkt, rdtype, LDNS_SECTION_ANSWER); + rrset->rri_nrdatas = ldns_rr_list_rr_count(rrdata); + if (!rrset->rri_nrdatas) { + result = ERRSET_NODATA; + goto fail; + } + + /* copy name from answer section */ + len = ldns_rdf_size(ldns_rr_owner(ldns_rr_list_rr(rrdata, 0))); + if ((rrset->rri_name = malloc(len)) == NULL) { + result = ERRSET_NOMEMORY; + goto fail; + } + memcpy(rrset->rri_name, + ldns_rdf_data(ldns_rr_owner(ldns_rr_list_rr(rrdata, 0))), len); + + rrset->rri_rdclass = ldns_rr_get_class(ldns_rr_list_rr(rrdata, 0)); + rrset->rri_rdtype = ldns_rr_get_type(ldns_rr_list_rr(rrdata, 0)); + rrset->rri_ttl = ldns_rr_ttl(ldns_rr_list_rr(rrdata, 0)); + + debug2("ldns: got %u answers from DNS", rrset->rri_nrdatas); + + /* Check for authenticated data */ + if (ldns_pkt_ad(pkt)) { + rrset->rri_flags |= RRSET_VALIDATED; + } else { /* AD is not set, try autonomous validation */ + ldns_rr_list * trusted_keys = ldns_rr_list_new(); + + debug2("ldns: trying to validate RRset"); + /* Get eventual sigs */ + rrsigs = ldns_pkt_rr_list_by_type(pkt, LDNS_RR_TYPE_RRSIG, + LDNS_SECTION_ANSWER); + + rrset->rri_nsigs = ldns_rr_list_rr_count(rrsigs); + debug2("ldns: got %u signature(s) (RRTYPE %u) from DNS", + rrset->rri_nsigs, LDNS_RR_TYPE_RRSIG); + + if ((err = ldns_verify_trusted(ldns_res, rrdata, rrsigs, + trusted_keys)) == LDNS_STATUS_OK) { + rrset->rri_flags |= RRSET_VALIDATED; + debug2("ldns: RRset is signed with a valid key"); + } else { + debug2("ldns: RRset validation failed: %s", + ldns_get_errorstr_by_id(err)); + } + + ldns_rr_list_deep_free(trusted_keys); + } + + /* allocate memory for answers */ + rrset->rri_rdatas = calloc(rrset->rri_nrdatas, + sizeof(struct rdatainfo)); + + if (rrset->rri_rdatas == NULL) { + result = ERRSET_NOMEMORY; + goto fail; + } + + /* allocate memory for signatures */ + if (rrset->rri_nsigs > 0) { + rrset->rri_sigs = calloc(rrset->rri_nsigs, + sizeof(struct rdatainfo)); + + if (rrset->rri_sigs == NULL) { + result = ERRSET_NOMEMORY; + goto fail; + } + } + + /* copy answers & signatures */ + for (i=0, index_ans=0, index_sig=0; i< pkt->_header->_ancount; i++) { + rdata = NULL; + rr = ldns_rr_list_rr(ldns_pkt_answer(pkt), i); + + if (ldns_rr_get_class(rr) == rrset->rri_rdclass && + ldns_rr_get_type(rr) == rrset->rri_rdtype) { + rdata = &rrset->rri_rdatas[index_ans++]; + } + + if (rr->_rr_class == rrset->rri_rdclass && + rr->_rr_type == LDNS_RR_TYPE_RRSIG && + rrset->rri_sigs) { + rdata = &rrset->rri_sigs[index_sig++]; + } + + if (rdata) { + size_t rdata_offset = 0; + + rdata->rdi_length = 0; + for (j=0; j< rr->_rd_count; j++) { + rdata->rdi_length += + ldns_rdf_size(ldns_rr_rdf(rr, j)); + } + + rdata->rdi_data = malloc(rdata->rdi_length); + if (rdata->rdi_data == NULL) { + result = ERRSET_NOMEMORY; + goto fail; + } + + /* Re-create the raw DNS RDATA */ + for (j=0; j< rr->_rd_count; j++) { + len = ldns_rdf_size(ldns_rr_rdf(rr, j)); + memcpy(rdata->rdi_data + rdata_offset, + ldns_rdf_data(ldns_rr_rdf(rr, j)), len); + rdata_offset += len; + } + } + } + + *res = rrset; + result = ERRSET_SUCCESS; + +fail: + /* freerrset(rrset); */ + ldns_rdf_deep_free(domain); + ldns_pkt_free(pkt); + ldns_rr_list_deep_free(rrsigs); + ldns_rr_list_deep_free(rrdata); + ldns_resolver_deep_free(ldns_res); + + return result; +} + + +void +freerrset(struct rrsetinfo *rrset) +{ + u_int16_t i; + + if (rrset == NULL) + return; + + if (rrset->rri_rdatas) { + for (i = 0; i < rrset->rri_nrdatas; i++) { + if (rrset->rri_rdatas[i].rdi_data == NULL) + break; + free(rrset->rri_rdatas[i].rdi_data); + } + free(rrset->rri_rdatas); + } + + if (rrset->rri_sigs) { + for (i = 0; i < rrset->rri_nsigs; i++) { + if (rrset->rri_sigs[i].rdi_data == NULL) + break; + free(rrset->rri_sigs[i].rdi_data); + } + free(rrset->rri_sigs); + } + + if (rrset->rri_name) + free(rrset->rri_name); + free(rrset); +} + + +#endif /* !defined (HAVE_GETRRSETBYNAME) && defined (HAVE_LDNS) */ diff --git a/crypto/openssh/openbsd-compat/strnlen.c b/crypto/openssh/openbsd-compat/strnlen.c new file mode 100644 index 000000000000..93d515595c97 --- /dev/null +++ b/crypto/openssh/openbsd-compat/strnlen.c @@ -0,0 +1,37 @@ +/* $OpenBSD: strnlen.c,v 1.3 2010/06/02 12:58:12 millert Exp $ */ + +/* + * Copyright (c) 2010 Todd C. Miller + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +/* OPENBSD ORIGINAL: lib/libc/string/strnlen.c */ + +#include "config.h" +#ifndef HAVE_STRNLEN +#include + +#include + +size_t +strnlen(const char *str, size_t maxlen) +{ + const char *cp; + + for (cp = str; maxlen != 0 && *cp != '\0'; cp++, maxlen--) + ; + + return (size_t)(cp - str); +} +#endif diff --git a/crypto/openssh/sandbox-seccomp-filter.c b/crypto/openssh/sandbox-seccomp-filter.c new file mode 100644 index 000000000000..e12418399a12 --- /dev/null +++ b/crypto/openssh/sandbox-seccomp-filter.c @@ -0,0 +1,236 @@ +/* + * Copyright (c) 2012 Will Drewry + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * Uncomment the SANDBOX_SECCOMP_FILTER_DEBUG macro below to help diagnose + * filter breakage during development. *Do not* use this in production, + * as it relies on making library calls that are unsafe in signal context. + * + * Instead, live systems the auditctl(8) may be used to monitor failures. + * E.g. + * auditctl -a task,always -F uid= + */ +/* #define SANDBOX_SECCOMP_FILTER_DEBUG 1 */ + +#ifdef SANDBOX_SECCOMP_FILTER_DEBUG +/* Use the kernel headers in case of an older toolchain. */ +# include +# define __have_siginfo_t 1 +# define __have_sigval_t 1 +# define __have_sigevent_t 1 +#endif /* SANDBOX_SECCOMP_FILTER_DEBUG */ + +#include "includes.h" + +#ifdef SANDBOX_SECCOMP_FILTER + +#include +#include +#include + +#include +#include +#include +#include + +#include + +#include +#include +#include +#include /* for offsetof */ +#include +#include +#include +#include + +#include "log.h" +#include "ssh-sandbox.h" +#include "xmalloc.h" + +/* Linux seccomp_filter sandbox */ +#define SECCOMP_FILTER_FAIL SECCOMP_RET_KILL + +/* Use a signal handler to emit violations when debugging */ +#ifdef SANDBOX_SECCOMP_FILTER_DEBUG +# undef SECCOMP_FILTER_FAIL +# define SECCOMP_FILTER_FAIL SECCOMP_RET_TRAP +#endif /* SANDBOX_SECCOMP_FILTER_DEBUG */ + +/* Simple helpers to avoid manual errors (but larger BPF programs). */ +#define SC_DENY(_nr, _errno) \ + BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, __NR_ ## _nr, 0, 1), \ + BPF_STMT(BPF_RET+BPF_K, SECCOMP_RET_ERRNO|(_errno)) +#define SC_ALLOW(_nr) \ + BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, __NR_ ## _nr, 0, 1), \ + BPF_STMT(BPF_RET+BPF_K, SECCOMP_RET_ALLOW) + +/* Syscall filtering set for preauth. */ +static const struct sock_filter preauth_insns[] = { + /* Ensure the syscall arch convention is as expected. */ + BPF_STMT(BPF_LD+BPF_W+BPF_ABS, + offsetof(struct seccomp_data, arch)), + BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, SECCOMP_AUDIT_ARCH, 1, 0), + BPF_STMT(BPF_RET+BPF_K, SECCOMP_FILTER_FAIL), + /* Load the syscall number for checking. */ + BPF_STMT(BPF_LD+BPF_W+BPF_ABS, + offsetof(struct seccomp_data, nr)), + SC_DENY(open, EACCES), + SC_ALLOW(getpid), + SC_ALLOW(gettimeofday), +#ifdef __NR_time /* not defined on EABI ARM */ + SC_ALLOW(time), +#endif + SC_ALLOW(read), + SC_ALLOW(write), + SC_ALLOW(close), + SC_ALLOW(brk), + SC_ALLOW(poll), +#ifdef __NR__newselect + SC_ALLOW(_newselect), +#else + SC_ALLOW(select), +#endif + SC_ALLOW(madvise), +#ifdef __NR_mmap2 /* EABI ARM only has mmap2() */ + SC_ALLOW(mmap2), +#endif +#ifdef __NR_mmap + SC_ALLOW(mmap), +#endif + SC_ALLOW(munmap), + SC_ALLOW(exit_group), +#ifdef __NR_rt_sigprocmask + SC_ALLOW(rt_sigprocmask), +#else + SC_ALLOW(sigprocmask), +#endif + BPF_STMT(BPF_RET+BPF_K, SECCOMP_FILTER_FAIL), +}; + +static const struct sock_fprog preauth_program = { + .len = (unsigned short)(sizeof(preauth_insns)/sizeof(preauth_insns[0])), + .filter = (struct sock_filter *)preauth_insns, +}; + +struct ssh_sandbox { + pid_t child_pid; +}; + +struct ssh_sandbox * +ssh_sandbox_init(void) +{ + struct ssh_sandbox *box; + + /* + * Strictly, we don't need to maintain any state here but we need + * to return non-NULL to satisfy the API. + */ + debug3("%s: preparing seccomp filter sandbox", __func__); + box = xcalloc(1, sizeof(*box)); + box->child_pid = 0; + + return box; +} + +#ifdef SANDBOX_SECCOMP_FILTER_DEBUG +extern struct monitor *pmonitor; +void mm_log_handler(LogLevel level, const char *msg, void *ctx); + +static void +ssh_sandbox_violation(int signum, siginfo_t *info, void *void_context) +{ + char msg[256]; + + snprintf(msg, sizeof(msg), + "%s: unexpected system call (arch:0x%x,syscall:%d @ %p)", + __func__, info->si_arch, info->si_syscall, info->si_call_addr); + mm_log_handler(SYSLOG_LEVEL_FATAL, msg, pmonitor); + _exit(1); +} + +static void +ssh_sandbox_child_debugging(void) +{ + struct sigaction act; + sigset_t mask; + + debug3("%s: installing SIGSYS handler", __func__); + memset(&act, 0, sizeof(act)); + sigemptyset(&mask); + sigaddset(&mask, SIGSYS); + + act.sa_sigaction = &ssh_sandbox_violation; + act.sa_flags = SA_SIGINFO; + if (sigaction(SIGSYS, &act, NULL) == -1) + fatal("%s: sigaction(SIGSYS): %s", __func__, strerror(errno)); + if (sigprocmask(SIG_UNBLOCK, &mask, NULL) == -1) + fatal("%s: sigprocmask(SIGSYS): %s", + __func__, strerror(errno)); +} +#endif /* SANDBOX_SECCOMP_FILTER_DEBUG */ + +void +ssh_sandbox_child(struct ssh_sandbox *box) +{ + struct rlimit rl_zero; + int nnp_failed = 0; + + /* Set rlimits for completeness if possible. */ + rl_zero.rlim_cur = rl_zero.rlim_max = 0; + if (setrlimit(RLIMIT_FSIZE, &rl_zero) == -1) + fatal("%s: setrlimit(RLIMIT_FSIZE, { 0, 0 }): %s", + __func__, strerror(errno)); + if (setrlimit(RLIMIT_NOFILE, &rl_zero) == -1) + fatal("%s: setrlimit(RLIMIT_NOFILE, { 0, 0 }): %s", + __func__, strerror(errno)); + if (setrlimit(RLIMIT_NPROC, &rl_zero) == -1) + fatal("%s: setrlimit(RLIMIT_NPROC, { 0, 0 }): %s", + __func__, strerror(errno)); + +#ifdef SANDBOX_SECCOMP_FILTER_DEBUG + ssh_sandbox_child_debugging(); +#endif /* SANDBOX_SECCOMP_FILTER_DEBUG */ + + debug3("%s: setting PR_SET_NO_NEW_PRIVS", __func__); + if (prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0) == -1) { + debug("%s: prctl(PR_SET_NO_NEW_PRIVS): %s", + __func__, strerror(errno)); + nnp_failed = 1; + } + debug3("%s: attaching seccomp filter program", __func__); + if (prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &preauth_program) == -1) + debug("%s: prctl(PR_SET_SECCOMP): %s", + __func__, strerror(errno)); + else if (nnp_failed) + fatal("%s: SECCOMP_MODE_FILTER activated but " + "PR_SET_NO_NEW_PRIVS failed", __func__); +} + +void +ssh_sandbox_parent_finish(struct ssh_sandbox *box) +{ + free(box); + debug3("%s: finished", __func__); +} + +void +ssh_sandbox_parent_preauth(struct ssh_sandbox *box, pid_t child_pid) +{ + box->child_pid = child_pid; +} + +#endif /* SANDBOX_SECCOMP_FILTER */ diff --git a/etc/Makefile b/etc/Makefile index 6e2a716cbcaf..ae52d791324d 100644 --- a/etc/Makefile +++ b/etc/Makefile @@ -50,6 +50,10 @@ BIN1= crontab \ syslog.conf \ termcap.small +.if ${MACHINE_ARCH} == "amd64" || ${MACHINE_ARCH} == "powerpc64" +BIN1+= libmap32.conf +.endif + .if exists(${.CURDIR}/etc.${MACHINE}/ttys) BIN1+= etc.${MACHINE}/ttys .elif exists(${.CURDIR}/etc.${MACHINE_ARCH}/ttys) diff --git a/etc/libmap32.conf b/etc/libmap32.conf new file mode 100644 index 000000000000..07fb13803c0c --- /dev/null +++ b/etc/libmap32.conf @@ -0,0 +1,2 @@ +# $FreeBSD$ +/usr/lib/private /usr/lib32/private diff --git a/etc/mtree/BSD.usr.dist b/etc/mtree/BSD.usr.dist index 636a5d2936d6..c06d3e1af678 100644 --- a/etc/mtree/BSD.usr.dist +++ b/etc/mtree/BSD.usr.dist @@ -24,12 +24,16 @@ .. i18n .. + private + .. .. lib32 dtrace .. i18n .. + private + .. .. libdata gcc diff --git a/etc/mtree/BSD.var.dist b/etc/mtree/BSD.var.dist index 6a9a7f49426c..196ee42ad19d 100644 --- a/etc/mtree/BSD.var.dist +++ b/etc/mtree/BSD.var.dist @@ -23,6 +23,8 @@ remote uname=auditdistd gname=wheel mode=0700 .. .. + authpf uname=root gname=authpf mode=0770 + .. /set gname=wheel backups .. diff --git a/etc/rc.d/ipfilter b/etc/rc.d/ipfilter index ec8e2f16c170..d540a6f98646 100755 --- a/etc/rc.d/ipfilter +++ b/etc/rc.d/ipfilter @@ -29,7 +29,7 @@ required_modules="ipl:ipfilter" ipfilter_start() { echo "Enabling ipfilter." - if [ `sysctl -n net.inet.ipf.fr_running` -le 0 ]; then + if ! ${ipfilter_program:-/sbin/ipf} -V | grep -q 'Running: yes'; then ${ipfilter_program:-/sbin/ipf} -E fi ${ipfilter_program:-/sbin/ipf} -Fa @@ -37,7 +37,6 @@ ipfilter_start() ${ipfilter_program:-/sbin/ipf} \ -f "${ipfilter_rules}" ${ipfilter_flags} fi - ${ipfilter_program:-/sbin/ipf} -6 -Fa if [ -r "${ipv6_ipfilter_rules}" ]; then ${ipfilter_program:-/sbin/ipf} -6 \ -f "${ipv6_ipfilter_rules}" ${ipfilter_flags} @@ -46,8 +45,7 @@ ipfilter_start() ipfilter_stop() { - # XXX - The ipf -D command is not effective for 'lkm's - if [ `sysctl -n net.inet.ipf.fr_running` -eq 1 ]; then + if ${ipfilter_program:-/sbin/ipf} -V | grep -q 'Running: yes'; then echo "Saving firewall state tables" ${ipfs_program:-/sbin/ipfs} -W ${ipfs_flags} echo "Disabling ipfilter." diff --git a/etc/rc.d/ipfs b/etc/rc.d/ipfs index ff4c74d301d5..ac6d5c2a7a1e 100755 --- a/etc/rc.d/ipfs +++ b/etc/rc.d/ipfs @@ -23,7 +23,7 @@ ipfs_prestart() if ! checkyesno ipfilter_enable -o ! checkyesno ipnat_enable ; then err 1 "${name} requires either ipfilter or ipnat enabled" fi - if ! sysctl net.inet.ipf.fr_pass >/dev/null 2>&1; then + if ! ${ipfilter_program:-/sbin/ipf} -V | grep -q 'Running: yes' >/dev/null 2>&1; then err 1 "ipfilter module is not loaded" fi return 0 diff --git a/etc/rc.d/ipmon b/etc/rc.d/ipmon index 27f483c97468..cdd87426695c 100755 --- a/etc/rc.d/ipmon +++ b/etc/rc.d/ipmon @@ -23,7 +23,7 @@ ipmon_precmd() if ! checkyesno ipfilter_enable && ! checkyesno ipnat_enable ; then err 1 "${name} requires either ipfilter or ipnat enabled" fi - if ! sysctl net.inet.ipf.fr_pass >/dev/null 2>&1; then + if ! ${ipfilter_program:-/sbin/ipf} -V | grep -q 'Running: yes' >/dev/null 2>&1; then err 1 "ipfilter module is not loaded" fi return 0 diff --git a/gnu/lib/Makefile b/gnu/lib/Makefile index 6750403d66c5..50797fced309 100644 --- a/gnu/lib/Makefile +++ b/gnu/lib/Makefile @@ -10,7 +10,7 @@ SUBDIR+= libssp # libsupc++ uses libstdc++ headers, although 'make includes' should # have taken care of that already. -.if ${MK_CXX} != "no" +.if ${MK_GNUCXX} != "no" SUBDIR+= libstdc++ libsupc++ .endif diff --git a/gnu/usr.bin/cc/Makefile b/gnu/usr.bin/cc/Makefile index efb548aaf62e..bf6d20c79ce4 100644 --- a/gnu/usr.bin/cc/Makefile +++ b/gnu/usr.bin/cc/Makefile @@ -12,7 +12,12 @@ SUBDIR+= cpp .endif .if ${MK_CXX} != "no" -SUBDIR+= cc1plus c++ c++filt +.if ${MK_GNUCXX} != "no" +SUBDIR+= cc1plus c++ +.endif +# This should be moved into the above block once c++filt from elftoolchain or +# similar is provided. +SUBDIR+= c++filt .endif .if ${MK_GCOV} != "no" diff --git a/include/iconv.h b/include/iconv.h index 3423a24d063b..69cc2c7d16a6 100644 --- a/include/iconv.h +++ b/include/iconv.h @@ -35,7 +35,6 @@ #include #include -#include #include #include @@ -48,6 +47,13 @@ #define libiconv iconv #define libiconv_t iconv_t #endif +#ifdef __cplusplus +typedef bool __iconv_bool; +#elif __STDC_VERSION__ >= 199901L +typedef _Bool __iconv_bool; +#else +typedef int __iconv_bool; +#endif struct __tag_iconv_t; typedef struct __tag_iconv_t *iconv_t; @@ -61,7 +67,7 @@ int iconv_close(iconv_t); /* * non-portable interfaces for iconv */ -int __iconv_get_list(char ***, size_t *, bool); +int __iconv_get_list(char ***, size_t *, __iconv_bool); void __iconv_free_list(char **, size_t); size_t __iconv(iconv_t, const char **, size_t *, char **, size_t *, __uint32_t, size_t *); diff --git a/kerberos5/Makefile.inc b/kerberos5/Makefile.inc index 51cfe34ec366..79355ddaa3b6 100644 --- a/kerberos5/Makefile.inc +++ b/kerberos5/Makefile.inc @@ -14,8 +14,6 @@ LDAPCFLAGS= -I${OPENLDAPBASE}/include -DOPENLDAP=1 -DLDAP_DEPRECATED=1 LDAPLDFLAGS= -L${OPENLDAPBASE}/lib -Wl,-rpath,${OPENLDAPBASE}/lib .endif -LIBHEIMIPCC= ${.OBJDIR}/../../lib/libheimipcc/libheimipcc.a -LIBHEIMIPCS= ${.OBJDIR}/../../lib/libheimipcs/libheimipcs.a LIBVERS= ${.OBJDIR}/../../lib/libvers/libvers.a LIBSL= ${.OBJDIR}/../../lib/libsl/libsl.a diff --git a/kerberos5/lib/libheimipcc/Makefile b/kerberos5/lib/libheimipcc/Makefile index adb8f579c536..eaab2d24d1fb 100644 --- a/kerberos5/lib/libheimipcc/Makefile +++ b/kerberos5/lib/libheimipcc/Makefile @@ -1,7 +1,7 @@ #$FreeBSD$ LIB= heimipcc -INTERNALLIB= +PRIVATELIB= LDADD= -lheimbase -lroken -lpthread DPADD= ${LIBHEIMBASE} ${LIBROKEN} ${LIBPTHREAD} @@ -9,7 +9,6 @@ SRCS= \ client.c \ common.c -CFLAGS+= -DPIC ${PICFLAG} CFLAGS+= -I${KRB5DIR}/lib/roken \ -I${KRB5DIR}/base \ -I${KRB5DIR}/lib/ipc diff --git a/kerberos5/lib/libheimipcs/Makefile b/kerberos5/lib/libheimipcs/Makefile index 55add1add4e6..31fd4afa1a56 100644 --- a/kerberos5/lib/libheimipcs/Makefile +++ b/kerberos5/lib/libheimipcs/Makefile @@ -1,7 +1,7 @@ #$FreeBSD$ LIB= heimipcs -INTERNALLIB= +PRIVATELIB= LDADD= -lheimbase -lroken LDFLAGS= -pthread DPADD= ${LIBHEIMBASE} ${LIBROKEN} @@ -10,7 +10,6 @@ SRCS= \ server.c \ common.c -CFLAGS+= -DPIC ${PICFLAG} CFLAGS+= -I${KRB5DIR}/lib/roken \ -I${KRB5DIR}/base \ -I${KRB5DIR}/lib/ipc -I. diff --git a/kerberos5/lib/libkrb5/Makefile b/kerberos5/lib/libkrb5/Makefile index 47368576a668..b30ec755d4b7 100644 --- a/kerberos5/lib/libkrb5/Makefile +++ b/kerberos5/lib/libkrb5/Makefile @@ -3,8 +3,9 @@ LIB= krb5 LDFLAGS= -Wl,--no-undefined VERSION_MAP= ${KRB5DIR}/lib/krb5/version-script.map -LDADD= -lasn1 -lcom_err -lcrypt -lcrypto -lhx509 -lroken -lwind -lheimbase ${LIBHEIMIPCC} +LDADD= -lasn1 -lcom_err -lcrypt -lcrypto -lhx509 -lroken -lwind -lheimbase -lheimipcc DPADD= ${LIBASN1} ${LIBCOM_ERR} ${LIBCRYPT} ${LIBCRYPTO} ${LIBHX509} ${LIBROKEN} ${LIBWIND} ${LIBHEIMBASE} ${LIBHEIMIPCC} +USEPRIVATELIB= heimipcc INCS= heim_err.h \ heim_threads.h \ diff --git a/kerberos5/libexec/digest-service/Makefile b/kerberos5/libexec/digest-service/Makefile index 82a8bc4f78bd..79a7c8b50177 100644 --- a/kerberos5/libexec/digest-service/Makefile +++ b/kerberos5/libexec/digest-service/Makefile @@ -8,10 +8,11 @@ CFLAGS+= -I${KRB5DIR}/kdc \ -I${KRB5DIR}/lib/ipc \ -I${KRB5DIR}/lib/wind \ -I${KRB5DIR}/lib/roken -DPADD= ${LIBHDB} ${LIBKDC} ${LIBHEIMIPCS} ${LIBKRB5} ${LIBROKEN} ${LIBASN1} ${LIBCRYPTO} \ - ${LIBCRYPT} ${LIBVERS} -LDADD= -lhdb -lkdc ${LIBHEIMIPCS} -lkrb5 -lroken -lasn1 -lcrypto -lcrypt \ +DPADD= ${LIBHDB} ${LIBKDC} ${LIBHEIMIPCS} ${LIBKRB5} ${LIBROKEN} ${LIBASN1} \ + ${LIBCRYPTO} ${LIBCRYPT} ${LIBVERS} +LDADD= -lhdb -lkdc -lheimipcs -lkrb5 -lroken -lasn1 -lcrypto -lcrypt \ ${LIBVERS} -lheimntlm +USEPRIVATELIB= heimipcs .include diff --git a/kerberos5/libexec/kcm/Makefile b/kerberos5/libexec/kcm/Makefile index 2643b83b690a..bc84c051831c 100644 --- a/kerberos5/libexec/kcm/Makefile +++ b/kerberos5/libexec/kcm/Makefile @@ -21,8 +21,9 @@ CFLAGS+=-I${KRB5DIR}/lib/krb5 -I${KRB5DIR}/lib/asn1 -I${KRB5DIR}/lib/roken \ -I${KRB5DIR}/kcm -I${KRB5DIR}/lib/ipc ${LDAPCFLAGS} DPADD= ${LIBHDB} ${LIBKRB5} ${LIBROKEN} ${LIBASN1} ${LIBHEIMNTLM} \ ${LIBHEIMIPCS} ${LIBCRYPTO} ${LIBCRYPT} ${LIBVERS} ${LDAPDPADD} -LDADD= -lhdb -lkrb5 -lroken -lasn1 -lheimntlm ${LIBHEIMIPCS} \ +LDADD= -lhdb -lkrb5 -lroken -lasn1 -lheimntlm -lheimipcs \ -lcrypto -lcrypt ${LIBVERS} ${LDAPLDADD} +USEPRIVATELIB= heimipcs LDFLAGS=${LDAPLDFLAGS} .include diff --git a/lib/libc/Makefile b/lib/libc/Makefile index cf2d2aa52529..2806cc7083e5 100644 --- a/lib/libc/Makefile +++ b/lib/libc/Makefile @@ -100,6 +100,7 @@ NOASM= CFLAGS+= -DYP .include "${.CURDIR}/yp/Makefile.inc" .endif +.include "${.CURDIR}/capability/Makefile.inc" .if ${MK_HESIOD} != "no" CFLAGS+= -DHESIOD .endif diff --git a/lib/libc/arm/_fpmath.h b/lib/libc/arm/_fpmath.h index 4c189459770c..28bcb4b4ffde 100644 --- a/lib/libc/arm/_fpmath.h +++ b/lib/libc/arm/_fpmath.h @@ -26,7 +26,7 @@ * $FreeBSD$ */ -#if defined(__VFP_FP__) +#if defined(__VFP_FP__) || defined(__ARM_EABI__) #define _IEEE_WORD_ORDER _BYTE_ORDER #else #define _IEEE_WORD_ORDER _BIG_ENDIAN diff --git a/lib/libc/arm/arith.h b/lib/libc/arm/arith.h index be78d862756d..5e2e3891dd91 100644 --- a/lib/libc/arm/arith.h +++ b/lib/libc/arm/arith.h @@ -11,7 +11,7 @@ * architecture. See contrib/gdtoa/gdtoaimp.h for details. */ -#if !defined(__ARMEB__) && defined(__VFP_FP__) +#if !defined(__ARMEB__) && (defined(__VFP_FP__) || defined(__ARM_EABI__)) #define IEEE_8087 #define Arith_Kind_ASL 1 #define Sudden_Underflow diff --git a/lib/libc/arm/softfloat/arm-gcc.h b/lib/libc/arm/softfloat/arm-gcc.h index 15bc509fbcb3..0e20ef91f059 100644 --- a/lib/libc/arm/softfloat/arm-gcc.h +++ b/lib/libc/arm/softfloat/arm-gcc.h @@ -91,7 +91,7 @@ what the endianness of the CPU. VFP is sane. ------------------------------------------------------------------------------- */ #if defined(SOFTFLOAT_FOR_GCC) -#if defined(__VFP_FP__) || defined(__ARMEB__) +#if defined (__ARM_EABI__) || defined(__VFP_FP__) || defined(__ARMEB__) #define FLOAT64_DEMANGLE(a) (a) #define FLOAT64_MANGLE(a) (a) #else diff --git a/lib/libc/capability/Makefile.inc b/lib/libc/capability/Makefile.inc new file mode 100644 index 000000000000..934fc8b91767 --- /dev/null +++ b/lib/libc/capability/Makefile.inc @@ -0,0 +1,19 @@ +# $FreeBSD$ + +# capability sources +.PATH: ${.CURDIR}/../../sys/kern + +SRCS+= subr_capability.c + +SYM_MAPS+= ${.CURDIR}/capability/Symbol.map + +#MAN+= cap_rights_init.3 + +#MLINKS+=cap_rights_init.3 cap_rights_set.3 +#MLINKS+=cap_rights_init.3 cap_rights_clear.3 +#MLINKS+=cap_rights_init.3 cap_rights_is_set.3 +#MLINKS+=cap_rights_init.3 cap_rights_is_valid.3 +#MLINKS+=cap_rights_init.3 cap_rights_merge.3 +#MLINKS+=cap_rights_init.3 cap_rights_remove.3 +#MLINKS+=cap_rights_init.3 cap_rights_contains.3 + diff --git a/lib/libc/capability/Symbol.map b/lib/libc/capability/Symbol.map new file mode 100644 index 000000000000..c5c18c2f5315 --- /dev/null +++ b/lib/libc/capability/Symbol.map @@ -0,0 +1,14 @@ +/* + * $FreeBSD$ + */ + +FBSD_1.3 { + __cap_rights_clear; + cap_rights_contains; + __cap_rights_init; + __cap_rights_is_set; + cap_rights_is_valid; + cap_rights_merge; + cap_rights_remove; + __cap_rights_set; +}; diff --git a/lib/libc/iconv/citrus_iconv_local.h b/lib/libc/iconv/citrus_iconv_local.h index 52ac8251cd24..e673c9a6afa1 100644 --- a/lib/libc/iconv/citrus_iconv_local.h +++ b/lib/libc/iconv/citrus_iconv_local.h @@ -31,6 +31,7 @@ #define _CITRUS_ICONV_LOCAL_H_ #include +#include #define _CITRUS_ICONV_GETOPS_FUNC_BASE(_n_) \ int _n_(struct _citrus_iconv_ops *) diff --git a/lib/libc/include/compat.h b/lib/libc/include/compat.h index 3739fe105c8f..769454002788 100644 --- a/lib/libc/include/compat.h +++ b/lib/libc/include/compat.h @@ -42,8 +42,6 @@ __sym_compat(__semctl, freebsd7___semctl, FBSD_1.0); __sym_compat(msgctl, freebsd7_msgctl, FBSD_1.0); __sym_compat(shmctl, freebsd7_shmctl, FBSD_1.0); -__sym_compat(cap_getrights, cap_rights_get, FBSD_1.2); - #undef __sym_compat #endif /* __LIBC_COMPAT_H__ */ diff --git a/lib/libc/net/getaddrinfo.c b/lib/libc/net/getaddrinfo.c index c6af6d8f6435..495ebc1ed6d8 100644 --- a/lib/libc/net/getaddrinfo.c +++ b/lib/libc/net/getaddrinfo.c @@ -831,7 +831,8 @@ set_source(struct ai_order *aio, struct policyhead *ph) get_port(&ai, "1", 0); /* open a socket to get the source address for the given dst */ - if ((s = _socket(ai.ai_family, ai.ai_socktype, ai.ai_protocol)) < 0) + if ((s = _socket(ai.ai_family, ai.ai_socktype | SOCK_CLOEXEC, + ai.ai_protocol)) < 0) return; /* give up */ if (_connect(s, ai.ai_addr, ai.ai_addrlen) < 0) goto cleanup; @@ -1131,7 +1132,7 @@ explore_null(const struct addrinfo *pai, const char *servname, * filter out AFs that are not supported by the kernel * XXX errno? */ - s = _socket(pai->ai_family, SOCK_DGRAM, 0); + s = _socket(pai->ai_family, SOCK_DGRAM | SOCK_CLOEXEC, 0); if (s < 0) { if (errno != EMFILE) return 0; @@ -1541,18 +1542,19 @@ addrconfig(struct addrinfo *pai) */ af = pai->ai_family; if (af == AF_UNSPEC) { - if ((s = _socket(AF_INET6, SOCK_DGRAM, 0)) < 0) + if ((s = _socket(AF_INET6, SOCK_DGRAM | SOCK_CLOEXEC, 0)) < 0) af = AF_INET; else { _close(s); - if ((s = _socket(AF_INET, SOCK_DGRAM, 0)) < 0) + if ((s = _socket(AF_INET, SOCK_DGRAM | SOCK_CLOEXEC, + 0)) < 0) af = AF_INET6; else _close(s); } } if (af != AF_UNSPEC) { - if ((s = _socket(af, SOCK_DGRAM, 0)) < 0) + if ((s = _socket(af, SOCK_DGRAM | SOCK_CLOEXEC, 0)) < 0) return 0; _close(s); } diff --git a/lib/libc/net/if_nametoindex.c b/lib/libc/net/if_nametoindex.c index 89076c0e021c..8f04921760eb 100644 --- a/lib/libc/net/if_nametoindex.c +++ b/lib/libc/net/if_nametoindex.c @@ -68,7 +68,7 @@ if_nametoindex(const char *ifname) struct ifaddrs *ifaddrs, *ifa; unsigned int ni; - s = _socket(AF_INET, SOCK_DGRAM, 0); + s = _socket(AF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0); if (s != -1) { #ifdef PURIFY memset(&ifr, 0, sizeof(ifr)); diff --git a/lib/libc/net/name6.c b/lib/libc/net/name6.c index 118e033e128d..97880a25e7d8 100644 --- a/lib/libc/net/name6.c +++ b/lib/libc/net/name6.c @@ -235,7 +235,7 @@ getipnodebyname(const char *name, int af, int flags, int *errp) if (flags & AI_ADDRCONFIG) { int s; - if ((s = _socket(af, SOCK_DGRAM, 0)) < 0) + if ((s = _socket(af, SOCK_DGRAM | SOCK_CLOEXEC, 0)) < 0) return NULL; /* * TODO: @@ -868,7 +868,8 @@ set_source(struct hp_order *aio, struct policyhead *ph) } /* open a socket to get the source address for the given dst */ - if ((s = _socket(ss.ss_family, SOCK_DGRAM, IPPROTO_UDP)) < 0) + if ((s = _socket(ss.ss_family, SOCK_DGRAM | SOCK_CLOEXEC, + IPPROTO_UDP)) < 0) return; /* give up */ if (_connect(s, (struct sockaddr *)&ss, ss.ss_len) < 0) goto cleanup; diff --git a/lib/libc/net/nscachedcli.c b/lib/libc/net/nscachedcli.c index b4de0c152dd0..2ceacb7e9b0b 100644 --- a/lib/libc/net/nscachedcli.c +++ b/lib/libc/net/nscachedcli.c @@ -200,7 +200,7 @@ __open_cached_connection(struct cached_connection_params const *params) assert(params != NULL); - client_socket = _socket(PF_LOCAL, SOCK_STREAM, 0); + client_socket = _socket(PF_LOCAL, SOCK_STREAM | SOCK_CLOEXEC, 0); client_address.sun_family = PF_LOCAL; strncpy(client_address.sun_path, params->socket_path, sizeof(client_address.sun_path)); diff --git a/lib/libc/resolv/res_send.c b/lib/libc/resolv/res_send.c index 716ae32f6a19..4896fe8cb36d 100644 --- a/lib/libc/resolv/res_send.c +++ b/lib/libc/resolv/res_send.c @@ -660,7 +660,8 @@ send_vc(res_state statp, if (statp->_vcsock >= 0) res_nclose(statp); - statp->_vcsock = _socket(nsap->sa_family, SOCK_STREAM, 0); + statp->_vcsock = _socket(nsap->sa_family, SOCK_STREAM | + SOCK_CLOEXEC, 0); #if !defined(USE_POLL) && !defined(USE_KQUEUE) if (statp->_vcsock > highestFD) { res_nclose(statp); @@ -851,7 +852,7 @@ send_dg(res_state statp, nsaplen = get_salen(nsap); if (EXT(statp).nssocks[ns] == -1) { EXT(statp).nssocks[ns] = _socket(nsap->sa_family, - SOCK_DGRAM, 0); + SOCK_DGRAM | SOCK_CLOEXEC, 0); #if !defined(USE_POLL) && !defined(USE_KQUEUE) if (EXT(statp).nssocks[ns] > highestFD) { res_nclose(statp); diff --git a/lib/libc/stdio/flags.c b/lib/libc/stdio/flags.c index 1878c2f4e134..b7552a43804c 100644 --- a/lib/libc/stdio/flags.c +++ b/lib/libc/stdio/flags.c @@ -51,7 +51,7 @@ __FBSDID("$FreeBSD$"); int __sflags(const char *mode, int *optr) { - int ret, m, o; + int ret, m, o, known; switch (*mode++) { @@ -78,34 +78,35 @@ __sflags(const char *mode, int *optr) return (0); } - /* 'b' (binary) is ignored */ - if (*mode == 'b') - mode++; - - /* [rwa][b]\+ means read and write */ - if (*mode == '+') { - mode++; - ret = __SRW; - m = O_RDWR; - } - - /* 'b' (binary) can appear here, too -- and is ignored again */ - if (*mode == 'b') - mode++; - - /* 'x' means exclusive (fail if the file exists) */ - if (*mode == 'x') { - mode++; - if (m == O_RDONLY) { - errno = EINVAL; - return (0); + do { + known = 1; + switch (*mode++) { + case 'b': + /* 'b' (binary) is ignored */ + break; + case '+': + /* [rwa][b]\+ means read and write */ + ret = __SRW; + m = O_RDWR; + break; + case 'x': + /* 'x' means exclusive (fail if the file exists) */ + o |= O_EXCL; + break; + case 'e': + /* set close-on-exec */ + o |= O_CLOEXEC; + break; + default: + known = 0; + break; } - o |= O_EXCL; - } + } while (known); - /* set close-on-exec */ - if (*mode == 'e') - o |= O_CLOEXEC; + if ((o & O_EXCL) != 0 && m == O_RDONLY) { + errno = EINVAL; + return (0); + } *optr = m | o; return (ret); diff --git a/lib/libc/sys/Symbol.map b/lib/libc/sys/Symbol.map index 4f1104e170be..222f5f0811f5 100644 --- a/lib/libc/sys/Symbol.map +++ b/lib/libc/sys/Symbol.map @@ -363,7 +363,6 @@ FBSD_1.1 { FBSD_1.2 { cap_enter; cap_getmode; - cap_new; getloginclass; pdfork; pdgetpid; @@ -385,7 +384,7 @@ FBSD_1.3 { cap_fcntls_limit; cap_ioctls_get; cap_ioctls_limit; - cap_rights_get; + __cap_rights_get; cap_rights_limit; cap_sandboxed; chflagsat; diff --git a/lib/libc/sys/mmap.2 b/lib/libc/sys/mmap.2 index 130f70bcaa88..01cde0ee5fe9 100644 --- a/lib/libc/sys/mmap.2 +++ b/lib/libc/sys/mmap.2 @@ -28,7 +28,7 @@ .\" @(#)mmap.2 8.4 (Berkeley) 5/11/95 .\" $FreeBSD$ .\" -.Dd August 16, 2013 +.Dd September 9, 2013 .Dt MMAP 2 .Os .Sh NAME @@ -98,6 +98,12 @@ argument by .Em or Ns 'ing the following values: .Bl -tag -width MAP_PREFAULT_READ +.It Dv MAP_32BIT +Request a region in the first 2GB of the current process's address space. +If a suitable region cannot be found, +.Fn mmap +will fail. +This flag is only available on 64-bit platforms. .It Dv MAP_ALIGNED Ns Pq Fa n Align the region on a requested boundary. If a suitable region cannot be found, @@ -362,6 +368,13 @@ was specified and the argument was not page aligned, or part of the desired address space resides out of the valid address space for a user process. .It Bq Er EINVAL +Both +.Dv MAP_FIXED +and +.Dv MAP_32BIT +were specified and part of the desired address space resides outside +of the first 2GB of user address space. +.It Bq Er EINVAL The .Fa len argument diff --git a/lib/libc/sys/sigaction.2 b/lib/libc/sys/sigaction.2 index d975ef931653..5c784f64475d 100644 --- a/lib/libc/sys/sigaction.2 +++ b/lib/libc/sys/sigaction.2 @@ -28,7 +28,7 @@ .\" From: @(#)sigaction.2 8.2 (Berkeley) 4/3/94 .\" $FreeBSD$ .\" -.Dd June 8, 2013 +.Dd September 6, 2013 .Dt SIGACTION 2 .Os .Sh NAME @@ -55,7 +55,7 @@ struct sigaction { .Sh DESCRIPTION The system defines a set of signals that may be delivered to a process. Signal delivery resembles the occurrence of a hardware interrupt: -the signal is normally blocked from further occurrence, the current process +the signal is normally blocked from further occurrence, the current thread context is saved, and a new one is built. A process may specify a .Em handler @@ -64,13 +64,14 @@ to which a signal is delivered, or specify that a signal is to be A process may also specify that a default action is to be taken by the system when a signal occurs. A signal may also be -.Em blocked , -in which case its delivery is postponed until it is +.Em blocked +for a thread, +in which case it will not be delivered to that thread until it is .Em unblocked . The action to be taken on delivery is determined at the time of delivery. Normally, signal handlers execute on the current stack -of the process. +of the thread. This may be changed, on a per-handler basis, so that signals are taken on a special .Em "signal stack" . @@ -82,20 +83,30 @@ but other signals may yet occur. A global .Em "signal mask" defines the set of signals currently blocked from delivery -to a process. -The signal mask for a process is initialized +to a thread. +The signal mask for a thread is initialized from that of its parent (normally empty). It may be changed with a .Xr sigprocmask 2 -call, or when a signal is delivered to the process. +or +.Xr pthread_sigmask 3 +call, or when a signal is delivered to the thread. .Pp When a signal -condition arises for a process, the signal is added to a set of -signals pending for the process. -If the signal is not currently +condition arises for a process or thread, the signal is added to a set of +signals pending for the process or thread. +Whether the signal is directed at the process in general or at a specific +thread depends on how it is generated. +For signals directed at a specific thread, +if the signal is not currently .Em blocked -by the process then it is delivered to the process. -Signals may be delivered any time a process enters the operating system +by the thread then it is delivered to the thread. +For signals directed at the process, +if the signal is not currently +.Em blocked +by all threads then it is delivered to one thread that does not have it blocked +(the selection of which is unspecified). +Signals may be delivered any time a thread enters the operating system (e.g., during a system call, page fault or trap, or clock interrupt). If multiple signals are ready to be delivered at the same time, any signals that could be caused by traps are delivered first. @@ -106,17 +117,17 @@ The set of pending signals is returned by the .Xr sigpending 2 system call. When a caught signal -is delivered, the current state of the process is saved, +is delivered, the current state of the thread is saved, a new signal mask is calculated (as described below), and the signal handler is invoked. The call to the handler is arranged so that if the signal handling routine returns -normally the process will resume execution in the context +normally the thread will resume execution in the context from before the signal's delivery. -If the process wishes to resume in a different context, then it +If the thread wishes to resume in a different context, then it must arrange to restore the previous context itself. .Pp -When a signal is delivered to a process a new signal mask is +When a signal is delivered to a thread a new signal mask is installed for the duration of the process' signal handler (or until a .Xr sigprocmask 2 @@ -218,7 +229,7 @@ to If this bit is set, the system will deliver the signal to the process on a .Em "signal stack" , -specified with +specified by each thread with .Xr sigaltstack 2 . .It Dv SA_NODEFER If this bit is set, further occurrences of the delivered signal are @@ -272,6 +283,11 @@ However, calls that have already committed are not restarted, but instead return a partial success (for example, a short read count). .Pp After a +.Xr pthread_create 3 +the signal mask is inherited by the new thread and +the set of pending signals and the signal stack for the new thread are empty. +.Pp +After a .Xr fork 2 or .Xr vfork 2 diff --git a/lib/libc/sys/sigpending.2 b/lib/libc/sys/sigpending.2 index 37f92d89d155..06ecc004501d 100644 --- a/lib/libc/sys/sigpending.2 +++ b/lib/libc/sys/sigpending.2 @@ -31,7 +31,7 @@ .\" @(#)sigpending.2 8.3 (Berkeley) 1/12/94 .\" $FreeBSD$ .\" -.Dd January 12, 1994 +.Dd September 6, 2013 .Dt SIGPENDING 2 .Os .Sh NAME @@ -47,7 +47,7 @@ The .Fn sigpending system call returns a mask of the signals pending for delivery -to the calling process in the location indicated by +to the calling thread or the calling process in the location indicated by .Fa set . Signals may be pending because they are currently masked, or transiently before delivery (although the latter case is not diff --git a/lib/libc/sys/sigreturn.2 b/lib/libc/sys/sigreturn.2 index 13d76f68d48b..1b76468a84ec 100644 --- a/lib/libc/sys/sigreturn.2 +++ b/lib/libc/sys/sigreturn.2 @@ -28,7 +28,7 @@ .\" @(#)sigreturn.2 8.1 (Berkeley) 6/4/93 .\" $FreeBSD$ .\" -.Dd June 4, 1993 +.Dd September 6, 2013 .Dt SIGRETURN 2 .Os .Sh NAME @@ -46,7 +46,7 @@ The system call allows users to atomically unmask, switch stacks, and return from a signal context. -The processes signal mask and stack status are +The thread's signal mask and stack status are restored from the context structure pointed to by .Fa scp . The system call does not return; @@ -65,7 +65,7 @@ is set to indicate the error. The .Fn sigreturn system call -will fail and the process context will remain unchanged +will fail and the thread context will remain unchanged if one of the following occurs. .Bl -tag -width Er .It Bq Er EFAULT diff --git a/lib/libc/sys/sigwait.2 b/lib/libc/sys/sigwait.2 index 525bffb2689f..4da64a99dddd 100644 --- a/lib/libc/sys/sigwait.2 +++ b/lib/libc/sys/sigwait.2 @@ -27,7 +27,7 @@ .\" .\" $FreeBSD$ .\" -.Dd September 27, 2012 +.Dd September 6, 2013 .Dt SIGWAIT 2 .Os .Sh NAME @@ -50,7 +50,7 @@ waits until one or more of the selected signals has been generated. Then .Fn sigwait atomically clears one of the selected signals from the set of pending signals -for the process and sets the location pointed to by +(for the process or for the current thread) and sets the location pointed to by .Fa sig to the signal number that was cleared. .Pp diff --git a/lib/libc/sys/wait.2 b/lib/libc/sys/wait.2 index 0c494bb6fb5c..cfa78e9fd83a 100644 --- a/lib/libc/sys/wait.2 +++ b/lib/libc/sys/wait.2 @@ -28,7 +28,7 @@ .\" @(#)wait.2 8.2 (Berkeley) 4/19/94 .\" $FreeBSD$ .\" -.Dd November 10, 2012 +.Dd September 7, 2013 .Dt WAIT 2 .Os .Sh NAME @@ -604,9 +604,23 @@ are not specified by POSIX. The .Fn WCOREDUMP macro -and the ability to restart a pending -.Fn wait -call are extensions to the POSIX interface. +is an extension to the POSIX interface. +.Pp +The ability to use the +.Dv WNOWAIT +flag with +.Fn waitpid +is an extension; +.Tn POSIX +only permits this flag with +.Fn waitid . +.Pp +.Tn POSIX +requires +.Fn waitid +to return the full 32 bits passed to +.Xr _exit 2 ; +this implementation only returns 8 bits like in the other calls. .Sh HISTORY The .Fn wait diff --git a/lib/libiconv_modules/Makefile.inc b/lib/libiconv_modules/Makefile.inc index 994939008ab5..3b25374b91e5 100644 --- a/lib/libiconv_modules/Makefile.inc +++ b/lib/libiconv_modules/Makefile.inc @@ -5,6 +5,9 @@ SHLIB_MAJOR= 4 WARNS?= 6 CFLAGS+= -I${.CURDIR}/../../libc/iconv + +CFLAGS+= -Dbool=_Bool + .if !defined(COMPAT_32BIT) SHLIBDIR= /usr/lib/i18n .else diff --git a/lib/libldns/Makefile b/lib/libldns/Makefile index a46c3ab72847..ae3518a4f263 100644 --- a/lib/libldns/Makefile +++ b/lib/libldns/Makefile @@ -6,7 +6,7 @@ LDNSDIR = ${.CURDIR}/../../contrib/ldns .PATH: ${LDNSDIR} ${LDNSDIR}/compat LIB= ldns -INTERNALLIB= true +PRIVATELIB= true CFLAGS+= -I${LDNSDIR} @@ -18,6 +18,9 @@ SRCS= buffer.c dane.c dname.c dnssec.c dnssec_sign.c dnssec_verify.c \ SRCS+= b32_ntop.c b32_pton.c b64_ntop.c b64_pton.c +DPADD+= ${LIBCRYPTO} +LDADD+= -lcrypto + WARNS ?= 3 .include diff --git a/lib/libpam/libpam/Makefile b/lib/libpam/libpam/Makefile index b57a38e7b543..f5cd4cd214e1 100644 --- a/lib/libpam/libpam/Makefile +++ b/lib/libpam/libpam/Makefile @@ -36,12 +36,13 @@ # $FreeBSD$ OPENPAM= ${.CURDIR}/../../../contrib/openpam -.PATH: ${OPENPAM}/include ${OPENPAM}/lib ${OPENPAM}/doc/man +.PATH: ${OPENPAM}/include ${OPENPAM}/lib/libpam ${OPENPAM}/doc/man LIB= pam NO_PROFILE= -SRCS= openpam_borrow_cred.c \ +SRCS= openpam_asprintf.c \ + openpam_borrow_cred.c \ openpam_check_owner_perms.c \ openpam_configure.c \ openpam_constants.c \ @@ -63,8 +64,11 @@ SRCS= openpam_borrow_cred.c \ openpam_set_feature.c \ openpam_set_option.c \ openpam_straddch.c \ + openpam_strlcat.c \ + openpam_strlcpy.c \ openpam_subst.c \ openpam_ttyconv.c \ + openpam_vasprintf.c \ pam_acct_mgmt.c \ pam_authenticate.c \ pam_chauthtok.c \ @@ -151,6 +155,7 @@ CSTD?= c99 CFLAGS+= -I${.CURDIR} -I${OPENPAM}/include CFLAGS+= -DLIB_MAJ=${SHLIB_MAJOR} CFLAGS+= -DOPENPAM_MODULES_DIR='"${PAM_MOD_DIR:C/\/*$//}/"' +CFLAGS+= -DHAVE_DLFUNC=1 CFLAGS+= -DHAVE_FDLOPEN=1 CFLAGS+= -DHAVE_FPURGE=1 CFLAGS+= -DHAVE_STRLCAT=1 diff --git a/lib/libpam/modules/pam_ssh/Makefile b/lib/libpam/modules/pam_ssh/Makefile index d00652a8c215..886610a8fd14 100644 --- a/lib/libpam/modules/pam_ssh/Makefile +++ b/lib/libpam/modules/pam_ssh/Makefile @@ -15,6 +15,7 @@ CFLAGS+= -I${SSHDIR} -include ssh_namespace.h DPADD= ${LIBSSH} ${LIBCRYPTO} ${LIBCRYPT} LDADD= -lssh -lcrypto -lcrypt +USEPRIVATELIB= ssh .include diff --git a/lib/libprocstat/libprocstat.c b/lib/libprocstat/libprocstat.c index dfb5ed328194..9056151e2b4d 100644 --- a/lib/libprocstat/libprocstat.c +++ b/lib/libprocstat/libprocstat.c @@ -378,7 +378,7 @@ procstat_freefiles(struct procstat *procstat, struct filestat_list *head) static struct filestat * filestat_new_entry(void *typedep, int type, int fd, int fflags, int uflags, - int refcount, off_t offset, char *path, cap_rights_t cap_rights) + int refcount, off_t offset, char *path, cap_rights_t *cap_rightsp) { struct filestat *entry; @@ -395,7 +395,7 @@ filestat_new_entry(void *typedep, int type, int fd, int fflags, int uflags, entry->fs_ref_count = refcount; entry->fs_offset = offset; entry->fs_path = path; - entry->fs_cap_rights = cap_rights; + entry->fs_cap_rights = *cap_rightsp; return (entry); } @@ -851,7 +851,7 @@ procstat_getfiles_sysctl(struct procstat *procstat, struct kinfo_proc *kp, * Create filestat entry. */ entry = filestat_new_entry(kif, type, fd, fflags, uflags, - refcount, offset, path, cap_rights); + refcount, offset, path, &cap_rights); if (entry != NULL) STAILQ_INSERT_TAIL(head, entry, next); } diff --git a/lib/libprocstat/libprocstat.h b/lib/libprocstat/libprocstat.h index 65a5eb955324..7af6ccba14a2 100644 --- a/lib/libprocstat/libprocstat.h +++ b/lib/libprocstat/libprocstat.h @@ -36,6 +36,7 @@ #ifndef ZFS #include #endif +#include /* * Vnode types. diff --git a/lib/libusb/libusb20_ugen20.c b/lib/libusb/libusb20_ugen20.c index 341bfb6d71ad..e40bc07e61e0 100644 --- a/lib/libusb/libusb20_ugen20.c +++ b/lib/libusb/libusb20_ugen20.c @@ -697,7 +697,7 @@ ugen20_detach_kernel_driver(struct libusb20_device *pdev, if (ioctl(pdev->file_ctrl, IOUSB(USB_IFACE_DRIVER_DETACH), &temp)) { return (LIBUSB20_ERROR_OTHER); } - return (0); /* kernel driver is active */ + return (0); /* kernel driver is detached */ } static int @@ -724,7 +724,7 @@ ugen20_do_request_sync(struct libusb20_device *pdev, /* get actual length */ *pactlen = req.ucr_actlen; } - return (0); /* kernel driver is active */ + return (0); /* request was successful */ } static int diff --git a/lib/msun/Makefile b/lib/msun/Makefile index 14db97e05c59..629d52300d80 100644 --- a/lib/msun/Makefile +++ b/lib/msun/Makefile @@ -53,6 +53,7 @@ COMMON_SRCS= b_exp.c b_log.c b_tgamma.c \ e_pow.c e_powf.c e_rem_pio2.c \ e_rem_pio2f.c e_remainder.c e_remainderf.c e_scalb.c e_scalbf.c \ e_sinh.c e_sinhf.c e_sqrt.c e_sqrtf.c fenv.c \ + imprecise.c \ k_cos.c k_cosf.c k_exp.c k_expf.c k_rem_pio2.c k_sin.c k_sinf.c \ k_tan.c k_tanf.c \ s_asinh.c s_asinhf.c s_atan.c s_atanf.c s_carg.c s_cargf.c s_cargl.c \ diff --git a/lib/msun/Symbol.map b/lib/msun/Symbol.map index f244af4793b7..5b75f0804b59 100644 --- a/lib/msun/Symbol.map +++ b/lib/msun/Symbol.map @@ -270,4 +270,13 @@ FBSD_1.3 { log1pl; log2l; logl; + # Implemented as weak aliases for imprecise versions + coshl; + erfcl; + erfl; + lgammal; + powl; + sinhl; + tanhl; + tgammal; }; diff --git a/lib/msun/src/imprecise.c b/lib/msun/src/imprecise.c new file mode 100644 index 000000000000..a7503bf1c234 --- /dev/null +++ b/lib/msun/src/imprecise.c @@ -0,0 +1,69 @@ +/*- + * Copyright (c) 2013 David Chisnall + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD$ + */ + +#include +#include + +/* + * If long double is not the same size as double, then these will lose + * precision and we should emit a warning whenever something links against + * them. + */ +#if (LDBL_MANT_DIG > 53) +#define WARN_IMPRECISE(x) \ + __warn_references(x, # x " has lower than advertised precision"); +#else +#define WARN_IMPRECISE(x) +#endif +/* + * Declare the functions as weak variants so that other libraries providing + * real versions can override them. + */ +#define DECLARE_WEAK(x)\ + __weak_reference(imprecise_## x, x);\ + WARN_IMPRECISE(x) + +long double +imprecise_powl(long double x, long double y) +{ + + return pow(x, y); +} +DECLARE_WEAK(powl); + +#define DECLARE_IMPRECISE(f) \ + long double imprecise_ ## f ## l(long double v) { return f(v); }\ + DECLARE_WEAK(f ## l) + +DECLARE_IMPRECISE(cosh); +DECLARE_IMPRECISE(erfc); +DECLARE_IMPRECISE(erf); +DECLARE_IMPRECISE(lgamma); +DECLARE_IMPRECISE(sinh); +DECLARE_IMPRECISE(tanh); +DECLARE_IMPRECISE(tgamma); diff --git a/lib/msun/src/math_private.h b/lib/msun/src/math_private.h index 8ebc7fbf30c8..8af2c650e77e 100644 --- a/lib/msun/src/math_private.h +++ b/lib/msun/src/math_private.h @@ -39,7 +39,7 @@ */ #ifdef __arm__ -#if defined(__VFP_FP__) +#if defined(__VFP_FP__) || defined(__ARM_EABI__) #define IEEE_WORD_ORDER BYTE_ORDER #else #define IEEE_WORD_ORDER BIG_ENDIAN diff --git a/release/picobsd/build/picobsd b/release/picobsd/build/picobsd index 095a6ef4283e..1bebc8701a21 100755 --- a/release/picobsd/build/picobsd +++ b/release/picobsd/build/picobsd @@ -693,17 +693,22 @@ populate_mfs_tree() { # rm $a # do not remove! ) || fail $? crunch - if [ -f ${dst}/stand/sshd ] ; then - log "Setting up host key for sshd:" - if [ -f ${BUILDDIR}/floppy.tree/etc/ssh_host_key.gz ] ; then - log "Using existing host key" + log "Setting up host key for sshd:" + for K in rsa1 rsa dsa ; do + if [ $K = rsa1 ] ; then + i=ssh_host_key else - log "Generating new host key" - ssh-keygen -t rsa1 -f ${BUILDDIR}/floppy.tree/etc/ssh_host_key \ - -N "" -C "root@picobsd" - gzip -9 ${BUILDDIR}/floppy.tree/etc/ssh_host_key* || true + i=ssh_host_${K}_key fi - fi + if [ -f ${BUILDDIR}/floppy.tree/etc/$i.gz ] ; then + log "Using existing host key $i" + else + log "Generating new host key $i" + ssh-keygen -t $K -f ${BUILDDIR}/floppy.tree/etc/$i \ + -N "" -C "root@picobsd" + gzip -9 ${BUILDDIR}/floppy.tree/etc/${i}* || true + fi + done log "Copy generic and site-specific MFS tree..." for MFS_TREE in ${PICO_TREE}/mfs_tree ${MY_TREE}/mfs_tree ; do @@ -880,9 +885,11 @@ fill_floppy_image() { mkdir -p ${dst}/boot/kernel # XXX loader.conf does not work unless we also load the .4th files - echo "hint.acpi.0.disabled=\"1\"" > ${dst}/boot/loader.conf - echo "console=\"comconsole\"" >> ${dst}/boot/loader.conf - cp -p /boot/loader ${dst}/boot/loader || fail $? no_space "copying bootloader" + # echo "hint.acpi.0.disabled=\"1\"" > ${dst}/boot/loader.conf + # echo "console=\"comconsole\"" >> ${dst}/boot/loader.conf + local blf="loader* *.4th" # loader.rc loader.4th support.4th" + (cd /boot; cp -p loader ${dst}/boot) || fail $? no_space "copying bootloader" + cp ${MY_TREE}/floppy.tree/boot/loader.conf ${dst}/boot || true gzip -c kernel > ${dst}/boot/kernel/kernel.gz || fail $? no_space "copying kernel" # now transfer the floppy tree. If it is already in mfs, dont bother. @@ -972,6 +979,8 @@ set_build_parameters() { #-- export MACHINE_ARCH=`uname -m` MACHINE=`uname -m` # export CWARNFLAGS="-Wextra -Wno-sign-compare -Wno-missing-field-initializers" eval "export BINMAKE=\"`cd ${SRC}; make -f Makefile -V BINMAKE`\"" + [ "$BINMAKE" = "" ] && \ + eval "export BINMAKE=\"`cd ${SRC}; make -f Makefile -V SUB_MAKE`\"" fi if [ "${o_init_src}" != "" ] ; then diff --git a/sbin/camcontrol/camcontrol.8 b/sbin/camcontrol/camcontrol.8 index df0b3e72b2a7..3b5eafedf42c 100644 --- a/sbin/camcontrol/camcontrol.8 +++ b/sbin/camcontrol/camcontrol.8 @@ -27,7 +27,7 @@ .\" .\" $FreeBSD$ .\" -.Dd April 24, 2013 +.Dd September 6, 2013 .Dt CAMCONTROL 8 .Os .Sh NAME @@ -207,6 +207,19 @@ .Op Fl w .Op Fl y .Nm +.Ic sanitize +.Op device id +.Op generic args +.Aq Fl a Ar overwrite | block | crypto | exitfailure +.Op Fl c Ar passes +.Op Fl I +.Op Fl P Ar pattern +.Op Fl q +.Op Fl U +.Op Fl r +.Op Fl w +.Op Fl y +.Nm .Ic idle .Op device id .Op generic args @@ -649,7 +662,8 @@ request and not expect CRC bytes to be returned in the response. .Bl -tag -width 17n .It Fl r Ar len Ar fmt Op args This specifies the size of the SMP request, without the CRC bytes, and the -SMP request format. If the format is +SMP request format. +If the format is .Sq - , .Ar len bytes of data will be read from standard input and written as the SMP @@ -1088,16 +1102,132 @@ The user will not be asked about the timeout if a timeout is specified on the command line. .El +.It Ic sanitize +Issue the +.Tn SCSI +SANITIZE command to the named device. +.Pp +.Em WARNING! WARNING! WARNING! +.Pp +ALL data in the cache and on the disk will be destroyed or made inaccessible. +Recovery of the data is not possible. +Use extreme caution when issuing this command. +.Pp +The +.Sq sanitize +subcommand takes several arguments that modify its default behavior. +The +.Fl q +and +.Fl y +arguments can be useful for scripts. +.Bl -tag -width 6n +.It Fl a Ar operation +Specify the sanitize operation to perform. +.Bl -tag -width 16n +.It overwrite +Perform an overwrite operation by writing a user supplied +data pattern to the device one or more times. +The pattern is given by the +.Fl P +argument. +The number of times is given by the +.Fl c +argument. +.It block +Perform a block erase operation. +All the device's blocks are set to a vendor defined +value, typically zero. +.It crypto +Perform a cryptographic erase operation. +The encryption keys are changed to prevent the decryption +of the data. +.It exitfailure +Exits a previously failed sanitize operation. +A failed sanitize operation can only be exited if it was +run in the unrestricted completion mode, as provided by the +.Fl U +argument. +.El +.It Fl c Ar passes +The number of passes when performing an +.Sq overwrite +operation. +Valid values are between 1 and 31. +The default is 1. +.It Fl I +When performing an +.Sq overwrite +operation, the pattern is inverted between consecutive passes. +.It Fl P Ar pattern +Path to the file containing the pattern to use when +performing an +.Sq overwrite +operation. +The pattern is repeated as needed to fill each block. +.It Fl q +Be quiet, do not print any status messages. +This option will not disable +the questions, however. +To disable questions, use the +.Fl y +argument, below. +.It Fl U +Perform the sanitize in the unrestricted completion mode. +If the operation fails, it can later be exited with the +.Sq exitfailure +operation. +.It Fl r +Run in +.Dq report only +mode. +This will report status on a sanitize that is already running on the drive. +.It Fl w +Issue a non-immediate sanitize command. +By default, +.Nm +issues the SANITIZE command with the immediate bit set. +This tells the +device to immediately return the sanitize command, before +the sanitize has actually completed. +Then, +.Nm +gathers +.Tn SCSI +sense information from the device every second to determine how far along +in the sanitize process it is. +If the +.Fl w +argument is specified, +.Nm +will issue a non-immediate sanitize command, and will be unable to print any +information to let the user know what percentage of the disk has been +sanitized. +.It Fl y +Do not ask any questions. +By default, +.Nm +will ask the user if he/she really wants to sanitize the disk in question, +and also if the default sanitize command timeout is acceptable. +The user +will not be asked about the timeout if a timeout is specified on the +command line. +.El .It Ic idle -Put ATA device into IDLE state. Optional parameter +Put ATA device into IDLE state. +Optional parameter .Pq Fl t -specifies automatic standby timer value in seconds. Value 0 disables timer. +specifies automatic standby timer value in seconds. +Value 0 disables timer. .It Ic standby -Put ATA device into STANDBY state. Optional parameter +Put ATA device into STANDBY state. +Optional parameter .Pq Fl t -specifies automatic standby timer value in seconds. Value 0 disables timer. +specifies automatic standby timer value in seconds. +Value 0 disables timer. .It Ic sleep -Put ATA device into SLEEP state. Note that the only way get device out of +Put ATA device into SLEEP state. +Note that the only way get device out of this state may be reset. .It Ic security Update or report security settings, using an ATA identify command (0xec). @@ -1123,7 +1253,8 @@ Issuing a secure erase will user data on the device and may take several hours to complete. .Pp When this command is used against an SSD drive all its cells will be marked as -empty, restoring it to factory default write performance. For SSD's this action +empty, restoring it to factory default write performance. +For SSD's this action usually takes just a few seconds. .It Fl f .Pp @@ -1153,8 +1284,10 @@ the devices configured security level. .Pp Specifies which security level to set when issuing a .Fl s Ar pwd -command. The security level determines device behavior when the master -password is used to unlock the device. When the security level is set to high +command. +The security level determines device behavior when the master +password is used to unlock the device. +When the security level is set to high the device requires the unlock command and the master password to unlock. When the security level is set to maximum the device requires a secure erase with the master password to unlock. @@ -1173,7 +1306,8 @@ argument, below. .It Fl s Ar pwd .Pp Password the device (enable security) using the given password for the selected -user. This option can be combined with other options such as +user. +This option can be combined with other options such as .Fl e Em pwd .Pp A master password may be set in a addition to the user password. The purpose of @@ -1212,7 +1346,7 @@ Confirm yes to dangerous options such as without prompting for confirmation. .Pp .El -If the password specified for any action commands doesn't match the configured +If the password specified for any action commands does not match the configured password for the specified user the command will fail. .Pp The password in all cases is limited to 32 characters, longer passwords will @@ -1269,7 +1403,7 @@ call can be made without a power-on reset or a hardware reset of the device. .It Fl U Ar pwd .Pp Unlock the HPA configuration of the specified device using the given password. -If the password specified doesn't match the password configured via +If the password specified does not match the password configured via .Fl p Ar pwd the command will fail. .Pp @@ -1300,6 +1434,8 @@ PLEXTOR .It QUANTUM .It +SAMSUNG +.It SEAGATE .El .Pp @@ -1474,7 +1610,7 @@ This will .Em ERASE ALL data from the device, so backup your data before using! .Pp -This command can be used used against an SSD drive to restoring it to +This command can be used against an SSD drive to restoring it to factory default write performance. .Bd -literal -offset indent camcontrol hpa ada0 diff --git a/sbin/camcontrol/camcontrol.c b/sbin/camcontrol/camcontrol.c index 76b393986a2e..e80c549cf96e 100644 --- a/sbin/camcontrol/camcontrol.c +++ b/sbin/camcontrol/camcontrol.c @@ -32,6 +32,7 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include #include @@ -93,7 +94,8 @@ typedef enum { CAM_CMD_SMP_MANINFO = 0x0000001b, CAM_CMD_DOWNLOAD_FW = 0x0000001c, CAM_CMD_SECURITY = 0x0000001d, - CAM_CMD_HPA = 0x0000001e + CAM_CMD_HPA = 0x0000001e, + CAM_CMD_SANITIZE = 0x0000001f, } cam_cmdmask; typedef enum { @@ -209,6 +211,7 @@ static struct camcontrol_opts option_table[] = { {"rate", CAM_CMD_RATE, CAM_ARG_NONE, negotiate_opts}, {"debug", CAM_CMD_DEBUG, CAM_ARG_NONE, "IPTSXcp"}, {"format", CAM_CMD_FORMAT, CAM_ARG_NONE, "qrwy"}, + {"sanitize", CAM_CMD_SANITIZE, CAM_ARG_NONE, "a:c:IP:qrUwy"}, {"idle", CAM_CMD_IDLE, CAM_ARG_NONE, "t:"}, {"standby", CAM_CMD_STANDBY, CAM_ARG_NONE, "t:"}, {"sleep", CAM_CMD_SLEEP, CAM_ARG_NONE, ""}, @@ -301,6 +304,8 @@ static int ratecontrol(struct cam_device *device, int retry_count, int timeout, int argc, char **argv, char *combinedopt); static int scsiformat(struct cam_device *device, int argc, char **argv, char *combinedopt, int retry_count, int timeout); +static int scsisanitize(struct cam_device *device, int argc, char **argv, + char *combinedopt, int retry_count, int timeout); static int scsireportluns(struct cam_device *device, int argc, char **argv, char *combinedopt, int retry_count, int timeout); static int scsireadcapacity(struct cam_device *device, int argc, char **argv, @@ -5536,6 +5541,402 @@ scsiformat(struct cam_device *device, int argc, char **argv, return(error); } +static int +scsisanitize(struct cam_device *device, int argc, char **argv, + char *combinedopt, int retry_count, int timeout) +{ + union ccb *ccb; + u_int8_t action = 0; + int c; + int ycount = 0, quiet = 0; + int error = 0, retval = 0; + int use_timeout = 10800 * 1000; + int immediate = 1; + int invert = 0; + int passes = 0; + int ause = 0; + int fd = -1; + const char *pattern = NULL; + u_int8_t *data_ptr = NULL; + u_int32_t dxfer_len = 0; + u_int8_t byte2 = 0; + int num_warnings = 0; + int reportonly = 0; + + ccb = cam_getccb(device); + + if (ccb == NULL) { + warnx("scsisanitize: error allocating ccb"); + return(1); + } + + bzero(&(&ccb->ccb_h)[1], + sizeof(struct ccb_scsiio) - sizeof(struct ccb_hdr)); + + while ((c = getopt(argc, argv, combinedopt)) != -1) { + switch(c) { + case 'a': + if (strcasecmp(optarg, "overwrite") == 0) + action = SSZ_SERVICE_ACTION_OVERWRITE; + else if (strcasecmp(optarg, "block") == 0) + action = SSZ_SERVICE_ACTION_BLOCK_ERASE; + else if (strcasecmp(optarg, "crypto") == 0) + action = SSZ_SERVICE_ACTION_CRYPTO_ERASE; + else if (strcasecmp(optarg, "exitfailure") == 0) + action = SSZ_SERVICE_ACTION_EXIT_MODE_FAILURE; + else { + warnx("invalid service operation \"%s\"", + optarg); + error = 1; + goto scsisanitize_bailout; + } + break; + case 'c': + passes = strtol(optarg, NULL, 0); + if (passes < 1 || passes > 31) { + warnx("invalid passes value %d", passes); + error = 1; + goto scsisanitize_bailout; + } + break; + case 'I': + invert = 1; + break; + case 'P': + pattern = optarg; + break; + case 'q': + quiet++; + break; + case 'U': + ause = 1; + break; + case 'r': + reportonly = 1; + break; + case 'w': + immediate = 0; + break; + case 'y': + ycount++; + break; + } + } + + if (reportonly) + goto doreport; + + if (action == 0) { + warnx("an action is required"); + error = 1; + goto scsisanitize_bailout; + } else if (action == SSZ_SERVICE_ACTION_OVERWRITE) { + struct scsi_sanitize_parameter_list *pl; + struct stat sb; + ssize_t sz, amt; + + if (pattern == NULL) { + warnx("overwrite action requires -P argument"); + error = 1; + goto scsisanitize_bailout; + } + fd = open(pattern, O_RDONLY); + if (fd < 0) { + warn("cannot open pattern file %s", pattern); + error = 1; + goto scsisanitize_bailout; + } + if (fstat(fd, &sb) < 0) { + warn("cannot stat pattern file %s", pattern); + error = 1; + goto scsisanitize_bailout; + } + sz = sb.st_size; + if (sz > SSZPL_MAX_PATTERN_LENGTH) { + warnx("pattern file size exceeds maximum value %d", + SSZPL_MAX_PATTERN_LENGTH); + error = 1; + goto scsisanitize_bailout; + } + dxfer_len = sizeof(*pl) + sz; + data_ptr = calloc(1, dxfer_len); + if (data_ptr == NULL) { + warnx("cannot allocate parameter list buffer"); + error = 1; + goto scsisanitize_bailout; + } + + amt = read(fd, data_ptr + sizeof(*pl), sz); + if (amt < 0) { + warn("cannot read pattern file"); + error = 1; + goto scsisanitize_bailout; + } else if (amt != sz) { + warnx("short pattern file read"); + error = 1; + goto scsisanitize_bailout; + } + + pl = (struct scsi_sanitize_parameter_list *)data_ptr; + if (passes == 0) + pl->byte1 = 1; + else + pl->byte1 = passes; + if (invert != 0) + pl->byte1 |= SSZPL_INVERT; + scsi_ulto2b(sz, pl->length); + } else { + const char *arg; + + if (passes != 0) + arg = "-c"; + else if (invert != 0) + arg = "-I"; + else if (pattern != NULL) + arg = "-P"; + else + arg = NULL; + if (arg != NULL) { + warnx("%s argument only valid with overwrite " + "operation", arg); + error = 1; + goto scsisanitize_bailout; + } + } + + if (quiet == 0) { + fprintf(stdout, "You are about to REMOVE ALL DATA from the " + "following device:\n"); + + error = scsidoinquiry(device, argc, argv, combinedopt, + retry_count, timeout); + + if (error != 0) { + warnx("scsisanitize: error sending inquiry"); + goto scsisanitize_bailout; + } + } + + if (ycount == 0) { + if (!get_confirmation()) { + error = 1; + goto scsisanitize_bailout; + } + } + + if (timeout != 0) + use_timeout = timeout; + + if (quiet == 0) { + fprintf(stdout, "Current sanitize timeout is %d seconds\n", + use_timeout / 1000); + } + + /* + * If the user hasn't disabled questions and didn't specify a + * timeout on the command line, ask them if they want the current + * timeout. + */ + if ((ycount == 0) + && (timeout == 0)) { + char str[1024]; + int new_timeout = 0; + + fprintf(stdout, "Enter new timeout in seconds or press\n" + "return to keep the current timeout [%d] ", + use_timeout / 1000); + + if (fgets(str, sizeof(str), stdin) != NULL) { + if (str[0] != '\0') + new_timeout = atoi(str); + } + + if (new_timeout != 0) { + use_timeout = new_timeout * 1000; + fprintf(stdout, "Using new timeout value %d\n", + use_timeout / 1000); + } + } + + byte2 = action; + if (ause != 0) + byte2 |= SSZ_UNRESTRICTED_EXIT; + if (immediate != 0) + byte2 |= SSZ_IMMED; + + scsi_sanitize(&ccb->csio, + /* retries */ retry_count, + /* cbfcnp */ NULL, + /* tag_action */ MSG_SIMPLE_Q_TAG, + /* byte2 */ byte2, + /* control */ 0, + /* data_ptr */ data_ptr, + /* dxfer_len */ dxfer_len, + /* sense_len */ SSD_FULL_SIZE, + /* timeout */ use_timeout); + + /* Disable freezing the device queue */ + ccb->ccb_h.flags |= CAM_DEV_QFRZDIS; + + if (arglist & CAM_ARG_ERR_RECOVER) + ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER; + + if (((retval = cam_send_ccb(device, ccb)) < 0) + || ((immediate == 0) + && ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP))) { + const char errstr[] = "error sending sanitize command"; + + if (retval < 0) + warn(errstr); + else + warnx(errstr); + + if (arglist & CAM_ARG_VERBOSE) { + cam_error_print(device, ccb, CAM_ESF_ALL, + CAM_EPF_ALL, stderr); + } + error = 1; + goto scsisanitize_bailout; + } + + /* + * If we ran in non-immediate mode, we already checked for errors + * above and printed out any necessary information. If we're in + * immediate mode, we need to loop through and get status + * information periodically. + */ + if (immediate == 0) { + if (quiet == 0) { + fprintf(stdout, "Sanitize Complete\n"); + } + goto scsisanitize_bailout; + } + +doreport: + do { + cam_status status; + + bzero(&(&ccb->ccb_h)[1], + sizeof(struct ccb_scsiio) - sizeof(struct ccb_hdr)); + + /* + * There's really no need to do error recovery or + * retries here, since we're just going to sit in a + * loop and wait for the device to finish sanitizing. + */ + scsi_test_unit_ready(&ccb->csio, + /* retries */ 0, + /* cbfcnp */ NULL, + /* tag_action */ MSG_SIMPLE_Q_TAG, + /* sense_len */ SSD_FULL_SIZE, + /* timeout */ 5000); + + /* Disable freezing the device queue */ + ccb->ccb_h.flags |= CAM_DEV_QFRZDIS; + + retval = cam_send_ccb(device, ccb); + + /* + * If we get an error from the ioctl, bail out. SCSI + * errors are expected. + */ + if (retval < 0) { + warn("error sending CAMIOCOMMAND ioctl"); + if (arglist & CAM_ARG_VERBOSE) { + cam_error_print(device, ccb, CAM_ESF_ALL, + CAM_EPF_ALL, stderr); + } + error = 1; + goto scsisanitize_bailout; + } + + status = ccb->ccb_h.status & CAM_STATUS_MASK; + + if ((status != CAM_REQ_CMP) + && (status == CAM_SCSI_STATUS_ERROR) + && ((ccb->ccb_h.status & CAM_AUTOSNS_VALID) != 0)) { + struct scsi_sense_data *sense; + int error_code, sense_key, asc, ascq; + + sense = &ccb->csio.sense_data; + scsi_extract_sense_len(sense, ccb->csio.sense_len - + ccb->csio.sense_resid, &error_code, &sense_key, + &asc, &ascq, /*show_errors*/ 1); + + /* + * According to the SCSI-3 spec, a drive that is in the + * middle of a sanitize should return NOT READY with an + * ASC of "logical unit not ready, sanitize in + * progress". The sense key specific bytes will then + * be a progress indicator. + */ + if ((sense_key == SSD_KEY_NOT_READY) + && (asc == 0x04) && (ascq == 0x1b)) { + uint8_t sks[3]; + + if ((scsi_get_sks(sense, ccb->csio.sense_len - + ccb->csio.sense_resid, sks) == 0) + && (quiet == 0)) { + int val; + u_int64_t percentage; + + val = scsi_2btoul(&sks[1]); + percentage = 10000 * val; + + fprintf(stdout, + "\rSanitizing: %ju.%02u %% " + "(%d/%d) done", + (uintmax_t)(percentage / + (0x10000 * 100)), + (unsigned)((percentage / + 0x10000) % 100), + val, 0x10000); + fflush(stdout); + } else if ((quiet == 0) + && (++num_warnings <= 1)) { + warnx("Unexpected SCSI Sense Key " + "Specific value returned " + "during sanitize:"); + scsi_sense_print(device, &ccb->csio, + stderr); + warnx("Unable to print status " + "information, but sanitze will " + "proceed."); + warnx("will exit when sanitize is " + "complete"); + } + sleep(1); + } else { + warnx("Unexpected SCSI error during sanitize"); + cam_error_print(device, ccb, CAM_ESF_ALL, + CAM_EPF_ALL, stderr); + error = 1; + goto scsisanitize_bailout; + } + + } else if (status != CAM_REQ_CMP) { + warnx("Unexpected CAM status %#x", status); + if (arglist & CAM_ARG_VERBOSE) + cam_error_print(device, ccb, CAM_ESF_ALL, + CAM_EPF_ALL, stderr); + error = 1; + goto scsisanitize_bailout; + } + } while((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP); + + if (quiet == 0) + fprintf(stdout, "\nSanitize Complete\n"); + +scsisanitize_bailout: + if (fd >= 0) + close(fd); + if (data_ptr != NULL) + free(data_ptr); + cam_freeccb(ccb); + + return(error); +} + static int scsireportluns(struct cam_device *device, int argc, char **argv, char *combinedopt, int retry_count, int timeout) @@ -7361,6 +7762,10 @@ usage(int printlong) " [-q][-R syncrate][-v][-T ]\n" " [-U][-W bus_width]\n" " camcontrol format [dev_id][generic args][-q][-r][-w][-y]\n" +" camcontrol sanitize [dev_id][generic args]\n" +" [-a overwrite|block|crypto|exitfailure]\n" +" [-c passes][-I][-P pattern][-q][-U][-r][-w]\n" +" [-y]\n" " camcontrol idle [dev_id][generic args][-t time]\n" " camcontrol standby [dev_id][generic args][-t time]\n" " camcontrol sleep [dev_id][generic args]\n" @@ -7403,6 +7808,7 @@ usage(int printlong) "tags report or set the number of transaction slots for a device\n" "negotiate report or set device negotiation parameters\n" "format send the SCSI FORMAT UNIT command to the named device\n" +"sanitize send the SCSI SANITIZE command to the named device\n" "idle send the ATA IDLE command to the named device\n" "standby send the ATA STANDBY command to the named device\n" "sleep send the ATA SLEEP command to the named device\n" @@ -7498,6 +7904,16 @@ usage(int printlong) "-r run in report only mode\n" "-w don't send immediate format command\n" "-y don't ask any questions\n" +"sanitize arguments:\n" +"-a operation operation mode: overwrite, block, crypto or exitfailure\n" +"-c passes overwrite passes to perform (1 to 31)\n" +"-I invert overwrite pattern after each pass\n" +"-P pattern path to overwrite pattern file\n" +"-q be quiet, don't print status messages\n" +"-r run in report only mode\n" +"-U run operation in unrestricted completion exit mode\n" +"-w don't send immediate sanitize command\n" +"-y don't ask any questions\n" "idle/standby arguments:\n" "-t number of seconds before respective state.\n" "fwdownload arguments:\n" @@ -7860,6 +8276,10 @@ main(int argc, char **argv) arglist & CAM_ARG_VERBOSE, retry_count, timeout, get_disk_type(cam_dev)); break; + case CAM_CMD_SANITIZE: + error = scsisanitize(cam_dev, argc, argv, + combinedopt, retry_count, timeout); + break; #endif /* MINIMALISTIC */ case CAM_CMD_USAGE: usage(1); diff --git a/sbin/camcontrol/fwdownload.c b/sbin/camcontrol/fwdownload.c index 2fa9ba4d9c88..7e57d320772f 100644 --- a/sbin/camcontrol/fwdownload.c +++ b/sbin/camcontrol/fwdownload.c @@ -77,6 +77,7 @@ typedef enum { VENDOR_PLEXTOR, VENDOR_QUALSTAR, VENDOR_QUANTUM, + VENDOR_SAMSUNG, VENDOR_SEAGATE, VENDOR_UNKNOWN } fw_vendor_t; @@ -98,6 +99,7 @@ static const struct fw_vendor vendors_list[] = { {VENDOR_PLEXTOR, "PLEXTOR", 0x2000, 0x04, 0x05, 0, 1}, {VENDOR_QUALSTAR, "QUALSTAR", 0x2030, 0x05, 0x05, 0, 0}, {VENDOR_QUANTUM, "QUANTUM", 0x2000, 0x04, 0x05, 0, 1}, + {VENDOR_SAMSUNG, "SAMSUNG", 0x8000, 0x07, 0x07, 0, 1}, {VENDOR_SEAGATE, "SEAGATE", 0x8000, 0x07, 0x07, 0, 1}, /* the next 2 are SATA disks going through SAS HBA */ {VENDOR_SEAGATE, "ATA ST", 0x8000, 0x07, 0x07, 0, 1}, diff --git a/sbin/dhclient/bpf.c b/sbin/dhclient/bpf.c index f43502832ef5..c0a172039116 100644 --- a/sbin/dhclient/bpf.c +++ b/sbin/dhclient/bpf.c @@ -43,6 +43,8 @@ #include __FBSDID("$FreeBSD$"); +#include + #include "dhcpd.h" #include "privsep.h" #include @@ -132,6 +134,7 @@ int dhcp_bpf_wfilter_len = sizeof(dhcp_bpf_wfilter) / sizeof(struct bpf_insn); void if_register_send(struct interface_info *info) { + cap_rights_t rights; struct bpf_version v; struct bpf_program p; int sock, on = 1; @@ -160,7 +163,8 @@ if_register_send(struct interface_info *info) if (ioctl(info->wfdesc, BIOCLOCK, NULL) < 0) error("Cannot lock bpf"); - if (cap_rights_limit(info->wfdesc, CAP_WRITE) < 0 && errno != ENOSYS) + cap_rights_init(&rights, CAP_WRITE); + if (cap_rights_limit(info->wfdesc, &rights) < 0 && errno != ENOSYS) error("Can't limit bpf descriptor: %m"); /* @@ -213,6 +217,7 @@ void if_register_receive(struct interface_info *info) { static const unsigned long cmds[2] = { SIOCGIFFLAGS, SIOCGIFMEDIA }; + cap_rights_t rights; struct bpf_version v; struct bpf_program p; int flag = 1, sz; @@ -264,10 +269,9 @@ if_register_receive(struct interface_info *info) if (ioctl(info->rfdesc, BIOCLOCK, NULL) < 0) error("Cannot lock bpf"); - if (cap_rights_limit(info->rfdesc, - CAP_IOCTL | CAP_POLL_EVENT | CAP_READ) < 0 && errno != ENOSYS) { + cap_rights_init(&rights, CAP_IOCTL, CAP_POLL_EVENT, CAP_READ); + if (cap_rights_limit(info->rfdesc, &rights) < 0 && errno != ENOSYS) error("Can't limit bpf descriptor: %m"); - } if (cap_ioctls_limit(info->rfdesc, cmds, 2) < 0 && errno != ENOSYS) error("Can't limit ioctls for bpf descriptor: %m"); } diff --git a/sbin/dhclient/dhclient.c b/sbin/dhclient/dhclient.c index c8f05b503d34..e16e464c6002 100644 --- a/sbin/dhclient/dhclient.c +++ b/sbin/dhclient/dhclient.c @@ -56,6 +56,8 @@ #include __FBSDID("$FreeBSD$"); +#include + #include "dhcpd.h" #include "privsep.h" @@ -346,6 +348,7 @@ main(int argc, char *argv[]) int immediate_daemon = 0; struct passwd *pw; pid_t otherpid; + cap_rights_t rights; /* Initially, log errors to stderr as well as to syslogd. */ openlog(__progname, LOG_PID | LOG_NDELAY, DHCPD_LOG_FACILITY); @@ -477,10 +480,9 @@ main(int argc, char *argv[]) close(pipe_fd[0]); privfd = pipe_fd[1]; - if (cap_rights_limit(privfd, CAP_READ | CAP_WRITE) < 0 && - errno != ENOSYS) { + cap_rights_init(&rights, CAP_READ, CAP_WRITE); + if (cap_rights_limit(privfd, &rights) < 0 && errno != ENOSYS) error("can't limit private descriptor: %m"); - } if ((fd = open(path_dhclient_db, O_RDONLY|O_EXLOCK|O_CREAT, 0)) == -1) error("can't open and lock %s: %m", path_dhclient_db); @@ -492,10 +494,9 @@ main(int argc, char *argv[]) add_protocol("AF_ROUTE", routefd, routehandler, ifi); if (shutdown(routefd, SHUT_WR) < 0) error("can't shutdown route socket: %m"); - if (cap_rights_limit(routefd, CAP_POLL_EVENT | CAP_READ) < 0 && - errno != ENOSYS) { + cap_rights_init(&rights, CAP_POLL_EVENT, CAP_READ); + if (cap_rights_limit(routefd, &rights) < 0 && errno != ENOSYS) error("can't limit route socket: %m"); - } if (chroot(_PATH_VAREMPTY) == -1) error("chroot"); @@ -1840,13 +1841,15 @@ void rewrite_client_leases(void) { struct client_lease *lp; + cap_rights_t rights; if (!leaseFile) { leaseFile = fopen(path_dhclient_db, "w"); if (!leaseFile) error("can't create %s: %m", path_dhclient_db); - if (cap_rights_limit(fileno(leaseFile), CAP_FSTAT | CAP_FSYNC | - CAP_FTRUNCATE | CAP_SEEK | CAP_WRITE) < 0 && + cap_rights_init(&rights, CAP_FSTAT, CAP_FSYNC, CAP_FTRUNCATE, + CAP_SEEK, CAP_WRITE); + if (cap_rights_limit(fileno(leaseFile), &rights) < 0 && errno != ENOSYS) { error("can't limit lease descriptor: %m"); } @@ -2354,6 +2357,7 @@ void go_daemon(void) { static int state = 0; + cap_rights_t rights; if (no_daemon || state) return; @@ -2366,9 +2370,11 @@ go_daemon(void) if (daemon(1, 0) == -1) error("daemon"); + cap_rights_init(&rights); + if (pidfile != NULL) { pidfile_write(pidfile); - if (cap_rights_limit(pidfile_fileno(pidfile), CAP_NONE) < 0 && + if (cap_rights_limit(pidfile_fileno(pidfile), &rights) < 0 && errno != ENOSYS) { error("can't limit pidfile descriptor: %m"); } @@ -2383,11 +2389,12 @@ go_daemon(void) nullfd = -1; } - if (cap_rights_limit(STDIN_FILENO, CAP_NONE) < 0 && errno != ENOSYS) + if (cap_rights_limit(STDIN_FILENO, &rights) < 0 && errno != ENOSYS) error("can't limit stdin: %m"); - if (cap_rights_limit(STDOUT_FILENO, CAP_WRITE) < 0 && errno != ENOSYS) + cap_rights_init(&rights, CAP_WRITE); + if (cap_rights_limit(STDOUT_FILENO, &rights) < 0 && errno != ENOSYS) error("can't limit stdout: %m"); - if (cap_rights_limit(STDERR_FILENO, CAP_WRITE) < 0 && errno != ENOSYS) + if (cap_rights_limit(STDERR_FILENO, &rights) < 0 && errno != ENOSYS) error("can't limit stderr: %m"); } diff --git a/sbin/hastd/subr.c b/sbin/hastd/subr.c index 440061e8c364..0e9930bcb7fa 100644 --- a/sbin/hastd/subr.c +++ b/sbin/hastd/subr.c @@ -231,6 +231,7 @@ drop_privs(const struct hast_resource *res) pjdlog_common(LOG_DEBUG, 1, errno, "Unable to sandbox using capsicum"); } else if (res != NULL) { + cap_rights_t rights; static const unsigned long geomcmds[] = { DIOCGDELETE, DIOCGFLUSH @@ -239,8 +240,9 @@ drop_privs(const struct hast_resource *res) PJDLOG_ASSERT(res->hr_role == HAST_ROLE_PRIMARY || res->hr_role == HAST_ROLE_SECONDARY); - if (cap_rights_limit(res->hr_localfd, - CAP_FLOCK | CAP_IOCTL | CAP_PREAD | CAP_PWRITE) == -1) { + cap_rights_init(&rights, CAP_FLOCK, CAP_IOCTL, CAP_PREAD, + CAP_PWRITE); + if (cap_rights_limit(res->hr_localfd, &rights) == -1) { pjdlog_errno(LOG_ERR, "Unable to limit capability rights on local descriptor"); } @@ -258,7 +260,8 @@ drop_privs(const struct hast_resource *res) G_GATE_CMD_DESTROY }; - if (cap_rights_limit(res->hr_ggatefd, CAP_IOCTL) == -1) { + cap_rights_init(&rights, CAP_IOCTL); + if (cap_rights_limit(res->hr_ggatefd, &rights) == -1) { pjdlog_errno(LOG_ERR, "Unable to limit capability rights to CAP_IOCTL on ggate descriptor"); } diff --git a/sbin/ipf/ipf/Makefile b/sbin/ipf/ipf/Makefile index 62a9b47d6cca..c3938c63af61 100644 --- a/sbin/ipf/ipf/Makefile +++ b/sbin/ipf/ipf/Makefile @@ -4,7 +4,7 @@ PROG= ipf SRCS= ${GENHDRS} ipf.c ipfcomp.c ipf_y.c ipf_l.c bpf_filter.c MAN= ipfilter.4 ipfilter.5 ipf.8 ipf.4 ipf.5 ipl.4 MLINKS= ipf.5 ipf.conf.5 ipf.5 ipf6.conf.5 -CFLAGS+= -I. -DIPFILTER_BPF +CFLAGS+= -I. -DIPFILTER_BPF -DHAS_SYS_MD5_H GENHDRS= ipf_l.h ipf_y.h DPSRCS+= ${GENHDRS} diff --git a/sbin/ipf/ipftest/Makefile b/sbin/ipf/ipftest/Makefile index d089b2b051e7..32b074cb93f4 100644 --- a/sbin/ipf/ipftest/Makefile +++ b/sbin/ipf/ipftest/Makefile @@ -2,15 +2,22 @@ PROG= ipftest SRCS= ${GENHDRS} ipftest.c fil.c ip_frag.c ip_state.c ip_nat.c \ + ip_nat6.c \ ip_proxy.c ip_auth.c ip_htable.c ip_lookup.c \ ip_pool.c ip_scan.c ip_sync.c ip_rules.c \ ip_fil.c ip_log.c ippool_y.c ippool_l.c ipf_y.c \ - ipf_l.c ipnat_y.c ipnat_l.c md5.c radix.c bpf_filter.c + ipf_l.c ipnat_y.c ipnat_l.c md5.c radix_ipf.c ip_dstlist.c MAN= ipftest.1 WARNS?= 0 CFLAGS+= -DIPFILTER_LOG -DIPFILTER_COMPILED -DIPFILTER_LOOKUP \ - -DIPFILTER_SCAN -DIPFILTER_SYNC -DIPFILTER_CKSUM -I. + -DIPFILTER_SYNC -DIPFILTER_CKSUM -DHAS_SYS_MD5_H -I. + +# XXX The original tarball does not define IPFILTER_SCAN when building this +# XXX and other modules. It is believed the reason is it fails to build. +# XXX It has been removed for now. +# XXX CFLAGS+= -DIPFILTER_SCAN + .PATH: ${.CURDIR}/../../../sys/contrib/ipfilter/netinet diff --git a/sbin/ipf/libipf/Makefile b/sbin/ipf/libipf/Makefile index 43428cc68f4e..077062fa1ed3 100644 --- a/sbin/ipf/libipf/Makefile +++ b/sbin/ipf/libipf/Makefile @@ -3,26 +3,43 @@ LIB= ipf INTERNALLIB= -SRCS= addicmp.c addipopt.c alist_free.c alist_new.c bcopywrap.c \ - binprint.c buildopts.c checkrev.c count4bits.c count6bits.c \ - debug.c facpri.c fill6bits.c flags.c gethost.c getifname.c \ +SRCS= addicmp.c addipopt.c alist_free.c alist_new.c allocmbt.c \ + assigndefined.c bcopywrap.c \ + binprint.c buildopts.c checkrev.c connecttcp.c \ + count4bits.c count6bits.c \ + debug.c dupmbt.c \ + facpri.c familyname.c \ + fill6bits.c findword.c \ + flags.c freembt.c ftov.c \ + genmask.c \ + gethost.c getifname.c geticmptype.c \ getnattype.c getport.c getportproto.c getproto.c getsumd.c \ - hostname.c icmpcode.c initparse.c ionames.c \ - ipf_dotuning.c ipft_ef.c ipft_hx.c ipft_pc.c ipft_sn.c \ - ipft_td.c ipft_tx.c ipoptsec.c kmem.c kmemcpywrap.c \ - kvatoname.c load_file.c load_hash.c load_hashnode.c \ + hostname.c icmpcode.c icmptypename.c icmptypes.c \ + initparse.c interror.c ionames.c \ + ipf_dotuning.c ipf_perror.c ipft_hx.c ipft_pc.c \ + ipft_tx.c ipoptsec.c kmem.c kmemcpywrap.c \ + kvatoname.c load_dstlist.c load_dstlistnode.c load_file.c \ + load_hash.c load_hashnode.c \ load_http.c load_pool.c load_poolnode.c load_url.c \ + mb_hexdump.c msgdsize.c \ mutex_emul.c nametokva.c nat_setgroupmap.c ntomask.c \ - optname.c optprint.c optprintv6.c optvalue.c portname.c \ - print_toif.c printactivenat.c printaps.c printbuf.c \ + optname.c optprint.c optprintv6.c optvalue.c parsefields.c \ + parseipfexpr.c parsewhoisline.c poolio.c portname.c \ + prependmbt.c \ + print_toif.c printactiveaddr.c printactivenat.c printaddr.c \ + printaps.c printbuf.c printdstl_live.c printdstlist.c \ + printdstlistdata.c printdstlistnode.c printdstlistpolicy.c \ + printfieldhdr.c \ printfr.c printfraginfo.c printhash.c printhash_live.c \ - printhashdata.c printhashnode.c printhostmap.c \ - printhostmask.c printifname.c printip.c printlog.c \ - printmask.c printnat.c printpacket.c printpacket6.c \ - printpool.c printpool_live.c printpooldata.c printpoolnode.c \ - printportcmp.c printproto.c printsbuf.c printstate.c \ - printtqtable.c printtunable.c remove_hash.c remove_hashnode.c \ + printhashdata.c printhashnode.c printhost.c printhostmap.c \ + printhostmask.c printifname.c printip.c printipfexpr.c printiphdr.c printlog.c printlookup.c \ + printmask.c printnat.c printnataddr.c printnatfield.c printnatside.c printpacket.c printpacket6.c \ + printpool.c printpool_live.c printpooldata.c printpoolfield.c printpoolnode.c \ + printportcmp.c printproto.c printsbuf.c printstate.c printstatefields.c \ + printtcpflags.c \ + printtqtable.c printtunable.c printunit.c remove_hash.c remove_hashnode.c \ remove_pool.c remove_poolnode.c resetlexer.c rwlock_emul.c \ + save_execute.c save_file.c save_nothing.c save_syslog.c save_v1trap.c save_v2trap.c vtof.c \ tcp_flags.c tcpflags.c tcpoptnames.c v6ionames.c v6optvalue.c \ var.c verbose.c diff --git a/sbin/newfs_msdos/newfs_msdos.c b/sbin/newfs_msdos/newfs_msdos.c index fe1631a73ca9..217b72055944 100644 --- a/sbin/newfs_msdos/newfs_msdos.c +++ b/sbin/newfs_msdos/newfs_msdos.c @@ -139,8 +139,8 @@ struct de { u_int8_t deName[11]; /* name and extension */ u_int8_t deAttributes; /* attributes */ u_int8_t rsvd[10]; /* reserved */ - u_int8_t deMTime[2]; /* creation time */ - u_int8_t deMDate[2]; /* creation date */ + u_int8_t deMTime[2]; /* last-modified time */ + u_int8_t deMDate[2]; /* last-modified date */ u_int8_t deStartCluster[2]; /* starting cluster */ u_int8_t deFileSize[4]; /* size */ } __packed; diff --git a/sbin/swapon/swapon.c b/sbin/swapon/swapon.c index d93277c6638b..bf621c1132f9 100644 --- a/sbin/swapon/swapon.c +++ b/sbin/swapon/swapon.c @@ -1,4 +1,4 @@ -/* +/*- * Copyright (c) 1980, 1993 * The Regents of the University of California. All rights reserved. * @@ -83,16 +83,16 @@ main(int argc, char **argv) struct fstab *fsp; const char *swfile; char *ptr; - int ret; - int ch, doall; - int sflag = 0, lflag = 0, late = 0, hflag = 0; + int ret, ch, doall; + int sflag, lflag, late, hflag; const char *etc_fstab; + sflag = lflag = late = hflag = 0; if ((ptr = strrchr(argv[0], '/')) == NULL) ptr = argv[0]; - if (strstr(ptr, "swapon")) + if (strstr(ptr, "swapon") != NULL) which_prog = SWAPON; - else if (strstr(ptr, "swapoff")) + else if (strstr(ptr, "swapoff") != NULL) which_prog = SWAPOFF; orig_prog = which_prog; @@ -104,9 +104,8 @@ main(int argc, char **argv) if (which_prog == SWAPCTL) { doall = 1; which_prog = SWAPON; - } else { + } else usage(); - } break; case 'a': if (which_prog == SWAPON || which_prog == SWAPOFF) @@ -149,9 +148,8 @@ main(int argc, char **argv) if (which_prog == SWAPCTL) { doall = 1; which_prog = SWAPOFF; - } else { + } else usage(); - } break; case 'F': etc_fstab = optarg; @@ -170,13 +168,20 @@ main(int argc, char **argv) if (which_prog == SWAPON || which_prog == SWAPOFF) { if (doall) { while ((fsp = getfsent()) != NULL) { - if (strcmp(fsp->fs_type, FSTAB_SW)) + if (strcmp(fsp->fs_type, FSTAB_SW) != 0) continue; - if (strstr(fsp->fs_mntops, "noauto")) + if (strstr(fsp->fs_mntops, "noauto") != NULL) continue; + /* + * Forcibly enable "late" option when file= is + * specified. This is because mounting file + * systems with rw option is typically + * required to make the backing store ready. + */ if (which_prog != SWAPOFF && - strstr(fsp->fs_mntops, "late") && - !late) + (strstr(fsp->fs_mntops, "late") != NULL || + strstr(fsp->fs_mntops, "file=") != NULL) && + late == 0) continue; swfile = swap_on_off(fsp->fs_spec, 1, fsp->fs_mntops); @@ -184,15 +189,14 @@ main(int argc, char **argv) ret = 1; continue; } - if (!qflag) { + if (qflag == 0) { printf("%s: %sing %s as swap device\n", getprogname(), (which_prog == SWAPOFF) ? "remov" : "add", swfile); } } - } - else if (!*argv) + } else if (*argv == NULL) usage(); for (; *argv; ++argv) { swfile = swap_on_off(*argv, 0, NULL); @@ -281,7 +285,7 @@ swap_on_off_gbde(const char *name, int doingall) if (error) { /* bde device found. Ignore it. */ free(dname); - if (!qflag) + if (qflag == 0) warnx("%s: Device already in use", name); return (NULL); } @@ -301,7 +305,7 @@ swap_on_off_gbde(const char *name, int doingall) free(dname); if (error) { /* bde device not found. Ignore it. */ - if (!qflag) + if (qflag == 0) warnx("%s: Device not found", name); return (NULL); } @@ -316,18 +320,16 @@ swap_on_geli_args(const char *mntops) { const char *aalgo, *ealgo, *keylen_str, *sectorsize_str; const char *aflag, *eflag, *lflag, *sflag; - char *p; - char *args; - char *token, *string, *ops; + char *p, *args, *token, *string, *ops; int argsize, pagesize; size_t pagesize_len; u_long ul; - /* Use built-in defaults for geli(8) */ + /* Use built-in defaults for geli(8). */ aalgo = ealgo = keylen_str = ""; aflag = eflag = lflag = ""; - /* We will always specify sectorsize */ + /* We will always specify sectorsize. */ sflag = " -s "; sectorsize_str = NULL; @@ -364,7 +366,8 @@ swap_on_geli_args(const char *mntops) errno = EINVAL; } if (errno) { - warn("Invalid sectorsize: %s", sectorsize_str); + warn("Invalid sectorsize: %s", + sectorsize_str); free(ops); return (NULL); } @@ -382,7 +385,7 @@ swap_on_geli_args(const char *mntops) * pagesize as sector size. */ if (sectorsize_str == NULL) { - /* Use pagesize as default sectorsize */ + /* Use pagesize as default sectorsize. */ pagesize = getpagesize(); pagesize_len = snprintf(NULL, 0, "%d", pagesize) + 1; p = alloca(pagesize_len); @@ -401,15 +404,14 @@ swap_on_geli_args(const char *mntops) static const char * swap_on_off_geli(const char *name, char *mntops, int doingall) { - char *dname; - char *args; struct stat sb; + char *dname, *args; int error; error = stat(name, &sb); if (which_prog == SWAPON) do { - /* Skip if the .eli device already exists */ + /* Skip if the .eli device already exists. */ if (error == 0) break; @@ -430,8 +432,8 @@ swap_on_off_geli(const char *name, char *mntops, int doingall) free(args); if (error) { - /* error occured during creation */ - if (!qflag) + /* error occured during creation. */ + if (qflag == 0) warnx("%s: Invalid parameters", name); return (NULL); } @@ -536,7 +538,7 @@ swap_on_off_md(const char *name, char *mntops, int doingall) if (error == 0) { /* md device found. Ignore it. */ close(fd); - if (!qflag) + if (qflag == 0) warnx("md%d on %s: Device already " "in use", mdunit, vnodefile); free(vnodefile); @@ -719,13 +721,13 @@ swap_on_off_sfile(const char *name, int doingall) if (error == -1) { switch (errno) { case EBUSY: - if (!doingall) + if (doingall == 0) warnx("%s: Device already in use", name); break; case EINVAL: if (which_prog == SWAPON) warnx("%s: NSWAPDEV limit reached", name); - else if (!doingall) + else if (doingall == 0) warn("%s", name); break; default: @@ -740,6 +742,7 @@ swap_on_off_sfile(const char *name, int doingall) static void usage(void) { + fprintf(stderr, "usage: %s ", getprogname()); switch(orig_prog) { case SWAPON: @@ -757,16 +760,14 @@ static void sizetobuf(char *buf, size_t bufsize, int hflag, long long val, int hlen, long blocksize) { + char tmp[16]; if (hflag == 'H') { - char tmp[16]; - humanize_number(tmp, 5, (int64_t)val, "", HN_AUTOSCALE, HN_B | HN_NOSPACE | HN_DECIMAL); snprintf(buf, bufsize, "%*s", hlen, tmp); - } else { + } else snprintf(buf, bufsize, "%*lld", hlen, val / blocksize); - } } static void @@ -785,32 +786,32 @@ swaplist(int lflag, int sflag, int hflag) pagesize = getpagesize(); switch(hflag) { case 'G': - blocksize = 1024 * 1024 * 1024; - strlcpy(buf, "1GB-blocks", sizeof(buf)); - hlen = 10; - break; + blocksize = 1024 * 1024 * 1024; + strlcpy(buf, "1GB-blocks", sizeof(buf)); + hlen = 10; + break; case 'H': - blocksize = -1; - strlcpy(buf, "Bytes", sizeof(buf)); - hlen = 10; - break; + blocksize = -1; + strlcpy(buf, "Bytes", sizeof(buf)); + hlen = 10; + break; case 'K': - blocksize = 1024; - strlcpy(buf, "1kB-blocks", sizeof(buf)); - hlen = 10; - break; + blocksize = 1024; + strlcpy(buf, "1kB-blocks", sizeof(buf)); + hlen = 10; + break; case 'M': - blocksize = 1024 * 1024; - strlcpy(buf, "1MB-blocks", sizeof(buf)); - hlen = 10; - break; + blocksize = 1024 * 1024; + strlcpy(buf, "1MB-blocks", sizeof(buf)); + hlen = 10; + break; default: - getbsize(&hlen, &blocksize); - snprintf(buf, sizeof(buf), "%ld-blocks", blocksize); - break; + getbsize(&hlen, &blocksize); + snprintf(buf, sizeof(buf), "%ld-blocks", blocksize); + break; } - mibsize = sizeof mib / sizeof mib[0]; + mibsize = nitems(mib); if (sysctlnametomib("vm.swap_info", mib, &mibsize) == -1) err(1, "sysctlnametomib()"); diff --git a/secure/lib/libssh/Makefile b/secure/lib/libssh/Makefile index 1daf972dc3db..3d30a18de80f 100644 --- a/secure/lib/libssh/Makefile +++ b/secure/lib/libssh/Makefile @@ -3,6 +3,7 @@ .include LIB= ssh +PRIVATELIB= true SHLIB_MAJOR= 5 SRCS= authfd.c authfile.c bufaux.c bufbn.c buffer.c \ canohost.c channels.c cipher.c cipher-aes.c \ diff --git a/secure/libexec/sftp-server/Makefile b/secure/libexec/sftp-server/Makefile index 7069cff90159..3755c986df57 100644 --- a/secure/libexec/sftp-server/Makefile +++ b/secure/libexec/sftp-server/Makefile @@ -10,6 +10,7 @@ SRCS+= roaming_dummy.c DPADD= ${LIBSSH} ${LIBCRYPT} ${LIBCRYPTO} ${LIBZ} LDADD= -lssh -lcrypt -lcrypto -lz +USEPRIVATELIB= ssh .include diff --git a/secure/libexec/ssh-keysign/Makefile b/secure/libexec/ssh-keysign/Makefile index c5fc68815759..66528e3ff1a2 100644 --- a/secure/libexec/ssh-keysign/Makefile +++ b/secure/libexec/ssh-keysign/Makefile @@ -8,6 +8,7 @@ BINMODE=4555 DPADD= ${LIBSSH} ${LIBCRYPT} ${LIBCRYPTO} ${LIBZ} LDADD= -lssh -lcrypt -lcrypto -lz +USEPRIVATELIB= ssh .include diff --git a/secure/libexec/ssh-pkcs11-helper/Makefile b/secure/libexec/ssh-pkcs11-helper/Makefile index f575a08afead..ec57a613b0b4 100644 --- a/secure/libexec/ssh-pkcs11-helper/Makefile +++ b/secure/libexec/ssh-pkcs11-helper/Makefile @@ -8,6 +8,7 @@ CFLAGS+=-I${SSHDIR} -include ssh_namespace.h DPADD= ${LIBSSH} ${LIBCRYPT} ${LIBCRYPTO} ${LIBZ} LDADD= -lssh -lcrypt -lcrypto -lz +USEPRIVATELIB= ssh .include diff --git a/secure/usr.bin/scp/Makefile b/secure/usr.bin/scp/Makefile index 8a558c77b951..fe248ab76368 100644 --- a/secure/usr.bin/scp/Makefile +++ b/secure/usr.bin/scp/Makefile @@ -9,6 +9,7 @@ SRCS+= roaming_dummy.c DPADD= ${LIBSSH} ${LIBCRYPT} ${LIBCRYPTO} ${LIBZ} LDADD= -lssh -lcrypt -lcrypto -lz +USEPRIVATELIB= ssh .include diff --git a/secure/usr.bin/sftp/Makefile b/secure/usr.bin/sftp/Makefile index dce01048429d..8164dac7b6e2 100644 --- a/secure/usr.bin/sftp/Makefile +++ b/secure/usr.bin/sftp/Makefile @@ -9,6 +9,7 @@ SRCS+= roaming_dummy.c DPADD= ${LIBSSH} ${LIBCRYPT} ${LIBCRYPTO} ${LIBZ} ${LIBEDIT} ${LIBNCURSES} LDADD= -lssh -lcrypt -lcrypto -lz -ledit -lncurses +USEPRIVATELIB= ssh .include diff --git a/secure/usr.bin/ssh-add/Makefile b/secure/usr.bin/ssh-add/Makefile index 0cbcbcb1a9b2..cb14ce6c81fc 100644 --- a/secure/usr.bin/ssh-add/Makefile +++ b/secure/usr.bin/ssh-add/Makefile @@ -9,6 +9,7 @@ SRCS+= roaming_dummy.c DPADD= ${LIBSSH} ${LIBCRYPT} ${LIBCRYPTO} ${LIBZ} LDADD= -lssh -lcrypt -lcrypto -lz +USEPRIVATELIB= ssh .include diff --git a/secure/usr.bin/ssh-agent/Makefile b/secure/usr.bin/ssh-agent/Makefile index a93a1c64776c..29620d18613f 100644 --- a/secure/usr.bin/ssh-agent/Makefile +++ b/secure/usr.bin/ssh-agent/Makefile @@ -9,6 +9,7 @@ SRCS+= roaming_dummy.c DPADD= ${LIBSSH} ${LIBCRYPT} ${LIBCRYPTO} ${LIBZ} LDADD= -lssh -lcrypt -lcrypto -lz +USEPRIVATELIB= ssh .include diff --git a/secure/usr.bin/ssh-keygen/Makefile b/secure/usr.bin/ssh-keygen/Makefile index 0c250331023c..48e486e573e0 100644 --- a/secure/usr.bin/ssh-keygen/Makefile +++ b/secure/usr.bin/ssh-keygen/Makefile @@ -9,6 +9,7 @@ SRCS+= roaming_dummy.c DPADD= ${LIBSSH} ${LIBCRYPT} ${LIBCRYPTO} ${LIBZ} LDADD= -lssh -lcrypt -lcrypto -lz +USEPRIVATELIB= ssh .include diff --git a/secure/usr.bin/ssh-keyscan/Makefile b/secure/usr.bin/ssh-keyscan/Makefile index 8d3f6c6b4e81..cc82d07e1b08 100644 --- a/secure/usr.bin/ssh-keyscan/Makefile +++ b/secure/usr.bin/ssh-keyscan/Makefile @@ -6,6 +6,7 @@ CFLAGS+=-I${SSHDIR} -include ssh_namespace.h DPADD= ${LIBSSH} ${LIBCRYPT} ${LIBCRYPTO} ${LIBZ} LDADD= -lssh -lcrypt -lcrypto -lz +USEPRIVATELIB= ssh .include diff --git a/secure/usr.bin/ssh/Makefile b/secure/usr.bin/ssh/Makefile index 0bee10cbc012..a5e580879d6b 100644 --- a/secure/usr.bin/ssh/Makefile +++ b/secure/usr.bin/ssh/Makefile @@ -18,6 +18,7 @@ SRCS+= gss-genr.c DPADD= ${LIBSSH} ${LIBUTIL} ${LIBZ} LDADD= -lssh -lutil -lz +USEPRIVATELIB= ssh .if ${MK_KERBEROS_SUPPORT} != "no" CFLAGS+= -DGSSAPI -DHAVE_GSSAPI_GSSAPI_H=1 -DKRB5 -DHEIMDAL diff --git a/secure/usr.sbin/sshd/Makefile b/secure/usr.sbin/sshd/Makefile index 3fb07087ca79..bb37ae4775f0 100644 --- a/secure/usr.sbin/sshd/Makefile +++ b/secure/usr.sbin/sshd/Makefile @@ -27,6 +27,7 @@ CFLAGS+=-I${SSHDIR} -include ssh_namespace.h DPADD= ${LIBSSH} ${LIBUTIL} ${LIBZ} ${LIBWRAP} ${LIBPAM} LDADD= -lssh -lutil -lz -lwrap ${MINUSLPAM} +USEPRIVATELIB= ssh .if ${MK_AUDIT} != "no" CFLAGS+= -DUSE_BSM_AUDIT -DHAVE_GETAUDIT_ADDR diff --git a/share/examples/kld/Makefile b/share/examples/kld/Makefile index 4e3b641f57c7..5e6fc7459bc5 100644 --- a/share/examples/kld/Makefile +++ b/share/examples/kld/Makefile @@ -67,6 +67,6 @@ # $FreeBSD$ # -SUBDIR= cdev dyn_sysctl firmware khelp syscall +SUBDIR= cdev dyn_sysctl firmware khelp random_adaptor syscall .include diff --git a/share/examples/kld/random_adaptor/Makefile b/share/examples/kld/random_adaptor/Makefile new file mode 100644 index 000000000000..d19b4dc26473 --- /dev/null +++ b/share/examples/kld/random_adaptor/Makefile @@ -0,0 +1,6 @@ +# $FreeBSD$ + +KMOD= random_adaptor_example +SRCS= ${KMOD}.c + +.include diff --git a/share/examples/kld/random_adaptor/random_adaptor_example.c b/share/examples/kld/random_adaptor/random_adaptor_example.c new file mode 100644 index 000000000000..c0ab10a83fc5 --- /dev/null +++ b/share/examples/kld/random_adaptor/random_adaptor_example.c @@ -0,0 +1,94 @@ +/*- + * Copyright (c) 2013 Arthur Mesh + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer + * in this position and unchanged. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#include +__FBSDID("$FreeBSD$"); + +#include +#include +#include +#include +#include + +#include +#include + +#define RNG_NAME "example" + +static int random_example_read(void *, int); + +struct random_adaptor random_example = { + .ident = "Example RNG", + .init = (random_init_func_t *)random_null_func, + .deinit = (random_deinit_func_t *)random_null_func, + .read = random_example_read, + .write = (random_write_func_t *)random_null_func, + .reseed = (random_reseed_func_t *)random_null_func, + .seeded = 1, +}; + +/* + * Used under the license provided @ http://xkcd.com/221/ + * http://creativecommons.org/licenses/by-nc/2.5/ + */ +static u_char +getRandomNumber(void) +{ + return 4; /* chosen by fair dice roll, guaranteed to be random */ +} + +static int +random_example_read(void *buf, int c) +{ + u_char *b; + int count; + + b = buf; + + for (count = 0; count < c; count++) { + b[count] = getRandomNumber(); + } + + printf("returning %d bytes of pure randomness\n", c); + return (c); +} + +static int +random_example_modevent(module_t mod, int type, void *unused) +{ + + switch (type) { + case MOD_LOAD: + random_adaptor_register(RNG_NAME, &random_example); + EVENTHANDLER_INVOKE(random_adaptor_attach, &random_example); + return (0); + } + + return (EINVAL); +} + +RANDOM_ADAPTOR_MODULE(random_example, random_example_modevent, 1); diff --git a/share/man/man4/capsicum.4 b/share/man/man4/capsicum.4 index 8f38dc42157d..84ddb91ff989 100644 --- a/share/man/man4/capsicum.4 +++ b/share/man/man4/capsicum.4 @@ -100,7 +100,7 @@ associated with file descriptors; described in greater detail in .Xr read 2 , .Xr shm_open 2 , .Xr write 2 , -.Xr procdesc 4 , +.Xr procdesc 4 .Sh HISTORY .Nm first appeared in diff --git a/share/man/man4/geom.4 b/share/man/man4/geom.4 index 460667650f04..3cfc28383d14 100644 --- a/share/man/man4/geom.4 +++ b/share/man/man4/geom.4 @@ -34,7 +34,7 @@ .\" .\" $FreeBSD$ .\" -.Dd March 14, 2013 +.Dd September 10, 2013 .Dt GEOM 4 .Os .Sh NAME @@ -354,24 +354,6 @@ only be done with their cooperation. Finally: the spoiling only happens when the write count goes from zero to non-zero and the retasting happens only when the write count goes from non-zero to zero. -.It Em INSERT/DELETE -are very special operations which allow a new geom -to be instantiated between a consumer and a provider attached to -each other and to remove it again. -.Pp -To understand the utility of this, imagine a provider -being mounted as a file system. -Between the DEVFS geom's consumer and its provider we insert -a mirror module which configures itself with one mirror -copy and consequently is transparent to the I/O requests -on the path. -We can now configure yet a mirror copy on the mirror geom, -request a synchronization, and finally drop the first mirror -copy. -We have now, in essence, moved a mounted file system from one -disk to another while it was being used. -At this point the mirror geom can be deleted from the path -again; it has served its purpose. .It Em CONFIGURE is the process where the administrator issues instructions for a particular class to instantiate itself. diff --git a/share/man/man4/netgraph.4 b/share/man/man4/netgraph.4 index ebd0aa5fdac4..6783973eac57 100644 --- a/share/man/man4/netgraph.4 +++ b/share/man/man4/netgraph.4 @@ -1284,7 +1284,7 @@ link between two machines. There is a full multilink PPP implementation that runs in .Nm . The -.Pa net/mpd +.Pa net/mpd5 port can use these modules to make a very low latency high capacity PPP system. It also supports @@ -1423,6 +1423,7 @@ common networking problems, solved using .Xr ng_bridge 4 , .Xr ng_bt3c 4 , .Xr ng_btsocket 4 , +.Xr ng_car 4 , .Xr ng_cisco 4 , .Xr ng_device 4 , .Xr ng_echo 4 , @@ -1439,13 +1440,16 @@ common networking problems, solved using .Xr ng_hub 4 , .Xr ng_iface 4 , .Xr ng_ip_input 4 , +.Xr ng_ipfw 4 , .Xr ng_ksocket 4 , .Xr ng_l2cap 4 , .Xr ng_l2tp 4 , .Xr ng_lmi 4 , .Xr ng_mppc 4 , +.Xr ng_nat 4 , .Xr ng_netflow 4 , .Xr ng_one2many 4 , +.Xr ng_patch 4 , .Xr ng_ppp 4 , .Xr ng_pppoe 4 , .Xr ng_pptpgre 4 , diff --git a/share/man/man4/ntb.4 b/share/man/man4/ntb.4 index c5765266e934..ac16c61ebe09 100644 --- a/share/man/man4/ntb.4 +++ b/share/man/man4/ntb.4 @@ -71,7 +71,7 @@ This needs to be done on both systems. Each system needs to have a different IP address assigned. The MAC address is randomly generated. Also for maximum performance, the MTU should be set to 16 kiB. -This can be down by adding the line below to +This can be done by adding the line below to .Xr rc.conf 5 : .Bd -literal -offset indent ifconfig_ntb0="inet 192.168.1.10 netmask 255.255.255.0 mtu 16384" diff --git a/share/man/man4/procdesc.4 b/share/man/man4/procdesc.4 index f7477da88243..9bd310200c20 100644 --- a/share/man/man4/procdesc.4 +++ b/share/man/man4/procdesc.4 @@ -68,7 +68,7 @@ Given a process descriptor, it is possible to query its conventional PID using .Xr pdfork 2 , .Xr pdgetpid 2 , .Xr pdkill 2 , -.Xr pdwait4 , +.Xr pdwait4 2 , .Xr capsicum 4 .Sh HISTORY .Nm diff --git a/share/man/man5/src.conf.5 b/share/man/man5/src.conf.5 index 4e8986445a90..3623b0ee4081 100644 --- a/share/man/man5/src.conf.5 +++ b/share/man/man5/src.conf.5 @@ -1,7 +1,7 @@ .\" DO NOT EDIT-- this file is automatically generated. .\" from FreeBSD: head/tools/build/options/makeman 253304 2013-07-12 23:08:44Z bapt .\" $FreeBSD$ -.Dd August 29, 2013 +.Dd September 6, 2013 .Dt SRC.CONF 5 .Os .Sh NAME @@ -471,12 +471,17 @@ Set to not build .\" from FreeBSD: head/tools/build/options/WITHOUT_GAMES 156932 2006-03-21 07:50:50Z ru Set to not build games. .It Va WITHOUT_GCC -.\" from FreeBSD: head/tools/build/options/WITHOUT_GCC 222090 2011-05-19 05:13:25Z imp -Set to not install gcc and g++. -.Bf -symbolic -The option does not generally work for build targets, unless some alternative -toolchain is enabled. -.Ef +.\" from FreeBSD: head/tools/build/options/WITHOUT_GCC 255326 2013-09-06 20:49:48Z zeising +Set to not build and install gcc and g++. +.Pp +It is a default setting on +amd64/amd64, arm/arm, arm/armv6 and i386/i386. +.It Va WITH_GCC +.\" from FreeBSD: head/tools/build/options/WITH_GCC 255326 2013-09-06 20:49:48Z zeising +Set to build and install gcc and g++. +.Pp +It is a default setting on +arm/armeb, arm/armv6eb, ia64/ia64, mips/mipsel, mips/mips, mips/mips64el, mips/mips64, mips/mipsn32, pc98/i386, powerpc/powerpc, powerpc/powerpc64 and sparc64/sparc64. .It Va WITHOUT_GCOV .\" from FreeBSD: head/tools/build/options/WITHOUT_GCOV 156932 2006-03-21 07:50:50Z ru Set to not build the @@ -500,6 +505,20 @@ When set, it also enforces the following options: .It .Va WITHOUT_GNU_SUPPORT .El +.It Va WITHOUT_GNUCXX +.\" from FreeBSD: head/tools/build/options/WITHOUT_GNUCXX 255321 2013-09-06 20:08:03Z theraven +Do not build the GNU C++ stack (g++, libstdc++). +This is the default on platforms where clang is the system compiler. +.Pp +It is a default setting on +amd64/amd64, arm/arm, arm/armv6, i386/i386 and pc98/i386. +.It Va WITH_GNUCXX +.\" from FreeBSD: head/tools/build/options/WITH_GNUCXX 255321 2013-09-06 20:08:03Z theraven +Build the GNU C++ stack (g++, libstdc++). +This is the default on platforms where gcc is the system compiler. +.Pp +It is a default setting on +arm/armeb, arm/armv6eb, ia64/ia64, mips/mipsel, mips/mips, mips/mips64el, mips/mips64, mips/mipsn32, powerpc/powerpc, powerpc/powerpc64 and sparc64/sparc64. .It Va WITHOUT_GNU_SUPPORT .\" from FreeBSD: head/tools/build/options/WITHOUT_GNU_SUPPORT 156932 2006-03-21 07:50:50Z ru Set to build some programs without optional GNU support. diff --git a/share/misc/committers-ports.dot b/share/misc/committers-ports.dot index 16dd34823d60..79831dcd3d70 100644 --- a/share/misc/committers-ports.dot +++ b/share/misc/committers-ports.dot @@ -103,6 +103,7 @@ gerald [label="Gerald Pfeifer\ngerald@FreeBSD.org\n2002/04/03"] gjb [label="Glen Barber\ngjb@FreeBSD.org\n2012/06/19"] glarkin [label="Greg Larkin\nglarkin@FreeBSD.org\n2008/07/17"] glewis [label="Greg Lewis\nglewis@FreeBSD.org\n2002/04/08"] +gnn [label="George Neville-Neil\ngnn@FreeBSD.org\n2013/09/04"] hq [label="Herve Quiroz\nhq@FreeBSD.org\n2004/08/05"] ijliao [label="Ying-Chieh Liao\nijliao@FreeBSD.org\n2001/01/20"] itetcu [label="Ion-Mihai Tetcu\nitetcu@FreeBSD.org\n2006/06/07"] @@ -491,6 +492,8 @@ sem -> stas shaun -> timur shaun -> matthew +skreuzer -> gnn + sobomax -> demon sobomax -> glewis sobomax -> lev diff --git a/share/misc/committers-src.dot b/share/misc/committers-src.dot index d158999151fa..a273cf9b3b97 100644 --- a/share/misc/committers-src.dot +++ b/share/misc/committers-src.dot @@ -290,6 +290,7 @@ wkoszek [label="Wojciech A. Koszek\nwkoszek@FreeBSD.org\n2006/02/21"] wollman [label="Garrett Wollman\nwollman@FreeBSD.org\n????/??/??"] wsalamon [label="Wayne Salamon\nwsalamon@FreeBSD.org\n2005/06/25"] yongari [label="Pyun YongHyeon\nyongari@FreeBSD.org\n2004/08/01"] +zbb [label="Zbigniew Bodek\nzbb@FreeBSD.org\n2013/09/02"] zec [label="Marko Zec\nzec@FreeBSD.org\n2008/06/22"] zml [label="Zachary Loafman\nzml@FreeBSD.org\n2009/05/27"] zont [label="Andrey Zonov\nzont@FreeBSD.org\n2012/08/21"] @@ -354,6 +355,7 @@ cognet -> jceel cognet -> kevlo cognet -> ian cognet -> wkoszek +cognet -> zbb cperciva -> eadler cperciva -> flz diff --git a/share/mk/bsd.lib.mk b/share/mk/bsd.lib.mk index 66d0a292605a..bb3db64c5763 100644 --- a/share/mk/bsd.lib.mk +++ b/share/mk/bsd.lib.mk @@ -119,16 +119,24 @@ PO_FLAG=-pg all: objwarn +.if defined(PRIVATELIB) +_LIBDIR:=${LIBPRIVATEDIR} +_SHLIBDIR:=${LIBPRIVATEDIR} +.else +_LIBDIR:=${LIBDIR} +_SHLIBDIR:=${SHLIBDIR} +.endif + .if defined(SHLIB_NAME) .if ${MK_DEBUG_FILES} != "no" SHLIB_NAME_FULL=${SHLIB_NAME}.full # Use ${DEBUGDIR} for base system debug files, else .debug subdirectory -.if ${SHLIBDIR} == "/boot" ||\ +.if ${_SHLIBDIR} == "/boot" ||\ ${SHLIBDIR:C%/lib(/.*)?$%/lib%} == "/lib" ||\ ${SHLIBDIR:C%/usr/lib(32)?(/.*)?%/usr/lib%} == "/usr/lib" -DEBUGFILEDIR=${DEBUGDIR}${SHLIBDIR} +DEBUGFILEDIR=${DEBUGDIR}${_SHLIBDIR} .else -DEBUGFILEDIR=${SHLIBDIR}/.debug +DEBUGFILEDIR=${_SHLIBDIR}/.debug DEBUGMKDIR= .endif .else @@ -145,6 +153,10 @@ ${SHLIB_NAME_FULL}: ${VERSION_MAP} LDFLAGS+= -Wl,--version-script=${VERSION_MAP} .endif +.if defined(USEPRIVATELIB) +LDFLAGS+= -L${_SHLIBDIRPREFIX}${LIBPRIVATEDIR} -rpath ${LIBPRIVATEDIR} +.endif + .if defined(LIB) && !empty(LIB) || defined(SHLIB_NAME) OBJS+= ${SRCS:N*.h:R:S/$/.o/} .endif @@ -291,16 +303,16 @@ realinstall: _libinstall _libinstall: .if defined(LIB) && !empty(LIB) && ${MK_INSTALLLIB} != "no" ${INSTALL} -C -o ${LIBOWN} -g ${LIBGRP} -m ${LIBMODE} \ - ${_INSTALLFLAGS} lib${LIB}.a ${DESTDIR}${LIBDIR} + ${_INSTALLFLAGS} lib${LIB}.a ${DESTDIR}${_LIBDIR} .endif .if ${MK_PROFILE} != "no" && defined(LIB) && !empty(LIB) ${INSTALL} -C -o ${LIBOWN} -g ${LIBGRP} -m ${LIBMODE} \ - ${_INSTALLFLAGS} lib${LIB}_p.a ${DESTDIR}${LIBDIR} + ${_INSTALLFLAGS} lib${LIB}_p.a ${DESTDIR}${_LIBDIR} .endif .if defined(SHLIB_NAME) ${INSTALL} ${STRIP} -o ${LIBOWN} -g ${LIBGRP} -m ${LIBMODE} \ ${_INSTALLFLAGS} ${_SHLINSTALLFLAGS} \ - ${SHLIB_NAME} ${DESTDIR}${SHLIBDIR} + ${SHLIB_NAME} ${DESTDIR}${_SHLIBDIR} .if ${MK_DEBUG_FILES} != "no" .if defined(DEBUGMKDIR) ${INSTALL} -T debug -d ${DESTDIR}${DEBUGFILEDIR} @@ -328,23 +340,23 @@ _libinstall: # installworld; in the later case ${_LDSCRIPTROOT} must be obviously empty # because on the target system, libraries are meant to be looked up from /. .if defined(SHLIB_LDSCRIPT) && !empty(SHLIB_LDSCRIPT) && exists(${.CURDIR}/${SHLIB_LDSCRIPT}) - sed -e 's,@@SHLIB@@,${_LDSCRIPTROOT}${SHLIBDIR}/${SHLIB_NAME},g' \ - -e 's,@@LIBDIR@@,${_LDSCRIPTROOT}${LIBDIR},g' \ - ${.CURDIR}/${SHLIB_LDSCRIPT} > ${DESTDIR}${LIBDIR}/${SHLIB_LINK:R}.ld + sed -e 's,@@SHLIB@@,${_LDSCRIPTROOT}${_SHLIBDIR}/${SHLIB_NAME},g' \ + -e 's,@@LIBDIR@@,${_LDSCRIPTROOT}${_LIBDIR},g' \ + ${.CURDIR}/${SHLIB_LDSCRIPT} > ${DESTDIR}${_LIBDIR}/${SHLIB_LINK:R}.ld ${INSTALL} -S -C -o ${LIBOWN} -g ${LIBGRP} -m ${LIBMODE} \ - ${_INSTALLFLAGS} ${DESTDIR}${LIBDIR}/${SHLIB_LINK:R}.ld \ - ${DESTDIR}${LIBDIR}/${SHLIB_LINK} - rm -f ${DESTDIR}${LIBDIR}/${SHLIB_LINK:R}.ld + ${_INSTALLFLAGS} ${DESTDIR}${_LIBDIR}/${SHLIB_LINK:R}.ld \ + ${DESTDIR}${_LIBDIR}/${SHLIB_LINK} + rm -f ${DESTDIR}${_LIBDIR}/${SHLIB_LINK:R}.ld .else -.if ${SHLIBDIR} == ${LIBDIR} - ${INSTALL_SYMLINK} ${SHLIB_NAME} ${DESTDIR}${LIBDIR}/${SHLIB_LINK} +.if ${_SHLIBDIR} == ${_LIBDIR} + ${INSTALL_SYMLINK} ${SHLIB_NAME} ${DESTDIR}${_LIBDIR}/${SHLIB_LINK} .else - ${INSTALL_SYMLINK} ${_SHLIBDIRPREFIX}${SHLIBDIR}/${SHLIB_NAME} \ - ${DESTDIR}${LIBDIR}/${SHLIB_LINK} -.if exists(${DESTDIR}${LIBDIR}/${SHLIB_NAME}) - -chflags noschg ${DESTDIR}${LIBDIR}/${SHLIB_NAME} - rm -f ${DESTDIR}${LIBDIR}/${SHLIB_NAME} + ${INSTALL_SYMLINK} ${_SHLIBDIRPREFIX}${_SHLIBDIR}/${SHLIB_NAME} \ + ${DESTDIR}${_LIBDIR}/${SHLIB_LINK} +.if exists(${DESTDIR}${_LIBDIR}/${SHLIB_NAME}) + -chflags noschg ${DESTDIR}${_LIBDIR}/${SHLIB_NAME} + rm -f ${DESTDIR}${_LIBDIR}/${SHLIB_NAME} .endif .endif .endif # SHLIB_LDSCRIPT @@ -352,7 +364,7 @@ _libinstall: .endif # SHIB_NAME .if defined(INSTALL_PIC_ARCHIVE) && defined(LIB) && !empty(LIB) && ${MK_TOOLCHAIN} != "no" ${INSTALL} -o ${LIBOWN} -g ${LIBGRP} -m ${LIBMODE} \ - ${_INSTALLFLAGS} lib${LIB}_pic.a ${DESTDIR}${LIBDIR} + ${_INSTALLFLAGS} lib${LIB}_pic.a ${DESTDIR}${_LIBDIR} .endif .if defined(WANT_LINT) && !defined(NO_LINT) && defined(LIB) && !empty(LIB) ${INSTALL} -o ${LIBOWN} -g ${LIBGRP} -m ${LIBMODE} \ diff --git a/share/mk/bsd.libnames.mk b/share/mk/bsd.libnames.mk index accda1caf53e..00d38ff192a9 100644 --- a/share/mk/bsd.libnames.mk +++ b/share/mk/bsd.libnames.mk @@ -65,6 +65,8 @@ LIBGSSAPI_KRB5?= ${DESTDIR}${LIBDIR}/libgssapi_krb5.a LIBHDB?= ${DESTDIR}${LIBDIR}/libhdb.a LIBHISTORY?= ${DESTDIR}${LIBDIR}/libhistory.a LIBHEIMBASE?= ${DESTDIR}${LIBDIR}/libheimbase.a +LIBHEIMIPCC?= ${DESTDIR}${LIBPRIVATEDIR}/libheimipcc.a +LIBHEIMIPCS?= ${DESTDIR}${LIBPRIVATEDIR}/libheimipcs.a LIBHEIMNTLM?= ${DESTDIR}${LIBDIR}/libheimntlm.a LIBHEIMSQLITE?= ${DESTDIR}${LIBDIR}/libheimsqlite.a LIBHX509?= ${DESTDIR}${LIBDIR}/libhx509.a @@ -88,7 +90,7 @@ LIBKRB5?= ${DESTDIR}${LIBDIR}/libkrb5.a LIBKVM?= ${DESTDIR}${LIBDIR}/libkvm.a LIBL?= ${DESTDIR}${LIBDIR}/libl.a .if ${MK_LDNS} != "no" -LIBLDNS?= ${DESTDIR}${LIBDIR}/libldns.a +LIBLDNS?= ${DESTDIR}${LIBPRIVATEDIR}/libldns.a .endif LIBLN?= "don't use LIBLN, use LIBL" .if ${MK_BIND} != "no" @@ -151,7 +153,7 @@ LIBRTLD_DB?= ${DESTDIR}${LIBDIR}/librtld_db.a LIBSBUF?= ${DESTDIR}${LIBDIR}/libsbuf.a LIBSDP?= ${DESTDIR}${LIBDIR}/libsdp.a LIBSMB?= ${DESTDIR}${LIBDIR}/libsmb.a -LIBSSH?= ${DESTDIR}${LIBDIR}/libssh.a +LIBSSH?= ${DESTDIR}${LIBPRIVATEDIR}/libssh.a LIBSSL?= ${DESTDIR}${LIBDIR}/libssl.a LIBSTAND?= ${DESTDIR}${LIBDIR}/libstand.a LIBSTDCPLUSPLUS?= ${DESTDIR}${LIBDIR}/libstdc++.a diff --git a/share/mk/bsd.own.mk b/share/mk/bsd.own.mk index da758d54cbbb..8f7f0b92c5ff 100644 --- a/share/mk/bsd.own.mk +++ b/share/mk/bsd.own.mk @@ -28,6 +28,8 @@ # # LIBCOMPATDIR Base path for compat libraries. [/usr/lib/compat] # +# LIBPRIVATEDIR Base path for private libraries. [/usr/lib/private] +# # LIBDATADIR Base path for misc. utility data files. [/usr/libdata] # # LIBEXECDIR Base path for system daemons and utilities. [/usr/libexec] @@ -144,6 +146,7 @@ KMODMODE?= ${BINMODE} LIBDIR?= /usr/lib LIBCOMPATDIR?= /usr/lib/compat +LIBPRIVATEDIR?= /usr/lib/private LIBDATADIR?= /usr/libdata LIBEXECDIR?= /usr/libexec LINTLIBDIR?= /usr/libdata/lint @@ -284,7 +287,6 @@ __DEFAULT_YES_OPTIONS = \ FP_LIBC \ FREEBSD_UPDATE \ GAMES \ - GCC \ GCOV \ GDB \ GNU \ @@ -400,6 +402,11 @@ __T=${TARGET_ARCH} .else __T=${MACHINE_ARCH} .endif +.if defined(TARGET) +__TT=${TARGET} +.else +__TT=${MACHINE} +.endif # Clang is only for x86, powerpc and little-endian arm right now, by default. .if ${__T} == "amd64" || ${__T} == "i386" || ${__T:Mpowerpc*} __DEFAULT_YES_OPTIONS+=CLANG CLANG_FULL @@ -414,8 +421,33 @@ __DEFAULT_NO_OPTIONS+=CLANG CLANG_FULL .if ${__T} == "amd64" || ${__T} == "arm" || ${__T} == "armv6" || \ ${__T} == "i386" __DEFAULT_YES_OPTIONS+=CLANG_IS_CC +# The pc98 bootloader requires gcc to build and so we must leave gcc enabled +# for pc98 for now. +.if ${__TT} == "pc98" +__DEFAULT_NO_OPTIONS+=GNUCXX +__DEFAULT_YES_OPTIONS+=GCC .else +__DEFAULT_NO_OPTIONS+=GCC GNUCXX +.endif +# The libc++ headers use c++11 extensions. These are normally silenced because +# they are treated as system headers, but we explicitly disable that warning +# suppression when building the base system to catch bugs in our headers. +# Eventually we'll want to start building the base system C++ code as C++11, +# but not yet. +_COMPVERSION!= ${CC} --version +.if ${_COMPVERSION:Mclang} +CXXFLAGS+= -Wno-c++11-extensions +.endif +.else +# If clang is not cc, then build gcc by default __DEFAULT_NO_OPTIONS+=CLANG_IS_CC +__DEFAULT_YES_OPTIONS+=GCC +# And if g++ is c++, build the rest of the GNU C++ stack +.if defined(WITHOUT_CXX) +__DEFAULT_NO_OPTIONS+=GNUCXX +.else +__DEFAULT_YES_OPTIONS+=GNUCXX +.endif .endif # FDT is needed only for arm, mips and powerpc .if ${__T:Marm*} || ${__T:Mpowerpc*} || ${__T:Mmips*} diff --git a/share/mk/bsd.prog.mk b/share/mk/bsd.prog.mk index f4546dcb17e3..22ddfb538435 100644 --- a/share/mk/bsd.prog.mk +++ b/share/mk/bsd.prog.mk @@ -52,6 +52,10 @@ STRIP?= -s LDFLAGS+= -static .endif +.if defined(USEPRIVATELIB) +LDFLAGS+= -L${_SHLIBDIRPREFIX}${LIBPRIVATEDIR} -rpath ${LIBPRIVATEDIR} +.endif + .if ${MK_DEBUG_FILES} != "no" PROG_FULL=${PROG}.full # Use ${DEBUGDIR} for base system debug files, else .debug subdirectory @@ -169,7 +173,7 @@ _EXTRADEPEND: .else echo ${PROG}: ${LIBC} ${DPADD} >> ${DEPENDFILE} .if defined(PROG_CXX) -.if !empty(CXXFLAGS:M-stdlib=libc++) +.if ${MK_CLANG_IS_CC} != "no" && empty(CXXFLAGS:M-stdlib=libstdc++) echo ${PROG}: ${LIBCPLUSPLUS} >> ${DEPENDFILE} .else echo ${PROG}: ${LIBSTDCPLUSPLUS} >> ${DEPENDFILE} diff --git a/sys/amd64/amd64/apic_vector.S b/sys/amd64/amd64/apic_vector.S index 79ec5ed9e78f..d002b4d86e0d 100644 --- a/sys/amd64/amd64/apic_vector.S +++ b/sys/amd64/amd64/apic_vector.S @@ -168,7 +168,7 @@ global_invltlb: invltlb_ret_clear_pm_save: movq smp_tlb_pmap,%rdx testq %rdx,%rdx - jz invltlb_ret + jz invltlb_ret_rdx testb $SEL_RPL_MASK,NAKE_INTR_CS(%rsp) jz 1f swapgs @@ -179,16 +179,17 @@ invltlb_ret_clear_pm_save: 2: LK btcl %eax,PM_SAVE(%rdx) SUPERALIGN_TEXT -invltlb_ret: +invltlb_ret_rdx: + popq %rdx +invltlb_ret_rax: movq lapic, %rax movl $0, LA_EOI(%rax) /* End Of Interrupt to APIC */ LK incl smp_tlb_wait - popq %rdx popq %rax jmp doreti_iret SUPERALIGN_TEXT -IDTVEC(invltlb) +IDTVEC(invltlb_pcid) #if defined(COUNT_XINVLTLB_HITS) || defined(COUNT_IPIS) PUSH_FRAME movl PCPU(CPUID), %eax @@ -206,8 +207,6 @@ IDTVEC(invltlb) pushq %rdx movq %cr3,%rax - cmpl $0,pmap_pcid_enabled - je 2f movq $smp_tlb_invpcid,%rdx cmpl $0,(%rdx) @@ -216,8 +215,7 @@ IDTVEC(invltlb) je global_invltlb /* - * Non-zero smp_tlb_invpcid, only invalidate TLB for entries with - * current PCID. + * Only invalidate TLB for entries with current PCID. */ cmpl $0,invpcid_works je 1f @@ -233,21 +231,36 @@ IDTVEC(invltlb) je 2f movq %rdx,%cr3 /* Invalidate, bit 63 is zero. */ btsq $63,%rax - - /* - * Invalidate the TLB if PCID is not enabled. - * Restore the old address space. - */ 2: movq %rax,%cr3 jmp invltlb_ret_clear_pm_save + SUPERALIGN_TEXT +IDTVEC(invltlb) +#if defined(COUNT_XINVLTLB_HITS) || defined(COUNT_IPIS) + PUSH_FRAME + movl PCPU(CPUID), %eax +#ifdef COUNT_XINVLTLB_HITS + incl xhits_gbl(,%rax,4) +#endif +#ifdef COUNT_IPIS + movq ipi_invltlb_counts(,%rax,8),%rax + incq (%rax) +#endif + POP_FRAME +#endif + + pushq %rax + movq %cr3, %rax /* invalidate the TLB */ + movq %rax, %cr3 + jmp invltlb_ret_rax + /* * Single page TLB shootdown */ .text SUPERALIGN_TEXT -IDTVEC(invlpg) +IDTVEC(invlpg_pcid) #if defined(COUNT_XINVLTLB_HITS) || defined(COUNT_IPIS) PUSH_FRAME movl PCPU(CPUID), %eax @@ -264,8 +277,6 @@ IDTVEC(invlpg) pushq %rax pushq %rdx movq $smp_tlb_invpcid,%rdx - cmpl $0,pmap_pcid_enabled - je 3f cmpl $0,invpcid_works jne 2f @@ -291,7 +302,7 @@ IDTVEC(invlpg) btsq $63,%rcx movq %rcx,%cr3 popq %rcx - jmp invltlb_ret + jmp invltlb_ret_rdx /* * Invalidate the TLB entry using INVPCID_ADDR. @@ -300,7 +311,7 @@ IDTVEC(invlpg) xorl %eax,%eax /* invpcid (%rdx),%rax */ .byte 0x66,0x0f,0x38,0x82,0x02 - jmp invltlb_ret + jmp invltlb_ret_rdx /* * PCID is not supported or kernel pmap. @@ -309,7 +320,27 @@ IDTVEC(invlpg) 3: movq 8(%rdx),%rax invlpg (%rax) - jmp invltlb_ret + jmp invltlb_ret_rdx + + SUPERALIGN_TEXT +IDTVEC(invlpg) +#if defined(COUNT_XINVLTLB_HITS) || defined(COUNT_IPIS) + PUSH_FRAME + movl PCPU(CPUID), %eax +#ifdef COUNT_XINVLTLB_HITS + incl xhits_pg(,%rax,4) +#endif +#ifdef COUNT_IPIS + movq ipi_invlpg_counts(,%rax,8),%rax + incq (%rax) +#endif + POP_FRAME +#endif + + pushq %rax + movq smp_tlb_invpcid+8,%rax + invlpg (%rax) /* invalidate single page */ + jmp invltlb_ret_rax /* * Page range TLB shootdown. @@ -334,15 +365,15 @@ IDTVEC(invlrng) pushq %rdx movq $smp_tlb_invpcid,%rdx cmpl $0,pmap_pcid_enabled - jne invlrng_single_page - cmpl $0,invpcid_works - jne invlrng_invpcid + je invlrng_single_page /* kernel pmap - use invlpg to invalidate global mapping */ cmpl $0,(%rdx) je invlrng_single_page cmpl $-1,(%rdx) je global_invltlb + cmpl $0,invpcid_works + jne invlrng_invpcid pushq %rcx movq %cr3,%rcx @@ -362,37 +393,27 @@ IDTVEC(invlrng) btsq $63,%rcx movq %rcx,%cr3 popq %rcx - jmp invltlb_ret + jmp invltlb_ret_rdx invlrng_invpcid: - testb $SEL_RPL_MASK,NAKE_INTR_CS(%rsp) - jz 1f - swapgs -1: pushq %rcx + subq $16,%rsp movq (%rdx),%rcx - movq %rcx,PCPU(INVPCID_DESCR) + movq %rcx,(%rsp) movq 8(%rdx),%rax - movq %rax,PCPU(INVPCID_DESCR)+8 + movq %rax,8(%rsp) movq smp_tlb_addr2,%rcx - xorl %eax,%eax - movq $PC_INVPCID_DESCR,%rdx - gs - subq 8(%rdx),%rcx + subq %rax,%rcx shrq $PAGE_SHIFT,%rcx -2: - gs +1: // invpcid (%rdx),%rax .byte 0x66,0x0f,0x38,0x82,0x02 - gs - addq $PAGE_SIZE,8(%rdx) + addq $PAGE_SIZE,8(%rsp) dec %rcx - jne 2b + jne 1b + addq $16,%rsp popq %rcx - testb $SEL_RPL_MASK,NAKE_INTR_CS(%rsp) - jz invltlb_ret - swapgs - jmp invltlb_ret + jmp invltlb_ret_rdx invlrng_single_page: movq 8(%rdx),%rdx @@ -401,7 +422,7 @@ invlrng_single_page: addq $PAGE_SIZE,%rdx cmpq %rax,%rdx jb 1b - jmp invltlb_ret + jmp invltlb_ret_rdx /* * Invalidate cache. @@ -418,9 +439,8 @@ IDTVEC(invlcache) #endif pushq %rax - pushq %rdx wbinvd - jmp invltlb_ret + jmp invltlb_ret_rax /* * Handler for IPIs sent via the per-cpu IPI bitmap. diff --git a/sys/amd64/amd64/genassym.c b/sys/amd64/amd64/genassym.c index 62017e7097e9..028a2cd84863 100644 --- a/sys/amd64/amd64/genassym.c +++ b/sys/amd64/amd64/genassym.c @@ -228,7 +228,6 @@ ASSYM(PC_LDT, offsetof(struct pcpu, pc_ldt)); ASSYM(PC_COMMONTSSP, offsetof(struct pcpu, pc_commontssp)); ASSYM(PC_TSS, offsetof(struct pcpu, pc_tss)); ASSYM(PC_PM_SAVE_CNT, offsetof(struct pcpu, pc_pm_save_cnt)); -ASSYM(PC_INVPCID_DESCR, offsetof(struct pcpu, pc_invpcid_descr)); ASSYM(LA_VER, offsetof(struct LAPIC, version)); ASSYM(LA_TPR, offsetof(struct LAPIC, tpr)); diff --git a/sys/amd64/amd64/mp_machdep.c b/sys/amd64/amd64/mp_machdep.c index 530aa61c7017..0fdb6685e620 100644 --- a/sys/amd64/amd64/mp_machdep.c +++ b/sys/amd64/amd64/mp_machdep.c @@ -69,6 +69,7 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #ifdef XENHVM #include @@ -125,8 +126,15 @@ u_long *ipi_rendezvous_counts[MAXCPU]; static u_long *ipi_hardclock_counts[MAXCPU]; #endif +/* Default cpu_ops implementation. */ +struct cpu_ops cpu_ops = { + .ipi_vectored = lapic_ipi_vectored +}; + extern inthand_t IDTVEC(fast_syscall), IDTVEC(fast_syscall32); +extern int pmap_pcid_enabled; + /* * Local data and functions. */ @@ -524,8 +532,15 @@ cpu_mp_start(void) } /* Install an inter-CPU IPI for TLB invalidation */ - setidt(IPI_INVLTLB, IDTVEC(invltlb), SDT_SYSIGT, SEL_KPL, 0); - setidt(IPI_INVLPG, IDTVEC(invlpg), SDT_SYSIGT, SEL_KPL, 0); + if (pmap_pcid_enabled) { + setidt(IPI_INVLTLB, IDTVEC(invltlb_pcid), SDT_SYSIGT, + SEL_KPL, 0); + setidt(IPI_INVLPG, IDTVEC(invlpg_pcid), SDT_SYSIGT, + SEL_KPL, 0); + } else { + setidt(IPI_INVLTLB, IDTVEC(invltlb), SDT_SYSIGT, SEL_KPL, 0); + setidt(IPI_INVLPG, IDTVEC(invlpg), SDT_SYSIGT, SEL_KPL, 0); + } setidt(IPI_INVLRNG, IDTVEC(invlrng), SDT_SYSIGT, SEL_KPL, 0); /* Install an inter-CPU IPI for cache invalidation. */ @@ -605,8 +620,6 @@ cpu_mp_announce(void) } } -extern int pmap_pcid_enabled; - /* * AP CPU's call this to initialize themselves. */ @@ -1118,7 +1131,7 @@ ipi_send_cpu(int cpu, u_int ipi) if (old_pending) return; } - lapic_ipi_vectored(ipi, cpu_apic_ids[cpu]); + cpu_ops.ipi_vectored(ipi, cpu_apic_ids[cpu]); } /* @@ -1141,8 +1154,7 @@ smp_tlb_shootdown(u_int vector, pmap_t pmap, vm_offset_t addr1, smp_tlb_invpcid.pcid = 0; } else { smp_tlb_invpcid.pcid = pmap->pm_pcid; - pcid_cr3 = DMAP_TO_PHYS((vm_offset_t)pmap->pm_pml4) | - (pmap->pm_pcid == -1 ? 0 : pmap->pm_pcid); + pcid_cr3 = pmap->pm_cr3; } smp_tlb_addr2 = addr2; smp_tlb_pmap = pmap; @@ -1176,8 +1188,7 @@ smp_targeted_tlb_shootdown(cpuset_t mask, u_int vector, pmap_t pmap, smp_tlb_invpcid.pcid = 0; } else { smp_tlb_invpcid.pcid = pmap->pm_pcid; - pcid_cr3 = DMAP_TO_PHYS((vm_offset_t)pmap->pm_pml4) | - (pmap->pm_pcid == -1 ? 0 : pmap->pm_pcid); + pcid_cr3 = pmap->pm_cr3; } smp_tlb_addr2 = addr2; smp_tlb_pmap = pmap; @@ -1390,7 +1401,7 @@ ipi_all_but_self(u_int ipi) CPU_OR_ATOMIC(&ipi_nmi_pending, &other_cpus); CTR2(KTR_SMP, "%s: ipi: %x", __func__, ipi); - lapic_ipi_vectored(ipi, APIC_IPI_DEST_OTHERS); + cpu_ops.ipi_vectored(ipi, APIC_IPI_DEST_OTHERS); } int diff --git a/sys/amd64/amd64/pmap.c b/sys/amd64/amd64/pmap.c index d90596135f36..69ae1082b1b4 100644 --- a/sys/amd64/amd64/pmap.c +++ b/sys/amd64/amd64/pmap.c @@ -254,30 +254,6 @@ SYSCTL_INT(_vm_pmap, OID_AUTO, pcid_enabled, CTLFLAG_RDTUN, &pmap_pcid_enabled, 0, "Is TLB Context ID enabled ?"); int invpcid_works = 0; -/* - * Perform the guaranteed invalidation of all TLB entries. This - * includes the global entries, and entries in all PCIDs, not only the - * current context. The function works both on non-PCID CPUs and CPUs - * with the PCID turned off or on. See IA-32 SDM Vol. 3a 4.10.4.1 - * Operations that Invalidate TLBs and Paging-Structure Caches. - */ -static __inline void -invltlb_globpcid(void) -{ - uint64_t cr4; - - cr4 = rcr4(); - load_cr4(cr4 & ~CR4_PGE); - /* - * Although preemption at this point could be detrimental to - * performance, it would not lead to an error. PG_G is simply - * ignored if CR4.PGE is clear. Moreover, in case this block - * is re-entered, the load_cr4() either above or below will - * modify CR4.PGE flushing the TLB. - */ - load_cr4(cr4 | CR4_PGE); -} - static int pmap_pcid_save_cnt_proc(SYSCTL_HANDLER_ARGS) { @@ -315,7 +291,6 @@ static void pmap_pv_promote_pde(pmap_t pmap, vm_offset_t va, vm_paddr_t pa, static void pmap_pvh_free(struct md_page *pvh, pmap_t pmap, vm_offset_t va); static pv_entry_t pmap_pvh_remove(struct md_page *pvh, pmap_t pmap, vm_offset_t va); -static int pmap_pvh_wired_mappings(struct md_page *pvh, int count); static int pmap_change_attr_locked(vm_offset_t va, vm_size_t size, int mode); static boolean_t pmap_demote_pde(pmap_t pmap, pd_entry_t *pde, vm_offset_t va); @@ -329,8 +304,6 @@ static vm_page_t pmap_enter_quick_locked(pmap_t pmap, vm_offset_t va, vm_page_t m, vm_prot_t prot, vm_page_t mpte, struct rwlock **lockp); static void pmap_fill_ptp(pt_entry_t *firstpte, pt_entry_t newpte); static int pmap_insert_pt_page(pmap_t pmap, vm_page_t mpte); -static boolean_t pmap_is_modified_pvh(struct md_page *pvh); -static boolean_t pmap_is_referenced_pvh(struct md_page *pvh); static void pmap_kenter_attr(vm_offset_t va, vm_paddr_t pa, int mode); static vm_page_t pmap_lookup_pt_page(pmap_t pmap, vm_offset_t va); static void pmap_pde_attr(pd_entry_t *pde, int cache_bits); @@ -728,6 +701,7 @@ pmap_bootstrap(vm_paddr_t *firstaddr) */ PMAP_LOCK_INIT(kernel_pmap); kernel_pmap->pm_pml4 = (pdp_entry_t *)PHYS_TO_DMAP(KPML4phys); + kernel_pmap->pm_cr3 = KPML4phys; CPU_FILL(&kernel_pmap->pm_active); /* don't allow deactivation */ CPU_ZERO(&kernel_pmap->pm_save); TAILQ_INIT(&kernel_pmap->pm_pvchunk); @@ -1049,8 +1023,7 @@ pmap_invalidate_page_pcid(pmap_t pmap, vm_offset_t va) cr3 = rcr3(); critical_enter(); - load_cr3(DMAP_TO_PHYS((vm_offset_t)pmap->pm_pml4) | pmap->pm_pcid | - CR3_PCID_SAVE); + load_cr3(pmap->pm_cr3 | CR3_PCID_SAVE); invlpg(va); load_cr3(cr3 | CR3_PCID_SAVE); critical_exit(); @@ -1137,8 +1110,7 @@ pmap_invalidate_range_pcid(pmap_t pmap, vm_offset_t sva, vm_offset_t eva) cr3 = rcr3(); critical_enter(); - load_cr3(DMAP_TO_PHYS((vm_offset_t)pmap->pm_pml4) | pmap->pm_pcid | - CR3_PCID_SAVE); + load_cr3(pmap->pm_cr3 | CR3_PCID_SAVE); for (addr = sva; addr < eva; addr += PAGE_SIZE) invlpg(addr); load_cr3(cr3 | CR3_PCID_SAVE); @@ -1239,8 +1211,7 @@ pmap_invalidate_all(pmap_t pmap) * Bit 63 is clear, pcid TLB * entries are invalidated. */ - load_cr3(DMAP_TO_PHYS((vm_offset_t) - pmap->pm_pml4) | pmap->pm_pcid); + load_cr3(pmap->pm_cr3); load_cr3(cr3 | CR3_PCID_SAVE); critical_exit(); } @@ -1862,6 +1833,7 @@ pmap_pinit0(pmap_t pmap) PMAP_LOCK_INIT(pmap); pmap->pm_pml4 = (pml4_entry_t *)PHYS_TO_DMAP(KPML4phys); + pmap->pm_cr3 = KPML4phys; pmap->pm_root.rt_root = 0; CPU_ZERO(&pmap->pm_active); CPU_ZERO(&pmap->pm_save); @@ -1869,7 +1841,6 @@ pmap_pinit0(pmap_t pmap) TAILQ_INIT(&pmap->pm_pvchunk); bzero(&pmap->pm_stats, sizeof pmap->pm_stats); pmap->pm_pcid = pmap_pcid_enabled ? 0 : -1; - CPU_ZERO(&pmap->pm_save); } /* @@ -1889,7 +1860,8 @@ pmap_pinit(pmap_t pmap) VM_ALLOC_NOOBJ | VM_ALLOC_WIRED | VM_ALLOC_ZERO)) == NULL) VM_WAIT; - pmap->pm_pml4 = (pml4_entry_t *)PHYS_TO_DMAP(VM_PAGE_TO_PHYS(pml4pg)); + pmap->pm_cr3 = VM_PAGE_TO_PHYS(pml4pg); + pmap->pm_pml4 = (pml4_entry_t *)PHYS_TO_DMAP(pmap->pm_cr3); if ((pml4pg->flags & PG_ZERO) == 0) pagezero(pmap->pm_pml4); @@ -1911,7 +1883,13 @@ pmap_pinit(pmap_t pmap) CPU_ZERO(&pmap->pm_active); TAILQ_INIT(&pmap->pm_pvchunk); bzero(&pmap->pm_stats, sizeof pmap->pm_stats); - pmap->pm_pcid = pmap_pcid_enabled ? alloc_unr(&pcid_unr) : -1; + if (pmap_pcid_enabled) { + pmap->pm_pcid = alloc_unr(&pcid_unr); + if (pmap->pm_pcid != -1) + pmap->pm_cr3 |= pmap->pm_pcid; + } else { + pmap->pm_pcid = -1; + } CPU_ZERO(&pmap->pm_save); return (1); @@ -2922,8 +2900,8 @@ pmap_demote_pde_locked(pmap_t pmap, pd_entry_t *pde, vm_offset_t va, oldpde = *pde; KASSERT((oldpde & (PG_PS | PG_V)) == (PG_PS | PG_V), ("pmap_demote_pde: oldpde is missing PG_PS and/or PG_V")); - mpte = pmap_lookup_pt_page(pmap, va); - if (mpte != NULL) + if ((oldpde & PG_A) != 0 && (mpte = pmap_lookup_pt_page(pmap, va)) != + NULL) pmap_remove_pt_page(pmap, mpte); else { KASSERT((oldpde & PG_W) == 0, @@ -4599,42 +4577,61 @@ pmap_page_exists_quick(pmap_t pmap, vm_page_t m) int pmap_page_wired_mappings(vm_page_t m) { - int count; - - count = 0; - if ((m->oflags & VPO_UNMANAGED) != 0) - return (count); - rw_wlock(&pvh_global_lock); - count = pmap_pvh_wired_mappings(&m->md, count); - if ((m->flags & PG_FICTITIOUS) == 0) { - count = pmap_pvh_wired_mappings(pa_to_pvh(VM_PAGE_TO_PHYS(m)), - count); - } - rw_wunlock(&pvh_global_lock); - return (count); -} - -/* - * pmap_pvh_wired_mappings: - * - * Return the updated number "count" of managed mappings that are wired. - */ -static int -pmap_pvh_wired_mappings(struct md_page *pvh, int count) -{ + struct rwlock *lock; + struct md_page *pvh; pmap_t pmap; pt_entry_t *pte; pv_entry_t pv; + int count, md_gen, pvh_gen; - rw_assert(&pvh_global_lock, RA_WLOCKED); - TAILQ_FOREACH(pv, &pvh->pv_list, pv_next) { + if ((m->oflags & VPO_UNMANAGED) != 0) + return (0); + rw_rlock(&pvh_global_lock); + lock = VM_PAGE_TO_PV_LIST_LOCK(m); + rw_rlock(lock); +restart: + count = 0; + TAILQ_FOREACH(pv, &m->md.pv_list, pv_next) { pmap = PV_PMAP(pv); - PMAP_LOCK(pmap); + if (!PMAP_TRYLOCK(pmap)) { + md_gen = m->md.pv_gen; + rw_runlock(lock); + PMAP_LOCK(pmap); + rw_rlock(lock); + if (md_gen != m->md.pv_gen) { + PMAP_UNLOCK(pmap); + goto restart; + } + } pte = pmap_pte(pmap, pv->pv_va); if ((*pte & PG_W) != 0) count++; PMAP_UNLOCK(pmap); } + if ((m->flags & PG_FICTITIOUS) == 0) { + pvh = pa_to_pvh(VM_PAGE_TO_PHYS(m)); + TAILQ_FOREACH(pv, &pvh->pv_list, pv_next) { + pmap = PV_PMAP(pv); + if (!PMAP_TRYLOCK(pmap)) { + md_gen = m->md.pv_gen; + pvh_gen = pvh->pv_gen; + rw_runlock(lock); + PMAP_LOCK(pmap); + rw_rlock(lock); + if (md_gen != m->md.pv_gen || + pvh_gen != pvh->pv_gen) { + PMAP_UNLOCK(pmap); + goto restart; + } + } + pte = pmap_pde(pmap, pv->pv_va); + if ((*pte & PG_W) != 0) + count++; + PMAP_UNLOCK(pmap); + } + } + rw_runlock(lock); + rw_runlock(&pvh_global_lock); return (count); } @@ -4830,6 +4827,69 @@ pmap_remove_pages(pmap_t pmap) pmap_free_zero_pages(&free); } +static boolean_t +pmap_page_test_mappings(vm_page_t m, pt_entry_t mask) +{ + struct rwlock *lock; + pv_entry_t pv; + struct md_page *pvh; + pt_entry_t *pte; + pmap_t pmap; + int md_gen, pvh_gen; + boolean_t rv; + + rv = FALSE; + rw_rlock(&pvh_global_lock); + lock = VM_PAGE_TO_PV_LIST_LOCK(m); + rw_rlock(lock); +restart: + TAILQ_FOREACH(pv, &m->md.pv_list, pv_next) { + pmap = PV_PMAP(pv); + if (!PMAP_TRYLOCK(pmap)) { + md_gen = m->md.pv_gen; + rw_runlock(lock); + PMAP_LOCK(pmap); + rw_rlock(lock); + if (md_gen != m->md.pv_gen) { + PMAP_UNLOCK(pmap); + goto restart; + } + } + pte = pmap_pte(pmap, pv->pv_va); + rv = (*pte & mask) == mask; + PMAP_UNLOCK(pmap); + if (rv) + goto out; + } + if ((m->flags & PG_FICTITIOUS) == 0) { + pvh = pa_to_pvh(VM_PAGE_TO_PHYS(m)); + TAILQ_FOREACH(pv, &pvh->pv_list, pv_next) { + pmap = PV_PMAP(pv); + if (!PMAP_TRYLOCK(pmap)) { + md_gen = m->md.pv_gen; + pvh_gen = pvh->pv_gen; + rw_runlock(lock); + PMAP_LOCK(pmap); + rw_rlock(lock); + if (md_gen != m->md.pv_gen || + pvh_gen != pvh->pv_gen) { + PMAP_UNLOCK(pmap); + goto restart; + } + } + pte = pmap_pde(pmap, pv->pv_va); + rv = (*pte & mask) == mask; + PMAP_UNLOCK(pmap); + if (rv) + goto out; + } + } +out: + rw_runlock(lock); + rw_runlock(&pvh_global_lock); + return (rv); +} + /* * pmap_is_modified: * @@ -4839,7 +4899,6 @@ pmap_remove_pages(pmap_t pmap) boolean_t pmap_is_modified(vm_page_t m) { - boolean_t rv; KASSERT((m->oflags & VPO_UNMANAGED) == 0, ("pmap_is_modified: page %p is not managed", m)); @@ -4852,39 +4911,7 @@ pmap_is_modified(vm_page_t m) VM_OBJECT_ASSERT_WLOCKED(m->object); if (!vm_page_xbusied(m) && (m->aflags & PGA_WRITEABLE) == 0) return (FALSE); - rw_wlock(&pvh_global_lock); - rv = pmap_is_modified_pvh(&m->md) || - ((m->flags & PG_FICTITIOUS) == 0 && - pmap_is_modified_pvh(pa_to_pvh(VM_PAGE_TO_PHYS(m)))); - rw_wunlock(&pvh_global_lock); - return (rv); -} - -/* - * Returns TRUE if any of the given mappings were used to modify - * physical memory. Otherwise, returns FALSE. Both page and 2mpage - * mappings are supported. - */ -static boolean_t -pmap_is_modified_pvh(struct md_page *pvh) -{ - pv_entry_t pv; - pt_entry_t *pte; - pmap_t pmap; - boolean_t rv; - - rw_assert(&pvh_global_lock, RA_WLOCKED); - rv = FALSE; - TAILQ_FOREACH(pv, &pvh->pv_list, pv_next) { - pmap = PV_PMAP(pv); - PMAP_LOCK(pmap); - pte = pmap_pte(pmap, pv->pv_va); - rv = (*pte & (PG_M | PG_RW)) == (PG_M | PG_RW); - PMAP_UNLOCK(pmap); - if (rv) - break; - } - return (rv); + return (pmap_page_test_mappings(m, PG_M | PG_RW)); } /* @@ -4920,42 +4947,10 @@ pmap_is_prefaultable(pmap_t pmap, vm_offset_t addr) boolean_t pmap_is_referenced(vm_page_t m) { - boolean_t rv; KASSERT((m->oflags & VPO_UNMANAGED) == 0, ("pmap_is_referenced: page %p is not managed", m)); - rw_wlock(&pvh_global_lock); - rv = pmap_is_referenced_pvh(&m->md) || - ((m->flags & PG_FICTITIOUS) == 0 && - pmap_is_referenced_pvh(pa_to_pvh(VM_PAGE_TO_PHYS(m)))); - rw_wunlock(&pvh_global_lock); - return (rv); -} - -/* - * Returns TRUE if any of the given mappings were referenced and FALSE - * otherwise. Both page and 2mpage mappings are supported. - */ -static boolean_t -pmap_is_referenced_pvh(struct md_page *pvh) -{ - pv_entry_t pv; - pt_entry_t *pte; - pmap_t pmap; - boolean_t rv; - - rw_assert(&pvh_global_lock, RA_WLOCKED); - rv = FALSE; - TAILQ_FOREACH(pv, &pvh->pv_list, pv_next) { - pmap = PV_PMAP(pv); - PMAP_LOCK(pmap); - pte = pmap_pte(pmap, pv->pv_va); - rv = (*pte & (PG_A | PG_V)) == (PG_A | PG_V); - PMAP_UNLOCK(pmap); - if (rv) - break; - } - return (rv); + return (pmap_page_test_mappings(m, PG_A | PG_V)); } /* @@ -5051,6 +5046,8 @@ pmap_remove_write(vm_page_t m) rw_runlock(&pvh_global_lock); } +#define PMAP_TS_REFERENCED_MAX 5 + /* * pmap_ts_referenced: * @@ -5067,25 +5064,29 @@ int pmap_ts_referenced(vm_page_t m) { struct md_page *pvh; - pv_entry_t pv, pvf, pvn; + pv_entry_t pv, pvf; pmap_t pmap; struct rwlock *lock; - pd_entry_t oldpde, *pde; + pd_entry_t *pde; pt_entry_t *pte; - vm_offset_t va; - int rtval, pvh_gen, md_gen; + vm_paddr_t pa; + int cleared, md_gen, not_cleared, pvh_gen; KASSERT((m->oflags & VPO_UNMANAGED) == 0, ("pmap_ts_referenced: page %p is not managed", m)); + cleared = 0; + pa = VM_PAGE_TO_PHYS(m); + lock = PHYS_TO_PV_LIST_LOCK(pa); + pvh = pa_to_pvh(pa); rw_rlock(&pvh_global_lock); - lock = VM_PAGE_TO_PV_LIST_LOCK(m); - pvh = pa_to_pvh(VM_PAGE_TO_PHYS(m)); - rtval = 0; -retry: rw_wlock(lock); - if ((m->flags & PG_FICTITIOUS) != 0) +retry: + not_cleared = 0; + if ((m->flags & PG_FICTITIOUS) != 0 || + (pvf = TAILQ_FIRST(&pvh->pv_list)) == NULL) goto small_mappings; - TAILQ_FOREACH_SAFE(pv, &pvh->pv_list, pv_next, pvn) { + pv = pvf; + do { pmap = PV_PMAP(pv); if (!PMAP_TRYLOCK(pmap)) { pvh_gen = pvh->pv_gen; @@ -5094,83 +5095,88 @@ pmap_ts_referenced(vm_page_t m) rw_wlock(lock); if (pvh_gen != pvh->pv_gen) { PMAP_UNLOCK(pmap); - rw_wunlock(lock); goto retry; } } - va = pv->pv_va; - pde = pmap_pde(pmap, va); - oldpde = *pde; - if ((oldpde & PG_A) != 0) { - if (pmap_demote_pde_locked(pmap, pde, va, &lock)) { - if ((oldpde & PG_W) == 0) { - /* - * Remove the mapping to a single page - * so that a subsequent access may - * repromote. Since the underlying - * page table page is fully populated, - * this removal never frees a page - * table page. - */ - va += VM_PAGE_TO_PHYS(m) - (oldpde & - PG_PS_FRAME); - pte = pmap_pde_to_pte(pde, va); - pmap_remove_pte(pmap, pte, va, *pde, - NULL, &lock); - pmap_invalidate_page(pmap, va); - rtval++; - if (rtval > 4) { - PMAP_UNLOCK(pmap); - goto out; - } - } - } - KASSERT(lock == VM_PAGE_TO_PV_LIST_LOCK(m), - ("inconsistent pv lock %p %p for page %p", - lock, VM_PAGE_TO_PV_LIST_LOCK(m), m)); + pde = pmap_pde(pmap, pv->pv_va); + if ((*pde & PG_A) != 0) { + /* + * Since this reference bit is shared by 512 4KB + * pages, it should not be cleared every time it is + * tested. Apply a simple "hash" function on the + * physical page number, the virtual superpage number, + * and the pmap address to select one 4KB page out of + * the 512 on which testing the reference bit will + * result in clearing that reference bit. This + * function is designed to avoid the selection of the + * same 4KB page for every 2MB page mapping. + * + * On demotion, a mapping that hasn't been referenced + * is simply destroyed. To avoid the possibility of a + * subsequent page fault on a demoted wired mapping, + * always leave its reference bit set. Moreover, + * since the superpage is wired, the current state of + * its reference bit won't affect page replacement. + */ + if ((((pa >> PAGE_SHIFT) ^ (pv->pv_va >> PDRSHIFT) ^ + (uintptr_t)pmap) & (NPTEPG - 1)) == 0 && + (*pde & PG_W) == 0) { + atomic_clear_long(pde, PG_A); + pmap_invalidate_page(pmap, pv->pv_va); + cleared++; + } else + not_cleared++; } PMAP_UNLOCK(pmap); - } + /* Rotate the PV list if it has more than one entry. */ + if (TAILQ_NEXT(pv, pv_next) != NULL) { + TAILQ_REMOVE(&pvh->pv_list, pv, pv_next); + TAILQ_INSERT_TAIL(&pvh->pv_list, pv, pv_next); + pvh->pv_gen++; + } + if (cleared + not_cleared >= PMAP_TS_REFERENCED_MAX) + goto out; + } while ((pv = TAILQ_FIRST(&pvh->pv_list)) != pvf); small_mappings: - if ((pv = TAILQ_FIRST(&m->md.pv_list)) != NULL) { - pvf = pv; - do { - pvn = TAILQ_NEXT(pv, pv_next); + if ((pvf = TAILQ_FIRST(&m->md.pv_list)) == NULL) + goto out; + pv = pvf; + do { + pmap = PV_PMAP(pv); + if (!PMAP_TRYLOCK(pmap)) { + pvh_gen = pvh->pv_gen; + md_gen = m->md.pv_gen; + rw_wunlock(lock); + PMAP_LOCK(pmap); + rw_wlock(lock); + if (pvh_gen != pvh->pv_gen || md_gen != m->md.pv_gen) { + PMAP_UNLOCK(pmap); + goto retry; + } + } + pde = pmap_pde(pmap, pv->pv_va); + KASSERT((*pde & PG_PS) == 0, + ("pmap_ts_referenced: found a 2mpage in page %p's pv list", + m)); + pte = pmap_pde_to_pte(pde, pv->pv_va); + if ((*pte & PG_A) != 0) { + atomic_clear_long(pte, PG_A); + pmap_invalidate_page(pmap, pv->pv_va); + cleared++; + } + PMAP_UNLOCK(pmap); + /* Rotate the PV list if it has more than one entry. */ + if (TAILQ_NEXT(pv, pv_next) != NULL) { TAILQ_REMOVE(&m->md.pv_list, pv, pv_next); TAILQ_INSERT_TAIL(&m->md.pv_list, pv, pv_next); m->md.pv_gen++; - pmap = PV_PMAP(pv); - if (!PMAP_TRYLOCK(pmap)) { - pvh_gen = pvh->pv_gen; - md_gen = m->md.pv_gen; - rw_wunlock(lock); - PMAP_LOCK(pmap); - rw_wlock(lock); - if (pvh_gen != pvh->pv_gen || - md_gen != m->md.pv_gen) { - PMAP_UNLOCK(pmap); - rw_wunlock(lock); - goto retry; - } - } - pde = pmap_pde(pmap, pv->pv_va); - KASSERT((*pde & PG_PS) == 0, ("pmap_ts_referenced:" - " found a 2mpage in page %p's pv list", m)); - pte = pmap_pde_to_pte(pde, pv->pv_va); - if ((*pte & PG_A) != 0) { - atomic_clear_long(pte, PG_A); - pmap_invalidate_page(pmap, pv->pv_va); - rtval++; - if (rtval > 4) - pvn = NULL; - } - PMAP_UNLOCK(pmap); - } while ((pv = pvn) != NULL && pv != pvf); - } + } + } while ((pv = TAILQ_FIRST(&m->md.pv_list)) != pvf && cleared + + not_cleared < PMAP_TS_REFERENCED_MAX); out: rw_wunlock(lock); rw_runlock(&pvh_global_lock); - return (rtval); + return (cleared + not_cleared); } /* @@ -5936,7 +5942,6 @@ pmap_activate(struct thread *td) { pmap_t pmap, oldpmap; u_int cpuid; - u_int64_t cr3; critical_enter(); pmap = vmspace_pmap(td->td_proc->p_vmspace); @@ -5951,11 +5956,8 @@ pmap_activate(struct thread *td) CPU_SET(cpuid, &pmap->pm_active); CPU_SET(cpuid, &pmap->pm_save); #endif - cr3 = DMAP_TO_PHYS((vm_offset_t)pmap->pm_pml4); - if (pmap->pm_pcid != -1) - cr3 |= pmap->pm_pcid; - td->td_pcb->pcb_cr3 = cr3; - load_cr3(cr3); + td->td_pcb->pcb_cr3 = pmap->pm_cr3; + load_cr3(pmap->pm_cr3); PCPU_SET(curpmap, pmap); critical_exit(); } diff --git a/sys/amd64/amd64/vm_machdep.c b/sys/amd64/amd64/vm_machdep.c index 3764f720c65b..7253fe23bb7a 100644 --- a/sys/amd64/amd64/vm_machdep.c +++ b/sys/amd64/amd64/vm_machdep.c @@ -59,7 +59,6 @@ __FBSDID("$FreeBSD$"); #include #include #include -#include #include #include #include @@ -220,9 +219,7 @@ cpu_fork(td1, p2, td2, flags) * return address on stack. These are the kernel mode register values. */ pmap2 = vmspace_pmap(p2->p_vmspace); - pcb2->pcb_cr3 = DMAP_TO_PHYS((vm_offset_t)pmap2->pm_pml4); - if (pmap2->pm_pcid != -1) - pcb2->pcb_cr3 |= pmap2->pm_pcid; + pcb2->pcb_cr3 = pmap2->pm_cr3; pcb2->pcb_r12 = (register_t)fork_return; /* fork_trampoline argument */ pcb2->pcb_rbp = 0; pcb2->pcb_rsp = (register_t)td2->td_frame - sizeof(void *); @@ -696,27 +693,6 @@ cpu_reset_real() while(1); } -/* - * Allocate an sf_buf for the given vm_page. On this machine, however, there - * is no sf_buf object. Instead, an opaque pointer to the given vm_page is - * returned. - */ -struct sf_buf * -sf_buf_alloc(struct vm_page *m, int pri) -{ - - return ((struct sf_buf *)m); -} - -/* - * Free the sf_buf. In fact, do nothing because there are no resources - * associated with the sf_buf. - */ -void -sf_buf_free(struct sf_buf *sf) -{ -} - /* * Software interrupt handler for queued VM system processing. */ diff --git a/sys/amd64/conf/NOTES b/sys/amd64/conf/NOTES index 95d4ce052cd2..57a93311f4f4 100644 --- a/sys/amd64/conf/NOTES +++ b/sys/amd64/conf/NOTES @@ -309,6 +309,7 @@ options DRM_DEBUG # Include debug printfs (slow) # nfe: nVidia nForce MCP on-board Ethernet Networking (BSD open source) # nve: nVidia nForce MCP on-board Ethernet Networking # sfxge: Solarflare SFC9000 family 10Gb Ethernet adapters +# vmx: VMware VMXNET3 Ethernet (BSD open source) # wpi: Intel 3945ABG Wireless LAN controller # Requires the wpi firmware module @@ -325,6 +326,7 @@ device mthca # Mellanox HCA InfiniBand device nfe # nVidia nForce MCP on-board Ethernet device nve # nVidia nForce MCP on-board Ethernet Networking device sfxge # Solarflare SFC9000 10Gb Ethernet +device vmx # VMware VMXNET3 Ethernet device wpi # Intel 3945ABG wireless NICs. # IEEE 802.11 adapter firmware modules diff --git a/sys/amd64/include/cpu.h b/sys/amd64/include/cpu.h index 1c2871f6dc10..5b994e154116 100644 --- a/sys/amd64/include/cpu.h +++ b/sys/amd64/include/cpu.h @@ -54,6 +54,17 @@ #define TRAPF_PC(framep) ((framep)->tf_rip) #ifdef _KERNEL +/* + * Struct containing pointers to CPU management functions whose + * implementation is run time selectable. Selection can be made, + * for example, based on detection of a particular CPU variant or + * hypervisor environment. + */ +struct cpu_ops { + void (*ipi_vectored)(u_int, int); +}; + +extern struct cpu_ops cpu_ops; extern char btext[]; extern char etext[]; diff --git a/sys/amd64/include/cpufunc.h b/sys/amd64/include/cpufunc.h index 3d381c654ff7..5f8197bf8e95 100644 --- a/sys/amd64/include/cpufunc.h +++ b/sys/amd64/include/cpufunc.h @@ -461,6 +461,34 @@ invltlb(void) load_cr3(rcr3()); } +#ifndef CR4_PGE +#define CR4_PGE 0x00000080 /* Page global enable */ +#endif + +/* + * Perform the guaranteed invalidation of all TLB entries. This + * includes the global entries, and entries in all PCIDs, not only the + * current context. The function works both on non-PCID CPUs and CPUs + * with the PCID turned off or on. See IA-32 SDM Vol. 3a 4.10.4.1 + * Operations that Invalidate TLBs and Paging-Structure Caches. + */ +static __inline void +invltlb_globpcid(void) +{ + uint64_t cr4; + + cr4 = rcr4(); + load_cr4(cr4 & ~CR4_PGE); + /* + * Although preemption at this point could be detrimental to + * performance, it would not lead to an error. PG_G is simply + * ignored if CR4.PGE is clear. Moreover, in case this block + * is re-entered, the load_cr4() either above or below will + * modify CR4.PGE flushing the TLB. + */ + load_cr4(cr4 | CR4_PGE); +} + /* * TLB flush for an individual page (even if it has PG_G). * Only works on 486+ CPUs (i386 does not have PG_G). diff --git a/sys/amd64/include/pcpu.h b/sys/amd64/include/pcpu.h index 0e11975c3806..3d51512316a8 100644 --- a/sys/amd64/include/pcpu.h +++ b/sys/amd64/include/pcpu.h @@ -33,15 +33,6 @@ #error "sys/cdefs.h is a prerequisite for this file" #endif -#if defined(XEN) || defined(XENHVM) -#ifndef NR_VIRQS -#define NR_VIRQS 24 -#endif -#ifndef NR_IPIS -#define NR_IPIS 2 -#endif -#endif - /* * The SMP parts are setup in pmap.c and locore.s for the BSP, and * mp_machdep.c sets up the data for the AP's to "see" when they awake. @@ -68,7 +59,6 @@ /* Pointer to the CPU TSS descriptor */ \ struct system_segment_descriptor *pc_tss; \ uint64_t pc_pm_save_cnt; \ - char pc_invpcid_descr[16]; \ u_int pc_cmci_mask; /* MCx banks for CMCI */ \ uint64_t pc_dbreg[16]; /* ddb debugging regs */ \ int pc_dbreg_cmd; /* ddb debugging reg cmd */ \ diff --git a/sys/amd64/include/pmap.h b/sys/amd64/include/pmap.h index fa42389671e3..b570cb78449c 100644 --- a/sys/amd64/include/pmap.h +++ b/sys/amd64/include/pmap.h @@ -238,6 +238,7 @@ struct md_page { struct pmap { struct mtx pm_mtx; pml4_entry_t *pm_pml4; /* KVA of level 4 page table */ + uint64_t pm_cr3; TAILQ_HEAD(,pv_chunk) pm_pvchunk; /* list of mappings in pmap */ cpuset_t pm_active; /* active on cpus */ cpuset_t pm_save; /* Context valid on cpus mask */ diff --git a/sys/amd64/include/sf_buf.h b/sys/amd64/include/sf_buf.h index b5245e63d210..729e8e50a473 100644 --- a/sys/amd64/include/sf_buf.h +++ b/sys/amd64/include/sf_buf.h @@ -41,6 +41,18 @@ */ struct sf_buf; +static inline struct sf_buf * +sf_buf_alloc(struct vm_page *m, int pri) +{ + + return ((struct sf_buf *)m); +} + +static inline void +sf_buf_free(struct sf_buf *sf) +{ +} + static __inline vm_offset_t sf_buf_kva(struct sf_buf *sf) { diff --git a/sys/amd64/include/smp.h b/sys/amd64/include/smp.h index d6cd476450d2..d1b366b3e17f 100644 --- a/sys/amd64/include/smp.h +++ b/sys/amd64/include/smp.h @@ -45,7 +45,9 @@ extern u_long *ipi_rendezvous_counts[MAXCPU]; /* IPI handlers */ inthand_t + IDTVEC(invltlb_pcid), /* TLB shootdowns - global, pcid enabled */ IDTVEC(invltlb), /* TLB shootdowns - global */ + IDTVEC(invlpg_pcid), /* TLB shootdowns - 1 page, pcid enabled */ IDTVEC(invlpg), /* TLB shootdowns - 1 page */ IDTVEC(invlrng), /* TLB shootdowns - page range */ IDTVEC(invlcache), /* Write back and invalidate cache */ diff --git a/sys/amd64/include/vmm.h b/sys/amd64/include/vmm.h index 617c682611d7..b74124731adc 100644 --- a/sys/amd64/include/vmm.h +++ b/sys/amd64/include/vmm.h @@ -150,7 +150,7 @@ void vm_interrupt_hostcpu(struct vm *vm, int vcpu); #include -#define VM_MAXCPU 8 /* maximum virtual cpus */ +#define VM_MAXCPU 16 /* maximum virtual cpus */ /* * Identifiers for events that can be injected into the VM diff --git a/sys/amd64/linux32/linux32_machdep.c b/sys/amd64/linux32/linux32_machdep.c index 65f034acc0de..3dd8f7a09987 100644 --- a/sys/amd64/linux32/linux32_machdep.c +++ b/sys/amd64/linux32/linux32_machdep.c @@ -519,6 +519,7 @@ linux_mmap_common(struct thread *td, l_uintptr_t addr, l_size_t len, l_int prot, } */ bsd_args; int error; struct file *fp; + cap_rights_t rights; error = 0; bsd_args.flags = 0; @@ -567,7 +568,9 @@ linux_mmap_common(struct thread *td, l_uintptr_t addr, l_size_t len, l_int prot, * protection options specified. */ - if ((error = fget(td, bsd_args.fd, CAP_MMAP, &fp)) != 0) + error = fget(td, bsd_args.fd, + cap_rights_init(&rights, CAP_MMAP), &fp); + if (error != 0) return (error); if (fp->f_type != DTYPE_VNODE) { fdrop(fp, td); diff --git a/sys/amd64/vmm/intel/vmx.c b/sys/amd64/vmm/intel/vmx.c index 419101f9fa6d..c365111c5d0b 100644 --- a/sys/amd64/vmm/intel/vmx.c +++ b/sys/amd64/vmm/intel/vmx.c @@ -138,8 +138,6 @@ SYSCTL_ULONG(_hw_vmm_vmx, OID_AUTO, cr4_ones_mask, CTLFLAG_RD, SYSCTL_ULONG(_hw_vmm_vmx, OID_AUTO, cr4_zeros_mask, CTLFLAG_RD, &cr4_zeros_mask, 0, NULL); -static volatile u_int nextvpid; - static int vmx_no_patmsr; static int vmx_initialized; @@ -172,6 +170,11 @@ static int cap_monitor_trap; /* statistics */ static VMM_STAT_INTEL(VMEXIT_HLT_IGNORED, "number of times hlt was ignored"); +static struct unrhdr *vpid_unr; +static u_int vpid_alloc_failed; +SYSCTL_UINT(_hw_vmm_vmx, OID_AUTO, vpid_alloc_failed, CTLFLAG_RD, + &vpid_alloc_failed, 0, NULL); + #ifdef KTR static const char * exit_reason_to_str(int reason) @@ -381,6 +384,88 @@ vmx_fix_cr4(u_long cr4) return ((cr4 | cr4_ones_mask) & ~cr4_zeros_mask); } +static void +vpid_free(int vpid) +{ + if (vpid < 0 || vpid > 0xffff) + panic("vpid_free: invalid vpid %d", vpid); + + /* + * VPIDs [0,VM_MAXCPU] are special and are not allocated from + * the unit number allocator. + */ + + if (vpid > VM_MAXCPU) + free_unr(vpid_unr, vpid); +} + +static void +vpid_alloc(uint16_t *vpid, int num) +{ + int i, x; + + if (num <= 0 || num > VM_MAXCPU) + panic("invalid number of vpids requested: %d", num); + + /* + * If the "enable vpid" execution control is not enabled then the + * VPID is required to be 0 for all vcpus. + */ + if ((procbased_ctls2 & PROCBASED2_ENABLE_VPID) == 0) { + for (i = 0; i < num; i++) + vpid[i] = 0; + return; + } + + /* + * Allocate a unique VPID for each vcpu from the unit number allocator. + */ + for (i = 0; i < num; i++) { + x = alloc_unr(vpid_unr); + if (x == -1) + break; + else + vpid[i] = x; + } + + if (i < num) { + atomic_add_int(&vpid_alloc_failed, 1); + + /* + * If the unit number allocator does not have enough unique + * VPIDs then we need to allocate from the [1,VM_MAXCPU] range. + * + * These VPIDs are not be unique across VMs but this does not + * affect correctness because the combined mappings are also + * tagged with the EP4TA which is unique for each VM. + * + * It is still sub-optimal because the invvpid will invalidate + * combined mappings for a particular VPID across all EP4TAs. + */ + while (i-- > 0) + vpid_free(vpid[i]); + + for (i = 0; i < num; i++) + vpid[i] = i + 1; + } +} + +static void +vpid_init(void) +{ + /* + * VPID 0 is required when the "enable VPID" execution control is + * disabled. + * + * VPIDs [1,VM_MAXCPU] are used as the "overflow namespace" when the + * unit number allocator does not have sufficient unique VPIDs to + * satisfy the allocation. + * + * The remaining VPIDs are managed by the unit number allocator. + */ + vpid_unr = new_unrhdr(VM_MAXCPU + 1, 0xffff, NULL); +} + static void msr_save_area_init(struct msr_entry *g_area, int *g_count) { @@ -422,6 +507,11 @@ static int vmx_cleanup(void) { + if (vpid_unr != NULL) { + delete_unrhdr(vpid_unr); + vpid_unr = NULL; + } + smp_rendezvous(NULL, vmx_disable, NULL, NULL); return (0); @@ -607,6 +697,8 @@ vmx_init(void) cr4_ones_mask = fixed0 & fixed1; cr4_zeros_mask = ~fixed0 & ~fixed1; + vpid_init(); + /* enable VMX operation */ smp_rendezvous(NULL, vmx_enable, NULL, NULL); @@ -615,37 +707,6 @@ vmx_init(void) return (0); } -/* - * If this processor does not support VPIDs then simply return 0. - * - * Otherwise generate the next value of VPID to use. Any value is alright - * as long as it is non-zero. - * - * We always execute in VMX non-root context with EPT enabled. Thus all - * combined mappings are tagged with the (EP4TA, VPID, PCID) tuple. This - * in turn means that multiple VMs can share the same VPID as long as - * they have distinct EPT page tables. - * - * XXX - * We should optimize this so that it returns VPIDs that are not in - * use. Then we will not unnecessarily invalidate mappings in - * vmx_set_pcpu_defaults() just because two or more vcpus happen to - * use the same 'vpid'. - */ -static uint16_t -vmx_vpid(void) -{ - uint16_t vpid = 0; - - if ((procbased_ctls2 & PROCBASED2_ENABLE_VPID) != 0) { - do { - vpid = atomic_fetchadd_int(&nextvpid, 1); - } while (vpid == 0); - } - - return (vpid); -} - static int vmx_setup_cr_shadow(int which, struct vmcs *vmcs, uint32_t initial) { @@ -681,7 +742,7 @@ vmx_setup_cr_shadow(int which, struct vmcs *vmcs, uint32_t initial) static void * vmx_vminit(struct vm *vm) { - uint16_t vpid; + uint16_t vpid[VM_MAXCPU]; int i, error, guest_msr_count; struct vmx *vmx; @@ -744,6 +805,8 @@ vmx_vminit(struct vm *vm) if (!vmx_no_patmsr && guest_msr_rw(vmx, MSR_PAT)) panic("vmx_vminit: error setting guest pat msr access"); + vpid_alloc(vpid, VM_MAXCPU); + for (i = 0; i < VM_MAXCPU; i++) { vmx->vmcs[i].identifier = vmx_revision(); error = vmclear(&vmx->vmcs[i]); @@ -752,8 +815,6 @@ vmx_vminit(struct vm *vm) error, i); } - vpid = vmx_vpid(); - error = vmcs_set_defaults(&vmx->vmcs[i], (u_long)vmx_longjmp, (u_long)&vmx->ctx[i], @@ -763,7 +824,7 @@ vmx_vminit(struct vm *vm) procbased_ctls2, exit_ctls, entry_ctls, vtophys(vmx->msr_bitmap), - vpid); + vpid[i]); if (error != 0) panic("vmx_vminit: vmcs_set_defaults error %d", error); @@ -772,7 +833,7 @@ vmx_vminit(struct vm *vm) vmx->cap[i].proc_ctls = procbased_ctls; vmx->state[i].lastcpu = -1; - vmx->state[i].vpid = vpid; + vmx->state[i].vpid = vpid[i]; msr_save_area_init(vmx->guest_msrs[i], &guest_msr_count); @@ -1580,9 +1641,12 @@ vmx_run(void *arg, int vcpu, register_t rip) static void vmx_vmcleanup(void *arg) { - int error; + int i, error; struct vmx *vmx = arg; + for (i = 0; i < VM_MAXCPU; i++) + vpid_free(vmx->state[i].vpid); + /* * XXXSMP we also need to clear the VMCS active on the other vcpus. */ diff --git a/sys/amd64/vmm/io/ppt.c b/sys/amd64/vmm/io/ppt.c index 5aedaf293421..878bf8a03f93 100644 --- a/sys/amd64/vmm/io/ppt.c +++ b/sys/amd64/vmm/io/ppt.c @@ -568,7 +568,7 @@ ppt_setup_msix(struct vm *vm, int vcpu, int bus, int slot, int func, return (ENXIO); ppt->msix.arg[idx].pptdev = ppt; - ppt->msix.arg[idx].vec = msg; + ppt->msix.arg[idx].vec = msg & 0xFF; ppt->msix.arg[idx].vcpu = (addr >> 12) & 0xFF; /* Setup the MSI-X interrupt */ diff --git a/sys/amd64/vmm/vmm_msr.c b/sys/amd64/vmm/vmm_msr.c index d97c819e4f40..0ccd7af07def 100644 --- a/sys/amd64/vmm/vmm_msr.c +++ b/sys/amd64/vmm/vmm_msr.c @@ -57,6 +57,7 @@ static struct vmm_msr vmm_msr[] = { { MSR_PAT, VMM_MSR_F_EMULATE | VMM_MSR_F_INVALID }, { MSR_BIOS_SIGN,VMM_MSR_F_EMULATE }, { MSR_MCG_CAP, VMM_MSR_F_EMULATE | VMM_MSR_F_READONLY }, + { MSR_IA32_MISC_ENABLE, VMM_MSR_F_EMULATE | VMM_MSR_F_READONLY }, }; #define vmm_msr_num (sizeof(vmm_msr) / sizeof(vmm_msr[0])) @@ -91,7 +92,7 @@ void guest_msrs_init(struct vm *vm, int cpu) { int i; - uint64_t *guest_msrs; + uint64_t *guest_msrs, misc; guest_msrs = vm_guest_msrs(vm, cpu); @@ -115,6 +116,20 @@ guest_msrs_init(struct vm *vm, int cpu) PAT_VALUE(6, PAT_UNCACHED) | PAT_VALUE(7, PAT_UNCACHEABLE); break; + case MSR_IA32_MISC_ENABLE: + misc = rdmsr(MSR_IA32_MISC_ENABLE); + /* + * Set mandatory bits + * 11: branch trace disabled + * 12: PEBS unavailable + * Clear unsupported features + * 16: SpeedStep enable + * 18: enable MONITOR FSM + */ + misc |= (1 << 12) | (1 << 11); + misc &= ~((1 << 18) | (1 << 16)); + guest_msrs[i] = misc; + break; default: panic("guest_msrs_init: missing initialization for msr " "0x%0x", vmm_msr[i].num); diff --git a/sys/amd64/vmm/x86.c b/sys/amd64/vmm/x86.c index 262efbd898ce..4416c530d55c 100644 --- a/sys/amd64/vmm/x86.c +++ b/sys/amd64/vmm/x86.c @@ -200,6 +200,7 @@ x86_emulate_cpuid(struct vm *vm, int vcpu_id, case CPUID_0000_0006: case CPUID_0000_0007: case CPUID_0000_000A: + case CPUID_0000_000D: /* * Handle the access, but report 0 for * all options diff --git a/sys/amd64/vmm/x86.h b/sys/amd64/vmm/x86.h index 368e96729827..8401c15f989a 100644 --- a/sys/amd64/vmm/x86.h +++ b/sys/amd64/vmm/x86.h @@ -38,6 +38,7 @@ #define CPUID_0000_0007 (0x7) #define CPUID_0000_000A (0xA) #define CPUID_0000_000B (0xB) +#define CPUID_0000_000D (0xD) #define CPUID_8000_0000 (0x80000000) #define CPUID_8000_0001 (0x80000001) #define CPUID_8000_0002 (0x80000002) diff --git a/sys/arm/broadcom/bcm2835/bcm2835_gpio.c b/sys/arm/broadcom/bcm2835/bcm2835_gpio.c index 9ddb44b2a792..26d23592c6d4 100644 --- a/sys/arm/broadcom/bcm2835/bcm2835_gpio.c +++ b/sys/arm/broadcom/bcm2835/bcm2835_gpio.c @@ -52,6 +52,8 @@ __FBSDID("$FreeBSD$"); #include #include +#include + #include "gpio_if.h" #undef DEBUG @@ -87,17 +89,6 @@ struct bcm_gpio_softc { struct bcm_gpio_sysctl sc_sysctl[BCM_GPIO_PINS]; }; -enum bcm_gpio_fsel { - BCM_GPIO_INPUT, - BCM_GPIO_OUTPUT, - BCM_GPIO_ALT5, - BCM_GPIO_ALT4, - BCM_GPIO_ALT0, - BCM_GPIO_ALT1, - BCM_GPIO_ALT2, - BCM_GPIO_ALT3, -}; - enum bcm_gpio_pud { BCM_GPIO_NONE, BCM_GPIO_PULLDOWN, @@ -257,6 +248,32 @@ bcm_gpio_set_pud(struct bcm_gpio_softc *sc, uint32_t pin, uint32_t state) BCM_GPIO_WRITE(sc, BCM_GPIO_GPPUDCLK(bank), 0); } +void +bcm_gpio_set_alternate(device_t dev, uint32_t pin, uint32_t nfunc) +{ + struct bcm_gpio_softc *sc; + int i; + + sc = device_get_softc(dev); + BCM_GPIO_LOCK(sc); + + /* Disable pull-up or pull-down on pin. */ + bcm_gpio_set_pud(sc, pin, BCM_GPIO_NONE); + + /* And now set the pin function. */ + bcm_gpio_set_function(sc, pin, nfunc); + + /* Update the pin flags. */ + for (i = 0; i < sc->sc_gpio_npins; i++) { + if (sc->sc_gpio_pins[i].gp_pin == pin) + break; + } + if (i < sc->sc_gpio_npins) + sc->sc_gpio_pins[i].gp_flags = bcm_gpio_func_flag(nfunc); + + BCM_GPIO_UNLOCK(sc); +} + static void bcm_gpio_pin_configure(struct bcm_gpio_softc *sc, struct gpio_pin *pin, unsigned int flags) @@ -535,7 +552,7 @@ bcm_gpio_func_proc(SYSCTL_HANDLER_ARGS) struct bcm_gpio_softc *sc; struct bcm_gpio_sysctl *sc_sysctl; uint32_t nfunc; - int i, error; + int error; sc_sysctl = arg1; sc = sc_sysctl->sc; @@ -552,23 +569,8 @@ bcm_gpio_func_proc(SYSCTL_HANDLER_ARGS) if (bcm_gpio_str_func(buf, &nfunc) != 0) return (EINVAL); - BCM_GPIO_LOCK(sc); - - /* Disable pull-up or pull-down on pin. */ - bcm_gpio_set_pud(sc, sc_sysctl->pin, BCM_GPIO_NONE); - - /* And now set the pin function. */ - bcm_gpio_set_function(sc, sc_sysctl->pin, nfunc); - - /* Update the pin flags. */ - for (i = 0; i < sc->sc_gpio_npins; i++) { - if (sc->sc_gpio_pins[i].gp_pin == sc_sysctl->pin) - break; - } - if (i < sc->sc_gpio_npins) - sc->sc_gpio_pins[i].gp_flags = bcm_gpio_func_flag(nfunc); - - BCM_GPIO_UNLOCK(sc); + /* Update the pin alternate function. */ + bcm_gpio_set_alternate(sc->sc_dev, sc_sysctl->pin, nfunc); return (0); } @@ -729,7 +731,7 @@ bcm_gpio_attach(device_t dev) goto fail; /* Initialize the software controlled pins. */ - for (i = 0, j = 0; j < BCM_GPIO_PINS - 1; j++) { + for (i = 0, j = 0; j < BCM_GPIO_PINS; j++) { if (bcm_gpio_pin_is_ro(sc, j)) continue; snprintf(sc->sc_gpio_pins[i].gp_name, GPIOMAXNAME, diff --git a/sys/arm/broadcom/bcm2835/bcm2835_gpio.h b/sys/arm/broadcom/bcm2835/bcm2835_gpio.h new file mode 100644 index 000000000000..911bcf219842 --- /dev/null +++ b/sys/arm/broadcom/bcm2835/bcm2835_gpio.h @@ -0,0 +1,44 @@ +/*- + * Copyright (c) 2013 Oleksandr Tymoshenko + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD$ + */ + +#ifndef _BCM2835_GPIO_H_ +#define _BCM2835_GPIO_H_ + +enum bcm_gpio_fsel { + BCM_GPIO_INPUT, + BCM_GPIO_OUTPUT, + BCM_GPIO_ALT5, + BCM_GPIO_ALT4, + BCM_GPIO_ALT0, + BCM_GPIO_ALT1, + BCM_GPIO_ALT2, + BCM_GPIO_ALT3, +}; + +void bcm_gpio_set_alternate(device_t, uint32_t, uint32_t); + +#endif /* _BCM2835_GPIO_H_ */ diff --git a/sys/arm/include/ieee.h b/sys/arm/include/ieee.h index 8ce9fd1085e6..25a096d10a47 100644 --- a/sys/arm/include/ieee.h +++ b/sys/arm/include/ieee.h @@ -91,7 +91,7 @@ #define DBL_EXPBITS 11 #define DBL_FRACBITS 52 -#if defined(__VFP_FP__) +#if defined(__VFP_FP__) || defined(__ARM_EABI__) #define _IEEE_WORD_ORDER _BYTE_ORDER #else #define _IEEE_WORD_ORDER _BIG_ENDIAN diff --git a/sys/arm/include/sf_buf.h b/sys/arm/include/sf_buf.h index 2225d5824939..fc00cc5a45e7 100644 --- a/sys/arm/include/sf_buf.h +++ b/sys/arm/include/sf_buf.h @@ -40,7 +40,6 @@ struct vm_page; struct sf_buf; - static __inline vm_offset_t sf_buf_kva(struct sf_buf *sf) { @@ -80,4 +79,8 @@ sf_buf_page(struct sf_buf *sf) } #endif + +struct sf_buf * sf_buf_alloc(struct vm_page *m, int flags); +void sf_buf_free(struct sf_buf *sf); + #endif /* !_MACHINE_SF_BUF_H_ */ diff --git a/sys/bsm/audit_kevents.h b/sys/bsm/audit_kevents.h index da2bc7c00c55..303d37ff80f2 100644 --- a/sys/bsm/audit_kevents.h +++ b/sys/bsm/audit_kevents.h @@ -589,6 +589,7 @@ #define AUE_POSIX_OPENPT 43185 /* FreeBSD. */ #define AUE_CAP_NEW 43186 /* TrustedBSD. */ #define AUE_CAP_RIGHTS_GET 43187 /* TrustedBSD. */ +#define AUE_CAP_GETRIGHTS AUE_CAP_RIGHTS_GET #define AUE_CAP_ENTER 43188 /* TrustedBSD. */ #define AUE_CAP_GETMODE 43189 /* TrustedBSD. */ #define AUE_POSIX_SPAWN 43190 /* Darwin. */ diff --git a/sys/bsm/audit_record.h b/sys/bsm/audit_record.h index 706c6f36ed1b..7e6074f3d344 100644 --- a/sys/bsm/audit_record.h +++ b/sys/bsm/audit_record.h @@ -34,6 +34,7 @@ #define _BSM_AUDIT_RECORD_H_ #include /* struct timeval */ +#include /* cap_rights_t */ /* * Token type identifiers. @@ -126,6 +127,8 @@ #define AUT_SOCKINET128 0x81 /* XXX */ #define AUT_SOCKUNIX 0x82 /* XXX */ +#define AUT_RIGHTS 0x83 + /* print values for the arbitrary token */ #define AUP_BINARY 0 #define AUP_OCTAL 1 @@ -248,6 +251,7 @@ token_t *au_to_process32_ex(au_id_t auid, uid_t euid, gid_t egid, au_tid_addr_t *tid); token_t *au_to_process64_ex(au_id_t auid, uid_t euid, gid_t egid, uid_t ruid, gid_t rgid, pid_t pid, au_asid_t sid, au_tid_addr_t *tid); +token_t *au_to_rights(cap_rights_t *rightsp); token_t *au_to_return(char status, uint32_t ret); token_t *au_to_return32(char status, uint32_t ret); token_t *au_to_return64(char status, uint64_t ret); diff --git a/sys/cam/scsi/scsi_da.c b/sys/cam/scsi/scsi_da.c index 8ee47f9c7baa..913951ef4ffa 100644 --- a/sys/cam/scsi/scsi_da.c +++ b/sys/cam/scsi/scsi_da.c @@ -3851,4 +3851,31 @@ scsi_format_unit(struct ccb_scsiio *csio, u_int32_t retries, timeout); } +void +scsi_sanitize(struct ccb_scsiio *csio, u_int32_t retries, + void (*cbfcnp)(struct cam_periph *, union ccb *), + u_int8_t tag_action, u_int8_t byte2, u_int16_t control, + u_int8_t *data_ptr, u_int32_t dxfer_len, u_int8_t sense_len, + u_int32_t timeout) +{ + struct scsi_sanitize *scsi_cmd; + + scsi_cmd = (struct scsi_sanitize *)&csio->cdb_io.cdb_bytes; + scsi_cmd->opcode = SANITIZE; + scsi_cmd->byte2 = byte2; + scsi_cmd->control = control; + scsi_ulto2b(dxfer_len, scsi_cmd->length); + + cam_fill_csio(csio, + retries, + cbfcnp, + /*flags*/ (dxfer_len > 0) ? CAM_DIR_OUT : CAM_DIR_NONE, + tag_action, + data_ptr, + dxfer_len, + sense_len, + sizeof(*scsi_cmd), + timeout); +} + #endif /* _KERNEL */ diff --git a/sys/cam/scsi/scsi_da.h b/sys/cam/scsi/scsi_da.h index 5799238196a5..4fbd7256af91 100644 --- a/sys/cam/scsi/scsi_da.h +++ b/sys/cam/scsi/scsi_da.h @@ -116,6 +116,31 @@ struct scsi_read_defect_data_10 u_int8_t control; }; +struct scsi_sanitize +{ + u_int8_t opcode; + u_int8_t byte2; +#define SSZ_SERVICE_ACTION_OVERWRITE 0x01 +#define SSZ_SERVICE_ACTION_BLOCK_ERASE 0x02 +#define SSZ_SERVICE_ACTION_CRYPTO_ERASE 0x03 +#define SSZ_SERVICE_ACTION_EXIT_MODE_FAILURE 0x1F +#define SSZ_UNRESTRICTED_EXIT 0x20 +#define SSZ_IMMED 0x80 + u_int8_t reserved[5]; + u_int8_t length[2]; + u_int8_t control; +}; + +struct scsi_sanitize_parameter_list +{ + u_int8_t byte1; +#define SSZPL_INVERT 0x80 + u_int8_t reserved; + u_int8_t length[2]; + /* Variable length initialization pattern. */ +#define SSZPL_MAX_PATTERN_LENGTH 65535 +}; + struct scsi_read_defect_data_12 { u_int8_t opcode; @@ -156,6 +181,7 @@ struct scsi_read_defect_data_12 #define WRITE_AND_VERIFY 0x2e #define VERIFY 0x2f #define READ_DEFECT_DATA_10 0x37 +#define SANITIZE 0x48 #define READ_DEFECT_DATA_12 0xb7 struct format_defect_list_header @@ -508,6 +534,12 @@ void scsi_format_unit(struct ccb_scsiio *csio, u_int32_t retries, u_int8_t *data_ptr, u_int32_t dxfer_len, u_int8_t sense_len, u_int32_t timeout); +void scsi_sanitize(struct ccb_scsiio *csio, u_int32_t retries, + void (*cbfcnp)(struct cam_periph *, union ccb *), + u_int8_t tag_action, u_int8_t byte2, u_int16_t control, + u_int8_t *data_ptr, u_int32_t dxfer_len, u_int8_t sense_len, + u_int32_t timeout); + #endif /* !_KERNEL */ __END_DECLS diff --git a/sys/cam/scsi/scsi_enc_ses.c b/sys/cam/scsi/scsi_enc_ses.c index 2e510301d30d..6917fffbd41f 100644 --- a/sys/cam/scsi/scsi_enc_ses.c +++ b/sys/cam/scsi/scsi_enc_ses.c @@ -567,8 +567,8 @@ ses_cache_free_elm_addlstatus(enc_softc_t *enc, enc_cache_t *cache) return; for (cur_elm = cache->elm_map, - last_elm = &cache->elm_map[cache->nelms - 1]; - cur_elm <= last_elm; cur_elm++) { + last_elm = &cache->elm_map[cache->nelms]; + cur_elm != last_elm; cur_elm++) { ses_element_t *elmpriv; elmpriv = cur_elm->elm_private; @@ -598,8 +598,8 @@ ses_cache_free_elm_descs(enc_softc_t *enc, enc_cache_t *cache) return; for (cur_elm = cache->elm_map, - last_elm = &cache->elm_map[cache->nelms - 1]; - cur_elm <= last_elm; cur_elm++) { + last_elm = &cache->elm_map[cache->nelms]; + cur_elm != last_elm; cur_elm++) { ses_element_t *elmpriv; elmpriv = cur_elm->elm_private; @@ -644,8 +644,8 @@ ses_cache_free_elm_map(enc_softc_t *enc, enc_cache_t *cache) ses_cache_free_elm_descs(enc, cache); ses_cache_free_elm_addlstatus(enc, cache); for (cur_elm = cache->elm_map, - last_elm = &cache->elm_map[cache->nelms - 1]; - cur_elm <= last_elm; cur_elm++) { + last_elm = &cache->elm_map[cache->nelms]; + cur_elm != last_elm; cur_elm++) { ENC_FREE_AND_NULL(cur_elm->elm_private); } @@ -717,8 +717,8 @@ ses_cache_clone(enc_softc_t *enc, enc_cache_t *src, enc_cache_t *dst) dst->elm_map = ENC_MALLOCZ(dst->nelms * sizeof(enc_element_t)); memcpy(dst->elm_map, src->elm_map, dst->nelms * sizeof(enc_element_t)); for (dst_elm = dst->elm_map, src_elm = src->elm_map, - last_elm = &src->elm_map[src->nelms - 1]; - src_elm <= last_elm; src_elm++, dst_elm++) { + last_elm = &src->elm_map[src->nelms]; + src_elm != last_elm; src_elm++, dst_elm++) { dst_elm->elm_private = ENC_MALLOCZ(sizeof(ses_element_t)); memcpy(dst_elm->elm_private, src_elm->elm_private, @@ -1555,6 +1555,18 @@ ses_process_status(enc_softc_t *enc, struct enc_fsm_state *state, ENC_VLOG(enc, "Enclosure Status Page Too Long\n"); goto out; } + + /* Check for simple enclosure reporting short enclosure status. */ + if (length >= 4 && page->hdr.page_code == SesShortStatus) { + ENC_DLOG(enc, "Got Short Enclosure Status page\n"); + ses->ses_flags &= ~(SES_FLAG_ADDLSTATUS | SES_FLAG_DESC); + ses_cache_free(enc, enc_cache); + enc_cache->enc_status = page->hdr.page_specific_flags; + enc_update_request(enc, SES_PUBLISH_CACHE); + err = 0; + goto out; + } + /* Make sure the length contains at least one header and status */ if (length < (sizeof(*page) + sizeof(*page->elements))) { ENC_VLOG(enc, "Enclosure Status Page Too Short\n"); diff --git a/sys/cddl/compat/opensolaris/sys/file.h b/sys/cddl/compat/opensolaris/sys/file.h index 0b8f87506614..5f83082f23c0 100644 --- a/sys/cddl/compat/opensolaris/sys/file.h +++ b/sys/cddl/compat/opensolaris/sys/file.h @@ -39,11 +39,11 @@ typedef struct file file_t; #include static __inline file_t * -getf(int fd, cap_rights_t rights) +getf(int fd, cap_rights_t *rightsp) { struct file *fp; - if (fget(curthread, fd, rights, &fp) == 0) + if (fget(curthread, fd, rightsp, &fp) == 0) return (fp); return (NULL); } @@ -54,7 +54,7 @@ releasef(int fd) struct file *fp; /* No CAP_ rights required, as we're only releasing. */ - if (fget(curthread, fd, 0, &fp) == 0) { + if (fget(curthread, fd, NULL, &fp) == 0) { fdrop(fp, curthread); fdrop(fp, curthread); } diff --git a/sys/cddl/compat/opensolaris/sys/kcondvar.h b/sys/cddl/compat/opensolaris/sys/kcondvar.h index 7c6884249a5e..bae053fa2ad8 100644 --- a/sys/cddl/compat/opensolaris/sys/kcondvar.h +++ b/sys/cddl/compat/opensolaris/sys/kcondvar.h @@ -1,5 +1,6 @@ /*- * Copyright (c) 2007 Pawel Jakub Dawidek + * Copyright (c) 2013 iXsystems, Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -36,6 +37,7 @@ #include #include +#include typedef struct cv kcondvar_t; @@ -57,6 +59,19 @@ typedef enum { } while (0) #define cv_init(cv, name, type, arg) zfs_cv_init(cv, name, type, arg) +static clock_t +cv_timedwait_hires(kcondvar_t *cvp, kmutex_t *mp, hrtime_t tim, hrtime_t res, + int flag) +{ + sbintime_t sbt; + sbintime_t pr; + + sbt = tim * SBT_1NS; + pr = res * SBT_1NS; + + return (cv_timedwait_sbt(cvp, mp, sbt, pr, 0)); +} + #endif /* _KERNEL */ #endif /* _OPENSOLARIS_SYS_CONDVAR_H_ */ diff --git a/sys/cddl/compat/opensolaris/sys/time.h b/sys/cddl/compat/opensolaris/sys/time.h index 2e8344721042..1f210c5f1873 100644 --- a/sys/cddl/compat/opensolaris/sys/time.h +++ b/sys/cddl/compat/opensolaris/sys/time.h @@ -37,6 +37,9 @@ #define NANOSEC 1000000000 #define TIME_MAX LLONG_MAX +#define MSEC2NSEC(m) ((hrtime_t)(m) * (NANOSEC / MILLISEC)) +#define NSEC2MSEC(n) ((n) / (NANOSEC / MILLISEC)) + typedef longlong_t hrtime_t; #if defined(__i386__) || defined(__powerpc__) diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dsl_dir.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dsl_dir.c index 4c86f9c3ae6d..123fb325d011 100644 --- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dsl_dir.c +++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dsl_dir.c @@ -744,7 +744,8 @@ dsl_dir_tempreserve_space(dsl_dir_t *dd, uint64_t lsize, uint64_t asize, err = dsl_pool_tempreserve_space(dd->dd_pool, asize, tx); } else { if (err == EAGAIN) { - txg_delay(dd->dd_pool, tx->tx_txg, 1); + txg_delay(dd->dd_pool, tx->tx_txg, + MSEC2NSEC(10), MSEC2NSEC(10)); err = SET_ERROR(ERESTART); } dsl_pool_memory_pressure(dd->dd_pool); diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dsl_pool.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dsl_pool.c index d7949e80c32d..963fd1c614ca 100644 --- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dsl_pool.c +++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dsl_pool.c @@ -85,6 +85,9 @@ SYSCTL_UQUAD(_vfs_zfs, OID_AUTO, write_limit_override, CTLFLAG_RDTUN, &zfs_write_limit_override, 0, "Force a txg if dirty buffers exceed this value (bytes)"); +hrtime_t zfs_throttle_delay = MSEC2NSEC(10); +hrtime_t zfs_throttle_resolution = MSEC2NSEC(10); + int dsl_pool_open_special_dir(dsl_pool_t *dp, const char *name, dsl_dir_t **ddp) { @@ -538,12 +541,13 @@ dsl_pool_sync(dsl_pool_t *dp, uint64_t txg) * Weight the throughput calculation towards the current value: * thru = 3/4 old_thru + 1/4 new_thru * - * Note: write_time is in nanosecs, so write_time/MICROSEC - * yields millisecs + * Note: write_time is in nanosecs while dp_throughput is expressed in + * bytes per millisecond. */ ASSERT(zfs_write_limit_min > 0); - if (data_written > zfs_write_limit_min / 8 && write_time > MICROSEC) { - uint64_t throughput = data_written / (write_time / MICROSEC); + if (data_written > zfs_write_limit_min / 8 && + write_time > MSEC2NSEC(1)) { + uint64_t throughput = data_written / NSEC2MSEC(write_time); if (dp->dp_throughput) dp->dp_throughput = throughput / 4 + @@ -641,8 +645,10 @@ dsl_pool_tempreserve_space(dsl_pool_t *dp, uint64_t space, dmu_tx_t *tx) * the caller 1 clock tick. This will slow down the "fill" * rate until the sync process can catch up with us. */ - if (reserved && reserved > (write_limit - (write_limit >> 3))) - txg_delay(dp, tx->tx_txg, 1); + if (reserved && reserved > (write_limit - (write_limit >> 3))) { + txg_delay(dp, tx->tx_txg, zfs_throttle_delay, + zfs_throttle_resolution); + } return (0); } diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dsl_scan.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dsl_scan.c index c4ec0daf02ef..78a0c6cbf76a 100644 --- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dsl_scan.c +++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dsl_scan.c @@ -444,7 +444,7 @@ dsl_scan_check_pause(dsl_scan_t *scn, const zbookmark_t *zb) zfs_resilver_min_time_ms : zfs_scan_min_time_ms; elapsed_nanosecs = gethrtime() - scn->scn_sync_start_time; if (elapsed_nanosecs / NANOSEC > zfs_txg_timeout || - (elapsed_nanosecs / MICROSEC > mintime && + (NSEC2MSEC(elapsed_nanosecs) > mintime && txg_sync_waiting(scn->scn_dp)) || spa_shutting_down(scn->scn_dp->dp_spa)) { if (zb) { @@ -1349,7 +1349,7 @@ dsl_scan_free_should_pause(dsl_scan_t *scn) elapsed_nanosecs = gethrtime() - scn->scn_sync_start_time; return (elapsed_nanosecs / NANOSEC > zfs_txg_timeout || - (elapsed_nanosecs / MICROSEC > zfs_free_min_time_ms && + (NSEC2MSEC(elapsed_nanosecs) > zfs_free_min_time_ms && txg_sync_waiting(scn->scn_dp)) || spa_shutting_down(scn->scn_dp->dp_spa)); } @@ -1473,7 +1473,7 @@ dsl_scan_sync(dsl_pool_t *dp, dmu_tx_t *tx) "free_bpobj/bptree txg %llu", (longlong_t)scn->scn_visited_this_txg, (longlong_t) - (gethrtime() - scn->scn_sync_start_time) / MICROSEC, + NSEC2MSEC(gethrtime() - scn->scn_sync_start_time), (longlong_t)tx->tx_txg); scn->scn_visited_this_txg = 0; /* @@ -1531,7 +1531,7 @@ dsl_scan_sync(dsl_pool_t *dp, dmu_tx_t *tx) zfs_dbgmsg("visited %llu blocks in %llums", (longlong_t)scn->scn_visited_this_txg, - (longlong_t)(gethrtime() - scn->scn_sync_start_time) / MICROSEC); + (longlong_t)NSEC2MSEC(gethrtime() - scn->scn_sync_start_time)); if (!scn->scn_pausing) { scn->scn_done_txg = tx->tx_txg + 1; diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/metaslab.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/metaslab.c index f2f713923006..50a1e82ba7f5 100644 --- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/metaslab.c +++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/metaslab.c @@ -32,6 +32,9 @@ #include #include +SYSCTL_DECL(_vfs_zfs); +SYSCTL_NODE(_vfs_zfs, OID_AUTO, metaslab, CTLFLAG_RW, 0, "ZFS metaslab"); + /* * Allow allocations to switch to gang blocks quickly. We do this to * avoid having to load lots of space_maps in a given txg. There are, @@ -46,6 +49,10 @@ uint64_t metaslab_aliquot = 512ULL << 10; uint64_t metaslab_gang_bang = SPA_MAXBLOCKSIZE + 1; /* force gang blocks */ +TUNABLE_QUAD("vfs.zfs.metaslab.gang_bang", &metaslab_gang_bang); +SYSCTL_QUAD(_vfs_zfs_metaslab, OID_AUTO, gang_bang, CTLFLAG_RWTUN, + &metaslab_gang_bang, 0, + "Force gang block allocation for blocks larger than or equal to this value"); /* * The in-core space map representation is more compact than its on-disk form. @@ -61,17 +68,19 @@ int zfs_condense_pct = 200; * allocations on that device. */ int zfs_mg_alloc_failures = 0; - -SYSCTL_DECL(_vfs_zfs); -SYSCTL_INT(_vfs_zfs, OID_AUTO, mg_alloc_failures, CTLFLAG_RDTUN, +TUNABLE_INT("vfs.zfs.mg_alloc_failures", &zfs_mg_alloc_failures); +SYSCTL_INT(_vfs_zfs, OID_AUTO, mg_alloc_failures, CTLFLAG_RWTUN, &zfs_mg_alloc_failures, 0, "Number of allowed allocation failures per vdev"); -TUNABLE_INT("vfs.zfs.mg_alloc_failures", &zfs_mg_alloc_failures); /* * Metaslab debugging: when set, keeps all space maps in core to verify frees. */ static int metaslab_debug = 0; +TUNABLE_INT("vfs.zfs.metaslab.debug", &metaslab_debug); +SYSCTL_INT(_vfs_zfs_metaslab, OID_AUTO, debug, CTLFLAG_RWTUN, &metaslab_debug, + 0, + "Metaslab debugging: when set, keeps all space maps in core to verify frees"); /* * Minimum size which forces the dynamic allocator to change @@ -80,6 +89,11 @@ static int metaslab_debug = 0; * aggressive strategy (i.e search by size rather than offset). */ uint64_t metaslab_df_alloc_threshold = SPA_MAXBLOCKSIZE; +TUNABLE_QUAD("vfs.zfs.metaslab.df_alloc_threshold", + &metaslab_df_alloc_threshold); +SYSCTL_QUAD(_vfs_zfs_metaslab, OID_AUTO, df_alloc_threshold, CTLFLAG_RWTUN, + &metaslab_df_alloc_threshold, 0, + "Minimum size which forces the dynamic allocator to change it's allocation strategy"); /* * The minimum free space, in percent, which must be available @@ -88,22 +102,37 @@ uint64_t metaslab_df_alloc_threshold = SPA_MAXBLOCKSIZE; * switch to using best-fit allocations. */ int metaslab_df_free_pct = 4; +TUNABLE_INT("vfs.zfs.metaslab.df_free_pct", &metaslab_df_free_pct); +SYSCTL_INT(_vfs_zfs_metaslab, OID_AUTO, df_free_pct, CTLFLAG_RWTUN, + &metaslab_df_free_pct, 0, + "The minimum free space, in percent, which must be available in a space map to continue allocations in a first-fit fashion"); /* * A metaslab is considered "free" if it contains a contiguous * segment which is greater than metaslab_min_alloc_size. */ uint64_t metaslab_min_alloc_size = DMU_MAX_ACCESS; +TUNABLE_QUAD("vfs.zfs.metaslab.min_alloc_size", + &metaslab_min_alloc_size); +SYSCTL_QUAD(_vfs_zfs_metaslab, OID_AUTO, min_alloc_size, CTLFLAG_RWTUN, + &metaslab_min_alloc_size, 0, + "A metaslab is considered \"free\" if it contains a contiguous segment which is greater than vfs.zfs.metaslab.min_alloc_size"); /* * Max number of space_maps to prefetch. */ int metaslab_prefetch_limit = SPA_DVAS_PER_BP; +TUNABLE_INT("vfs.zfs.metaslab.prefetch_limit", &metaslab_prefetch_limit); +SYSCTL_INT(_vfs_zfs_metaslab, OID_AUTO, prefetch_limit, CTLFLAG_RWTUN, + &metaslab_prefetch_limit, 0, "Maximum number of space_maps to prefetch"); /* * Percentage bonus multiplier for metaslabs that are in the bonus area. */ int metaslab_smo_bonus_pct = 150; +TUNABLE_INT("vfs.zfs.metaslab.smo_bonus_pct", &metaslab_smo_bonus_pct); +SYSCTL_INT(_vfs_zfs_metaslab, OID_AUTO, smo_bonus_pct, CTLFLAG_RWTUN, + &metaslab_smo_bonus_pct, 0, "Maximum number of space_maps to prefetch"); /* * Should we be willing to write data to degraded vdevs? diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/spa_misc.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/spa_misc.c index 836c2224e0f1..d92bcf06ff66 100644 --- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/spa_misc.c +++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/spa_misc.c @@ -534,8 +534,8 @@ spa_add(const char *name, nvlist_t *config, const char *altroot) hdlr.cyh_level = CY_LOW_LEVEL; #endif - spa->spa_deadman_synctime = zfs_deadman_synctime * - zfs_txg_synctime_ms * MICROSEC; + spa->spa_deadman_synctime = MSEC2NSEC(zfs_deadman_synctime * + zfs_txg_synctime_ms); #ifdef illumos /* @@ -544,7 +544,7 @@ spa_add(const char *name, nvlist_t *config, const char *altroot) * an expensive operation we don't want to check too frequently. * Instead wait for 5 synctimes before checking again. */ - when.cyt_interval = 5ULL * zfs_txg_synctime_ms * MICROSEC; + when.cyt_interval = MSEC2NSEC(5 * zfs_txg_synctime_ms); when.cyt_when = CY_INFINITY; mutex_enter(&cpu_lock); spa->spa_deadman_cycid = cyclic_add(&hdlr, &when); diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/txg.h b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/txg.h index 2df33f0fb0a7..1529e5ac6da4 100644 --- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/txg.h +++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/txg.h @@ -74,13 +74,8 @@ extern void txg_rele_to_quiesce(txg_handle_t *txghp); extern void txg_rele_to_sync(txg_handle_t *txghp); extern void txg_register_callbacks(txg_handle_t *txghp, list_t *tx_callbacks); -/* - * Delay the caller by the specified number of ticks or until - * the txg closes (whichever comes first). This is intended - * to be used to throttle writers when the system nears its - * capacity. - */ -extern void txg_delay(struct dsl_pool *dp, uint64_t txg, int ticks); +extern void txg_delay(struct dsl_pool *dp, uint64_t txg, hrtime_t delta, + hrtime_t resolution); /* * Wait until the given transaction group has finished syncing. diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/txg_impl.h b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/txg_impl.h index 5a6d0e19f071..8a0977f1f4dc 100644 --- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/txg_impl.h +++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/txg_impl.h @@ -70,7 +70,7 @@ struct tx_cpu { kmutex_t tc_open_lock; /* protects tx_open_txg */ kmutex_t tc_lock; /* protects the rest of this struct */ kcondvar_t tc_cv[TXG_SIZE]; - uint64_t tc_count[TXG_SIZE]; + uint64_t tc_count[TXG_SIZE]; /* tx hold count on each txg */ list_t tc_callbacks[TXG_SIZE]; /* commit cb list */ char tc_pad[8]; /* pad to fill 3 cache lines */ }; @@ -87,8 +87,8 @@ struct tx_cpu { * every cpu (see txg_quiesce()). */ typedef struct tx_state { - tx_cpu_t *tx_cpu; /* protects right to enter txg */ - kmutex_t tx_sync_lock; /* protects tx_state_t */ + tx_cpu_t *tx_cpu; /* protects access to tx_open_txg */ + kmutex_t tx_sync_lock; /* protects the rest of this struct */ uint64_t tx_open_txg; /* currently open txg id */ uint64_t tx_quiesced_txg; /* quiesced txg waiting for sync */ uint64_t tx_syncing_txg; /* currently syncing txg id */ diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/txg.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/txg.c index 18c722e56be2..ae2fdd7da6be 100644 --- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/txg.c +++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/txg.c @@ -241,7 +241,7 @@ txg_thread_exit(tx_state_t *tx, callb_cpr_t *cpr, kthread_t **tpp) } static void -txg_thread_wait(tx_state_t *tx, callb_cpr_t *cpr, kcondvar_t *cv, uint64_t time) +txg_thread_wait(tx_state_t *tx, callb_cpr_t *cpr, kcondvar_t *cv, clock_t time) { CALLB_CPR_SAFE_BEGIN(cpr); @@ -370,6 +370,9 @@ txg_quiesce(dsl_pool_t *dp, uint64_t txg) ASSERT(txg == tx->tx_open_txg); tx->tx_open_txg++; + DTRACE_PROBE2(txg__quiescing, dsl_pool_t *, dp, uint64_t, txg); + DTRACE_PROBE2(txg__opened, dsl_pool_t *, dp, uint64_t, tx->tx_open_txg); + /* * Now that we've incremented tx_open_txg, we can let threads * enter the next transaction group. @@ -501,6 +504,7 @@ txg_sync_thread(void *arg) txg = tx->tx_quiesced_txg; tx->tx_quiesced_txg = 0; tx->tx_syncing_txg = txg; + DTRACE_PROBE2(txg__syncing, dsl_pool_t *, dp, uint64_t, txg); cv_broadcast(&tx->tx_quiesce_more_cv); dprintf("txg=%llu quiesce_txg=%llu sync_txg=%llu\n", @@ -514,6 +518,7 @@ txg_sync_thread(void *arg) mutex_enter(&tx->tx_sync_lock); tx->tx_synced_txg = txg; tx->tx_syncing_txg = 0; + DTRACE_PROBE2(txg__synced, dsl_pool_t *, dp, uint64_t, txg); cv_broadcast(&tx->tx_sync_done_cv); /* @@ -563,21 +568,22 @@ txg_quiesce_thread(void *arg) */ dprintf("quiesce done, handing off txg %llu\n", txg); tx->tx_quiesced_txg = txg; + DTRACE_PROBE2(txg__quiesced, dsl_pool_t *, dp, uint64_t, txg); cv_broadcast(&tx->tx_sync_more_cv); cv_broadcast(&tx->tx_quiesce_done_cv); } } /* - * Delay this thread by 'ticks' if we are still in the open transaction - * group and there is already a waiting txg quiescing or quiesced. - * Abort the delay if this txg stalls or enters the quiescing state. + * Delay this thread by delay nanoseconds if we are still in the open + * transaction group and there is already a waiting txg quiesing or quiesced. + * Abort the delay if this txg stalls or enters the quiesing state. */ void -txg_delay(dsl_pool_t *dp, uint64_t txg, int ticks) +txg_delay(dsl_pool_t *dp, uint64_t txg, hrtime_t delay, hrtime_t resolution) { tx_state_t *tx = &dp->dp_tx; - clock_t timeout = ddi_get_lbolt() + ticks; + hrtime_t start = gethrtime(); /* don't delay if this txg could transition to quiescing immediately */ if (tx->tx_open_txg > txg || @@ -590,10 +596,11 @@ txg_delay(dsl_pool_t *dp, uint64_t txg, int ticks) return; } - while (ddi_get_lbolt() < timeout && - tx->tx_syncing_txg < txg-1 && !txg_stalled(dp)) - (void) cv_timedwait(&tx->tx_quiesce_more_cv, &tx->tx_sync_lock, - timeout - ddi_get_lbolt()); + while (gethrtime() - start < delay && + tx->tx_syncing_txg < txg-1 && !txg_stalled(dp)) { + (void) cv_timedwait_hires(&tx->tx_quiesce_more_cv, + &tx->tx_sync_lock, delay, resolution, 0); + } mutex_exit(&tx->tx_sync_lock); } diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_ioctl.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_ioctl.c index 10456f886061..e9fba26d8365 100644 --- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_ioctl.c +++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_ioctl.c @@ -4005,6 +4005,7 @@ zfs_ioc_recv(zfs_cmd_t *zc) char *origin = NULL; char *tosnap; char tofs[ZFS_MAXNAMELEN]; + cap_rights_t rights; boolean_t first_recvd_props = B_FALSE; if (dataset_namecheck(zc->zc_value, NULL, NULL) != 0 || @@ -4022,7 +4023,7 @@ zfs_ioc_recv(zfs_cmd_t *zc) return (error); fd = zc->zc_cookie; - fp = getf(fd, CAP_PREAD); + fp = getf(fd, cap_rights_init(&rights, CAP_PREAD)); if (fp == NULL) { nvlist_free(props); return (SET_ERROR(EBADF)); @@ -4260,7 +4261,11 @@ zfs_ioc_send(zfs_cmd_t *zc) dsl_dataset_rele(tosnap, FTAG); dsl_pool_rele(dp, FTAG); } else { - file_t *fp = getf(zc->zc_cookie, CAP_WRITE); + file_t *fp; + cap_rights_t rights; + + fp = getf(zc->zc_cookie, + cap_rights_init(&rights, CAP_WRITE)); if (fp == NULL) return (SET_ERROR(EBADF)); @@ -4851,10 +4856,11 @@ static int zfs_ioc_diff(zfs_cmd_t *zc) { file_t *fp; + cap_rights_t rights; offset_t off; int error; - fp = getf(zc->zc_cookie, CAP_WRITE); + fp = getf(zc->zc_cookie, cap_rights_init(&rights, CAP_WRITE)); if (fp == NULL) return (SET_ERROR(EBADF)); @@ -5214,6 +5220,7 @@ zfs_ioc_unjail(zfs_cmd_t *zc) static int zfs_ioc_send_new(const char *snapname, nvlist_t *innvl, nvlist_t *outnvl) { + cap_rights_t rights; int error; offset_t off; char *fromname = NULL; @@ -5225,7 +5232,7 @@ zfs_ioc_send_new(const char *snapname, nvlist_t *innvl, nvlist_t *outnvl) (void) nvlist_lookup_string(innvl, "fromsnap", &fromname); - file_t *fp = getf(fd, CAP_READ); + file_t *fp = getf(fd, cap_rights_init(&rights, CAP_READ)); if (fp == NULL) return (SET_ERROR(EBADF)); diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_onexit.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_onexit.c index 05252cbd0645..6a90b9cf2028 100644 --- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_onexit.c +++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_onexit.c @@ -122,10 +122,11 @@ zfs_onexit_fd_hold(int fd, minor_t *minorp) { file_t *fp, *tmpfp; zfs_onexit_t *zo; + cap_rights_t rights; void *data; int error; - fp = getf(fd, CAP_NONE); + fp = getf(fd, cap_rights_init(&rights)); if (fp == NULL) return (SET_ERROR(EBADF)); diff --git a/sys/cddl/dev/dtrace/dtrace_clone.c b/sys/cddl/dev/dtrace/dtrace_clone.c index be1e3d41ac99..5009e9d5981c 100644 --- a/sys/cddl/dev/dtrace/dtrace_clone.c +++ b/sys/cddl/dev/dtrace/dtrace_clone.c @@ -52,10 +52,6 @@ dtrace_clone(void *arg, struct ucred *cred, char *name, int namelen, struct cdev /* Clone the device to the new minor number. */ if (clone_create(&dtrace_clones, &dtrace_cdevsw, &u, dev, 0) != 0) /* Create the /dev/dtrace/dtraceNN entry. */ - *dev = make_dev_cred(&dtrace_cdevsw, u, cred, + *dev = make_dev_credf(MAKEDEV_REF, &dtrace_cdevsw, u, cred, UID_ROOT, GID_WHEEL, 0600, "dtrace/dtrace%d", u); - if (*dev != NULL) { - dev_ref(*dev); - (*dev)->si_flags |= SI_CHEAPCLONE; - } } diff --git a/sys/compat/freebsd32/freebsd32_capability.c b/sys/compat/freebsd32/freebsd32_capability.c index e17c39417ffc..b23cf959d125 100644 --- a/sys/compat/freebsd32/freebsd32_capability.c +++ b/sys/compat/freebsd32/freebsd32_capability.c @@ -42,24 +42,12 @@ __FBSDID("$FreeBSD$"); #include -#include #include #ifdef CAPABILITIES MALLOC_DECLARE(M_FILECAPS); -int -freebsd32_cap_rights_limit(struct thread *td, - struct freebsd32_cap_rights_limit_args *uap) -{ - struct cap_rights_limit_args ap; - - ap.fd = uap->fd; - ap.rights = PAIR32TO64(uint64_t, uap->rights); - return (sys_cap_rights_limit(td, &ap)); -} - int freebsd32_cap_ioctls_limit(struct thread *td, struct freebsd32_cap_ioctls_limit_args *uap) @@ -147,14 +135,6 @@ freebsd32_cap_ioctls_get(struct thread *td, #else /* !CAPABILITIES */ -int -freebsd32_cap_rights_limit(struct thread *td, - struct freebsd32_cap_rights_limit_args *uap) -{ - - return (ENOSYS); -} - int freebsd32_cap_ioctls_limit(struct thread *td, struct freebsd32_cap_ioctls_limit_args *uap) diff --git a/sys/compat/freebsd32/freebsd32_ioctl.c b/sys/compat/freebsd32/freebsd32_ioctl.c index 81f5c8ed4715..1f90e58541b6 100644 --- a/sys/compat/freebsd32/freebsd32_ioctl.c +++ b/sys/compat/freebsd32/freebsd32_ioctl.c @@ -353,9 +353,11 @@ freebsd32_ioctl(struct thread *td, struct freebsd32_ioctl_args *uap) caddr_t data; }*/ ; struct file *fp; + cap_rights_t rights; int error; - if ((error = fget(td, uap->fd, CAP_IOCTL, &fp)) != 0) + error = fget(td, uap->fd, cap_rights_init(&rights, CAP_IOCTL), &fp); + if (error != 0) return (error); if ((fp->f_flag & (FREAD | FWRITE)) == 0) { fdrop(fp, td); diff --git a/sys/compat/freebsd32/freebsd32_misc.c b/sys/compat/freebsd32/freebsd32_misc.c index 16d12053e5e5..dbdafeb3f716 100644 --- a/sys/compat/freebsd32/freebsd32_misc.c +++ b/sys/compat/freebsd32/freebsd32_misc.c @@ -448,9 +448,8 @@ freebsd32_mmap_partial(struct thread *td, vm_offset_t start, vm_offset_t end, } } else { vm_offset_t addr = trunc_page(start); - rv = vm_map_find(map, 0, 0, - &addr, PAGE_SIZE, FALSE, prot, - VM_PROT_ALL, 0); + rv = vm_map_find(map, NULL, 0, &addr, PAGE_SIZE, 0, + VMFS_NO_SPACE, prot, VM_PROT_ALL, 0); if (rv != KERN_SUCCESS) return (EINVAL); } @@ -542,9 +541,8 @@ freebsd32_mmap(struct thread *td, struct freebsd32_mmap_args *uap) rv = vm_map_remove(map, start, end); if (rv != KERN_SUCCESS) return (EINVAL); - rv = vm_map_find(map, 0, 0, - &start, end - start, FALSE, - prot, VM_PROT_ALL, 0); + rv = vm_map_find(map, NULL, 0, &start, end - start, + 0, VMFS_NO_SPACE, prot, VM_PROT_ALL, 0); if (rv != KERN_SUCCESS) return (EINVAL); r.fd = fd; @@ -1650,6 +1648,7 @@ freebsd32_do_sendfile(struct thread *td, struct uio *hdr_uio, *trl_uio; struct iovec32 *iov32; struct file *fp; + cap_rights_t rights; off_t offset; int error; @@ -1686,8 +1685,10 @@ freebsd32_do_sendfile(struct thread *td, AUDIT_ARG_FD(uap->fd); - if ((error = fget_read(td, uap->fd, CAP_PREAD, &fp)) != 0) + if ((error = fget_read(td, uap->fd, + cap_rights_init(&rights, CAP_PREAD), &fp)) != 0) { goto out; + } error = fo_sendfile(fp, uap->s, hdr_uio, trl_uio, offset, uap->nbytes, uap->sbytes, uap->flags, compat ? SFK_COMPAT : 0, td); diff --git a/sys/compat/freebsd32/freebsd32_proto.h b/sys/compat/freebsd32/freebsd32_proto.h index 363aad38caf0..96b9b37ea6d6 100644 --- a/sys/compat/freebsd32/freebsd32_proto.h +++ b/sys/compat/freebsd32/freebsd32_proto.h @@ -3,7 +3,7 @@ * * DO NOT EDIT-- this file is automatically generated. * $FreeBSD$ - * created from FreeBSD: head/sys/compat/freebsd32/syscalls.master 254491 2013-08-18 13:37:54Z pjd + * created from FreeBSD: head/sys/compat/freebsd32/syscalls.master 255219 2013-09-05 00:09:56Z pjd */ #ifndef _FREEBSD32_SYSPROTO_H_ @@ -627,12 +627,6 @@ struct freebsd32_wait6_args { char wrusage_l_[PADL_(struct wrusage32 *)]; struct wrusage32 * wrusage; char wrusage_r_[PADR_(struct wrusage32 *)]; char info_l_[PADL_(siginfo_t *)]; siginfo_t * info; char info_r_[PADR_(siginfo_t *)]; }; -struct freebsd32_cap_rights_limit_args { - char fd_l_[PADL_(int)]; int fd; char fd_r_[PADR_(int)]; - char pad_l_[PADL_(int)]; int pad; char pad_r_[PADR_(int)]; - char rights1_l_[PADL_(uint32_t)]; uint32_t rights1; char rights1_r_[PADR_(uint32_t)]; - char rights2_l_[PADL_(uint32_t)]; uint32_t rights2; char rights2_r_[PADR_(uint32_t)]; -}; #else struct freebsd32_posix_fallocate_args { char fd_l_[PADL_(int)]; int fd; char fd_r_[PADR_(int)]; @@ -658,11 +652,6 @@ struct freebsd32_wait6_args { char wrusage_l_[PADL_(struct wrusage32 *)]; struct wrusage32 * wrusage; char wrusage_r_[PADR_(struct wrusage32 *)]; char info_l_[PADL_(siginfo_t *)]; siginfo_t * info; char info_r_[PADR_(siginfo_t *)]; }; -struct freebsd32_cap_rights_limit_args { - char fd_l_[PADL_(int)]; int fd; char fd_r_[PADR_(int)]; - char rights1_l_[PADL_(uint32_t)]; uint32_t rights1; char rights1_r_[PADR_(uint32_t)]; - char rights2_l_[PADL_(uint32_t)]; uint32_t rights2; char rights2_r_[PADR_(uint32_t)]; -}; #endif struct freebsd32_cap_ioctls_limit_args { char fd_l_[PADL_(int)]; int fd; char fd_r_[PADR_(int)]; @@ -795,12 +784,10 @@ int freebsd32_pselect(struct thread *, struct freebsd32_pselect_args *); int freebsd32_posix_fallocate(struct thread *, struct freebsd32_posix_fallocate_args *); int freebsd32_posix_fadvise(struct thread *, struct freebsd32_posix_fadvise_args *); int freebsd32_wait6(struct thread *, struct freebsd32_wait6_args *); -int freebsd32_cap_rights_limit(struct thread *, struct freebsd32_cap_rights_limit_args *); #else int freebsd32_posix_fallocate(struct thread *, struct freebsd32_posix_fallocate_args *); int freebsd32_posix_fadvise(struct thread *, struct freebsd32_posix_fadvise_args *); int freebsd32_wait6(struct thread *, struct freebsd32_wait6_args *); -int freebsd32_cap_rights_limit(struct thread *, struct freebsd32_cap_rights_limit_args *); #endif int freebsd32_cap_ioctls_limit(struct thread *, struct freebsd32_cap_ioctls_limit_args *); int freebsd32_cap_ioctls_get(struct thread *, struct freebsd32_cap_ioctls_get_args *); @@ -1199,11 +1186,9 @@ int freebsd7_freebsd32_shmctl(struct thread *, struct freebsd7_freebsd32_shmctl_ #define FREEBSD32_SYS_AUE_freebsd32_posix_fallocate AUE_NULL #define FREEBSD32_SYS_AUE_freebsd32_posix_fadvise AUE_NULL #define FREEBSD32_SYS_AUE_freebsd32_wait6 AUE_WAIT6 -#define FREEBSD32_SYS_AUE_freebsd32_cap_rights_limit AUE_CAP_RIGHTS_LIMIT #define FREEBSD32_SYS_AUE_freebsd32_posix_fallocate AUE_NULL #define FREEBSD32_SYS_AUE_freebsd32_posix_fadvise AUE_NULL #define FREEBSD32_SYS_AUE_freebsd32_wait6 AUE_WAIT6 -#define FREEBSD32_SYS_AUE_freebsd32_cap_rights_limit AUE_CAP_RIGHTS_LIMIT #define FREEBSD32_SYS_AUE_freebsd32_cap_ioctls_limit AUE_CAP_IOCTLS_LIMIT #define FREEBSD32_SYS_AUE_freebsd32_cap_ioctls_get AUE_CAP_IOCTLS_GET #define FREEBSD32_SYS_AUE_freebsd32_aio_mlock AUE_NULL diff --git a/sys/compat/freebsd32/freebsd32_syscall.h b/sys/compat/freebsd32/freebsd32_syscall.h index 8568201a0c56..dbbee5bf6a06 100644 --- a/sys/compat/freebsd32/freebsd32_syscall.h +++ b/sys/compat/freebsd32/freebsd32_syscall.h @@ -3,7 +3,7 @@ * * DO NOT EDIT-- this file is automatically generated. * $FreeBSD$ - * created from FreeBSD: head/sys/compat/freebsd32/syscalls.master 254491 2013-08-18 13:37:54Z pjd + * created from FreeBSD: head/sys/compat/freebsd32/syscalls.master 255219 2013-09-05 00:09:56Z pjd */ #define FREEBSD32_SYS_syscall 0 @@ -420,8 +420,8 @@ #define FREEBSD32_SYS_freebsd32_msgctl 511 #define FREEBSD32_SYS_freebsd32_shmctl 512 #define FREEBSD32_SYS_lpathconf 513 -#define FREEBSD32_SYS_cap_new 514 -#define FREEBSD32_SYS_cap_rights_get 515 + /* 514 is obsolete cap_new */ +#define FREEBSD32_SYS___cap_rights_get 515 #define FREEBSD32_SYS_cap_enter 516 #define FREEBSD32_SYS_cap_getmode 517 #define FREEBSD32_SYS_pdfork 518 @@ -438,11 +438,10 @@ #define FREEBSD32_SYS_freebsd32_posix_fallocate 530 #define FREEBSD32_SYS_freebsd32_posix_fadvise 531 #define FREEBSD32_SYS_freebsd32_wait6 532 -#define FREEBSD32_SYS_freebsd32_cap_rights_limit 533 #define FREEBSD32_SYS_freebsd32_posix_fallocate 530 #define FREEBSD32_SYS_freebsd32_posix_fadvise 531 #define FREEBSD32_SYS_freebsd32_wait6 532 -#define FREEBSD32_SYS_freebsd32_cap_rights_limit 533 +#define FREEBSD32_SYS_cap_rights_limit 533 #define FREEBSD32_SYS_freebsd32_cap_ioctls_limit 534 #define FREEBSD32_SYS_freebsd32_cap_ioctls_get 535 #define FREEBSD32_SYS_cap_fcntls_limit 536 diff --git a/sys/compat/freebsd32/freebsd32_syscalls.c b/sys/compat/freebsd32/freebsd32_syscalls.c index 734b9fdb468a..3f6cbfc467ec 100644 --- a/sys/compat/freebsd32/freebsd32_syscalls.c +++ b/sys/compat/freebsd32/freebsd32_syscalls.c @@ -3,7 +3,7 @@ * * DO NOT EDIT-- this file is automatically generated. * $FreeBSD$ - * created from FreeBSD: head/sys/compat/freebsd32/syscalls.master 254491 2013-08-18 13:37:54Z pjd + * created from FreeBSD: head/sys/compat/freebsd32/syscalls.master 255219 2013-09-05 00:09:56Z pjd */ const char *freebsd32_syscallnames[] = { @@ -537,8 +537,8 @@ const char *freebsd32_syscallnames[] = { "freebsd32_msgctl", /* 511 = freebsd32_msgctl */ "freebsd32_shmctl", /* 512 = freebsd32_shmctl */ "lpathconf", /* 513 = lpathconf */ - "cap_new", /* 514 = cap_new */ - "cap_rights_get", /* 515 = cap_rights_get */ + "obs_cap_new", /* 514 = obsolete cap_new */ + "__cap_rights_get", /* 515 = __cap_rights_get */ "cap_enter", /* 516 = cap_enter */ "cap_getmode", /* 517 = cap_getmode */ "pdfork", /* 518 = pdfork */ @@ -557,13 +557,12 @@ const char *freebsd32_syscallnames[] = { "freebsd32_posix_fallocate", /* 530 = freebsd32_posix_fallocate */ "freebsd32_posix_fadvise", /* 531 = freebsd32_posix_fadvise */ "freebsd32_wait6", /* 532 = freebsd32_wait6 */ - "freebsd32_cap_rights_limit", /* 533 = freebsd32_cap_rights_limit */ #else "freebsd32_posix_fallocate", /* 530 = freebsd32_posix_fallocate */ "freebsd32_posix_fadvise", /* 531 = freebsd32_posix_fadvise */ "freebsd32_wait6", /* 532 = freebsd32_wait6 */ - "freebsd32_cap_rights_limit", /* 533 = freebsd32_cap_rights_limit */ #endif + "cap_rights_limit", /* 533 = cap_rights_limit */ "freebsd32_cap_ioctls_limit", /* 534 = freebsd32_cap_ioctls_limit */ "freebsd32_cap_ioctls_get", /* 535 = freebsd32_cap_ioctls_get */ "cap_fcntls_limit", /* 536 = cap_fcntls_limit */ diff --git a/sys/compat/freebsd32/freebsd32_sysent.c b/sys/compat/freebsd32/freebsd32_sysent.c index 1c82a00f98f8..00b4153b2594 100644 --- a/sys/compat/freebsd32/freebsd32_sysent.c +++ b/sys/compat/freebsd32/freebsd32_sysent.c @@ -3,7 +3,7 @@ * * DO NOT EDIT-- this file is automatically generated. * $FreeBSD$ - * created from FreeBSD: head/sys/compat/freebsd32/syscalls.master 254491 2013-08-18 13:37:54Z pjd + * created from FreeBSD: head/sys/compat/freebsd32/syscalls.master 255219 2013-09-05 00:09:56Z pjd */ #include "opt_compat.h" @@ -574,8 +574,8 @@ struct sysent freebsd32_sysent[] = { { AS(freebsd32_msgctl_args), (sy_call_t *)lkmressys, AUE_NULL, NULL, 0, 0, 0, SY_THR_ABSENT }, /* 511 = freebsd32_msgctl */ { AS(freebsd32_shmctl_args), (sy_call_t *)lkmressys, AUE_NULL, NULL, 0, 0, 0, SY_THR_ABSENT }, /* 512 = freebsd32_shmctl */ { AS(lpathconf_args), (sy_call_t *)sys_lpathconf, AUE_LPATHCONF, NULL, 0, 0, 0, SY_THR_STATIC }, /* 513 = lpathconf */ - { AS(cap_new_args), (sy_call_t *)sys_cap_new, AUE_CAP_NEW, NULL, 0, 0, 0, SY_THR_STATIC }, /* 514 = cap_new */ - { AS(cap_rights_get_args), (sy_call_t *)sys_cap_rights_get, AUE_CAP_RIGHTS_GET, NULL, 0, 0, 0, SY_THR_STATIC }, /* 515 = cap_rights_get */ + { 0, (sy_call_t *)nosys, AUE_NULL, NULL, 0, 0, 0, SY_THR_ABSENT }, /* 514 = obsolete cap_new */ + { AS(__cap_rights_get_args), (sy_call_t *)sys___cap_rights_get, AUE_CAP_RIGHTS_GET, NULL, 0, 0, 0, SY_THR_STATIC }, /* 515 = __cap_rights_get */ { 0, (sy_call_t *)sys_cap_enter, AUE_CAP_ENTER, NULL, 0, 0, 0, SY_THR_STATIC }, /* 516 = cap_enter */ { AS(cap_getmode_args), (sy_call_t *)sys_cap_getmode, AUE_CAP_GETMODE, NULL, 0, 0, 0, SY_THR_STATIC }, /* 517 = cap_getmode */ { AS(pdfork_args), (sy_call_t *)sys_pdfork, AUE_PDFORK, NULL, 0, 0, 0, SY_THR_STATIC }, /* 518 = pdfork */ @@ -594,13 +594,12 @@ struct sysent freebsd32_sysent[] = { { AS(freebsd32_posix_fallocate_args), (sy_call_t *)freebsd32_posix_fallocate, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 530 = freebsd32_posix_fallocate */ { AS(freebsd32_posix_fadvise_args), (sy_call_t *)freebsd32_posix_fadvise, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 531 = freebsd32_posix_fadvise */ { AS(freebsd32_wait6_args), (sy_call_t *)freebsd32_wait6, AUE_WAIT6, NULL, 0, 0, 0, SY_THR_STATIC }, /* 532 = freebsd32_wait6 */ - { AS(freebsd32_cap_rights_limit_args), (sy_call_t *)freebsd32_cap_rights_limit, AUE_CAP_RIGHTS_LIMIT, NULL, 0, 0, 0, SY_THR_STATIC }, /* 533 = freebsd32_cap_rights_limit */ #else { AS(freebsd32_posix_fallocate_args), (sy_call_t *)freebsd32_posix_fallocate, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 530 = freebsd32_posix_fallocate */ { AS(freebsd32_posix_fadvise_args), (sy_call_t *)freebsd32_posix_fadvise, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 531 = freebsd32_posix_fadvise */ { AS(freebsd32_wait6_args), (sy_call_t *)freebsd32_wait6, AUE_WAIT6, NULL, 0, 0, 0, SY_THR_STATIC }, /* 532 = freebsd32_wait6 */ - { AS(freebsd32_cap_rights_limit_args), (sy_call_t *)freebsd32_cap_rights_limit, AUE_CAP_RIGHTS_LIMIT, NULL, 0, 0, 0, SY_THR_STATIC }, /* 533 = freebsd32_cap_rights_limit */ #endif + { AS(cap_rights_limit_args), (sy_call_t *)sys_cap_rights_limit, AUE_CAP_RIGHTS_LIMIT, NULL, 0, 0, 0, SY_THR_STATIC }, /* 533 = cap_rights_limit */ { AS(freebsd32_cap_ioctls_limit_args), (sy_call_t *)freebsd32_cap_ioctls_limit, AUE_CAP_IOCTLS_LIMIT, NULL, 0, 0, 0, SY_THR_STATIC }, /* 534 = freebsd32_cap_ioctls_limit */ { AS(freebsd32_cap_ioctls_get_args), (sy_call_t *)freebsd32_cap_ioctls_get, AUE_CAP_IOCTLS_GET, NULL, 0, 0, 0, SY_THR_STATIC }, /* 535 = freebsd32_cap_ioctls_get */ { AS(cap_fcntls_limit_args), (sy_call_t *)sys_cap_fcntls_limit, AUE_CAP_FCNTLS_LIMIT, NULL, 0, 0, 0, SY_THR_STATIC }, /* 536 = cap_fcntls_limit */ diff --git a/sys/compat/freebsd32/freebsd32_systrace_args.c b/sys/compat/freebsd32/freebsd32_systrace_args.c index 94ff8639ef14..7146ee45e69d 100644 --- a/sys/compat/freebsd32/freebsd32_systrace_args.c +++ b/sys/compat/freebsd32/freebsd32_systrace_args.c @@ -2990,20 +2990,13 @@ systrace_args(int sysnum, void *params, uint64_t *uarg, int *n_args) *n_args = 2; break; } - /* cap_new */ - case 514: { - struct cap_new_args *p = params; - iarg[0] = p->fd; /* int */ - uarg[1] = p->rights; /* uint64_t */ - *n_args = 2; - break; - } - /* cap_rights_get */ + /* __cap_rights_get */ case 515: { - struct cap_rights_get_args *p = params; - iarg[0] = p->fd; /* int */ - uarg[1] = (intptr_t) p->rightsp; /* uint64_t * */ - *n_args = 2; + struct __cap_rights_get_args *p = params; + iarg[0] = p->version; /* int */ + iarg[1] = p->fd; /* int */ + uarg[2] = (intptr_t) p->rightsp; /* cap_rights_t * */ + *n_args = 3; break; } /* cap_enter */ @@ -3159,16 +3152,6 @@ systrace_args(int sysnum, void *params, uint64_t *uarg, int *n_args) *n_args = 8; break; } - /* freebsd32_cap_rights_limit */ - case 533: { - struct freebsd32_cap_rights_limit_args *p = params; - iarg[0] = p->fd; /* int */ - iarg[1] = p->pad; /* int */ - uarg[2] = p->rights1; /* uint32_t */ - uarg[3] = p->rights2; /* uint32_t */ - *n_args = 4; - break; - } #else /* freebsd32_posix_fallocate */ case 530: { @@ -3206,16 +3189,15 @@ systrace_args(int sysnum, void *params, uint64_t *uarg, int *n_args) *n_args = 7; break; } - /* freebsd32_cap_rights_limit */ +#endif + /* cap_rights_limit */ case 533: { - struct freebsd32_cap_rights_limit_args *p = params; + struct cap_rights_limit_args *p = params; iarg[0] = p->fd; /* int */ - uarg[1] = p->rights1; /* uint32_t */ - uarg[2] = p->rights2; /* uint32_t */ - *n_args = 3; + uarg[1] = (intptr_t) p->rightsp; /* cap_rights_t * */ + *n_args = 2; break; } -#endif /* freebsd32_cap_ioctls_limit */ case 534: { struct freebsd32_cap_ioctls_limit_args *p = params; @@ -8277,27 +8259,17 @@ systrace_entry_setargdesc(int sysnum, int ndx, char *desc, size_t descsz) break; }; break; - /* cap_new */ - case 514: - switch(ndx) { - case 0: - p = "int"; - break; - case 1: - p = "uint64_t"; - break; - default: - break; - }; - break; - /* cap_rights_get */ + /* __cap_rights_get */ case 515: switch(ndx) { case 0: p = "int"; break; case 1: - p = "uint64_t *"; + p = "int"; + break; + case 2: + p = "cap_rights_t *"; break; default: break; @@ -8583,25 +8555,6 @@ systrace_entry_setargdesc(int sysnum, int ndx, char *desc, size_t descsz) break; }; break; - /* freebsd32_cap_rights_limit */ - case 533: - switch(ndx) { - case 0: - p = "int"; - break; - case 1: - p = "int"; - break; - case 2: - p = "uint32_t"; - break; - case 3: - p = "uint32_t"; - break; - default: - break; - }; - break; #else /* freebsd32_posix_fallocate */ case 530: @@ -8678,23 +8631,20 @@ systrace_entry_setargdesc(int sysnum, int ndx, char *desc, size_t descsz) break; }; break; - /* freebsd32_cap_rights_limit */ +#endif + /* cap_rights_limit */ case 533: switch(ndx) { case 0: p = "int"; break; case 1: - p = "uint32_t"; - break; - case 2: - p = "uint32_t"; + p = "cap_rights_t *"; break; default: break; }; break; -#endif /* freebsd32_cap_ioctls_limit */ case 534: switch(ndx) { @@ -10567,12 +10517,7 @@ systrace_return_setargdesc(int sysnum, int ndx, char *desc, size_t descsz) if (ndx == 0 || ndx == 1) p = "int"; break; - /* cap_new */ - case 514: - if (ndx == 0 || ndx == 1) - p = "int"; - break; - /* cap_rights_get */ + /* __cap_rights_get */ case 515: if (ndx == 0 || ndx == 1) p = "int"; @@ -10655,11 +10600,6 @@ systrace_return_setargdesc(int sysnum, int ndx, char *desc, size_t descsz) if (ndx == 0 || ndx == 1) p = "int"; break; - /* freebsd32_cap_rights_limit */ - case 533: - if (ndx == 0 || ndx == 1) - p = "int"; - break; #else /* freebsd32_posix_fallocate */ case 530: @@ -10676,12 +10616,12 @@ systrace_return_setargdesc(int sysnum, int ndx, char *desc, size_t descsz) if (ndx == 0 || ndx == 1) p = "int"; break; - /* freebsd32_cap_rights_limit */ +#endif + /* cap_rights_limit */ case 533: if (ndx == 0 || ndx == 1) p = "int"; break; -#endif /* freebsd32_cap_ioctls_limit */ case 534: if (ndx == 0 || ndx == 1) diff --git a/sys/compat/freebsd32/syscalls.master b/sys/compat/freebsd32/syscalls.master index a2e3e7836e6a..f537a5411a37 100644 --- a/sys/compat/freebsd32/syscalls.master +++ b/sys/compat/freebsd32/syscalls.master @@ -970,9 +970,9 @@ 512 AUE_SHMCTL NOSTD { int freebsd32_shmctl(int shmid, int cmd, \ struct shmid_ds32 *buf); } 513 AUE_LPATHCONF NOPROTO { int lpathconf(char *path, int name); } -514 AUE_CAP_NEW NOPROTO { int cap_new(int fd, uint64_t rights); } -515 AUE_CAP_RIGHTS_GET NOPROTO { int cap_rights_get(int fd, \ - uint64_t *rightsp); } +514 AUE_NULL OBSOL cap_new +515 AUE_CAP_RIGHTS_GET NOPROTO { int __cap_rights_get(int version, \ + int fd, cap_rights_t *rightsp); } 516 AUE_CAP_ENTER NOPROTO { int cap_enter(void); } 517 AUE_CAP_GETMODE NOPROTO { int cap_getmode(u_int *modep); } 518 AUE_PDFORK NOPROTO { int pdfork(int *fdp, int flags); } @@ -1016,10 +1016,6 @@ int *status, int options, \ struct wrusage32 *wrusage, \ siginfo_t *info); } -533 AUE_CAP_RIGHTS_LIMIT STD { \ - int freebsd32_cap_rights_limit(int fd, \ - int pad, \ - uint32_t rights1, uint32_t rights2); } #else 530 AUE_NULL STD { int freebsd32_posix_fallocate(int fd,\ uint32_t offset1, uint32_t offset2,\ @@ -1033,10 +1029,10 @@ int *status, int options, \ struct wrusage32 *wrusage, \ siginfo_t *info); } -533 AUE_CAP_RIGHTS_LIMIT STD { \ - int freebsd32_cap_rights_limit(int fd, \ - uint32_t rights1, uint32_t rights2); } #endif +533 AUE_CAP_RIGHTS_LIMIT NOPROTO { \ + int cap_rights_limit(int fd, \ + cap_rights_t *rightsp); } 534 AUE_CAP_IOCTLS_LIMIT STD { \ int freebsd32_cap_ioctls_limit(int fd, \ const uint32_t *cmds, size_t ncmds); } diff --git a/sys/compat/linux/linux_file.c b/sys/compat/linux/linux_file.c index 49c3fdf14d30..a6b1d35e4f19 100644 --- a/sys/compat/linux/linux_file.c +++ b/sys/compat/linux/linux_file.c @@ -92,6 +92,7 @@ linux_creat(struct thread *td, struct linux_creat_args *args) static int linux_common_open(struct thread *td, int dirfd, char *path, int l_flags, int mode) { + cap_rights_t rights; struct proc *p = td->td_proc; struct file *fp; int fd; @@ -143,7 +144,7 @@ linux_common_open(struct thread *td, int dirfd, char *path, int l_flags, int mod * having the same filedesc could use that fd without * checking below. */ - error = fget(td, fd, CAP_IOCTL, &fp); + error = fget(td, fd, cap_rights_init(&rights, CAP_IOCTL), &fp); if (!error) { sx_slock(&proctree_lock); PROC_LOCK(p); @@ -328,6 +329,7 @@ getdents_common(struct thread *td, struct linux_getdents64_args *args, caddr_t outp; /* Linux-format */ int resid, linuxreclen=0; /* Linux-format */ caddr_t lbuf; /* Linux-format */ + cap_rights_t rights; struct file *fp; struct uio auio; struct iovec aiov; @@ -348,7 +350,9 @@ getdents_common(struct thread *td, struct linux_getdents64_args *args, } else justone = 0; - if ((error = getvnode(td->td_proc->p_fd, args->fd, CAP_READ, &fp)) != 0) + error = getvnode(td->td_proc->p_fd, args->fd, + cap_rights_init(&rights, CAP_READ), &fp); + if (error != 0) return (error); if ((fp->f_flag & FREAD) == 0) { @@ -1024,6 +1028,7 @@ linux_pread(td, uap) struct linux_pread_args *uap; { struct pread_args bsd; + cap_rights_t rights; struct vnode *vp; int error; @@ -1036,7 +1041,9 @@ linux_pread(td, uap) if (error == 0) { /* This seems to violate POSIX but linux does it */ - if ((error = fgetvp(td, uap->fd, CAP_PREAD, &vp)) != 0) + error = fgetvp(td, uap->fd, + cap_rights_init(&rights, CAP_PREAD), &vp); + if (error != 0) return (error); if (vp->v_type == VDIR) { vrele(vp); @@ -1283,6 +1290,7 @@ fcntl_common(struct thread *td, struct linux_fcntl64_args *args) { struct l_flock linux_flock; struct flock bsd_flock; + cap_rights_t rights; struct file *fp; long arg; int error, result; @@ -1385,7 +1393,8 @@ fcntl_common(struct thread *td, struct linux_fcntl64_args *args) * significant effect for pipes (SIGIO is not delivered for * pipes under Linux-2.2.35 at least). */ - error = fget(td, args->fd, CAP_FCNTL, &fp); + error = fget(td, args->fd, + cap_rights_init(&rights, CAP_FCNTL), &fp); if (error) return (error); if (fp->f_type == DTYPE_PIPE) { diff --git a/sys/compat/linux/linux_ioctl.c b/sys/compat/linux/linux_ioctl.c index 4df28aab27cc..2a4016a30553 100644 --- a/sys/compat/linux/linux_ioctl.c +++ b/sys/compat/linux/linux_ioctl.c @@ -189,12 +189,14 @@ struct linux_hd_big_geometry { static int linux_ioctl_hdio(struct thread *td, struct linux_ioctl_args *args) { + cap_rights_t rights; struct file *fp; int error; u_int sectorsize, fwcylinders, fwheads, fwsectors; off_t mediasize, bytespercyl; - if ((error = fget(td, args->fd, CAP_IOCTL, &fp)) != 0) + error = fget(td, args->fd, cap_rights_init(&rights, CAP_IOCTL), &fp); + if (error != 0) return (error); switch (args->cmd & 0xffff) { case LINUX_HDIO_GET_GEO: @@ -270,12 +272,14 @@ linux_ioctl_hdio(struct thread *td, struct linux_ioctl_args *args) static int linux_ioctl_disk(struct thread *td, struct linux_ioctl_args *args) { + cap_rights_t rights; struct file *fp; int error; u_int sectorsize; off_t mediasize; - if ((error = fget(td, args->fd, CAP_IOCTL, &fp)) != 0) + error = fget(td, args->fd, cap_rights_init(&rights, CAP_IOCTL), &fp); + if (error != 0) return (error); switch (args->cmd & 0xffff) { case LINUX_BLKGETSIZE: @@ -698,10 +702,12 @@ linux_ioctl_termio(struct thread *td, struct linux_ioctl_args *args) struct termios bios; struct linux_termios lios; struct linux_termio lio; + cap_rights_t rights; struct file *fp; int error; - if ((error = fget(td, args->fd, CAP_IOCTL, &fp)) != 0) + error = fget(td, args->fd, cap_rights_init(&rights, CAP_IOCTL), &fp); + if (error != 0) return (error); switch (args->cmd & 0xffff) { @@ -1438,10 +1444,12 @@ bsd_to_linux_dvd_authinfo(struct dvd_authinfo *bp, l_dvd_authinfo *lp) static int linux_ioctl_cdrom(struct thread *td, struct linux_ioctl_args *args) { + cap_rights_t rights; struct file *fp; int error; - if ((error = fget(td, args->fd, CAP_IOCTL, &fp)) != 0) + error = fget(td, args->fd, cap_rights_init(&rights, CAP_IOCTL), &fp); + if (error != 0) return (error); switch (args->cmd & 0xffff) { @@ -1963,10 +1971,12 @@ linux_ioctl_sound(struct thread *td, struct linux_ioctl_args *args) static int linux_ioctl_console(struct thread *td, struct linux_ioctl_args *args) { + cap_rights_t rights; struct file *fp; int error; - if ((error = fget(td, args->fd, CAP_IOCTL, &fp)) != 0) + error = fget(td, args->fd, cap_rights_init(&rights, CAP_IOCTL), &fp); + if (error != 0) return (error); switch (args->cmd & 0xffff) { @@ -2351,6 +2361,7 @@ static int linux_ioctl_socket(struct thread *td, struct linux_ioctl_args *args) { char lifname[LINUX_IFNAMSIZ], ifname[IFNAMSIZ]; + cap_rights_t rights; struct ifnet *ifp; struct file *fp; int error, type; @@ -2358,7 +2369,8 @@ linux_ioctl_socket(struct thread *td, struct linux_ioctl_args *args) ifp = NULL; error = 0; - if ((error = fget(td, args->fd, CAP_IOCTL, &fp)) != 0) + error = fget(td, args->fd, cap_rights_init(&rights, CAP_IOCTL), &fp); + if (error != 0) return (error); type = fp->f_type; fdrop(fp, td); @@ -2581,10 +2593,12 @@ linux_ioctl_socket(struct thread *td, struct linux_ioctl_args *args) static int linux_ioctl_private(struct thread *td, struct linux_ioctl_args *args) { + cap_rights_t rights; struct file *fp; int error, type; - if ((error = fget(td, args->fd, CAP_IOCTL, &fp)) != 0) + error = fget(td, args->fd, cap_rights_init(&rights, CAP_IOCTL), &fp); + if (error != 0) return (error); type = fp->f_type; fdrop(fp, td); @@ -2606,11 +2620,13 @@ linux_ioctl_drm(struct thread *td, struct linux_ioctl_args *args) static int linux_ioctl_sg(struct thread *td, struct linux_ioctl_args *args) { + cap_rights_t rights; struct file *fp; u_long cmd; int error; - if ((error = fget(td, args->fd, CAP_IOCTL, &fp)) != 0) { + error = fget(td, args->fd, cap_rights_init(&rights, CAP_IOCTL), &fp); + if (error != 0) { printf("sg_linux_ioctl: fget returned %d\n", error); return (error); } @@ -2828,6 +2844,7 @@ linux_v4l_cliplist_copy(struct l_video_window *lvw, struct video_window *vw) static int linux_ioctl_v4l(struct thread *td, struct linux_ioctl_args *args) { + cap_rights_t rights; struct file *fp; int error; struct video_tuner vtun; @@ -2845,7 +2862,9 @@ linux_ioctl_v4l(struct thread *td, struct linux_ioctl_args *args) case LINUX_VIDIOCSCHAN: args->cmd = VIDIOCSCHAN; break; case LINUX_VIDIOCGTUNER: - if ((error = fget(td, args->fd, CAP_IOCTL, &fp)) != 0) + error = fget(td, args->fd, + cap_rights_init(&rights, CAP_IOCTL), &fp); + if (error != 0) return (error); error = copyin((void *) args->arg, &l_vtun, sizeof(l_vtun)); if (error) { @@ -2863,7 +2882,9 @@ linux_ioctl_v4l(struct thread *td, struct linux_ioctl_args *args) return (error); case LINUX_VIDIOCSTUNER: - if ((error = fget(td, args->fd, CAP_IOCTL, &fp)) != 0) + error = fget(td, args->fd, + cap_rights_init(&rights, CAP_IOCTL), &fp); + if (error != 0) return (error); error = copyin((void *) args->arg, &l_vtun, sizeof(l_vtun)); if (error) { @@ -2880,7 +2901,9 @@ linux_ioctl_v4l(struct thread *td, struct linux_ioctl_args *args) case LINUX_VIDIOCCAPTURE: args->cmd = VIDIOCCAPTURE; break; case LINUX_VIDIOCGWIN: - if ((error = fget(td, args->fd, CAP_IOCTL, &fp)) != 0) + error = fget(td, args->fd, + cap_rights_init(&rights, CAP_IOCTL), &fp); + if (error != 0) return (error); error = fo_ioctl(fp, VIDIOCGWIN, &vwin, td->td_ucred, td); if (!error) { @@ -2892,7 +2915,9 @@ linux_ioctl_v4l(struct thread *td, struct linux_ioctl_args *args) return (error); case LINUX_VIDIOCSWIN: - if ((error = fget(td, args->fd, CAP_IOCTL, &fp)) != 0) + error = fget(td, args->fd, + cap_rights_init(&rights, CAP_IOCTL), &fp); + if (error != 0) return (error); error = copyin((void *) args->arg, &l_vwin, sizeof(l_vwin)); if (error) { @@ -2915,7 +2940,9 @@ linux_ioctl_v4l(struct thread *td, struct linux_ioctl_args *args) return (error); case LINUX_VIDIOCGFBUF: - if ((error = fget(td, args->fd, CAP_IOCTL, &fp)) != 0) + error = fget(td, args->fd, + cap_rights_init(&rights, CAP_IOCTL), &fp); + if (error != 0) return (error); error = fo_ioctl(fp, VIDIOCGFBUF, &vbuf, td->td_ucred, td); if (!error) { @@ -2927,7 +2954,9 @@ linux_ioctl_v4l(struct thread *td, struct linux_ioctl_args *args) return (error); case LINUX_VIDIOCSFBUF: - if ((error = fget(td, args->fd, CAP_IOCTL, &fp)) != 0) + error = fget(td, args->fd, + cap_rights_init(&rights, CAP_IOCTL), &fp); + if (error != 0) return (error); error = copyin((void *) args->arg, &l_vbuf, sizeof(l_vbuf)); if (error) { @@ -2955,7 +2984,9 @@ linux_ioctl_v4l(struct thread *td, struct linux_ioctl_args *args) case LINUX_VIDIOCGPLAYINFO: args->cmd = VIDIOCGPLAYINFO; break; case LINUX_VIDIOCSMICROCODE: - if ((error = fget(td, args->fd, CAP_IOCTL, &fp)) != 0) + error = fget(td, args->fd, + cap_rights_init(&rights, CAP_IOCTL), &fp); + if (error != 0) return (error); error = copyin((void *) args->arg, &l_vcode, sizeof(l_vcode)); if (error) { @@ -3108,6 +3139,7 @@ bsd_to_linux_v4l2_format(struct v4l2_format *vf, struct l_v4l2_format *lvf) static int linux_ioctl_v4l2(struct thread *td, struct linux_ioctl_args *args) { + cap_rights_t rights; struct file *fp; int error; struct v4l2_format vformat; @@ -3199,7 +3231,9 @@ linux_ioctl_v4l2(struct thread *td, struct linux_ioctl_args *args) error = copyin((void *)args->arg, &l_vformat, sizeof(l_vformat)); if (error) return (error); - if ((error = fget(td, args->fd, CAP_IOCTL, &fp)) != 0) + error = fget(td, args->fd, + cap_rights_init(&rights, CAP_IOCTL), &fp); + if (error) return (error); if (linux_to_bsd_v4l2_format(&l_vformat, &vformat) != 0) error = EINVAL; @@ -3222,7 +3256,9 @@ linux_ioctl_v4l2(struct thread *td, struct linux_ioctl_args *args) if (error) return (error); linux_to_bsd_v4l2_standard(&l_vstd, &vstd); - if ((error = fget(td, args->fd, CAP_IOCTL, &fp)) != 0) + error = fget(td, args->fd, + cap_rights_init(&rights, CAP_IOCTL), &fp); + if (error) return (error); error = fo_ioctl(fp, VIDIOC_ENUMSTD, (caddr_t)&vstd, td->td_ucred, td); @@ -3244,7 +3280,9 @@ linux_ioctl_v4l2(struct thread *td, struct linux_ioctl_args *args) sizeof(struct l_v4l2_input)); if (error != 0) return (error); - if ((error = fget(td, args->fd, CAP_IOCTL, &fp)) != 0) + error = fget(td, args->fd, + cap_rights_init(&rights, CAP_IOCTL), &fp); + if (error != 0) return (error); error = fo_ioctl(fp, VIDIOC_ENUMINPUT, (caddr_t)&vinp, td->td_ucred, td); @@ -3263,7 +3301,9 @@ linux_ioctl_v4l2(struct thread *td, struct linux_ioctl_args *args) error = copyin((void *)args->arg, &l_vbuf, sizeof(l_vbuf)); if (error) return (error); - if ((error = fget(td, args->fd, CAP_IOCTL, &fp)) != 0) + error = fget(td, args->fd, + cap_rights_init(&rights, CAP_IOCTL), &fp); + if (error) return (error); linux_to_bsd_v4l2_buffer(&l_vbuf, &vbuf); if ((args->cmd & 0xffff) == LINUX_VIDIOC_QUERYBUF) @@ -3432,6 +3472,7 @@ linux_ioctl_fbsd_usb(struct thread *td, struct linux_ioctl_args *args) int linux_ioctl(struct thread *td, struct linux_ioctl_args *args) { + cap_rights_t rights; struct file *fp; struct handler_element *he; int error, cmd; @@ -3442,7 +3483,8 @@ linux_ioctl(struct thread *td, struct linux_ioctl_args *args) (unsigned long)args->cmd); #endif - if ((error = fget(td, args->fd, CAP_IOCTL, &fp)) != 0) + error = fget(td, args->fd, cap_rights_init(&rights, CAP_IOCTL), &fp); + if (error != 0) return (error); if ((fp->f_flag & (FREAD|FWRITE)) == 0) { fdrop(fp, td); diff --git a/sys/compat/linux/linux_misc.c b/sys/compat/linux/linux_misc.c index 378bc3728127..ac2384cd0b05 100644 --- a/sys/compat/linux/linux_misc.c +++ b/sys/compat/linux/linux_misc.c @@ -410,8 +410,8 @@ linux_uselib(struct thread *td, struct linux_uselib_args *args) /* get anon user mapping, read+write+execute */ error = vm_map_find(&td->td_proc->p_vmspace->vm_map, NULL, 0, - &vmaddr, a_out->a_text + a_out->a_data, FALSE, VM_PROT_ALL, - VM_PROT_ALL, 0); + &vmaddr, a_out->a_text + a_out->a_data, 0, VMFS_NO_SPACE, + VM_PROT_ALL, VM_PROT_ALL, 0); if (error) goto cleanup; @@ -455,7 +455,8 @@ linux_uselib(struct thread *td, struct linux_uselib_args *args) /* allocate some 'anon' space */ error = vm_map_find(&td->td_proc->p_vmspace->vm_map, NULL, 0, - &vmaddr, bss_size, FALSE, VM_PROT_ALL, VM_PROT_ALL, 0); + &vmaddr, bss_size, 0, VMFS_NO_SPACE, VM_PROT_ALL, + VM_PROT_ALL, 0); if (error) goto cleanup; } diff --git a/sys/compat/linux/linux_socket.c b/sys/compat/linux/linux_socket.c index 36b23acec4a6..22f811c50a77 100644 --- a/sys/compat/linux/linux_socket.c +++ b/sys/compat/linux/linux_socket.c @@ -748,6 +748,7 @@ int linux_connect(struct thread *, struct linux_connect_args *); int linux_connect(struct thread *td, struct linux_connect_args *args) { + cap_rights_t rights; struct socket *so; struct sockaddr *sa; u_int fflag; @@ -772,7 +773,8 @@ linux_connect(struct thread *td, struct linux_connect_args *args) * socket and use the file descriptor reference instead of * creating a new one. */ - error = fgetsock(td, args->s, CAP_CONNECT, &so, &fflag); + error = fgetsock(td, args->s, cap_rights_init(&rights, CAP_CONNECT), + &so, &fflag); if (error == 0) { error = EISCONN; if (fflag & FNONBLOCK) { diff --git a/sys/compat/svr4/imgact_svr4.c b/sys/compat/svr4/imgact_svr4.c index 69e88900622a..f3bb09e51688 100644 --- a/sys/compat/svr4/imgact_svr4.c +++ b/sys/compat/svr4/imgact_svr4.c @@ -140,8 +140,8 @@ exec_svr4_imgact(imgp) */ vmaddr = virtual_offset; error = vm_map_find(&vmspace->vm_map, NULL, 0, &vmaddr, - a_out->a_text + a_out->a_data + bss_size, FALSE, - VM_PROT_ALL, VM_PROT_ALL, 0); + a_out->a_text + a_out->a_data + bss_size, 0, VMFS_NO_SPACE, + VM_PROT_ALL, VM_PROT_ALL, 0); if (error) goto fail; @@ -204,7 +204,7 @@ exec_svr4_imgact(imgp) if (bss_size != 0) { vmaddr = virtual_offset + a_out->a_text + a_out->a_data; error = vm_map_find(&vmspace->vm_map, NULL, 0, &vmaddr, - bss_size, FALSE, VM_PROT_ALL, VM_PROT_ALL, 0); + bss_size, 0, VMFS_NO_SPACE, VM_PROT_ALL, VM_PROT_ALL, 0); if (error) goto fail; #ifdef DEBUG diff --git a/sys/compat/svr4/svr4_fcntl.c b/sys/compat/svr4/svr4_fcntl.c index 86fab788efa9..8d0b7156d251 100644 --- a/sys/compat/svr4/svr4_fcntl.c +++ b/sys/compat/svr4/svr4_fcntl.c @@ -259,6 +259,7 @@ fd_revoke(td, fd) struct vnode *vp; struct mount *mp; struct vattr vattr; + cap_rights_t rights; int error, *retval; retval = td->td_retval; @@ -267,12 +268,13 @@ fd_revoke(td, fd) * or FreeBSD grows a native frevoke() (more likely), we will need a * CAP_FREVOKE here. * - * In the meantime, use CAP_ALL: if a SVR4 process wants to + * In the meantime, use CAP_ALL(): if a SVR4 process wants to * do an frevoke(), it needs to do it on either a regular file * descriptor or a fully-privileged capability (which is effectively * the same as a non-capability-restricted file descriptor). */ - if ((error = fgetvp(td, fd, CAP_ALL, &vp)) != 0) + CAP_ALL(&rights); + if ((error = fgetvp(td, fd, &rights, &vp)) != 0) return (error); if (vp->v_type != VCHR && vp->v_type != VBLK) { @@ -318,13 +320,15 @@ fd_truncate(td, fd, flp) struct vattr vattr; int error, *retval; struct ftruncate_args ft; + cap_rights_t rights; retval = td->td_retval; /* * We only support truncating the file. */ - if ((error = fget(td, fd, CAP_FTRUNCATE, &fp)) != 0) + error = fget(td, fd, cap_rights_init(&rights, CAP_FTRUNCATE), &fp); + if (error != 0) return (error); vp = fp->f_vnode; @@ -401,9 +405,11 @@ svr4_sys_open(td, uap) if (!(bsd_flags & O_NOCTTY) && SESS_LEADER(p) && !(p->p_flag & P_CONTROLT)) { #if defined(NOTYET) - struct file *fp; + cap_rights_t rights; + struct file *fp; - error = fget(td, retval, CAP_IOCTL, &fp); + error = fget(td, retval, + cap_rights_init(&rights, CAP_IOCTL), &fp); PROC_UNLOCK(p); /* * we may have lost a race the above open() and diff --git a/sys/compat/svr4/svr4_filio.c b/sys/compat/svr4/svr4_filio.c index 0fbba0754a0c..b953e72136f9 100644 --- a/sys/compat/svr4/svr4_filio.c +++ b/sys/compat/svr4/svr4_filio.c @@ -104,6 +104,7 @@ svr4_sys_read(td, uap) struct svr4_sys_read_args *uap; { struct read_args ra; + cap_rights_t rights; struct file *fp; struct socket *so = NULL; int so_state; @@ -114,7 +115,7 @@ svr4_sys_read(td, uap) ra.buf = uap->buf; ra.nbyte = uap->nbyte; - if (fget(td, uap->fd, CAP_READ, &fp) != 0) { + if (fget(td, uap->fd, cap_rights_init(&rights, CAP_READ), &fp) != 0) { DPRINTF(("Something fishy with the user-supplied file descriptor...\n")); return EBADF; } diff --git a/sys/compat/svr4/svr4_ioctl.c b/sys/compat/svr4/svr4_ioctl.c index 36b05803821f..a8c8c8c36243 100644 --- a/sys/compat/svr4/svr4_ioctl.c +++ b/sys/compat/svr4/svr4_ioctl.c @@ -84,6 +84,7 @@ svr4_sys_ioctl(td, uap) struct svr4_sys_ioctl_args *uap; { int *retval; + cap_rights_t rights; struct file *fp; u_long cmd; int (*fun)(struct file *, struct thread *, register_t *, @@ -103,7 +104,8 @@ svr4_sys_ioctl(td, uap) retval = td->td_retval; cmd = uap->com; - if ((error = fget(td, uap->fd, CAP_IOCTL, &fp)) != 0) + error = fget(td, uap->fd, cap_rights_init(&rights, CAP_IOCTL), &fp); + if (error != 0) return (error); if ((fp->f_flag & (FREAD | FWRITE)) == 0) { diff --git a/sys/compat/svr4/svr4_misc.c b/sys/compat/svr4/svr4_misc.c index 0cfaeaebb6cc..48886987b7cb 100644 --- a/sys/compat/svr4/svr4_misc.c +++ b/sys/compat/svr4/svr4_misc.c @@ -236,6 +236,7 @@ svr4_sys_getdents64(td, uap) int len, reclen; /* BSD-format */ caddr_t outp; /* SVR4-format */ int resid, svr4reclen=0; /* SVR4-format */ + cap_rights_t rights; struct file *fp; struct uio auio; struct iovec aiov; @@ -247,7 +248,9 @@ svr4_sys_getdents64(td, uap) DPRINTF(("svr4_sys_getdents64(%d, *, %d)\n", uap->fd, uap->nbytes)); - if ((error = getvnode(td->td_proc->p_fd, uap->fd, CAP_READ, &fp)) != 0) + error = getvnode(td->td_proc->p_fd, uap->fd, + cap_rights_init(&rights, CAP_READ), &fp); + if (error != 0) return (error); if ((fp->f_flag & FREAD) == 0) { @@ -412,6 +415,7 @@ svr4_sys_getdents(td, uap) int len, reclen; /* BSD-format */ caddr_t outp; /* SVR4-format */ int resid, svr4_reclen; /* SVR4-format */ + cap_rights_t rights; struct file *fp; struct uio auio; struct iovec aiov; @@ -424,7 +428,9 @@ svr4_sys_getdents(td, uap) if (uap->nbytes < 0) return (EINVAL); - if ((error = getvnode(td->td_proc->p_fd, uap->fd, CAP_READ, &fp)) != 0) + error = getvnode(td->td_proc->p_fd, uap->fd, + cap_rights_init(&rights, CAP_READ), &fp); + if (error != 0) return (error); if ((fp->f_flag & FREAD) == 0) { diff --git a/sys/compat/svr4/svr4_stream.c b/sys/compat/svr4/svr4_stream.c index 1c7e83edb914..6348b9b51c67 100644 --- a/sys/compat/svr4/svr4_stream.c +++ b/sys/compat/svr4/svr4_stream.c @@ -1446,10 +1446,12 @@ svr4_sys_putmsg(td, uap) struct thread *td; struct svr4_sys_putmsg_args *uap; { - struct file *fp; + cap_rights_t rights; + struct file *fp; int error; - if ((error = fget(td, uap->fd, CAP_SEND, &fp)) != 0) { + error = fget(td, uap->fd, cap_rights_init(&rights, CAP_SEND), &fp); + if (error != 0) { #ifdef DEBUG_SVR4 uprintf("putmsg: bad fp\n"); #endif @@ -1618,10 +1620,12 @@ svr4_sys_getmsg(td, uap) struct thread *td; struct svr4_sys_getmsg_args *uap; { - struct file *fp; + cap_rights_t rights; + struct file *fp; int error; - if ((error = fget(td, uap->fd, CAP_RECV, &fp)) != 0) { + error = fget(td, uap->fd, cap_rights_init(&rights, CAP_RECV), &fp); + if (error != 0) { #ifdef DEBUG_SVR4 uprintf("getmsg: bad fp\n"); #endif diff --git a/sys/conf/files b/sys/conf/files index f02944ff3ac9..f790acb62faa 100644 --- a/sys/conf/files +++ b/sys/conf/files @@ -483,6 +483,16 @@ contrib/ipfilter/netinet/ip_sync.c optional ipfilter inet \ compile-with "${NORMAL_C} -I$S/contrib/ipfilter" contrib/ipfilter/netinet/mlfk_ipl.c optional ipfilter inet \ compile-with "${NORMAL_C} -I$S/contrib/ipfilter" +contrib/ipfilter/netinet/ip_nat6.c optional ipfilter inet \ + compile-with "${NORMAL_C} -I$S/contrib/ipfilter" +contrib/ipfilter/netinet/ip_rules.c optional ipfilter inet \ + compile-with "${NORMAL_C} -I$S/contrib/ipfilter" +contrib/ipfilter/netinet/ip_scan.c optional ipfilter inet \ + compile-with "${NORMAL_C} -I$S/contrib/ipfilter" +contrib/ipfilter/netinet/ip_dstlist.c optional ipfilter inet \ + compile-with "${NORMAL_C} -I$S/contrib/ipfilter" +contrib/ipfilter/netinet/radix_ipf.c optional ipfilter inet \ + compile-with "${NORMAL_C} -I$S/contrib/ipfilter" contrib/libfdt/fdt.c optional fdt contrib/libfdt/fdt_ro.c optional fdt contrib/libfdt/fdt_rw.c optional fdt @@ -2032,8 +2042,9 @@ rt2860.fw optional rt2860fw | ralfw \ clean "rt2860.fw" dev/random/harvest.c standard dev/random/hash.c optional random -dev/random/probe.c optional random +dev/random/pseudo_rng.c standard dev/random/random_adaptors.c standard +dev/random/random_harvestq.c standard dev/random/randomdev.c optional random dev/random/randomdev_soft.c optional random dev/random/yarrow.c optional random @@ -2847,6 +2858,7 @@ kern/subr_blist.c standard kern/subr_bus.c standard kern/subr_bus_dma.c standard kern/subr_bufring.c standard +kern/subr_capability.c standard kern/subr_clock.c standard kern/subr_counter.c standard kern/subr_devstat.c standard diff --git a/sys/conf/files.mips b/sys/conf/files.mips index ca8dee27a415..82d9a69e2671 100644 --- a/sys/conf/files.mips +++ b/sys/conf/files.mips @@ -38,6 +38,7 @@ mips/mips/stack_machdep.c optional ddb | stack mips/mips/stdatomic.c standard \ compile-with "${NORMAL_C:N-Wmissing-prototypes}" mips/mips/support.S standard +mips/mips/bcopy.S standard mips/mips/swtch.S standard mips/mips/sys_machdep.c standard mips/mips/tlb.c standard @@ -56,6 +57,7 @@ libkern/ffsl.c standard libkern/fls.c standard libkern/flsl.c standard libkern/memmove.c standard +libkern/cmpdi2.c optional mips | mipsel libkern/ucmpdi2.c optional mips | mipsel # cfe support diff --git a/sys/conf/files.powerpc b/sys/conf/files.powerpc index 5808d856838f..fc0663e4c1d6 100644 --- a/sys/conf/files.powerpc +++ b/sys/conf/files.powerpc @@ -30,6 +30,7 @@ dev/agp/agp_apple.c optional agp powermac dev/fb/fb.c optional sc dev/fdt/fdt_powerpc.c optional fdt dev/hwpmc/hwpmc_powerpc.c optional hwpmc +dev/hwpmc/hwpmc_mpc7xxx.c optional hwpmc dev/iicbus/ad7417.c optional ad7417 powermac dev/iicbus/ds1631.c optional ds1631 powermac dev/iicbus/ds1775.c optional ds1775 powermac diff --git a/sys/contrib/ipfilter/netinet/QNX_OCL.txt b/sys/contrib/ipfilter/netinet/QNX_OCL.txt deleted file mode 100644 index b62377679670..000000000000 --- a/sys/contrib/ipfilter/netinet/QNX_OCL.txt +++ /dev/null @@ -1,277 +0,0 @@ -$FreeBSD$ - - End User License Certificate (EULA) End User License Certificate - (EULA) - Support Support - QNX Source Licenses QNX Source Licenses - License of the month - Confidential Source License - Version 1.0 - -QNX Open Community License Version 1.0 - - THIS QNX OPEN COMMUNITY LICENSE ( "THE OCL", OR "THIS AGREEMENT") - APPLIES TO PROGRAMS THAT QNX SOFTWARE SYSTEMS LTD. ("QSS") EXPRESSLY - ELECTS TO LICENSE UNDER THE OCL TERMS. IT ALSO APPLIES TO DERIVATIVE - WORKS CREATED UNDER THIS AGREEMENT THAT CREATORS ELECT TO LICENSE TO - OTHERS IN SOURCE CODE FORM. ANY USE, REPRODUCTION, MODIFICATION OR - DISTRIBUTION OF SUCH PROGRAMS CONSTITUTES RECIPIENT'S ACCEPTANCE OF - THE OCL. THE LICENSE RIGHTS GRANTED BELOW ARE CONDITIONAL UPON - RECIPIENT'S ACCEPTANCE OF THIS AGREEMENT AND THE FORMATION OF A - BINDING CONTRACT. NOTHING ELSE GRANTS PERMISSION TO USE, REPRODUCE, - MODIFY OR DISTRIBUTE SUCH PROGRAMS OR THEIR DERIVATIVE WORKS. THESE - ACTIONS ARE OTHERWISE PROHIBITED. CONTACT QSS IF OTHER STEPS ARE - REQUIRED LOCALLY TO CREATE A BINDING CONTRACT. - - The OCL is intended to promote the development, use and distribution - of derivative works created from QSS source code. This includes - commercial distribution of object code versions under the terms of - Recipient's own license agreement and, at Recipient's option, sharing - of source code modifications within the QNX developer's community. The - license granted under the OCL is royalty free. Recipient is entitled - to charge royalties for object code versions of derivative works that - originate with Recipient. If Recipient elects to license source code - for its derivative works to others, then it must be licensed under the - OCL. The terms of the OCL are as follows: - -1. DEFINITIONS - - "Contribution" means: - - a. in the case of QSS: (i) the Original Program, where the Original - Program originates from QSS, (ii) changes and/or additions to - Unrestricted Open Source, where the Original Program originates - from Unrestricted Open Source and where such changes and/or - additions originate from QSS, and (iii) changes and/or additions - to the Program where such changes and/or additions originate from - QSS. - b. in the case of each Contributor, changes and/or additions to the - Program, where such changes and/or additions originate from and - are distributed by that particular Contributor. - - A Contribution 'originates' from a Contributor if it was added to the - Program by such Contributor itself or anyone acting on such - Contributor's behalf. Contributions do not include additions to the - Program which: (i) are separate modules of software distributed in - conjunction with the Program under their own license agreement, and - (ii) are not derivative works of the Program. - - "Contributor" means QSS and any other entity that distributes the - Program. - - "Licensed Patents " mean patent claims licensable by Contributor to - others, which are necessarily infringed by the use or sale of its - Contribution alone or when combined with the Program. - - "Unrestricted Open Source" means published source code that is - licensed for free use and distribution under an unrestricted licensing - and distribution model, such as the Berkley Software Design ("BSD") - and "BSD-like" licenses. It specifically excludes any source code - licensed under any version of the GNU General Public License (GPL) or - the GNU Lesser/Library GPL. All "Unrestricted Open Source" license - terms appear or are clearly identified in the header of any affected - source code for the Original Program. - - "Original Program" means the original version of the software - accompanying this Agreement as released by QSS, including source code, - object code and documentation, if any. - - "Program" means the Original Program and Contributions. - - "Recipient" means anyone who receives the Program under this - Agreement, including all Contributors. - -2. GRANT OF RIGHTS - - a. Subject to the terms of this Agreement, each Contributor hereby - grants Recipient a non-exclusive, worldwide, royalty-free - copyright license to reproduce, prepare derivative works of, - publicly display, publicly perform, and directly and indirectly - sublicense and distribute the Contribution of such Contributor, if - any, and such derivative works, in source code and object code - form. - b. Subject to the terms of this Agreement, each Contributor hereby - grants Recipient a non-exclusive, worldwide, royalty-free patent - license under Licensed Patents to make, use, sell, offer to sell, - import and otherwise transfer the Contribution of such - Contributor, if any, in source code and object code form. This - patent license shall apply to the combination of the Contribution - and the Program if, at the time the Contribution is added by the - Contributor, such addition of the Contribution causes such - combination to be covered by the Licensed Patents. The patent - license shall not apply to any other combinations which include - the Contribution. - c. Recipient understands that although each Contributor grants the - licenses to its Contributions set forth herein, no assurances are - provided by any Contributor that the Program does not infringe the - patent or other intellectual property rights of any other entity. - Each Contributor disclaims any liability to Recipient for claims - brought by any other entity based on infringement of intellectual - property rights or otherwise. As a condition to exercising the - rights and licenses granted hereunder, each Recipient hereby - assumes sole responsibility to secure any other intellectual - property rights needed, if any. For example, if a third party - patent license is required to allow Recipient to distribute the - Program, it is Recipient's responsibility to acquire that license - before distributing the Program. - d. Each Contributor represents that to its knowledge it has - sufficient copyright rights in its Contribution, if any, to grant - the copyright license set forth in this Agreement. - - 3. REQUIREMENTS - - A Contributor may choose to distribute the Program in object code form - under its own license agreement, provided that: - - a. it complies with the terms and conditions of this Agreement; and - b. its license agreement: - i. effectively disclaims on behalf of all Contributors all - warranties and conditions, express and implied, including - warranties or conditions of title and non-infringement, and - implied warranties or conditions of merchantability and - fitness for a particular purpose; - ii. effectively excludes on behalf of all Contributors all - liability for damages, including direct, indirect, special, - incidental and consequential damages, such as lost profits; - and - iii. states that any provisions which differ from this Agreement - are offered by that Contributor alone and not by any other - party. - - If the Program is made available in source code form: - - a. it must be made available under this Agreement; and - b. a copy of this Agreement must be included with each copy of the - Program. Each Contributor must include the following in a - conspicuous location in the Program along with any other copyright - or attribution statements required by the terms of any applicable - Unrestricted Open Source license: - Copyright {date here}, QNX Software Systems Ltd. and others. All - Rights Reserved. - - In addition, each Contributor must identify itself as the originator - of its Contribution, if any, in a manner that reasonably allows - subsequent Recipients to identify the originator of the Contribution. - - 4. COMMERCIAL DISTRIBUTION - - Commercial distributors of software may accept certain - responsibilities with respect to end users, business partners and the - like. While this license is intended to facilitate the commercial use - of the Program, the Contributor who includes the Program in a - commercial product offering should do so in a manner which does not - create potential liability for other Contributors. Therefore, if a - Contributor includes the Program in a commercial product offering, - such Contributor ("Commercial Contributor") hereby agrees to defend - and indemnify every other Contributor ("Indemnified Contributor") - against any losses, damages and costs (collectively "Losses") arising - from claims, lawsuits and other legal actions brought by a third party - against the Indemnified Contributor to the extent caused by the acts - or omissions of such Commercial Contributor in connection with its - distribution of the Program in a commercial product offering. The - obligations in this section do not apply to any claims or Losses - relating to any actual or alleged intellectual property infringement. - In order to qualify, an Indemnified Contributor must: a) promptly - notify the Commercial Contributor in writing of such claim, and b) - allow the Commercial Contributor to control, and cooperate with the - Commercial Contributor in, the defense and any related settlement - negotiations. The Indemnified Contributor may participate in any such - claim at its own expense. - - For example, a Contributor might include the Program in a commercial - product offering, Product X. That Contributor is then a Commercial - Contributor. If that Commercial Contributor then makes performance - claims, or offers warranties related to Product X, those performance - claims and warranties are such Commercial Contributor's responsibility - alone. Under this section, the Commercial Contributor would have to - defend claims against the other Contributors related to those - performance claims and warranties, and if a court requires any other - Contributor to pay any damages as a result, the Commercial Contributor - must pay those damages. - - 5. NO WARRANTY - - Recipient acknowledges that there may be errors or bugs in the Program - and that it is imperative that Recipient conduct thorough testing to - identify and correct any problems prior to the productive use or - commercial release of any products that use the Program, and prior to - the release of any modifications, updates or enhancements thereto. - - EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, THE PROGRAM IS - PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, ANY - WARRANTIES OR CONDITIONS OF TITLE, NON- INFRINGEMENT, MERCHANTABILITY - OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is solely - responsible for determining the appropriateness of using and - distributing the Program and assumes all risks associated with its - exercise of rights under this Agreement, including but not limited to - the risks and costs of program errors, compliance with applicable - laws, damage to or loss of data, programs or equipment, and - unavailability or interruption of operations. - - 6. DISCLAIMER OF LIABILITY - - EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, NEITHER RECIPIENT NOR - ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY DIRECT, INDIRECT, - INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING - WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND ON ANY THEORY OF - LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OR - DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED - HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. - - 7. GENERAL - - If any provision of this Agreement is invalid or unenforceable under - applicable law, it shall not affect the validity or enforceability of - the remainder of the terms of this Agreement, and without further - action by the parties hereto, such provision shall be reformed to the - minimum extent necessary to make such provision valid and enforceable. - - If Recipient institutes patent litigation against a Contributor with - respect to a patent applicable to software (including a cross-claim or - counterclaim in a lawsuit), then any patent licenses granted by that - Contributor to such recipient under this Agreement shall terminate as - of the date such litigation is filed. In addition, If Recipient - institutes patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Program - itself (excluding combinations of the Program with other software or - hardware) infringes such Recipient's patent(s), then such Recipient's - rights granted under Section 2(b) shall terminate as of the date such - litigation is filed. - - All Recipient's rights under this Agreement shall terminate if it - fails to comply with any of the material terms or conditions of this - Agreement and does not cure such failure in a reasonable period of - time after becoming aware of such noncompliance. If all Recipient's - rights under this Agreement terminate, Recipient agrees to cease use - and distribution of the Program as soon as reasonably practicable. - However, Recipient's obligations under this Agreement and any licenses - granted by Recipient relating to the Program shall continue and - survive. - - QSS may publish new versions (including revisions) of this Agreement - from time to time. Each new version of the Agreement will be given a - distinguishing version number. The Program (including Contributions) - may always be distributed subject to the version of the Agreement - under which it was received. In addition, after a new version of the - Agreement is published, Contributor may elect to distribute the - Program (including its Contributions) under the new version. No one - other than QSS has the right to modify this Agreement. Except as - expressly stated in Sections 2(a) and 2(b) above, Recipient receives - no rights or licenses to the intellectual property of any Contributor - under this Agreement, whether expressly, by implication, estoppel or - otherwise. All rights in the Program not expressly granted under this - Agreement are reserved. - - This Agreement is governed by the laws in force in the Province of - Ontario, Canada without regard to the conflict of law provisions - therein. The parties expressly disclaim the provisions of the United - Nations Convention on Contracts for the International Sale of Goods. - No party to this Agreement will bring a legal action under this - Agreement more than one year after the cause of action arose. Each - party waives its rights to a jury trial in any resulting litigation. - - * QNX is a registered trademark of QNX Software Systems Ltd. - - Document Version: ocl1_00 diff --git a/sys/contrib/ipfilter/netinet/fil.c b/sys/contrib/ipfilter/netinet/fil.c index e8e543a10836..2adfe26bdd23 100644 --- a/sys/contrib/ipfilter/netinet/fil.c +++ b/sys/contrib/ipfilter/netinet/fil.c @@ -1,9 +1,14 @@ /* $FreeBSD$ */ /* - * Copyright (C) 1993-2003 by Darren Reed. + * Copyright (C) 2012 by Darren Reed. * * See the IPFILTER.LICENCE file for details on licencing. + * + * Copyright 2008 Sun Microsystems. + * + * $Id$ + * */ #if defined(KERNEL) || defined(_KERNEL) # undef KERNEL @@ -15,15 +20,6 @@ #include #include #include -#if defined(__NetBSD__) -# if (NetBSD >= 199905) && !defined(IPFILTER_LKM) && defined(_KERNEL) -# if (__NetBSD_Version__ < 301000000) -# include "opt_ipfilter_log.h" -# else -# include "opt_ipfilter.h" -# endif -# endif -#endif #if defined(_KERNEL) && defined(__FreeBSD_version) && \ (__FreeBSD_version >= 220000) # if (__FreeBSD_version >= 400000) @@ -82,23 +78,9 @@ struct file; #ifdef sun # include #endif -#if !defined(_KERNEL) && (defined(__FreeBSD__) || defined(SOLARIS2)) -# if (__FreeBSD_version >= 504000) -# undef _RADIX_H_ -# endif -# include "radix_ipf.h" -#endif -#ifdef __osf__ -# include "radix_ipf.h" -#else -# include -#endif #include #include #include -#if !defined(linux) -# include -#endif #if defined(__sgi) && defined(IFF_DRVRLOCK) /* IRIX 6 */ # include # include @@ -121,7 +103,6 @@ struct file; # include # endif #endif -#include #include "netinet/ip_fil.h" #include "netinet/ip_nat.h" #include "netinet/ip_frag.h" @@ -131,9 +112,8 @@ struct file; #ifdef IPFILTER_SCAN # include "netinet/ip_scan.h" #endif -#ifdef IPFILTER_SYNC -# include "netinet/ip_sync.h" -#endif +#include "netinet/ip_sync.h" +#include "netinet/ip_lookup.h" #include "netinet/ip_pool.h" #include "netinet/ip_htable.h" #ifdef IPFILTER_COMPILED @@ -144,14 +124,18 @@ struct file; #endif #if defined(__FreeBSD_version) && (__FreeBSD_version >= 300000) # include -# if defined(_KERNEL) && !defined(IPFILTER_LKM) -# include "opt_ipfilter.h" -# endif #endif #include "netinet/ipl.h" -/* END OF INCLUDES */ -#include +#if defined(__NetBSD__) && (__NetBSD_Version__ >= 104230000) +# include +extern struct callout ipf_slowtimer_ch; +#endif +#if defined(__OpenBSD__) +# include +extern struct timeout ipf_slowtimer_ch; +#endif +/* END OF INCLUDES */ #if !defined(lint) static const char sccsid[] = "@(#)fil.c 1.36 6/5/96 (C) 1993-2000 Darren Reed"; @@ -162,101 +146,80 @@ static const char rcsid[] = "@(#)$FreeBSD$"; #ifndef _KERNEL # include "ipf.h" # include "ipt.h" -# include "bpf-ipf.h" extern int opts; +extern int blockreason; #endif /* _KERNEL */ +#define LBUMP(x) softc->x++ +#define LBUMPD(x, y) do { softc->x.y++; DT(y); } while (0) -fr_info_t frcache[2][8]; -struct filterstats frstats[2]; -struct frentry *ipfilter[2][2] = { { NULL, NULL }, { NULL, NULL } }, - *ipfilter6[2][2] = { { NULL, NULL }, { NULL, NULL } }, - *ipacct6[2][2] = { { NULL, NULL }, { NULL, NULL } }, - *ipacct[2][2] = { { NULL, NULL }, { NULL, NULL } }, - *ipnatrules[2][2] = { { NULL, NULL }, { NULL, NULL } }; -struct frgroup *ipfgroups[IPL_LOGSIZE][2]; -char ipfilter_version[] = IPL_VERSION; -int fr_refcnt = 0; -/* - * For fr_running: - * 0 == loading, 1 = running, -1 = disabled, -2 = unloading - */ -int fr_running = 0; -int fr_flags = IPF_LOGGING; -int fr_active = 0; -int fr_control_forwarding = 0; -int fr_update_ipid = 0; -u_short fr_ip_id = 0; -int fr_chksrc = 0; /* causes a system crash if enabled */ -int fr_minttl = 4; -int fr_icmpminfragmtu = 68; -u_long fr_frouteok[2] = {0, 0}; -u_long fr_userifqs = 0; -u_long fr_badcoalesces[2] = {0, 0}; -u_char ipf_iss_secret[32]; -#if defined(IPFILTER_DEFAULT_BLOCK) -int fr_pass = FR_BLOCK|FR_NOMATCH; -#else -int fr_pass = (IPF_DEFAULT_PASS)|FR_NOMATCH; +static INLINE int ipf_check_ipf __P((fr_info_t *, frentry_t *, int)); +static u_32_t ipf_checkcipso __P((fr_info_t *, u_char *, int)); +static u_32_t ipf_checkripso __P((u_char *)); +static u_32_t ipf_decaps __P((fr_info_t *, u_32_t, int)); +#ifdef IPFILTER_LOG +static frentry_t *ipf_dolog __P((fr_info_t *, u_32_t *)); #endif -int fr_features = 0 -#ifdef IPFILTER_LKM - | IPF_FEAT_LKM +static int ipf_flushlist __P((ipf_main_softc_t *, int *, + frentry_t **)); +static int ipf_flush_groups __P((ipf_main_softc_t *, frgroup_t **, + int)); +static ipfunc_t ipf_findfunc __P((ipfunc_t)); +static void *ipf_findlookup __P((ipf_main_softc_t *, int, + frentry_t *, + i6addr_t *, i6addr_t *)); +static frentry_t *ipf_firewall __P((fr_info_t *, u_32_t *)); +static int ipf_fr_matcharray __P((fr_info_t *, int *)); +static int ipf_frruleiter __P((ipf_main_softc_t *, void *, int, + void *)); +static void ipf_funcfini __P((ipf_main_softc_t *, frentry_t *)); +static int ipf_funcinit __P((ipf_main_softc_t *, frentry_t *)); +static int ipf_geniter __P((ipf_main_softc_t *, ipftoken_t *, + ipfgeniter_t *)); +static void ipf_getstat __P((ipf_main_softc_t *, + struct friostat *, int)); +static int ipf_group_flush __P((ipf_main_softc_t *, frgroup_t *)); +static void ipf_group_free __P((frgroup_t *)); +static int ipf_grpmapfini __P((struct ipf_main_softc_s *, + frentry_t *)); +static int ipf_grpmapinit __P((struct ipf_main_softc_s *, + frentry_t *)); +static frentry_t *ipf_nextrule __P((ipf_main_softc_t *, int, int, + frentry_t *, int)); +static int ipf_portcheck __P((frpcmp_t *, u_32_t)); +static INLINE int ipf_pr_ah __P((fr_info_t *)); +static INLINE void ipf_pr_esp __P((fr_info_t *)); +static INLINE void ipf_pr_gre __P((fr_info_t *)); +static INLINE void ipf_pr_udp __P((fr_info_t *)); +static INLINE void ipf_pr_tcp __P((fr_info_t *)); +static INLINE void ipf_pr_icmp __P((fr_info_t *)); +static INLINE void ipf_pr_ipv4hdr __P((fr_info_t *)); +static INLINE void ipf_pr_short __P((fr_info_t *, int)); +static INLINE int ipf_pr_tcpcommon __P((fr_info_t *)); +static INLINE int ipf_pr_udpcommon __P((fr_info_t *)); +static void ipf_rule_delete __P((ipf_main_softc_t *, frentry_t *f, + int, int)); +static void ipf_rule_expire_insert __P((ipf_main_softc_t *, + frentry_t *, int)); +static int ipf_synclist __P((ipf_main_softc_t *, frentry_t *, + void *)); +static void ipf_token_flush __P((ipf_main_softc_t *)); +static void ipf_token_unlink __P((ipf_main_softc_t *, + ipftoken_t *)); +static ipftuneable_t *ipf_tune_findbyname __P((ipftuneable_t *, + const char *)); +static ipftuneable_t *ipf_tune_findbycookie __P((ipftuneable_t **, void *, + void **)); +static int ipf_updateipid __P((fr_info_t *)); +static int ipf_settimeout __P((struct ipf_main_softc_s *, + struct ipftuneable *, + ipftuneval_t *)); +#if !defined(_KERNEL) || (!defined(__NetBSD__) && !defined(__OpenBSD__) && \ + !defined(__FreeBSD__)) || \ + FREEBSD_LT_REV(501000) || NETBSD_LT_REV(105000000) || \ + OPENBSD_LT_REV(200006) +static int ppsratecheck(struct timeval *, int *, int); #endif -#ifdef IPFILTER_LOG - | IPF_FEAT_LOG -#endif -#ifdef IPFILTER_LOOKUP - | IPF_FEAT_LOOKUP -#endif -#ifdef IPFILTER_BPF - | IPF_FEAT_BPF -#endif -#ifdef IPFILTER_COMPILED - | IPF_FEAT_COMPILED -#endif -#ifdef IPFILTER_CKSUM - | IPF_FEAT_CKSUM -#endif -#ifdef IPFILTER_SYNC - | IPF_FEAT_SYNC -#endif -#ifdef IPFILTER_SCAN - | IPF_FEAT_SCAN -#endif -#ifdef USE_INET6 - | IPF_FEAT_IPV6 -#endif - ; - -static INLINE int fr_ipfcheck __P((fr_info_t *, frentry_t *, int)); -static int fr_portcheck __P((frpcmp_t *, u_short *)); -static int frflushlist __P((int, minor_t, int *, frentry_t **)); -static ipfunc_t fr_findfunc __P((ipfunc_t)); -static frentry_t *fr_firewall __P((fr_info_t *, u_32_t *)); -static int fr_funcinit __P((frentry_t *fr)); -static INLINE void frpr_ah __P((fr_info_t *)); -static INLINE void frpr_esp __P((fr_info_t *)); -static INLINE void frpr_gre __P((fr_info_t *)); -static INLINE void frpr_udp __P((fr_info_t *)); -static INLINE void frpr_tcp __P((fr_info_t *)); -static INLINE void frpr_icmp __P((fr_info_t *)); -static INLINE void frpr_ipv4hdr __P((fr_info_t *)); -static INLINE int frpr_pullup __P((fr_info_t *, int)); -static INLINE void frpr_short __P((fr_info_t *, int)); -static INLINE int frpr_tcpcommon __P((fr_info_t *)); -static INLINE int frpr_udpcommon __P((fr_info_t *)); -static int fr_updateipid __P((fr_info_t *)); -#ifdef IPFILTER_LOOKUP -static int fr_grpmapinit __P((frentry_t *fr)); -static INLINE void *fr_resolvelookup __P((u_int, u_int, i6addr_t *, lookupfunc_t *)); -#endif -static void frsynclist __P((frentry_t *, void *)); -static ipftuneable_t *fr_findtunebyname __P((const char *)); -static ipftuneable_t *fr_findtunebycookie __P((void *, void **)); -static int ipf_geniter __P((ipftoken_t *, ipfgeniter_t *)); -static int ipf_frruleiter __P((void *, int, void *)); -static void ipf_unlinktoken __P((ipftoken_t *)); /* @@ -265,7 +228,7 @@ static void ipf_unlinktoken __P((ipftoken_t *)); * hand side to allow for binary searching of the array and include a trailer * with a 0 for the bitmask for linear searches to easily find the end with. */ -const struct optlist ipopts[20] = { +static const struct optlist ipopts[20] = { { IPOPT_NOP, 0x000001 }, { IPOPT_RR, 0x000002 }, { IPOPT_ZSU, 0x000004 }, @@ -289,7 +252,7 @@ const struct optlist ipopts[20] = { }; #ifdef USE_INET6 -struct optlist ip6exthdr[] = { +static struct optlist ip6exthdr[] = { { IPPROTO_HOPOPTS, 0x000001 }, { IPPROTO_IPV6, 0x000002 }, { IPPROTO_ROUTING, 0x000004 }, @@ -303,20 +266,10 @@ struct optlist ip6exthdr[] = { }; #endif -struct optlist tcpopts[] = { - { TCPOPT_NOP, 0x000001 }, - { TCPOPT_MAXSEG, 0x000002 }, - { TCPOPT_WINDOW, 0x000004 }, - { TCPOPT_SACK_PERMITTED, 0x000008 }, - { TCPOPT_SACK, 0x000010 }, - { TCPOPT_TIMESTAMP, 0x000020 }, - { 0, 0x000000 } -}; - /* * bit values for identifying presence of individual IP security options */ -const struct optlist secopt[8] = { +static const struct optlist secopt[8] = { { IPSO_CLASS_RES4, 0x01 }, { IPSO_CLASS_TOPS, 0x02 }, { IPSO_CLASS_SECR, 0x04 }, @@ -327,16 +280,143 @@ const struct optlist secopt[8] = { { IPSO_CLASS_RES1, 0x80 } }; +char ipfilter_version[] = IPL_VERSION; + +int ipf_features = 0 +#ifdef IPFILTER_LKM + | IPF_FEAT_LKM +#endif +#ifdef IPFILTER_LOG + | IPF_FEAT_LOG +#endif + | IPF_FEAT_LOOKUP +#ifdef IPFILTER_BPF + | IPF_FEAT_BPF +#endif +#ifdef IPFILTER_COMPILED + | IPF_FEAT_COMPILED +#endif +#ifdef IPFILTER_CKSUM + | IPF_FEAT_CKSUM +#endif + | IPF_FEAT_SYNC +#ifdef IPFILTER_SCAN + | IPF_FEAT_SCAN +#endif +#ifdef USE_INET6 + | IPF_FEAT_IPV6 +#endif + ; + /* * Table of functions available for use with call rules. */ -static ipfunc_resolve_t fr_availfuncs[] = { -#ifdef IPFILTER_LOOKUP - { "fr_srcgrpmap", fr_srcgrpmap, fr_grpmapinit }, - { "fr_dstgrpmap", fr_dstgrpmap, fr_grpmapinit }, +static ipfunc_resolve_t ipf_availfuncs[] = { + { "srcgrpmap", ipf_srcgrpmap, ipf_grpmapinit, ipf_grpmapfini }, + { "dstgrpmap", ipf_dstgrpmap, ipf_grpmapinit, ipf_grpmapfini }, + { "", NULL, NULL, NULL } +}; + +static ipftuneable_t ipf_main_tuneables[] = { + { { (void *)offsetof(struct ipf_main_softc_s, ipf_flags) }, + "ipf_flags", 0, 0xffffffff, + stsizeof(ipf_main_softc_t, ipf_flags), + 0, NULL, NULL }, + { { (void *)offsetof(struct ipf_main_softc_s, ipf_active) }, + "active", 0, 0, + stsizeof(ipf_main_softc_t, ipf_active), + IPFT_RDONLY, NULL, NULL }, + { { (void *)offsetof(ipf_main_softc_t, ipf_control_forwarding) }, + "control_forwarding", 0, 1, + stsizeof(ipf_main_softc_t, ipf_control_forwarding), + 0, NULL, NULL }, + { { (void *)offsetof(ipf_main_softc_t, ipf_update_ipid) }, + "update_ipid", 0, 1, + stsizeof(ipf_main_softc_t, ipf_update_ipid), + 0, NULL, NULL }, + { { (void *)offsetof(ipf_main_softc_t, ipf_chksrc) }, + "chksrc", 0, 1, + stsizeof(ipf_main_softc_t, ipf_chksrc), + 0, NULL, NULL }, + { { (void *)offsetof(ipf_main_softc_t, ipf_minttl) }, + "min_ttl", 0, 1, + stsizeof(ipf_main_softc_t, ipf_minttl), + 0, NULL, NULL }, + { { (void *)offsetof(ipf_main_softc_t, ipf_icmpminfragmtu) }, + "icmp_minfragmtu", 0, 1, + stsizeof(ipf_main_softc_t, ipf_icmpminfragmtu), + 0, NULL, NULL }, + { { (void *)offsetof(ipf_main_softc_t, ipf_pass) }, + "default_pass", 0, 0xffffffff, + stsizeof(ipf_main_softc_t, ipf_pass), + 0, NULL, NULL }, + { { (void *)offsetof(ipf_main_softc_t, ipf_tcpidletimeout) }, + "tcp_idle_timeout", 1, 0x7fffffff, + stsizeof(ipf_main_softc_t, ipf_tcpidletimeout), + 0, NULL, ipf_settimeout }, + { { (void *)offsetof(ipf_main_softc_t, ipf_tcpclosewait) }, + "tcp_close_wait", 1, 0x7fffffff, + stsizeof(ipf_main_softc_t, ipf_tcpclosewait), + 0, NULL, ipf_settimeout }, + { { (void *)offsetof(ipf_main_softc_t, ipf_tcplastack) }, + "tcp_last_ack", 1, 0x7fffffff, + stsizeof(ipf_main_softc_t, ipf_tcplastack), + 0, NULL, ipf_settimeout }, + { { (void *)offsetof(ipf_main_softc_t, ipf_tcptimeout) }, + "tcp_timeout", 1, 0x7fffffff, + stsizeof(ipf_main_softc_t, ipf_tcptimeout), + 0, NULL, ipf_settimeout }, + { { (void *)offsetof(ipf_main_softc_t, ipf_tcpsynsent) }, + "tcp_syn_sent", 1, 0x7fffffff, + stsizeof(ipf_main_softc_t, ipf_tcpsynsent), + 0, NULL, ipf_settimeout }, + { { (void *)offsetof(ipf_main_softc_t, ipf_tcpsynrecv) }, + "tcp_syn_received", 1, 0x7fffffff, + stsizeof(ipf_main_softc_t, ipf_tcpsynrecv), + 0, NULL, ipf_settimeout }, + { { (void *)offsetof(ipf_main_softc_t, ipf_tcpclosed) }, + "tcp_closed", 1, 0x7fffffff, + stsizeof(ipf_main_softc_t, ipf_tcpclosed), + 0, NULL, ipf_settimeout }, + { { (void *)offsetof(ipf_main_softc_t, ipf_tcphalfclosed) }, + "tcp_half_closed", 1, 0x7fffffff, + stsizeof(ipf_main_softc_t, ipf_tcphalfclosed), + 0, NULL, ipf_settimeout }, + { { (void *)offsetof(ipf_main_softc_t, ipf_tcptimewait) }, + "tcp_time_wait", 1, 0x7fffffff, + stsizeof(ipf_main_softc_t, ipf_tcptimewait), + 0, NULL, ipf_settimeout }, + { { (void *)offsetof(ipf_main_softc_t, ipf_udptimeout) }, + "udp_timeout", 1, 0x7fffffff, + stsizeof(ipf_main_softc_t, ipf_udptimeout), + 0, NULL, ipf_settimeout }, + { { (void *)offsetof(ipf_main_softc_t, ipf_udpacktimeout) }, + "udp_ack_timeout", 1, 0x7fffffff, + stsizeof(ipf_main_softc_t, ipf_udpacktimeout), + 0, NULL, ipf_settimeout }, + { { (void *)offsetof(ipf_main_softc_t, ipf_icmptimeout) }, + "icmp_timeout", 1, 0x7fffffff, + stsizeof(ipf_main_softc_t, ipf_icmptimeout), + 0, NULL, ipf_settimeout }, + { { (void *)offsetof(ipf_main_softc_t, ipf_icmpacktimeout) }, + "icmp_ack_timeout", 1, 0x7fffffff, + stsizeof(ipf_main_softc_t, ipf_icmpacktimeout), + 0, NULL, ipf_settimeout }, + { { (void *)offsetof(ipf_main_softc_t, ipf_iptimeout) }, + "ip_timeout", 1, 0x7fffffff, + stsizeof(ipf_main_softc_t, ipf_iptimeout), + 0, NULL, ipf_settimeout }, +#if defined(INSTANCES) && defined(_KERNEL) + { { (void *)offsetof(ipf_main_softc_t, ipf_get_loopback) }, + "intercept_loopback", 0, 1, + stsizeof(ipf_main_softc_t, ipf_get_loopback), + 0, NULL, ipf_set_loopback }, #endif - { "", NULL, NULL } + { { 0 }, + NULL, 0, 0, + 0, + 0, NULL, NULL } }; @@ -346,39 +426,41 @@ static ipfunc_resolve_t fr_availfuncs[] = { * current packet. There are different routines for the same protocol * for each of IPv4 and IPv6. Adding a new protocol, for which there * will "special" inspection for setup, is now more easily done by adding - * a new routine and expanding the frpr_ipinit*() function rather than by + * a new routine and expanding the ipf_pr_ipinit*() function rather than by * adding more code to a growing switch statement. */ #ifdef USE_INET6 -static INLINE int frpr_ah6 __P((fr_info_t *)); -static INLINE void frpr_esp6 __P((fr_info_t *)); -static INLINE void frpr_gre6 __P((fr_info_t *)); -static INLINE void frpr_udp6 __P((fr_info_t *)); -static INLINE void frpr_tcp6 __P((fr_info_t *)); -static INLINE void frpr_icmp6 __P((fr_info_t *)); -static INLINE int frpr_ipv6hdr __P((fr_info_t *)); -static INLINE void frpr_short6 __P((fr_info_t *, int)); -static INLINE int frpr_hopopts6 __P((fr_info_t *)); -static INLINE int frpr_mobility6 __P((fr_info_t *)); -static INLINE int frpr_routing6 __P((fr_info_t *)); -static INLINE int frpr_dstopts6 __P((fr_info_t *)); -static INLINE int frpr_fragment6 __P((fr_info_t *)); -static INLINE int frpr_ipv6exthdr __P((fr_info_t *, int, int)); +static INLINE int ipf_pr_ah6 __P((fr_info_t *)); +static INLINE void ipf_pr_esp6 __P((fr_info_t *)); +static INLINE void ipf_pr_gre6 __P((fr_info_t *)); +static INLINE void ipf_pr_udp6 __P((fr_info_t *)); +static INLINE void ipf_pr_tcp6 __P((fr_info_t *)); +static INLINE void ipf_pr_icmp6 __P((fr_info_t *)); +static INLINE void ipf_pr_ipv6hdr __P((fr_info_t *)); +static INLINE void ipf_pr_short6 __P((fr_info_t *, int)); +static INLINE int ipf_pr_hopopts6 __P((fr_info_t *)); +static INLINE int ipf_pr_mobility6 __P((fr_info_t *)); +static INLINE int ipf_pr_routing6 __P((fr_info_t *)); +static INLINE int ipf_pr_dstopts6 __P((fr_info_t *)); +static INLINE int ipf_pr_fragment6 __P((fr_info_t *)); +static INLINE struct ip6_ext *ipf_pr_ipv6exthdr __P((fr_info_t *, int, int)); /* ------------------------------------------------------------------------ */ -/* Function: frpr_short6 */ +/* Function: ipf_pr_short6 */ /* Returns: void */ -/* Parameters: fin(I) - pointer to packet information */ +/* Parameters: fin(I) - pointer to packet information */ +/* xmin(I) - minimum header size */ /* */ /* IPv6 Only */ /* This is function enforces the 'is a packet too short to be legit' rule */ /* for IPv6 and marks the packet with FI_SHORT if so. See function comment */ -/* for frpr_short() for more details. */ +/* for ipf_pr_short() for more details. */ /* ------------------------------------------------------------------------ */ -static INLINE void frpr_short6(fin, xmin) -fr_info_t *fin; -int xmin; +static INLINE void +ipf_pr_short6(fin, xmin) + fr_info_t *fin; + int xmin; { if (fin->fin_dlen < xmin) @@ -387,8 +469,8 @@ int xmin; /* ------------------------------------------------------------------------ */ -/* Function: frpr_ipv6hdr */ -/* Returns: int - 0 = IPv6 packet intact, -1 = packet lost */ +/* Function: ipf_pr_ipv6hdr */ +/* Returns: void */ /* Parameters: fin(I) - pointer to packet information */ /* */ /* IPv6 Only */ @@ -397,8 +479,9 @@ int xmin; /* analyzer may pullup or free the packet itself so we need to be vigiliant */ /* of that possibility arising. */ /* ------------------------------------------------------------------------ */ -static INLINE int frpr_ipv6hdr(fin) -fr_info_t *fin; +static INLINE void +ipf_pr_ipv6hdr(fin) + fr_info_t *fin; { ip6_t *ip6 = (ip6_t *)fin->fin_ip; int p, go = 1, i, hdrcount; @@ -412,57 +495,68 @@ fr_info_t *fin; fi->fi_auth = 0; p = ip6->ip6_nxt; + fin->fin_crc = p; fi->fi_ttl = ip6->ip6_hlim; fi->fi_src.in6 = ip6->ip6_src; + fin->fin_crc += fi->fi_src.i6[0]; + fin->fin_crc += fi->fi_src.i6[1]; + fin->fin_crc += fi->fi_src.i6[2]; + fin->fin_crc += fi->fi_src.i6[3]; fi->fi_dst.in6 = ip6->ip6_dst; - fin->fin_id = (u_short)(ip6->ip6_flow & 0xffff); + fin->fin_crc += fi->fi_dst.i6[0]; + fin->fin_crc += fi->fi_dst.i6[1]; + fin->fin_crc += fi->fi_dst.i6[2]; + fin->fin_crc += fi->fi_dst.i6[3]; + fin->fin_id = 0; + if (IN6_IS_ADDR_MULTICAST(&fi->fi_dst.in6)) + fin->fin_flx |= FI_MULTICAST|FI_MBCAST; hdrcount = 0; - while (go && !(fin->fin_flx & (FI_BAD|FI_SHORT))) { + while (go && !(fin->fin_flx & FI_SHORT)) { switch (p) { case IPPROTO_UDP : - frpr_udp6(fin); + ipf_pr_udp6(fin); go = 0; break; case IPPROTO_TCP : - frpr_tcp6(fin); + ipf_pr_tcp6(fin); go = 0; break; case IPPROTO_ICMPV6 : - frpr_icmp6(fin); + ipf_pr_icmp6(fin); go = 0; break; case IPPROTO_GRE : - frpr_gre6(fin); + ipf_pr_gre6(fin); go = 0; break; case IPPROTO_HOPOPTS : - p = frpr_hopopts6(fin); + p = ipf_pr_hopopts6(fin); break; case IPPROTO_MOBILITY : - p = frpr_mobility6(fin); + p = ipf_pr_mobility6(fin); break; case IPPROTO_DSTOPTS : - p = frpr_dstopts6(fin); + p = ipf_pr_dstopts6(fin); break; case IPPROTO_ROUTING : - p = frpr_routing6(fin); + p = ipf_pr_routing6(fin); break; case IPPROTO_AH : - p = frpr_ah6(fin); + p = ipf_pr_ah6(fin); break; case IPPROTO_ESP : - frpr_esp6(fin); + ipf_pr_esp6(fin); go = 0; break; @@ -480,7 +574,13 @@ fr_info_t *fin; break; case IPPROTO_FRAGMENT : - p = frpr_fragment6(fin); + p = ipf_pr_fragment6(fin); + /* + * Given that the only fragments we want to let through + * (where fin_off != 0) are those where the non-first + * fragments only have data, we can safely stop looking + * at headers if this is a non-leading fragment. + */ if (fin->fin_off != 0) go = 0; break; @@ -501,39 +601,61 @@ fr_info_t *fin; * header. */ if ((go != 0) && (p != IPPROTO_NONE) && - (frpr_pullup(fin, 0) == -1)) { + (ipf_pr_pullup(fin, 0) == -1)) { p = IPPROTO_NONE; - go = 0; + break; } } + + /* + * Some of the above functions, like ipf_pr_esp6(), can call ipf_pullup + * and destroy whatever packet was here. The caller of this function + * expects us to return if there is a problem with ipf_pullup. + */ + if (fin->fin_m == NULL) { + ipf_main_softc_t *softc = fin->fin_main_soft; + + LBUMPD(ipf_stats[fin->fin_out], fr_v6_bad); + return; + } + fi->fi_p = p; /* - * Some of the above functions, like frpr_esp6(), can call fr_pullup - * and destroy whatever packet was here. The caller of this function - * expects us to return -1 if there is a problem with fr_pullup. + * IPv6 fragment case 1 - see comment for ipf_pr_fragment6(). + * "go != 0" imples the above loop hasn't arrived at a layer 4 header. */ - if (fin->fin_m == NULL) - return -1; + if ((go != 0) && (fin->fin_flx & FI_FRAG) && (fin->fin_off == 0)) { + ipf_main_softc_t *softc = fin->fin_main_soft; - return 0; + fin->fin_flx |= FI_BAD; + LBUMPD(ipf_stats[fin->fin_out], fr_v6_badfrag); + LBUMP(ipf_stats[fin->fin_out].fr_v6_bad); + } } /* ------------------------------------------------------------------------ */ -/* Function: frpr_ipv6exthdr */ -/* Returns: int - value of the next header or IPPROTO_NONE if error */ +/* Function: ipf_pr_ipv6exthdr */ +/* Returns: struct ip6_ext * - pointer to the start of the next header */ +/* or NULL if there is a prolblem. */ /* Parameters: fin(I) - pointer to packet information */ /* multiple(I) - flag indicating yes/no if multiple occurances */ /* of this extension header are allowed. */ /* proto(I) - protocol number for this extension header */ /* */ /* IPv6 Only */ +/* This function embodies a number of common checks that all IPv6 extension */ +/* headers must be subjected to. For example, making sure the packet is */ +/* big enough for it to be in, checking if it is repeated and setting a */ +/* flag to indicate its presence. */ /* ------------------------------------------------------------------------ */ -static INLINE int frpr_ipv6exthdr(fin, multiple, proto) -fr_info_t *fin; -int multiple, proto; +static INLINE struct ip6_ext * +ipf_pr_ipv6exthdr(fin, multiple, proto) + fr_info_t *fin; + int multiple, proto; { + ipf_main_softc_t *softc = fin->fin_main_soft; struct ip6_ext *hdr; u_short shift; int i; @@ -543,11 +665,14 @@ int multiple, proto; /* 8 is default length of extension hdr */ if ((fin->fin_dlen - 8) < 0) { fin->fin_flx |= FI_SHORT; - return IPPROTO_NONE; + LBUMPD(ipf_stats[fin->fin_out], fr_v6_ext_short); + return NULL; } - if (frpr_pullup(fin, 8) == -1) - return IPPROTO_NONE; + if (ipf_pr_pullup(fin, 8) == -1) { + LBUMPD(ipf_stats[fin->fin_out], fr_v6_ext_pullup); + return NULL; + } hdr = fin->fin_dp; switch (proto) @@ -562,9 +687,21 @@ int multiple, proto; if (shift > fin->fin_dlen) { /* Nasty extension header length? */ fin->fin_flx |= FI_BAD; - return IPPROTO_NONE; + LBUMPD(ipf_stats[fin->fin_out], fr_v6_ext_hlen); + return NULL; } + fin->fin_dp = (char *)fin->fin_dp + shift; + fin->fin_dlen -= shift; + + /* + * If we have seen a fragment header, do not set any flags to indicate + * the presence of this extension header as it has no impact on the + * end result until after it has been defragmented. + */ + if (fin->fin_flx & FI_FRAG) + return hdr; + for (i = 0; ip6exthdr[i].ol_bit != 0; i++) if (ip6exthdr[i].ol_val == proto) { /* @@ -578,149 +715,196 @@ int multiple, proto; break; } - fin->fin_exthdr = fin->fin_dp; - fin->fin_dp = (char *)fin->fin_dp + shift; - fin->fin_dlen -= shift; - - return hdr->ip6e_nxt; + return hdr; } /* ------------------------------------------------------------------------ */ -/* Function: frpr_hopopts6 */ +/* Function: ipf_pr_hopopts6 */ /* Returns: int - value of the next header or IPPROTO_NONE if error */ /* Parameters: fin(I) - pointer to packet information */ /* */ /* IPv6 Only */ /* This is function checks pending hop by hop options extension header */ /* ------------------------------------------------------------------------ */ -static INLINE int frpr_hopopts6(fin) -fr_info_t *fin; +static INLINE int +ipf_pr_hopopts6(fin) + fr_info_t *fin; { - return frpr_ipv6exthdr(fin, 0, IPPROTO_HOPOPTS); + struct ip6_ext *hdr; + + hdr = ipf_pr_ipv6exthdr(fin, 0, IPPROTO_HOPOPTS); + if (hdr == NULL) + return IPPROTO_NONE; + return hdr->ip6e_nxt; } /* ------------------------------------------------------------------------ */ -/* Function: frpr_mobility6 */ +/* Function: ipf_pr_mobility6 */ /* Returns: int - value of the next header or IPPROTO_NONE if error */ /* Parameters: fin(I) - pointer to packet information */ /* */ /* IPv6 Only */ /* This is function checks the IPv6 mobility extension header */ /* ------------------------------------------------------------------------ */ -static INLINE int frpr_mobility6(fin) -fr_info_t *fin; +static INLINE int +ipf_pr_mobility6(fin) + fr_info_t *fin; { - return frpr_ipv6exthdr(fin, 0, IPPROTO_MOBILITY); + struct ip6_ext *hdr; + + hdr = ipf_pr_ipv6exthdr(fin, 0, IPPROTO_MOBILITY); + if (hdr == NULL) + return IPPROTO_NONE; + return hdr->ip6e_nxt; } /* ------------------------------------------------------------------------ */ -/* Function: frpr_routing6 */ +/* Function: ipf_pr_routing6 */ /* Returns: int - value of the next header or IPPROTO_NONE if error */ /* Parameters: fin(I) - pointer to packet information */ /* */ /* IPv6 Only */ /* This is function checks pending routing extension header */ /* ------------------------------------------------------------------------ */ -static INLINE int frpr_routing6(fin) -fr_info_t *fin; +static INLINE int +ipf_pr_routing6(fin) + fr_info_t *fin; { - struct ip6_ext *hdr; + struct ip6_routing *hdr; - if (frpr_ipv6exthdr(fin, 0, IPPROTO_ROUTING) == IPPROTO_NONE) + hdr = (struct ip6_routing *)ipf_pr_ipv6exthdr(fin, 0, IPPROTO_ROUTING); + if (hdr == NULL) return IPPROTO_NONE; - hdr = fin->fin_exthdr; - if ((hdr->ip6e_len & 1) != 0) { + switch (hdr->ip6r_type) + { + case 0 : /* - * The routing header data is made up of 128 bit IPv6 addresses - * which means it must be a multiple of 2 lots of 8 in length. + * Nasty extension header length? */ - fin->fin_flx |= FI_BAD; - /* - * Compensate for the changes made in frpr_ipv6exthdr() - */ - fin->fin_dlen += 8 + (hdr->ip6e_len << 3); - fin->fin_dp = hdr; - return IPPROTO_NONE; + if (((hdr->ip6r_len >> 1) < hdr->ip6r_segleft) || + (hdr->ip6r_segleft && (hdr->ip6r_len & 1))) { + ipf_main_softc_t *softc = fin->fin_main_soft; + + fin->fin_flx |= FI_BAD; + LBUMPD(ipf_stats[fin->fin_out], fr_v6_rh_bad); + return IPPROTO_NONE; + } + break; + + default : + break; } - return hdr->ip6e_nxt; + return hdr->ip6r_nxt; } /* ------------------------------------------------------------------------ */ -/* Function: frpr_fragment6 */ +/* Function: ipf_pr_fragment6 */ /* Returns: int - value of the next header or IPPROTO_NONE if error */ /* Parameters: fin(I) - pointer to packet information */ /* */ /* IPv6 Only */ /* Examine the IPv6 fragment header and extract fragment offset information.*/ /* */ -/* We don't know where the transport layer header (or whatever is next is), */ -/* as it could be behind destination options (amongst others). Because */ -/* there is no fragment cache, there is no knowledge about whether or not an*/ -/* upper layer header has been seen (or where it ends) and thus we are not */ -/* able to continue processing beyond this header with any confidence. */ +/* Fragments in IPv6 are extraordinarily difficult to deal with - much more */ +/* so than in IPv4. There are 5 cases of fragments with IPv6 that all */ +/* packets with a fragment header can fit into. They are as follows: */ +/* */ +/* 1. [IPv6][0-n EH][FH][0-n EH] (no L4HDR present) */ +/* 2. [IPV6][0-n EH][FH][0-n EH][L4HDR part] (short) */ +/* 3. [IPV6][0-n EH][FH][L4HDR part][0-n data] (short) */ +/* 4. [IPV6][0-n EH][FH][0-n EH][L4HDR][0-n data] */ +/* 5. [IPV6][0-n EH][FH][data] */ +/* */ +/* IPV6 = IPv6 header, FH = Fragment Header, */ +/* 0-n EH = 0 or more extension headers, 0-n data = 0 or more bytes of data */ +/* */ +/* Packets that match 1, 2, 3 will be dropped as the only reasonable */ +/* scenario in which they happen is in extreme circumstances that are most */ +/* likely to be an indication of an attack rather than normal traffic. */ +/* A type 3 packet may be sent by an attacked after a type 4 packet. There */ +/* are two rules that can be used to guard against type 3 packets: L4 */ +/* headers must always be in a packet that has the offset field set to 0 */ +/* and no packet is allowed to overlay that where offset = 0. */ /* ------------------------------------------------------------------------ */ -static INLINE int frpr_fragment6(fin) -fr_info_t *fin; +static INLINE int +ipf_pr_fragment6(fin) + fr_info_t *fin; { + ipf_main_softc_t *softc = fin->fin_main_soft; struct ip6_frag *frag; - int extoff; fin->fin_flx |= FI_FRAG; - if (frpr_ipv6exthdr(fin, 0, IPPROTO_FRAGMENT) == IPPROTO_NONE) - return IPPROTO_NONE; - - extoff = (char *)fin->fin_exthdr - (char *)fin->fin_dp; - - if (frpr_pullup(fin, sizeof(*frag)) == -1) - return IPPROTO_NONE; - - fin->fin_exthdr = (char *)fin->fin_dp + extoff; - frag = fin->fin_exthdr; - /* - * Fragment but no fragmentation info set? Bad packet... - */ - if (frag->ip6f_offlg == 0) { - fin->fin_flx |= FI_BAD; + frag = (struct ip6_frag *)ipf_pr_ipv6exthdr(fin, 0, IPPROTO_FRAGMENT); + if (frag == NULL) { + LBUMPD(ipf_stats[fin->fin_out], fr_v6_frag_bad); return IPPROTO_NONE; } + if ((frag->ip6f_offlg & IP6F_MORE_FRAG) != 0) { + /* + * Any fragment that isn't the last fragment must have its + * length as a multiple of 8. + */ + if ((fin->fin_plen & 7) != 0) + fin->fin_flx |= FI_BAD; + } + + fin->fin_fraghdr = frag; + fin->fin_id = frag->ip6f_ident; fin->fin_off = ntohs(frag->ip6f_offlg & IP6F_OFF_MASK); - fin->fin_off <<= 3; if (fin->fin_off != 0) fin->fin_flx |= FI_FRAGBODY; - fin->fin_dp = (char *)fin->fin_dp + sizeof(*frag); - fin->fin_dlen -= sizeof(*frag); + /* + * Jumbograms aren't handled, so the max. length is 64k + */ + if ((fin->fin_off << 3) + fin->fin_dlen > 65535) + fin->fin_flx |= FI_BAD; + /* + * We don't know where the transport layer header (or whatever is next + * is), as it could be behind destination options (amongst others) so + * return the fragment header as the type of packet this is. Note that + * this effectively disables the fragment cache for > 1 protocol at a + * time. + */ return frag->ip6f_nxt; } /* ------------------------------------------------------------------------ */ -/* Function: frpr_dstopts6 */ +/* Function: ipf_pr_dstopts6 */ /* Returns: int - value of the next header or IPPROTO_NONE if error */ /* Parameters: fin(I) - pointer to packet information */ -/* nextheader(I) - stores next header value */ /* */ /* IPv6 Only */ /* This is function checks pending destination options extension header */ /* ------------------------------------------------------------------------ */ -static INLINE int frpr_dstopts6(fin) -fr_info_t *fin; +static INLINE int +ipf_pr_dstopts6(fin) + fr_info_t *fin; { - return frpr_ipv6exthdr(fin, 1, IPPROTO_DSTOPTS); + ipf_main_softc_t *softc = fin->fin_main_soft; + struct ip6_ext *hdr; + + hdr = ipf_pr_ipv6exthdr(fin, 0, IPPROTO_DSTOPTS); + if (hdr == NULL) { + LBUMPD(ipf_stats[fin->fin_out], fr_v6_dst_bad); + return IPPROTO_NONE; + } + return hdr->ip6e_nxt; } /* ------------------------------------------------------------------------ */ -/* Function: frpr_icmp6 */ +/* Function: ipf_pr_icmp6 */ /* Returns: void */ /* Parameters: fin(I) - pointer to packet information */ /* */ @@ -728,14 +912,19 @@ fr_info_t *fin; /* This routine is mainly concerned with determining the minimum valid size */ /* for an ICMPv6 packet. */ /* ------------------------------------------------------------------------ */ -static INLINE void frpr_icmp6(fin) -fr_info_t *fin; +static INLINE void +ipf_pr_icmp6(fin) + fr_info_t *fin; { int minicmpsz = sizeof(struct icmp6_hdr); struct icmp6_hdr *icmp6; - if (frpr_pullup(fin, ICMP6ERR_MINPKTLEN - sizeof(ip6_t)) == -1) + if (ipf_pr_pullup(fin, ICMP6ERR_MINPKTLEN - sizeof(ip6_t)) == -1) { + ipf_main_softc_t *softc = fin->fin_main_soft; + + LBUMPD(ipf_stats[fin->fin_out], fr_v6_icmp6_pullup); return; + } if (fin->fin_dlen > 1) { ip6_t *ip6; @@ -744,12 +933,18 @@ fr_info_t *fin; fin->fin_data[0] = *(u_short *)icmp6; + if ((icmp6->icmp6_type & ICMP6_INFOMSG_MASK) != 0) + fin->fin_flx |= FI_ICMPQUERY; + switch (icmp6->icmp6_type) { case ICMP6_ECHO_REPLY : case ICMP6_ECHO_REQUEST : + if (fin->fin_dlen >= 6) + fin->fin_data[1] = icmp6->icmp6_id; minicmpsz = ICMP6ERR_MINPKTLEN - sizeof(ip6_t); break; + case ICMP6_DST_UNREACH : case ICMP6_PACKET_TOO_BIG : case ICMP6_TIME_EXCEEDED : @@ -760,10 +955,13 @@ fr_info_t *fin; break; if (M_LEN(fin->fin_m) < fin->fin_plen) { - if (fr_coalesce(fin) != 1) + if (ipf_coalesce(fin) != 1) return; } + if (ipf_pr_pullup(fin, ICMP6ERR_MINPKTLEN) == -1) + return; + /* * If the destination of this packet doesn't match the * source of the original packet then this packet is @@ -774,19 +972,25 @@ fr_info_t *fin; if (IP6_NEQ(&fin->fin_fi.fi_dst, (i6addr_t *)&ip6->ip6_src)) fin->fin_flx |= FI_BAD; - break; default : break; } } - frpr_short6(fin, minicmpsz); + ipf_pr_short6(fin, minicmpsz); + if ((fin->fin_flx & (FI_SHORT|FI_BAD)) == 0) { + u_char p = fin->fin_p; + + fin->fin_p = IPPROTO_ICMPV6; + ipf_checkv6sum(fin); + fin->fin_p = p; + } } /* ------------------------------------------------------------------------ */ -/* Function: frpr_udp6 */ +/* Function: ipf_pr_udp6 */ /* Returns: void */ /* Parameters: fin(I) - pointer to packet information */ /* */ @@ -794,24 +998,23 @@ fr_info_t *fin; /* Analyse the packet for IPv6/UDP properties. */ /* Is not expected to be called for fragmented packets. */ /* ------------------------------------------------------------------------ */ -static INLINE void frpr_udp6(fin) -fr_info_t *fin; +static INLINE void +ipf_pr_udp6(fin) + fr_info_t *fin; { - frpr_short6(fin, sizeof(struct udphdr)); - - if (frpr_udpcommon(fin) == 0) { + if (ipf_pr_udpcommon(fin) == 0) { u_char p = fin->fin_p; fin->fin_p = IPPROTO_UDP; - fr_checkv6sum(fin); + ipf_checkv6sum(fin); fin->fin_p = p; } } /* ------------------------------------------------------------------------ */ -/* Function: frpr_tcp6 */ +/* Function: ipf_pr_tcp6 */ /* Returns: void */ /* Parameters: fin(I) - pointer to packet information */ /* */ @@ -819,24 +1022,23 @@ fr_info_t *fin; /* Analyse the packet for IPv6/TCP properties. */ /* Is not expected to be called for fragmented packets. */ /* ------------------------------------------------------------------------ */ -static INLINE void frpr_tcp6(fin) -fr_info_t *fin; +static INLINE void +ipf_pr_tcp6(fin) + fr_info_t *fin; { - frpr_short6(fin, sizeof(struct tcphdr)); - - if (frpr_tcpcommon(fin) == 0) { + if (ipf_pr_tcpcommon(fin) == 0) { u_char p = fin->fin_p; fin->fin_p = IPPROTO_TCP; - fr_checkv6sum(fin); + ipf_checkv6sum(fin); fin->fin_p = p; } } /* ------------------------------------------------------------------------ */ -/* Function: frpr_esp6 */ +/* Function: ipf_pr_esp6 */ /* Returns: void */ /* Parameters: fin(I) - pointer to packet information */ /* */ @@ -847,19 +1049,23 @@ fr_info_t *fin; /* is 32bits as well, it is not possible(?) to determine the version from a */ /* simple packet header. */ /* ------------------------------------------------------------------------ */ -static INLINE void frpr_esp6(fin) -fr_info_t *fin; +static INLINE void +ipf_pr_esp6(fin) + fr_info_t *fin; { - frpr_short6(fin, sizeof(grehdr_t)); + if ((fin->fin_off == 0) && (ipf_pr_pullup(fin, 8) == -1)) { + ipf_main_softc_t *softc = fin->fin_main_soft; - (void) frpr_pullup(fin, 8); + LBUMPD(ipf_stats[fin->fin_out], fr_v6_esp_pullup); + return; + } } /* ------------------------------------------------------------------------ */ -/* Function: frpr_ah6 */ -/* Returns: void */ +/* Function: ipf_pr_ah6 */ +/* Returns: int - value of the next header or IPPROTO_NONE if error */ /* Parameters: fin(I) - pointer to packet information */ /* */ /* IPv6 Only */ @@ -867,37 +1073,51 @@ fr_info_t *fin; /* The minimum length is taken to be the combination of all fields in the */ /* header being present and no authentication data (null algorithm used.) */ /* ------------------------------------------------------------------------ */ -static INLINE int frpr_ah6(fin) -fr_info_t *fin; +static INLINE int +ipf_pr_ah6(fin) + fr_info_t *fin; { authhdr_t *ah; - frpr_short6(fin, 12); + fin->fin_flx |= FI_AH; - if (frpr_pullup(fin, sizeof(*ah)) == -1) + ah = (authhdr_t *)ipf_pr_ipv6exthdr(fin, 0, IPPROTO_HOPOPTS); + if (ah == NULL) { + ipf_main_softc_t *softc = fin->fin_main_soft; + + LBUMPD(ipf_stats[fin->fin_out], fr_v6_ah_bad); return IPPROTO_NONE; + } - ah = (authhdr_t *)fin->fin_dp; + ipf_pr_short6(fin, sizeof(*ah)); + + /* + * No need for another pullup, ipf_pr_ipv6exthdr() will pullup + * enough data to satisfy ah_next (the very first one.) + */ return ah->ah_next; } /* ------------------------------------------------------------------------ */ -/* Function: frpr_gre6 */ +/* Function: ipf_pr_gre6 */ /* Returns: void */ /* Parameters: fin(I) - pointer to packet information */ /* */ /* Analyse the packet for GRE properties. */ /* ------------------------------------------------------------------------ */ -static INLINE void frpr_gre6(fin) -fr_info_t *fin; +static INLINE void +ipf_pr_gre6(fin) + fr_info_t *fin; { grehdr_t *gre; - frpr_short6(fin, sizeof(grehdr_t)); + if (ipf_pr_pullup(fin, sizeof(grehdr_t)) == -1) { + ipf_main_softc_t *softc = fin->fin_main_soft; - if (frpr_pullup(fin, sizeof(grehdr_t)) == -1) + LBUMPD(ipf_stats[fin->fin_out], fr_v6_gre_pullup); return; + } gre = fin->fin_dp; if (GRE_REV(gre->gr_flags) == 1) @@ -907,13 +1127,13 @@ fr_info_t *fin; /* ------------------------------------------------------------------------ */ -/* Function: frpr_pullup */ +/* Function: ipf_pr_pullup */ /* Returns: int - 0 == pullup succeeded, -1 == failure */ /* Parameters: fin(I) - pointer to packet information */ /* plen(I) - length (excluding L3 header) to pullup */ /* */ /* Short inline function to cut down on code duplication to perform a call */ -/* to fr_pullup to ensure there is the required amount of data, */ +/* to ipf_pullup to ensure there is the required amount of data, */ /* consecutively in the packet buffer. */ /* */ /* This function pulls up 'extra' data at the location of fin_dp. fin_dp */ @@ -924,23 +1144,32 @@ fr_info_t *fin; /* is necessary to add those we can already assume to be pulled up (fin_dp */ /* - fin_ip) to what is passed through. */ /* ------------------------------------------------------------------------ */ -static INLINE int frpr_pullup(fin, plen) -fr_info_t *fin; -int plen; +int +ipf_pr_pullup(fin, plen) + fr_info_t *fin; + int plen; { + ipf_main_softc_t *softc = fin->fin_main_soft; + if (fin->fin_m != NULL) { if (fin->fin_dp != NULL) plen += (char *)fin->fin_dp - ((char *)fin->fin_ip + fin->fin_hlen); plen += fin->fin_hlen; - if (M_LEN(fin->fin_m) < plen) { + if (M_LEN(fin->fin_m) < plen + fin->fin_ipoff) { #if defined(_KERNEL) - if (fr_pullup(fin->fin_m, fin, plen) == NULL) + if (ipf_pullup(fin->fin_m, fin, plen) == NULL) { + DT(ipf_pullup_fail); + LBUMP(ipf_stats[fin->fin_out].fr_pull[1]); return -1; + } + LBUMP(ipf_stats[fin->fin_out].fr_pull[0]); #else + LBUMP(ipf_stats[fin->fin_out].fr_pull[1]); /* - * Fake fr_pullup failing + * Fake ipf_pullup failing */ + fin->fin_reason = FRB_PULLUP; *fin->fin_mp = NULL; fin->fin_m = NULL; fin->fin_ip = NULL; @@ -953,7 +1182,7 @@ int plen; /* ------------------------------------------------------------------------ */ -/* Function: frpr_short */ +/* Function: ipf_pr_short */ /* Returns: void */ /* Parameters: fin(I) - pointer to packet information */ /* xmin(I) - minimum header size */ @@ -964,9 +1193,10 @@ int plen; /* start within the layer 4 header (hdrmin) or if it is at offset 0, the */ /* entire layer 4 header must be present (min). */ /* ------------------------------------------------------------------------ */ -static INLINE void frpr_short(fin, xmin) -fr_info_t *fin; -int xmin; +static INLINE void +ipf_pr_short(fin, xmin) + fr_info_t *fin; + int xmin; { if (fin->fin_off == 0) { @@ -979,7 +1209,7 @@ int xmin; /* ------------------------------------------------------------------------ */ -/* Function: frpr_icmp */ +/* Function: ipf_pr_icmp */ /* Returns: void */ /* Parameters: fin(I) - pointer to packet information */ /* */ @@ -991,110 +1221,111 @@ int xmin; /* */ /* XXX - other ICMP sanity checks? */ /* ------------------------------------------------------------------------ */ -static INLINE void frpr_icmp(fin) -fr_info_t *fin; +static INLINE void +ipf_pr_icmp(fin) + fr_info_t *fin; { + ipf_main_softc_t *softc = fin->fin_main_soft; int minicmpsz = sizeof(struct icmp); icmphdr_t *icmp; ip_t *oip; + ipf_pr_short(fin, ICMPERR_ICMPHLEN); + if (fin->fin_off != 0) { - frpr_short(fin, ICMPERR_ICMPHLEN); + LBUMPD(ipf_stats[fin->fin_out], fr_v4_icmp_frag); return; } - if (frpr_pullup(fin, ICMPERR_ICMPHLEN) == -1) + if (ipf_pr_pullup(fin, ICMPERR_ICMPHLEN) == -1) { + LBUMPD(ipf_stats[fin->fin_out], fr_v4_icmp_pullup); return; + } - if (fin->fin_dlen > 1) { - icmp = fin->fin_dp; + icmp = fin->fin_dp; - fin->fin_data[0] = *(u_short *)icmp; + fin->fin_data[0] = *(u_short *)icmp; + fin->fin_data[1] = icmp->icmp_id; - if (fin->fin_dlen >= 6) /* ID field */ - fin->fin_data[1] = icmp->icmp_id; - - switch (icmp->icmp_type) - { - case ICMP_ECHOREPLY : - case ICMP_ECHO : - /* Router discovery messaes - RFC 1256 */ - case ICMP_ROUTERADVERT : - case ICMP_ROUTERSOLICIT : - minicmpsz = ICMP_MINLEN; - break; - /* - * type(1) + code(1) + cksum(2) + id(2) seq(2) + - * 3 * timestamp(3 * 4) - */ - case ICMP_TSTAMP : - case ICMP_TSTAMPREPLY : - minicmpsz = 20; - break; - /* - * type(1) + code(1) + cksum(2) + id(2) seq(2) + - * mask(4) - */ - case ICMP_MASKREQ : - case ICMP_MASKREPLY : - minicmpsz = 12; - break; - /* - * type(1) + code(1) + cksum(2) + id(2) seq(2) + ip(20+) - */ - case ICMP_UNREACH : + switch (icmp->icmp_type) + { + case ICMP_ECHOREPLY : + case ICMP_ECHO : + /* Router discovery messaes - RFC 1256 */ + case ICMP_ROUTERADVERT : + case ICMP_ROUTERSOLICIT : + fin->fin_flx |= FI_ICMPQUERY; + minicmpsz = ICMP_MINLEN; + break; + /* + * type(1) + code(1) + cksum(2) + id(2) seq(2) + + * 3 * timestamp(3 * 4) + */ + case ICMP_TSTAMP : + case ICMP_TSTAMPREPLY : + fin->fin_flx |= FI_ICMPQUERY; + minicmpsz = 20; + break; + /* + * type(1) + code(1) + cksum(2) + id(2) seq(2) + + * mask(4) + */ + case ICMP_IREQ : + case ICMP_IREQREPLY : + case ICMP_MASKREQ : + case ICMP_MASKREPLY : + fin->fin_flx |= FI_ICMPQUERY; + minicmpsz = 12; + break; + /* + * type(1) + code(1) + cksum(2) + id(2) seq(2) + ip(20+) + */ + case ICMP_UNREACH : #ifdef icmp_nextmtu - if (icmp->icmp_code == ICMP_UNREACH_NEEDFRAG) { - if (icmp->icmp_nextmtu < fr_icmpminfragmtu) - fin->fin_flx |= FI_BAD; - } -#endif - case ICMP_SOURCEQUENCH : - case ICMP_REDIRECT : - case ICMP_TIMXCEED : - case ICMP_PARAMPROB : - fin->fin_flx |= FI_ICMPERR; - if (fr_coalesce(fin) != 1) - return; - /* - * ICMP error packets should not be generated for IP - * packets that are a fragment that isn't the first - * fragment. - */ - oip = (ip_t *)((char *)fin->fin_dp + ICMPERR_ICMPHLEN); - if ((ntohs(oip->ip_off) & IP_OFFMASK) != 0) + if (icmp->icmp_code == ICMP_UNREACH_NEEDFRAG) { + if (icmp->icmp_nextmtu < softc->ipf_icmpminfragmtu) fin->fin_flx |= FI_BAD; - - /* - * If the destination of this packet doesn't match the - * source of the original packet then this packet is - * not correct. - */ - if (oip->ip_src.s_addr != fin->fin_daddr) - fin->fin_flx |= FI_BAD; - - /* - * If the destination of this packet doesn't match the - * source of the original packet then this packet is - * not correct. - */ - if (oip->ip_src.s_addr != fin->fin_daddr) - fin->fin_flx |= FI_BAD; - break; - default : - break; } +#endif + case ICMP_SOURCEQUENCH : + case ICMP_REDIRECT : + case ICMP_TIMXCEED : + case ICMP_PARAMPROB : + fin->fin_flx |= FI_ICMPERR; + if (ipf_coalesce(fin) != 1) { + LBUMPD(ipf_stats[fin->fin_out], fr_icmp_coalesce); + return; + } + + /* + * ICMP error packets should not be generated for IP + * packets that are a fragment that isn't the first + * fragment. + */ + oip = (ip_t *)((char *)fin->fin_dp + ICMPERR_ICMPHLEN); + if ((ntohs(oip->ip_off) & IP_OFFMASK) != 0) + fin->fin_flx |= FI_BAD; + + /* + * If the destination of this packet doesn't match the + * source of the original packet then this packet is + * not correct. + */ + if (oip->ip_src.s_addr != fin->fin_daddr) + fin->fin_flx |= FI_BAD; + break; + default : + break; } - frpr_short(fin, minicmpsz); + ipf_pr_short(fin, minicmpsz); - if ((fin->fin_flx & FI_FRAG) == 0) - fr_checkv4sum(fin); + ipf_checkv4sum(fin); } /* ------------------------------------------------------------------------ */ -/* Function: frpr_tcpcommon */ +/* Function: ipf_pr_tcpcommon */ /* Returns: int - 0 = header ok, 1 = bad packet, -1 = buffer error */ /* Parameters: fin(I) - pointer to packet information */ /* */ @@ -1103,27 +1334,35 @@ fr_info_t *fin; /* If compiled with IPFILTER_CKSUM, check to see if the TCP checksum is */ /* valid and mark the packet as bad if not. */ /* ------------------------------------------------------------------------ */ -static INLINE int frpr_tcpcommon(fin) -fr_info_t *fin; +static INLINE int +ipf_pr_tcpcommon(fin) + fr_info_t *fin; { + ipf_main_softc_t *softc = fin->fin_main_soft; int flags, tlen; tcphdr_t *tcp; fin->fin_flx |= FI_TCPUDP; - if (fin->fin_off != 0) + if (fin->fin_off != 0) { + LBUMPD(ipf_stats[fin->fin_out], fr_tcp_frag); return 0; + } - if (frpr_pullup(fin, sizeof(*tcp)) == -1) + if (ipf_pr_pullup(fin, sizeof(*tcp)) == -1) { + LBUMPD(ipf_stats[fin->fin_out], fr_tcp_pullup); return -1; - tcp = fin->fin_dp; + } + tcp = fin->fin_dp; if (fin->fin_dlen > 3) { fin->fin_sport = ntohs(tcp->th_sport); fin->fin_dport = ntohs(tcp->th_dport); } - if ((fin->fin_flx & FI_SHORT) != 0) + if ((fin->fin_flx & FI_SHORT) != 0) { + LBUMPD(ipf_stats[fin->fin_out], fr_tcp_short); return 1; + } /* * Use of the TCP data offset *must* result in a value that is at @@ -1131,6 +1370,7 @@ fr_info_t *fin; */ tlen = TCP_OFF(tcp) << 2; if (tlen < sizeof(tcphdr_t)) { + LBUMPD(ipf_stats[fin->fin_out], fr_tcp_small); fin->fin_flx |= FI_BAD; return 1; } @@ -1189,6 +1429,10 @@ fr_info_t *fin; fin->fin_flx |= FI_BAD; } } + if (fin->fin_flx & FI_BAD) { + LBUMPD(ipf_stats[fin->fin_out], fr_tcp_bad_flags); + return 1; + } /* * At this point, it's not exactly clear what is to be gained by @@ -1198,11 +1442,14 @@ fr_info_t *fin; * Now if we were to analyse the header for passive fingerprinting, * then that might add some weight to adding this... */ - if (tlen == sizeof(tcphdr_t)) + if (tlen == sizeof(tcphdr_t)) { return 0; + } - if (frpr_pullup(fin, tlen) == -1) + if (ipf_pr_pullup(fin, tlen) == -1) { + LBUMPD(ipf_stats[fin->fin_out], fr_tcp_pullup); return -1; + } #if 0 tcp = fin->fin_dp; @@ -1249,23 +1496,27 @@ fr_info_t *fin; /* ------------------------------------------------------------------------ */ -/* Function: frpr_udpcommon */ +/* Function: ipf_pr_udpcommon */ /* Returns: int - 0 = header ok, 1 = bad packet */ /* Parameters: fin(I) - pointer to packet information */ /* */ /* Extract the UDP source and destination ports, if present. If compiled */ /* with IPFILTER_CKSUM, check to see if the UDP checksum is valid. */ /* ------------------------------------------------------------------------ */ -static INLINE int frpr_udpcommon(fin) -fr_info_t *fin; +static INLINE int +ipf_pr_udpcommon(fin) + fr_info_t *fin; { udphdr_t *udp; fin->fin_flx |= FI_TCPUDP; if (!fin->fin_off && (fin->fin_dlen > 3)) { - if (frpr_pullup(fin, sizeof(*udp)) == -1) { + if (ipf_pr_pullup(fin, sizeof(*udp)) == -1) { + ipf_main_softc_t *softc = fin->fin_main_soft; + fin->fin_flx |= FI_SHORT; + LBUMPD(ipf_stats[fin->fin_out], fr_udp_pullup); return 1; } @@ -1280,49 +1531,47 @@ fr_info_t *fin; /* ------------------------------------------------------------------------ */ -/* Function: frpr_tcp */ +/* Function: ipf_pr_tcp */ /* Returns: void */ /* Parameters: fin(I) - pointer to packet information */ /* */ /* IPv4 Only */ /* Analyse the packet for IPv4/TCP properties. */ /* ------------------------------------------------------------------------ */ -static INLINE void frpr_tcp(fin) -fr_info_t *fin; +static INLINE void +ipf_pr_tcp(fin) + fr_info_t *fin; { - frpr_short(fin, sizeof(tcphdr_t)); + ipf_pr_short(fin, sizeof(tcphdr_t)); - if (frpr_tcpcommon(fin) == 0) { - if ((fin->fin_flx & FI_FRAG) == 0) - fr_checkv4sum(fin); - } + if (ipf_pr_tcpcommon(fin) == 0) + ipf_checkv4sum(fin); } /* ------------------------------------------------------------------------ */ -/* Function: frpr_udp */ +/* Function: ipf_pr_udp */ /* Returns: void */ /* Parameters: fin(I) - pointer to packet information */ /* */ /* IPv4 Only */ /* Analyse the packet for IPv4/UDP properties. */ /* ------------------------------------------------------------------------ */ -static INLINE void frpr_udp(fin) -fr_info_t *fin; +static INLINE void +ipf_pr_udp(fin) + fr_info_t *fin; { - frpr_short(fin, sizeof(udphdr_t)); + ipf_pr_short(fin, sizeof(udphdr_t)); - if (frpr_udpcommon(fin) == 0) { - if ((fin->fin_flx & FI_FRAG) == 0) - fr_checkv4sum(fin); - } + if (ipf_pr_udpcommon(fin) == 0) + ipf_checkv4sum(fin); } /* ------------------------------------------------------------------------ */ -/* Function: frpr_esp */ +/* Function: ipf_pr_esp */ /* Returns: void */ /* Parameters: fin(I) - pointer to packet information */ /* */ @@ -1332,78 +1581,107 @@ fr_info_t *fin; /* is 32bits as well, it is not possible(?) to determine the version from a */ /* simple packet header. */ /* ------------------------------------------------------------------------ */ -static INLINE void frpr_esp(fin) -fr_info_t *fin; +static INLINE void +ipf_pr_esp(fin) + fr_info_t *fin; { if (fin->fin_off == 0) { - frpr_short(fin, 8); - (void) frpr_pullup(fin, 8); - } + ipf_pr_short(fin, 8); + if (ipf_pr_pullup(fin, 8) == -1) { + ipf_main_softc_t *softc = fin->fin_main_soft; + LBUMPD(ipf_stats[fin->fin_out], fr_v4_esp_pullup); + } + } } /* ------------------------------------------------------------------------ */ -/* Function: frpr_ah */ -/* Returns: void */ +/* Function: ipf_pr_ah */ +/* Returns: int - value of the next header or IPPROTO_NONE if error */ /* Parameters: fin(I) - pointer to packet information */ /* */ /* Analyse the packet for AH properties. */ /* The minimum length is taken to be the combination of all fields in the */ /* header being present and no authentication data (null algorithm used.) */ /* ------------------------------------------------------------------------ */ -static INLINE void frpr_ah(fin) -fr_info_t *fin; +static INLINE int +ipf_pr_ah(fin) + fr_info_t *fin; { + ipf_main_softc_t *softc = fin->fin_main_soft; authhdr_t *ah; int len; - frpr_short(fin, sizeof(*ah)); + fin->fin_flx |= FI_AH; + ipf_pr_short(fin, sizeof(*ah)); - if (((fin->fin_flx & FI_SHORT) != 0) || (fin->fin_off != 0)) - return; + if (((fin->fin_flx & FI_SHORT) != 0) || (fin->fin_off != 0)) { + LBUMPD(ipf_stats[fin->fin_out], fr_v4_ah_bad); + return IPPROTO_NONE; + } - if (frpr_pullup(fin, sizeof(*ah)) == -1) - return; + if (ipf_pr_pullup(fin, sizeof(*ah)) == -1) { + DT(fr_v4_ah_pullup_1); + LBUMP(ipf_stats[fin->fin_out].fr_v4_ah_pullup); + return IPPROTO_NONE; + } ah = (authhdr_t *)fin->fin_dp; len = (ah->ah_plen + 2) << 2; - frpr_short(fin, len); + ipf_pr_short(fin, len); + if (ipf_pr_pullup(fin, len) == -1) { + DT(fr_v4_ah_pullup_2); + LBUMP(ipf_stats[fin->fin_out].fr_v4_ah_pullup); + return IPPROTO_NONE; + } + + /* + * Adjust fin_dp and fin_dlen for skipping over the authentication + * header. + */ + fin->fin_dp = (char *)fin->fin_dp + len; + fin->fin_dlen -= len; + return ah->ah_next; } /* ------------------------------------------------------------------------ */ -/* Function: frpr_gre */ +/* Function: ipf_pr_gre */ /* Returns: void */ /* Parameters: fin(I) - pointer to packet information */ /* */ /* Analyse the packet for GRE properties. */ /* ------------------------------------------------------------------------ */ -static INLINE void frpr_gre(fin) -fr_info_t *fin; +static INLINE void +ipf_pr_gre(fin) + fr_info_t *fin; { + ipf_main_softc_t *softc = fin->fin_main_soft; grehdr_t *gre; - frpr_short(fin, sizeof(*gre)); + ipf_pr_short(fin, sizeof(grehdr_t)); - if (fin->fin_off != 0) + if (fin->fin_off != 0) { + LBUMPD(ipf_stats[fin->fin_out], fr_v4_gre_frag); return; - - if (frpr_pullup(fin, sizeof(*gre)) == -1) - return; - - if (fin->fin_off == 0) { - gre = fin->fin_dp; - if (GRE_REV(gre->gr_flags) == 1) - fin->fin_data[0] = gre->gr_call; } + + if (ipf_pr_pullup(fin, sizeof(grehdr_t)) == -1) { + LBUMPD(ipf_stats[fin->fin_out], fr_v4_gre_pullup); + return; + } + + gre = fin->fin_dp; + if (GRE_REV(gre->gr_flags) == 1) + fin->fin_data[0] = gre->gr_call; } /* ------------------------------------------------------------------------ */ -/* Function: frpr_ipv4hdr */ +/* Function: ipf_pr_ipv4hdr */ /* Returns: void */ /* Parameters: fin(I) - pointer to packet information */ /* */ @@ -1411,8 +1689,9 @@ fr_info_t *fin; /* Analyze the IPv4 header and set fields in the fr_info_t structure. */ /* Check all options present and flag their presence if any exist. */ /* ------------------------------------------------------------------------ */ -static INLINE void frpr_ipv4hdr(fin) -fr_info_t *fin; +static INLINE void +ipf_pr_ipv4hdr(fin) + fr_info_t *fin; { u_short optmsk = 0, secmsk = 0, auth = 0; int hlen, ol, mv, p, i; @@ -1428,16 +1707,14 @@ fr_info_t *fin; ip = fin->fin_ip; p = ip->ip_p; fi->fi_p = p; + fin->fin_crc = p; fi->fi_tos = ip->ip_tos; fin->fin_id = ip->ip_id; - off = ip->ip_off; + off = ntohs(ip->ip_off); /* Get both TTL and protocol */ fi->fi_p = ip->ip_p; fi->fi_ttl = ip->ip_ttl; -#if 0 - (*(((u_short *)fi) + 1)) = (*(((u_short *)ip) + 4)); -#endif /* Zero out bits not used in IPv6 address */ fi->fi_src.i6[1] = 0; @@ -1448,7 +1725,11 @@ fr_info_t *fin; fi->fi_dst.i6[3] = 0; fi->fi_saddr = ip->ip_src.s_addr; + fin->fin_crc += fi->fi_saddr; fi->fi_daddr = ip->ip_dst.s_addr; + fin->fin_crc += fi->fi_daddr; + if (IN_CLASSD(ntohl(fi->fi_daddr))) + fin->fin_flx |= FI_MULTICAST|FI_MBCAST; /* * set packet attribute flags based on the offset and @@ -1463,12 +1744,12 @@ fr_info_t *fin; if (off != 0) { fin->fin_flx |= FI_FRAGBODY; off <<= 3; - if ((off + fin->fin_dlen > 65535) || + if ((off + fin->fin_dlen > 65535) || (fin->fin_dlen == 0) || ((morefrag != 0) && ((fin->fin_dlen & 7) != 0))) { - /* + /* * The length of the packet, starting at its - * offset cannot exceed 65535 (0xffff) as the + * offset cannot exceed 65535 (0xffff) as the * length of an IP packet is only 16 bits. * * Any fragment that isn't the last fragment @@ -1484,25 +1765,30 @@ fr_info_t *fin; /* * Call per-protocol setup and checking */ + if (p == IPPROTO_AH) { + /* + * Treat AH differently because we expect there to be another + * layer 4 header after it. + */ + p = ipf_pr_ah(fin); + } + switch (p) { case IPPROTO_UDP : - frpr_udp(fin); + ipf_pr_udp(fin); break; case IPPROTO_TCP : - frpr_tcp(fin); + ipf_pr_tcp(fin); break; case IPPROTO_ICMP : - frpr_icmp(fin); - break; - case IPPROTO_AH : - frpr_ah(fin); + ipf_pr_icmp(fin); break; case IPPROTO_ESP : - frpr_esp(fin); + ipf_pr_esp(fin); break; case IPPROTO_GRE : - frpr_gre(fin); + ipf_pr_gre(fin); break; } @@ -1545,32 +1831,37 @@ fr_info_t *fin; } for (i = 9, mv = 4; mv >= 0; ) { op = ipopts + i; - if ((opt == (u_char)op->ol_val) && (ol > 4)) { - optmsk |= op->ol_bit; - if (opt == IPOPT_SECURITY) { - const struct optlist *sp; - u_char sec; - int j, m; - sec = *(s + 2); /* classification */ - for (j = 3, m = 2; m >= 0; ) { - sp = secopt + j; - if (sec == sp->ol_val) { - secmsk |= sp->ol_bit; - auth = *(s + 3); - auth *= 256; - auth += *(s + 4); - break; - } - if (sec < sp->ol_val) - j -= m; - else - j += m; - m--; + if ((opt == (u_char)op->ol_val) && (ol > 4)) { + u_32_t doi; + + switch (opt) + { + case IPOPT_SECURITY : + if (optmsk & op->ol_bit) { + fin->fin_flx |= FI_BAD; + } else { + doi = ipf_checkripso(s); + secmsk = doi >> 16; + auth = doi & 0xffff; } + break; + + case IPOPT_CIPSO : + + if (optmsk & op->ol_bit) { + fin->fin_flx |= FI_BAD; + } else { + doi = ipf_checkcipso(fin, + s, ol); + secmsk = doi >> 16; + auth = doi & 0xffff; + } + break; } - break; + optmsk |= op->ol_bit; } + if (opt < op->ol_val) i -= mv; else @@ -1593,8 +1884,142 @@ fr_info_t *fin; /* ------------------------------------------------------------------------ */ -/* Function: fr_makefrip */ +/* Function: ipf_checkripso */ /* Returns: void */ +/* Parameters: s(I) - pointer to start of RIPSO option */ +/* */ +/* ------------------------------------------------------------------------ */ +static u_32_t +ipf_checkripso(s) + u_char *s; +{ + const struct optlist *sp; + u_short secmsk = 0, auth = 0; + u_char sec; + int j, m; + + sec = *(s + 2); /* classification */ + for (j = 3, m = 2; m >= 0; ) { + sp = secopt + j; + if (sec == sp->ol_val) { + secmsk |= sp->ol_bit; + auth = *(s + 3); + auth *= 256; + auth += *(s + 4); + break; + } + if (sec < sp->ol_val) + j -= m; + else + j += m; + m--; + } + + return (secmsk << 16) | auth; +} + + +/* ------------------------------------------------------------------------ */ +/* Function: ipf_checkcipso */ +/* Returns: u_32_t - 0 = failure, else the doi from the header */ +/* Parameters: fin(IO) - pointer to packet information */ +/* s(I) - pointer to start of CIPSO option */ +/* ol(I) - length of CIPSO option field */ +/* */ +/* This function returns the domain of integrity (DOI) field from the CIPSO */ +/* header and returns that whilst also storing the highest sensitivity */ +/* value found in the fr_info_t structure. */ +/* */ +/* No attempt is made to extract the category bitmaps as these are defined */ +/* by the user (rather than the protocol) and can be rather numerous on the */ +/* end nodes. */ +/* ------------------------------------------------------------------------ */ +static u_32_t +ipf_checkcipso(fin, s, ol) + fr_info_t *fin; + u_char *s; + int ol; +{ + ipf_main_softc_t *softc = fin->fin_main_soft; + fr_ip_t *fi; + u_32_t doi; + u_char *t, tag, tlen, sensitivity; + int len; + + if (ol < 6 || ol > 40) { + LBUMPD(ipf_stats[fin->fin_out], fr_v4_cipso_bad); + fin->fin_flx |= FI_BAD; + return 0; + } + + fi = &fin->fin_fi; + fi->fi_sensitivity = 0; + /* + * The DOI field MUST be there. + */ + bcopy(s + 2, &doi, sizeof(doi)); + + t = (u_char *)s + 6; + for (len = ol - 6; len >= 2; len -= tlen, t+= tlen) { + tag = *t; + tlen = *(t + 1); + if (tlen > len || tlen < 4 || tlen > 34) { + LBUMPD(ipf_stats[fin->fin_out], fr_v4_cipso_tlen); + fin->fin_flx |= FI_BAD; + return 0; + } + + sensitivity = 0; + /* + * Tag numbers 0, 1, 2, 5 are laid out in the CIPSO Internet + * draft (16 July 1992) that has expired. + */ + if (tag == 0) { + fin->fin_flx |= FI_BAD; + continue; + } else if (tag == 1) { + if (*(t + 2) != 0) { + fin->fin_flx |= FI_BAD; + continue; + } + sensitivity = *(t + 3); + /* Category bitmap for categories 0-239 */ + + } else if (tag == 4) { + if (*(t + 2) != 0) { + fin->fin_flx |= FI_BAD; + continue; + } + sensitivity = *(t + 3); + /* Enumerated categories, 16bits each, upto 15 */ + + } else if (tag == 5) { + if (*(t + 2) != 0) { + fin->fin_flx |= FI_BAD; + continue; + } + sensitivity = *(t + 3); + /* Range of categories (2*16bits), up to 7 pairs */ + + } else if (tag > 127) { + /* Custom defined DOI */ + ; + } else { + fin->fin_flx |= FI_BAD; + continue; + } + + if (sensitivity > fi->fi_sensitivity) + fi->fi_sensitivity = sensitivity; + } + + return doi; +} + + +/* ------------------------------------------------------------------------ */ +/* Function: ipf_makefrip */ +/* Returns: int - 0 == packet ok, -1 == packet freed */ /* Parameters: hlen(I) - length of IP packet header */ /* ip(I) - pointer to the IP header */ /* fin(IO) - pointer to packet information */ @@ -1604,15 +2029,15 @@ fr_info_t *fin; /* in the fr_info_t structure pointer to by fin. At present, it is assumed */ /* this function will be called with either an IPv4 or IPv6 packet. */ /* ------------------------------------------------------------------------ */ -int fr_makefrip(hlen, ip, fin) -int hlen; -ip_t *ip; -fr_info_t *fin; +int +ipf_makefrip(hlen, ip, fin) + int hlen; + ip_t *ip; + fr_info_t *fin; { + ipf_main_softc_t *softc = fin->fin_main_soft; int v; - fin->fin_nat = NULL; - fin->fin_state = NULL; fin->fin_depth = 0; fin->fin_hlen = (u_short)hlen; fin->fin_ip = ip; @@ -1623,43 +2048,43 @@ fr_info_t *fin; v = fin->fin_v; if (v == 4) { - fin->fin_plen = ip->ip_len; + fin->fin_plen = ntohs(ip->ip_len); fin->fin_dlen = fin->fin_plen - hlen; - - frpr_ipv4hdr(fin); + ipf_pr_ipv4hdr(fin); #ifdef USE_INET6 } else if (v == 6) { fin->fin_plen = ntohs(((ip6_t *)ip)->ip6_plen); fin->fin_dlen = fin->fin_plen; fin->fin_plen += hlen; - if (frpr_ipv6hdr(fin) == -1) - return -1; + ipf_pr_ipv6hdr(fin); #endif } - if (fin->fin_ip == NULL) + if (fin->fin_ip == NULL) { + LBUMP(ipf_stats[fin->fin_out].fr_ip_freed); return -1; + } return 0; } /* ------------------------------------------------------------------------ */ -/* Function: fr_portcheck */ +/* Function: ipf_portcheck */ /* Returns: int - 1 == port matched, 0 == port match failed */ /* Parameters: frp(I) - pointer to port check `expression' */ -/* pop(I) - pointer to port number to evaluate */ +/* pop(I) - port number to evaluate */ /* */ /* Perform a comparison of a port number against some other(s), using a */ /* structure with compare information stored in it. */ /* ------------------------------------------------------------------------ */ -static INLINE int fr_portcheck(frp, pop) -frpcmp_t *frp; -u_short *pop; +static INLINE int +ipf_portcheck(frp, pop) + frpcmp_t *frp; + u_32_t pop; { - u_short tup, po; int err = 1; + u_32_t po; - tup = *pop; po = frp->frp_port; /* @@ -1668,39 +2093,39 @@ u_short *pop; switch (frp->frp_cmp) { case FR_EQUAL : - if (tup != po) /* EQUAL */ + if (pop != po) /* EQUAL */ err = 0; break; case FR_NEQUAL : - if (tup == po) /* NOTEQUAL */ + if (pop == po) /* NOTEQUAL */ err = 0; break; case FR_LESST : - if (tup >= po) /* LESSTHAN */ + if (pop >= po) /* LESSTHAN */ err = 0; break; case FR_GREATERT : - if (tup <= po) /* GREATERTHAN */ + if (pop <= po) /* GREATERTHAN */ err = 0; break; case FR_LESSTE : - if (tup > po) /* LT or EQ */ + if (pop > po) /* LT or EQ */ err = 0; break; case FR_GREATERTE : - if (tup < po) /* GT or EQ */ + if (pop < po) /* GT or EQ */ err = 0; break; case FR_OUTRANGE : - if (tup >= po && tup <= frp->frp_top) /* Out of range */ + if (pop >= po && pop <= frp->frp_top) /* Out of range */ err = 0; break; case FR_INRANGE : - if (tup <= po || tup >= frp->frp_top) /* In range */ + if (pop <= po || pop >= frp->frp_top) /* In range */ err = 0; break; case FR_INCRANGE : - if (tup < po || tup > frp->frp_top) /* Inclusive range */ + if (pop < po || pop > frp->frp_top) /* Inclusive range */ err = 0; break; default : @@ -1711,17 +2136,18 @@ u_short *pop; /* ------------------------------------------------------------------------ */ -/* Function: fr_tcpudpchk */ +/* Function: ipf_tcpudpchk */ /* Returns: int - 1 == protocol matched, 0 == check failed */ -/* Parameters: fin(I) - pointer to packet information */ +/* Parameters: fda(I) - pointer to packet information */ /* ft(I) - pointer to structure with comparison data */ /* */ /* Compares the current pcket (assuming it is TCP/UDP) information with a */ /* structure containing information that we want to match against. */ /* ------------------------------------------------------------------------ */ -int fr_tcpudpchk(fin, ft) -fr_info_t *fin; -frtuc_t *ft; +int +ipf_tcpudpchk(fi, ft) + fr_ip_t *fi; + frtuc_t *ft; { int err = 1; @@ -1732,13 +2158,13 @@ frtuc_t *ft; * compare destination ports */ if (ft->ftu_dcmp) - err = fr_portcheck(&ft->ftu_dst, &fin->fin_dport); + err = ipf_portcheck(&ft->ftu_dst, fi->fi_ports[1]); /* * compare source ports */ if (err && ft->ftu_scmp) - err = fr_portcheck(&ft->ftu_src, &fin->fin_sport); + err = ipf_portcheck(&ft->ftu_src, fi->fi_ports[0]); /* * If we don't have all the TCP/UDP header, then how can we @@ -1746,15 +2172,15 @@ frtuc_t *ft; * TCP flags, then NO match. If not, then match (which should * satisfy the "short" class too). */ - if (err && (fin->fin_p == IPPROTO_TCP)) { - if (fin->fin_flx & FI_SHORT) + if (err && (fi->fi_p == IPPROTO_TCP)) { + if (fi->fi_flx & FI_SHORT) return !(ft->ftu_tcpf | ft->ftu_tcpfm); /* * Match the flags ? If not, abort this match. */ if (ft->ftu_tcpfm && - ft->ftu_tcpf != (fin->fin_tcpf & ft->ftu_tcpfm)) { - FR_DEBUG(("f. %#x & %#x != %#x\n", fin->fin_tcpf, + ft->ftu_tcpf != (fi->fi_tcpf & ft->ftu_tcpfm)) { + FR_DEBUG(("f. %#x & %#x != %#x\n", fi->fi_tcpf, ft->ftu_tcpfm, ft->ftu_tcpf)); err = 0; } @@ -1763,10 +2189,9 @@ frtuc_t *ft; } - /* ------------------------------------------------------------------------ */ -/* Function: fr_ipfcheck */ -/* Returns: int - 0 == match, 1 == no match */ +/* Function: ipf_check_ipf */ +/* Returns: int - 0 == match, else no match */ /* Parameters: fin(I) - pointer to packet information */ /* fr(I) - pointer to filter rule */ /* portcmp(I) - flag indicating whether to attempt matching on */ @@ -1776,10 +2201,11 @@ frtuc_t *ft; /* port numbers, etc, for "standard" IPFilter rules are all orchestrated in */ /* this function. */ /* ------------------------------------------------------------------------ */ -static INLINE int fr_ipfcheck(fin, fr, portcmp) -fr_info_t *fin; -frentry_t *fr; -int portcmp; +static INLINE int +ipf_check_ipf(fin, fr, portcmp) + fr_info_t *fin; + frentry_t *fr; + int portcmp; { u_32_t *ld, *lm, *lip; fripf_t *fri; @@ -1807,10 +2233,10 @@ int portcmp; * are present (if any) in this packet. */ lip++, lm++, ld++; - i |= ((*lip & *lm) != *ld); + i = ((*lip & *lm) != *ld); FR_DEBUG(("1. %#08x & %#08x != %#08x\n", ntohl(*lip), ntohl(*lm), ntohl(*ld))); - if (i) + if (i != 0) return 1; lip++, lm++, ld++; @@ -1820,16 +2246,15 @@ int portcmp; /* * Check the source address. */ -#ifdef IPFILTER_LOOKUP if (fr->fr_satype == FRI_LOOKUP) { - i = (*fr->fr_srcfunc)(fr->fr_srcptr, fi->fi_v, lip); + i = (*fr->fr_srcfunc)(fin->fin_main_soft, fr->fr_srcptr, + fi->fi_v, lip, fin->fin_plen); if (i == -1) return 1; lip += 3; lm += 3; ld += 3; } else { -#endif i = ((*lip & *lm) != *ld); FR_DEBUG(("2a. %#08x & %#08x != %#08x\n", ntohl(*lip), ntohl(*lm), ntohl(*ld))); @@ -1851,27 +2276,24 @@ int portcmp; lm += 3; ld += 3; } -#ifdef IPFILTER_LOOKUP } -#endif i ^= (fr->fr_flags & FR_NOTSRCIP) >> 6; - if (i) + if (i != 0) return 1; /* * Check the destination address. */ lip++, lm++, ld++; -#ifdef IPFILTER_LOOKUP if (fr->fr_datype == FRI_LOOKUP) { - i = (*fr->fr_dstfunc)(fr->fr_dstptr, fi->fi_v, lip); + i = (*fr->fr_dstfunc)(fin->fin_main_soft, fr->fr_dstptr, + fi->fi_v, lip, fin->fin_plen); if (i == -1) return 1; lip += 3; lm += 3; ld += 3; } else { -#endif i = ((*lip & *lm) != *ld); FR_DEBUG(("3a. %#08x & %#08x != %#08x\n", ntohl(*lip), ntohl(*lm), ntohl(*ld))); @@ -1893,28 +2315,24 @@ int portcmp; lm += 3; ld += 3; } -#ifdef IPFILTER_LOOKUP } -#endif i ^= (fr->fr_flags & FR_NOTDSTIP) >> 7; - if (i) + if (i != 0) return 1; /* * IP addresses matched. The next 32bits contains: * mast of old IP header security & authentication bits. */ lip++, lm++, ld++; - i |= ((*lip & *lm) != *ld); - FR_DEBUG(("4. %#08x & %#08x != %#08x\n", - *lip, *lm, *ld)); + i = (*ld - (*lip & *lm)); + FR_DEBUG(("4. %#08x & %#08x != %#08x\n", *lip, *lm, *ld)); /* * Next we have 32 bits of packet flags. */ lip++, lm++, ld++; - i |= ((*lip & *lm) != *ld); - FR_DEBUG(("5. %#08x & %#08x != %#08x\n", - *lip, *lm, *ld)); + i |= (*ld - (*lip & *lm)); + FR_DEBUG(("5. %#08x & %#08x != %#08x\n", *lip, *lm, *ld)); if (i == 0) { /* @@ -1922,7 +2340,7 @@ int portcmp; * looking for here... */ if (portcmp) { - if (!fr_tcpudpchk(fin, &fr->fr_tuc)) + if (!ipf_tcpudpchk(&fin->fin_fi, &fr->fr_tuc)) i = 1; } else { if (fr->fr_dcmp || fr->fr_scmp || @@ -1948,7 +2366,7 @@ int portcmp; /* ------------------------------------------------------------------------ */ -/* Function: fr_scanlist */ +/* Function: ipf_scanlist */ /* Returns: int - result flags of scanning filter list */ /* Parameters: fin(I) - pointer to packet information */ /* pass(I) - default result to return for filtering */ @@ -1963,10 +2381,12 @@ int portcmp; /* Could be per interface, but this gets real nasty when you don't have, */ /* or can't easily change, the kernel source code to . */ /* ------------------------------------------------------------------------ */ -int fr_scanlist(fin, pass) -fr_info_t *fin; -u_32_t pass; +int +ipf_scanlist(fin, pass) + fr_info_t *fin; + u_32_t pass; { + ipf_main_softc_t *softc = fin->fin_main_soft; int rulen, portcmp, off, skip; struct frentry *fr, *fnext; u_32_t passt, passo; @@ -1997,7 +2417,7 @@ u_32_t pass; for (rulen = 0; fr; fr = fnext, rulen++) { fnext = fr->fr_next; if (skip != 0) { - FR_VERBOSE(("%d (%#x)\n", skip, fr->fr_flags)); + FR_VERBOSE(("SKIP %d (%#x)\n", skip, fr->fr_flags)); skip--; continue; } @@ -2027,27 +2447,29 @@ u_32_t pass; switch (fr->fr_type) { case FR_T_IPF : - case FR_T_IPF|FR_T_BUILTIN : - if (fr_ipfcheck(fin, fr, portcmp)) + case FR_T_IPF_BUILTIN : + if (ipf_check_ipf(fin, fr, portcmp)) continue; break; #if defined(IPFILTER_BPF) case FR_T_BPFOPC : - case FR_T_BPFOPC|FR_T_BUILTIN : + case FR_T_BPFOPC_BUILTIN : { u_char *mc; + int wlen; if (*fin->fin_mp == NULL) continue; - if (fin->fin_v != fr->fr_v) + if (fin->fin_family != fr->fr_family) continue; mc = (u_char *)fin->fin_m; - if (!bpf_filter(fr->fr_data, mc, fin->fin_plen, 0)) + wlen = fin->fin_dlen + fin->fin_hlen; + if (!bpf_filter(fr->fr_data, mc, wlen, 0)) continue; break; } #endif - case FR_T_CALLFUNC|FR_T_BUILTIN : + case FR_T_CALLFUNC_BUILTIN : { frentry_t *f; @@ -2058,6 +2480,15 @@ u_32_t pass; continue; break; } + + case FR_T_IPFEXPR : + case FR_T_IPFEXPR_BUILTIN : + if (fin->fin_family != fr->fr_family) + continue; + if (ipf_fr_matcharray(fin, fr->fr_data) == 0) + continue; + break; + default : break; } @@ -2065,22 +2496,13 @@ u_32_t pass; if ((fin->fin_out == 0) && (fr->fr_nattag.ipt_num[0] != 0)) { if (fin->fin_nattag == NULL) continue; - if (fr_matchtag(&fr->fr_nattag, fin->fin_nattag) == 0) + if (ipf_matchtag(&fr->fr_nattag, fin->fin_nattag) == 0) continue; } - FR_VERBOSE(("=%s.%d *", fr->fr_group, rulen)); + FR_VERBOSE(("=%d/%d.%d *", fr->fr_grhead, fr->fr_group, rulen)); passt = fr->fr_flags; - /* - * Allowing a rule with the "keep state" flag set to match - * packets that have been tagged "out of window" by the TCP - * state tracking is foolish as the attempt to add a new - * state entry to the table will fail. - */ - if ((passt & FR_KEEPSTATE) && (fin->fin_flx & FI_OOW)) - continue; - /* * If the rule is a "call now" rule, then call the function * in the rule, if it exists and use the results from that. @@ -2091,7 +2513,7 @@ u_32_t pass; frentry_t *frs; ATOMIC_INC64(fr->fr_hits); - if ((fr->fr_func != NULL) && + if ((fr->fr_func == NULL) || (fr->fr_func == (ipfunc_t)-1)) continue; @@ -2111,43 +2533,69 @@ u_32_t pass; * Just log this packet... */ if ((passt & FR_LOGMASK) == FR_LOG) { - if (ipflog(fin, passt) == -1) { + if (ipf_log_pkt(fin, passt) == -1) { if (passt & FR_LOGORBLOCK) { + DT(frb_logfail); passt &= ~FR_CMDMASK; passt |= FR_BLOCK|FR_QUICK; + fin->fin_reason = FRB_LOGFAIL; } - ATOMIC_INCL(frstats[fin->fin_out].fr_skip); } - ATOMIC_INCL(frstats[fin->fin_out].fr_pkl); - fin->fin_flx |= FI_DONTCACHE; } #endif /* IPFILTER_LOG */ + + MUTEX_ENTER(&fr->fr_lock); fr->fr_bytes += (U_QUAD_T)fin->fin_plen; + fr->fr_hits++; + MUTEX_EXIT(&fr->fr_lock); + fin->fin_rule = rulen; + passo = pass; - if (FR_ISSKIP(passt)) + if (FR_ISSKIP(passt)) { skip = fr->fr_arg; - else if ((passt & FR_LOGMASK) != FR_LOG) + continue; + } else if (((passt & FR_LOGMASK) != FR_LOG) && + ((passt & FR_LOGMASK) != FR_DECAPSULATE)) { pass = passt; + } + if (passt & (FR_RETICMP|FR_FAKEICMP)) fin->fin_icode = fr->fr_icode; - FR_DEBUG(("pass %#x\n", pass)); - ATOMIC_INC64(fr->fr_hits); - fin->fin_rule = rulen; - (void) strncpy(fin->fin_group, fr->fr_group, FR_GROUPLEN); - if (fr->fr_grp != NULL) { - fin->fin_fr = *fr->fr_grp; - passt = fr_scanlist(fin, pass); + + if (fr->fr_group != -1) { + (void) strncpy(fin->fin_group, + FR_NAME(fr, fr_group), + strlen(FR_NAME(fr, fr_group))); + } else { + fin->fin_group[0] = '\0'; + } + + FR_DEBUG(("pass %#x/%#x/%x\n", passo, pass, passt)); + + if (fr->fr_grphead != NULL) { + fin->fin_fr = fr->fr_grphead->fg_start; + FR_VERBOSE(("group %s\n", FR_NAME(fr, fr_grhead))); + + if (FR_ISDECAPS(passt)) + passt = ipf_decaps(fin, pass, fr->fr_icode); + else + passt = ipf_scanlist(fin, pass); + if (fin->fin_fr == NULL) { fin->fin_rule = rulen; - (void) strncpy(fin->fin_group, fr->fr_group, - FR_GROUPLEN); + if (fr->fr_group != -1) + (void) strncpy(fin->fin_group, + fr->fr_names + + fr->fr_group, + strlen(fr->fr_names + + fr->fr_group)); fin->fin_fr = fr; passt = pass; } pass = passt; } - if (passt & FR_QUICK) { + if (pass & FR_QUICK) { /* * Finally, if we've asked to track state for this * packet, set it up. Add state for "quick" rules @@ -2155,15 +2603,15 @@ u_32_t pass; * the rule to "not match" and keep on processing * filter rules. */ - if ((pass & FR_KEEPSTATE) && + if ((pass & FR_KEEPSTATE) && !FR_ISAUTH(pass) && !(fin->fin_flx & FI_STATE)) { int out = fin->fin_out; fin->fin_fr = fr; - if (fr_addstate(fin, NULL, 0) != NULL) { - ATOMIC_INCL(frstats[out].fr_ads); + if (ipf_state_add(softc, fin, NULL, 0) == 0) { + LBUMPD(ipf_stats[out], fr_ads); } else { - ATOMIC_INCL(frstats[out].fr_bads); + LBUMPD(ipf_stats[out], fr_bads); pass = passo; continue; } @@ -2177,7 +2625,7 @@ u_32_t pass; /* ------------------------------------------------------------------------ */ -/* Function: fr_acctpkt */ +/* Function: ipf_acctpkt */ /* Returns: frentry_t* - always returns NULL */ /* Parameters: fin(I) - pointer to packet information */ /* passp(IO) - pointer to current/new filter decision (unused) */ @@ -2186,32 +2634,29 @@ u_32_t pass; /* IP protocol version. */ /* */ /* N.B.: this function returns NULL to match the prototype used by other */ -/* functions called from the IPFilter "mainline" in fr_check(). */ +/* functions called from the IPFilter "mainline" in ipf_check(). */ /* ------------------------------------------------------------------------ */ -frentry_t *fr_acctpkt(fin, passp) -fr_info_t *fin; -u_32_t *passp; +frentry_t * +ipf_acctpkt(fin, passp) + fr_info_t *fin; + u_32_t *passp; { + ipf_main_softc_t *softc = fin->fin_main_soft; char group[FR_GROUPLEN]; frentry_t *fr, *frsave; u_32_t pass, rulen; passp = passp; -#ifdef USE_INET6 - if (fin->fin_v == 6) - fr = ipacct6[fin->fin_out][fr_active]; - else -#endif - fr = ipacct[fin->fin_out][fr_active]; + fr = softc->ipf_acct[fin->fin_out][softc->ipf_active]; if (fr != NULL) { frsave = fin->fin_fr; bcopy(fin->fin_group, group, FR_GROUPLEN); rulen = fin->fin_rule; fin->fin_fr = fr; - pass = fr_scanlist(fin, FR_NOMATCH); + pass = ipf_scanlist(fin, FR_NOMATCH); if (FR_ISACCOUNT(pass)) { - ATOMIC_INCL(frstats[0].fr_acct); + LBUMPD(ipf_stats[0], fr_acct); } fin->fin_fr = frsave; bcopy(group, fin->fin_group, FR_GROUPLEN); @@ -2222,7 +2667,7 @@ u_32_t *passp; /* ------------------------------------------------------------------------ */ -/* Function: fr_firewall */ +/* Function: ipf_firewall */ /* Returns: frentry_t* - returns pointer to matched rule, if no matches */ /* were found, returns NULL. */ /* Parameters: fin(I) - pointer to packet information */ @@ -2234,12 +2679,13 @@ u_32_t *passp; /* matching rule is found, take any appropriate actions as defined by the */ /* rule - except logging. */ /* ------------------------------------------------------------------------ */ -static frentry_t *fr_firewall(fin, passp) -fr_info_t *fin; -u_32_t *passp; +static frentry_t * +ipf_firewall(fin, passp) + fr_info_t *fin; + u_32_t *passp; { + ipf_main_softc_t *softc = fin->fin_main_soft; frentry_t *fr; - fr_info_t *fc; u_32_t pass; int out; @@ -2247,56 +2693,28 @@ u_32_t *passp; pass = *passp; /* - * If a packet is found in the auth table, then skip checking - * the access lists for permission but we do need to consider - * the result as if it were from the ACL's. + * This rule cache will only affect packets that are not being + * statefully filtered. */ - fc = &frcache[out][CACHE_HASH(fin)]; - READ_ENTER(&ipf_frcache); - if (!bcmp((char *)fin, (char *)fc, FI_CSIZE)) { - /* - * copy cached data so we can unlock the mutexes earlier. - */ - bcopy((char *)fc, (char *)fin, FI_COPYSIZE); - RWLOCK_EXIT(&ipf_frcache); - ATOMIC_INCL(frstats[out].fr_chit); + fin->fin_fr = softc->ipf_rules[out][softc->ipf_active]; + if (fin->fin_fr != NULL) + pass = ipf_scanlist(fin, softc->ipf_pass); - if ((fr = fin->fin_fr) != NULL) { - ATOMIC_INC64(fr->fr_hits); - pass = fr->fr_flags; - } - } else { - RWLOCK_EXIT(&ipf_frcache); - -#ifdef USE_INET6 - if (fin->fin_v == 6) - fin->fin_fr = ipfilter6[out][fr_active]; - else -#endif - fin->fin_fr = ipfilter[out][fr_active]; - if (fin->fin_fr != NULL) - pass = fr_scanlist(fin, fr_pass); - - if (((pass & FR_KEEPSTATE) == 0) && - ((fin->fin_flx & FI_DONTCACHE) == 0)) { - WRITE_ENTER(&ipf_frcache); - bcopy((char *)fin, (char *)fc, FI_COPYSIZE); - RWLOCK_EXIT(&ipf_frcache); - } - if ((pass & FR_NOMATCH)) { - ATOMIC_INCL(frstats[out].fr_nom); - } - fr = fin->fin_fr; + if ((pass & FR_NOMATCH)) { + LBUMPD(ipf_stats[out], fr_nom); } + fr = fin->fin_fr; /* * Apply packets per second rate-limiting to a rule as required. */ if ((fr != NULL) && (fr->fr_pps != 0) && !ppsratecheck(&fr->fr_lastpkt, &fr->fr_curpps, fr->fr_pps)) { - pass &= ~(FR_CMDMASK|FR_DUP|FR_RETICMP|FR_RETRST); + DT2(frb_ppsrate, fr_info_t *, fin, frentry_t *, fr); + pass &= ~(FR_CMDMASK|FR_RETICMP|FR_RETRST); pass |= FR_BLOCK; - ATOMIC_INCL(frstats[out].fr_ppshit); + LBUMPD(ipf_stats[out], fr_ppshit); + fin->fin_reason = FRB_PPSRATE; } /* @@ -2305,15 +2723,15 @@ u_32_t *passp; * we've dropped it already. */ if (FR_ISAUTH(pass)) { - if (fr_newauth(fin->fin_m, fin) != 0) { -#ifdef _KERNEL + if (ipf_auth_new(fin->fin_m, fin) != 0) { + DT1(frb_authnew, fr_info_t *, fin); fin->fin_m = *fin->fin_mp = NULL; -#else - ; -#endif + fin->fin_reason = FRB_AUTHNEW; fin->fin_error = 0; - } else + } else { + IPFERROR(1); fin->fin_error = ENOSPC; + } } if ((fr != NULL) && (fr->fr_func != NULL) && @@ -2327,8 +2745,7 @@ u_32_t *passp; * is treated as "not a pass", hence the packet is blocked. */ if (FR_ISPREAUTH(pass)) { - if ((fin->fin_fr = ipauth) != NULL) - pass = fr_scanlist(fin, fr_pass); + pass = ipf_auth_pre_scanlist(softc, fin, pass); } /* @@ -2337,27 +2754,25 @@ u_32_t *passp; */ if ((pass & (FR_KEEPFRAG|FR_KEEPSTATE)) == FR_KEEPFRAG) { if (fin->fin_flx & FI_FRAG) { - if (fr_newfrag(fin, pass) == -1) { - ATOMIC_INCL(frstats[out].fr_bnfr); + if (ipf_frag_new(softc, fin, pass) == -1) { + LBUMP(ipf_stats[out].fr_bnfr); } else { - ATOMIC_INCL(frstats[out].fr_nfr); + LBUMP(ipf_stats[out].fr_nfr); } } else { - ATOMIC_INCL(frstats[out].fr_cfr); + LBUMP(ipf_stats[out].fr_cfr); } } fr = fin->fin_fr; - - if (passp != NULL) - *passp = pass; + *passp = pass; return fr; } /* ------------------------------------------------------------------------ */ -/* Function: fr_check */ +/* Function: ipf_check */ /* Returns: int - 0 == packet allowed through, */ /* User space: */ /* -1 == packet blocked */ @@ -2375,7 +2790,7 @@ u_32_t *passp; /* qpi(I) - pointer to STREAMS queue information for this */ /* interface & direction. */ /* */ -/* fr_check() is the master function for all IPFilter packet processing. */ +/* ipf_check() is the master function for all IPFilter packet processing. */ /* It orchestrates: Network Address Translation (NAT), checking for packet */ /* authorisation (or pre-authorisation), presence of related state info., */ /* generating log entries, IP packet accounting, routing of packets as */ @@ -2386,31 +2801,34 @@ u_32_t *passp; /* freed. Packets passed may be returned with the pointer pointed to by */ /* by "mp" changed to a new buffer. */ /* ------------------------------------------------------------------------ */ -int fr_check(ip, hlen, ifp, out +int +ipf_check(ctx, ip, hlen, ifp, out #if defined(_KERNEL) && defined(MENTAT) -, qif, mp) -void *qif; + , qif, mp) + void *qif; #else -, mp) + , mp) #endif -mb_t **mp; -ip_t *ip; -int hlen; -void *ifp; -int out; + mb_t **mp; + ip_t *ip; + int hlen; + void *ifp; + int out; + void *ctx; { /* * The above really sucks, but short of writing a diff */ + ipf_main_softc_t *softc = ctx; fr_info_t frinfo; fr_info_t *fin = &frinfo; - u_32_t pass = fr_pass; + u_32_t pass = softc->ipf_pass; frentry_t *fr = NULL; int v = IP_V(ip); mb_t *mc = NULL; mb_t *m; /* - * The first part of fr_check() deals with making sure that what goes + * The first part of ipf_check() deals with making sure that what goes * into the filtering engine makes some sense. Information about the * the packet is distilled, collected into a fr_info_t structure and * the an attempt to ensure the buffer the packet is in is big enough @@ -2420,7 +2838,7 @@ int out; # ifdef MENTAT qpktinfo_t *qpi = qif; -# if !defined(_INET_IP_STACK_H) +# ifdef __sparc if ((u_int)ip & 0x3) return 2; # endif @@ -2428,18 +2846,17 @@ int out; SPL_INT(s); # endif - READ_ENTER(&ipf_global); - - if (fr_running <= 0) { - RWLOCK_EXIT(&ipf_global); + if (softc->ipf_running <= 0) { return 0; } bzero((char *)fin, sizeof(*fin)); # ifdef MENTAT - if (qpi->qpi_flags & QF_GROUP) - fin->fin_flx |= FI_MBCAST; + if (qpi->qpi_flags & QF_BROADCAST) + fin->fin_flx |= FI_MBCAST|FI_BROADCAST; + if (qpi->qpi_flags & QF_MULTICAST) + fin->fin_flx |= FI_MBCAST|FI_MULTICAST; m = qpi->qpi_m; fin->fin_qfm = m; fin->fin_qpi = qpi; @@ -2467,7 +2884,8 @@ int out; */ m->m_flags &= ~M_CANFASTFWD; # endif /* M_CANFASTFWD */ -# ifdef CSUM_DELAY_DATA +# if defined(CSUM_DELAY_DATA) && (!defined(__FreeBSD_version) || \ + (__FreeBSD_version < 501108)) /* * disable delayed checksums. */ @@ -2478,10 +2896,20 @@ int out; # endif /* CSUM_DELAY_DATA */ # endif /* MENTAT */ #else - READ_ENTER(&ipf_global); - bzero((char *)fin, sizeof(*fin)); m = *mp; +# if defined(M_MCAST) + if ((m->m_flags & M_MCAST) != 0) + fin->fin_flx |= FI_MBCAST|FI_MULTICAST; +# endif +# if defined(M_MLOOP) + if ((m->m_flags & M_MLOOP) != 0) + fin->fin_flx |= FI_MBCAST|FI_MULTICAST; +# endif +# if defined(M_BCAST) + if ((m->m_flags & M_BCAST) != 0) + fin->fin_flx |= FI_MBCAST|FI_BROADCAST; +# endif #endif /* _KERNEL */ fin->fin_v = v; @@ -2493,6 +2921,7 @@ int out; fin->fin_error = ENETUNREACH; fin->fin_hlen = (u_short)hlen; fin->fin_dp = (char *)ip + hlen; + fin->fin_main_soft = softc; fin->fin_ipoff = (char *)ip - MTOD(m, char *); @@ -2500,27 +2929,29 @@ int out; #ifdef USE_INET6 if (v == 6) { - ATOMIC_INCL(frstats[out].fr_ipv6); + LBUMP(ipf_stats[out].fr_ipv6); /* * Jumbo grams are quite likely too big for internal buffer * structures to handle comfortably, for now, so just drop * them. */ if (((ip6_t *)ip)->ip6_plen == 0) { + DT1(frb_jumbo, ip6_t *, (ip6_t *)ip); pass = FR_BLOCK|FR_NOMATCH; + fin->fin_reason = FRB_JUMBO; goto finished; } + fin->fin_family = AF_INET6; } else #endif { -#if ((defined(OpenBSD) && (OpenBSD >= 200311)) || (__FreeBSD_version >= 1000019)) && defined(_KERNEL) - ip->ip_len = ntohs(ip->ip_len); - ip->ip_off = ntohs(ip->ip_off); -#endif + fin->fin_family = AF_INET; } - if (fr_makefrip(hlen, ip, fin) == -1) { + if (ipf_makefrip(hlen, ip, fin) == -1) { + DT1(frb_makefrip, fr_info_t *, fin); pass = FR_BLOCK|FR_NOMATCH; + fin->fin_reason = FRB_MAKEFRIP; goto finished; } @@ -2533,21 +2964,19 @@ int out; if (!out) { if (v == 4) { -#ifdef _KERNEL - if (fr_chksrc && !fr_verifysrc(fin)) { - ATOMIC_INCL(frstats[0].fr_badsrc); + if (softc->ipf_chksrc && !ipf_verifysrc(fin)) { + LBUMPD(ipf_stats[0], fr_v4_badsrc); fin->fin_flx |= FI_BADSRC; } -#endif - if (fin->fin_ip->ip_ttl < fr_minttl) { - ATOMIC_INCL(frstats[0].fr_badttl); + if (fin->fin_ip->ip_ttl < softc->ipf_minttl) { + LBUMPD(ipf_stats[0], fr_v4_badttl); fin->fin_flx |= FI_LOWTTL; } } #ifdef USE_INET6 else if (v == 6) { - if (((ip6_t *)ip)->ip6_hlim < fr_minttl) { - ATOMIC_INCL(frstats[0].fr_badttl); + if (((ip6_t *)ip)->ip6_hlim < softc->ipf_minttl) { + LBUMPD(ipf_stats[0], fr_v6_badttl); fin->fin_flx |= FI_LOWTTL; } } @@ -2555,120 +2984,135 @@ int out; } if (fin->fin_flx & FI_SHORT) { - ATOMIC_INCL(frstats[out].fr_short); + LBUMPD(ipf_stats[out], fr_short); } - READ_ENTER(&ipf_mutex); + READ_ENTER(&softc->ipf_mutex); - /* - * Check auth now. This, combined with the check below to see if apass - * is 0 is to ensure that we don't count the packet twice, which can - * otherwise occur when we reprocess it. As it is, we only count it - * after it has no auth. table matchup. This also stops NAT from - * occuring until after the packet has been auth'd. - */ - fr = fr_checkauth(fin, &pass); if (!out) { - if (fr_checknatin(fin, &pass) == -1) { - goto filterdone; + switch (fin->fin_v) + { + case 4 : + if (ipf_nat_checkin(fin, &pass) == -1) { + goto filterdone; + } + break; +#ifdef USE_INET6 + case 6 : + if (ipf_nat6_checkin(fin, &pass) == -1) { + goto filterdone; + } + break; +#endif + default : + break; } } - if (!out) - (void) fr_acctpkt(fin, NULL); + /* + * Check auth now. + * If a packet is found in the auth table, then skip checking + * the access lists for permission but we do need to consider + * the result as if it were from the ACL's. In addition, being + * found in the auth table means it has been seen before, so do + * not pass it through accounting (again), lest it be counted twice. + */ + fr = ipf_auth_check(fin, &pass); + if (!out && (fr == NULL)) + (void) ipf_acctpkt(fin, NULL); if (fr == NULL) { - if ((fin->fin_flx & (FI_FRAG|FI_BAD)) == FI_FRAG) { - fr = fr_knownfrag(fin, &pass); - /* - * Reset the keep state flag here so that we don't - * try and add a new state entry because of it, leading - * to a blocked packet because the add will fail. - */ - if (fr != NULL) - pass &= ~FR_KEEPSTATE; - } + if ((fin->fin_flx & FI_FRAG) != 0) + fr = ipf_frag_known(fin, &pass); + if (fr == NULL) - fr = fr_checkstate(fin, &pass); + fr = ipf_state_check(fin, &pass); } if ((pass & FR_NOMATCH) || (fr == NULL)) - fr = fr_firewall(fin, &pass); + fr = ipf_firewall(fin, &pass); /* * If we've asked to track state for this packet, set it up. - * Here rather than fr_firewall because fr_checkauth may decide + * Here rather than ipf_firewall because ipf_checkauth may decide * to return a packet for "keep state" */ if ((pass & FR_KEEPSTATE) && (fin->fin_m != NULL) && !(fin->fin_flx & FI_STATE)) { - if (fr_addstate(fin, NULL, 0) != NULL) { - ATOMIC_INCL(frstats[out].fr_ads); + if (ipf_state_add(softc, fin, NULL, 0) == 0) { + LBUMP(ipf_stats[out].fr_ads); } else { - ATOMIC_INCL(frstats[out].fr_bads); + LBUMP(ipf_stats[out].fr_bads); if (FR_ISPASS(pass)) { + DT(frb_stateadd); pass &= ~FR_CMDMASK; pass |= FR_BLOCK; + fin->fin_reason = FRB_STATEADD; } } } fin->fin_fr = fr; + if ((fr != NULL) && !(fin->fin_flx & FI_STATE)) { + fin->fin_dif = &fr->fr_dif; + fin->fin_tif = &fr->fr_tifs[fin->fin_rev]; + } /* * Only count/translate packets which will be passed on, out the * interface. */ if (out && FR_ISPASS(pass)) { - (void) fr_acctpkt(fin, NULL); + (void) ipf_acctpkt(fin, NULL); - if (fr_checknatout(fin, &pass) == -1) { - ; - } else if ((fr_update_ipid != 0) && (v == 4)) { - if (fr_updateipid(fin) == -1) { - ATOMIC_INCL(frstats[1].fr_ipud); - pass &= ~FR_CMDMASK; - pass |= FR_BLOCK; - } else { - ATOMIC_INCL(frstats[0].fr_ipud); + switch (fin->fin_v) + { + case 4 : + if (ipf_nat_checkout(fin, &pass) == -1) { + ; + } else if ((softc->ipf_update_ipid != 0) && (v == 4)) { + if (ipf_updateipid(fin) == -1) { + DT(frb_updateipid); + LBUMP(ipf_stats[1].fr_ipud); + pass &= ~FR_CMDMASK; + pass |= FR_BLOCK; + fin->fin_reason = FRB_UPDATEIPID; + } else { + LBUMP(ipf_stats[0].fr_ipud); + } } + break; +#ifdef USE_INET6 + case 6 : + (void) ipf_nat6_checkout(fin, &pass); + break; +#endif + default : + break; } } filterdone: #ifdef IPFILTER_LOG - if ((fr_flags & FF_LOGGING) || (pass & FR_LOGMASK)) { - (void) fr_dolog(fin, &pass); + if ((softc->ipf_flags & FF_LOGGING) || (pass & FR_LOGMASK)) { + (void) ipf_dolog(fin, &pass); } #endif /* - * The FI_STATE flag is cleared here so that calling fr_checkstate + * The FI_STATE flag is cleared here so that calling ipf_state_check * will work when called from inside of fr_fastroute. Although * there is a similar flag, FI_NATED, for NAT, it does have the same * impact on code execution. */ - if (fin->fin_state != NULL) { - fr_statederef((ipstate_t **)&fin->fin_state); - fin->fin_flx ^= FI_STATE; - } - - if (fin->fin_nat != NULL) { - if (FR_ISBLOCK(pass) && (fin->fin_flx & FI_NEWNAT)) { - WRITE_ENTER(&ipf_nat); - nat_delete((nat_t *)fin->fin_nat, NL_DESTROY); - RWLOCK_EXIT(&ipf_nat); - fin->fin_nat = NULL; - } else { - fr_natderef((nat_t **)&fin->fin_nat); - } - } + fin->fin_flx &= ~FI_STATE; +#if defined(FASTROUTE_RECURSION) /* - * Up the reference on fr_lock and exit ipf_mutex. fr_fastroute - * only frees up the lock on ipf_global and the generation of a - * packet below could cause a recursive call into IPFilter. - * Hang onto the filter rule just in case someone decides to remove - * or flush it in the meantime. + * Up the reference on fr_lock and exit ipf_mutex. The generation of + * a packet below can sometimes cause a recursive call into IPFilter. + * On those platforms where that does happen, we need to hang onto + * the filter rule just in case someone decides to remove or flush it + * in the meantime. */ if (fr != NULL) { MUTEX_ENTER(&fr->fr_lock); @@ -2676,16 +3120,17 @@ int out; MUTEX_EXIT(&fr->fr_lock); } - RWLOCK_EXIT(&ipf_mutex); + RWLOCK_EXIT(&softc->ipf_mutex); +#endif if ((pass & FR_RETMASK) != 0) { /* * Should we return an ICMP packet to indicate error * status passing through the packet filter ? * WARNING: ICMP error packets AND TCP RST packets should - * ONLY be sent in repsonse to incoming packets. Sending them - * in response to outbound packets can result in a panic on - * some operating systems. + * ONLY be sent in repsonse to incoming packets. Sending + * them in response to outbound packets can result in a + * panic on some operating systems. */ if (!out) { if (pass & FR_RETICMP) { @@ -2695,13 +3140,14 @@ int out; dst = 1; else dst = 0; - (void) fr_send_icmp_err(ICMP_UNREACH, fin, dst); - ATOMIC_INCL(frstats[0].fr_ret); + (void) ipf_send_icmp_err(ICMP_UNREACH, fin, + dst); + LBUMP(ipf_stats[0].fr_ret); } else if (((pass & FR_RETMASK) == FR_RETRST) && !(fin->fin_flx & FI_SHORT)) { if (((fin->fin_flx & FI_OOW) != 0) || - (fr_send_reset(fin) == 0)) { - ATOMIC_INCL(frstats[1].fr_ret); + (ipf_send_reset(fin) == 0)) { + LBUMP(ipf_stats[1].fr_ret); } } @@ -2710,61 +3156,81 @@ int out; * takes over disposing of this packet. */ if (FR_ISAUTH(pass) && (fin->fin_m != NULL)) { + DT1(frb_authcapture, fr_info_t *, fin); fin->fin_m = *fin->fin_mp = NULL; + fin->fin_reason = FRB_AUTHCAPTURE; + m = NULL; } } else { - if (pass & FR_RETRST) + if (pass & FR_RETRST) { fin->fin_error = ECONNRESET; + } } } + /* + * After the above so that ICMP unreachables and TCP RSTs get + * created properly. + */ + if (FR_ISBLOCK(pass) && (fin->fin_flx & FI_NEWNAT)) + ipf_nat_uncreate(fin); + /* * If we didn't drop off the bottom of the list of rules (and thus * the 'current' rule fr is not NULL), then we may have some extra * instructions about what to do with a packet. * Once we're finished return to our caller, freeing the packet if - * we are dropping it (* BSD ONLY *). + * we are dropping it. */ if (fr != NULL) { frdest_t *fdp; - fdp = &fr->fr_tifs[fin->fin_rev]; + /* + * Generate a duplicated packet first because ipf_fastroute + * can lead to fin_m being free'd... not good. + */ + fdp = fin->fin_dif; + if ((fdp != NULL) && (fdp->fd_ptr != NULL) && + (fdp->fd_ptr != (void *)-1)) { + mc = M_COPY(fin->fin_m); + if (mc != NULL) + ipf_fastroute(mc, &mc, fin, fdp); + } + fdp = fin->fin_tif; if (!out && (pass & FR_FASTROUTE)) { /* - * For fastroute rule, no destioation interface defined + * For fastroute rule, no destination interface defined * so pass NULL as the frdest_t parameter */ - (void) fr_fastroute(fin->fin_m, mp, fin, NULL); + (void) ipf_fastroute(fin->fin_m, mp, fin, NULL); m = *mp = NULL; - } else if ((fdp->fd_ifp != NULL) && - (fdp->fd_ifp != (struct ifnet *)-1)) { + } else if ((fdp != NULL) && (fdp->fd_ptr != NULL) && + (fdp->fd_ptr != (struct ifnet *)-1)) { /* this is for to rules: */ - (void) fr_fastroute(fin->fin_m, mp, fin, fdp); + ipf_fastroute(fin->fin_m, mp, fin, fdp); m = *mp = NULL; } - /* - * Generate a duplicated packet. - */ - if ((pass & FR_DUP) != 0) { - mc = M_DUPLICATE(fin->fin_m); - if (mc != NULL) - (void) fr_fastroute(mc, &mc, fin, &fr->fr_dif); - } - - (void) fr_derefrule(&fr); +#if defined(FASTROUTE_RECURSION) + (void) ipf_derefrule(softc, &fr); +#endif } +#if !defined(FASTROUTE_RECURSION) + RWLOCK_EXIT(&softc->ipf_mutex); +#endif finished: if (!FR_ISPASS(pass)) { - ATOMIC_INCL(frstats[out].fr_block); + LBUMP(ipf_stats[out].fr_block); if (*mp != NULL) { +#ifdef _KERNEL FREE_MB_T(*mp); +#endif m = *mp = NULL; } } else { - ATOMIC_INCL(frstats[out].fr_pass); + LBUMP(ipf_stats[out].fr_pass); #if defined(_KERNEL) && defined(__sgi) if ((fin->fin_hbuf != NULL) && (mtod(fin->fin_m, struct ip *) != fin->fin_ip)) { @@ -2774,21 +3240,20 @@ int out; } SPL_X(s); - RWLOCK_EXIT(&ipf_global); #ifdef _KERNEL -# if (defined(OpenBSD) && (OpenBSD >= 200311)) || (__FreeBSD_version >= 1000019) - if (FR_ISPASS(pass) && (v == 4)) { - ip = fin->fin_ip; - ip->ip_len = ntohs(ip->ip_len); - ip->ip_off = ntohs(ip->ip_off); - } -# endif - return (FR_ISPASS(pass)) ? 0 : fin->fin_error; + if (FR_ISPASS(pass)) + return 0; + LBUMP(ipf_stats[out].fr_blocked[fin->fin_reason]); + return fin->fin_error; #else /* _KERNEL */ + if (*mp != NULL) + (*mp)->mb_ifp = fin->fin_ifp; + blockreason = fin->fin_reason; FR_VERBOSE(("fin_flx %#x pass %#x ", fin->fin_flx, pass)); - if ((pass & FR_NOMATCH) != 0) - return 1; + /*if ((pass & FR_CMDMASK) == (softc->ipf_pass & FR_CMDMASK))*/ + if ((pass & FR_NOMATCH) != 0) + return 1; if ((pass & FR_RETMASK) != 0) switch (pass & FR_RETMASK) @@ -2821,7 +3286,7 @@ int out; #ifdef IPFILTER_LOG /* ------------------------------------------------------------------------ */ -/* Function: fr_dolog */ +/* Function: ipf_dolog */ /* Returns: frentry_t* - returns contents of fin_fr (no change made) */ /* Parameters: fin(I) - pointer to packet information */ /* passp(IO) - pointer to current/new filter decision (unused) */ @@ -2829,43 +3294,47 @@ int out; /* Checks flags set to see how a packet should be logged, if it is to be */ /* logged. Adjust statistics based on its success or not. */ /* ------------------------------------------------------------------------ */ -frentry_t *fr_dolog(fin, passp) -fr_info_t *fin; -u_32_t *passp; +frentry_t * +ipf_dolog(fin, passp) + fr_info_t *fin; + u_32_t *passp; { + ipf_main_softc_t *softc = fin->fin_main_soft; u_32_t pass; int out; out = fin->fin_out; pass = *passp; - if ((fr_flags & FF_LOGNOMATCH) && (pass & FR_NOMATCH)) { + if ((softc->ipf_flags & FF_LOGNOMATCH) && (pass & FR_NOMATCH)) { pass |= FF_LOGNOMATCH; - ATOMIC_INCL(frstats[out].fr_npkl); + LBUMPD(ipf_stats[out], fr_npkl); goto logit; + } else if (((pass & FR_LOGMASK) == FR_LOGP) || - (FR_ISPASS(pass) && (fr_flags & FF_LOGPASS))) { + (FR_ISPASS(pass) && (softc->ipf_flags & FF_LOGPASS))) { if ((pass & FR_LOGMASK) != FR_LOGP) pass |= FF_LOGPASS; - ATOMIC_INCL(frstats[out].fr_ppkl); + LBUMPD(ipf_stats[out], fr_ppkl); goto logit; + } else if (((pass & FR_LOGMASK) == FR_LOGB) || - (FR_ISBLOCK(pass) && (fr_flags & FF_LOGBLOCK))) { + (FR_ISBLOCK(pass) && (softc->ipf_flags & FF_LOGBLOCK))) { if ((pass & FR_LOGMASK) != FR_LOGB) pass |= FF_LOGBLOCK; - ATOMIC_INCL(frstats[out].fr_bpkl); -logit: - if (ipflog(fin, pass) == -1) { - ATOMIC_INCL(frstats[out].fr_skip); + LBUMPD(ipf_stats[out], fr_bpkl); +logit: + if (ipf_log_pkt(fin, pass) == -1) { /* * If the "or-block" option has been used then * block the packet if we failed to log it. */ - if ((pass & FR_LOGORBLOCK) && - FR_ISPASS(pass)) { + if ((pass & FR_LOGORBLOCK) && FR_ISPASS(pass)) { + DT1(frb_logfail2, u_int, pass); pass &= ~FR_CMDMASK; pass |= FR_BLOCK; + fin->fin_reason = FRB_LOGFAIL2; } } *passp = pass; @@ -2886,9 +3355,10 @@ u_32_t *passp; /* */ /* N.B.: addr should be 16bit aligned. */ /* ------------------------------------------------------------------------ */ -u_short ipf_cksum(addr, len) -u_short *addr; -int len; +u_short +ipf_cksum(addr, len) + u_short *addr; + int len; { u_32_t sum = 0; @@ -2911,11 +3381,10 @@ int len; /* ------------------------------------------------------------------------ */ /* Function: fr_cksum */ /* Returns: u_short - layer 4 checksum */ -/* Parameters: m(I ) - pointer to buffer holding packet */ +/* Parameters: fin(I) - pointer to packet information */ /* ip(I) - pointer to IP header */ /* l4proto(I) - protocol to caclulate checksum for */ /* l4hdr(I) - pointer to layer 4 header */ -/* l3len(I) - length of layer 4 data plus layer 3 header */ /* */ /* Calculates the TCP checksum for the packet held in "m", using the data */ /* in the IP header "ip" to seed it. */ @@ -2924,31 +3393,31 @@ int len; /* and the TCP header. We also assume that data blocks aren't allocated in */ /* odd sizes. */ /* */ -/* For IPv6, l3len excludes extension header size. */ -/* */ -/* Expects ip_len to be in host byte order when called. */ +/* Expects ip_len and ip_off to be in network byte order when called. */ /* ------------------------------------------------------------------------ */ -u_short fr_cksum(m, ip, l4proto, l4hdr, l3len) -mb_t *m; -ip_t *ip; -int l4proto, l3len; -void *l4hdr; +u_short +fr_cksum(fin, ip, l4proto, l4hdr) + fr_info_t *fin; + ip_t *ip; + int l4proto; + void *l4hdr; { - u_short *sp, slen, sumsave, l4hlen, *csump; + u_short *sp, slen, sumsave, *csump; u_int sum, sum2; int hlen; + int off; #ifdef USE_INET6 ip6_t *ip6; #endif csump = NULL; sumsave = 0; - l4hlen = 0; sp = NULL; slen = 0; hlen = 0; sum = 0; + sum = htons((u_short)l4proto); /* * Add up IP Header portion */ @@ -2956,9 +3425,7 @@ void *l4hdr; if (IP_V(ip) == 4) { #endif hlen = IP_HL(ip) << 2; - slen = l3len - hlen; - sum = htons((u_short)l4proto); - sum += htons(slen); + off = hlen; sp = (u_short *)&ip->ip_src; sum += *sp++; /* ip_src */ sum += *sp++; @@ -2968,9 +3435,7 @@ void *l4hdr; } else if (IP_V(ip) == 6) { ip6 = (ip6_t *)ip; hlen = sizeof(*ip6); - slen = l3len - hlen; - sum = htons((u_short)l4proto); - sum += htons(slen); + off = ((char *)fin->fin_dp - (char *)fin->fin_ip); sp = (u_short *)&ip6->ip6_src; sum += *sp++; /* ip6_src */ sum += *sp++; @@ -2980,6 +3445,7 @@ void *l4hdr; sum += *sp++; sum += *sp++; sum += *sp++; + /* This needs to be routing header aware. */ sum += *sp++; /* ip6_dst */ sum += *sp++; sum += *sp++; @@ -2988,25 +3454,31 @@ void *l4hdr; sum += *sp++; sum += *sp++; sum += *sp++; + } else { + return 0xffff; } #endif + slen = fin->fin_plen - off; + sum += htons(slen); switch (l4proto) { case IPPROTO_UDP : csump = &((udphdr_t *)l4hdr)->uh_sum; - l4hlen = sizeof(udphdr_t); break; case IPPROTO_TCP : csump = &((tcphdr_t *)l4hdr)->th_sum; - l4hlen = sizeof(tcphdr_t); break; case IPPROTO_ICMP : csump = &((icmphdr_t *)l4hdr)->icmp_cksum; - l4hlen = 4; - sum = 0; + sum = 0; /* Pseudo-checksum is not included */ break; +#ifdef USE_INET6 + case IPPROTO_ICMPV6 : + csump = &((struct icmp6_hdr *)l4hdr)->icmp6_cksum; + break; +#endif default : break; } @@ -3016,298 +3488,18 @@ void *l4hdr; *csump = 0; } - l4hlen = l4hlen; /* LINT */ - -#ifdef _KERNEL -# ifdef MENTAT - { - void *rp = m->b_rptr; - - if ((unsigned char *)ip > m->b_rptr && (unsigned char *)ip < m->b_wptr) - m->b_rptr = (u_char *)ip; - sum2 = ip_cksum(m, hlen, sum); /* hlen == offset */ - m->b_rptr = rp; - sum2 = (u_short)(~sum2 & 0xffff); - } -# else /* MENTAT */ -# if defined(BSD) || defined(sun) -# if BSD >= 199103 - m->m_data += hlen; -# else - m->m_off += hlen; -# endif - m->m_len -= hlen; - sum2 = in_cksum(m, slen); - m->m_len += hlen; -# if BSD >= 199103 - m->m_data -= hlen; -# else - m->m_off -= hlen; -# endif - /* - * Both sum and sum2 are partial sums, so combine them together. - */ - sum += ~sum2 & 0xffff; - while (sum > 0xffff) - sum = (sum & 0xffff) + (sum >> 16); - sum2 = ~sum & 0xffff; -# else /* defined(BSD) || defined(sun) */ -{ - union { - u_char c[2]; - u_short s; - } bytes; - u_short len = ip->ip_len; -# if defined(__sgi) - int add; -# endif - - /* - * Add up IP Header portion - */ - if (sp != (u_short *)l4hdr) - sp = (u_short *)l4hdr; - - switch (l4proto) - { - case IPPROTO_UDP : - sum += *sp++; /* sport */ - sum += *sp++; /* dport */ - sum += *sp++; /* udp length */ - sum += *sp++; /* checksum */ - break; - - case IPPROTO_TCP : - sum += *sp++; /* sport */ - sum += *sp++; /* dport */ - sum += *sp++; /* seq */ - sum += *sp++; - sum += *sp++; /* ack */ - sum += *sp++; - sum += *sp++; /* off */ - sum += *sp++; /* win */ - sum += *sp++; /* checksum */ - sum += *sp++; /* urp */ - break; - case IPPROTO_ICMP : - sum = *sp++; /* type/code */ - sum += *sp++; /* checksum */ - break; - } - -# ifdef __sgi - /* - * In case we had to copy the IP & TCP header out of mbufs, - * skip over the mbuf bits which are the header - */ - if ((char *)ip != mtod(m, char *)) { - hlen = (char *)sp - (char *)ip; - while (hlen) { - add = MIN(hlen, m->m_len); - sp = (u_short *)(mtod(m, caddr_t) + add); - hlen -= add; - if (add == m->m_len) { - m = m->m_next; - if (!hlen) { - if (!m) - break; - sp = mtod(m, u_short *); - } - PANIC((!m),("fr_cksum(1): not enough data")); - } - } - } -# endif - - len -= (l4hlen + hlen); - if (len <= 0) - goto nodata; - - while (len > 1) { - if (((char *)sp - mtod(m, char *)) >= m->m_len) { - m = m->m_next; - PANIC((!m),("fr_cksum(2): not enough data")); - sp = mtod(m, u_short *); - } - if (((char *)(sp + 1) - mtod(m, char *)) > m->m_len) { - bytes.c[0] = *(u_char *)sp; - m = m->m_next; - PANIC((!m),("fr_cksum(3): not enough data")); - sp = mtod(m, u_short *); - bytes.c[1] = *(u_char *)sp; - sum += bytes.s; - sp = (u_short *)((u_char *)sp + 1); - } - if ((u_long)sp & 1) { - bcopy((char *)sp++, (char *)&bytes.s, sizeof(bytes.s)); - sum += bytes.s; - } else - sum += *sp++; - len -= 2; - } - - if (len != 0) - sum += ntohs(*(u_char *)sp << 8); -nodata: - while (sum > 0xffff) - sum = (sum & 0xffff) + (sum >> 16); - sum2 = (u_short)(~sum & 0xffff); -} -# endif /* defined(BSD) || defined(sun) */ -# endif /* MENTAT */ -#else /* _KERNEL */ - /* - * Add up IP Header portion - */ - if (sp != (u_short *)l4hdr) - sp = (u_short *)l4hdr; - - for (; slen > 1; slen -= 2) - sum += *sp++; - if (slen) - sum += ntohs(*(u_char *)sp << 8); - while (sum > 0xffff) - sum = (sum & 0xffff) + (sum >> 16); - sum2 = (u_short)(~sum & 0xffff); -#endif /* _KERNEL */ + sum2 = ipf_pcksum(fin, off, sum); if (csump != NULL) *csump = sumsave; return sum2; } -#if defined(_KERNEL) && ( ((BSD < 199103) && !defined(MENTAT)) || \ - defined(__sgi) ) && !defined(linux) && !defined(_AIX51) -/* - * Copyright (c) 1982, 1986, 1988, 1991, 1993 - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * @(#)uipc_mbuf.c 8.2 (Berkeley) 1/4/94 - * $Id: fil.c,v 2.243.2.125 2007/10/10 09:27:20 darrenr Exp $ - */ -/* - * Copy data from an mbuf chain starting "off" bytes from the beginning, - * continuing for "len" bytes, into the indicated buffer. - */ -void -m_copydata(m, off, len, cp) - mb_t *m; - int off; - int len; - caddr_t cp; -{ - unsigned count; - - if (off < 0 || len < 0) - panic("m_copydata"); - while (off > 0) { - if (m == 0) - panic("m_copydata"); - if (off < m->m_len) - break; - off -= m->m_len; - m = m->m_next; - } - while (len > 0) { - if (m == 0) - panic("m_copydata"); - count = MIN(m->m_len - off, len); - bcopy(mtod(m, caddr_t) + off, cp, count); - len -= count; - cp += count; - off = 0; - m = m->m_next; - } -} - - -/* - * Copy data from a buffer back into the indicated mbuf chain, - * starting "off" bytes from the beginning, extending the mbuf - * chain if necessary. - */ -void -m_copyback(m0, off, len, cp) - struct mbuf *m0; - int off; - int len; - caddr_t cp; -{ - int mlen; - struct mbuf *m = m0, *n; - int totlen = 0; - - if (m0 == 0) - return; - while (off > (mlen = m->m_len)) { - off -= mlen; - totlen += mlen; - if (m->m_next == 0) { - n = m_getclr(M_DONTWAIT, m->m_type); - if (n == 0) - goto out; - n->m_len = min(MLEN, len + off); - m->m_next = n; - } - m = m->m_next; - } - while (len > 0) { - mlen = min(m->m_len - off, len); - bcopy(cp, off + mtod(m, caddr_t), (unsigned)mlen); - cp += mlen; - len -= mlen; - mlen += off; - off = 0; - totlen += mlen; - if (len == 0) - break; - if (m->m_next == 0) { - n = m_get(M_DONTWAIT, m->m_type); - if (n == 0) - break; - n->m_len = min(MLEN, len); - m->m_next = n; - } - m = m->m_next; - } -out: -#if 0 - if (((m = m0)->m_flags & M_PKTHDR) && (m->m_pkthdr.len < totlen)) - m->m_pkthdr.len = totlen; -#endif - return; -} -#endif /* (_KERNEL) && ( ((BSD < 199103) && !MENTAT) || __sgi) */ - - /* ------------------------------------------------------------------------ */ -/* Function: fr_findgroup */ +/* Function: ipf_findgroup */ /* Returns: frgroup_t * - NULL = group not found, else pointer to group */ -/* Parameters: group(I) - group name to search for */ +/* Parameters: softc(I) - pointer to soft context main structure */ +/* group(I) - group name to search for */ /* unit(I) - device to which this group belongs */ /* set(I) - which set of rules (inactive/inactive) this is */ /* fgpp(O) - pointer to place to store pointer to the pointer */ @@ -3316,11 +3508,13 @@ m_copyback(m0, off, len, cp) /* */ /* Search amongst the defined groups for a particular group number. */ /* ------------------------------------------------------------------------ */ -frgroup_t *fr_findgroup(group, unit, set, fgpp) -char *group; -minor_t unit; -int set; -frgroup_t ***fgpp; +frgroup_t * +ipf_findgroup(softc, group, unit, set, fgpp) + ipf_main_softc_t *softc; + char *group; + minor_t unit; + int set; + frgroup_t ***fgpp; { frgroup_t *fg, **fgp; @@ -3328,7 +3522,7 @@ frgroup_t ***fgpp; * Which list of groups to search in is dependent on which list of * rules are being operated on. */ - fgp = &ipfgroups[unit][set]; + fgp = &softc->ipf_groups[unit][set]; while ((fg = *fgp) != NULL) { if (strncmp(group, fg->fg_name, FR_GROUPLEN) == 0) @@ -3343,10 +3537,11 @@ frgroup_t ***fgpp; /* ------------------------------------------------------------------------ */ -/* Function: fr_addgroup */ +/* Function: ipf_group_add */ /* Returns: frgroup_t * - NULL == did not create group, */ /* != NULL == pointer to the group */ -/* Parameters: num(I) - group number to add */ +/* Parameters: softc(I) - pointer to soft context main structure */ +/* num(I) - group number to add */ /* head(I) - rule pointer that is using this as the head */ /* flags(I) - rule flags which describe the type of rule it is */ /* unit(I) - device to which this group will belong to */ @@ -3356,12 +3551,14 @@ frgroup_t ***fgpp; /* Add a new group head, or if it already exists, increase the reference */ /* count to it. */ /* ------------------------------------------------------------------------ */ -frgroup_t *fr_addgroup(group, head, flags, unit, set) -char *group; -void *head; -u_32_t flags; -minor_t unit; -int set; +frgroup_t * +ipf_group_add(softc, group, head, flags, unit, set) + ipf_main_softc_t *softc; + char *group; + void *head; + u_32_t flags; + minor_t unit; + int set; { frgroup_t *fg, **fgp; u_32_t gflags; @@ -3375,8 +3572,10 @@ int set; fgp = NULL; gflags = flags & FR_INOUT; - fg = fr_findgroup(group, unit, set, &fgp); + fg = ipf_findgroup(softc, group, unit, set, &fgp); if (fg != NULL) { + if (fg->fg_head == NULL && head != NULL) + fg->fg_head = head; if (fg->fg_flags == 0) fg->fg_flags = gflags; else if (gflags != fg->fg_flags) @@ -3384,14 +3583,16 @@ int set; fg->fg_ref++; return fg; } + KMALLOC(fg, frgroup_t *); if (fg != NULL) { fg->fg_head = head; fg->fg_start = NULL; fg->fg_next = *fgp; - bcopy(group, fg->fg_name, FR_GROUPLEN); + bcopy(group, fg->fg_name, strlen(group) + 1); fg->fg_flags = gflags; fg->fg_ref = 1; + fg->fg_set = &softc->ipf_groups[unit][set]; *fgp = fg; } return fg; @@ -3399,38 +3600,82 @@ int set; /* ------------------------------------------------------------------------ */ -/* Function: fr_delgroup */ -/* Returns: Nil */ -/* Parameters: group(I) - group name to delete */ -/* unit(I) - device to which this group belongs */ -/* set(I) - which set of rules (inactive/inactive) this is */ +/* Function: ipf_group_del */ +/* Returns: int - number of rules deleted */ +/* Parameters: softc(I) - pointer to soft context main structure */ +/* group(I) - group name to delete */ +/* fr(I) - filter rule from which group is referenced */ /* Write Locks: ipf_mutex */ /* */ -/* Attempt to delete a group head. */ -/* Only do this when its reference count reaches 0. */ +/* This function is called whenever a reference to a group is to be dropped */ +/* and thus its reference count needs to be lowered and the group free'd if */ +/* the reference count reaches zero. Passing in fr is really for the sole */ +/* purpose of knowing when the head rule is being deleted. */ /* ------------------------------------------------------------------------ */ -void fr_delgroup(group, unit, set) -char *group; -minor_t unit; -int set; +void +ipf_group_del(softc, group, fr) + ipf_main_softc_t *softc; + frgroup_t *group; + frentry_t *fr; { - frgroup_t *fg, **fgp; - fg = fr_findgroup(group, unit, set, &fgp); - if (fg == NULL) - return; + if (group->fg_head == fr) + group->fg_head = NULL; - fg->fg_ref--; - if (fg->fg_ref == 0) { - *fgp = fg->fg_next; - KFREE(fg); - } + group->fg_ref--; + if ((group->fg_ref == 0) && (group->fg_start == NULL)) + ipf_group_free(group); } /* ------------------------------------------------------------------------ */ -/* Function: fr_getrulen */ +/* Function: ipf_group_free */ +/* Returns: Nil */ +/* Parameters: group(I) - pointer to filter rule group */ +/* */ +/* Remove the group from the list of groups and free it. */ +/* ------------------------------------------------------------------------ */ +static void +ipf_group_free(group) + frgroup_t *group; +{ + frgroup_t **gp; + + for (gp = group->fg_set; *gp != NULL; gp = &(*gp)->fg_next) { + if (*gp == group) { + *gp = group->fg_next; + break; + } + } + KFREE(group); +} + + +/* ------------------------------------------------------------------------ */ +/* Function: ipf_group_flush */ +/* Returns: int - number of rules flush from group */ +/* Parameters: softc(I) - pointer to soft context main structure */ +/* Parameters: group(I) - pointer to filter rule group */ +/* */ +/* Remove all of the rules that currently are listed under the given group. */ +/* ------------------------------------------------------------------------ */ +static int +ipf_group_flush(softc, group) + ipf_main_softc_t *softc; + frgroup_t *group; +{ + int gone = 0; + + (void) ipf_flushlist(softc, &gone, &group->fg_start); + + return gone; +} + + +/* ------------------------------------------------------------------------ */ +/* Function: ipf_getrulen */ /* Returns: frentry_t * - NULL == not found, else pointer to rule n */ +/* Parameters: softc(I) - pointer to soft context main structure */ /* Parameters: unit(I) - device for which to count the rule's number */ /* flags(I) - which set of rules to find the rule in */ /* group(I) - group name */ @@ -3439,18 +3684,20 @@ int set; /* Find rule # n in group # g and return a pointer to it. Return NULl if */ /* group # g doesn't exist or there are less than n rules in the group. */ /* ------------------------------------------------------------------------ */ -frentry_t *fr_getrulen(unit, group, n) -int unit; -char *group; -u_32_t n; +frentry_t * +ipf_getrulen(softc, unit, group, n) + ipf_main_softc_t *softc; + int unit; + char *group; + u_32_t n; { frentry_t *fr; frgroup_t *fg; - fg = fr_findgroup(group, unit, fr_active, NULL); + fg = ipf_findgroup(softc, group, unit, softc->ipf_active, NULL); if (fg == NULL) return NULL; - for (fr = fg->fg_head; fr && n; fr = fr->fr_next, n--) + for (fr = fg->fg_start; fr && n; fr = fr->fr_next, n--) ; if (n != 0) return NULL; @@ -3459,41 +3706,9 @@ u_32_t n; /* ------------------------------------------------------------------------ */ -/* Function: fr_rulen */ -/* Returns: int - >= 0 - rule number, -1 == search failed */ -/* Parameters: unit(I) - device for which to count the rule's number */ -/* fr(I) - pointer to rule to match */ -/* */ -/* Return the number for a rule on a specific filtering device. */ -/* ------------------------------------------------------------------------ */ -int fr_rulen(unit, fr) -int unit; -frentry_t *fr; -{ - frentry_t *fh; - frgroup_t *fg; - u_32_t n = 0; - - if (fr == NULL) - return -1; - fg = fr_findgroup(fr->fr_group, unit, fr_active, NULL); - if (fg == NULL) - return -1; - for (fh = fg->fg_head; fh; n++, fh = fh->fr_next) - if (fh == fr) - break; - if (fh == NULL) - return -1; - return n; -} - - -/* ------------------------------------------------------------------------ */ -/* Function: frflushlist */ +/* Function: ipf_flushlist */ /* Returns: int - >= 0 - number of flushed rules */ -/* Parameters: set(I) - which set of rules (inactive/inactive) this is */ -/* unit(I) - device for which to flush rules */ -/* flags(I) - which set of rules to flush */ +/* Parameters: softc(I) - pointer to soft context main structure */ /* nfreedp(O) - pointer to int where flush count is stored */ /* listp(I) - pointer to list to flush pointer */ /* Write Locks: ipf_mutex */ @@ -3507,11 +3722,11 @@ frentry_t *fr; /* */ /* NOTE: Rules not loaded from user space cannot be flushed. */ /* ------------------------------------------------------------------------ */ -static int frflushlist(set, unit, nfreedp, listp) -int set; -minor_t unit; -int *nfreedp; -frentry_t **listp; +static int +ipf_flushlist(softc, nfreedp, listp) + ipf_main_softc_t *softc; + int *nfreedp; + frentry_t **listp; { int freed = 0; frentry_t *fp; @@ -3523,18 +3738,27 @@ frentry_t **listp; continue; } *listp = fp->fr_next; - if (fp->fr_grp != NULL) { - (void) frflushlist(set, unit, nfreedp, fp->fr_grp); + if (fp->fr_next != NULL) + fp->fr_next->fr_pnext = fp->fr_pnext; + fp->fr_pnext = NULL; + + if (fp->fr_grphead != NULL) { + freed += ipf_group_flush(softc, fp->fr_grphead); + fp->fr_names[fp->fr_grhead] = '\0'; } - if (fp->fr_grhead != NULL) { - fr_delgroup(fp->fr_grhead, unit, set); - *fp->fr_grhead = '\0'; + if (fp->fr_icmpgrp != NULL) { + freed += ipf_group_flush(softc, fp->fr_icmpgrp); + fp->fr_names[fp->fr_icmphead] = '\0'; } + if (fp->fr_srctrack.ht_max_nodes) + ipf_rb_ht_flush(&fp->fr_srctrack); + + fp->fr_next = NULL; + ASSERT(fp->fr_ref > 0); - fp->fr_next = NULL; - if (fr_derefrule(&fp) == 0) + if (ipf_derefrule(softc, &fp) == 0) freed++; } *nfreedp += freed; @@ -3543,61 +3767,47 @@ frentry_t **listp; /* ------------------------------------------------------------------------ */ -/* Function: frflush */ +/* Function: ipf_flush */ /* Returns: int - >= 0 - number of flushed rules */ -/* Parameters: unit(I) - device for which to flush rules */ +/* Parameters: softc(I) - pointer to soft context main structure */ +/* unit(I) - device for which to flush rules */ /* flags(I) - which set of rules to flush */ /* */ /* Calls flushlist() for all filter rules (accounting, firewall - both IPv4 */ /* and IPv6) as defined by the value of flags. */ /* ------------------------------------------------------------------------ */ -int frflush(unit, proto, flags) -minor_t unit; -int proto, flags; +int +ipf_flush(softc, unit, flags) + ipf_main_softc_t *softc; + minor_t unit; + int flags; { int flushed = 0, set; - WRITE_ENTER(&ipf_mutex); - bzero((char *)frcache, sizeof(frcache)); + WRITE_ENTER(&softc->ipf_mutex); - set = fr_active; + set = softc->ipf_active; if ((flags & FR_INACTIVE) == FR_INACTIVE) set = 1 - set; if (flags & FR_OUTQUE) { - if (proto == 0 || proto == 6) { - (void) frflushlist(set, unit, - &flushed, &ipfilter6[1][set]); - (void) frflushlist(set, unit, - &flushed, &ipacct6[1][set]); - } - if (proto == 0 || proto == 4) { - (void) frflushlist(set, unit, - &flushed, &ipfilter[1][set]); - (void) frflushlist(set, unit, - &flushed, &ipacct[1][set]); - } + ipf_flushlist(softc, &flushed, &softc->ipf_rules[1][set]); + ipf_flushlist(softc, &flushed, &softc->ipf_acct[1][set]); } if (flags & FR_INQUE) { - if (proto == 0 || proto == 6) { - (void) frflushlist(set, unit, - &flushed, &ipfilter6[0][set]); - (void) frflushlist(set, unit, - &flushed, &ipacct6[0][set]); - } - if (proto == 0 || proto == 4) { - (void) frflushlist(set, unit, - &flushed, &ipfilter[0][set]); - (void) frflushlist(set, unit, - &flushed, &ipacct[0][set]); - } + ipf_flushlist(softc, &flushed, &softc->ipf_rules[0][set]); + ipf_flushlist(softc, &flushed, &softc->ipf_acct[0][set]); } - RWLOCK_EXIT(&ipf_mutex); + + flushed += ipf_flush_groups(softc, &softc->ipf_groups[unit][set], + flags & (FR_INQUE|FR_OUTQUE)); + + RWLOCK_EXIT(&softc->ipf_mutex); if (unit == IPL_LOGIPF) { int tmp; - tmp = frflush(IPL_LOGCOUNT, proto, flags); + tmp = ipf_flush(softc, IPL_LOGCOUNT, flags); if (tmp >= 0) flushed += tmp; } @@ -3605,6 +3815,59 @@ int proto, flags; } +/* ------------------------------------------------------------------------ */ +/* Function: ipf_flush_groups */ +/* Returns: int - >= 0 - number of flushed rules */ +/* Parameters: softc(I) - soft context pointerto work with */ +/* grhead(I) - pointer to the start of the group list to flush */ +/* flags(I) - which set of rules to flush */ +/* */ +/* Walk through all of the groups under the given group head and remove all */ +/* of those that match the flags passed in. The for loop here is bit more */ +/* complicated than usual because the removal of a rule with ipf_derefrule */ +/* may end up removing not only the structure pointed to by "fg" but also */ +/* what is fg_next and fg_next after that. So if a filter rule is actually */ +/* removed from the group then it is necessary to start again. */ +/* ------------------------------------------------------------------------ */ +static int +ipf_flush_groups(softc, grhead, flags) + ipf_main_softc_t *softc; + frgroup_t **grhead; + int flags; +{ + frentry_t *fr, **frp; + frgroup_t *fg, **fgp; + int flushed = 0; + int removed = 0; + + for (fgp = grhead; (fg = *fgp) != NULL; ) { + while ((fg != NULL) && ((fg->fg_flags & flags) == 0)) + fg = fg->fg_next; + if (fg == NULL) + break; + removed = 0; + frp = &fg->fg_start; + while ((removed == 0) && ((fr = *frp) != NULL)) { + if ((fr->fr_flags & flags) == 0) { + frp = &fr->fr_next; + } else { + if (fr->fr_next != NULL) + fr->fr_next->fr_pnext = fr->fr_pnext; + *frp = fr->fr_next; + fr->fr_pnext = NULL; + fr->fr_next = NULL; + (void) ipf_derefrule(softc, &fr); + flushed++; + removed++; + } + } + if (removed == 0) + fgp = &fg->fg_next; + } + return flushed; +} + + /* ------------------------------------------------------------------------ */ /* Function: memstr */ /* Returns: char * - NULL if failed, != NULL pointer to matching bytes */ @@ -3616,10 +3879,11 @@ int proto, flags; /* Search dst for a sequence of bytes matching those at src and extend for */ /* slen bytes. */ /* ------------------------------------------------------------------------ */ -char *memstr(src, dst, slen, dlen) -const char *src; -char *dst; -size_t slen, dlen; +char * +memstr(src, dst, slen, dlen) + const char *src; + char *dst; + size_t slen, dlen; { char *s = NULL; @@ -3634,7 +3898,7 @@ size_t slen, dlen; return s; } /* ------------------------------------------------------------------------ */ -/* Function: fr_fixskip */ +/* Function: ipf_fixskip */ /* Returns: Nil */ /* Parameters: listp(IO) - pointer to start of list with skip rule */ /* rp(I) - rule added/removed with skip in it. */ @@ -3645,9 +3909,10 @@ size_t slen, dlen; /* Adjust all the rules in a list which would have skip'd past the position */ /* where we are inserting to skip to the right place given the change. */ /* ------------------------------------------------------------------------ */ -void fr_fixskip(listp, rp, addremove) -frentry_t **listp, *rp; -int addremove; +void +ipf_fixskip(listp, rp, addremove) + frentry_t **listp, *rp; + int addremove; { int rules, rn; frentry_t *fp; @@ -3676,8 +3941,9 @@ int addremove; /* consecutive 1's is different to that passed, return -1, else return # */ /* of bits. */ /* ------------------------------------------------------------------------ */ -int count4bits(ip) -u_32_t ip; +int +count4bits(ip) + u_32_t ip; { u_32_t ipn; int cnt = 0, i, j; @@ -3700,7 +3966,6 @@ u_32_t ip; } -# if 0 /* ------------------------------------------------------------------------ */ /* Function: count6bits */ /* Returns: int - >= 0 - number of consecutive bits in input */ @@ -3709,8 +3974,10 @@ u_32_t ip; /* IPv6 ONLY */ /* count consecutive 1's in bit mask. */ /* ------------------------------------------------------------------------ */ -int count6bits(msk) -u_32_t *msk; +# ifdef USE_INET6 +int +count6bits(msk) + u_32_t *msk; { int i = 0, k; u_32_t j; @@ -3730,8 +3997,8 @@ u_32_t *msk; /* ------------------------------------------------------------------------ */ -/* Function: frsynclist */ -/* Returns: void */ +/* Function: ipf_synclist */ +/* Returns: int - 0 = no failures, else indication of first failure */ /* Parameters: fr(I) - start of filter list to sync interface names for */ /* ifp(I) - interface pointer for limiting sync lookups */ /* Write Locks: ipf_mutex */ @@ -3740,16 +4007,33 @@ u_32_t *msk; /* pointers. Where dynamic addresses are used, also update the IP address */ /* used in the rule. The interface pointer is used to limit the lookups to */ /* a specific set of matching names if it is non-NULL. */ +/* Errors can occur when resolving the destination name of to/dup-to fields */ +/* when the name points to a pool and that pool doest not exist. If this */ +/* does happen then it is necessary to check if there are any lookup refs */ +/* that need to be dropped before returning with an error. */ /* ------------------------------------------------------------------------ */ -static void frsynclist(fr, ifp) -frentry_t *fr; -void *ifp; +static int +ipf_synclist(softc, fr, ifp) + ipf_main_softc_t *softc; + frentry_t *fr; + void *ifp; { + frentry_t *frt, *start = fr; frdest_t *fdp; + char *name; + int error; + void *ifa; int v, i; + error = 0; + for (; fr; fr = fr->fr_next) { - v = fr->fr_v; + if (fr->fr_family == AF_INET) + v = 4; + else if (fr->fr_family == AF_INET6) + v = 6; + else + v = 0; /* * Lookup all the interface names that are part of the rule. @@ -3757,102 +4041,124 @@ void *ifp; for (i = 0; i < 4; i++) { if ((ifp != NULL) && (fr->fr_ifas[i] != ifp)) continue; - fr->fr_ifas[i] = fr_resolvenic(fr->fr_ifnames[i], v); + if (fr->fr_ifnames[i] == -1) + continue; + name = FR_NAME(fr, fr_ifnames[i]); + fr->fr_ifas[i] = ipf_resolvenic(softc, name, v); } - if (fr->fr_type == FR_T_IPF) { + if ((fr->fr_type & ~FR_T_BUILTIN) == FR_T_IPF) { if (fr->fr_satype != FRI_NORMAL && fr->fr_satype != FRI_LOOKUP) { - (void)fr_ifpaddr(v, fr->fr_satype, - fr->fr_ifas[fr->fr_sifpidx], - &fr->fr_src, &fr->fr_smsk); + ifa = ipf_resolvenic(softc, fr->fr_names + + fr->fr_sifpidx, v); + ipf_ifpaddr(softc, v, fr->fr_satype, ifa, + &fr->fr_src6, &fr->fr_smsk6); } if (fr->fr_datype != FRI_NORMAL && fr->fr_datype != FRI_LOOKUP) { - (void)fr_ifpaddr(v, fr->fr_datype, - fr->fr_ifas[fr->fr_difpidx], - &fr->fr_dst, &fr->fr_dmsk); + ifa = ipf_resolvenic(softc, fr->fr_names + + fr->fr_sifpidx, v); + ipf_ifpaddr(softc, v, fr->fr_datype, ifa, + &fr->fr_dst6, &fr->fr_dmsk6); } } fdp = &fr->fr_tifs[0]; - if ((ifp == NULL) || (fdp->fd_ifp == ifp)) - fr_resolvedest(fdp, v); + if ((ifp == NULL) || (fdp->fd_ptr == ifp)) { + error = ipf_resolvedest(softc, fr->fr_names, fdp, v); + if (error != 0) + goto unwind; + } fdp = &fr->fr_tifs[1]; - if ((ifp == NULL) || (fdp->fd_ifp == ifp)) - fr_resolvedest(fdp, v); + if ((ifp == NULL) || (fdp->fd_ptr == ifp)) { + error = ipf_resolvedest(softc, fr->fr_names, fdp, v); + if (error != 0) + goto unwind; + } fdp = &fr->fr_dif; - if ((ifp == NULL) || (fdp->fd_ifp == ifp)) { - fr_resolvedest(fdp, v); - - fr->fr_flags &= ~FR_DUP; - if ((fdp->fd_ifp != (void *)-1) && - (fdp->fd_ifp != NULL)) - fr->fr_flags |= FR_DUP; + if ((ifp == NULL) || (fdp->fd_ptr == ifp)) { + error = ipf_resolvedest(softc, fr->fr_names, fdp, v); + if (error != 0) + goto unwind; } -#ifdef IPFILTER_LOOKUP - if (fr->fr_type == FR_T_IPF && fr->fr_satype == FRI_LOOKUP && - fr->fr_srcptr == NULL) { - fr->fr_srcptr = fr_resolvelookup(fr->fr_srctype, - fr->fr_srcsubtype, - &fr->fr_slookup, - &fr->fr_srcfunc); + if (((fr->fr_type & ~FR_T_BUILTIN) == FR_T_IPF) && + (fr->fr_satype == FRI_LOOKUP) && (fr->fr_srcptr == NULL)) { + fr->fr_srcptr = ipf_lookup_res_num(softc, + fr->fr_srctype, + IPL_LOGIPF, + fr->fr_srcnum, + &fr->fr_srcfunc); } - if (fr->fr_type == FR_T_IPF && fr->fr_datype == FRI_LOOKUP && - fr->fr_dstptr == NULL) { - fr->fr_dstptr = fr_resolvelookup(fr->fr_dsttype, - fr->fr_dstsubtype, - &fr->fr_dlookup, - &fr->fr_dstfunc); + if (((fr->fr_type & ~FR_T_BUILTIN) == FR_T_IPF) && + (fr->fr_datype == FRI_LOOKUP) && (fr->fr_dstptr == NULL)) { + fr->fr_dstptr = ipf_lookup_res_num(softc, + fr->fr_dsttype, + IPL_LOGIPF, + fr->fr_dstnum, + &fr->fr_dstfunc); } -#endif } + return 0; + +unwind: + for (frt = start; frt != fr; fr = fr->fr_next) { + if (((frt->fr_type & ~FR_T_BUILTIN) == FR_T_IPF) && + (frt->fr_satype == FRI_LOOKUP) && (frt->fr_srcptr != NULL)) + ipf_lookup_deref(softc, frt->fr_srctype, + frt->fr_srcptr); + if (((frt->fr_type & ~FR_T_BUILTIN) == FR_T_IPF) && + (frt->fr_datype == FRI_LOOKUP) && (frt->fr_dstptr != NULL)) + ipf_lookup_deref(softc, frt->fr_dsttype, + frt->fr_dstptr); + } + return error; } -#ifdef _KERNEL /* ------------------------------------------------------------------------ */ -/* Function: frsync */ +/* Function: ipf_sync */ /* Returns: void */ /* Parameters: Nil */ /* */ -/* frsync() is called when we suspect that the interface list or */ +/* ipf_sync() is called when we suspect that the interface list or */ /* information about interfaces (like IP#) has changed. Go through all */ /* filter rules, NAT entries and the state table and check if anything */ /* needs to be changed/updated. */ /* ------------------------------------------------------------------------ */ -void frsync(ifp) -void *ifp; +int +ipf_sync(softc, ifp) + ipf_main_softc_t *softc; + void *ifp; { int i; # if !SOLARIS - fr_natsync(ifp); - fr_statesync(ifp); + ipf_nat_sync(softc, ifp); + ipf_state_sync(softc, ifp); + ipf_lookup_sync(softc, ifp); # endif - WRITE_ENTER(&ipf_mutex); - frsynclist(ipacct[0][fr_active], ifp); - frsynclist(ipacct[1][fr_active], ifp); - frsynclist(ipfilter[0][fr_active], ifp); - frsynclist(ipfilter[1][fr_active], ifp); - frsynclist(ipacct6[0][fr_active], ifp); - frsynclist(ipacct6[1][fr_active], ifp); - frsynclist(ipfilter6[0][fr_active], ifp); - frsynclist(ipfilter6[1][fr_active], ifp); + WRITE_ENTER(&softc->ipf_mutex); + (void) ipf_synclist(softc, softc->ipf_acct[0][softc->ipf_active], ifp); + (void) ipf_synclist(softc, softc->ipf_acct[1][softc->ipf_active], ifp); + (void) ipf_synclist(softc, softc->ipf_rules[0][softc->ipf_active], ifp); + (void) ipf_synclist(softc, softc->ipf_rules[1][softc->ipf_active], ifp); for (i = 0; i < IPL_LOGSIZE; i++) { frgroup_t *g; - for (g = ipfgroups[i][0]; g != NULL; g = g->fg_next) - frsynclist(g->fg_start, ifp); - for (g = ipfgroups[i][1]; g != NULL; g = g->fg_next) - frsynclist(g->fg_start, ifp); + for (g = softc->ipf_groups[i][0]; g != NULL; g = g->fg_next) + (void) ipf_synclist(softc, g->fg_start, ifp); + for (g = softc->ipf_groups[i][1]; g != NULL; g = g->fg_next) + (void) ipf_synclist(softc, g->fg_start, ifp); } - RWLOCK_EXIT(&ipf_mutex); + RWLOCK_EXIT(&softc->ipf_mutex); + + return 0; } @@ -3872,9 +4178,11 @@ void *ifp; /* to start copying from (src) and a pointer to where to store it (dst). */ /* NB: src - pointer to user space pointer, dst - kernel space pointer */ /* ------------------------------------------------------------------------ */ -int copyinptr(src, dst, size) -void *src, *dst; -size_t size; +int +copyinptr(softc, src, dst, size) + ipf_main_softc_t *softc; + void *src, *dst; + size_t size; { caddr_t ca; int error; @@ -3887,8 +4195,10 @@ size_t size; bcopy(src, (caddr_t)&ca, sizeof(ca)); # endif error = COPYIN(ca, dst, size); - if (error != 0) + if (error != 0) { + IPFERROR(3); error = EFAULT; + } return error; } @@ -3904,24 +4214,29 @@ size_t size; /* to start copying from (src) and a pointer to where to store it (dst). */ /* NB: src - kernel space pointer, dst - pointer to user space pointer. */ /* ------------------------------------------------------------------------ */ -int copyoutptr(src, dst, size) -void *src, *dst; -size_t size; +int +copyoutptr(softc, src, dst, size) + ipf_main_softc_t *softc; + void *src, *dst; + size_t size; { caddr_t ca; int error; bcopy(dst, (caddr_t)&ca, sizeof(ca)); error = COPYOUT(src, ca, size); - if (error != 0) + if (error != 0) { + IPFERROR(4); error = EFAULT; + } return error; } +#ifdef _KERNEL #endif /* ------------------------------------------------------------------------ */ -/* Function: fr_lock */ +/* Function: ipf_lock */ /* Returns: int - 0 = success, else error */ /* Parameters: data(I) - pointer to lock value to set */ /* lockp(O) - pointer to location to store old lock value */ @@ -3929,9 +4244,10 @@ size_t size; /* Get the new value for the lock integer, set it and return the old value */ /* in *lockp. */ /* ------------------------------------------------------------------------ */ -int fr_lock(data, lockp) -caddr_t data; -int *lockp; +int +ipf_lock(data, lockp) + caddr_t data; + int *lockp; { int arg, err; @@ -3947,51 +4263,78 @@ int *lockp; /* ------------------------------------------------------------------------ */ -/* Function: fr_getstat */ +/* Function: ipf_getstat */ /* Returns: Nil */ -/* Parameters: fiop(I) - pointer to ipfilter stats structure */ +/* Parameters: softc(I) - pointer to soft context main structure */ +/* fiop(I) - pointer to ipfilter stats structure */ +/* rev(I) - version claim by program doing ioctl */ /* */ /* Stores a copy of current pointers, counters, etc, in the friostat */ /* structure. */ +/* If IPFILTER_COMPAT is compiled, we pretend to be whatever version the */ +/* program is looking for. This ensure that validation of the version it */ +/* expects will always succeed. Thus kernels with IPFILTER_COMPAT will */ +/* allow older binaries to work but kernels without it will not. */ /* ------------------------------------------------------------------------ */ -void fr_getstat(fiop) -friostat_t *fiop; +/*ARGSUSED*/ +static void +ipf_getstat(softc, fiop, rev) + ipf_main_softc_t *softc; + friostat_t *fiop; + int rev; { - int i, j; + int i; - bcopy((char *)frstats, (char *)fiop->f_st, sizeof(filterstats_t) * 2); - fiop->f_locks[IPL_LOGSTATE] = fr_state_lock; - fiop->f_locks[IPL_LOGNAT] = fr_nat_lock; - fiop->f_locks[IPL_LOGIPF] = fr_frag_lock; - fiop->f_locks[IPL_LOGAUTH] = fr_auth_lock; + bcopy((char *)softc->ipf_stats, (char *)fiop->f_st, + sizeof(ipf_statistics_t) * 2); + fiop->f_locks[IPL_LOGSTATE] = -1; + fiop->f_locks[IPL_LOGNAT] = -1; + fiop->f_locks[IPL_LOGIPF] = -1; + fiop->f_locks[IPL_LOGAUTH] = -1; - for (i = 0; i < 2; i++) - for (j = 0; j < 2; j++) { - fiop->f_ipf[i][j] = ipfilter[i][j]; - fiop->f_acct[i][j] = ipacct[i][j]; - fiop->f_ipf6[i][j] = ipfilter6[i][j]; - fiop->f_acct6[i][j] = ipacct6[i][j]; - } + fiop->f_ipf[0][0] = softc->ipf_rules[0][0]; + fiop->f_acct[0][0] = softc->ipf_acct[0][0]; + fiop->f_ipf[0][1] = softc->ipf_rules[0][1]; + fiop->f_acct[0][1] = softc->ipf_acct[0][1]; + fiop->f_ipf[1][0] = softc->ipf_rules[1][0]; + fiop->f_acct[1][0] = softc->ipf_acct[1][0]; + fiop->f_ipf[1][1] = softc->ipf_rules[1][1]; + fiop->f_acct[1][1] = softc->ipf_acct[1][1]; - fiop->f_ticks = fr_ticks; - fiop->f_active = fr_active; - fiop->f_froute[0] = fr_frouteok[0]; - fiop->f_froute[1] = fr_frouteok[1]; + fiop->f_ticks = softc->ipf_ticks; + fiop->f_active = softc->ipf_active; + fiop->f_froute[0] = softc->ipf_frouteok[0]; + fiop->f_froute[1] = softc->ipf_frouteok[1]; + fiop->f_rb_no_mem = softc->ipf_rb_no_mem; + fiop->f_rb_node_max = softc->ipf_rb_node_max; - fiop->f_running = fr_running; + fiop->f_running = softc->ipf_running; for (i = 0; i < IPL_LOGSIZE; i++) { - fiop->f_groups[i][0] = ipfgroups[i][0]; - fiop->f_groups[i][1] = ipfgroups[i][1]; + fiop->f_groups[i][0] = softc->ipf_groups[i][0]; + fiop->f_groups[i][1] = softc->ipf_groups[i][1]; } #ifdef IPFILTER_LOG + fiop->f_log_ok = ipf_log_logok(softc, IPL_LOGIPF); + fiop->f_log_fail = ipf_log_failures(softc, IPL_LOGIPF); fiop->f_logging = 1; #else + fiop->f_log_ok = 0; + fiop->f_log_fail = 0; fiop->f_logging = 0; #endif - fiop->f_defpass = fr_pass; - fiop->f_features = fr_features; + fiop->f_defpass = softc->ipf_pass; + fiop->f_features = ipf_features; + +#ifdef IPFILTER_COMPAT + sprintf(fiop->f_version, "IP Filter: v%d.%d.%d", + (rev / 1000000) % 100, + (rev / 10000) % 100, + (rev / 100) % 100); +#else + rev = rev; (void) strncpy(fiop->f_version, ipfilter_version, sizeof(fiop->f_version)); +#endif } @@ -4042,7 +4385,7 @@ int icmpreplytype4[ICMP_MAXTYPE + 1]; /* ------------------------------------------------------------------------ */ -/* Function: fr_matchicmpqueryreply */ +/* Function: ipf_matchicmpqueryreply */ /* Returns: int - 1 if "icmp" is a valid reply to "ic" else 0. */ /* Parameters: v(I) - IP protocol version (4 or 6) */ /* ic(I) - ICMP information */ @@ -4053,11 +4396,12 @@ int icmpreplytype4[ICMP_MAXTYPE + 1]; /* reply to one as described by what's in ic. If it is a match, return 1, */ /* else return 0 for no match. */ /* ------------------------------------------------------------------------ */ -int fr_matchicmpqueryreply(v, ic, icmp, rev) -int v; -icmpinfo_t *ic; -icmphdr_t *icmp; -int rev; +int +ipf_matchicmpqueryreply(v, ic, icmp, rev) + int v; + icmpinfo_t *ic; + icmphdr_t *icmp; + int rev; { int ictype; @@ -4091,88 +4435,6 @@ int rev; } -#ifdef IPFILTER_LOOKUP -/* ------------------------------------------------------------------------ */ -/* Function: fr_resolvelookup */ -/* Returns: void * - NULL = failure, else success. */ -/* Parameters: type(I) - type of lookup these parameters are for. */ -/* subtype(I) - whether the info below contains number/name */ -/* info(I) - pointer to name/number of the lookup data */ -/* funcptr(IO) - pointer to pointer for storing IP address */ -/* searching function. */ -/* */ -/* Search for the "table" number passed in amongst those configured for */ -/* that particular type. If the type is recognised then the function to */ -/* call to do the IP address search will be change, regardless of whether */ -/* or not the "table" number exists. */ -/* ------------------------------------------------------------------------ */ -static void *fr_resolvelookup(type, subtype, info, funcptr) -u_int type, subtype; -i6addr_t *info; -lookupfunc_t *funcptr; -{ - char label[FR_GROUPLEN], *name; - iphtable_t *iph; - ip_pool_t *ipo; - void *ptr; - - if (subtype == 0) { -#if defined(SNPRINTF) && defined(_KERNEL) - SNPRINTF(label, sizeof(label), "%u", info->iplookupnum); -#else - (void) sprintf(label, "%u", info->iplookupnum); -#endif - name = label; - } else if (subtype == 1) { - /* - * Because iplookupname is currently only a 12 character - * string and FR_GROUPLEN is 16, copy all of it into the - * label buffer and add on a NULL at the end. - */ - strncpy(label, info->iplookupname, sizeof(info->iplookupname)); - label[sizeof(info->iplookupname)] = '\0'; - name = label; - } else { - return NULL; - } - - READ_ENTER(&ip_poolrw); - - switch (type) - { - case IPLT_POOL : -# if (defined(__osf__) && defined(_KERNEL)) - ptr = NULL; - *funcptr = NULL; -# else - ipo = ip_pool_find(IPL_LOGIPF, name); - ptr = ipo; - if (ipo != NULL) { - ATOMIC_INC32(ipo->ipo_ref); - } - *funcptr = ip_pool_search; -# endif - break; - case IPLT_HASH : - iph = fr_findhtable(IPL_LOGIPF, name); - ptr = iph; - if (iph != NULL) { - ATOMIC_INC32(iph->iph_ref); - } - *funcptr = fr_iphmfindip; - break; - default: - ptr = NULL; - *funcptr = NULL; - break; - } - RWLOCK_EXIT(&ip_poolrw); - - return ptr; -} -#endif - - /* ------------------------------------------------------------------------ */ /* Function: frrequest */ /* Returns: int - 0 == success, > 0 == errno value */ @@ -4190,54 +4452,98 @@ lookupfunc_t *funcptr; /* of the rule structure being loaded. If a rule has user defined timeouts */ /* then make sure they are created and initialised before exiting. */ /* ------------------------------------------------------------------------ */ -int frrequest(unit, req, data, set, makecopy) -int unit; -ioctlcmd_t req; -int set, makecopy; -caddr_t data; +int +frrequest(softc, unit, req, data, set, makecopy) + ipf_main_softc_t *softc; + int unit; + ioctlcmd_t req; + int set, makecopy; + caddr_t data; { + int error = 0, in, family, addrem, need_free = 0; frentry_t frd, *fp, *f, **fprev, **ftail; - int error = 0, in, v; - void *ptr, *uptr; + void *ptr, *uptr, *cptr; u_int *p, *pp; frgroup_t *fg; char *group; + ptr = NULL; + cptr = NULL; fg = NULL; fp = &frd; if (makecopy != 0) { - error = fr_inobj(data, fp, IPFOBJ_FRENTRY); - if (error) - return EFAULT; - if ((fp->fr_flags & FR_T_BUILTIN) != 0) + bzero(fp, sizeof(frd)); + error = ipf_inobj(softc, data, NULL, fp, IPFOBJ_FRENTRY); + if (error) { + return error; + } + if ((fp->fr_type & FR_T_BUILTIN) != 0) { + IPFERROR(6); return EINVAL; + } + KMALLOCS(f, frentry_t *, fp->fr_size); + if (f == NULL) { + IPFERROR(131); + return ENOMEM; + } + bzero(f, fp->fr_size); + error = ipf_inobjsz(softc, data, f, IPFOBJ_FRENTRY, + fp->fr_size); + if (error) { + KFREES(f, fp->fr_size); + return error; + } + + fp = f; + f = NULL; + fp->fr_dnext = NULL; fp->fr_ref = 0; fp->fr_flags |= FR_COPIED; } else { fp = (frentry_t *)data; - if ((fp->fr_type & FR_T_BUILTIN) == 0) + if ((fp->fr_type & FR_T_BUILTIN) == 0) { + IPFERROR(7); return EINVAL; + } fp->fr_flags &= ~FR_COPIED; } if (((fp->fr_dsize == 0) && (fp->fr_data != NULL)) || - ((fp->fr_dsize != 0) && (fp->fr_data == NULL))) - return EINVAL; + ((fp->fr_dsize != 0) && (fp->fr_data == NULL))) { + IPFERROR(8); + error = EINVAL; + goto donenolock; + } - v = fp->fr_v; + family = fp->fr_family; uptr = fp->fr_data; + if (req == (ioctlcmd_t)SIOCINAFR || req == (ioctlcmd_t)SIOCINIFR || + req == (ioctlcmd_t)SIOCADAFR || req == (ioctlcmd_t)SIOCADIFR) + addrem = 0; + else if (req == (ioctlcmd_t)SIOCRMAFR || req == (ioctlcmd_t)SIOCRMIFR) + addrem = 1; + else if (req == (ioctlcmd_t)SIOCZRLST) + addrem = 2; + else { + IPFERROR(9); + error = EINVAL; + goto donenolock; + } + /* * Only filter rules for IPv4 or IPv6 are accepted. */ - if (v == 4) + if (family == AF_INET) { /*EMPTY*/; #ifdef USE_INET6 - else if (v == 6) + } else if (family == AF_INET6) { /*EMPTY*/; #endif - else { - return EINVAL; + } else if (family != 0) { + IPFERROR(10); + error = EINVAL; + goto donenolock; } /* @@ -4246,37 +4552,110 @@ caddr_t data; * rule. */ if ((makecopy == 1) && (fp->fr_func != NULL)) { - if (fr_findfunc(fp->fr_func) == NULL) - return ESRCH; - error = fr_funcinit(fp); - if (error != 0) - return error; + if (ipf_findfunc(fp->fr_func) == NULL) { + IPFERROR(11); + error = ESRCH; + goto donenolock; + } + + if (addrem == 0) { + error = ipf_funcinit(softc, fp); + if (error != 0) + goto donenolock; + } + } + if ((fp->fr_flags & FR_CALLNOW) && + ((fp->fr_func == NULL) || (fp->fr_func == (ipfunc_t)-1))) { + IPFERROR(142); + error = ESRCH; + goto donenolock; + } + if (((fp->fr_flags & FR_CMDMASK) == FR_CALL) && + ((fp->fr_func == NULL) || (fp->fr_func == (ipfunc_t)-1))) { + IPFERROR(143); + error = ESRCH; + goto donenolock; } ptr = NULL; - /* - * Check that the group number does exist and that its use (in/out) - * matches what the rule is. - */ - if (!strncmp(fp->fr_grhead, "0", FR_GROUPLEN)) - *fp->fr_grhead = '\0'; - group = fp->fr_group; - if (!strncmp(group, "0", FR_GROUPLEN)) - *group = '\0'; + cptr = NULL; if (FR_ISACCOUNT(fp->fr_flags)) unit = IPL_LOGCOUNT; - if ((req != (int)SIOCZRLST) && (*group != '\0')) { - fg = fr_findgroup(group, unit, set, NULL); - if (fg == NULL) - return ESRCH; - if (fg->fg_flags == 0) - fg->fg_flags = fp->fr_flags & FR_INOUT; - else if (fg->fg_flags != (fp->fr_flags & FR_INOUT)) - return ESRCH; + /* + * Check that each group name in the rule has a start index that + * is valid. + */ + if (fp->fr_icmphead != -1) { + if ((fp->fr_icmphead < 0) || + (fp->fr_icmphead >= fp->fr_namelen)) { + IPFERROR(136); + error = EINVAL; + goto donenolock; + } + if (!strcmp(FR_NAME(fp, fr_icmphead), "0")) + fp->fr_names[fp->fr_icmphead] = '\0'; } + if (fp->fr_grhead != -1) { + if ((fp->fr_grhead < 0) || + (fp->fr_grhead >= fp->fr_namelen)) { + IPFERROR(137); + error = EINVAL; + goto donenolock; + } + if (!strcmp(FR_NAME(fp, fr_grhead), "0")) + fp->fr_names[fp->fr_grhead] = '\0'; + } + + if (fp->fr_group != -1) { + if ((fp->fr_group < 0) || + (fp->fr_group >= fp->fr_namelen)) { + IPFERROR(138); + error = EINVAL; + goto donenolock; + } + if ((req != (int)SIOCZRLST) && (fp->fr_group != -1)) { + /* + * Allow loading rules that are in groups to cause + * them to be created if they don't already exit. + */ + group = FR_NAME(fp, fr_group); + if (addrem == 0) { + fg = ipf_group_add(softc, group, NULL, + fp->fr_flags, unit, set); + fp->fr_grp = fg; + } else { + fg = ipf_findgroup(softc, group, unit, + set, NULL); + if (fg == NULL) { + IPFERROR(12); + error = ESRCH; + goto donenolock; + } + } + + if (fg->fg_flags == 0) { + fg->fg_flags = fp->fr_flags & FR_INOUT; + } else if (fg->fg_flags != (fp->fr_flags & FR_INOUT)) { + IPFERROR(13); + error = ESRCH; + goto donenolock; + } + } + } else { + /* + * If a rule is going to be part of a group then it does + * not matter whether it is an in or out rule, but if it + * isn't in a group, then it does... + */ + if ((fp->fr_flags & (FR_INQUE|FR_OUTQUE)) == 0) { + IPFERROR(14); + error = EINVAL; + goto donenolock; + } + } in = (fp->fr_flags & FR_INQUE) ? 0 : 1; /* @@ -4284,27 +4663,30 @@ caddr_t data; */ ftail = NULL; fprev = NULL; - if (unit == IPL_LOGAUTH) - fprev = &ipauth; - else if (v == 4) { + if (unit == IPL_LOGAUTH) { + if ((fp->fr_tifs[0].fd_ptr != NULL) || + (fp->fr_tifs[1].fd_ptr != NULL) || + (fp->fr_dif.fd_ptr != NULL) || + (fp->fr_flags & FR_FASTROUTE)) { + softc->ipf_interror = 145; + error = EINVAL; + goto donenolock; + } + fprev = ipf_auth_rulehead(softc); + } else { if (FR_ISACCOUNT(fp->fr_flags)) - fprev = &ipacct[in][set]; + fprev = &softc->ipf_acct[in][set]; else if ((fp->fr_flags & (FR_OUTQUE|FR_INQUE)) != 0) - fprev = &ipfilter[in][set]; - } else if (v == 6) { - if (FR_ISACCOUNT(fp->fr_flags)) - fprev = &ipacct6[in][set]; - else if ((fp->fr_flags & (FR_OUTQUE|FR_INQUE)) != 0) - fprev = &ipfilter6[in][set]; + fprev = &softc->ipf_rules[in][set]; + } + if (fprev == NULL) { + IPFERROR(15); + error = ESRCH; + goto donenolock; } - if (fprev == NULL) - return ESRCH; - if (*group != '\0') { - if (!fg && !(fg = fr_findgroup(group, unit, set, NULL))) - return ESRCH; + if (fg != NULL) fprev = &fg->fg_start; - } /* * Copy in extra data for the rule. @@ -4312,51 +4694,82 @@ caddr_t data; if (fp->fr_dsize != 0) { if (makecopy != 0) { KMALLOCS(ptr, void *, fp->fr_dsize); - if (!ptr) - return ENOMEM; - error = COPYIN(uptr, ptr, fp->fr_dsize); - if (error != 0) - error = EFAULT; + if (ptr == NULL) { + IPFERROR(16); + error = ENOMEM; + goto donenolock; + } + + /* + * The bcopy case is for when the data is appended + * to the rule by ipf_in_compat(). + */ + if (uptr >= (void *)fp && + uptr < (void *)((char *)fp + fp->fr_size)) { + bcopy(uptr, ptr, fp->fr_dsize); + error = 0; + } else { + error = COPYIN(uptr, ptr, fp->fr_dsize); + if (error != 0) { + IPFERROR(17); + error = EFAULT; + goto donenolock; + } + } } else { ptr = uptr; - error = 0; - } - if (error != 0) { - KFREES(ptr, fp->fr_dsize); - return ENOMEM; } fp->fr_data = ptr; - } else + } else { fp->fr_data = NULL; + } /* * Perform per-rule type sanity checks of their members. + * All code after this needs to be aware that allocated memory + * may need to be free'd before exiting. */ switch (fp->fr_type & ~FR_T_BUILTIN) { #if defined(IPFILTER_BPF) case FR_T_BPFOPC : - if (fp->fr_dsize == 0) - return EINVAL; + if (fp->fr_dsize == 0) { + IPFERROR(19); + error = EINVAL; + break; + } if (!bpf_validate(ptr, fp->fr_dsize/sizeof(struct bpf_insn))) { - if (makecopy && fp->fr_data != NULL) { - KFREES(fp->fr_data, fp->fr_dsize); - } - return EINVAL; + IPFERROR(20); + error = EINVAL; + break; } break; #endif case FR_T_IPF : - if (fp->fr_dsize != sizeof(fripf_t)) - return EINVAL; + /* + * Preparation for error case at the bottom of this function. + */ + if (fp->fr_datype == FRI_LOOKUP) + fp->fr_dstptr = NULL; + if (fp->fr_satype == FRI_LOOKUP) + fp->fr_srcptr = NULL; + + if (fp->fr_dsize != sizeof(fripf_t)) { + IPFERROR(21); + error = EINVAL; + break; + } /* * Allowing a rule with both "keep state" and "with oow" is * pointless because adding a state entry to the table will * fail with the out of window (oow) flag set. */ - if ((fp->fr_flags & FR_KEEPSTATE) && (fp->fr_flx & FI_OOW)) - return EINVAL; + if ((fp->fr_flags & FR_KEEPSTATE) && (fp->fr_flx & FI_OOW)) { + IPFERROR(22); + error = EINVAL; + break; + } switch (fp->fr_satype) { @@ -4365,26 +4778,30 @@ caddr_t data; case FRI_NETWORK : case FRI_NETMASKED : case FRI_PEERADDR : - if (fp->fr_sifpidx < 0 || fp->fr_sifpidx > 3) { - if (makecopy && fp->fr_data != NULL) { - KFREES(fp->fr_data, fp->fr_dsize); - } - return EINVAL; + if (fp->fr_sifpidx < 0) { + IPFERROR(23); + error = EINVAL; } break; -#ifdef IPFILTER_LOOKUP case FRI_LOOKUP : - fp->fr_srcptr = fr_resolvelookup(fp->fr_srctype, - fp->fr_srcsubtype, - &fp->fr_slookup, - &fp->fr_srcfunc); - if (fp->fr_srcptr == NULL) - return ESRCH; + fp->fr_srcptr = ipf_findlookup(softc, unit, fp, + &fp->fr_src6, + &fp->fr_smsk6); + if (fp->fr_srcfunc == NULL) { + IPFERROR(132); + error = ESRCH; + break; + } + break; + case FRI_NORMAL : break; -#endif default : + IPFERROR(133); + error = EINVAL; break; } + if (error != 0) + break; switch (fp->fr_datype) { @@ -4393,45 +4810,84 @@ caddr_t data; case FRI_NETWORK : case FRI_NETMASKED : case FRI_PEERADDR : - if (fp->fr_difpidx < 0 || fp->fr_difpidx > 3) { - if (makecopy && fp->fr_data != NULL) { - KFREES(fp->fr_data, fp->fr_dsize); - } - return EINVAL; + if (fp->fr_difpidx < 0) { + IPFERROR(24); + error = EINVAL; } break; -#ifdef IPFILTER_LOOKUP case FRI_LOOKUP : - fp->fr_dstptr = fr_resolvelookup(fp->fr_dsttype, - fp->fr_dstsubtype, - &fp->fr_dlookup, - &fp->fr_dstfunc); - if (fp->fr_dstptr == NULL) - return ESRCH; + fp->fr_dstptr = ipf_findlookup(softc, unit, fp, + &fp->fr_dst6, + &fp->fr_dmsk6); + if (fp->fr_dstfunc == NULL) { + IPFERROR(134); + error = ESRCH; + } + break; + case FRI_NORMAL : break; -#endif default : - break; + IPFERROR(135); + error = EINVAL; } break; + case FR_T_NONE : - break; case FR_T_CALLFUNC : - break; case FR_T_COMPIPF : break; - default : - if (makecopy && fp->fr_data != NULL) { - KFREES(fp->fr_data, fp->fr_dsize); + + case FR_T_IPFEXPR : + if (ipf_matcharray_verify(fp->fr_data, fp->fr_dsize) == -1) { + IPFERROR(25); + error = EINVAL; + } + break; + + default : + IPFERROR(26); + error = EINVAL; + break; + } + if (error != 0) + goto donenolock; + + if (fp->fr_tif.fd_name != -1) { + if ((fp->fr_tif.fd_name < 0) || + (fp->fr_tif.fd_name >= fp->fr_namelen)) { + IPFERROR(139); + error = EINVAL; + goto donenolock; + } + } + + if (fp->fr_dif.fd_name != -1) { + if ((fp->fr_dif.fd_name < 0) || + (fp->fr_dif.fd_name >= fp->fr_namelen)) { + IPFERROR(140); + error = EINVAL; + goto donenolock; + } + } + + if (fp->fr_rif.fd_name != -1) { + if ((fp->fr_rif.fd_name < 0) || + (fp->fr_rif.fd_name >= fp->fr_namelen)) { + IPFERROR(141); + error = EINVAL; + goto donenolock; } - return EINVAL; } /* * Lookup all the interface names that are part of the rule. */ - frsynclist(fp, NULL); + error = ipf_synclist(softc, fp, NULL); + if (error != 0) + goto donenolock; fp->fr_statecnt = 0; + if (fp->fr_srctrack.ht_max_nodes != 0) + ipf_rb_ht_init(&fp->fr_srctrack); /* * Look for an existing matching filter rule, but don't include the @@ -4447,7 +4903,7 @@ caddr_t data; for (p = (u_int *)fp->fr_data; p < pp; p++) fp->fr_cksum += *p; - WRITE_ENTER(&ipf_mutex); + WRITE_ENTER(&softc->ipf_mutex); /* * Now that the filter rule lists are locked, we can walk the @@ -4462,13 +4918,15 @@ caddr_t data; } fprev = ftail; } - bzero((char *)frcache, sizeof(frcache)); for (; (f = *ftail) != NULL; ftail = &f->fr_next) { + DT2(rule_cmp, frentry_t *, fp, frentry_t *, f); if ((fp->fr_cksum != f->fr_cksum) || + (fp->fr_size != f->fr_size) || (f->fr_dsize != fp->fr_dsize)) continue; - if (bcmp((char *)&f->fr_func, (char *)&fp->fr_func, FR_CMPSIZ)) + if (bcmp((char *)&f->fr_func, (char *)&fp->fr_func, + fp->fr_size - offsetof(struct frentry, fr_func)) != 0) continue; if ((!ptr && !f->fr_data) || (ptr && f->fr_data && @@ -4479,10 +4937,11 @@ caddr_t data; /* * If zero'ing statistics, copy current to caller and zero. */ - if (req == (ioctlcmd_t)SIOCZRLST) { - if (f == NULL) + if (addrem == 2) { + if (f == NULL) { + IPFERROR(27); error = ESRCH; - else { + } else { /* * Copy and reduce lock because of impending copyout. * Well we should, but if we do then the atomicity of @@ -4491,22 +4950,24 @@ caddr_t data; * only resets them to 0 if they are successfully * copied out into user space. */ - bcopy((char *)f, (char *)fp, sizeof(*f)); - /* MUTEX_DOWNGRADE(&ipf_mutex); */ + bcopy((char *)f, (char *)fp, f->fr_size); + /* MUTEX_DOWNGRADE(&softc->ipf_mutex); */ /* * When we copy this rule back out, set the data * pointer to be what it was in user space. */ fp->fr_data = uptr; - error = fr_outobj(data, fp, IPFOBJ_FRENTRY); + error = ipf_outobj(softc, data, fp, IPFOBJ_FRENTRY); if (error == 0) { if ((f->fr_dsize != 0) && (uptr != NULL)) error = COPYOUT(f->fr_data, uptr, f->fr_dsize); - if (error != 0) + if (error != 0) { + IPFERROR(28); error = EFAULT; + } if (error == 0) { f->fr_hits = 0; f->fr_bytes = 0; @@ -4514,14 +4975,17 @@ caddr_t data; } } - if ((ptr != NULL) && (makecopy != 0)) { - KFREES(ptr, fp->fr_dsize); + if (makecopy != 0) { + if (ptr != NULL) { + KFREES(ptr, fp->fr_dsize); + } + KFREES(fp, fp->fr_size); } - RWLOCK_EXIT(&ipf_mutex); + RWLOCK_EXIT(&softc->ipf_mutex); return error; } - if (!f) { + if (!f) { /* * At the end of this, ftail must point to the place where the * new rule is to be saved/inserted/added. @@ -4539,7 +5003,6 @@ caddr_t data; } f = NULL; ptr = NULL; - error = 0; } else if (req == (ioctlcmd_t)SIOCINAFR || req == (ioctlcmd_t)SIOCINIFR) { while ((f = *fprev) != NULL) { @@ -4547,34 +5010,35 @@ caddr_t data; break; fprev = &f->fr_next; } - ftail = fprev; - if (fp->fr_hits != 0) { + ftail = fprev; + if (fp->fr_hits != 0) { while (fp->fr_hits && (f = *ftail)) { if (f->fr_collect != fp->fr_collect) break; fprev = ftail; - ftail = &f->fr_next; + ftail = &f->fr_next; fp->fr_hits--; } - } - f = NULL; - ptr = NULL; - error = 0; + } + f = NULL; + ptr = NULL; } } /* * Request to remove a rule. */ - if (req == (ioctlcmd_t)SIOCRMAFR || req == (ioctlcmd_t)SIOCRMIFR) { - if (!f) + if (addrem == 1) { + if (!f) { + IPFERROR(29); error = ESRCH; - else { + } else { /* * Do not allow activity from user space to interfere * with rules not loaded that way. */ if ((makecopy == 1) && !(f->fr_flags & FR_COPIED)) { + IPFERROR(30); error = EPERM; goto done; } @@ -4584,101 +5048,265 @@ caddr_t data; * something else (eg state information.) */ if (f->fr_ref > 1) { + IPFERROR(31); error = EBUSY; goto done; } #ifdef IPFILTER_SCAN - if (f->fr_isctag[0] != '\0' && + if (f->fr_isctag != -1 && (f->fr_isc != (struct ipscan *)-1)) - ipsc_detachfr(f); + ipf_scan_detachfr(f); #endif + if (unit == IPL_LOGAUTH) { - error = fr_preauthcmd(req, f, ftail); + error = ipf_auth_precmd(softc, req, f, ftail); goto done; } - if (*f->fr_grhead != '\0') - fr_delgroup(f->fr_grhead, unit, set); - fr_fixskip(ftail, f, -1); - *ftail = f->fr_next; - f->fr_next = NULL; - (void) fr_derefrule(&f); + + ipf_rule_delete(softc, f, unit, set); + + need_free = makecopy; } } else { /* * Not removing, so we must be adding/inserting a rule. */ - if (f) + if (f != NULL) { + IPFERROR(32); error = EEXIST; - else { - if (unit == IPL_LOGAUTH) { - error = fr_preauthcmd(req, fp, ftail); - goto done; - } - if (makecopy) { - KMALLOC(f, frentry_t *); - } else - f = fp; - if (f != NULL) { - if (fp != f) - bcopy((char *)fp, (char *)f, - sizeof(*f)); - MUTEX_NUKE(&f->fr_lock); - MUTEX_INIT(&f->fr_lock, "filter rule lock"); -#ifdef IPFILTER_SCAN - if (f->fr_isctag[0] != '\0' && - ipsc_attachfr(f)) - f->fr_isc = (struct ipscan *)-1; -#endif - f->fr_hits = 0; - if (makecopy != 0) - f->fr_ref = 1; - f->fr_next = *ftail; - *ftail = f; - if (req == (ioctlcmd_t)SIOCINIFR || - req == (ioctlcmd_t)SIOCINAFR) - fr_fixskip(ftail, f, 1); - f->fr_grp = NULL; - group = f->fr_grhead; - if (*group != '\0') { - fg = fr_addgroup(group, f, f->fr_flags, - unit, set); - if (fg != NULL) - f->fr_grp = &fg->fg_start; - } - } else - error = ENOMEM; + goto done; + } + if (unit == IPL_LOGAUTH) { + error = ipf_auth_precmd(softc, req, fp, ftail); + goto done; + } + + MUTEX_NUKE(&fp->fr_lock); + MUTEX_INIT(&fp->fr_lock, "filter rule lock"); + if (fp->fr_die != 0) + ipf_rule_expire_insert(softc, fp, set); + + fp->fr_hits = 0; + if (makecopy != 0) + fp->fr_ref = 1; + fp->fr_pnext = ftail; + fp->fr_next = *ftail; + *ftail = fp; + if (addrem == 0) + ipf_fixskip(ftail, fp, 1); + + fp->fr_icmpgrp = NULL; + if (fp->fr_icmphead != -1) { + group = FR_NAME(fp, fr_icmphead); + fg = ipf_group_add(softc, group, fp, 0, unit, set); + fp->fr_icmpgrp = fg; + } + + fp->fr_grphead = NULL; + if (fp->fr_grhead != -1) { + group = FR_NAME(fp, fr_grhead); + fg = ipf_group_add(softc, group, fp, fp->fr_flags, + unit, set); + fp->fr_grphead = fg; } } done: - RWLOCK_EXIT(&ipf_mutex); - if ((ptr != NULL) && (error != 0) && (makecopy != 0)) { - KFREES(ptr, fp->fr_dsize); + RWLOCK_EXIT(&softc->ipf_mutex); +donenolock: + if (need_free || (error != 0)) { + if ((fp->fr_type & ~FR_T_BUILTIN) == FR_T_IPF) { + if ((fp->fr_satype == FRI_LOOKUP) && + (fp->fr_srcptr != NULL)) + ipf_lookup_deref(softc, fp->fr_srctype, + fp->fr_srcptr); + if ((fp->fr_datype == FRI_LOOKUP) && + (fp->fr_dstptr != NULL)) + ipf_lookup_deref(softc, fp->fr_dsttype, + fp->fr_dstptr); + } + if (fp->fr_grp != NULL) { + WRITE_ENTER(&softc->ipf_mutex); + ipf_group_del(softc, fp->fr_grp, fp); + RWLOCK_EXIT(&softc->ipf_mutex); + } + if ((ptr != NULL) && (makecopy != 0)) { + KFREES(ptr, fp->fr_dsize); + } + KFREES(fp, fp->fr_size); } return (error); } /* ------------------------------------------------------------------------ */ -/* Function: fr_funcinit */ +/* Function: ipf_rule_delete */ +/* Returns: Nil */ +/* Parameters: softc(I) - pointer to soft context main structure */ +/* f(I) - pointer to the rule being deleted */ +/* ftail(I) - pointer to the pointer to f */ +/* unit(I) - device for which this is for */ +/* set(I) - 1 or 0 (filter set) */ +/* */ +/* This function attempts to do what it can to delete a filter rule: remove */ +/* it from any linked lists and remove any groups it is responsible for. */ +/* But in the end, removing a rule can only drop the reference count - we */ +/* must use that as the guide for whether or not it can be freed. */ +/* ------------------------------------------------------------------------ */ +static void +ipf_rule_delete(softc, f, unit, set) + ipf_main_softc_t *softc; + frentry_t *f; + int unit, set; +{ + + /* + * If fr_pdnext is set, then the rule is on the expire list, so + * remove it from there. + */ + if (f->fr_pdnext != NULL) { + *f->fr_pdnext = f->fr_dnext; + if (f->fr_dnext != NULL) + f->fr_dnext->fr_pdnext = f->fr_pdnext; + f->fr_pdnext = NULL; + f->fr_dnext = NULL; + } + + ipf_fixskip(f->fr_pnext, f, -1); + if (f->fr_pnext != NULL) + *f->fr_pnext = f->fr_next; + if (f->fr_next != NULL) + f->fr_next->fr_pnext = f->fr_pnext; + f->fr_pnext = NULL; + f->fr_next = NULL; + + (void) ipf_derefrule(softc, &f); +} + +/* ------------------------------------------------------------------------ */ +/* Function: ipf_rule_expire_insert */ +/* Returns: Nil */ +/* Parameters: softc(I) - pointer to soft context main structure */ +/* f(I) - pointer to rule to be added to expire list */ +/* set(I) - 1 or 0 (filter set) */ +/* */ +/* If the new rule has a given expiration time, insert it into the list of */ +/* expiring rules with the ones to be removed first added to the front of */ +/* the list. The insertion is O(n) but it is kept sorted for quick scans at */ +/* expiration interval checks. */ +/* ------------------------------------------------------------------------ */ +static void +ipf_rule_expire_insert(softc, f, set) + ipf_main_softc_t *softc; + frentry_t *f; + int set; +{ + frentry_t *fr; + + /* + */ + + f->fr_die = softc->ipf_ticks + IPF_TTLVAL(f->fr_die); + for (fr = softc->ipf_rule_explist[set]; fr != NULL; + fr = fr->fr_dnext) { + if (f->fr_die < fr->fr_die) + break; + if (fr->fr_dnext == NULL) { + /* + * We've got to the last rule and everything + * wanted to be expired before this new node, + * so we have to tack it on the end... + */ + fr->fr_dnext = f; + f->fr_pdnext = &fr->fr_dnext; + fr = NULL; + break; + } + } + + if (softc->ipf_rule_explist[set] == NULL) { + softc->ipf_rule_explist[set] = f; + f->fr_pdnext = &softc->ipf_rule_explist[set]; + } else if (fr != NULL) { + f->fr_dnext = fr; + f->fr_pdnext = fr->fr_pdnext; + fr->fr_pdnext = &f->fr_dnext; + } +} + + +/* ------------------------------------------------------------------------ */ +/* Function: ipf_findlookup */ +/* Returns: NULL = failure, else success */ +/* Parameters: softc(I) - pointer to soft context main structure */ +/* unit(I) - ipf device we want to find match for */ +/* fp(I) - rule for which lookup is for */ +/* addrp(I) - pointer to lookup information in address struct */ +/* maskp(O) - pointer to lookup information for storage */ +/* */ +/* When using pools and hash tables to store addresses for matching in */ +/* rules, it is necessary to resolve both the object referred to by the */ +/* name or address (and return that pointer) and also provide the means by */ +/* which to determine if an address belongs to that object to make the */ +/* packet matching quicker. */ +/* ------------------------------------------------------------------------ */ +static void * +ipf_findlookup(softc, unit, fr, addrp, maskp) + ipf_main_softc_t *softc; + int unit; + frentry_t *fr; + i6addr_t *addrp, *maskp; +{ + void *ptr = NULL; + + switch (addrp->iplookupsubtype) + { + case 0 : + ptr = ipf_lookup_res_num(softc, unit, addrp->iplookuptype, + addrp->iplookupnum, + &maskp->iplookupfunc); + break; + case 1 : + if (addrp->iplookupname < 0) + break; + if (addrp->iplookupname >= fr->fr_namelen) + break; + ptr = ipf_lookup_res_name(softc, unit, addrp->iplookuptype, + fr->fr_names + addrp->iplookupname, + &maskp->iplookupfunc); + break; + default : + break; + } + + return ptr; +} + + +/* ------------------------------------------------------------------------ */ +/* Function: ipf_funcinit */ /* Returns: int - 0 == success, else ESRCH: cannot resolve rule details */ -/* Parameters: fr(I) - pointer to filter rule */ +/* Parameters: softc(I) - pointer to soft context main structure */ +/* fr(I) - pointer to filter rule */ /* */ /* If a rule is a call rule, then check if the function it points to needs */ /* an init function to be called now the rule has been loaded. */ /* ------------------------------------------------------------------------ */ -static int fr_funcinit(fr) -frentry_t *fr; +static int +ipf_funcinit(softc, fr) + ipf_main_softc_t *softc; + frentry_t *fr; { ipfunc_resolve_t *ft; int err; + IPFERROR(34); err = ESRCH; - for (ft = fr_availfuncs; ft->ipfu_addr != NULL; ft++) + for (ft = ipf_availfuncs; ft->ipfu_addr != NULL; ft++) if (ft->ipfu_addr == fr->fr_func) { err = 0; if (ft->ipfu_init != NULL) - err = (*ft->ipfu_init)(fr); + err = (*ft->ipfu_init)(softc, fr); break; } return err; @@ -4686,18 +5314,45 @@ frentry_t *fr; /* ------------------------------------------------------------------------ */ -/* Function: fr_findfunc */ +/* Function: ipf_funcfini */ +/* Returns: Nil */ +/* Parameters: softc(I) - pointer to soft context main structure */ +/* fr(I) - pointer to filter rule */ +/* */ +/* For a given filter rule, call the matching "fini" function if the rule */ +/* is using a known function that would have resulted in the "init" being */ +/* called for ealier. */ +/* ------------------------------------------------------------------------ */ +static void +ipf_funcfini(softc, fr) + ipf_main_softc_t *softc; + frentry_t *fr; +{ + ipfunc_resolve_t *ft; + + for (ft = ipf_availfuncs; ft->ipfu_addr != NULL; ft++) + if (ft->ipfu_addr == fr->fr_func) { + if (ft->ipfu_fini != NULL) + (void) (*ft->ipfu_fini)(softc, fr); + break; + } +} + + +/* ------------------------------------------------------------------------ */ +/* Function: ipf_findfunc */ /* Returns: ipfunc_t - pointer to function if found, else NULL */ /* Parameters: funcptr(I) - function pointer to lookup */ /* */ /* Look for a function in the table of known functions. */ /* ------------------------------------------------------------------------ */ -static ipfunc_t fr_findfunc(funcptr) -ipfunc_t funcptr; +static ipfunc_t +ipf_findfunc(funcptr) + ipfunc_t funcptr; { ipfunc_resolve_t *ft; - for (ft = fr_availfuncs; ft->ipfu_addr != NULL; ft++) + for (ft = ipf_availfuncs; ft->ipfu_addr != NULL; ft++) if (ft->ipfu_addr == funcptr) return funcptr; return NULL; @@ -4705,7 +5360,7 @@ ipfunc_t funcptr; /* ------------------------------------------------------------------------ */ -/* Function: fr_resolvefunc */ +/* Function: ipf_resolvefunc */ /* Returns: int - 0 == success, else error */ /* Parameters: data(IO) - ioctl data pointer to ipfunc_resolve_t struct */ /* */ @@ -4714,46 +5369,55 @@ ipfunc_t funcptr; /* function pointer if the name is set. When found, fill in the other one */ /* so that the entire, complete, structure can be copied back to user space.*/ /* ------------------------------------------------------------------------ */ -int fr_resolvefunc(data) -void *data; +int +ipf_resolvefunc(softc, data) + ipf_main_softc_t *softc; + void *data; { ipfunc_resolve_t res, *ft; - int err; + int error; - err = BCOPYIN(data, &res, sizeof(res)); - if (err != 0) + error = BCOPYIN(data, &res, sizeof(res)); + if (error != 0) { + IPFERROR(123); return EFAULT; + } if (res.ipfu_addr == NULL && res.ipfu_name[0] != '\0') { - for (ft = fr_availfuncs; ft->ipfu_addr != NULL; ft++) + for (ft = ipf_availfuncs; ft->ipfu_addr != NULL; ft++) if (strncmp(res.ipfu_name, ft->ipfu_name, sizeof(res.ipfu_name)) == 0) { res.ipfu_addr = ft->ipfu_addr; res.ipfu_init = ft->ipfu_init; - if (COPYOUT(&res, data, sizeof(res)) != 0) + if (COPYOUT(&res, data, sizeof(res)) != 0) { + IPFERROR(35); return EFAULT; + } return 0; } } if (res.ipfu_addr != NULL && res.ipfu_name[0] == '\0') { - for (ft = fr_availfuncs; ft->ipfu_addr != NULL; ft++) + for (ft = ipf_availfuncs; ft->ipfu_addr != NULL; ft++) if (ft->ipfu_addr == res.ipfu_addr) { (void) strncpy(res.ipfu_name, ft->ipfu_name, sizeof(res.ipfu_name)); res.ipfu_init = ft->ipfu_init; - if (COPYOUT(&res, data, sizeof(res)) != 0) + if (COPYOUT(&res, data, sizeof(res)) != 0) { + IPFERROR(36); return EFAULT; + } return 0; } } + IPFERROR(37); return ESRCH; } -#if !defined(_KERNEL) || (!defined(__NetBSD__) && !defined(__OpenBSD__) && !defined(__FreeBSD__)) || \ - (defined(__FreeBSD__) && (__FreeBSD_version < 501000)) || \ - (defined(__NetBSD__) && (__NetBSD_Version__ < 105000000)) || \ - (defined(__OpenBSD__) && (OpenBSD < 200006)) +#if !defined(_KERNEL) || (!defined(__NetBSD__) && !defined(__OpenBSD__) && \ + !defined(__FreeBSD__)) || \ + FREEBSD_LT_REV(501000) || NETBSD_LT_REV(105000000) || \ + OPENBSD_LT_REV(200006) /* * From: NetBSD * ppsratecheck(): packets (or events) per second limitation. @@ -4803,17 +5467,20 @@ ppsratecheck(lasttime, curpps, maxpps) /* ------------------------------------------------------------------------ */ -/* Function: fr_derefrule */ +/* Function: ipf_derefrule */ /* Returns: int - 0 == rule freed up, else rule not freed */ /* Parameters: fr(I) - pointer to filter rule */ /* */ /* Decrement the reference counter to a rule by one. If it reaches zero, */ /* free it and any associated storage space being used by it. */ /* ------------------------------------------------------------------------ */ -int fr_derefrule(frp) -frentry_t **frp; +int +ipf_derefrule(softc, frp) + ipf_main_softc_t *softc; + frentry_t **frp; { frentry_t *fr; + frdest_t *fdp; fr = *frp; *frp = NULL; @@ -4824,18 +5491,41 @@ frentry_t **frp; MUTEX_EXIT(&fr->fr_lock); MUTEX_DESTROY(&fr->fr_lock); -#ifdef IPFILTER_LOOKUP - if (fr->fr_type == FR_T_IPF && fr->fr_satype == FRI_LOOKUP) - ip_lookup_deref(fr->fr_srctype, fr->fr_srcptr); - if (fr->fr_type == FR_T_IPF && fr->fr_datype == FRI_LOOKUP) - ip_lookup_deref(fr->fr_dsttype, fr->fr_dstptr); -#endif + ipf_funcfini(softc, fr); + + fdp = &fr->fr_tif; + if (fdp->fd_type == FRD_DSTLIST) + ipf_lookup_deref(softc, IPLT_DSTLIST, fdp->fd_ptr); + + fdp = &fr->fr_rif; + if (fdp->fd_type == FRD_DSTLIST) + ipf_lookup_deref(softc, IPLT_DSTLIST, fdp->fd_ptr); + + fdp = &fr->fr_dif; + if (fdp->fd_type == FRD_DSTLIST) + ipf_lookup_deref(softc, IPLT_DSTLIST, fdp->fd_ptr); + + if ((fr->fr_type & ~FR_T_BUILTIN) == FR_T_IPF && + fr->fr_satype == FRI_LOOKUP) + ipf_lookup_deref(softc, fr->fr_srctype, fr->fr_srcptr); + if ((fr->fr_type & ~FR_T_BUILTIN) == FR_T_IPF && + fr->fr_datype == FRI_LOOKUP) + ipf_lookup_deref(softc, fr->fr_dsttype, fr->fr_dstptr); + + if (fr->fr_grp != NULL) + ipf_group_del(softc, fr->fr_grp, fr); + + if (fr->fr_grphead != NULL) + ipf_group_del(softc, fr->fr_grphead, fr); + + if (fr->fr_icmpgrp != NULL) + ipf_group_del(softc, fr->fr_icmpgrp, fr); - if (fr->fr_dsize) { - KFREES(fr->fr_data, fr->fr_dsize); - } if ((fr->fr_flags & FR_COPIED) != 0) { - KFREE(fr); + if (fr->fr_dsize) { + KFREES(fr->fr_data, fr->fr_dsize); + } + KFREES(fr, fr->fr_size); return 0; } return 1; @@ -4846,17 +5536,18 @@ frentry_t **frp; } -#ifdef IPFILTER_LOOKUP /* ------------------------------------------------------------------------ */ -/* Function: fr_grpmapinit */ +/* Function: ipf_grpmapinit */ /* Returns: int - 0 == success, else ESRCH because table entry not found*/ /* Parameters: fr(I) - pointer to rule to find hash table for */ /* */ /* Looks for group hash table fr_arg and stores a pointer to it in fr_ptr. */ -/* fr_ptr is later used by fr_srcgrpmap and fr_dstgrpmap. */ +/* fr_ptr is later used by ipf_srcgrpmap and ipf_dstgrpmap. */ /* ------------------------------------------------------------------------ */ -static int fr_grpmapinit(fr) -frentry_t *fr; +static int +ipf_grpmapinit(softc, fr) + ipf_main_softc_t *softc; + frentry_t *fr; { char name[FR_GROUPLEN]; iphtable_t *iph; @@ -4866,18 +5557,45 @@ frentry_t *fr; #else (void) sprintf(name, "%d", fr->fr_arg); #endif - iph = fr_findhtable(IPL_LOGIPF, name); - if (iph == NULL) + iph = ipf_lookup_find_htable(softc, IPL_LOGIPF, name); + if (iph == NULL) { + IPFERROR(38); return ESRCH; - if ((iph->iph_flags & FR_INOUT) != (fr->fr_flags & FR_INOUT)) + } + if ((iph->iph_flags & FR_INOUT) != (fr->fr_flags & FR_INOUT)) { + IPFERROR(39); return ESRCH; + } + iph->iph_ref++; fr->fr_ptr = iph; return 0; } /* ------------------------------------------------------------------------ */ -/* Function: fr_srcgrpmap */ +/* Function: ipf_grpmapfini */ +/* Returns: int - 0 == success, else ESRCH because table entry not found*/ +/* Parameters: softc(I) - pointer to soft context main structure */ +/* fr(I) - pointer to rule to release hash table for */ +/* */ +/* For rules that have had ipf_grpmapinit called, ipf_lookup_deref needs to */ +/* be called to undo what ipf_grpmapinit caused to be done. */ +/* ------------------------------------------------------------------------ */ +static int +ipf_grpmapfini(softc, fr) + ipf_main_softc_t *softc; + frentry_t *fr; +{ + iphtable_t *iph; + iph = fr->fr_ptr; + if (iph != NULL) + ipf_lookup_deref(softc, IPLT_HASH, iph); + return 0; +} + + +/* ------------------------------------------------------------------------ */ +/* Function: ipf_srcgrpmap */ /* Returns: frentry_t * - pointer to "new last matching" rule or NULL */ /* Parameters: fin(I) - pointer to packet information */ /* passp(IO) - pointer to current/new filter decision (unused) */ @@ -4886,26 +5604,28 @@ frentry_t *fr; /* the key, and descend into that group and continue matching rules against */ /* the packet. */ /* ------------------------------------------------------------------------ */ -frentry_t *fr_srcgrpmap(fin, passp) -fr_info_t *fin; -u_32_t *passp; +frentry_t * +ipf_srcgrpmap(fin, passp) + fr_info_t *fin; + u_32_t *passp; { frgroup_t *fg; void *rval; - rval = fr_iphmfindgroup(fin->fin_fr->fr_ptr, &fin->fin_src); + rval = ipf_iphmfindgroup(fin->fin_main_soft, fin->fin_fr->fr_ptr, + &fin->fin_src); if (rval == NULL) return NULL; fg = rval; fin->fin_fr = fg->fg_start; - (void) fr_scanlist(fin, *passp); + (void) ipf_scanlist(fin, *passp); return fin->fin_fr; } /* ------------------------------------------------------------------------ */ -/* Function: fr_dstgrpmap */ +/* Function: ipf_dstgrpmap */ /* Returns: frentry_t * - pointer to "new last matching" rule or NULL */ /* Parameters: fin(I) - pointer to packet information */ /* passp(IO) - pointer to current/new filter decision (unused) */ @@ -4914,37 +5634,39 @@ u_32_t *passp; /* address as the key, and descend into that group and continue matching */ /* rules against the packet. */ /* ------------------------------------------------------------------------ */ -frentry_t *fr_dstgrpmap(fin, passp) -fr_info_t *fin; -u_32_t *passp; +frentry_t * +ipf_dstgrpmap(fin, passp) + fr_info_t *fin; + u_32_t *passp; { frgroup_t *fg; void *rval; - rval = fr_iphmfindgroup(fin->fin_fr->fr_ptr, &fin->fin_dst); + rval = ipf_iphmfindgroup(fin->fin_main_soft, fin->fin_fr->fr_ptr, + &fin->fin_dst); if (rval == NULL) return NULL; fg = rval; fin->fin_fr = fg->fg_start; - (void) fr_scanlist(fin, *passp); + (void) ipf_scanlist(fin, *passp); return fin->fin_fr; } -#endif /* IPFILTER_LOOKUP */ /* * Queue functions * =============== - * These functions manage objects on queues for efficient timeouts. There are - * a number of system defined queues as well as user defined timeouts. It is - * expected that a lock is held in the domain in which the queue belongs - * (i.e. either state or NAT) when calling any of these functions that prevents - * fr_freetimeoutqueue() from being called at the same time as any other. + * These functions manage objects on queues for efficient timeouts. There + * are a number of system defined queues as well as user defined timeouts. + * It is expected that a lock is held in the domain in which the queue + * belongs (i.e. either state or NAT) when calling any of these functions + * that prevents ipf_freetimeoutqueue() from being called at the same time + * as any other. */ /* ------------------------------------------------------------------------ */ -/* Function: fr_addtimeoutqueue */ +/* Function: ipf_addtimeoutqueue */ /* Returns: struct ifqtq * - NULL if malloc fails, else pointer to */ /* timeout queue with given interval. */ /* Parameters: parent(I) - pointer to pointer to parent node of this list */ @@ -4960,16 +5682,18 @@ u_32_t *passp; /* It is assumed that the caller of this function has an appropriate lock */ /* held (exclusively) in the domain that encompases 'parent'. */ /* ------------------------------------------------------------------------ */ -ipftq_t *fr_addtimeoutqueue(parent, seconds) -ipftq_t **parent; -u_int seconds; +ipftq_t * +ipf_addtimeoutqueue(softc, parent, seconds) + ipf_main_softc_t *softc; + ipftq_t **parent; + u_int seconds; { ipftq_t *ifq; u_int period; period = seconds * IPF_HZ_DIVIDE; - MUTEX_ENTER(&ipf_timeoutlock); + MUTEX_ENTER(&softc->ipf_timeoutlock); for (ifq = *parent; ifq != NULL; ifq = ifq->ifq_next) { if (ifq->ifq_ttl == period) { /* @@ -4980,7 +5704,7 @@ u_int seconds; ifq->ifq_flags &= ~IFQF_DELETE; ifq->ifq_ref++; MUTEX_EXIT(&ifq->ifq_lock); - MUTEX_EXIT(&ipf_timeoutlock); + MUTEX_EXIT(&softc->ipf_timeoutlock); return ifq; } @@ -4988,25 +5712,22 @@ u_int seconds; KMALLOC(ifq, ipftq_t *); if (ifq != NULL) { - ifq->ifq_ttl = period; - ifq->ifq_head = NULL; - ifq->ifq_tail = &ifq->ifq_head; + MUTEX_NUKE(&ifq->ifq_lock); + IPFTQ_INIT(ifq, period, "ipftq mutex"); ifq->ifq_next = *parent; ifq->ifq_pnext = parent; - ifq->ifq_ref = 1; ifq->ifq_flags = IFQF_USER; + ifq->ifq_ref++; *parent = ifq; - fr_userifqs++; - MUTEX_NUKE(&ifq->ifq_lock); - MUTEX_INIT(&ifq->ifq_lock, "ipftq mutex"); + softc->ipf_userifqs++; } - MUTEX_EXIT(&ipf_timeoutlock); + MUTEX_EXIT(&softc->ipf_timeoutlock); return ifq; } /* ------------------------------------------------------------------------ */ -/* Function: fr_deletetimeoutqueue */ +/* Function: ipf_deletetimeoutqueue */ /* Returns: int - new reference count value of the timeout queue */ /* Parameters: ifq(I) - timeout queue which is losing a reference. */ /* Locks: ifq->ifq_lock */ @@ -5020,8 +5741,9 @@ u_int seconds; /* way because the locking may not be sufficient to safely do a free when */ /* this function is called. */ /* ------------------------------------------------------------------------ */ -int fr_deletetimeoutqueue(ifq) -ipftq_t *ifq; +int +ipf_deletetimeoutqueue(ifq) + ipftq_t *ifq; { ifq->ifq_ref--; @@ -5034,7 +5756,7 @@ ipftq_t *ifq; /* ------------------------------------------------------------------------ */ -/* Function: fr_freetimeoutqueue */ +/* Function: ipf_freetimeoutqueue */ /* Parameters: ifq(I) - timeout queue which is losing a reference. */ /* Returns: Nil */ /* */ @@ -5043,17 +5765,18 @@ ipftq_t *ifq; /* held (exclusively) in the domain that encompases the callers "domain". */ /* The ifq_lock for this structure should not be held. */ /* */ -/* Remove a user definde timeout queue from the list of queues it is in and */ +/* Remove a user defined timeout queue from the list of queues it is in and */ /* tidy up after this is done. */ /* ------------------------------------------------------------------------ */ -void fr_freetimeoutqueue(ifq) -ipftq_t *ifq; +void +ipf_freetimeoutqueue(softc, ifq) + ipf_main_softc_t *softc; + ipftq_t *ifq; { - if (((ifq->ifq_flags & IFQF_DELETE) == 0) || (ifq->ifq_ref != 0) || ((ifq->ifq_flags & IFQF_USER) == 0)) { - printf("fr_freetimeoutqueue(%lx) flags 0x%x ttl %d ref %d\n", + printf("ipf_freetimeoutqueue(%lx) flags 0x%x ttl %d ref %d\n", (u_long)ifq, ifq->ifq_flags, ifq->ifq_ttl, ifq->ifq_ref); return; @@ -5065,26 +5788,28 @@ ipftq_t *ifq; *ifq->ifq_pnext = ifq->ifq_next; if (ifq->ifq_next != NULL) ifq->ifq_next->ifq_pnext = ifq->ifq_pnext; + ifq->ifq_next = NULL; + ifq->ifq_pnext = NULL; MUTEX_DESTROY(&ifq->ifq_lock); - ATOMIC_DEC(fr_userifqs); + ATOMIC_DEC(softc->ipf_userifqs); KFREE(ifq); } /* ------------------------------------------------------------------------ */ -/* Function: fr_deletequeueentry */ +/* Function: ipf_deletequeueentry */ /* Returns: Nil */ /* Parameters: tqe(I) - timeout queue entry to delete */ -/* ifq(I) - timeout queue to remove entry from */ /* */ /* Remove a tail queue entry from its queue and make it an orphan. */ -/* fr_deletetimeoutqueue is called to make sure the reference count on the */ -/* queue is correct. We can't, however, call fr_freetimeoutqueue because */ +/* ipf_deletetimeoutqueue is called to make sure the reference count on the */ +/* queue is correct. We can't, however, call ipf_freetimeoutqueue because */ /* the correct lock(s) may not be held that would make it safe to do so. */ /* ------------------------------------------------------------------------ */ -void fr_deletequeueentry(tqe) -ipftqent_t *tqe; +void +ipf_deletequeueentry(tqe) + ipftqent_t *tqe; { ipftq_t *ifq; @@ -5103,21 +5828,23 @@ ipftqent_t *tqe; tqe->tqe_ifq = NULL; } - (void) fr_deletetimeoutqueue(ifq); + (void) ipf_deletetimeoutqueue(ifq); + ASSERT(ifq->ifq_ref > 0); MUTEX_EXIT(&ifq->ifq_lock); } /* ------------------------------------------------------------------------ */ -/* Function: fr_queuefront */ +/* Function: ipf_queuefront */ /* Returns: Nil */ /* Parameters: tqe(I) - pointer to timeout queue entry */ /* */ /* Move a queue entry to the front of the queue, if it isn't already there. */ /* ------------------------------------------------------------------------ */ -void fr_queuefront(tqe) -ipftqent_t *tqe; +void +ipf_queuefront(tqe) + ipftqent_t *tqe; { ipftq_t *ifq; @@ -5143,21 +5870,27 @@ ipftqent_t *tqe; /* ------------------------------------------------------------------------ */ -/* Function: fr_queueback */ +/* Function: ipf_queueback */ /* Returns: Nil */ -/* Parameters: tqe(I) - pointer to timeout queue entry */ +/* Parameters: ticks(I) - ipf tick time to use with this call */ +/* tqe(I) - pointer to timeout queue entry */ /* */ /* Move a queue entry to the back of the queue, if it isn't already there. */ +/* We use use ticks to calculate the expiration and mark for when we last */ +/* touched the structure. */ /* ------------------------------------------------------------------------ */ -void fr_queueback(tqe) -ipftqent_t *tqe; +void +ipf_queueback(ticks, tqe) + u_long ticks; + ipftqent_t *tqe; { ipftq_t *ifq; ifq = tqe->tqe_ifq; if (ifq == NULL) return; - tqe->tqe_die = fr_ticks + ifq->ifq_ttl; + tqe->tqe_die = ticks + ifq->ifq_ttl; + tqe->tqe_touched = ticks; MUTEX_ENTER(&ifq->ifq_lock); if (tqe->tqe_next != NULL) { /* at the end already ? */ @@ -5180,18 +5913,23 @@ ipftqent_t *tqe; /* ------------------------------------------------------------------------ */ -/* Function: fr_queueappend */ +/* Function: ipf_queueappend */ /* Returns: Nil */ -/* Parameters: tqe(I) - pointer to timeout queue entry */ +/* Parameters: ticks(I) - ipf tick time to use with this call */ +/* tqe(I) - pointer to timeout queue entry */ /* ifq(I) - pointer to timeout queue */ /* parent(I) - owing object pointer */ /* */ /* Add a new item to this queue and put it on the very end. */ +/* We use use ticks to calculate the expiration and mark for when we last */ +/* touched the structure. */ /* ------------------------------------------------------------------------ */ -void fr_queueappend(tqe, ifq, parent) -ipftqent_t *tqe; -ipftq_t *ifq; -void *parent; +void +ipf_queueappend(ticks, tqe, ifq, parent) + u_long ticks; + ipftqent_t *tqe; + ipftq_t *ifq; + void *parent; { MUTEX_ENTER(&ifq->ifq_lock); @@ -5201,14 +5939,15 @@ void *parent; ifq->ifq_tail = &tqe->tqe_next; tqe->tqe_next = NULL; tqe->tqe_ifq = ifq; - tqe->tqe_die = fr_ticks + ifq->ifq_ttl; + tqe->tqe_die = ticks + ifq->ifq_ttl; + tqe->tqe_touched = ticks; ifq->ifq_ref++; MUTEX_EXIT(&ifq->ifq_lock); } /* ------------------------------------------------------------------------ */ -/* Function: fr_movequeue */ +/* Function: ipf_movequeue */ /* Returns: Nil */ /* Parameters: tq(I) - pointer to timeout queue information */ /* oifp(I) - old timeout queue entry was on */ @@ -5218,58 +5957,82 @@ void *parent; /* If it notices that the current entry is already last and does not need */ /* to move queue, the return. */ /* ------------------------------------------------------------------------ */ -void fr_movequeue(tqe, oifq, nifq) -ipftqent_t *tqe; -ipftq_t *oifq, *nifq; +void +ipf_movequeue(ticks, tqe, oifq, nifq) + u_long ticks; + ipftqent_t *tqe; + ipftq_t *oifq, *nifq; { + + /* + * If the queue hasn't changed and we last touched this entry at the + * same ipf time, then we're not going to achieve anything by either + * changing the ttl or moving it on the queue. + */ + if (oifq == nifq && tqe->tqe_touched == ticks) + return; + + /* + * For any of this to be outside the lock, there is a risk that two + * packets entering simultaneously, with one changing to a different + * queue and one not, could end up with things in a bizarre state. + */ + MUTEX_ENTER(&oifq->ifq_lock); + + tqe->tqe_touched = ticks; + tqe->tqe_die = ticks + nifq->ifq_ttl; /* * Is the operation here going to be a no-op ? */ - MUTEX_ENTER(&oifq->ifq_lock); - if ((oifq != nifq) || (*oifq->ifq_tail != tqe)) { - /* - * Remove from the old queue - */ - *tqe->tqe_pnext = tqe->tqe_next; - if (tqe->tqe_next) - tqe->tqe_next->tqe_pnext = tqe->tqe_pnext; - else - oifq->ifq_tail = tqe->tqe_pnext; - tqe->tqe_next = NULL; - - /* - * If we're moving from one queue to another, release the - * lock on the old queue and get a lock on the new queue. - * For user defined queues, if we're moving off it, call - * delete in case it can now be freed. - */ - if (oifq != nifq) { - tqe->tqe_ifq = NULL; - - (void) fr_deletetimeoutqueue(oifq); - + if (oifq == nifq) { + if ((tqe->tqe_next == NULL) || + (tqe->tqe_next->tqe_die == tqe->tqe_die)) { MUTEX_EXIT(&oifq->ifq_lock); - - MUTEX_ENTER(&nifq->ifq_lock); - - tqe->tqe_ifq = nifq; - nifq->ifq_ref++; + return; } - - /* - * Add to the bottom of the new queue - */ - tqe->tqe_die = fr_ticks + nifq->ifq_ttl; - tqe->tqe_pnext = nifq->ifq_tail; - *nifq->ifq_tail = tqe; - nifq->ifq_tail = &tqe->tqe_next; } + + /* + * Remove from the old queue + */ + *tqe->tqe_pnext = tqe->tqe_next; + if (tqe->tqe_next) + tqe->tqe_next->tqe_pnext = tqe->tqe_pnext; + else + oifq->ifq_tail = tqe->tqe_pnext; + tqe->tqe_next = NULL; + + /* + * If we're moving from one queue to another, release the + * lock on the old queue and get a lock on the new queue. + * For user defined queues, if we're moving off it, call + * delete in case it can now be freed. + */ + if (oifq != nifq) { + tqe->tqe_ifq = NULL; + + (void) ipf_deletetimeoutqueue(oifq); + + MUTEX_EXIT(&oifq->ifq_lock); + + MUTEX_ENTER(&nifq->ifq_lock); + + tqe->tqe_ifq = nifq; + nifq->ifq_ref++; + } + + /* + * Add to the bottom of the new queue + */ + tqe->tqe_pnext = nifq->ifq_tail; + *nifq->ifq_tail = tqe; + nifq->ifq_tail = &tqe->tqe_next; MUTEX_EXIT(&nifq->ifq_lock); } /* ------------------------------------------------------------------------ */ -/* Function: fr_updateipid */ +/* Function: ipf_updateipid */ /* Returns: int - 0 == success, -1 == error (packet should be droppped) */ /* Parameters: fin(I) - pointer to packet information */ /* */ @@ -5280,23 +6043,24 @@ ipftq_t *oifq, *nifq; /* the fragment cache for non-leading fragments. If a non-leading fragment */ /* has no match in the cache, return an error. */ /* ------------------------------------------------------------------------ */ -static int fr_updateipid(fin) -fr_info_t *fin; +static int +ipf_updateipid(fin) + fr_info_t *fin; { u_short id, ido, sums; u_32_t sumd, sum; ip_t *ip; if (fin->fin_off != 0) { - sum = fr_ipid_knownfrag(fin); + sum = ipf_frag_ipidknown(fin); if (sum == 0xffffffff) return -1; sum &= 0xffff; id = (u_short)sum; } else { - id = fr_nextipid(fin); + id = ipf_nextipid(fin); if (fin->fin_off == 0 && (fin->fin_flx & FI_FRAG) != 0) - (void) fr_ipid_newfrag(fin, (u_32_t)id); + (void) ipf_frag_ipidnew(fin, (u_32_t)id); } ip = fin->fin_ip; @@ -5317,7 +6081,7 @@ fr_info_t *fin; #ifdef NEED_FRGETIFNAME /* ------------------------------------------------------------------------ */ -/* Function: fr_getifname */ +/* Function: ipf_getifname */ /* Returns: char * - pointer to interface name */ /* Parameters: ifp(I) - pointer to network interface */ /* buffer(O) - pointer to where to store interface name */ @@ -5326,9 +6090,10 @@ fr_info_t *fin; /* expected to be at least LIFNAMSIZ in bytes big. If buffer is passed in */ /* as a NULL pointer then return a pointer to a static array. */ /* ------------------------------------------------------------------------ */ -char *fr_getifname(ifp, buffer) -struct ifnet *ifp; -char *buffer; +char * +ipf_getifname(ifp, buffer) + struct ifnet *ifp; + char *buffer; { static char namebuf[LIFNAMSIZ]; # if defined(MENTAT) || defined(__FreeBSD__) || defined(__osf__) || \ @@ -5350,7 +6115,7 @@ char *buffer; ; unit = ifp->if_unit; space = LIFNAMSIZ - (s - buffer); - if (space > 0) { + if ((space > 0) && (unit >= 0)) { # if defined(SNPRINTF) && defined(_KERNEL) SNPRINTF(temp, sizeof(temp), "%d", unit); # else @@ -5365,7 +6130,7 @@ char *buffer; /* ------------------------------------------------------------------------ */ -/* Function: fr_ioctlswitch */ +/* Function: ipf_ioctlswitch */ /* Returns: int - -1 continue processing, else ioctl return value */ /* Parameters: unit(I) - device unit opened */ /* data(I) - pointer to ioctl data */ @@ -5376,63 +6141,99 @@ char *buffer; /* */ /* Based on the value of unit, call the appropriate ioctl handler or return */ /* EIO if ipfilter is not running. Also checks if write perms are req'd */ -/* for the device in order to execute the ioctl. */ +/* for the device in order to execute the ioctl. A special case is made */ +/* SIOCIPFINTERROR so that the same code isn't required in every handler. */ +/* The context data pointer is passed through as this is used as the key */ +/* for locating a matching token for continued access for walking lists, */ +/* etc. */ /* ------------------------------------------------------------------------ */ -int fr_ioctlswitch(unit, data, cmd, mode, uid, ctx) -int unit, mode, uid; -ioctlcmd_t cmd; -void *data, *ctx; +int +ipf_ioctlswitch(softc, unit, data, cmd, mode, uid, ctx) + ipf_main_softc_t *softc; + int unit, mode, uid; + ioctlcmd_t cmd; + void *data, *ctx; { int error = 0; + switch (cmd) + { + case SIOCIPFINTERROR : + error = BCOPYOUT(&softc->ipf_interror, data, + sizeof(softc->ipf_interror)); + if (error != 0) { + IPFERROR(40); + error = EFAULT; + } + return error; + default : + break; + } + switch (unit) { case IPL_LOGIPF : - error = fr_ipf_ioctl(data, cmd, mode, uid, ctx); + error = ipf_ipf_ioctl(softc, data, cmd, mode, uid, ctx); break; case IPL_LOGNAT : - if (fr_running > 0) - error = fr_nat_ioctl(data, cmd, mode, uid, ctx); - else + if (softc->ipf_running > 0) { + error = ipf_nat_ioctl(softc, data, cmd, mode, + uid, ctx); + } else { + IPFERROR(42); error = EIO; + } break; case IPL_LOGSTATE : - if (fr_running > 0) - error = fr_state_ioctl(data, cmd, mode, uid, ctx); - else + if (softc->ipf_running > 0) { + error = ipf_state_ioctl(softc, data, cmd, mode, + uid, ctx); + } else { + IPFERROR(43); error = EIO; + } break; case IPL_LOGAUTH : - if (fr_running > 0) - error = fr_auth_ioctl(data, cmd, mode, uid, ctx); - else + if (softc->ipf_running > 0) { + error = ipf_auth_ioctl(softc, data, cmd, mode, + uid, ctx); + } else { + IPFERROR(44); error = EIO; + } break; case IPL_LOGSYNC : -#ifdef IPFILTER_SYNC - if (fr_running > 0) - error = fr_sync_ioctl(data, cmd, mode, uid, ctx); - else -#endif + if (softc->ipf_running > 0) { + error = ipf_sync_ioctl(softc, data, cmd, mode, + uid, ctx); + } else { error = EIO; + IPFERROR(45); + } break; case IPL_LOGSCAN : #ifdef IPFILTER_SCAN - if (fr_running > 0) - error = fr_scan_ioctl(data, cmd, mode, uid, ctx); + if (softc->ipf_running > 0) + error = ipf_scan_ioctl(softc, data, cmd, mode, + uid, ctx); else #endif + { error = EIO; + IPFERROR(46); + } break; case IPL_LOGLOOKUP : -#ifdef IPFILTER_LOOKUP - if (fr_running > 0) - error = ip_lookup_ioctl(data, cmd, mode, uid, ctx); - else -#endif + if (softc->ipf_running > 0) { + error = ipf_lookup_ioctl(softc, data, cmd, mode, + uid, ctx); + } else { error = EIO; + IPFERROR(47); + } break; default : + IPFERROR(48); error = EIO; break; } @@ -5443,200 +6244,244 @@ void *data, *ctx; /* * This array defines the expected size of objects coming into the kernel - * for the various recognised object types. + * for the various recognised object types. The first column is flags (see + * below), 2nd column is current size, 3rd column is the version number of + * when the current size became current. + * Flags: + * 1 = minimum size, not absolute size */ -static int fr_objbytes[IPFOBJ_COUNT][2] = { - { 1, sizeof(struct frentry) }, /* frentry */ - { 0, sizeof(struct friostat) }, - { 0, sizeof(struct fr_info) }, - { 0, sizeof(struct fr_authstat) }, - { 0, sizeof(struct ipfrstat) }, - { 0, sizeof(struct ipnat) }, - { 0, sizeof(struct natstat) }, - { 0, sizeof(struct ipstate_save) }, - { 1, sizeof(struct nat_save) }, /* nat_save */ - { 0, sizeof(struct natlookup) }, - { 1, sizeof(struct ipstate) }, /* ipstate */ - { 0, sizeof(struct ips_stat) }, - { 0, sizeof(struct frauth) }, - { 0, sizeof(struct ipftune) }, - { 0, sizeof(struct nat) }, /* nat_t */ - { 0, sizeof(struct ipfruleiter) }, - { 0, sizeof(struct ipfgeniter) }, - { 0, sizeof(struct ipftable) }, - { 0, sizeof(struct ipflookupiter) }, +static int ipf_objbytes[IPFOBJ_COUNT][3] = { + { 1, sizeof(struct frentry), 5010000 }, /* 0 */ + { 1, sizeof(struct friostat), 5010000 }, + { 0, sizeof(struct fr_info), 5010000 }, + { 0, sizeof(struct ipf_authstat), 4010100 }, + { 0, sizeof(struct ipfrstat), 5010000 }, + { 1, sizeof(struct ipnat), 5010000 }, /* 5 */ + { 0, sizeof(struct natstat), 5010000 }, + { 0, sizeof(struct ipstate_save), 5010000 }, + { 1, sizeof(struct nat_save), 5010000 }, + { 0, sizeof(struct natlookup), 5010000 }, + { 1, sizeof(struct ipstate), 5010000 }, /* 10 */ + { 0, sizeof(struct ips_stat), 5010000 }, + { 0, sizeof(struct frauth), 5010000 }, + { 0, sizeof(struct ipftune), 4010100 }, + { 0, sizeof(struct nat), 5010000 }, + { 0, sizeof(struct ipfruleiter), 4011400 }, /* 15 */ + { 0, sizeof(struct ipfgeniter), 4011400 }, + { 0, sizeof(struct ipftable), 4011400 }, + { 0, sizeof(struct ipflookupiter), 4011400 }, { 0, sizeof(struct ipftq) * IPF_TCP_NSTATES }, + { 1, 0, 0 }, /* IPFEXPR */ + { 0, 0, 0 }, /* PROXYCTL */ + { 0, sizeof (struct fripf), 5010000 } }; /* ------------------------------------------------------------------------ */ -/* Function: fr_inobj */ +/* Function: ipf_inobj */ /* Returns: int - 0 = success, else failure */ -/* Parameters: data(I) - pointer to ioctl data */ -/* ptr(I) - pointer to store real data in */ -/* type(I) - type of structure being moved */ +/* Parameters: softc(I) - soft context pointerto work with */ +/* data(I) - pointer to ioctl data */ +/* objp(O) - where to store ipfobj structure */ +/* ptr(I) - pointer to data to copy out */ +/* type(I) - type of structure being moved */ /* */ /* Copy in the contents of what the ipfobj_t points to. In future, we */ /* add things to check for version numbers, sizes, etc, to make it backward */ /* compatible at the ABI for user land. */ +/* If objp is not NULL then we assume that the caller wants to see what is */ +/* in the ipfobj_t structure being copied in. As an example, this can tell */ +/* the caller what version of ipfilter the ioctl program was written to. */ /* ------------------------------------------------------------------------ */ -int fr_inobj(data, ptr, type) -void *data; -void *ptr; -int type; +int +ipf_inobj(softc, data, objp, ptr, type) + ipf_main_softc_t *softc; + void *data; + ipfobj_t *objp; + void *ptr; + int type; { ipfobj_t obj; - int error = 0; + int error; + int size; - if ((type < 0) || (type >= IPFOBJ_COUNT)) - return EINVAL; - - error = BCOPYIN(data, &obj, sizeof(obj)); - if (error != 0) - return EFAULT; - - if (obj.ipfo_type != type) - return EINVAL; - -#ifndef IPFILTER_COMPAT - if ((fr_objbytes[type][0] & 1) != 0) { - if (obj.ipfo_size < fr_objbytes[type][1]) - return EINVAL; - } else if (obj.ipfo_size != fr_objbytes[type][1]) { + if ((type < 0) || (type >= IPFOBJ_COUNT)) { + IPFERROR(49); return EINVAL; } -#else - if (obj.ipfo_rev != IPFILTER_VERSION) - /* XXX compatibility hook here */ - ; - if ((fr_objbytes[type][0] & 1) != 0) { - if (obj.ipfo_size < fr_objbytes[type][1]) - /* XXX compatibility hook here */ - return EINVAL; - } else if (obj.ipfo_size != fr_objbytes[type][1]) - /* XXX compatibility hook here */ - return EINVAL; -#endif - if ((fr_objbytes[type][0] & 1) != 0) { - error = COPYIN(obj.ipfo_ptr, ptr, fr_objbytes[type][1]); + if (objp == NULL) + objp = &obj; + error = BCOPYIN(data, objp, sizeof(*objp)); + if (error != 0) { + IPFERROR(124); + return EFAULT; + } + + if (objp->ipfo_type != type) { + IPFERROR(50); + return EINVAL; + } + + if (objp->ipfo_rev >= ipf_objbytes[type][2]) { + if ((ipf_objbytes[type][0] & 1) != 0) { + if (objp->ipfo_size < ipf_objbytes[type][1]) { + IPFERROR(51); + return EINVAL; + } + size = ipf_objbytes[type][1]; + } else if (objp->ipfo_size == ipf_objbytes[type][1]) { + size = objp->ipfo_size; + } else { + IPFERROR(52); + return EINVAL; + } + error = COPYIN(objp->ipfo_ptr, ptr, size); + if (error != 0) { + IPFERROR(55); + error = EFAULT; + } } else { - error = COPYIN(obj.ipfo_ptr, ptr, obj.ipfo_size); +#ifdef IPFILTER_COMPAT + error = ipf_in_compat(softc, objp, ptr, 0); +#else + IPFERROR(54); + error = EINVAL; +#endif } - if (error != 0) - error = EFAULT; return error; } /* ------------------------------------------------------------------------ */ -/* Function: fr_inobjsz */ +/* Function: ipf_inobjsz */ +/* Returns: int - 0 = success, else failure */ +/* Parameters: softc(I) - soft context pointerto work with */ +/* data(I) - pointer to ioctl data */ +/* ptr(I) - pointer to store real data in */ +/* type(I) - type of structure being moved */ +/* sz(I) - size of data to copy */ +/* */ +/* As per ipf_inobj, except the size of the object to copy in is passed in */ +/* but it must not be smaller than the size defined for the type and the */ +/* type must allow for varied sized objects. The extra requirement here is */ +/* that sz must match the size of the object being passed in - this is not */ +/* not possible nor required in ipf_inobj(). */ +/* ------------------------------------------------------------------------ */ +int +ipf_inobjsz(softc, data, ptr, type, sz) + ipf_main_softc_t *softc; + void *data; + void *ptr; + int type, sz; +{ + ipfobj_t obj; + int error; + + if ((type < 0) || (type >= IPFOBJ_COUNT)) { + IPFERROR(56); + return EINVAL; + } + + error = BCOPYIN(data, &obj, sizeof(obj)); + if (error != 0) { + IPFERROR(125); + return EFAULT; + } + + if (obj.ipfo_type != type) { + IPFERROR(58); + return EINVAL; + } + + if (obj.ipfo_rev >= ipf_objbytes[type][2]) { + if (((ipf_objbytes[type][0] & 1) == 0) || + (sz < ipf_objbytes[type][1])) { + IPFERROR(57); + return EINVAL; + } + error = COPYIN(obj.ipfo_ptr, ptr, sz); + if (error != 0) { + IPFERROR(61); + error = EFAULT; + } + } else { +#ifdef IPFILTER_COMPAT + error = ipf_in_compat(softc, &obj, ptr, sz); +#else + IPFERROR(60); + error = EINVAL; +#endif + } + return error; +} + + +/* ------------------------------------------------------------------------ */ +/* Function: ipf_outobjsz */ /* Returns: int - 0 = success, else failure */ /* Parameters: data(I) - pointer to ioctl data */ /* ptr(I) - pointer to store real data in */ /* type(I) - type of structure being moved */ /* sz(I) - size of data to copy */ /* */ -/* As per fr_inobj, except the size of the object to copy in is passed in */ +/* As per ipf_outobj, except the size of the object to copy out is passed in*/ /* but it must not be smaller than the size defined for the type and the */ /* type must allow for varied sized objects. The extra requirement here is */ /* that sz must match the size of the object being passed in - this is not */ -/* not possible nor required in fr_inobj(). */ +/* not possible nor required in ipf_outobj(). */ /* ------------------------------------------------------------------------ */ -int fr_inobjsz(data, ptr, type, sz) -void *data; -void *ptr; -int type, sz; +int +ipf_outobjsz(softc, data, ptr, type, sz) + ipf_main_softc_t *softc; + void *data; + void *ptr; + int type, sz; { ipfobj_t obj; int error; - if ((type < 0) || (type >= IPFOBJ_COUNT)) - return EINVAL; - if (((fr_objbytes[type][0] & 1) == 0) || (sz < fr_objbytes[type][1])) + if ((type < 0) || (type >= IPFOBJ_COUNT)) { + IPFERROR(62); return EINVAL; + } error = BCOPYIN(data, &obj, sizeof(obj)); - if (error != 0) + if (error != 0) { + IPFERROR(127); return EFAULT; + } - if (obj.ipfo_type != type) + if (obj.ipfo_type != type) { + IPFERROR(63); return EINVAL; + } -#ifndef IPFILTER_COMPAT - if (obj.ipfo_size != sz) - return EINVAL; + if (obj.ipfo_rev >= ipf_objbytes[type][2]) { + if (((ipf_objbytes[type][0] & 1) == 0) || + (sz < ipf_objbytes[type][1])) { + IPFERROR(146); + return EINVAL; + } + error = COPYOUT(ptr, obj.ipfo_ptr, sz); + if (error != 0) { + IPFERROR(66); + error = EFAULT; + } + } else { +#ifdef IPFILTER_COMPAT + error = ipf_out_compat(softc, &obj, ptr); #else - if (obj.ipfo_rev != IPFILTER_VERSION) - /* XXX compatibility hook here */ - ; - if (obj.ipfo_size != sz) - /* XXX compatibility hook here */ - return EINVAL; + IPFERROR(65); + error = EINVAL; #endif - - error = COPYIN(obj.ipfo_ptr, ptr, sz); - if (error != 0) - error = EFAULT; + } return error; } /* ------------------------------------------------------------------------ */ -/* Function: fr_outobjsz */ -/* Returns: int - 0 = success, else failure */ -/* Parameters: data(I) - pointer to ioctl data */ -/* ptr(I) - pointer to store real data in */ -/* type(I) - type of structure being moved */ -/* sz(I) - size of data to copy */ -/* */ -/* As per fr_outobj, except the size of the object to copy out is passed in */ -/* but it must not be smaller than the size defined for the type and the */ -/* type must allow for varied sized objects. The extra requirement here is */ -/* that sz must match the size of the object being passed in - this is not */ -/* not possible nor required in fr_outobj(). */ -/* ------------------------------------------------------------------------ */ -int fr_outobjsz(data, ptr, type, sz) -void *data; -void *ptr; -int type, sz; -{ - ipfobj_t obj; - int error; - - if ((type < 0) || (type >= IPFOBJ_COUNT) || - ((fr_objbytes[type][0] & 1) == 0) || - (sz < fr_objbytes[type][1])) - return EINVAL; - - error = BCOPYIN(data, &obj, sizeof(obj)); - if (error != 0) - return EFAULT; - - if (obj.ipfo_type != type) - return EINVAL; - -#ifndef IPFILTER_COMPAT - if (obj.ipfo_size != sz) - return EINVAL; -#else - if (obj.ipfo_rev != IPFILTER_VERSION) - /* XXX compatibility hook here */ - ; - if (obj.ipfo_size != sz) - /* XXX compatibility hook here */ - return EINVAL; -#endif - - error = COPYOUT(ptr, obj.ipfo_ptr, sz); - if (error != 0) - error = EFAULT; - return error; -} - - -/* ------------------------------------------------------------------------ */ -/* Function: fr_outobj */ +/* Function: ipf_outobj */ /* Returns: int - 0 = success, else failure */ /* Parameters: data(I) - pointer to ioctl data */ /* ptr(I) - pointer to store real data in */ @@ -5646,75 +6491,134 @@ int type, sz; /* future, we add things to check for version numbers, sizes, etc, to make */ /* it backward compatible at the ABI for user land. */ /* ------------------------------------------------------------------------ */ -int fr_outobj(data, ptr, type) -void *data; -void *ptr; -int type; +int +ipf_outobj(softc, data, ptr, type) + ipf_main_softc_t *softc; + void *data; + void *ptr; + int type; { ipfobj_t obj; int error; - if ((type < 0) || (type >= IPFOBJ_COUNT)) + if ((type < 0) || (type >= IPFOBJ_COUNT)) { + IPFERROR(67); return EINVAL; + } error = BCOPYIN(data, &obj, sizeof(obj)); - if (error != 0) + if (error != 0) { + IPFERROR(126); return EFAULT; + } - if (obj.ipfo_type != type) + if (obj.ipfo_type != type) { + IPFERROR(68); return EINVAL; + } -#ifndef IPFILTER_COMPAT - if ((fr_objbytes[type][0] & 1) != 0) { - if (obj.ipfo_size < fr_objbytes[type][1]) + if (obj.ipfo_rev >= ipf_objbytes[type][2]) { + if ((ipf_objbytes[type][0] & 1) != 0) { + if (obj.ipfo_size < ipf_objbytes[type][1]) { + IPFERROR(69); + return EINVAL; + } + } else if (obj.ipfo_size != ipf_objbytes[type][1]) { + IPFERROR(70); return EINVAL; - } else if (obj.ipfo_size != fr_objbytes[type][1]) - return EINVAL; + } + + error = COPYOUT(ptr, obj.ipfo_ptr, obj.ipfo_size); + if (error != 0) { + IPFERROR(73); + error = EFAULT; + } + } else { +#ifdef IPFILTER_COMPAT + error = ipf_out_compat(softc, &obj, ptr); #else - if (obj.ipfo_rev != IPFILTER_VERSION) - /* XXX compatibility hook here */ - ; - if ((fr_objbytes[type][0] & 1) != 0) { - if (obj.ipfo_size < fr_objbytes[type][1]) - /* XXX compatibility hook here */ - return EINVAL; - } else if (obj.ipfo_size != fr_objbytes[type][1]) - /* XXX compatibility hook here */ - return EINVAL; + IPFERROR(72); + error = EINVAL; #endif - - error = COPYOUT(ptr, obj.ipfo_ptr, obj.ipfo_size); - if (error != 0) - error = EFAULT; + } return error; } /* ------------------------------------------------------------------------ */ -/* Function: fr_checkl4sum */ +/* Function: ipf_outobjk */ +/* Returns: int - 0 = success, else failure */ +/* Parameters: obj(I) - pointer to data description structure */ +/* ptr(I) - pointer to kernel data to copy out */ +/* */ +/* In the above functions, the ipfobj_t structure is copied into the kernel,*/ +/* telling ipfilter how to copy out data. In this instance, the ipfobj_t is */ +/* already populated with information and now we just need to use it. */ +/* There is no need for this function to have a "type" parameter as there */ +/* is no point in validating information that comes from the kernel with */ +/* itself. */ +/* ------------------------------------------------------------------------ */ +int +ipf_outobjk(softc, obj, ptr) + ipf_main_softc_t *softc; + ipfobj_t *obj; + void *ptr; +{ + int type = obj->ipfo_type; + int error; + + if ((type < 0) || (type >= IPFOBJ_COUNT)) { + IPFERROR(147); + return EINVAL; + } + + if (obj->ipfo_rev >= ipf_objbytes[type][2]) { + if ((ipf_objbytes[type][0] & 1) != 0) { + if (obj->ipfo_size < ipf_objbytes[type][1]) { + IPFERROR(148); + return EINVAL; + } + + } else if (obj->ipfo_size != ipf_objbytes[type][1]) { + IPFERROR(149); + return EINVAL; + } + + error = COPYOUT(ptr, obj->ipfo_ptr, obj->ipfo_size); + if (error != 0) { + IPFERROR(150); + error = EFAULT; + } + } else { +#ifdef IPFILTER_COMPAT + error = ipf_out_compat(softc, obj, ptr); +#else + IPFERROR(151); + error = EINVAL; +#endif + } + return error; +} + + +/* ------------------------------------------------------------------------ */ +/* Function: ipf_checkl4sum */ /* Returns: int - 0 = good, -1 = bad, 1 = cannot check */ /* Parameters: fin(I) - pointer to packet information */ /* */ /* If possible, calculate the layer 4 checksum for the packet. If this is */ /* not possible, return without indicating a failure or success but in a */ -/* way that is ditinguishable. */ +/* way that is ditinguishable. This function should only be called by the */ +/* ipf_checkv6sum() for each platform. */ /* ------------------------------------------------------------------------ */ -int fr_checkl4sum(fin) -fr_info_t *fin; +INLINE int +ipf_checkl4sum(fin) + fr_info_t *fin; { u_short sum, hdrsum, *csump; udphdr_t *udp; int dosum; - if ((fin->fin_flx & FI_NOCKSUM) != 0) - return 0; - - if (fin->fin_cksum == 1) - return 0; - - if (fin->fin_cksum == -1) - return -1; - /* * If the TCP packet isn't a fragment, isn't too short and otherwise * isn't already considered "bad", then validate the checksum. If @@ -5728,48 +6632,44 @@ fr_info_t *fin; dosum = 0; sum = 0; -#if SOLARIS && defined(_KERNEL) && (SOLARIS2 >= 6) && defined(ICK_VALID) - if (dohwcksum && ((*fin->fin_mp)->b_ick_flag == ICK_VALID)) { - hdrsum = 0; - sum = 0; - } else { + switch (fin->fin_p) + { + case IPPROTO_TCP : + csump = &((tcphdr_t *)fin->fin_dp)->th_sum; + dosum = 1; + break; + + case IPPROTO_UDP : + udp = fin->fin_dp; + if (udp->uh_sum != 0) { + csump = &udp->uh_sum; + dosum = 1; + } + break; + +#ifdef USE_INET6 + case IPPROTO_ICMPV6 : + csump = &((struct icmp6_hdr *)fin->fin_dp)->icmp6_cksum; + dosum = 1; + break; #endif - switch (fin->fin_p) - { - case IPPROTO_TCP : - csump = &((tcphdr_t *)fin->fin_dp)->th_sum; - dosum = 1; - break; - case IPPROTO_UDP : - udp = fin->fin_dp; - if (udp->uh_sum != 0) { - csump = &udp->uh_sum; - dosum = 1; - } - break; + case IPPROTO_ICMP : + csump = &((struct icmp *)fin->fin_dp)->icmp_cksum; + dosum = 1; + break; - case IPPROTO_ICMP : - csump = &((struct icmp *)fin->fin_dp)->icmp_cksum; - dosum = 1; - break; - - default : - return 1; - /*NOTREACHED*/ - } - - if (csump != NULL) - hdrsum = *csump; - - if (dosum) { - sum = fr_cksum(fin->fin_m, fin->fin_ip, - fin->fin_p, fin->fin_dp, - fin->fin_dlen + fin->fin_hlen); - } -#if SOLARIS && defined(_KERNEL) && (SOLARIS2 >= 6) && defined(ICK_VALID) + default : + return 1; + /*NOTREACHED*/ + } + + if (csump != NULL) + hdrsum = *csump; + + if (dosum) { + sum = fr_cksum(fin, fin->fin_ip, fin->fin_p, fin->fin_dp); } -#endif #if !defined(_KERNEL) if (sum == hdrsum) { FR_DEBUG(("checkl4sum: %hx == %hx\n", sum, hdrsum)); @@ -5777,17 +6677,18 @@ fr_info_t *fin; FR_DEBUG(("checkl4sum: %hx != %hx\n", sum, hdrsum)); } #endif + DT2(l4sums, u_short, hdrsum, u_short, sum); if (hdrsum == sum) { - fin->fin_cksum = 1; + fin->fin_cksum = FI_CK_SUMOK; return 0; } - fin->fin_cksum = -1; + fin->fin_cksum = FI_CK_BAD; return -1; } /* ------------------------------------------------------------------------ */ -/* Function: fr_ifpfillv4addr */ +/* Function: ipf_ifpfillv4addr */ /* Returns: int - 0 = address update, -1 = address not updated */ /* Parameters: atype(I) - type of network address update to perform */ /* sin(I) - pointer to source of address information */ @@ -5802,10 +6703,11 @@ fr_info_t *fin; /* FRI_NETMASKED, if inpmask is non-NULL then the mask is set to an all 1s */ /* value. */ /* ------------------------------------------------------------------------ */ -int fr_ifpfillv4addr(atype, sin, mask, inp, inpmask) -int atype; -struct sockaddr_in *sin, *mask; -struct in_addr *inp, *inpmask; +int +ipf_ifpfillv4addr(atype, sin, mask, inp, inpmask) + int atype; + struct sockaddr_in *sin, *mask; + struct in_addr *inp, *inpmask; { if (inpmask != NULL && atype != FRI_NETMASKED) inpmask->s_addr = 0xffffffff; @@ -5826,7 +6728,7 @@ struct in_addr *inp, *inpmask; #ifdef USE_INET6 /* ------------------------------------------------------------------------ */ -/* Function: fr_ifpfillv6addr */ +/* Function: ipf_ifpfillv6addr */ /* Returns: int - 0 = address update, -1 = address not updated */ /* Parameters: atype(I) - type of network address update to perform */ /* sin(I) - pointer to source of address information */ @@ -5841,44 +6743,43 @@ struct in_addr *inp, *inpmask; /* FRI_NETMASKED, if inpmask is non-NULL then the mask is set to an all 1s */ /* value. */ /* ------------------------------------------------------------------------ */ -int fr_ifpfillv6addr(atype, sin, mask, inp, inpmask) -int atype; -struct sockaddr_in6 *sin, *mask; -struct in_addr *inp, *inpmask; +int +ipf_ifpfillv6addr(atype, sin, mask, inp, inpmask) + int atype; + struct sockaddr_in6 *sin, *mask; + i6addr_t *inp, *inpmask; { - i6addr_t *src, *dst, *and, *dmask; + i6addr_t *src, *and; src = (i6addr_t *)&sin->sin6_addr; and = (i6addr_t *)&mask->sin6_addr; - dst = (i6addr_t *)inp; - dmask = (i6addr_t *)inpmask; if (inpmask != NULL && atype != FRI_NETMASKED) { - dmask->i6[0] = 0xffffffff; - dmask->i6[1] = 0xffffffff; - dmask->i6[2] = 0xffffffff; - dmask->i6[3] = 0xffffffff; + inpmask->i6[0] = 0xffffffff; + inpmask->i6[1] = 0xffffffff; + inpmask->i6[2] = 0xffffffff; + inpmask->i6[3] = 0xffffffff; } if (atype == FRI_NETWORK || atype == FRI_NETMASKED) { if (atype == FRI_NETMASKED) { if (inpmask == NULL) return -1; - dmask->i6[0] = and->i6[0]; - dmask->i6[1] = and->i6[1]; - dmask->i6[2] = and->i6[2]; - dmask->i6[3] = and->i6[3]; + inpmask->i6[0] = and->i6[0]; + inpmask->i6[1] = and->i6[1]; + inpmask->i6[2] = and->i6[2]; + inpmask->i6[3] = and->i6[3]; } - dst->i6[0] = src->i6[0] & and->i6[0]; - dst->i6[1] = src->i6[1] & and->i6[1]; - dst->i6[2] = src->i6[2] & and->i6[2]; - dst->i6[3] = src->i6[3] & and->i6[3]; + inp->i6[0] = src->i6[0] & and->i6[0]; + inp->i6[1] = src->i6[1] & and->i6[1]; + inp->i6[2] = src->i6[2] & and->i6[2]; + inp->i6[3] = src->i6[3] & and->i6[3]; } else { - dst->i6[0] = src->i6[0]; - dst->i6[1] = src->i6[1]; - dst->i6[2] = src->i6[2]; - dst->i6[3] = src->i6[3]; + inp->i6[0] = src->i6[0]; + inp->i6[1] = src->i6[1]; + inp->i6[2] = src->i6[2]; + inp->i6[3] = src->i6[3]; } return 0; } @@ -5886,7 +6787,7 @@ struct in_addr *inp, *inpmask; /* ------------------------------------------------------------------------ */ -/* Function: fr_matchtag */ +/* Function: ipf_matchtag */ /* Returns: 0 == mismatch, 1 == match. */ /* Parameters: tag1(I) - pointer to first tag to compare */ /* tag2(I) - pointer to second tag to compare */ @@ -5898,8 +6799,9 @@ struct in_addr *inp, *inpmask; /* comparison. This function should only be called with both tag1 and tag2 */ /* as non-NULL pointers. */ /* ------------------------------------------------------------------------ */ -int fr_matchtag(tag1, tag2) -ipftag_t *tag1, *tag2; +int +ipf_matchtag(tag1, tag2) + ipftag_t *tag1, *tag2; { if (tag1 == tag2) return 1; @@ -5917,16 +6819,18 @@ ipftag_t *tag1, *tag2; /* ------------------------------------------------------------------------ */ -/* Function: fr_coalesce */ +/* Function: ipf_coalesce */ /* Returns: 1 == success, -1 == failure, 0 == no change */ /* Parameters: fin(I) - pointer to packet information */ /* */ /* Attempt to get all of the packet data into a single, contiguous buffer. */ /* If this call returns a failure then the buffers have also been freed. */ /* ------------------------------------------------------------------------ */ -int fr_coalesce(fin) -fr_info_t *fin; +int +ipf_coalesce(fin) + fr_info_t *fin; { + if ((fin->fin_flx & FI_COALESCE) != 0) return 1; @@ -5938,11 +6842,15 @@ fr_info_t *fin; return 0; #if defined(_KERNEL) - if (fr_pullup(fin->fin_m, fin, fin->fin_plen) == NULL) { - ATOMIC_INCL(fr_badcoalesces[fin->fin_out]); + if (ipf_pullup(fin->fin_m, fin, fin->fin_plen) == NULL) { + ipf_main_softc_t *softc = fin->fin_main_soft; + + DT1(frb_coalesce, fr_info_t *, fin); + LBUMP(ipf_stats[fin->fin_out].fr_badcoalesces); # ifdef MENTAT FREE_MB_T(*fin->fin_mp); # endif + fin->fin_reason = FRB_COALESCE; *fin->fin_mp = NULL; fin->fin_m = NULL; return -1; @@ -5967,114 +6875,10 @@ fr_info_t *fin; * The obvious implication is if neither of these are set then the value can be * changed at any time without harm. */ -ipftuneable_t ipf_tuneables[] = { - /* filtering */ - { { &fr_flags }, "fr_flags", 0, 0xffffffff, - sizeof(fr_flags), 0, NULL }, - { { &fr_active }, "fr_active", 0, 0, - sizeof(fr_active), IPFT_RDONLY, NULL }, - { { &fr_control_forwarding }, "fr_control_forwarding", 0, 1, - sizeof(fr_control_forwarding), 0, NULL }, - { { &fr_update_ipid }, "fr_update_ipid", 0, 1, - sizeof(fr_update_ipid), 0, NULL }, - { { &fr_chksrc }, "fr_chksrc", 0, 1, - sizeof(fr_chksrc), 0, NULL }, - { { &fr_minttl }, "fr_minttl", 0, 1, - sizeof(fr_minttl), 0, NULL }, - { { &fr_icmpminfragmtu }, "fr_icmpminfragmtu", 0, 1, - sizeof(fr_icmpminfragmtu), 0, NULL }, - { { &fr_pass }, "fr_pass", 0, 0xffffffff, - sizeof(fr_pass), 0, NULL }, - /* state */ - { { &fr_tcpidletimeout }, "fr_tcpidletimeout", 1, 0x7fffffff, - sizeof(fr_tcpidletimeout), IPFT_WRDISABLED, NULL }, - { { &fr_tcpclosewait }, "fr_tcpclosewait", 1, 0x7fffffff, - sizeof(fr_tcpclosewait), IPFT_WRDISABLED, NULL }, - { { &fr_tcplastack }, "fr_tcplastack", 1, 0x7fffffff, - sizeof(fr_tcplastack), IPFT_WRDISABLED, NULL }, - { { &fr_tcptimeout }, "fr_tcptimeout", 1, 0x7fffffff, - sizeof(fr_tcptimeout), IPFT_WRDISABLED, NULL }, - { { &fr_tcpclosed }, "fr_tcpclosed", 1, 0x7fffffff, - sizeof(fr_tcpclosed), IPFT_WRDISABLED, NULL }, - { { &fr_tcphalfclosed }, "fr_tcphalfclosed", 1, 0x7fffffff, - sizeof(fr_tcphalfclosed), IPFT_WRDISABLED, NULL }, - { { &fr_udptimeout }, "fr_udptimeout", 1, 0x7fffffff, - sizeof(fr_udptimeout), IPFT_WRDISABLED, NULL }, - { { &fr_udpacktimeout }, "fr_udpacktimeout", 1, 0x7fffffff, - sizeof(fr_udpacktimeout), IPFT_WRDISABLED, NULL }, - { { &fr_icmptimeout }, "fr_icmptimeout", 1, 0x7fffffff, - sizeof(fr_icmptimeout), IPFT_WRDISABLED, NULL }, - { { &fr_icmpacktimeout }, "fr_icmpacktimeout", 1, 0x7fffffff, - sizeof(fr_icmpacktimeout), IPFT_WRDISABLED, NULL }, - { { &fr_iptimeout }, "fr_iptimeout", 1, 0x7fffffff, - sizeof(fr_iptimeout), IPFT_WRDISABLED, NULL }, - { { &fr_statemax }, "fr_statemax", 1, 0x7fffffff, - sizeof(fr_statemax), 0, NULL }, - { { &fr_statesize }, "fr_statesize", 1, 0x7fffffff, - sizeof(fr_statesize), IPFT_WRDISABLED, NULL }, - { { &fr_state_lock }, "fr_state_lock", 0, 1, - sizeof(fr_state_lock), IPFT_RDONLY, NULL }, - { { &fr_state_maxbucket }, "fr_state_maxbucket", 1, 0x7fffffff, - sizeof(fr_state_maxbucket), IPFT_WRDISABLED, NULL }, - { { &fr_state_maxbucket_reset }, "fr_state_maxbucket_reset", 0, 1, - sizeof(fr_state_maxbucket_reset), IPFT_WRDISABLED, NULL }, - { { &ipstate_logging }, "ipstate_logging", 0, 1, - sizeof(ipstate_logging), 0, NULL }, - /* nat */ - { { &fr_nat_lock }, "fr_nat_lock", 0, 1, - sizeof(fr_nat_lock), IPFT_RDONLY, NULL }, - { { &ipf_nattable_sz }, "ipf_nattable_sz", 1, 0x7fffffff, - sizeof(ipf_nattable_sz), IPFT_WRDISABLED, NULL }, - { { &ipf_nattable_max }, "ipf_nattable_max", 1, 0x7fffffff, - sizeof(ipf_nattable_max), 0, NULL }, - { { &ipf_natrules_sz }, "ipf_natrules_sz", 1, 0x7fffffff, - sizeof(ipf_natrules_sz), IPFT_WRDISABLED, NULL }, - { { &ipf_rdrrules_sz }, "ipf_rdrrules_sz", 1, 0x7fffffff, - sizeof(ipf_rdrrules_sz), IPFT_WRDISABLED, NULL }, - { { &ipf_hostmap_sz }, "ipf_hostmap_sz", 1, 0x7fffffff, - sizeof(ipf_hostmap_sz), IPFT_WRDISABLED, NULL }, - { { &fr_nat_maxbucket }, "fr_nat_maxbucket", 1, 0x7fffffff, - sizeof(fr_nat_maxbucket), 0, NULL }, - { { &fr_nat_maxbucket_reset }, "fr_nat_maxbucket_reset", 0, 1, - sizeof(fr_nat_maxbucket_reset), IPFT_WRDISABLED, NULL }, - { { &nat_logging }, "nat_logging", 0, 1, - sizeof(nat_logging), 0, NULL }, - { { &fr_defnatage }, "fr_defnatage", 1, 0x7fffffff, - sizeof(fr_defnatage), IPFT_WRDISABLED, NULL }, - { { &fr_defnatipage }, "fr_defnatipage", 1, 0x7fffffff, - sizeof(fr_defnatipage), IPFT_WRDISABLED, NULL }, - { { &fr_defnaticmpage }, "fr_defnaticmpage", 1, 0x7fffffff, - sizeof(fr_defnaticmpage), IPFT_WRDISABLED, NULL }, - { { &fr_nat_doflush }, "fr_nat_doflush", 0, 1, - sizeof(fr_nat_doflush), 0, NULL }, - /* proxy */ - { { &ipf_proxy_debug }, "ipf_proxy_debug", 0, 10, - sizeof(ipf_proxy_debug), 0, 0 }, - /* frag */ - { { &ipfr_size }, "ipfr_size", 1, 0x7fffffff, - sizeof(ipfr_size), IPFT_WRDISABLED, NULL }, - { { &fr_ipfrttl }, "fr_ipfrttl", 1, 0x7fffffff, - sizeof(fr_ipfrttl), IPFT_WRDISABLED, NULL }, -#ifdef IPFILTER_LOG - /* log */ - { { &ipl_suppress }, "ipl_suppress", 0, 1, - sizeof(ipl_suppress), 0, NULL }, - { { &ipl_logmax }, "ipl_logmax", 0, 0x7fffffff, - sizeof(ipl_logmax), IPFT_WRDISABLED, NULL }, - { { &ipl_logall }, "ipl_logall", 0, 1, - sizeof(ipl_logall), 0, NULL }, - { { &ipl_logsize }, "ipl_logsize", 0, 0x80000, - sizeof(ipl_logsize), 0, NULL }, -#endif - { { NULL }, NULL, 0, 0, - 0, 0, NULL } -}; - -static ipftuneable_t *ipf_tunelist = NULL; /* ------------------------------------------------------------------------ */ -/* Function: fr_findtunebycookie */ +/* Function: ipf_tune_findbycookie */ /* Returns: NULL = search failed, else pointer to tune struct */ /* Parameters: cookie(I) - cookie value to search for amongst tuneables */ /* next(O) - pointer to place to store the cookie for the */ @@ -6085,12 +6889,14 @@ static ipftuneable_t *ipf_tunelist = NULL; /* a matching value for "cookie" - ie its address. When returning a match, */ /* the next one to be found may be returned inside next. */ /* ------------------------------------------------------------------------ */ -static ipftuneable_t *fr_findtunebycookie(cookie, next) -void *cookie, **next; +static ipftuneable_t * +ipf_tune_findbycookie(ptop, cookie, next) + ipftuneable_t **ptop; + void *cookie, **next; { ipftuneable_t *ta, **tap; - for (ta = ipf_tuneables; ta->ipft_name != NULL; ta++) + for (ta = *ptop; ta->ipft_name != NULL; ta++) if (ta == cookie) { if (next != NULL) { /* @@ -6104,12 +6910,12 @@ void *cookie, **next; if ((ta + 1)->ipft_name != NULL) *next = ta + 1; else - *next = &ipf_tunelist; + *next = ptop; } return ta; } - for (tap = &ipf_tunelist; (ta = *tap) != NULL; tap = &ta->ipft_next) + for (tap = ptop; (ta = *tap) != NULL; tap = &ta->ipft_next) if (tap == cookie) { if (next != NULL) *next = &ta->ipft_next; @@ -6123,7 +6929,7 @@ void *cookie, **next; /* ------------------------------------------------------------------------ */ -/* Function: fr_findtunebyname */ +/* Function: ipf_tune_findbyname */ /* Returns: NULL = search failed, else pointer to tune struct */ /* Parameters: name(I) - name of the tuneable entry to find. */ /* */ @@ -6131,17 +6937,14 @@ void *cookie, **next; /* for an entry with a matching name. If we can find one, return a pointer */ /* to the matching structure. */ /* ------------------------------------------------------------------------ */ -static ipftuneable_t *fr_findtunebyname(name) -const char *name; +static ipftuneable_t * +ipf_tune_findbyname(top, name) + ipftuneable_t *top; + const char *name; { ipftuneable_t *ta; - for (ta = ipf_tuneables; ta->ipft_name != NULL; ta++) - if (!strcmp(ta->ipft_name, name)) { - return ta; - } - - for (ta = ipf_tunelist; ta != NULL; ta = ta->ipft_next) + for (ta = top; ta != NULL; ta = ta->ipft_next) if (!strcmp(ta->ipft_name, name)) { return ta; } @@ -6151,24 +6954,175 @@ const char *name; /* ------------------------------------------------------------------------ */ -/* Function: fr_addipftune */ +/* Function: ipf_tune_add_array */ /* Returns: int - 0 == success, else failure */ -/* Parameters: newtune - pointer to new tune struct to add to tuneables */ +/* Parameters: newtune - pointer to new tune array to add to tuneables */ /* */ -/* Appends the tune structure pointer to by "newtune" to the end of the */ -/* current list of "dynamic" tuneable parameters. Once added, the owner */ -/* of the object is not expected to ever change "ipft_next". */ +/* Appends tune structures from the array passed in (newtune) to the end of */ +/* the current list of "dynamic" tuneable parameters. */ +/* If any entry to be added is already present (by name) then the operation */ +/* is aborted - entries that have been added are removed before returning. */ +/* An entry with no name (NULL) is used as the indication that the end of */ +/* the array has been reached. */ /* ------------------------------------------------------------------------ */ -int fr_addipftune(newtune) -ipftuneable_t *newtune; +int +ipf_tune_add_array(softc, newtune) + ipf_main_softc_t *softc; + ipftuneable_t *newtune; +{ + ipftuneable_t *nt, *dt; + int error = 0; + + for (nt = newtune; nt->ipft_name != NULL; nt++) { + error = ipf_tune_add(softc, nt); + if (error != 0) { + for (dt = newtune; dt != nt; dt++) { + (void) ipf_tune_del(softc, dt); + } + } + } + + return error; +} + + +/* ------------------------------------------------------------------------ */ +/* Function: ipf_tune_array_link */ +/* Returns: 0 == success, -1 == failure */ +/* Parameters: softc(I) - soft context pointerto work with */ +/* array(I) - pointer to an array of tuneables */ +/* */ +/* Given an array of tunables (array), append them to the current list of */ +/* tuneables for this context (softc->ipf_tuners.) To properly prepare the */ +/* the array for being appended to the list, initialise all of the next */ +/* pointers so we don't need to walk parts of it with ++ and others with */ +/* next. The array is expected to have an entry with a NULL name as the */ +/* terminator. Trying to add an array with no non-NULL names will return as */ +/* a failure. */ +/* ------------------------------------------------------------------------ */ +int +ipf_tune_array_link(softc, array) + ipf_main_softc_t *softc; + ipftuneable_t *array; +{ + ipftuneable_t *t, **p; + + t = array; + if (t->ipft_name == NULL) + return -1; + + for (; t[1].ipft_name != NULL; t++) + t[0].ipft_next = &t[1]; + t->ipft_next = NULL; + + /* + * Since a pointer to the last entry isn't kept, we need to find it + * each time we want to add new variables to the list. + */ + for (p = &softc->ipf_tuners; (t = *p) != NULL; p = &t->ipft_next) + if (t->ipft_name == NULL) + break; + *p = array; + + return 0; +} + + +/* ------------------------------------------------------------------------ */ +/* Function: ipf_tune_array_unlink */ +/* Returns: 0 == success, -1 == failure */ +/* Parameters: softc(I) - soft context pointerto work with */ +/* array(I) - pointer to an array of tuneables */ +/* */ +/* ------------------------------------------------------------------------ */ +int +ipf_tune_array_unlink(softc, array) + ipf_main_softc_t *softc; + ipftuneable_t *array; +{ + ipftuneable_t *t, **p; + + for (p = &softc->ipf_tuners; (t = *p) != NULL; p = &t->ipft_next) + if (t == array) + break; + if (t == NULL) + return -1; + + for (; t[1].ipft_name != NULL; t++) + ; + + *p = t->ipft_next; + + return 0; +} + + +/* ------------------------------------------------------------------------ */ +/* Function: ipf_tune_array_copy */ +/* Returns: NULL = failure, else pointer to new array */ +/* Parameters: base(I) - pointer to structure base */ +/* size(I) - size of the array at template */ +/* template(I) - original array to copy */ +/* */ +/* Allocate memory for a new set of tuneable values and copy everything */ +/* from template into the new region of memory. The new region is full of */ +/* uninitialised pointers (ipft_next) so set them up. Now, ipftp_offset... */ +/* */ +/* NOTE: the following assumes that sizeof(long) == sizeof(void *) */ +/* In the array template, ipftp_offset is the offset (in bytes) of the */ +/* location of the tuneable value inside the structure pointed to by base. */ +/* As ipftp_offset is a union over the pointers to the tuneable values, if */ +/* we add base to the copy's ipftp_offset, copy ends up with a pointer in */ +/* ipftp_void that points to the stored value. */ +/* ------------------------------------------------------------------------ */ +ipftuneable_t * +ipf_tune_array_copy(base, size, template) + void *base; + size_t size; + ipftuneable_t *template; +{ + ipftuneable_t *copy; + int i; + + + KMALLOCS(copy, ipftuneable_t *, size); + if (copy == NULL) { + return NULL; + } + bcopy(template, copy, size); + + for (i = 0; copy[i].ipft_name; i++) { + copy[i].ipft_una.ipftp_offset += (u_long)base; + copy[i].ipft_next = copy + i + 1; + } + + return copy; +} + + +/* ------------------------------------------------------------------------ */ +/* Function: ipf_tune_add */ +/* Returns: int - 0 == success, else failure */ +/* Parameters: newtune - pointer to new tune entry to add to tuneables */ +/* */ +/* Appends tune structures from the array passed in (newtune) to the end of */ +/* the current list of "dynamic" tuneable parameters. Once added, the */ +/* owner of the object is not expected to ever change "ipft_next". */ +/* ------------------------------------------------------------------------ */ +int +ipf_tune_add(softc, newtune) + ipf_main_softc_t *softc; + ipftuneable_t *newtune; { ipftuneable_t *ta, **tap; - ta = fr_findtunebyname(newtune->ipft_name); - if (ta != NULL) + ta = ipf_tune_findbyname(softc->ipf_tuners, newtune->ipft_name); + if (ta != NULL) { + IPFERROR(74); return EEXIST; + } - for (tap = &ipf_tunelist; *tap != NULL; tap = &(*tap)->ipft_next) + for (tap = &softc->ipf_tuners; *tap != NULL; tap = &(*tap)->ipft_next) ; newtune->ipft_next = NULL; @@ -6178,33 +7132,72 @@ ipftuneable_t *newtune; /* ------------------------------------------------------------------------ */ -/* Function: fr_delipftune */ +/* Function: ipf_tune_del */ /* Returns: int - 0 == success, else failure */ -/* Parameters: oldtune - pointer to tune struct to remove from the list of */ +/* Parameters: oldtune - pointer to tune entry to remove from the list of */ /* current dynamic tuneables */ /* */ /* Search for the tune structure, by pointer, in the list of those that are */ /* dynamically added at run time. If found, adjust the list so that this */ /* structure is no longer part of it. */ /* ------------------------------------------------------------------------ */ -int fr_delipftune(oldtune) -ipftuneable_t *oldtune; +int +ipf_tune_del(softc, oldtune) + ipf_main_softc_t *softc; + ipftuneable_t *oldtune; { ipftuneable_t *ta, **tap; + int error = 0; - for (tap = &ipf_tunelist; (ta = *tap) != NULL; tap = &ta->ipft_next) + for (tap = &softc->ipf_tuners; (ta = *tap) != NULL; + tap = &ta->ipft_next) { if (ta == oldtune) { *tap = oldtune->ipft_next; oldtune->ipft_next = NULL; - return 0; + break; } + } - return ESRCH; + if (ta == NULL) { + error = ESRCH; + IPFERROR(75); + } + return error; } /* ------------------------------------------------------------------------ */ -/* Function: fr_ipftune */ +/* Function: ipf_tune_del_array */ +/* Returns: int - 0 == success, else failure */ +/* Parameters: oldtune - pointer to tuneables array */ +/* */ +/* Remove each tuneable entry in the array from the list of "dynamic" */ +/* tunables. If one entry should fail to be found, an error will be */ +/* returned and no further ones removed. */ +/* An entry with a NULL name is used as the indicator of the last entry in */ +/* the array. */ +/* ------------------------------------------------------------------------ */ +int +ipf_tune_del_array(softc, oldtune) + ipf_main_softc_t *softc; + ipftuneable_t *oldtune; +{ + ipftuneable_t *ot; + int error = 0; + + for (ot = oldtune; ot->ipft_name != NULL; ot++) { + error = ipf_tune_del(softc, ot); + if (error != 0) + break; + } + + return error; + +} + + +/* ------------------------------------------------------------------------ */ +/* Function: ipf_tune */ /* Returns: int - 0 == success, else failure */ /* Parameters: cmd(I) - ioctl command number */ /* data(I) - pointer to ioctl data structure */ @@ -6216,16 +7209,18 @@ ipftuneable_t *oldtune; /* and 'destruction' routines of the various components of ipfilter are all */ /* each responsible for handling their own values being too big. */ /* ------------------------------------------------------------------------ */ -int fr_ipftune(cmd, data) -ioctlcmd_t cmd; -void *data; +int +ipf_ipftune(softc, cmd, data) + ipf_main_softc_t *softc; + ioctlcmd_t cmd; + void *data; { ipftuneable_t *ta; ipftune_t tu; void *cookie; int error; - error = fr_inobj(data, &tu, IPFOBJ_TUNEABLE); + error = ipf_inobj(softc, data, NULL, &tu, IPFOBJ_TUNEABLE); if (error != 0) return error; @@ -6246,9 +7241,10 @@ void *data; * at the front of the list. */ if (cookie != NULL) { - ta = fr_findtunebycookie(cookie, &tu.ipft_cookie); + ta = ipf_tune_findbycookie(&softc->ipf_tuners, + cookie, &tu.ipft_cookie); } else { - ta = ipf_tuneables; + ta = softc->ipf_tuners; tu.ipft_cookie = ta + 1; } if (ta != NULL) { @@ -6256,8 +7252,10 @@ void *data; * Entry found, but does the data pointed to by that * row fit in what we can return? */ - if (ta->ipft_sz > sizeof(tu.ipft_un)) + if (ta->ipft_sz > sizeof(tu.ipft_un)) { + IPFERROR(76); return EINVAL; + } tu.ipft_vlong = 0; if (ta->ipft_sz == sizeof(u_long)) @@ -6277,7 +7275,7 @@ void *data; MIN(sizeof(tu.ipft_name), strlen(ta->ipft_name) + 1)); } - error = fr_outobj(data, &tu, IPFOBJ_TUNEABLE); + error = ipf_outobj(softc, data, &tu, IPFOBJ_TUNEABLE); break; case SIOCIPFGET : @@ -6286,13 +7284,16 @@ void *data; * Search by name or by cookie value for a particular entry * in the tuning paramter table. */ + IPFERROR(77); error = ESRCH; if (cookie != NULL) { - ta = fr_findtunebycookie(cookie, NULL); + ta = ipf_tune_findbycookie(&softc->ipf_tuners, + cookie, NULL); if (ta != NULL) error = 0; } else if (tu.ipft_name[0] != '\0') { - ta = fr_findtunebyname(tu.ipft_name); + ta = ipf_tune_findbyname(softc->ipf_tuners, + tu.ipft_name); if (ta != NULL) error = 0; } @@ -6317,7 +7318,7 @@ void *data; tu.ipft_min = ta->ipft_min; tu.ipft_max = ta->ipft_max; tu.ipft_flags = ta->ipft_flags; - error = fr_outobj(data, &tu, IPFOBJ_TUNEABLE); + error = ipf_outobj(softc, data, &tu, IPFOBJ_TUNEABLE); } else if (cmd == (ioctlcmd_t)SIOCIPFSET) { /* @@ -6328,35 +7329,49 @@ void *data; u_long in; if (((ta->ipft_flags & IPFT_WRDISABLED) != 0) && - (fr_running > 0)) { + (softc->ipf_running > 0)) { + IPFERROR(78); error = EBUSY; break; } in = tu.ipft_vlong; if (in < ta->ipft_min || in > ta->ipft_max) { + IPFERROR(79); error = EINVAL; break; } - if (ta->ipft_sz == sizeof(u_long)) { + if (ta->ipft_func != NULL) { + SPL_INT(s); + + SPL_NET(s); + error = (*ta->ipft_func)(softc, ta, + &tu.ipft_un); + SPL_X(s); + + } else if (ta->ipft_sz == sizeof(u_long)) { tu.ipft_vlong = *ta->ipft_plong; *ta->ipft_plong = in; + } else if (ta->ipft_sz == sizeof(u_int)) { tu.ipft_vint = *ta->ipft_pint; *ta->ipft_pint = (u_int)(in & 0xffffffff); + } else if (ta->ipft_sz == sizeof(u_short)) { tu.ipft_vshort = *ta->ipft_pshort; *ta->ipft_pshort = (u_short)(in & 0xffff); + } else if (ta->ipft_sz == sizeof(u_char)) { tu.ipft_vchar = *ta->ipft_pchar; *ta->ipft_pchar = (u_char)(in & 0xff); } - error = fr_outobj(data, &tu, IPFOBJ_TUNEABLE); + error = ipf_outobj(softc, data, &tu, IPFOBJ_TUNEABLE); } break; default : + IPFERROR(80); error = EINVAL; break; } @@ -6366,109 +7381,7 @@ void *data; /* ------------------------------------------------------------------------ */ -/* Function: fr_initialise */ -/* Returns: int - 0 == success, < 0 == failure */ -/* Parameters: None. */ -/* */ -/* Call of the initialise functions for all the various subsystems inside */ -/* of IPFilter. If any of them should fail, return immeadiately a failure */ -/* BUT do not try to recover from the error here. */ -/* ------------------------------------------------------------------------ */ -int fr_initialise() -{ - int i; - - bzero(&frstats, sizeof(frstats)); - -#ifdef IPFILTER_LOG - i = fr_loginit(); - if (i < 0) - return -10 + i; -#endif - i = fr_natinit(); - if (i < 0) - return -20 + i; - - i = fr_stateinit(); - if (i < 0) - return -30 + i; - - i = fr_authinit(); - if (i < 0) - return -40 + i; - - i = fr_fraginit(); - if (i < 0) - return -50 + i; - - i = appr_init(); - if (i < 0) - return -60 + i; - -#ifdef IPFILTER_SYNC - i = ipfsync_init(); - if (i < 0) - return -70 + i; -#endif -#ifdef IPFILTER_SCAN - i = ipsc_init(); - if (i < 0) - return -80 + i; -#endif -#ifdef IPFILTER_LOOKUP - i = ip_lookup_init(); - if (i < 0) - return -90 + i; -#endif -#ifdef IPFILTER_COMPILED - ipfrule_add(); -#endif - return 0; -} - - -/* ------------------------------------------------------------------------ */ -/* Function: fr_deinitialise */ -/* Returns: None. */ -/* Parameters: None. */ -/* */ -/* Call all the various subsystem cleanup routines to deallocate memory or */ -/* destroy locks or whatever they've done that they need to now undo. */ -/* The order here IS important as there are some cross references of */ -/* internal data structures. */ -/* ------------------------------------------------------------------------ */ -void fr_deinitialise() -{ - fr_fragunload(); - fr_authunload(); - fr_natunload(); - fr_stateunload(); -#ifdef IPFILTER_SCAN - fr_scanunload(); -#endif - appr_unload(); - -#ifdef IPFILTER_COMPILED - ipfrule_remove(); -#endif - - (void) frflush(IPL_LOGIPF, 0, FR_INQUE|FR_OUTQUE|FR_INACTIVE); - (void) frflush(IPL_LOGIPF, 0, FR_INQUE|FR_OUTQUE); - (void) frflush(IPL_LOGCOUNT, 0, FR_INQUE|FR_OUTQUE|FR_INACTIVE); - (void) frflush(IPL_LOGCOUNT, 0, FR_INQUE|FR_OUTQUE); - -#ifdef IPFILTER_LOOKUP - ip_lookup_unload(); -#endif - -#ifdef IPFILTER_LOG - fr_logunload(); -#endif -} - - -/* ------------------------------------------------------------------------ */ -/* Function: fr_zerostats */ +/* Function: ipf_zerostats */ /* Returns: int - 0 = success, else failure */ /* Parameters: data(O) - pointer to pointer for copying data back to */ /* */ @@ -6476,30 +7389,38 @@ void fr_deinitialise() /* current ones in the kernel. The lock is only held across the bzero() as */ /* the copyout may result in paging (ie network activity.) */ /* ------------------------------------------------------------------------ */ -int fr_zerostats(data) -void *data; +int +ipf_zerostats(softc, data) + ipf_main_softc_t *softc; + caddr_t data; { friostat_t fio; + ipfobj_t obj; int error; - fr_getstat(&fio); - error = fr_outobj(data, &fio, IPFOBJ_IPFSTAT); - if (error) - return EFAULT; + error = ipf_inobj(softc, data, &obj, &fio, IPFOBJ_IPFSTAT); + if (error != 0) + return error; + ipf_getstat(softc, &fio, obj.ipfo_rev); + error = ipf_outobj(softc, data, &fio, IPFOBJ_IPFSTAT); + if (error != 0) + return error; - WRITE_ENTER(&ipf_mutex); - bzero(&frstats, sizeof(frstats)); - RWLOCK_EXIT(&ipf_mutex); + WRITE_ENTER(&softc->ipf_mutex); + bzero(&softc->ipf_stats, sizeof(softc->ipf_stats)); + RWLOCK_EXIT(&softc->ipf_mutex); return 0; } /* ------------------------------------------------------------------------ */ -/* Function: fr_resolvedest */ +/* Function: ipf_resolvedest */ /* Returns: Nil */ -/* Parameters: fdp(IO) - pointer to destination information to resolve */ -/* v(I) - IP protocol version to match */ +/* Parameters: softc(I) - pointer to soft context main structure */ +/* base(I) - where strings are stored */ +/* fdp(IO) - pointer to destination information to resolve */ +/* v(I) - IP protocol version to match */ /* */ /* Looks up an interface name in the frdest structure pointed to by fdp and */ /* if a matching name can be found for the particular IP protocol version */ @@ -6507,52 +7428,66 @@ void *data; /* found, then set the interface pointer to be -1 as NULL is considered to */ /* indicate there is no information at all in the structure. */ /* ------------------------------------------------------------------------ */ -void fr_resolvedest(fdp, v) -frdest_t *fdp; -int v; +int +ipf_resolvedest(softc, base, fdp, v) + ipf_main_softc_t *softc; + char *base; + frdest_t *fdp; + int v; { + int errval = 0; void *ifp; ifp = NULL; - v = v; /* LINT */ - if (*fdp->fd_ifname != '\0') { - ifp = GETIFP(fdp->fd_ifname, v); - if (ifp == NULL) - ifp = (void *)-1; + if (fdp->fd_name != -1) { + if (fdp->fd_type == FRD_DSTLIST) { + ifp = ipf_lookup_res_name(softc, IPL_LOGIPF, + IPLT_DSTLIST, + base + fdp->fd_name, + NULL); + if (ifp == NULL) { + IPFERROR(144); + errval = ESRCH; + } + } else { + ifp = GETIFP(base + fdp->fd_name, v); + if (ifp == NULL) + ifp = (void *)-1; + } } - fdp->fd_ifp = ifp; + fdp->fd_ptr = ifp; + + if ((ifp != NULL) && (ifp != (void *)-1)) { + fdp->fd_local = ipf_deliverlocal(softc, v, ifp, &fdp->fd_ip6); + } + + return errval; } /* ------------------------------------------------------------------------ */ -/* Function: fr_resolvenic */ +/* Function: ipf_resolvenic */ /* Returns: void* - NULL = wildcard name, -1 = failed to find NIC, else */ /* pointer to interface structure for NIC */ -/* Parameters: name(I) - complete interface name */ +/* Parameters: softc(I)- pointer to soft context main structure */ +/* name(I) - complete interface name */ /* v(I) - IP protocol version */ /* */ /* Look for a network interface structure that firstly has a matching name */ /* to that passed in and that is also being used for that IP protocol */ /* version (necessary on some platforms where there are separate listings */ /* for both IPv4 and IPv6 on the same physical NIC. */ -/* */ -/* One might wonder why name gets terminated with a \0 byte in here. The */ -/* reason is an interface name could get into the kernel structures of ipf */ -/* in any number of ways and so long as they all use the same sized array */ -/* to put the name in, it makes sense to ensure it gets null terminated */ -/* before it is used for its intended purpose - finding its match in the */ -/* kernel's list of configured interfaces. */ -/* */ -/* NOTE: This SHOULD ONLY be used with IPFilter structures that have an */ -/* array for the name that is LIFNAMSIZ bytes (at least) in length. */ /* ------------------------------------------------------------------------ */ -void *fr_resolvenic(name, v) -char *name; -int v; +void * +ipf_resolvenic(softc, name, v) + ipf_main_softc_t *softc; + char *name; + int v; { void *nic; + softc = softc; /* gcc -Wextra */ if (name[0] == '\0') return NULL; @@ -6560,8 +7495,6 @@ int v; return NULL; } - name[LIFNAMSIZ - 1] = '\0'; - nic = GETIFP(name, v); if (nic == NULL) nic = (void *)-1; @@ -6569,68 +7502,121 @@ int v; } -ipftoken_t *ipftokenhead = NULL, **ipftokentail = &ipftokenhead; - - /* ------------------------------------------------------------------------ */ -/* Function: ipf_expiretokens */ +/* Function: ipf_token_expire */ /* Returns: None. */ -/* Parameters: None. */ +/* Parameters: softc(I) - pointer to soft context main structure */ /* */ /* This function is run every ipf tick to see if there are any tokens that */ /* have been held for too long and need to be freed up. */ /* ------------------------------------------------------------------------ */ -void ipf_expiretokens() +void +ipf_token_expire(softc) + ipf_main_softc_t *softc; { ipftoken_t *it; - WRITE_ENTER(&ipf_tokens); - while ((it = ipftokenhead) != NULL) { - if (it->ipt_die > fr_ticks) + WRITE_ENTER(&softc->ipf_tokens); + while ((it = softc->ipf_token_head) != NULL) { + if (it->ipt_die > softc->ipf_ticks) break; - ipf_freetoken(it); + ipf_token_deref(softc, it); } - RWLOCK_EXIT(&ipf_tokens); + RWLOCK_EXIT(&softc->ipf_tokens); } /* ------------------------------------------------------------------------ */ -/* Function: ipf_deltoken */ +/* Function: ipf_token_flush */ +/* Returns: None. */ +/* Parameters: softc(I) - pointer to soft context main structure */ +/* */ +/* Loop through all of the existing tokens and call deref to see if they */ +/* can be freed. Normally a function like this might just loop on */ +/* ipf_token_head but there is a chance that a token might have a ref count */ +/* of greater than one and in that case the the reference would drop twice */ +/* by code that is only entitled to drop it once. */ +/* ------------------------------------------------------------------------ */ +static void +ipf_token_flush(softc) + ipf_main_softc_t *softc; +{ + ipftoken_t *it, *next; + + WRITE_ENTER(&softc->ipf_tokens); + for (it = softc->ipf_token_head; it != NULL; it = next) { + next = it->ipt_next; + (void) ipf_token_deref(softc, it); + } + RWLOCK_EXIT(&softc->ipf_tokens); +} + + +/* ------------------------------------------------------------------------ */ +/* Function: ipf_token_del */ /* Returns: int - 0 = success, else error */ -/* Parameters: type(I) - the token type to match */ +/* Parameters: softc(I)- pointer to soft context main structure */ +/* type(I) - the token type to match */ /* uid(I) - uid owning the token */ /* ptr(I) - context pointer for the token */ /* */ /* This function looks for a a token in the current list that matches up */ /* the fields (type, uid, ptr). If none is found, ESRCH is returned, else */ -/* call ipf_freetoken() to remove it from the list. */ +/* call ipf_token_dewref() to remove it from the list. In the event that */ +/* the token has a reference held elsewhere, setting ipt_complete to 2 */ +/* enables debugging to distinguish between the two paths that ultimately */ +/* lead to a token to be deleted. */ /* ------------------------------------------------------------------------ */ -int ipf_deltoken(type, uid, ptr) -int type, uid; -void *ptr; +int +ipf_token_del(softc, type, uid, ptr) + ipf_main_softc_t *softc; + int type, uid; + void *ptr; { ipftoken_t *it; - int error = ESRCH; + int error; - WRITE_ENTER(&ipf_tokens); - for (it = ipftokenhead; it != NULL; it = it->ipt_next) + IPFERROR(82); + error = ESRCH; + + WRITE_ENTER(&softc->ipf_tokens); + for (it = softc->ipf_token_head; it != NULL; it = it->ipt_next) { if (ptr == it->ipt_ctx && type == it->ipt_type && uid == it->ipt_uid) { - ipf_freetoken(it); + it->ipt_complete = 2; + ipf_token_deref(softc, it); error = 0; break; + } } - RWLOCK_EXIT(&ipf_tokens); + RWLOCK_EXIT(&softc->ipf_tokens); return error; } /* ------------------------------------------------------------------------ */ -/* Function: ipf_findtoken */ +/* Function: ipf_token_mark_complete */ +/* Returns: None. */ +/* Parameters: token(I) - pointer to token structure */ +/* */ +/* Mark a token as being ineligable for being found with ipf_token_find. */ +/* ------------------------------------------------------------------------ */ +void +ipf_token_mark_complete(token) + ipftoken_t *token; +{ + if (token->ipt_complete == 0) + token->ipt_complete = 1; +} + + +/* ------------------------------------------------------------------------ */ +/* Function: ipf_token_find */ /* Returns: ipftoken_t * - NULL if no memory, else pointer to token */ -/* Parameters: type(I) - the token type to match */ +/* Parameters: softc(I)- pointer to soft context main structure */ +/* type(I) - the token type to match */ /* uid(I) - uid owning the token */ /* ptr(I) - context pointer for the token */ /* */ @@ -6638,97 +7624,115 @@ void *ptr; /* matches the tuple (type, uid, ptr). If one cannot be found then one is */ /* allocated. If one is found then it is moved to the top of the list of */ /* currently active tokens. */ -/* */ -/* NOTE: It is by design that this function returns holding a read lock on */ -/* ipf_tokens. Callers must make sure they release it! */ /* ------------------------------------------------------------------------ */ -ipftoken_t *ipf_findtoken(type, uid, ptr) -int type, uid; -void *ptr; +ipftoken_t * +ipf_token_find(softc, type, uid, ptr) + ipf_main_softc_t *softc; + int type, uid; + void *ptr; { ipftoken_t *it, *new; KMALLOC(new, ipftoken_t *); + if (new != NULL) + bzero((char *)new, sizeof(*new)); - WRITE_ENTER(&ipf_tokens); - for (it = ipftokenhead; it != NULL; it = it->ipt_next) { - if (it->ipt_alive == 0) - continue; - if (ptr == it->ipt_ctx && type == it->ipt_type && - uid == it->ipt_uid) + WRITE_ENTER(&softc->ipf_tokens); + for (it = softc->ipf_token_head; it != NULL; it = it->ipt_next) { + if ((ptr == it->ipt_ctx) && (type == it->ipt_type) && + (uid == it->ipt_uid) && (it->ipt_complete < 2)) break; } if (it == NULL) { it = new; new = NULL; - if (it == NULL) + if (it == NULL) { + RWLOCK_EXIT(&softc->ipf_tokens); return NULL; - it->ipt_data = NULL; + } it->ipt_ctx = ptr; it->ipt_uid = uid; it->ipt_type = type; - it->ipt_next = NULL; - it->ipt_alive = 1; + it->ipt_ref = 1; } else { if (new != NULL) { KFREE(new); new = NULL; } - ipf_unlinktoken(it); + if (it->ipt_complete > 0) + it = NULL; + else + ipf_token_unlink(softc, it); } - it->ipt_pnext = ipftokentail; - *ipftokentail = it; - ipftokentail = &it->ipt_next; - it->ipt_next = NULL; - it->ipt_die = fr_ticks + 2; + if (it != NULL) { + it->ipt_pnext = softc->ipf_token_tail; + *softc->ipf_token_tail = it; + softc->ipf_token_tail = &it->ipt_next; + it->ipt_next = NULL; + it->ipt_ref++; - MUTEX_DOWNGRADE(&ipf_tokens); + it->ipt_die = softc->ipf_ticks + 20; + } + + RWLOCK_EXIT(&softc->ipf_tokens); return it; } /* ------------------------------------------------------------------------ */ -/* Function: ipf_unlinktoken */ +/* Function: ipf_token_unlink */ /* Returns: None. */ -/* Parameters: token(I) - pointer to token structure */ +/* Parameters: softc(I) - pointer to soft context main structure */ +/* token(I) - pointer to token structure */ +/* Write Locks: ipf_tokens */ /* */ /* This function unlinks a token structure from the linked list of tokens */ /* that "own" it. The head pointer never needs to be explicitly adjusted */ /* but the tail does due to the linked list implementation. */ /* ------------------------------------------------------------------------ */ -static void ipf_unlinktoken(token) -ipftoken_t *token; +static void +ipf_token_unlink(softc, token) + ipf_main_softc_t *softc; + ipftoken_t *token; { - if (ipftokentail == &token->ipt_next) - ipftokentail = token->ipt_pnext; + if (softc->ipf_token_tail == &token->ipt_next) + softc->ipf_token_tail = token->ipt_pnext; *token->ipt_pnext = token->ipt_next; if (token->ipt_next != NULL) token->ipt_next->ipt_pnext = token->ipt_pnext; + token->ipt_next = NULL; + token->ipt_pnext = NULL; } /* ------------------------------------------------------------------------ */ -/* Function: ipf_freetoken */ -/* Returns: None. */ -/* Parameters: token(I) - pointer to token structure */ +/* Function: ipf_token_deref */ +/* Returns: int - 0 == token freed, else reference count */ +/* Parameters: softc(I) - pointer to soft context main structure */ +/* token(I) - pointer to token structure */ +/* Write Locks: ipf_tokens */ /* */ -/* This function unlinks a token from the linked list and on the path to */ -/* free'ing the data, it calls the dereference function that is associated */ -/* with the type of data pointed to by the token as it is considered to */ -/* hold a reference to it. */ +/* Drop the reference count on the token structure and if it drops to zero, */ +/* call the dereference function for the token type because it is then */ +/* possible to free the token data structure. */ /* ------------------------------------------------------------------------ */ -void ipf_freetoken(token) -ipftoken_t *token; +int +ipf_token_deref(softc, token) + ipf_main_softc_t *softc; + ipftoken_t *token; { void *data, **datap; - ipf_unlinktoken(token); + ASSERT(token->ipt_ref > 0); + token->ipt_ref--; + if (token->ipt_ref > 0) + return token->ipt_ref; data = token->ipt_data; datap = &data; @@ -6737,54 +7741,96 @@ ipftoken_t *token; switch (token->ipt_type) { case IPFGENITER_IPF : - (void) fr_derefrule((frentry_t **)datap); + (void) ipf_derefrule(softc, (frentry_t **)datap); break; case IPFGENITER_IPNAT : - WRITE_ENTER(&ipf_nat); - fr_ipnatderef((ipnat_t **)datap); - RWLOCK_EXIT(&ipf_nat); + WRITE_ENTER(&softc->ipf_nat); + ipf_nat_rule_deref(softc, (ipnat_t **)datap); + RWLOCK_EXIT(&softc->ipf_nat); break; case IPFGENITER_NAT : - fr_natderef((nat_t **)datap); + ipf_nat_deref(softc, (nat_t **)datap); break; case IPFGENITER_STATE : - fr_statederef((ipstate_t **)datap); + ipf_state_deref(softc, (ipstate_t **)datap); break; case IPFGENITER_FRAG : -#ifdef USE_MUTEXES - fr_fragderef((ipfr_t **)datap, &ipf_frag); -#else - fr_fragderef((ipfr_t **)datap); -#endif + ipf_frag_pkt_deref(softc, (ipfr_t **)datap); break; case IPFGENITER_NATFRAG : -#ifdef USE_MUTEXES - fr_fragderef((ipfr_t **)datap, &ipf_natfrag); -#else - fr_fragderef((ipfr_t **)datap); -#endif + ipf_frag_nat_deref(softc, (ipfr_t **)datap); break; case IPFGENITER_HOSTMAP : - WRITE_ENTER(&ipf_nat); - fr_hostmapdel((hostmap_t **)datap); - RWLOCK_EXIT(&ipf_nat); + WRITE_ENTER(&softc->ipf_nat); + ipf_nat_hostmapdel(softc, (hostmap_t **)datap); + RWLOCK_EXIT(&softc->ipf_nat); break; default : -#ifdef IPFILTER_LOOKUP - ip_lookup_iterderef(token->ipt_type, data); -#endif + ipf_lookup_iterderef(softc, token->ipt_type, data); break; } } + ipf_token_unlink(softc, token); KFREE(token); + return 0; } +/* ------------------------------------------------------------------------ */ +/* Function: ipf_nextrule */ +/* Returns: frentry_t * - NULL == no more rules, else pointer to next */ +/* Parameters: softc(I) - pointer to soft context main structure */ +/* fr(I) - pointer to filter rule */ +/* out(I) - 1 == out rules, 0 == input rules */ +/* */ +/* Starting with "fr", find the next rule to visit. This includes visiting */ +/* the list of rule groups if either fr is NULL (empty list) or it is the */ +/* last rule in the list. When walking rule lists, it is either input or */ +/* output rules that are returned, never both. */ +/* ------------------------------------------------------------------------ */ +static frentry_t * +ipf_nextrule(softc, active, unit, fr, out) + ipf_main_softc_t *softc; + int active, unit; + frentry_t *fr; + int out; +{ + frentry_t *next; + frgroup_t *fg; + + if (fr != NULL && fr->fr_group != -1) { + fg = ipf_findgroup(softc, fr->fr_names + fr->fr_group, + unit, active, NULL); + if (fg != NULL) + fg = fg->fg_next; + } else { + fg = softc->ipf_groups[unit][active]; + } + + while (fg != NULL) { + next = fg->fg_start; + while (next != NULL) { + if (out) { + if (next->fr_flags & FR_OUTQUE) + return next; + } else if (next->fr_flags & FR_INQUE) { + return next; + } + next = next->fr_next; + } + if (next == NULL) + fg = fg->fg_next; + } + + return NULL; +} + /* ------------------------------------------------------------------------ */ /* Function: ipf_getnextrule */ /* Returns: int - 0 = success, else error */ -/* Parameters: t(I) - pointer to destination information to resolve */ +/* Parameters: softc(I)- pointer to soft context main structure */ +/* t(I) - pointer to destination information to resolve */ /* ptr(I) - pointer to ipfobj_t to copyin from user space */ /* */ /* This function's first job is to bring in the ipfruleiter_t structure via */ @@ -6795,47 +7841,72 @@ ipftoken_t *token; /* When we have found the rule to return, increase its reference count and */ /* if we used an existing rule to get here, decrease its reference count. */ /* ------------------------------------------------------------------------ */ -int ipf_getnextrule(ipftoken_t *t, void *ptr) +int +ipf_getnextrule(softc, t, ptr) + ipf_main_softc_t *softc; + ipftoken_t *t; + void *ptr; { frentry_t *fr, *next, zero; - int error, count, out; ipfruleiter_t it; + int error, out; frgroup_t *fg; + ipfobj_t obj; + int predict; char *dst; + int unit; - if (t == NULL || ptr == NULL) + if (t == NULL || ptr == NULL) { + IPFERROR(84); return EFAULT; - error = fr_inobj(ptr, &it, IPFOBJ_IPFITER); + } + + error = ipf_inobj(softc, ptr, &obj, &it, IPFOBJ_IPFITER); if (error != 0) return error; - if ((it.iri_inout < 0) || (it.iri_inout > 3)) - return EINVAL; - if ((it.iri_active != 0) && (it.iri_active != 1)) - return EINVAL; - if (it.iri_nrules == 0) - return ENOSPC; - if (it.iri_rule == NULL) - return EFAULT; - out = it.iri_inout & F_OUT; + if ((it.iri_inout < 0) || (it.iri_inout > 3)) { + IPFERROR(85); + return EINVAL; + } + if ((it.iri_active != 0) && (it.iri_active != 1)) { + IPFERROR(86); + return EINVAL; + } + if (it.iri_nrules == 0) { + IPFERROR(87); + return ENOSPC; + } + if (it.iri_rule == NULL) { + IPFERROR(88); + return EFAULT; + } + + fg = NULL; fr = t->ipt_data; - READ_ENTER(&ipf_mutex); + if ((it.iri_inout & F_OUT) != 0) + out = 1; + else + out = 0; + if ((it.iri_inout & F_ACIN) != 0) + unit = IPL_LOGCOUNT; + else + unit = IPL_LOGIPF; + + READ_ENTER(&softc->ipf_mutex); if (fr == NULL) { if (*it.iri_group == '\0') { - if ((it.iri_inout & F_ACIN) != 0) { - if (it.iri_v == 4) - next = ipacct[out][it.iri_active]; - else - next = ipacct6[out][it.iri_active]; + if (unit == IPL_LOGCOUNT) { + next = softc->ipf_acct[out][it.iri_active]; } else { - if (it.iri_v == 4) - next = ipfilter[out][it.iri_active]; - else - next = ipfilter6[out][it.iri_active]; + next = softc->ipf_rules[out][it.iri_active]; } + if (next == NULL) + next = ipf_nextrule(softc, it.iri_active, + unit, NULL, out); } else { - fg = fr_findgroup(it.iri_group, IPL_LOGIPF, - it.iri_active, NULL); + fg = ipf_findgroup(softc, it.iri_group, unit, + it.iri_active, NULL); if (fg != NULL) next = fg->fg_start; else @@ -6843,113 +7914,133 @@ int ipf_getnextrule(ipftoken_t *t, void *ptr) } } else { next = fr->fr_next; + if (next == NULL) + next = ipf_nextrule(softc, it.iri_active, unit, + fr, out); } + if (next != NULL && next->fr_next != NULL) + predict = 1; + else if (ipf_nextrule(softc, it.iri_active, unit, next, out) != NULL) + predict = 1; + else + predict = 0; + + if (fr != NULL) + (void) ipf_derefrule(softc, &fr); + + obj.ipfo_type = IPFOBJ_FRENTRY; dst = (char *)it.iri_rule; - count = it.iri_nrules; - /* - * The ipfruleiter may ask for more than 1 rule at a time to be - * copied out, so long as that many exist in the list to start with! - */ - for (;;) { - if (next != NULL) { - if (count == 1) { - MUTEX_ENTER(&next->fr_lock); - next->fr_ref++; - MUTEX_EXIT(&next->fr_lock); - t->ipt_data = next; - } - } else { - bzero(&zero, sizeof(zero)); - next = &zero; - count = 1; - t->ipt_data = NULL; - } - RWLOCK_EXIT(&ipf_mutex); - error = COPYOUT(next, dst, sizeof(*next)); - if (error != 0) - return EFAULT; + if (next != NULL) { + obj.ipfo_size = next->fr_size; + MUTEX_ENTER(&next->fr_lock); + next->fr_ref++; + MUTEX_EXIT(&next->fr_lock); + t->ipt_data = next; + } else { + obj.ipfo_size = sizeof(frentry_t); + bzero(&zero, sizeof(zero)); + next = &zero; + t->ipt_data = NULL; + } + it.iri_rule = predict ? next : NULL; + if (predict == 0) + ipf_token_mark_complete(t); + RWLOCK_EXIT(&softc->ipf_mutex); + + obj.ipfo_ptr = dst; + error = ipf_outobjk(softc, &obj, next); + if (error == 0 && t->ipt_data != NULL) { + dst += obj.ipfo_size; if (next->fr_data != NULL) { - dst += sizeof(*next); - error = COPYOUT(next->fr_data, dst, next->fr_dsize); - if (error != 0) - error = EFAULT; + ipfobj_t dobj; + + if (next->fr_type == FR_T_IPFEXPR) + dobj.ipfo_type = IPFOBJ_IPFEXPR; else - dst += next->fr_dsize; + dobj.ipfo_type = IPFOBJ_FRIPF; + dobj.ipfo_size = next->fr_dsize; + dobj.ipfo_rev = obj.ipfo_rev; + dobj.ipfo_ptr = dst; + error = ipf_outobjk(softc, &dobj, next->fr_data); } - - if ((count == 1) || (error != 0)) - break; - - count--; - - READ_ENTER(&ipf_mutex); - next = next->fr_next; } - if (fr != NULL) { - (void) fr_derefrule(&fr); - } + if ((fr != NULL) && (next == &zero)) + (void) ipf_derefrule(softc, &fr); return error; } /* ------------------------------------------------------------------------ */ -/* Function: fr_frruleiter */ +/* Function: ipf_frruleiter */ /* Returns: int - 0 = success, else error */ -/* Parameters: data(I) - the token type to match */ +/* Parameters: softc(I)- pointer to soft context main structure */ +/* data(I) - the token type to match */ /* uid(I) - uid owning the token */ /* ptr(I) - context pointer for the token */ /* */ -/* This function serves as a stepping stone between fr_ipf_ioctl and */ +/* This function serves as a stepping stone between ipf_ipf_ioctl and */ /* ipf_getnextrule. It's role is to find the right token in the kernel for */ /* the process doing the ioctl and use that to ask for the next rule. */ /* ------------------------------------------------------------------------ */ -static int ipf_frruleiter(data, uid, ctx) -void *data, *ctx; -int uid; +static int +ipf_frruleiter(softc, data, uid, ctx) + ipf_main_softc_t *softc; + void *data, *ctx; + int uid; { ipftoken_t *token; + ipfruleiter_t it; + ipfobj_t obj; int error; - token = ipf_findtoken(IPFGENITER_IPF, uid, ctx); - if (token != NULL) - error = ipf_getnextrule(token, data); - else - error = EFAULT; - RWLOCK_EXIT(&ipf_tokens); + token = ipf_token_find(softc, IPFGENITER_IPF, uid, ctx); + if (token != NULL) { + error = ipf_getnextrule(softc, token, data); + WRITE_ENTER(&softc->ipf_tokens); + ipf_token_deref(softc, token); + RWLOCK_EXIT(&softc->ipf_tokens); + } else { + error = ipf_inobj(softc, data, &obj, &it, IPFOBJ_IPFITER); + if (error != 0) + return error; + it.iri_rule = NULL; + error = ipf_outobj(softc, data, &it, IPFOBJ_IPFITER); + } return error; } /* ------------------------------------------------------------------------ */ -/* Function: fr_geniter */ +/* Function: ipf_geniter */ /* Returns: int - 0 = success, else error */ -/* Parameters: token(I) - pointer to ipftoken_t structure */ -/* itp(I) - */ +/* Parameters: softc(I) - pointer to soft context main structure */ +/* token(I) - pointer to ipftoken_t structure */ +/* itp(I) - pointer to iterator data */ /* */ +/* Decide which iterator function to call using information passed through */ +/* the ipfgeniter_t structure at itp. */ /* ------------------------------------------------------------------------ */ -static int ipf_geniter(token, itp) -ipftoken_t *token; -ipfgeniter_t *itp; +static int +ipf_geniter(softc, token, itp) + ipf_main_softc_t *softc; + ipftoken_t *token; + ipfgeniter_t *itp; { int error; switch (itp->igi_type) { case IPFGENITER_FRAG : -#ifdef USE_MUTEXES - error = fr_nextfrag(token, itp, - &ipfr_list, &ipfr_tail, &ipf_frag); -#else - error = fr_nextfrag(token, itp, &ipfr_list, &ipfr_tail); -#endif + error = ipf_frag_pkt_next(softc, token, itp); break; default : + IPFERROR(92); error = EINVAL; break; } @@ -6959,41 +8050,50 @@ ipfgeniter_t *itp; /* ------------------------------------------------------------------------ */ -/* Function: fr_genericiter */ +/* Function: ipf_genericiter */ /* Returns: int - 0 = success, else error */ -/* Parameters: data(I) - the token type to match */ +/* Parameters: softc(I)- pointer to soft context main structure */ +/* data(I) - the token type to match */ /* uid(I) - uid owning the token */ /* ptr(I) - context pointer for the token */ /* */ +/* Handle the SIOCGENITER ioctl for the ipfilter device. The primary role */ /* ------------------------------------------------------------------------ */ -int ipf_genericiter(data, uid, ctx) -void *data, *ctx; -int uid; +int +ipf_genericiter(softc, data, uid, ctx) + ipf_main_softc_t *softc; + void *data, *ctx; + int uid; { ipftoken_t *token; ipfgeniter_t iter; int error; - error = fr_inobj(data, &iter, IPFOBJ_GENITER); + error = ipf_inobj(softc, data, NULL, &iter, IPFOBJ_GENITER); if (error != 0) return error; - token = ipf_findtoken(iter.igi_type, uid, ctx); + token = ipf_token_find(softc, iter.igi_type, uid, ctx); if (token != NULL) { token->ipt_subtype = iter.igi_type; - error = ipf_geniter(token, &iter); - } else - error = EFAULT; - RWLOCK_EXIT(&ipf_tokens); + error = ipf_geniter(softc, token, &iter); + WRITE_ENTER(&softc->ipf_tokens); + ipf_token_deref(softc, token); + RWLOCK_EXIT(&softc->ipf_tokens); + } else { + IPFERROR(93); + error = 0; + } return error; } /* ------------------------------------------------------------------------ */ -/* Function: fr_ipf_ioctl */ +/* Function: ipf_ipf_ioctl */ /* Returns: int - 0 = success, else error */ -/* Parameters: data(I) - the token type to match */ +/* Parameters: softc(I)- pointer to soft context main structure */ +/* data(I) - the token type to match */ /* cmd(I) - the ioctl command number */ /* mode(I) - mode flags for the ioctl */ /* uid(I) - uid owning the token */ @@ -7002,231 +8102,283 @@ int uid; /* This function handles all of the ioctl command that are actually isssued */ /* to the /dev/ipl device. */ /* ------------------------------------------------------------------------ */ -int fr_ipf_ioctl(data, cmd, mode, uid, ctx) -caddr_t data; -ioctlcmd_t cmd; -int mode, uid; -void *ctx; +int +ipf_ipf_ioctl(softc, data, cmd, mode, uid, ctx) + ipf_main_softc_t *softc; + caddr_t data; + ioctlcmd_t cmd; + int mode, uid; + void *ctx; { friostat_t fio; int error, tmp; + ipfobj_t obj; SPL_INT(s); switch (cmd) { case SIOCFRENB : - if (!(mode & FWRITE)) + if (!(mode & FWRITE)) { + IPFERROR(94); error = EPERM; - else { + } else { error = BCOPYIN(data, &tmp, sizeof(tmp)); if (error != 0) { + IPFERROR(95); error = EFAULT; break; } - WRITE_ENTER(&ipf_global); + WRITE_ENTER(&softc->ipf_global); if (tmp) { - if (fr_running > 0) + if (softc->ipf_running > 0) error = 0; else - error = ipfattach(); + error = ipfattach(softc); if (error == 0) - fr_running = 1; + softc->ipf_running = 1; else - (void) ipfdetach(); + (void) ipfdetach(softc); } else { - error = ipfdetach(); + if (softc->ipf_running == 1) + error = ipfdetach(softc); + else + error = 0; if (error == 0) - fr_running = -1; + softc->ipf_running = -1; } - RWLOCK_EXIT(&ipf_global); + RWLOCK_EXIT(&softc->ipf_global); } break; case SIOCIPFSET : if (!(mode & FWRITE)) { + IPFERROR(96); error = EPERM; break; } /* FALLTHRU */ case SIOCIPFGETNEXT : case SIOCIPFGET : - error = fr_ipftune(cmd, (void *)data); + error = ipf_ipftune(softc, cmd, (void *)data); break; case SIOCSETFF : - if (!(mode & FWRITE)) + if (!(mode & FWRITE)) { + IPFERROR(97); error = EPERM; - else { - error = BCOPYIN(data, &fr_flags, sizeof(fr_flags)); - if (error != 0) + } else { + error = BCOPYIN(data, &softc->ipf_flags, + sizeof(softc->ipf_flags)); + if (error != 0) { + IPFERROR(98); error = EFAULT; + } } break; case SIOCGETFF : - error = BCOPYOUT(&fr_flags, data, sizeof(fr_flags)); - if (error != 0) + error = BCOPYOUT(&softc->ipf_flags, data, + sizeof(softc->ipf_flags)); + if (error != 0) { + IPFERROR(99); error = EFAULT; + } break; case SIOCFUNCL : - error = fr_resolvefunc((void *)data); + error = ipf_resolvefunc(softc, (void *)data); break; case SIOCINAFR : case SIOCRMAFR : case SIOCADAFR : case SIOCZRLST : - if (!(mode & FWRITE)) + if (!(mode & FWRITE)) { + IPFERROR(100); error = EPERM; - else - error = frrequest(IPL_LOGIPF, cmd, data, fr_active, 1); + } else { + error = frrequest(softc, IPL_LOGIPF, cmd, (caddr_t)data, + softc->ipf_active, 1); + } break; case SIOCINIFR : case SIOCRMIFR : case SIOCADIFR : - if (!(mode & FWRITE)) + if (!(mode & FWRITE)) { + IPFERROR(101); error = EPERM; - else - error = frrequest(IPL_LOGIPF, cmd, data, - 1 - fr_active, 1); + } else { + error = frrequest(softc, IPL_LOGIPF, cmd, (caddr_t)data, + 1 - softc->ipf_active, 1); + } break; case SIOCSWAPA : - if (!(mode & FWRITE)) + if (!(mode & FWRITE)) { + IPFERROR(102); error = EPERM; - else { - WRITE_ENTER(&ipf_mutex); - bzero((char *)frcache, sizeof(frcache[0]) * 2); - error = BCOPYOUT(&fr_active, data, sizeof(fr_active)); - if (error != 0) + } else { + WRITE_ENTER(&softc->ipf_mutex); + error = BCOPYOUT(&softc->ipf_active, data, + sizeof(softc->ipf_active)); + if (error != 0) { + IPFERROR(103); error = EFAULT; - else - fr_active = 1 - fr_active; - RWLOCK_EXIT(&ipf_mutex); + } else { + softc->ipf_active = 1 - softc->ipf_active; + } + RWLOCK_EXIT(&softc->ipf_mutex); } break; case SIOCGETFS : - fr_getstat(&fio); - error = fr_outobj((void *)data, &fio, IPFOBJ_IPFSTAT); + error = ipf_inobj(softc, (void *)data, &obj, &fio, + IPFOBJ_IPFSTAT); + if (error != 0) + break; + ipf_getstat(softc, &fio, obj.ipfo_rev); + error = ipf_outobj(softc, (void *)data, &fio, IPFOBJ_IPFSTAT); break; case SIOCFRZST : - if (!(mode & FWRITE)) + if (!(mode & FWRITE)) { + IPFERROR(104); error = EPERM; - else - error = fr_zerostats(data); + } else + error = ipf_zerostats(softc, (caddr_t)data); break; case SIOCIPFFL : - if (!(mode & FWRITE)) + if (!(mode & FWRITE)) { + IPFERROR(105); error = EPERM; - else { + } else { error = BCOPYIN(data, &tmp, sizeof(tmp)); if (!error) { - tmp = frflush(IPL_LOGIPF, 4, tmp); + tmp = ipf_flush(softc, IPL_LOGIPF, tmp); error = BCOPYOUT(&tmp, data, sizeof(tmp)); - if (error != 0) + if (error != 0) { + IPFERROR(106); error = EFAULT; - } else + } + } else { + IPFERROR(107); error = EFAULT; + } } break; #ifdef USE_INET6 case SIOCIPFL6 : - if (!(mode & FWRITE)) + if (!(mode & FWRITE)) { + IPFERROR(108); error = EPERM; - else { + } else { error = BCOPYIN(data, &tmp, sizeof(tmp)); if (!error) { - tmp = frflush(IPL_LOGIPF, 6, tmp); + tmp = ipf_flush(softc, IPL_LOGIPF, tmp); error = BCOPYOUT(&tmp, data, sizeof(tmp)); - if (error != 0) + if (error != 0) { + IPFERROR(109); error = EFAULT; - } else + } + } else { + IPFERROR(110); error = EFAULT; + } } break; #endif case SIOCSTLCK : - error = BCOPYIN(data, &tmp, sizeof(tmp)); - if (error == 0) { - fr_state_lock = tmp; - fr_nat_lock = tmp; - fr_frag_lock = tmp; - fr_auth_lock = tmp; - } else - error = EFAULT; + if (!(mode & FWRITE)) { + IPFERROR(122); + error = EPERM; + } else { + error = BCOPYIN(data, &tmp, sizeof(tmp)); + if (error == 0) { + ipf_state_setlock(softc->ipf_state_soft, tmp); + ipf_nat_setlock(softc->ipf_nat_soft, tmp); + ipf_frag_setlock(softc->ipf_frag_soft, tmp); + ipf_auth_setlock(softc->ipf_auth_soft, tmp); + } else { + IPFERROR(111); + error = EFAULT; + } + } break; #ifdef IPFILTER_LOG case SIOCIPFFB : - if (!(mode & FWRITE)) + if (!(mode & FWRITE)) { + IPFERROR(112); error = EPERM; - else { - tmp = ipflog_clear(IPL_LOGIPF); + } else { + tmp = ipf_log_clear(softc, IPL_LOGIPF); error = BCOPYOUT(&tmp, data, sizeof(tmp)); - if (error) + if (error) { + IPFERROR(113); error = EFAULT; + } } break; #endif /* IPFILTER_LOG */ case SIOCFRSYN : - if (!(mode & FWRITE)) + if (!(mode & FWRITE)) { + IPFERROR(114); error = EPERM; - else { - WRITE_ENTER(&ipf_global); -#ifdef MENTAT + } else { + WRITE_ENTER(&softc->ipf_global); +#if (defined(MENTAT) && defined(_KERNEL)) && !defined(INSTANCES) error = ipfsync(); #else - frsync(NULL); + ipf_sync(softc, NULL); error = 0; #endif - RWLOCK_EXIT(&ipf_global); + RWLOCK_EXIT(&softc->ipf_global); } break; case SIOCGFRST : - error = fr_outobj((void *)data, fr_fragstats(), - IPFOBJ_FRAGSTAT); + error = ipf_outobj(softc, (void *)data, + ipf_frag_stats(softc->ipf_frag_soft), + IPFOBJ_FRAGSTAT); break; #ifdef IPFILTER_LOG case FIONREAD : - tmp = (int)iplused[IPL_LOGIPF]; - + tmp = ipf_log_bytesused(softc, IPL_LOGIPF); error = BCOPYOUT(&tmp, data, sizeof(tmp)); break; #endif case SIOCIPFITER : SPL_SCHED(s); - error = ipf_frruleiter(data, uid, ctx); + error = ipf_frruleiter(softc, data, uid, ctx); SPL_X(s); break; case SIOCGENITER : SPL_SCHED(s); - error = ipf_genericiter(data, uid, ctx); + error = ipf_genericiter(softc, data, uid, ctx); SPL_X(s); break; case SIOCIPFDELTOK : - SPL_SCHED(s); error = BCOPYIN(data, &tmp, sizeof(tmp)); - if (error == 0) - error = ipf_deltoken(tmp, uid, ctx); - SPL_X(s); + if (error == 0) { + SPL_SCHED(s); + error = ipf_token_del(softc, tmp, uid, ctx); + SPL_X(s); + } break; default : + IPFERROR(115); error = EINVAL; break; } @@ -7235,91 +8387,611 @@ void *ctx; } +/* ------------------------------------------------------------------------ */ +/* Function: ipf_decaps */ +/* Returns: int - -1 == decapsulation failed, else bit mask of */ +/* flags indicating packet filtering decision. */ +/* Parameters: fin(I) - pointer to packet information */ +/* pass(I) - IP protocol version to match */ +/* l5proto(I) - layer 5 protocol to decode UDP data as. */ +/* */ +/* This function is called for packets that are wrapt up in other packets, */ +/* for example, an IP packet that is the entire data segment for another IP */ +/* packet. If the basic constraints for this are satisfied, change the */ +/* buffer to point to the start of the inner packet and start processing */ +/* rules belonging to the head group this rule specifies. */ +/* ------------------------------------------------------------------------ */ +u_32_t +ipf_decaps(fin, pass, l5proto) + fr_info_t *fin; + u_32_t pass; + int l5proto; +{ + fr_info_t fin2, *fino = NULL; + int elen, hlen, nh; + grehdr_t gre; + ip_t *ip; + mb_t *m; + + if ((fin->fin_flx & FI_COALESCE) == 0) + if (ipf_coalesce(fin) == -1) + goto cantdecaps; + + m = fin->fin_m; + hlen = fin->fin_hlen; + + switch (fin->fin_p) + { + case IPPROTO_UDP : + /* + * In this case, the specific protocol being decapsulated + * inside UDP frames comes from the rule. + */ + nh = fin->fin_fr->fr_icode; + break; + + case IPPROTO_GRE : /* 47 */ + bcopy(fin->fin_dp, (char *)&gre, sizeof(gre)); + hlen += sizeof(grehdr_t); + if (gre.gr_R|gre.gr_s) + goto cantdecaps; + if (gre.gr_C) + hlen += 4; + if (gre.gr_K) + hlen += 4; + if (gre.gr_S) + hlen += 4; + + nh = IPPROTO_IP; + + /* + * If the routing options flag is set, validate that it is + * there and bounce over it. + */ +#if 0 + /* This is really heavy weight and lots of room for error, */ + /* so for now, put it off and get the simple stuff right. */ + if (gre.gr_R) { + u_char off, len, *s; + u_short af; + int end; + + end = 0; + s = fin->fin_dp; + s += hlen; + aplen = fin->fin_plen - hlen; + while (aplen > 3) { + af = (s[0] << 8) | s[1]; + off = s[2]; + len = s[3]; + aplen -= 4; + s += 4; + if (af == 0 && len == 0) { + end = 1; + break; + } + if (aplen < len) + break; + s += len; + aplen -= len; + } + if (end != 1) + goto cantdecaps; + hlen = s - (u_char *)fin->fin_dp; + } +#endif + break; + +#ifdef IPPROTO_IPIP + case IPPROTO_IPIP : /* 4 */ +#endif + nh = IPPROTO_IP; + break; + + default : /* Includes ESP, AH is special for IPv4 */ + goto cantdecaps; + } + + switch (nh) + { + case IPPROTO_IP : + case IPPROTO_IPV6 : + break; + default : + goto cantdecaps; + } + + bcopy((char *)fin, (char *)&fin2, sizeof(fin2)); + fino = fin; + fin = &fin2; + elen = hlen; +#if defined(MENTAT) && defined(_KERNEL) + m->b_rptr += elen; +#else + m->m_data += elen; + m->m_len -= elen; +#endif + fin->fin_plen -= elen; + + ip = (ip_t *)((char *)fin->fin_ip + elen); + + /* + * Make sure we have at least enough data for the network layer + * header. + */ + if (IP_V(ip) == 4) + hlen = IP_HL(ip) << 2; +#ifdef USE_INET6 + else if (IP_V(ip) == 6) + hlen = sizeof(ip6_t); +#endif + else + goto cantdecaps2; + + if (fin->fin_plen < hlen) + goto cantdecaps2; + + fin->fin_dp = (char *)ip + hlen; + + if (IP_V(ip) == 4) { + /* + * Perform IPv4 header checksum validation. + */ + if (ipf_cksum((u_short *)ip, hlen)) + goto cantdecaps2; + } + + if (ipf_makefrip(hlen, ip, fin) == -1) { +cantdecaps2: + if (m != NULL) { +#if defined(MENTAT) && defined(_KERNEL) + m->b_rptr -= elen; +#else + m->m_data -= elen; + m->m_len += elen; +#endif + } +cantdecaps: + DT1(frb_decapfrip, fr_info_t *, fin); + pass &= ~FR_CMDMASK; + pass |= FR_BLOCK|FR_QUICK; + fin->fin_reason = FRB_DECAPFRIP; + return -1; + } + + pass = ipf_scanlist(fin, pass); + + /* + * Copy the packet filter "result" fields out of the fr_info_t struct + * that is local to the decapsulation processing and back into the + * one we were called with. + */ + fino->fin_flx = fin->fin_flx; + fino->fin_rev = fin->fin_rev; + fino->fin_icode = fin->fin_icode; + fino->fin_rule = fin->fin_rule; + (void) strncpy(fino->fin_group, fin->fin_group, FR_GROUPLEN); + fino->fin_fr = fin->fin_fr; + fino->fin_error = fin->fin_error; + fino->fin_mp = fin->fin_mp; + fino->fin_m = fin->fin_m; + m = fin->fin_m; + if (m != NULL) { +#if defined(MENTAT) && defined(_KERNEL) + m->b_rptr -= elen; +#else + m->m_data -= elen; + m->m_len += elen; +#endif + } + return pass; +} + + +/* ------------------------------------------------------------------------ */ +/* Function: ipf_matcharray_load */ +/* Returns: int - 0 = success, else error */ +/* Parameters: softc(I) - pointer to soft context main structure */ +/* data(I) - pointer to ioctl data */ +/* objp(I) - ipfobj_t structure to load data into */ +/* arrayptr(I) - pointer to location to store array pointer */ +/* */ +/* This function loads in a mathing array through the ipfobj_t struct that */ +/* describes it. Sanity checking and array size limitations are enforced */ +/* in this function to prevent userspace from trying to load in something */ +/* that is insanely big. Once the size of the array is known, the memory */ +/* required is malloc'd and returned through changing *arrayptr. The */ +/* contents of the array are verified before returning. Only in the event */ +/* of a successful call is the caller required to free up the malloc area. */ +/* ------------------------------------------------------------------------ */ +int +ipf_matcharray_load(softc, data, objp, arrayptr) + ipf_main_softc_t *softc; + caddr_t data; + ipfobj_t *objp; + int **arrayptr; +{ + int arraysize, *array, error; + + *arrayptr = NULL; + + error = BCOPYIN(data, objp, sizeof(*objp)); + if (error != 0) { + IPFERROR(116); + return EFAULT; + } + + if (objp->ipfo_type != IPFOBJ_IPFEXPR) { + IPFERROR(117); + return EINVAL; + } + + if (((objp->ipfo_size & 3) != 0) || (objp->ipfo_size == 0) || + (objp->ipfo_size > 1024)) { + IPFERROR(118); + return EINVAL; + } + + arraysize = objp->ipfo_size * sizeof(*array); + KMALLOCS(array, int *, arraysize); + if (array == NULL) { + IPFERROR(119); + return ENOMEM; + } + + error = COPYIN(objp->ipfo_ptr, array, arraysize); + if (error != 0) { + KFREES(array, arraysize); + IPFERROR(120); + return EFAULT; + } + + if (ipf_matcharray_verify(array, arraysize) != 0) { + KFREES(array, arraysize); + IPFERROR(121); + return EINVAL; + } + + *arrayptr = array; + return 0; +} + + +/* ------------------------------------------------------------------------ */ +/* Function: ipf_matcharray_verify */ +/* Returns: Nil */ +/* Parameters: array(I) - pointer to matching array */ +/* arraysize(I) - number of elements in the array */ +/* */ +/* Verify the contents of a matching array by stepping through each element */ +/* in it. The actual commands in the array are not verified for */ +/* correctness, only that all of the sizes are correctly within limits. */ +/* ------------------------------------------------------------------------ */ +int +ipf_matcharray_verify(array, arraysize) + int *array, arraysize; +{ + int i, nelem, maxidx; + ipfexp_t *e; + + nelem = arraysize / sizeof(*array); + + /* + * Currently, it makes no sense to have an array less than 6 + * elements long - the initial size at the from, a single operation + * (minimum 4 in length) and a trailer, for a total of 6. + */ + if ((array[0] < 6) || (arraysize < 24) || (arraysize > 4096)) { + return -1; + } + + /* + * Verify the size of data pointed to by array with how long + * the array claims to be itself. + */ + if (array[0] * sizeof(*array) != arraysize) { + return -1; + } + + maxidx = nelem - 1; + /* + * The last opcode in this array should be an IPF_EXP_END. + */ + if (array[maxidx] != IPF_EXP_END) { + return -1; + } + + for (i = 1; i < maxidx; ) { + e = (ipfexp_t *)(array + i); + + /* + * The length of the bits to check must be at least 1 + * (or else there is nothing to comapre with!) and it + * cannot exceed the length of the data present. + */ + if ((e->ipfe_size < 1 ) || + (e->ipfe_size + i > maxidx)) { + return -1; + } + i += e->ipfe_size; + } + return 0; +} + + +/* ------------------------------------------------------------------------ */ +/* Function: ipf_fr_matcharray */ +/* Returns: int - 0 = match failed, else positive match */ +/* Parameters: fin(I) - pointer to packet information */ +/* array(I) - pointer to matching array */ +/* */ +/* This function is used to apply a matching array against a packet and */ +/* return an indication of whether or not the packet successfully matches */ +/* all of the commands in it. */ +/* ------------------------------------------------------------------------ */ +static int +ipf_fr_matcharray(fin, array) + fr_info_t *fin; + int *array; +{ + int i, n, *x, rv, p; + ipfexp_t *e; + + rv = 0; + n = array[0]; + x = array + 1; + + for (; n > 0; x += 3 + x[3], rv = 0) { + e = (ipfexp_t *)x; + if (e->ipfe_cmd == IPF_EXP_END) + break; + n -= e->ipfe_size; + + /* + * The upper 16 bits currently store the protocol value. + * This is currently used with TCP and UDP port compares and + * allows "tcp.port = 80" without requiring an explicit + " "ip.pr = tcp" first. + */ + p = e->ipfe_cmd >> 16; + if ((p != 0) && (p != fin->fin_p)) + break; + + switch (e->ipfe_cmd) + { + case IPF_EXP_IP_PR : + for (i = 0; !rv && i < e->ipfe_narg; i++) { + rv |= (fin->fin_p == e->ipfe_arg0[i]); + } + break; + + case IPF_EXP_IP_SRCADDR : + if (fin->fin_v != 4) + break; + for (i = 0; !rv && i < e->ipfe_narg; i++) { + rv |= ((fin->fin_saddr & + e->ipfe_arg0[i * 2 + 1]) == + e->ipfe_arg0[i * 2]); + } + break; + + case IPF_EXP_IP_DSTADDR : + if (fin->fin_v != 4) + break; + for (i = 0; !rv && i < e->ipfe_narg; i++) { + rv |= ((fin->fin_daddr & + e->ipfe_arg0[i * 2 + 1]) == + e->ipfe_arg0[i * 2]); + } + break; + + case IPF_EXP_IP_ADDR : + if (fin->fin_v != 4) + break; + for (i = 0; !rv && i < e->ipfe_narg; i++) { + rv |= ((fin->fin_saddr & + e->ipfe_arg0[i * 2 + 1]) == + e->ipfe_arg0[i * 2]) || + ((fin->fin_daddr & + e->ipfe_arg0[i * 2 + 1]) == + e->ipfe_arg0[i * 2]); + } + break; + +#ifdef USE_INET6 + case IPF_EXP_IP6_SRCADDR : + if (fin->fin_v != 6) + break; + for (i = 0; !rv && i < e->ipfe_narg; i++) { + rv |= IP6_MASKEQ(&fin->fin_src6, + &e->ipfe_arg0[i * 8 + 4], + &e->ipfe_arg0[i * 8]); + } + break; + + case IPF_EXP_IP6_DSTADDR : + if (fin->fin_v != 6) + break; + for (i = 0; !rv && i < e->ipfe_narg; i++) { + rv |= IP6_MASKEQ(&fin->fin_dst6, + &e->ipfe_arg0[i * 8 + 4], + &e->ipfe_arg0[i * 8]); + } + break; + + case IPF_EXP_IP6_ADDR : + if (fin->fin_v != 6) + break; + for (i = 0; !rv && i < e->ipfe_narg; i++) { + rv |= IP6_MASKEQ(&fin->fin_src6, + &e->ipfe_arg0[i * 8 + 4], + &e->ipfe_arg0[i * 8]) || + IP6_MASKEQ(&fin->fin_dst6, + &e->ipfe_arg0[i * 8 + 4], + &e->ipfe_arg0[i * 8]); + } + break; +#endif + + case IPF_EXP_UDP_PORT : + case IPF_EXP_TCP_PORT : + for (i = 0; !rv && i < e->ipfe_narg; i++) { + rv |= (fin->fin_sport == e->ipfe_arg0[i]) || + (fin->fin_dport == e->ipfe_arg0[i]); + } + break; + + case IPF_EXP_UDP_SPORT : + case IPF_EXP_TCP_SPORT : + for (i = 0; !rv && i < e->ipfe_narg; i++) { + rv |= (fin->fin_sport == e->ipfe_arg0[i]); + } + break; + + case IPF_EXP_UDP_DPORT : + case IPF_EXP_TCP_DPORT : + for (i = 0; !rv && i < e->ipfe_narg; i++) { + rv |= (fin->fin_dport == e->ipfe_arg0[i]); + } + break; + + case IPF_EXP_TCP_FLAGS : + for (i = 0; !rv && i < e->ipfe_narg; i++) { + rv |= ((fin->fin_tcpf & + e->ipfe_arg0[i * 2 + 1]) == + e->ipfe_arg0[i * 2]); + } + break; + } + rv ^= e->ipfe_not; + + if (rv == 0) + break; + } + + return rv; +} + + /* ------------------------------------------------------------------------ */ /* Function: ipf_queueflush */ /* Returns: int - number of entries flushed (0 = none) */ -/* Parameters: deletefn(I) - function to call to delete entry */ +/* Parameters: softc(I) - pointer to soft context main structure */ +/* deletefn(I) - function to call to delete entry */ /* ipfqs(I) - top of the list of ipf internal queues */ /* userqs(I) - top of the list of user defined timeouts */ /* */ /* This fucntion gets called when the state/NAT hash tables fill up and we */ -/* need to try a bit harder to free up some space. The algorithm used is */ -/* to look for the oldest entries on each timeout queue and free them if */ -/* they are within the given window we are considering. Where the window */ -/* starts and the steps taken to increase its size depend upon how long ipf */ -/* has been running (fr_ticks.) Anything modified in the last 30 seconds */ -/* is not touched. */ +/* need to try a bit harder to free up some space. The algorithm used here */ +/* split into two parts but both halves have the same goal: to reduce the */ +/* number of connections considered to be "active" to the low watermark. */ +/* There are two steps in doing this: */ +/* 1) Remove any TCP connections that are already considered to be "closed" */ +/* but have not yet been removed from the state table. The two states */ +/* TCPS_TIME_WAIT and TCPS_CLOSED are considered to be the perfect */ +/* candidates for this style of removal. If freeing up entries in */ +/* CLOSED or both CLOSED and TIME_WAIT brings us to the low watermark, */ +/* we do not go on to step 2. */ +/* */ +/* 2) Look for the oldest entries on each timeout queue and free them if */ +/* they are within the given window we are considering. Where the */ +/* window starts and the steps taken to increase its size depend upon */ +/* how long ipf has been running (ipf_ticks.) Anything modified in the */ +/* last 30 seconds is not touched. */ /* touched */ -/* die fr_ticks 30*1.5 1800*1.5 | 43200*1.5 */ +/* die ipf_ticks 30*1.5 1800*1.5 | 43200*1.5 */ /* | | | | | | */ /* future <--+----------+--------+-----------+-----+-----+-----------> past */ /* now \_int=30s_/ \_int=1hr_/ \_int=12hr */ /* */ /* Points to note: */ /* - tqe_die is the time, in the future, when entries die. */ -/* - tqe_die - fr_ticks is how long left the connection has to live in ipf */ +/* - tqe_die - ipf_ticks is how long left the connection has to live in ipf */ /* ticks. */ /* - tqe_touched is when the entry was last used by NAT/state */ -/* - the closer tqe_touched is to fr_ticks, the further tqe_die will be for */ -/* any given timeout queue and vice versa. */ +/* - the closer tqe_touched is to ipf_ticks, the further tqe_die will be */ +/* ipf_ticks any given timeout queue and vice versa. */ /* - both tqe_die and tqe_touched increase over time */ /* - timeout queues are sorted with the highest value of tqe_die at the */ /* bottom and therefore the smallest values of each are at the top */ +/* - the pointer passed in as ipfqs should point to an array of timeout */ +/* queues representing each of the TCP states */ /* */ /* We start by setting up a maximum range to scan for things to move of */ /* iend (newest) to istart (oldest) in chunks of "interval". If nothing is */ /* found in that range, "interval" is adjusted (so long as it isn't 30) and */ -/* we start again with a new value for "iend" and "istart". The downside */ -/* of the current implementation is that it may return removing just 1 entry*/ -/* every time (pathological case) where it could remove more. */ +/* we start again with a new value for "iend" and "istart". This is */ +/* continued until we either finish the scan of 30 second intervals or the */ +/* low water mark is reached. */ /* ------------------------------------------------------------------------ */ -int ipf_queueflush(deletefn, ipfqs, userqs) -ipftq_delete_fn_t deletefn; -ipftq_t *ipfqs, *userqs; +int +ipf_queueflush(softc, deletefn, ipfqs, userqs, activep, size, low) + ipf_main_softc_t *softc; + ipftq_delete_fn_t deletefn; + ipftq_t *ipfqs, *userqs; + u_int *activep; + int size, low; { u_long interval, istart, iend; ipftq_t *ifq, *ifqnext; ipftqent_t *tqe, *tqn; - int removed; + int removed = 0; + + for (tqn = ipfqs[IPF_TCPS_CLOSED].ifq_head; ((tqe = tqn) != NULL); ) { + tqn = tqe->tqe_next; + if ((*deletefn)(softc, tqe->tqe_parent) == 0) + removed++; + } + if ((*activep * 100 / size) > low) { + for (tqn = ipfqs[IPF_TCPS_TIME_WAIT].ifq_head; + ((tqe = tqn) != NULL); ) { + tqn = tqe->tqe_next; + if ((*deletefn)(softc, tqe->tqe_parent) == 0) + removed++; + } + } + + if ((*activep * 100 / size) <= low) { + return removed; + } /* * NOTE: Use of "* 15 / 10" is required here because if "* 1.5" is * used then the operations are upgraded to floating point * and kernels don't like floating point... */ - if (fr_ticks > IPF_TTLVAL(43200 * 15 / 10)) { + if (softc->ipf_ticks > IPF_TTLVAL(43200 * 15 / 10)) { istart = IPF_TTLVAL(86400 * 4); interval = IPF_TTLVAL(43200); - } else if (fr_ticks > IPF_TTLVAL(1800 * 15 / 10)) { + } else if (softc->ipf_ticks > IPF_TTLVAL(1800 * 15 / 10)) { istart = IPF_TTLVAL(43200); interval = IPF_TTLVAL(1800); - } else if (fr_ticks > IPF_TTLVAL(30 * 15 / 10)) { + } else if (softc->ipf_ticks > IPF_TTLVAL(30 * 15 / 10)) { istart = IPF_TTLVAL(1800); interval = IPF_TTLVAL(30); } else { return 0; } - if (istart > fr_ticks) { - if (fr_ticks - interval < interval) + if (istart > softc->ipf_ticks) { + if (softc->ipf_ticks - interval < interval) istart = interval; else - istart = (fr_ticks / interval) * interval; + istart = (softc->ipf_ticks / interval) * interval; } - iend = fr_ticks - interval; - removed = 0; + iend = softc->ipf_ticks - interval; - for (;;) { + while ((*activep * 100 / size) > low) { u_long try; - try = fr_ticks - istart; + try = softc->ipf_ticks - istart; for (ifq = ipfqs; ifq != NULL; ifq = ifq->ifq_next) { for (tqn = ifq->ifq_head; ((tqe = tqn) != NULL); ) { if (try < tqe->tqe_touched) break; tqn = tqe->tqe_next; - if ((*deletefn)(tqe->tqe_parent) == 0) + if ((*deletefn)(softc, tqe->tqe_parent) == 0) removed++; } } @@ -7331,14 +9003,12 @@ ipftq_t *ipfqs, *userqs; if (try < tqe->tqe_touched) break; tqn = tqe->tqe_next; - if ((*deletefn)(tqe->tqe_parent) == 0) + if ((*deletefn)(softc, tqe->tqe_parent) == 0) removed++; } } if (try >= iend) { - if (removed > 0) - break; if (interval == IPF_TTLVAL(43200)) { interval = IPF_TTLVAL(1800); } else if (interval == IPF_TTLVAL(1800)) { @@ -7346,13 +9016,1200 @@ ipftq_t *ipfqs, *userqs; } else { break; } - if (interval >= fr_ticks) + if (interval >= softc->ipf_ticks) break; - iend = fr_ticks - interval; + iend = softc->ipf_ticks - interval; } istart -= interval; } return removed; } + + +/* ------------------------------------------------------------------------ */ +/* Function: ipf_deliverlocal */ +/* Returns: int - 1 = local address, 0 = non-local address */ +/* Parameters: softc(I) - pointer to soft context main structure */ +/* ipversion(I) - IP protocol version (4 or 6) */ +/* ifp(I) - network interface pointer */ +/* ipaddr(I) - IPv4/6 destination address */ +/* */ +/* This fucntion is used to determine in the address "ipaddr" belongs to */ +/* the network interface represented by ifp. */ +/* ------------------------------------------------------------------------ */ +int +ipf_deliverlocal(softc, ipversion, ifp, ipaddr) + ipf_main_softc_t *softc; + int ipversion; + void *ifp; + i6addr_t *ipaddr; +{ + i6addr_t addr; + int islocal = 0; + + if (ipversion == 4) { + if (ipf_ifpaddr(softc, 4, FRI_NORMAL, ifp, &addr, NULL) == 0) { + if (addr.in4.s_addr == ipaddr->in4.s_addr) + islocal = 1; + } + +#ifdef USE_INET6 + } else if (ipversion == 6) { + if (ipf_ifpaddr(softc, 6, FRI_NORMAL, ifp, &addr, NULL) == 0) { + if (IP6_EQ(&addr, ipaddr)) + islocal = 1; + } +#endif + } + + return islocal; +} + + +/* ------------------------------------------------------------------------ */ +/* Function: ipf_settimeout */ +/* Returns: int - 0 = success, -1 = failure */ +/* Parameters: softc(I) - pointer to soft context main structure */ +/* t(I) - pointer to tuneable array entry */ +/* p(I) - pointer to values passed in to apply */ +/* */ +/* This function is called to set the timeout values for each distinct */ +/* queue timeout that is available. When called, it calls into both the */ +/* state and NAT code, telling them to update their timeout queues. */ +/* ------------------------------------------------------------------------ */ +static int +ipf_settimeout(softc, t, p) + struct ipf_main_softc_s *softc; + ipftuneable_t *t; + ipftuneval_t *p; +{ + + /* + * ipf_interror should be set by the functions called here, not + * by this function - it's just a middle man. + */ + if (ipf_state_settimeout(softc, t, p) == -1) + return -1; + if (ipf_nat_settimeout(softc, t, p) == -1) + return -1; + return 0; +} + + +/* ------------------------------------------------------------------------ */ +/* Function: ipf_apply_timeout */ +/* Returns: int - 0 = success, -1 = failure */ +/* Parameters: head(I) - pointer to tuneable array entry */ +/* seconds(I) - pointer to values passed in to apply */ +/* */ +/* This function applies a timeout of "seconds" to the timeout queue that */ +/* is pointed to by "head". All entries on this list have an expiration */ +/* set to be the current tick value of ipf plus the ttl. Given that this */ +/* function should only be called when the delta is non-zero, the task is */ +/* to walk the entire list and apply the change. The sort order will not */ +/* change. The only catch is that this is O(n) across the list, so if the */ +/* queue has lots of entries (10s of thousands or 100s of thousands), it */ +/* could take a relatively long time to work through them all. */ +/* ------------------------------------------------------------------------ */ +void +ipf_apply_timeout(head, seconds) + ipftq_t *head; + u_int seconds; +{ + u_int oldtimeout, newtimeout; + ipftqent_t *tqe; + int delta; + + MUTEX_ENTER(&head->ifq_lock); + oldtimeout = head->ifq_ttl; + newtimeout = IPF_TTLVAL(seconds); + delta = oldtimeout - newtimeout; + + head->ifq_ttl = newtimeout; + + for (tqe = head->ifq_head; tqe != NULL; tqe = tqe->tqe_next) { + tqe->tqe_die += delta; + } + MUTEX_EXIT(&head->ifq_lock); +} + + +/* ------------------------------------------------------------------------ */ +/* Function: ipf_settimeout_tcp */ +/* Returns: int - 0 = successfully applied, -1 = failed */ +/* Parameters: t(I) - pointer to tuneable to change */ +/* p(I) - pointer to new timeout information */ +/* tab(I) - pointer to table of TCP queues */ +/* */ +/* This function applies the new timeout (p) to the TCP tunable (t) and */ +/* updates all of the entries on the relevant timeout queue by calling */ +/* ipf_apply_timeout(). */ +/* ------------------------------------------------------------------------ */ +int +ipf_settimeout_tcp(t, p, tab) + ipftuneable_t *t; + ipftuneval_t *p; + ipftq_t *tab; +{ + if (!strcmp(t->ipft_name, "tcp_idle_timeout") || + !strcmp(t->ipft_name, "tcp_established")) { + ipf_apply_timeout(&tab[IPF_TCPS_ESTABLISHED], p->ipftu_int); + } else if (!strcmp(t->ipft_name, "tcp_close_wait")) { + ipf_apply_timeout(&tab[IPF_TCPS_CLOSE_WAIT], p->ipftu_int); + } else if (!strcmp(t->ipft_name, "tcp_last_ack")) { + ipf_apply_timeout(&tab[IPF_TCPS_LAST_ACK], p->ipftu_int); + } else if (!strcmp(t->ipft_name, "tcp_timeout")) { + ipf_apply_timeout(&tab[IPF_TCPS_LISTEN], p->ipftu_int); + ipf_apply_timeout(&tab[IPF_TCPS_HALF_ESTAB], p->ipftu_int); + ipf_apply_timeout(&tab[IPF_TCPS_CLOSING], p->ipftu_int); + } else if (!strcmp(t->ipft_name, "tcp_listen")) { + ipf_apply_timeout(&tab[IPF_TCPS_LISTEN], p->ipftu_int); + } else if (!strcmp(t->ipft_name, "tcp_half_established")) { + ipf_apply_timeout(&tab[IPF_TCPS_HALF_ESTAB], p->ipftu_int); + } else if (!strcmp(t->ipft_name, "tcp_closing")) { + ipf_apply_timeout(&tab[IPF_TCPS_CLOSING], p->ipftu_int); + } else if (!strcmp(t->ipft_name, "tcp_syn_received")) { + ipf_apply_timeout(&tab[IPF_TCPS_SYN_RECEIVED], p->ipftu_int); + } else if (!strcmp(t->ipft_name, "tcp_syn_sent")) { + ipf_apply_timeout(&tab[IPF_TCPS_SYN_SENT], p->ipftu_int); + } else if (!strcmp(t->ipft_name, "tcp_closed")) { + ipf_apply_timeout(&tab[IPF_TCPS_CLOSED], p->ipftu_int); + } else if (!strcmp(t->ipft_name, "tcp_half_closed")) { + ipf_apply_timeout(&tab[IPF_TCPS_CLOSED], p->ipftu_int); + } else if (!strcmp(t->ipft_name, "tcp_time_wait")) { + ipf_apply_timeout(&tab[IPF_TCPS_TIME_WAIT], p->ipftu_int); + } else { + /* + * ipf_interror isn't set here because it should be set + * by whatever called this function. + */ + return -1; + } + return 0; +} + + +/* ------------------------------------------------------------------------ */ +/* Function: ipf_main_soft_create */ +/* Returns: NULL = failure, else success */ +/* Parameters: arg(I) - pointer to soft context structure if already allocd */ +/* */ +/* Create the foundation soft context structure. In circumstances where it */ +/* is not required to dynamically allocate the context, a pointer can be */ +/* passed in (rather than NULL) to a structure to be initialised. */ +/* The main thing of interest is that a number of locks are initialised */ +/* here instead of in the where might be expected - in the relevant create */ +/* function elsewhere. This is done because the current locking design has */ +/* some areas where these locks are used outside of their module. */ +/* Possibly the most important exercise that is done here is setting of all */ +/* the timeout values, allowing them to be changed before init(). */ +/* ------------------------------------------------------------------------ */ +void * +ipf_main_soft_create(arg) + void *arg; +{ + ipf_main_softc_t *softc; + + if (arg == NULL) { + KMALLOC(softc, ipf_main_softc_t *); + if (softc == NULL) + return NULL; + } else { + softc = arg; + } + + bzero((char *)softc, sizeof(*softc)); + + /* + * This serves as a flag as to whether or not the softc should be + * free'd when _destroy is called. + */ + softc->ipf_dynamic_softc = (arg == NULL) ? 1 : 0; + + softc->ipf_tuners = ipf_tune_array_copy(softc, + sizeof(ipf_main_tuneables), + ipf_main_tuneables); + if (softc->ipf_tuners == NULL) { + ipf_main_soft_destroy(softc); + return NULL; + } + + MUTEX_INIT(&softc->ipf_rw, "ipf rw mutex"); + MUTEX_INIT(&softc->ipf_timeoutlock, "ipf timeout lock"); + RWLOCK_INIT(&softc->ipf_global, "ipf filter load/unload mutex"); + RWLOCK_INIT(&softc->ipf_mutex, "ipf filter rwlock"); + RWLOCK_INIT(&softc->ipf_tokens, "ipf token rwlock"); + RWLOCK_INIT(&softc->ipf_state, "ipf state rwlock"); + RWLOCK_INIT(&softc->ipf_nat, "ipf IP NAT rwlock"); + RWLOCK_INIT(&softc->ipf_poolrw, "ipf pool rwlock"); + RWLOCK_INIT(&softc->ipf_frag, "ipf frag rwlock"); + + softc->ipf_token_head = NULL; + softc->ipf_token_tail = &softc->ipf_token_head; + + softc->ipf_tcpidletimeout = FIVE_DAYS; + softc->ipf_tcpclosewait = IPF_TTLVAL(2 * TCP_MSL); + softc->ipf_tcplastack = IPF_TTLVAL(30); + softc->ipf_tcptimewait = IPF_TTLVAL(2 * TCP_MSL); + softc->ipf_tcptimeout = IPF_TTLVAL(2 * TCP_MSL); + softc->ipf_tcpsynsent = IPF_TTLVAL(2 * TCP_MSL); + softc->ipf_tcpsynrecv = IPF_TTLVAL(2 * TCP_MSL); + softc->ipf_tcpclosed = IPF_TTLVAL(30); + softc->ipf_tcphalfclosed = IPF_TTLVAL(2 * 3600); + softc->ipf_udptimeout = IPF_TTLVAL(120); + softc->ipf_udpacktimeout = IPF_TTLVAL(12); + softc->ipf_icmptimeout = IPF_TTLVAL(60); + softc->ipf_icmpacktimeout = IPF_TTLVAL(6); + softc->ipf_iptimeout = IPF_TTLVAL(60); + +#if defined(IPFILTER_DEFAULT_BLOCK) + softc->ipf_pass = FR_BLOCK|FR_NOMATCH; +#else + softc->ipf_pass = (IPF_DEFAULT_PASS)|FR_NOMATCH; +#endif + softc->ipf_minttl = 4; + softc->ipf_icmpminfragmtu = 68; + softc->ipf_flags = IPF_LOGGING; + + return softc; +} + +/* ------------------------------------------------------------------------ */ +/* Function: ipf_main_soft_init */ +/* Returns: 0 = success, -1 = failure */ +/* Parameters: softc(I) - pointer to soft context main structure */ +/* */ +/* A null-op function that exists as a placeholder so that the flow in */ +/* other functions is obvious. */ +/* ------------------------------------------------------------------------ */ +/*ARGSUSED*/ +int +ipf_main_soft_init(softc) + ipf_main_softc_t *softc; +{ + return 0; +} + + +/* ------------------------------------------------------------------------ */ +/* Function: ipf_main_soft_destroy */ +/* Returns: void */ +/* Parameters: softc(I) - pointer to soft context main structure */ +/* */ +/* Undo everything that we did in ipf_main_soft_create. */ +/* */ +/* The most important check that needs to be made here is whether or not */ +/* the structure was allocated by ipf_main_soft_create() by checking what */ +/* value is stored in ipf_dynamic_main. */ +/* ------------------------------------------------------------------------ */ +/*ARGSUSED*/ +void +ipf_main_soft_destroy(softc) + ipf_main_softc_t *softc; +{ + + RW_DESTROY(&softc->ipf_frag); + RW_DESTROY(&softc->ipf_poolrw); + RW_DESTROY(&softc->ipf_nat); + RW_DESTROY(&softc->ipf_state); + RW_DESTROY(&softc->ipf_tokens); + RW_DESTROY(&softc->ipf_mutex); + RW_DESTROY(&softc->ipf_global); + MUTEX_DESTROY(&softc->ipf_timeoutlock); + MUTEX_DESTROY(&softc->ipf_rw); + + if (softc->ipf_tuners != NULL) { + KFREES(softc->ipf_tuners, sizeof(ipf_main_tuneables)); + } + if (softc->ipf_dynamic_softc == 1) { + KFREE(softc); + } +} + + +/* ------------------------------------------------------------------------ */ +/* Function: ipf_main_soft_fini */ +/* Returns: 0 = success, -1 = failure */ +/* Parameters: softc(I) - pointer to soft context main structure */ +/* */ +/* Clean out the rules which have been added since _init was last called, */ +/* the only dynamic part of the mainline. */ +/* ------------------------------------------------------------------------ */ +int +ipf_main_soft_fini(softc) + ipf_main_softc_t *softc; +{ + (void) ipf_flush(softc, IPL_LOGIPF, FR_INQUE|FR_OUTQUE|FR_INACTIVE); + (void) ipf_flush(softc, IPL_LOGIPF, FR_INQUE|FR_OUTQUE); + (void) ipf_flush(softc, IPL_LOGCOUNT, FR_INQUE|FR_OUTQUE|FR_INACTIVE); + (void) ipf_flush(softc, IPL_LOGCOUNT, FR_INQUE|FR_OUTQUE); + + return 0; +} + + +/* ------------------------------------------------------------------------ */ +/* Function: ipf_main_load */ +/* Returns: 0 = success, -1 = failure */ +/* Parameters: none */ +/* */ +/* Handle global initialisation that needs to be done for the base part of */ +/* IPFilter. At present this just amounts to initialising some ICMP lookup */ +/* arrays that get used by the state/NAT code. */ +/* ------------------------------------------------------------------------ */ +int +ipf_main_load() +{ + int i; + + /* fill icmp reply type table */ + for (i = 0; i <= ICMP_MAXTYPE; i++) + icmpreplytype4[i] = -1; + icmpreplytype4[ICMP_ECHO] = ICMP_ECHOREPLY; + icmpreplytype4[ICMP_TSTAMP] = ICMP_TSTAMPREPLY; + icmpreplytype4[ICMP_IREQ] = ICMP_IREQREPLY; + icmpreplytype4[ICMP_MASKREQ] = ICMP_MASKREPLY; + +#ifdef USE_INET6 + /* fill icmp reply type table */ + for (i = 0; i <= ICMP6_MAXTYPE; i++) + icmpreplytype6[i] = -1; + icmpreplytype6[ICMP6_ECHO_REQUEST] = ICMP6_ECHO_REPLY; + icmpreplytype6[ICMP6_MEMBERSHIP_QUERY] = ICMP6_MEMBERSHIP_REPORT; + icmpreplytype6[ICMP6_NI_QUERY] = ICMP6_NI_REPLY; + icmpreplytype6[ND_ROUTER_SOLICIT] = ND_ROUTER_ADVERT; + icmpreplytype6[ND_NEIGHBOR_SOLICIT] = ND_NEIGHBOR_ADVERT; +#endif + + return 0; +} + + +/* ------------------------------------------------------------------------ */ +/* Function: ipf_main_unload */ +/* Returns: 0 = success, -1 = failure */ +/* Parameters: none */ +/* */ +/* A null-op function that exists as a placeholder so that the flow in */ +/* other functions is obvious. */ +/* ------------------------------------------------------------------------ */ +int +ipf_main_unload() +{ + return 0; +} + + +/* ------------------------------------------------------------------------ */ +/* Function: ipf_load_all */ +/* Returns: 0 = success, -1 = failure */ +/* Parameters: none */ +/* */ +/* Work through all of the subsystems inside IPFilter and call the load */ +/* function for each in an order that won't lead to a crash :) */ +/* ------------------------------------------------------------------------ */ +int +ipf_load_all() +{ + if (ipf_main_load() == -1) + return -1; + + if (ipf_state_main_load() == -1) + return -1; + + if (ipf_nat_main_load() == -1) + return -1; + + if (ipf_frag_main_load() == -1) + return -1; + + if (ipf_auth_main_load() == -1) + return -1; + + if (ipf_proxy_main_load() == -1) + return -1; + + return 0; +} + + +/* ------------------------------------------------------------------------ */ +/* Function: ipf_unload_all */ +/* Returns: 0 = success, -1 = failure */ +/* Parameters: none */ +/* */ +/* Work through all of the subsystems inside IPFilter and call the unload */ +/* function for each in an order that won't lead to a crash :) */ +/* ------------------------------------------------------------------------ */ +int +ipf_unload_all() +{ + if (ipf_proxy_main_unload() == -1) + return -1; + + if (ipf_auth_main_unload() == -1) + return -1; + + if (ipf_frag_main_unload() == -1) + return -1; + + if (ipf_nat_main_unload() == -1) + return -1; + + if (ipf_state_main_unload() == -1) + return -1; + + if (ipf_main_unload() == -1) + return -1; + + return 0; +} + + +/* ------------------------------------------------------------------------ */ +/* Function: ipf_create_all */ +/* Returns: NULL = failure, else success */ +/* Parameters: arg(I) - pointer to soft context main structure */ +/* */ +/* Work through all of the subsystems inside IPFilter and call the create */ +/* function for each in an order that won't lead to a crash :) */ +/* ------------------------------------------------------------------------ */ +ipf_main_softc_t * +ipf_create_all(arg) + void *arg; +{ + ipf_main_softc_t *softc; + + softc = ipf_main_soft_create(arg); + if (softc == NULL) + return NULL; + +#ifdef IPFILTER_LOG + softc->ipf_log_soft = ipf_log_soft_create(softc); + if (softc->ipf_log_soft == NULL) { + ipf_destroy_all(softc); + return NULL; + } +#endif + + softc->ipf_lookup_soft = ipf_lookup_soft_create(softc); + if (softc->ipf_lookup_soft == NULL) { + ipf_destroy_all(softc); + return NULL; + } + + softc->ipf_sync_soft = ipf_sync_soft_create(softc); + if (softc->ipf_sync_soft == NULL) { + ipf_destroy_all(softc); + return NULL; + } + + softc->ipf_state_soft = ipf_state_soft_create(softc); + if (softc->ipf_state_soft == NULL) { + ipf_destroy_all(softc); + return NULL; + } + + softc->ipf_nat_soft = ipf_nat_soft_create(softc); + if (softc->ipf_nat_soft == NULL) { + ipf_destroy_all(softc); + return NULL; + } + + softc->ipf_frag_soft = ipf_frag_soft_create(softc); + if (softc->ipf_frag_soft == NULL) { + ipf_destroy_all(softc); + return NULL; + } + + softc->ipf_auth_soft = ipf_auth_soft_create(softc); + if (softc->ipf_auth_soft == NULL) { + ipf_destroy_all(softc); + return NULL; + } + + softc->ipf_proxy_soft = ipf_proxy_soft_create(softc); + if (softc->ipf_proxy_soft == NULL) { + ipf_destroy_all(softc); + return NULL; + } + + return softc; +} + + +/* ------------------------------------------------------------------------ */ +/* Function: ipf_destroy_all */ +/* Returns: void */ +/* Parameters: softc(I) - pointer to soft context main structure */ +/* */ +/* Work through all of the subsystems inside IPFilter and call the destroy */ +/* function for each in an order that won't lead to a crash :) */ +/* */ +/* Every one of these functions is expected to succeed, so there is no */ +/* checking of return values. */ +/* ------------------------------------------------------------------------ */ +void +ipf_destroy_all(softc) + ipf_main_softc_t *softc; +{ + + if (softc->ipf_state_soft != NULL) { + ipf_state_soft_destroy(softc, softc->ipf_state_soft); + softc->ipf_state_soft = NULL; + } + + if (softc->ipf_nat_soft != NULL) { + ipf_nat_soft_destroy(softc, softc->ipf_nat_soft); + softc->ipf_nat_soft = NULL; + } + + if (softc->ipf_frag_soft != NULL) { + ipf_frag_soft_destroy(softc, softc->ipf_frag_soft); + softc->ipf_frag_soft = NULL; + } + + if (softc->ipf_auth_soft != NULL) { + ipf_auth_soft_destroy(softc, softc->ipf_auth_soft); + softc->ipf_auth_soft = NULL; + } + + if (softc->ipf_proxy_soft != NULL) { + ipf_proxy_soft_destroy(softc, softc->ipf_proxy_soft); + softc->ipf_proxy_soft = NULL; + } + + if (softc->ipf_sync_soft != NULL) { + ipf_sync_soft_destroy(softc, softc->ipf_sync_soft); + softc->ipf_sync_soft = NULL; + } + + if (softc->ipf_lookup_soft != NULL) { + ipf_lookup_soft_destroy(softc, softc->ipf_lookup_soft); + softc->ipf_lookup_soft = NULL; + } + +#ifdef IPFILTER_LOG + if (softc->ipf_log_soft != NULL) { + ipf_log_soft_destroy(softc, softc->ipf_log_soft); + softc->ipf_log_soft = NULL; + } +#endif + + ipf_main_soft_destroy(softc); +} + + +/* ------------------------------------------------------------------------ */ +/* Function: ipf_init_all */ +/* Returns: 0 = success, -1 = failure */ +/* Parameters: softc(I) - pointer to soft context main structure */ +/* */ +/* Work through all of the subsystems inside IPFilter and call the init */ +/* function for each in an order that won't lead to a crash :) */ +/* ------------------------------------------------------------------------ */ +int +ipf_init_all(softc) + ipf_main_softc_t *softc; +{ + + if (ipf_main_soft_init(softc) == -1) + return -1; + +#ifdef IPFILTER_LOG + if (ipf_log_soft_init(softc, softc->ipf_log_soft) == -1) + return -1; +#endif + + if (ipf_lookup_soft_init(softc, softc->ipf_lookup_soft) == -1) + return -1; + + if (ipf_sync_soft_init(softc, softc->ipf_sync_soft) == -1) + return -1; + + if (ipf_state_soft_init(softc, softc->ipf_state_soft) == -1) + return -1; + + if (ipf_nat_soft_init(softc, softc->ipf_nat_soft) == -1) + return -1; + + if (ipf_frag_soft_init(softc, softc->ipf_frag_soft) == -1) + return -1; + + if (ipf_auth_soft_init(softc, softc->ipf_auth_soft) == -1) + return -1; + + if (ipf_proxy_soft_init(softc, softc->ipf_proxy_soft) == -1) + return -1; + + return 0; +} + + +/* ------------------------------------------------------------------------ */ +/* Function: ipf_fini_all */ +/* Returns: 0 = success, -1 = failure */ +/* Parameters: softc(I) - pointer to soft context main structure */ +/* */ +/* Work through all of the subsystems inside IPFilter and call the fini */ +/* function for each in an order that won't lead to a crash :) */ +/* ------------------------------------------------------------------------ */ +int +ipf_fini_all(softc) + ipf_main_softc_t *softc; +{ + + ipf_token_flush(softc); + + if (ipf_proxy_soft_fini(softc, softc->ipf_proxy_soft) == -1) + return -1; + + if (ipf_auth_soft_fini(softc, softc->ipf_auth_soft) == -1) + return -1; + + if (ipf_frag_soft_fini(softc, softc->ipf_frag_soft) == -1) + return -1; + + if (ipf_nat_soft_fini(softc, softc->ipf_nat_soft) == -1) + return -1; + + if (ipf_state_soft_fini(softc, softc->ipf_state_soft) == -1) + return -1; + + if (ipf_sync_soft_fini(softc, softc->ipf_sync_soft) == -1) + return -1; + + if (ipf_lookup_soft_fini(softc, softc->ipf_lookup_soft) == -1) + return -1; + +#ifdef IPFILTER_LOG + if (ipf_log_soft_fini(softc, softc->ipf_log_soft) == -1) + return -1; +#endif + + if (ipf_main_soft_fini(softc) == -1) + return -1; + + return 0; +} + + +/* ------------------------------------------------------------------------ */ +/* Function: ipf_rule_expire */ +/* Returns: Nil */ +/* Parameters: softc(I) - pointer to soft context main structure */ +/* */ +/* At present this function exists just to support temporary addition of */ +/* firewall rules. Both inactive and active lists are scanned for items to */ +/* purge, as by rights, the expiration is computed as soon as the rule is */ +/* loaded in. */ +/* ------------------------------------------------------------------------ */ +void +ipf_rule_expire(softc) + ipf_main_softc_t *softc; +{ + frentry_t *fr; + + if ((softc->ipf_rule_explist[0] == NULL) && + (softc->ipf_rule_explist[1] == NULL)) + return; + + WRITE_ENTER(&softc->ipf_mutex); + + while ((fr = softc->ipf_rule_explist[0]) != NULL) { + /* + * Because the list is kept sorted on insertion, the fist + * one that dies in the future means no more work to do. + */ + if (fr->fr_die > softc->ipf_ticks) + break; + ipf_rule_delete(softc, fr, IPL_LOGIPF, 0); + } + + while ((fr = softc->ipf_rule_explist[1]) != NULL) { + /* + * Because the list is kept sorted on insertion, the fist + * one that dies in the future means no more work to do. + */ + if (fr->fr_die > softc->ipf_ticks) + break; + ipf_rule_delete(softc, fr, IPL_LOGIPF, 1); + } + + RWLOCK_EXIT(&softc->ipf_mutex); +} + + +static int ipf_ht_node_cmp __P((struct host_node_s *, struct host_node_s *)); +static void ipf_ht_node_make_key __P((host_track_t *, host_node_t *, int, + i6addr_t *)); + +host_node_t RBI_ZERO(ipf_rb); +RBI_CODE(ipf_rb, host_node_t, hn_entry, ipf_ht_node_cmp) + + +/* ------------------------------------------------------------------------ */ +/* Function: ipf_ht_node_cmp */ +/* Returns: int - 0 == nodes are the same, .. */ +/* Parameters: k1(I) - pointer to first key to compare */ +/* k2(I) - pointer to second key to compare */ +/* */ +/* The "key" for the node is a combination of two fields: the address */ +/* family and the address itself. */ +/* */ +/* Because we're not actually interpreting the address data, it isn't */ +/* necessary to convert them to/from network/host byte order. The mask is */ +/* just used to remove bits that aren't significant - it doesn't matter */ +/* where they are, as long as they're always in the same place. */ +/* */ +/* As with IP6_EQ, comparing IPv6 addresses starts at the bottom because */ +/* this is where individual ones will differ the most - but not true for */ +/* for /48's, etc. */ +/* ------------------------------------------------------------------------ */ +static int +ipf_ht_node_cmp(k1, k2) + struct host_node_s *k1, *k2; +{ + int i; + + i = (k2->hn_addr.adf_family - k1->hn_addr.adf_family); + if (i != 0) + return i; + + if (k1->hn_addr.adf_family == AF_INET) + return (k2->hn_addr.adf_addr.in4.s_addr - + k1->hn_addr.adf_addr.in4.s_addr); + + i = k2->hn_addr.adf_addr.i6[3] - k1->hn_addr.adf_addr.i6[3]; + if (i != 0) + return i; + i = k2->hn_addr.adf_addr.i6[2] - k1->hn_addr.adf_addr.i6[2]; + if (i != 0) + return i; + i = k2->hn_addr.adf_addr.i6[1] - k1->hn_addr.adf_addr.i6[1]; + if (i != 0) + return i; + i = k2->hn_addr.adf_addr.i6[0] - k1->hn_addr.adf_addr.i6[0]; + return i; +} + + +/* ------------------------------------------------------------------------ */ +/* Function: ipf_ht_node_make_key */ +/* Returns: Nil */ +/* parameters: htp(I) - pointer to address tracking structure */ +/* key(I) - where to store masked address for lookup */ +/* family(I) - protocol family of address */ +/* addr(I) - pointer to network address */ +/* */ +/* Using the "netmask" (number of bits) stored parent host tracking struct, */ +/* copy the address passed in into the key structure whilst masking out the */ +/* bits that we don't want. */ +/* */ +/* Because the parser will set ht_netmask to 128 if there is no protocol */ +/* specified (the parser doesn't know if it should be a v4 or v6 rule), we */ +/* have to be wary of that and not allow 32-128 to happen. */ +/* ------------------------------------------------------------------------ */ +static void +ipf_ht_node_make_key(htp, key, family, addr) + host_track_t *htp; + host_node_t *key; + int family; + i6addr_t *addr; +{ + key->hn_addr.adf_family = family; + if (family == AF_INET) { + u_32_t mask; + int bits; + + key->hn_addr.adf_len = sizeof(key->hn_addr.adf_addr.in4); + bits = htp->ht_netmask; + if (bits >= 32) { + mask = 0xffffffff; + } else { + mask = htonl(0xffffffff << (32 - bits)); + } + key->hn_addr.adf_addr.in4.s_addr = addr->in4.s_addr & mask; +#ifdef USE_INET6 + } else { + int bits = htp->ht_netmask; + + key->hn_addr.adf_len = sizeof(key->hn_addr.adf_addr.in6); + if (bits > 96) { + key->hn_addr.adf_addr.i6[3] = addr->i6[3] & + htonl(0xffffffff << (128 - bits)); + key->hn_addr.adf_addr.i6[2] = addr->i6[2]; + key->hn_addr.adf_addr.i6[1] = addr->i6[2]; + key->hn_addr.adf_addr.i6[0] = addr->i6[2]; + } else if (bits > 64) { + key->hn_addr.adf_addr.i6[3] = 0; + key->hn_addr.adf_addr.i6[2] = addr->i6[2] & + htonl(0xffffffff << (96 - bits)); + key->hn_addr.adf_addr.i6[1] = addr->i6[1]; + key->hn_addr.adf_addr.i6[0] = addr->i6[0]; + } else if (bits > 32) { + key->hn_addr.adf_addr.i6[3] = 0; + key->hn_addr.adf_addr.i6[2] = 0; + key->hn_addr.adf_addr.i6[1] = addr->i6[1] & + htonl(0xffffffff << (64 - bits)); + key->hn_addr.adf_addr.i6[0] = addr->i6[0]; + } else { + key->hn_addr.adf_addr.i6[3] = 0; + key->hn_addr.adf_addr.i6[2] = 0; + key->hn_addr.adf_addr.i6[1] = 0; + key->hn_addr.adf_addr.i6[0] = addr->i6[0] & + htonl(0xffffffff << (32 - bits)); + } +#endif + } +} + + +/* ------------------------------------------------------------------------ */ +/* Function: ipf_ht_node_add */ +/* Returns: int - 0 == success, -1 == failure */ +/* Parameters: softc(I) - pointer to soft context main structure */ +/* htp(I) - pointer to address tracking structure */ +/* family(I) - protocol family of address */ +/* addr(I) - pointer to network address */ +/* */ +/* NOTE: THIS FUNCTION MUST BE CALLED WITH AN EXCLUSIVE LOCK THAT PREVENTS */ +/* ipf_ht_node_del FROM RUNNING CONCURRENTLY ON THE SAME htp. */ +/* */ +/* After preparing the key with the address information to find, look in */ +/* the red-black tree to see if the address is known. A successful call to */ +/* this function can mean one of two things: a new node was added to the */ +/* tree or a matching node exists and we're able to bump up its activity. */ +/* ------------------------------------------------------------------------ */ +int +ipf_ht_node_add(softc, htp, family, addr) + ipf_main_softc_t *softc; + host_track_t *htp; + int family; + i6addr_t *addr; +{ + host_node_t *h; + host_node_t k; + + ipf_ht_node_make_key(htp, &k, family, addr); + + h = RBI_SEARCH(ipf_rb, &htp->ht_root, &k); + if (h == NULL) { + if (htp->ht_cur_nodes >= htp->ht_max_nodes) + return -1; + KMALLOC(h, host_node_t *); + if (h == NULL) { + DT(ipf_rb_no_mem); + LBUMP(ipf_rb_no_mem); + return -1; + } + + /* + * If there was a macro to initialise the RB node then that + * would get used here, but there isn't... + */ + bzero((char *)h, sizeof(*h)); + h->hn_addr = k.hn_addr; + h->hn_addr.adf_family = k.hn_addr.adf_family; + RBI_INSERT(ipf_rb, &htp->ht_root, h); + htp->ht_cur_nodes++; + } else { + if ((htp->ht_max_per_node != 0) && + (h->hn_active >= htp->ht_max_per_node)) { + DT(ipf_rb_node_max); + LBUMP(ipf_rb_node_max); + return -1; + } + } + + h->hn_active++; + + return 0; +} + + +/* ------------------------------------------------------------------------ */ +/* Function: ipf_ht_node_del */ +/* Returns: int - 0 == success, -1 == failure */ +/* parameters: htp(I) - pointer to address tracking structure */ +/* family(I) - protocol family of address */ +/* addr(I) - pointer to network address */ +/* */ +/* NOTE: THIS FUNCTION MUST BE CALLED WITH AN EXCLUSIVE LOCK THAT PREVENTS */ +/* ipf_ht_node_add FROM RUNNING CONCURRENTLY ON THE SAME htp. */ +/* */ +/* Try and find the address passed in amongst the leavese on this tree to */ +/* be friend. If found then drop the active account for that node drops by */ +/* one. If that count reaches 0, it is time to free it all up. */ +/* ------------------------------------------------------------------------ */ +int +ipf_ht_node_del(htp, family, addr) + host_track_t *htp; + int family; + i6addr_t *addr; +{ + host_node_t *h; + host_node_t k; + + ipf_ht_node_make_key(htp, &k, family, addr); + + h = RBI_SEARCH(ipf_rb, &htp->ht_root, &k); + if (h == NULL) { + return -1; + } else { + h->hn_active--; + if (h->hn_active == 0) { + (void) RBI_DELETE(ipf_rb, &htp->ht_root, h); + htp->ht_cur_nodes--; + KFREE(h); + } + } + + return 0; +} + + +/* ------------------------------------------------------------------------ */ +/* Function: ipf_rb_ht_init */ +/* Returns: Nil */ +/* Parameters: head(I) - pointer to host tracking structure */ +/* */ +/* Initialise the host tracking structure to be ready for use above. */ +/* ------------------------------------------------------------------------ */ +void +ipf_rb_ht_init(head) + host_track_t *head; +{ + RBI_INIT(ipf_rb, &head->ht_root); +} + + +/* ------------------------------------------------------------------------ */ +/* Function: ipf_rb_ht_freenode */ +/* Returns: Nil */ +/* Parameters: head(I) - pointer to host tracking structure */ +/* arg(I) - additional argument from walk caller */ +/* */ +/* Free an actual host_node_t structure. */ +/* ------------------------------------------------------------------------ */ +void +ipf_rb_ht_freenode(node, arg) + host_node_t *node; + void *arg; +{ + KFREE(node); +} + + +/* ------------------------------------------------------------------------ */ +/* Function: ipf_rb_ht_flush */ +/* Returns: Nil */ +/* Parameters: head(I) - pointer to host tracking structure */ +/* */ +/* Remove all of the nodes in the tree tracking hosts by calling a walker */ +/* and free'ing each one. */ +/* ------------------------------------------------------------------------ */ +void +ipf_rb_ht_flush(head) + host_track_t *head; +{ + RBI_WALK(ipf_rb, &head->ht_root, ipf_rb_ht_freenode, NULL); +} + + +/* ------------------------------------------------------------------------ */ +/* Function: ipf_slowtimer */ +/* Returns: Nil */ +/* Parameters: ptr(I) - pointer to main ipf soft context structure */ +/* */ +/* Slowly expire held state for fragments. Timeouts are set * in */ +/* expectation of this being called twice per second. */ +/* ------------------------------------------------------------------------ */ +void +ipf_slowtimer(softc) + ipf_main_softc_t *softc; +{ + + ipf_token_expire(softc); + ipf_frag_expire(softc); + ipf_state_expire(softc); + ipf_nat_expire(softc); + ipf_auth_expire(softc); + ipf_lookup_expire(softc); + ipf_rule_expire(softc); + ipf_sync_expire(softc); + softc->ipf_ticks++; +# if defined(__OpenBSD__) + timeout_add(&ipf_slowtimer_ch, hz/2); +# endif +} + + +/* ------------------------------------------------------------------------ */ +/* Function: ipf_inet_mask_add */ +/* Returns: Nil */ +/* Parameters: bits(I) - pointer to nat context information */ +/* mtab(I) - pointer to mask hash table structure */ +/* */ +/* When called, bits represents the mask of a new NAT rule that has just */ +/* been added. This function inserts a bitmask into the array of masks to */ +/* search when searching for a matching NAT rule for a packet. */ +/* Prevention of duplicate masks is achieved by checking the use count for */ +/* a given netmask. */ +/* ------------------------------------------------------------------------ */ +void +ipf_inet_mask_add(bits, mtab) + int bits; + ipf_v4_masktab_t *mtab; +{ + u_32_t mask; + int i, j; + + mtab->imt4_masks[bits]++; + if (mtab->imt4_masks[bits] > 1) + return; + + if (bits == 0) + mask = 0; + else + mask = 0xffffffff << (32 - bits); + + for (i = 0; i < 33; i++) { + if (ntohl(mtab->imt4_active[i]) < mask) { + for (j = 32; j > i; j--) + mtab->imt4_active[j] = mtab->imt4_active[j - 1]; + mtab->imt4_active[i] = htonl(mask); + break; + } + } + mtab->imt4_max++; +} + + +/* ------------------------------------------------------------------------ */ +/* Function: ipf_inet_mask_del */ +/* Returns: Nil */ +/* Parameters: bits(I) - number of bits set in the netmask */ +/* mtab(I) - pointer to mask hash table structure */ +/* */ +/* Remove the 32bit bitmask represented by "bits" from the collection of */ +/* netmasks stored inside of mtab. */ +/* ------------------------------------------------------------------------ */ +void +ipf_inet_mask_del(bits, mtab) + int bits; + ipf_v4_masktab_t *mtab; +{ + u_32_t mask; + int i, j; + + mtab->imt4_masks[bits]--; + if (mtab->imt4_masks[bits] > 0) + return; + + mask = htonl(0xffffffff << (32 - bits)); + for (i = 0; i < 33; i++) { + if (mtab->imt4_active[i] == mask) { + for (j = i + 1; j < 33; j++) + mtab->imt4_active[j - 1] = mtab->imt4_active[j]; + break; + } + } + mtab->imt4_max--; + ASSERT(mtab->imt4_max >= 0); +} + + +#ifdef USE_INET6 +/* ------------------------------------------------------------------------ */ +/* Function: ipf_inet6_mask_add */ +/* Returns: Nil */ +/* Parameters: bits(I) - number of bits set in mask */ +/* mask(I) - pointer to mask to add */ +/* mtab(I) - pointer to mask hash table structure */ +/* */ +/* When called, bitcount represents the mask of a IPv6 NAT map rule that */ +/* has just been added. This function inserts a bitmask into the array of */ +/* masks to search when searching for a matching NAT rule for a packet. */ +/* Prevention of duplicate masks is achieved by checking the use count for */ +/* a given netmask. */ +/* ------------------------------------------------------------------------ */ +void +ipf_inet6_mask_add(bits, mask, mtab) + int bits; + i6addr_t *mask; + ipf_v6_masktab_t *mtab; +{ + i6addr_t zero; + int i, j; + + mtab->imt6_masks[bits]++; + if (mtab->imt6_masks[bits] > 1) + return; + + if (bits == 0) { + mask = &zero; + zero.i6[0] = 0; + zero.i6[1] = 0; + zero.i6[2] = 0; + zero.i6[3] = 0; + } + + for (i = 0; i < 129; i++) { + if (IP6_LT(&mtab->imt6_active[i], mask)) { + for (j = 128; j > i; j--) + mtab->imt6_active[j] = mtab->imt6_active[j - 1]; + mtab->imt6_active[i] = *mask; + break; + } + } + mtab->imt6_max++; +} + + +/* ------------------------------------------------------------------------ */ +/* Function: ipf_inet6_mask_del */ +/* Returns: Nil */ +/* Parameters: bits(I) - number of bits set in mask */ +/* mask(I) - pointer to mask to remove */ +/* mtab(I) - pointer to mask hash table structure */ +/* */ +/* Remove the 128bit bitmask represented by "bits" from the collection of */ +/* netmasks stored inside of mtab. */ +/* ------------------------------------------------------------------------ */ +void +ipf_inet6_mask_del(bits, mask, mtab) + int bits; + i6addr_t *mask; + ipf_v6_masktab_t *mtab; +{ + i6addr_t zero; + int i, j; + + mtab->imt6_masks[bits]--; + if (mtab->imt6_masks[bits] > 0) + return; + + if (bits == 0) + mask = &zero; + zero.i6[0] = 0; + zero.i6[1] = 0; + zero.i6[2] = 0; + zero.i6[3] = 0; + + for (i = 0; i < 129; i++) { + if (IP6_EQ(&mtab->imt6_active[i], mask)) { + for (j = i + 1; j < 129; j++) { + mtab->imt6_active[j - 1] = mtab->imt6_active[j]; + if (IP6_EQ(&mtab->imt6_active[j - 1], &zero)) + break; + } + break; + } + } + mtab->imt6_max--; + ASSERT(mtab->imt6_max >= 0); +} +#endif diff --git a/sys/contrib/ipfilter/netinet/ip_auth.c b/sys/contrib/ipfilter/netinet/ip_auth.c index fcd891f7f94e..5a2ebeca5daf 100644 --- a/sys/contrib/ipfilter/netinet/ip_auth.c +++ b/sys/contrib/ipfilter/netinet/ip_auth.c @@ -1,7 +1,7 @@ /* $FreeBSD$ */ /* - * Copyright (C) 1998-2003 by Darren Reed & Guido van Rooij. + * Copyright (C) 2012 by Darren Reed. * * See the IPFILTER.LICENCE file for details on licencing. */ @@ -19,6 +19,9 @@ #if !defined(_KERNEL) # include # include +# ifdef _STDC_C99 +# include +# endif # include # define _KERNEL # ifdef __OpenBSD__ @@ -52,7 +55,7 @@ struct file; # include # include #endif -#if (defined(_BSDI_VERSION) && _BSDI_VERSION >= 199802) || \ +#if (defined(_BSDI_VERSION) && (_BSDI_VERSION >= 199802)) || \ (defined(__FreeBSD_version) &&(__FreeBSD_version >= 400000)) # include #endif @@ -62,11 +65,14 @@ struct file; #if defined(_KERNEL) && defined(__NetBSD__) && (__NetBSD_Version__ >= 104000000) # include #endif +#if defined(__NetBSD_Version__) && (__NetBSD_Version__ >= 400000) && \ + !defined(_KERNEL) +# include +#endif #include #ifdef sun # include #endif -#include #include #include #include @@ -125,71 +131,249 @@ static const char rcsid[] = "@(#)$FreeBSD$"; #endif + +typedef struct ipf_auth_softc_s { #if SOLARIS && defined(_KERNEL) -extern kcondvar_t ipfauthwait; -extern struct pollhead iplpollhead[IPL_LOGSIZE]; + kcondvar_t ipf_auth_wait; #endif /* SOLARIS */ #if defined(linux) && defined(_KERNEL) -wait_queue_head_t fr_authnext_linux; + wait_queue_head_t ipf_auth_next_linux; #endif + ipfrwlock_t ipf_authlk; + ipfmutex_t ipf_auth_mx; + int ipf_auth_size; + int ipf_auth_used; + int ipf_auth_replies; + int ipf_auth_defaultage; + int ipf_auth_lock; + ipf_authstat_t ipf_auth_stats; + frauth_t *ipf_auth; + mb_t **ipf_auth_pkts; + int ipf_auth_start; + int ipf_auth_end; + int ipf_auth_next; + frauthent_t *ipf_auth_entries; + frentry_t *ipf_auth_ip; + frentry_t *ipf_auth_rules; +} ipf_auth_softc_t; -int fr_authsize = FR_NUMAUTH; -int fr_authused = 0; -int fr_defaultauthage = 600; -int fr_auth_lock = 0; -int fr_auth_init = 0; -fr_authstat_t fr_authstats; -static frauth_t *fr_auth = NULL; -mb_t **fr_authpkts = NULL; -int fr_authstart = 0, fr_authend = 0, fr_authnext = 0; -frauthent_t *fae_list = NULL; -frentry_t *ipauth = NULL, - *fr_authlist = NULL; -void fr_authderef __P((frauthent_t **)); -int fr_authgeniter __P((ipftoken_t *, ipfgeniter_t *)); -int fr_authreply __P((char *)); -int fr_authwait __P((char *)); +static void ipf_auth_deref __P((frauthent_t **)); +static void ipf_auth_deref_unlocked __P((ipf_auth_softc_t *, frauthent_t **)); +static int ipf_auth_geniter __P((ipf_main_softc_t *, ipftoken_t *, + ipfgeniter_t *, ipfobj_t *)); +static int ipf_auth_reply __P((ipf_main_softc_t *, ipf_auth_softc_t *, char *)); +static int ipf_auth_wait __P((ipf_main_softc_t *, ipf_auth_softc_t *, char *)); +static int ipf_auth_flush __P((void *)); + /* ------------------------------------------------------------------------ */ -/* Function: fr_authinit */ +/* Function: ipf_auth_main_load */ /* Returns: int - 0 == success, else error */ /* Parameters: None */ /* */ +/* A null-op function that exists as a placeholder so that the flow in */ +/* other functions is obvious. */ +/* ------------------------------------------------------------------------ */ +int +ipf_auth_main_load() +{ + return 0; +} + + +/* ------------------------------------------------------------------------ */ +/* Function: ipf_auth_main_unload */ +/* Returns: int - 0 == success, else error */ +/* Parameters: None */ +/* */ +/* A null-op function that exists as a placeholder so that the flow in */ +/* other functions is obvious. */ +/* ------------------------------------------------------------------------ */ +int +ipf_auth_main_unload() +{ + return 0; +} + + +/* ------------------------------------------------------------------------ */ +/* Function: ipf_auth_soft_create */ +/* Returns: int - NULL = failure, else success */ +/* Parameters: softc(I) - pointer to soft context data */ +/* */ +/* Create a structre to store all of the run-time data for packet auth in */ +/* and initialise some fields to their defaults. */ +/* ------------------------------------------------------------------------ */ +void * +ipf_auth_soft_create(softc) + ipf_main_softc_t *softc; +{ + ipf_auth_softc_t *softa; + + KMALLOC(softa, ipf_auth_softc_t *); + if (softa == NULL) + return NULL; + + bzero((char *)softa, sizeof(*softa)); + + softa->ipf_auth_size = FR_NUMAUTH; + softa->ipf_auth_defaultage = 600; + + RWLOCK_INIT(&softa->ipf_authlk, "ipf IP User-Auth rwlock"); + MUTEX_INIT(&softa->ipf_auth_mx, "ipf auth log mutex"); +#if SOLARIS && defined(_KERNEL) + cv_init(&softa->ipf_auth_wait, "ipf auth condvar", CV_DRIVER, NULL); +#endif + + return softa; +} + +/* ------------------------------------------------------------------------ */ +/* Function: ipf_auth_soft_init */ +/* Returns: int - 0 == success, else error */ +/* Parameters: softc(I) - pointer to soft context data */ +/* arg(I) - opaque pointer to auth context data */ +/* */ /* Allocate memory and initialise data structures used in handling auth */ /* rules. */ /* ------------------------------------------------------------------------ */ -int fr_authinit() +int +ipf_auth_soft_init(softc, arg) + ipf_main_softc_t *softc; + void *arg; { - KMALLOCS(fr_auth, frauth_t *, fr_authsize * sizeof(*fr_auth)); - if (fr_auth != NULL) - bzero((char *)fr_auth, fr_authsize * sizeof(*fr_auth)); - else + ipf_auth_softc_t *softa = arg; + + KMALLOCS(softa->ipf_auth, frauth_t *, + softa->ipf_auth_size * sizeof(*softa->ipf_auth)); + if (softa->ipf_auth == NULL) return -1; + bzero((char *)softa->ipf_auth, + softa->ipf_auth_size * sizeof(*softa->ipf_auth)); - KMALLOCS(fr_authpkts, mb_t **, fr_authsize * sizeof(*fr_authpkts)); - if (fr_authpkts != NULL) - bzero((char *)fr_authpkts, fr_authsize * sizeof(*fr_authpkts)); - else + KMALLOCS(softa->ipf_auth_pkts, mb_t **, + softa->ipf_auth_size * sizeof(*softa->ipf_auth_pkts)); + if (softa->ipf_auth_pkts == NULL) return -2; + bzero((char *)softa->ipf_auth_pkts, + softa->ipf_auth_size * sizeof(*softa->ipf_auth_pkts)); - MUTEX_INIT(&ipf_authmx, "ipf auth log mutex"); - RWLOCK_INIT(&ipf_auth, "ipf IP User-Auth rwlock"); -#if SOLARIS && defined(_KERNEL) - cv_init(&ipfauthwait, "ipf auth condvar", CV_DRIVER, NULL); -#endif #if defined(linux) && defined(_KERNEL) - init_waitqueue_head(&fr_authnext_linux); + init_waitqueue_head(&softa->ipf_auth_next_linux); #endif - fr_auth_init = 1; - return 0; } /* ------------------------------------------------------------------------ */ -/* Function: fr_checkauth */ +/* Function: ipf_auth_soft_fini */ +/* Returns: int - 0 == success, else error */ +/* Parameters: softc(I) - pointer to soft context data */ +/* arg(I) - opaque pointer to auth context data */ +/* */ +/* Free all network buffer memory used to keep saved packets that have been */ +/* connectedd to the soft soft context structure *but* do not free that: it */ +/* is free'd by _destroy(). */ +/* ------------------------------------------------------------------------ */ +int +ipf_auth_soft_fini(softc, arg) + ipf_main_softc_t *softc; + void *arg; +{ + ipf_auth_softc_t *softa = arg; + frauthent_t *fae, **faep; + frentry_t *fr, **frp; + mb_t *m; + int i; + + if (softa->ipf_auth != NULL) { + KFREES(softa->ipf_auth, + softa->ipf_auth_size * sizeof(*softa->ipf_auth)); + softa->ipf_auth = NULL; + } + + if (softa->ipf_auth_pkts != NULL) { + for (i = 0; i < softa->ipf_auth_size; i++) { + m = softa->ipf_auth_pkts[i]; + if (m != NULL) { + FREE_MB_T(m); + softa->ipf_auth_pkts[i] = NULL; + } + } + KFREES(softa->ipf_auth_pkts, + softa->ipf_auth_size * sizeof(*softa->ipf_auth_pkts)); + softa->ipf_auth_pkts = NULL; + } + + faep = &softa->ipf_auth_entries; + while ((fae = *faep) != NULL) { + *faep = fae->fae_next; + KFREE(fae); + } + softa->ipf_auth_ip = NULL; + + if (softa->ipf_auth_rules != NULL) { + for (frp = &softa->ipf_auth_rules; ((fr = *frp) != NULL); ) { + if (fr->fr_ref == 1) { + *frp = fr->fr_next; + MUTEX_DESTROY(&fr->fr_lock); + KFREE(fr); + } else + frp = &fr->fr_next; + } + } + + return 0; +} + + +/* ------------------------------------------------------------------------ */ +/* Function: ipf_auth_soft_destroy */ +/* Returns: void */ +/* Parameters: softc(I) - pointer to soft context data */ +/* arg(I) - opaque pointer to auth context data */ +/* */ +/* Undo what was done in _create() - i.e. free the soft context data. */ +/* ------------------------------------------------------------------------ */ +void +ipf_auth_soft_destroy(softc, arg) + ipf_main_softc_t *softc; + void *arg; +{ + ipf_auth_softc_t *softa = arg; + +# if SOLARIS && defined(_KERNEL) + cv_destroy(&softa->ipf_auth_wait); +# endif + MUTEX_DESTROY(&softa->ipf_auth_mx); + RW_DESTROY(&softa->ipf_authlk); + + KFREE(softa); +} + + +/* ------------------------------------------------------------------------ */ +/* Function: ipf_auth_setlock */ +/* Returns: void */ +/* Paramters: arg(I) - pointer to soft context data */ +/* tmp(I) - value to assign to auth lock */ +/* */ +/* ------------------------------------------------------------------------ */ +void +ipf_auth_setlock(arg, tmp) + void *arg; + int tmp; +{ + ipf_auth_softc_t *softa = arg; + + softa->ipf_auth_lock = tmp; +} + + +/* ------------------------------------------------------------------------ */ +/* Function: ipf_auth_check */ /* Returns: frentry_t* - pointer to ipf rule if match found, else NULL */ /* Parameters: fin(I) - pointer to ipftoken structure */ /* passp(I) - pointer to ipfgeniter structure */ @@ -198,10 +382,13 @@ int fr_authinit() /* authorization result and that would result in a feedback loop (i.e. it */ /* will end up returning FR_AUTH) then return FR_BLOCK instead. */ /* ------------------------------------------------------------------------ */ -frentry_t *fr_checkauth(fin, passp) -fr_info_t *fin; -u_32_t *passp; +frentry_t * +ipf_auth_check(fin, passp) + fr_info_t *fin; + u_32_t *passp; { + ipf_main_softc_t *softc = fin->fin_main_soft; + ipf_auth_softc_t *softa = softc->ipf_auth_soft; frentry_t *fr; frauth_t *fra; u_32_t pass; @@ -209,27 +396,29 @@ u_32_t *passp; ip_t *ip; int i; - if (fr_auth_lock || !fr_authused) + if (softa->ipf_auth_lock || !softa->ipf_auth_used) return NULL; ip = fin->fin_ip; id = ip->ip_id; - READ_ENTER(&ipf_auth); - for (i = fr_authstart; i != fr_authend; ) { + READ_ENTER(&softa->ipf_authlk); + for (i = softa->ipf_auth_start; i != softa->ipf_auth_end; ) { /* * index becomes -2 only after an SIOCAUTHW. Check this in * case the same packet gets sent again and it hasn't yet been * auth'd. */ - fra = fr_auth + i; + fra = softa->ipf_auth + i; if ((fra->fra_index == -2) && (id == fra->fra_info.fin_id) && !bcmp((char *)fin, (char *)&fra->fra_info, FI_CSIZE)) { /* * Avoid feedback loop. */ - if (!(pass = fra->fra_pass) || (FR_ISAUTH(pass))) + if (!(pass = fra->fra_pass) || (FR_ISAUTH(pass))) { pass = FR_BLOCK; + fin->fin_reason = FRB_AUTHFEEDBACK; + } /* * Create a dummy rule for the stateful checking to * use and return. Zero out any values we don't @@ -249,60 +438,65 @@ u_32_t *passp; fr->fr_ifas[1] = NULL; fr->fr_ifas[2] = NULL; fr->fr_ifas[3] = NULL; + MUTEX_INIT(&fr->fr_lock, + "ipf auth rule"); } } else fr = fra->fra_info.fin_fr; fin->fin_fr = fr; - RWLOCK_EXIT(&ipf_auth); + fin->fin_flx |= fra->fra_flx; + RWLOCK_EXIT(&softa->ipf_authlk); - WRITE_ENTER(&ipf_auth); + WRITE_ENTER(&softa->ipf_authlk); /* - * fr_authlist is populated with the rules malloc'd + * ipf_auth_rules is populated with the rules malloc'd * above and only those. */ if ((fr != NULL) && (fr != fra->fra_info.fin_fr)) { - fr->fr_next = fr_authlist; - fr_authlist = fr; + fr->fr_next = softa->ipf_auth_rules; + softa->ipf_auth_rules = fr; } - fr_authstats.fas_hits++; + softa->ipf_auth_stats.fas_hits++; fra->fra_index = -1; - fr_authused--; - if (i == fr_authstart) { + softa->ipf_auth_used--; + softa->ipf_auth_replies--; + if (i == softa->ipf_auth_start) { while (fra->fra_index == -1) { i++; fra++; - if (i == fr_authsize) { + if (i == softa->ipf_auth_size) { i = 0; - fra = fr_auth; + fra = softa->ipf_auth; } - fr_authstart = i; - if (i == fr_authend) + softa->ipf_auth_start = i; + if (i == softa->ipf_auth_end) break; } - if (fr_authstart == fr_authend) { - fr_authnext = 0; - fr_authstart = fr_authend = 0; + if (softa->ipf_auth_start == + softa->ipf_auth_end) { + softa->ipf_auth_next = 0; + softa->ipf_auth_start = 0; + softa->ipf_auth_end = 0; } } - RWLOCK_EXIT(&ipf_auth); + RWLOCK_EXIT(&softa->ipf_authlk); if (passp != NULL) *passp = pass; - ATOMIC_INC64(fr_authstats.fas_hits); + softa->ipf_auth_stats.fas_hits++; return fr; } i++; - if (i == fr_authsize) + if (i == softa->ipf_auth_size) i = 0; } - fr_authstats.fas_miss++; - RWLOCK_EXIT(&ipf_auth); - ATOMIC_INC64(fr_authstats.fas_miss); + RWLOCK_EXIT(&softa->ipf_authlk); + softa->ipf_auth_stats.fas_miss++; return NULL; } /* ------------------------------------------------------------------------ */ -/* Function: fr_newauth */ +/* Function: ipf_auth_new */ /* Returns: int - 1 == success, 0 = did not put packet on auth queue */ /* Parameters: m(I) - pointer to mb_t with packet in it */ /* fin(I) - pointer to packet information */ @@ -311,10 +505,13 @@ u_32_t *passp; /* packet. If we do, store it and wake up any user programs which are */ /* waiting to hear about these events. */ /* ------------------------------------------------------------------------ */ -int fr_newauth(m, fin) -mb_t *m; -fr_info_t *fin; +int +ipf_auth_new(m, fin) + mb_t *m; + fr_info_t *fin; { + ipf_main_softc_t *softc = fin->fin_main_soft; + ipf_auth_softc_t *softa = softc->ipf_auth_soft; #if defined(_KERNEL) && defined(MENTAT) qpktinfo_t *qpi = fin->fin_qpi; #endif @@ -324,31 +521,33 @@ fr_info_t *fin; #endif int i; - if (fr_auth_lock) + if (softa->ipf_auth_lock) return 0; - WRITE_ENTER(&ipf_auth); - if (((fr_authend + 1) % fr_authsize) == fr_authstart) { - fr_authstats.fas_nospace++; - RWLOCK_EXIT(&ipf_auth); + WRITE_ENTER(&softa->ipf_authlk); + if (((softa->ipf_auth_end + 1) % softa->ipf_auth_size) == + softa->ipf_auth_start) { + softa->ipf_auth_stats.fas_nospace++; + RWLOCK_EXIT(&softa->ipf_authlk); return 0; } - fr_authstats.fas_added++; - fr_authused++; - i = fr_authend++; - if (fr_authend == fr_authsize) - fr_authend = 0; - fra = fr_auth + i; - fra->fra_index = i; - RWLOCK_EXIT(&ipf_auth); + softa->ipf_auth_stats.fas_added++; + softa->ipf_auth_used++; + i = softa->ipf_auth_end++; + if (softa->ipf_auth_end == softa->ipf_auth_size) + softa->ipf_auth_end = 0; + fra = softa->ipf_auth + i; + fra->fra_index = i; if (fin->fin_fr != NULL) fra->fra_pass = fin->fin_fr->fr_flags; else fra->fra_pass = 0; - fra->fra_age = fr_defaultauthage; + fra->fra_age = softa->ipf_auth_defaultage; bcopy((char *)fin, (char *)&fra->fra_info, sizeof(*fin)); + fra->fra_flx = fra->fra_info.fin_flx & (FI_STATE|FI_NATED); + fra->fra_info.fin_flx &= ~(FI_STATE|FI_NATED); #if !defined(sparc) && !defined(m68k) /* * No need to copyback here as we want to undo the changes, not keep @@ -370,24 +569,24 @@ fr_info_t *fin; #if SOLARIS && defined(_KERNEL) COPYIFNAME(fin->fin_v, fin->fin_ifp, fra->fra_info.fin_ifname); m->b_rptr -= qpi->qpi_off; - fr_authpkts[i] = *(mblk_t **)fin->fin_mp; -# if !defined(_INET_IP_STACK_H) fra->fra_q = qpi->qpi_q; /* The queue can disappear! */ -# endif fra->fra_m = *fin->fin_mp; fra->fra_info.fin_mp = &fra->fra_m; - cv_signal(&ipfauthwait); - pollwakeup(&iplpollhead[IPL_LOGAUTH], POLLIN|POLLRDNORM); + softa->ipf_auth_pkts[i] = *(mblk_t **)fin->fin_mp; + RWLOCK_EXIT(&softa->ipf_authlk); + cv_signal(&softa->ipf_auth_wait); + pollwakeup(&softc->ipf_poll_head[IPL_LOGAUTH], POLLIN|POLLRDNORM); #else - fr_authpkts[i] = m; - WAKEUP(&fr_authnext,0); + softa->ipf_auth_pkts[i] = m; + RWLOCK_EXIT(&softa->ipf_authlk); + WAKEUP(&softa->ipf_auth_next, 0); #endif return 1; } /* ------------------------------------------------------------------------ */ -/* Function: fr_auth_ioctl */ +/* Function: ipf_auth_ioctl */ /* Returns: int - 0 == success, else error */ /* Parameters: data(IO) - pointer to ioctl data */ /* cmd(I) - ioctl command */ @@ -396,14 +595,17 @@ fr_info_t *fin; /* ctx(I) - pointer for context */ /* */ /* This function handles all of the ioctls recognised by the auth component */ -/* in IPFilter - ie ioctls called on an open fd for /dev/ipauth */ +/* in IPFilter - ie ioctls called on an open fd for /dev/ipf_auth */ /* ------------------------------------------------------------------------ */ -int fr_auth_ioctl(data, cmd, mode, uid, ctx) -caddr_t data; -ioctlcmd_t cmd; -int mode, uid; -void *ctx; +int +ipf_auth_ioctl(softc, data, cmd, mode, uid, ctx) + ipf_main_softc_t *softc; + caddr_t data; + ioctlcmd_t cmd; + int mode, uid; + void *ctx; { + ipf_auth_softc_t *softa = softc->ipf_auth_soft; int error = 0, i; SPL_INT(s); @@ -413,18 +615,23 @@ void *ctx; { ipftoken_t *token; ipfgeniter_t iter; + ipfobj_t obj; - error = fr_inobj(data, &iter, IPFOBJ_GENITER); + error = ipf_inobj(softc, data, &obj, &iter, IPFOBJ_GENITER); if (error != 0) break; SPL_SCHED(s); - token = ipf_findtoken(IPFGENITER_AUTH, uid, ctx); + token = ipf_token_find(softc, IPFGENITER_AUTH, uid, ctx); if (token != NULL) - error = fr_authgeniter(token, &iter); - else + error = ipf_auth_geniter(softc, token, &iter, &obj); + else { + WRITE_ENTER(&softc->ipf_tokens); + ipf_token_deref(softc, token); + RWLOCK_EXIT(&softc->ipf_tokens); + IPFERROR(10001); error = ESRCH; - RWLOCK_EXIT(&ipf_tokens); + } SPL_X(s); break; @@ -432,46 +639,52 @@ void *ctx; case SIOCADAFR : case SIOCRMAFR : - if (!(mode & FWRITE)) + if (!(mode & FWRITE)) { + IPFERROR(10002); error = EPERM; - else - error = frrequest(IPL_LOGAUTH, cmd, data, - fr_active, 1); + } else + error = frrequest(softc, IPL_LOGAUTH, cmd, data, + softc->ipf_active, 1); break; case SIOCSTLCK : if (!(mode & FWRITE)) { + IPFERROR(10003); error = EPERM; - break; + } else { + error = ipf_lock(data, &softa->ipf_auth_lock); } - error = fr_lock(data, &fr_auth_lock); break; case SIOCATHST: - fr_authstats.fas_faelist = fae_list; - error = fr_outobj(data, &fr_authstats, IPFOBJ_AUTHSTAT); + softa->ipf_auth_stats.fas_faelist = softa->ipf_auth_entries; + error = ipf_outobj(softc, data, &softa->ipf_auth_stats, + IPFOBJ_AUTHSTAT); break; case SIOCIPFFL: SPL_NET(s); - WRITE_ENTER(&ipf_auth); - i = fr_authflush(); - RWLOCK_EXIT(&ipf_auth); + WRITE_ENTER(&softa->ipf_authlk); + i = ipf_auth_flush(softa); + RWLOCK_EXIT(&softa->ipf_authlk); SPL_X(s); - error = BCOPYOUT((char *)&i, data, sizeof(i)); - if (error != 0) + error = BCOPYOUT(&i, data, sizeof(i)); + if (error != 0) { + IPFERROR(10004); error = EFAULT; + } break; case SIOCAUTHW: - error = fr_authwait(data); + error = ipf_auth_wait(softc, softa, data); break; case SIOCAUTHR: - error = fr_authreply(data); + error = ipf_auth_reply(softc, softa, data); break; default : + IPFERROR(10005); error = EINVAL; break; } @@ -480,75 +693,18 @@ void *ctx; /* ------------------------------------------------------------------------ */ -/* Function: fr_authunload */ -/* Returns: None */ -/* Parameters: None */ -/* */ -/* Free all network buffer memory used to keep saved packets. */ -/* ------------------------------------------------------------------------ */ -void fr_authunload() -{ - register int i; - register frauthent_t *fae, **faep; - frentry_t *fr, **frp; - mb_t *m; - - if (fr_auth != NULL) { - KFREES(fr_auth, fr_authsize * sizeof(*fr_auth)); - fr_auth = NULL; - } - - if (fr_authpkts != NULL) { - for (i = 0; i < fr_authsize; i++) { - m = fr_authpkts[i]; - if (m != NULL) { - FREE_MB_T(m); - fr_authpkts[i] = NULL; - } - } - KFREES(fr_authpkts, fr_authsize * sizeof(*fr_authpkts)); - fr_authpkts = NULL; - } - - faep = &fae_list; - while ((fae = *faep) != NULL) { - *faep = fae->fae_next; - KFREE(fae); - } - ipauth = NULL; - - if (fr_authlist != NULL) { - for (frp = &fr_authlist; ((fr = *frp) != NULL); ) { - if (fr->fr_ref == 1) { - *frp = fr->fr_next; - KFREE(fr); - } else - frp = &fr->fr_next; - } - } - - if (fr_auth_init == 1) { -# if SOLARIS && defined(_KERNEL) - cv_destroy(&ipfauthwait); -# endif - MUTEX_DESTROY(&ipf_authmx); - RW_DESTROY(&ipf_auth); - - fr_auth_init = 0; - } -} - - -/* ------------------------------------------------------------------------ */ -/* Function: fr_authexpire */ +/* Function: ipf_auth_expire */ /* Returns: None */ /* Parameters: None */ /* */ /* Slowly expire held auth records. Timeouts are set in expectation of */ /* this being called twice per second. */ /* ------------------------------------------------------------------------ */ -void fr_authexpire() +void +ipf_auth_expire(softc) + ipf_main_softc_t *softc; { + ipf_auth_softc_t *softa = softc->ipf_auth_soft; frauthent_t *fae, **faep; frentry_t *fr, **frp; frauth_t *fra; @@ -556,70 +712,81 @@ void fr_authexpire() int i; SPL_INT(s); - if (fr_auth_lock) + if (softa->ipf_auth_lock) return; - SPL_NET(s); - WRITE_ENTER(&ipf_auth); - for (i = 0, fra = fr_auth; i < fr_authsize; i++, fra++) { + WRITE_ENTER(&softa->ipf_authlk); + for (i = 0, fra = softa->ipf_auth; i < softa->ipf_auth_size; + i++, fra++) { fra->fra_age--; - if ((fra->fra_age == 0) && (m = fr_authpkts[i])) { - FREE_MB_T(m); - fr_authpkts[i] = NULL; - fr_auth[i].fra_index = -1; - fr_authstats.fas_expire++; - fr_authused--; + if ((fra->fra_age == 0) && + (softa->ipf_auth[i].fra_index != -1)) { + if ((m = softa->ipf_auth_pkts[i]) != NULL) { + FREE_MB_T(m); + softa->ipf_auth_pkts[i] = NULL; + } else if (softa->ipf_auth[i].fra_index == -2) { + softa->ipf_auth_replies--; + } + softa->ipf_auth[i].fra_index = -1; + softa->ipf_auth_stats.fas_expire++; + softa->ipf_auth_used--; } } /* * Expire pre-auth rules */ - for (faep = &fae_list; ((fae = *faep) != NULL); ) { + for (faep = &softa->ipf_auth_entries; ((fae = *faep) != NULL); ) { fae->fae_age--; if (fae->fae_age == 0) { - fr_authderef(&fae); - fr_authstats.fas_expire++; + ipf_auth_deref(&fae); + softa->ipf_auth_stats.fas_expire++; } else faep = &fae->fae_next; } - if (fae_list != NULL) - ipauth = &fae_list->fae_fr; + if (softa->ipf_auth_entries != NULL) + softa->ipf_auth_ip = &softa->ipf_auth_entries->fae_fr; else - ipauth = NULL; + softa->ipf_auth_ip = NULL; - for (frp = &fr_authlist; ((fr = *frp) != NULL); ) { + for (frp = &softa->ipf_auth_rules; ((fr = *frp) != NULL); ) { if (fr->fr_ref == 1) { *frp = fr->fr_next; + MUTEX_DESTROY(&fr->fr_lock); KFREE(fr); } else frp = &fr->fr_next; } - RWLOCK_EXIT(&ipf_auth); + RWLOCK_EXIT(&softa->ipf_authlk); SPL_X(s); } /* ------------------------------------------------------------------------ */ -/* Function: fr_preauthcmd */ +/* Function: ipf_auth_precmd */ /* Returns: int - 0 == success, else error */ /* Parameters: cmd(I) - ioctl command for rule */ /* fr(I) - pointer to ipf rule */ /* fptr(I) - pointer to caller's 'fr' */ /* */ /* ------------------------------------------------------------------------ */ -int fr_preauthcmd(cmd, fr, frptr) -ioctlcmd_t cmd; -frentry_t *fr, **frptr; +int +ipf_auth_precmd(softc, cmd, fr, frptr) + ipf_main_softc_t *softc; + ioctlcmd_t cmd; + frentry_t *fr, **frptr; { + ipf_auth_softc_t *softa = softc->ipf_auth_soft; frauthent_t *fae, **faep; int error = 0; SPL_INT(s); - if ((cmd != SIOCADAFR) && (cmd != SIOCRMAFR)) + if ((cmd != SIOCADAFR) && (cmd != SIOCRMAFR)) { + IPFERROR(10006); return EIO; + } - for (faep = &fae_list; ((fae = *faep) != NULL); ) { + for (faep = &softa->ipf_auth_entries; ((fae = *faep) != NULL); ) { if (&fae->fae_fr == fr) break; else @@ -627,17 +794,22 @@ frentry_t *fr, **frptr; } if (cmd == (ioctlcmd_t)SIOCRMAFR) { - if (fr == NULL || frptr == NULL) + if (fr == NULL || frptr == NULL) { + IPFERROR(10007); error = EINVAL; - else if (fae == NULL) + + } else if (fae == NULL) { + IPFERROR(10008); error = ESRCH; - else { + + } else { SPL_NET(s); - WRITE_ENTER(&ipf_auth); + WRITE_ENTER(&softa->ipf_authlk); *faep = fae->fae_next; - if (ipauth == &fae->fae_fr) - ipauth = fae_list ? &fae_list->fae_fr : NULL; - RWLOCK_EXIT(&ipf_auth); + if (softa->ipf_auth_ip == &fae->fae_fr) + softa->ipf_auth_ip = softa->ipf_auth_entries ? + &softa->ipf_auth_entries->fae_fr : NULL; + RWLOCK_EXIT(&softa->ipf_authlk); SPL_X(s); KFREE(fae); @@ -648,161 +820,199 @@ frentry_t *fr, **frptr; bcopy((char *)fr, (char *)&fae->fae_fr, sizeof(*fr)); SPL_NET(s); - WRITE_ENTER(&ipf_auth); - fae->fae_age = fr_defaultauthage; + WRITE_ENTER(&softa->ipf_authlk); + fae->fae_age = softa->ipf_auth_defaultage; fae->fae_fr.fr_hits = 0; fae->fae_fr.fr_next = *frptr; fae->fae_ref = 1; *frptr = &fae->fae_fr; fae->fae_next = *faep; *faep = fae; - ipauth = &fae_list->fae_fr; - RWLOCK_EXIT(&ipf_auth); + softa->ipf_auth_ip = &softa->ipf_auth_entries->fae_fr; + RWLOCK_EXIT(&softa->ipf_authlk); SPL_X(s); - } else + } else { + IPFERROR(10009); error = ENOMEM; - } else + } + } else { + IPFERROR(10010); error = EINVAL; + } return error; } /* ------------------------------------------------------------------------ */ -/* Function: fr_authflush */ +/* Function: ipf_auth_flush */ /* Returns: int - number of auth entries flushed */ /* Parameters: None */ -/* Locks: WRITE(ipf_auth) */ +/* Locks: WRITE(ipf_authlk) */ /* */ -/* This function flushs the fr_authpkts array of any packet data with */ +/* This function flushs the ipf_auth_pkts array of any packet data with */ /* references still there. */ /* It is expected that the caller has already acquired the correct locks or */ /* set the priority level correctly for this to block out other code paths */ /* into these data structures. */ /* ------------------------------------------------------------------------ */ -int fr_authflush() +static int +ipf_auth_flush(arg) + void *arg; { - register int i, num_flushed; + ipf_auth_softc_t *softa = arg; + int i, num_flushed; mb_t *m; - if (fr_auth_lock) + if (softa->ipf_auth_lock) return -1; num_flushed = 0; - for (i = 0 ; i < fr_authsize; i++) { - m = fr_authpkts[i]; - if (m != NULL) { - FREE_MB_T(m); - fr_authpkts[i] = NULL; - fr_auth[i].fra_index = -1; + for (i = 0 ; i < softa->ipf_auth_size; i++) { + if (softa->ipf_auth[i].fra_index != -1) { + m = softa->ipf_auth_pkts[i]; + if (m != NULL) { + FREE_MB_T(m); + softa->ipf_auth_pkts[i] = NULL; + } + + softa->ipf_auth[i].fra_index = -1; /* perhaps add & use a flush counter inst.*/ - fr_authstats.fas_expire++; - fr_authused--; + softa->ipf_auth_stats.fas_expire++; num_flushed++; } } - fr_authstart = 0; - fr_authend = 0; - fr_authnext = 0; + softa->ipf_auth_start = 0; + softa->ipf_auth_end = 0; + softa->ipf_auth_next = 0; + softa->ipf_auth_used = 0; + softa->ipf_auth_replies = 0; return num_flushed; } /* ------------------------------------------------------------------------ */ -/* Function: fr_auth_waiting */ -/* Returns: int - 0 = no packets waiting, 1 = packets waiting. */ +/* Function: ipf_auth_waiting */ +/* Returns: int - number of packets in the auth queue */ /* Parameters: None */ /* */ /* Simple truth check to see if there are any packets waiting in the auth */ /* queue. */ /* ------------------------------------------------------------------------ */ -int fr_auth_waiting() +int +ipf_auth_waiting(softc) + ipf_main_softc_t *softc; { - return (fr_authused != 0); + ipf_auth_softc_t *softa = softc->ipf_auth_soft; + + return (softa->ipf_auth_used != 0); } /* ------------------------------------------------------------------------ */ -/* Function: fr_authgeniter */ +/* Function: ipf_auth_geniter */ /* Returns: int - 0 == success, else error */ /* Parameters: token(I) - pointer to ipftoken structure */ /* itp(I) - pointer to ipfgeniter structure */ +/* objp(I) - pointer to ipf object destription */ /* */ +/* Iterate through the list of entries in the auth queue list. */ +/* objp is used here to get the location of where to do the copy out to. */ +/* Stomping over various fields with new information will not harm anything */ /* ------------------------------------------------------------------------ */ -int fr_authgeniter(token, itp) -ipftoken_t *token; -ipfgeniter_t *itp; +static int +ipf_auth_geniter(softc, token, itp, objp) + ipf_main_softc_t *softc; + ipftoken_t *token; + ipfgeniter_t *itp; + ipfobj_t *objp; { + ipf_auth_softc_t *softa = softc->ipf_auth_soft; frauthent_t *fae, *next, zero; int error; - if (itp->igi_data == NULL) + if (itp->igi_data == NULL) { + IPFERROR(10011); return EFAULT; + } - if (itp->igi_type != IPFGENITER_AUTH) + if (itp->igi_type != IPFGENITER_AUTH) { + IPFERROR(10012); return EINVAL; + } + + objp->ipfo_type = IPFOBJ_FRAUTH; + objp->ipfo_ptr = itp->igi_data; + objp->ipfo_size = sizeof(frauth_t); + + READ_ENTER(&softa->ipf_authlk); fae = token->ipt_data; - READ_ENTER(&ipf_auth); if (fae == NULL) { - next = fae_list; + next = softa->ipf_auth_entries; } else { next = fae->fae_next; } + /* + * If we found an auth entry to use, bump its reference count + * so that it can be used for is_next when we come back. + */ if (next != NULL) { - /* - * If we find an auth entry to use, bump its reference count - * so that it can be used for is_next when we come back. - */ ATOMIC_INC(next->fae_ref); - if (next->fae_next == NULL) { - ipf_freetoken(token); - token = NULL; - } else { - token->ipt_data = next; - } + token->ipt_data = next; } else { bzero(&zero, sizeof(zero)); next = &zero; - } - RWLOCK_EXIT(&ipf_auth); - - /* - * If we had a prior pointer to an auth entry, release it. - */ - if (fae != NULL) { - WRITE_ENTER(&ipf_auth); - fr_authderef(&fae); - RWLOCK_EXIT(&ipf_auth); + token->ipt_data = NULL; } - /* - * This should arguably be via fr_outobj() so that the auth - * structure can (if required) be massaged going out. - */ - error = COPYOUT(next, itp->igi_data, sizeof(*next)); - if (error != 0) - error = EFAULT; + RWLOCK_EXIT(&softa->ipf_authlk); + error = ipf_outobjk(softc, objp, next); + if (fae != NULL) + ipf_auth_deref_unlocked(softa, &fae); + + if (next->fae_next == NULL) + ipf_token_mark_complete(token); return error; } /* ------------------------------------------------------------------------ */ -/* Function: fr_authderef */ +/* Function: ipf_auth_deref_unlocked */ /* Returns: None */ /* Parameters: faep(IO) - pointer to caller's frauthent_t pointer */ -/* Locks: WRITE(ipf_auth) */ +/* */ +/* Wrapper for ipf_auth_deref for when a write lock on ipf_authlk is not */ +/* held. */ +/* ------------------------------------------------------------------------ */ +static void +ipf_auth_deref_unlocked(softa, faep) + ipf_auth_softc_t *softa; + frauthent_t **faep; +{ + WRITE_ENTER(&softa->ipf_authlk); + ipf_auth_deref(faep); + RWLOCK_EXIT(&softa->ipf_authlk); +} + + +/* ------------------------------------------------------------------------ */ +/* Function: ipf_auth_deref */ +/* Returns: None */ +/* Parameters: faep(IO) - pointer to caller's frauthent_t pointer */ +/* Locks: WRITE(ipf_authlk) */ /* */ /* This function unconditionally sets the pointer in the caller to NULL, */ /* to make it clear that it should no longer use that pointer, and drops */ /* the reference count on the structure by 1. If it reaches 0, free it up. */ /* ------------------------------------------------------------------------ */ -void fr_authderef(faep) -frauthent_t **faep; +static void +ipf_auth_deref(faep) + frauthent_t **faep; { frauthent_t *fae; @@ -817,30 +1027,30 @@ frauthent_t **faep; /* ------------------------------------------------------------------------ */ -/* Function: fr_authwait */ +/* Function: ipf_auth_wait_pkt */ /* Returns: int - 0 == success, else error */ /* Parameters: data(I) - pointer to data from ioctl call */ /* */ /* This function is called when an application is waiting for a packet to */ /* match an "auth" rule by issuing an SIOCAUTHW ioctl. If there is already */ /* a packet waiting on the queue then we will return that _one_ immediately.*/ -/* If there are no packets present in the queue (fr_authpkts) then we go to */ -/* sleep. */ +/* If there are no packets present in the queue (ipf_auth_pkts) then we go */ +/* to sleep. */ /* ------------------------------------------------------------------------ */ -int fr_authwait(data) -char *data; +static int +ipf_auth_wait(softc, softa, data) + ipf_main_softc_t *softc; + ipf_auth_softc_t *softa; + char *data; { frauth_t auth, *au = &auth; int error, len, i; mb_t *m; char *t; -#if defined(_KERNEL) && !defined(MENTAT) && !defined(linux) && \ - (!defined(__FreeBSD_version) || (__FreeBSD_version < 501000)) SPL_INT(s); -#endif -fr_authioctlloop: - error = fr_inobj(data, au, IPFOBJ_FRAUTH); +ipf_auth_ioctlloop: + error = ipf_inobj(softc, data, NULL, au, IPFOBJ_FRAUTH); if (error != 0) return error; @@ -850,30 +1060,36 @@ char *data; * we are trying to guard against here is an error in the copyout * steps should not cause the packet to "disappear" from the queue. */ - READ_ENTER(&ipf_auth); + SPL_NET(s); + READ_ENTER(&softa->ipf_authlk); /* - * If fr_authnext is not equal to fr_authend it will be because there - * is a packet waiting to be delt with in the fr_authpkts array. We - * copy as much of that out to user space as requested. + * If ipf_auth_next is not equal to ipf_auth_end it will be because + * there is a packet waiting to be delt with in the ipf_auth_pkts + * array. We copy as much of that out to user space as requested. */ - if (fr_authused > 0) { - while (fr_authpkts[fr_authnext] == NULL) { - fr_authnext++; - if (fr_authnext == fr_authsize) - fr_authnext = 0; + if (softa->ipf_auth_used > 0) { + while (softa->ipf_auth_pkts[softa->ipf_auth_next] == NULL) { + softa->ipf_auth_next++; + if (softa->ipf_auth_next == softa->ipf_auth_size) + softa->ipf_auth_next = 0; } - error = fr_outobj(data, &fr_auth[fr_authnext], IPFOBJ_FRAUTH); - if (error != 0) + error = ipf_outobj(softc, data, + &softa->ipf_auth[softa->ipf_auth_next], + IPFOBJ_FRAUTH); + if (error != 0) { + RWLOCK_EXIT(&softa->ipf_authlk); + SPL_X(s); return error; + } if (auth.fra_len != 0 && auth.fra_buf != NULL) { /* * Copy packet contents out to user space if * requested. Bail on an error. */ - m = fr_authpkts[fr_authnext]; + m = softa->ipf_auth_pkts[softa->ipf_auth_next]; len = MSGDSIZE(m); if (len > auth.fra_len) len = auth.fra_len; @@ -881,62 +1097,69 @@ char *data; for (t = auth.fra_buf; m && (len > 0); ) { i = MIN(M_LEN(m), len); - error = copyoutptr(MTOD(m, char *), &t, i); + error = copyoutptr(softc, MTOD(m, char *), + &t, i); len -= i; t += i; - if (error != 0) + if (error != 0) { + RWLOCK_EXIT(&softa->ipf_authlk); + SPL_X(s); return error; + } m = m->m_next; } } - RWLOCK_EXIT(&ipf_auth); + RWLOCK_EXIT(&softa->ipf_authlk); SPL_NET(s); - WRITE_ENTER(&ipf_auth); - fr_authnext++; - if (fr_authnext == fr_authsize) - fr_authnext = 0; - RWLOCK_EXIT(&ipf_auth); + WRITE_ENTER(&softa->ipf_authlk); + softa->ipf_auth_next++; + if (softa->ipf_auth_next == softa->ipf_auth_size) + softa->ipf_auth_next = 0; + RWLOCK_EXIT(&softa->ipf_authlk); SPL_X(s); return 0; } - RWLOCK_EXIT(&ipf_auth); + RWLOCK_EXIT(&softa->ipf_authlk); + SPL_X(s); - MUTEX_ENTER(&ipf_authmx); + MUTEX_ENTER(&softa->ipf_auth_mx); #ifdef _KERNEL # if SOLARIS error = 0; - if (!cv_wait_sig(&ipfauthwait, &ipf_authmx.ipf_lk)) + if (!cv_wait_sig(&softa->ipf_auth_wait, &softa->ipf_auth_mx.ipf_lk)) { + IPFERROR(10014); error = EINTR; + } # else /* SOLARIS */ # ifdef __hpux { lock_t *l; - l = get_sleep_lock(&fr_authnext); - error = sleep(&fr_authnext, PZERO+1); + l = get_sleep_lock(&softa->ipf_auth_next); + error = sleep(&softa->ipf_auth_next, PZERO+1); spinunlock(l); } # else # ifdef __osf__ - error = mpsleep(&fr_authnext, PSUSP|PCATCH, "fr_authnext", 0, - &ipf_authmx, MS_LOCK_SIMPLE); + error = mpsleep(&softa->ipf_auth_next, PSUSP|PCATCH, "ipf_auth_next", + 0, &softa->ipf_auth_mx, MS_LOCK_SIMPLE); # else - error = SLEEP(&fr_authnext, "fr_authnext"); + error = SLEEP(&softa->ipf_auth_next, "ipf_auth_next"); # endif /* __osf__ */ # endif /* __hpux */ # endif /* SOLARIS */ #endif - MUTEX_EXIT(&ipf_authmx); + MUTEX_EXIT(&softa->ipf_auth_mx); if (error == 0) - goto fr_authioctlloop; + goto ipf_auth_ioctlloop; return error; } /* ------------------------------------------------------------------------ */ -/* Function: fr_authreply */ +/* Function: ipf_auth_reply */ /* Returns: int - 0 == success, else error */ /* Parameters: data(I) - pointer to data from ioctl call */ /* */ @@ -945,23 +1168,27 @@ char *data; /* received information using an SIOCAUTHW. The decision returned in the */ /* form of flags, the same as those used in each rule. */ /* ------------------------------------------------------------------------ */ -int fr_authreply(data) -char *data; +static int +ipf_auth_reply(softc, softa, data) + ipf_main_softc_t *softc; + ipf_auth_softc_t *softa; + char *data; { frauth_t auth, *au = &auth, *fra; + fr_info_t fin; int error, i; mb_t *m; SPL_INT(s); - error = fr_inobj(data, &auth, IPFOBJ_FRAUTH); + error = ipf_inobj(softc, data, NULL, &auth, IPFOBJ_FRAUTH); if (error != 0) return error; SPL_NET(s); - WRITE_ENTER(&ipf_auth); + WRITE_ENTER(&softa->ipf_authlk); i = au->fra_index; - fra = fr_auth + i; + fra = softa->ipf_auth + i; error = 0; /* @@ -969,19 +1196,27 @@ char *data; * checks. First, the auth index value should be within the size of * the array and second the packet id being returned should also match. */ - if ((i < 0) || (i >= fr_authsize) || - (fra->fra_info.fin_id != au->fra_info.fin_id)) { - RWLOCK_EXIT(&ipf_auth); + if ((i < 0) || (i >= softa->ipf_auth_size)) { + RWLOCK_EXIT(&softa->ipf_authlk); SPL_X(s); + IPFERROR(10015); + return ESRCH; + } + if (fra->fra_info.fin_id != au->fra_info.fin_id) { + RWLOCK_EXIT(&softa->ipf_authlk); + SPL_X(s); + IPFERROR(10019); return ESRCH; } - m = fr_authpkts[i]; + m = softa->ipf_auth_pkts[i]; fra->fra_index = -2; fra->fra_pass = au->fra_pass; - fr_authpkts[i] = NULL; + softa->ipf_auth_pkts[i] = NULL; + softa->ipf_auth_replies++; + bcopy(&fra->fra_info, &fin, sizeof(fin)); - RWLOCK_EXIT(&ipf_auth); + RWLOCK_EXIT(&softa->ipf_authlk); /* * Re-insert the packet back into the packet stream flowing through @@ -992,22 +1227,25 @@ char *data; */ #ifdef _KERNEL if ((m != NULL) && (au->fra_info.fin_out != 0)) { - error = ipf_inject(&fra->fra_info, m); + error = ipf_inject(&fin, m); if (error != 0) { + IPFERROR(10016); error = ENOBUFS; - fr_authstats.fas_sendfail++; + softa->ipf_auth_stats.fas_sendfail++; } else { - fr_authstats.fas_sendok++; + softa->ipf_auth_stats.fas_sendok++; } } else if (m) { - error = ipf_inject(&fra->fra_info, m); + error = ipf_inject(&fin, m); if (error != 0) { + IPFERROR(10017); error = ENOBUFS; - fr_authstats.fas_quefail++; + softa->ipf_auth_stats.fas_quefail++; } else { - fr_authstats.fas_queok++; + softa->ipf_auth_stats.fas_queok++; } } else { + IPFERROR(10018); error = EINVAL; } @@ -1016,28 +1254,54 @@ char *data; * not being processed, make sure we advance to the next one. */ if (error == ENOBUFS) { - WRITE_ENTER(&ipf_auth); - fr_authused--; + WRITE_ENTER(&softa->ipf_authlk); + softa->ipf_auth_used--; fra->fra_index = -1; fra->fra_pass = 0; - if (i == fr_authstart) { + if (i == softa->ipf_auth_start) { while (fra->fra_index == -1) { i++; - if (i == fr_authsize) + if (i == softa->ipf_auth_size) i = 0; - fr_authstart = i; - if (i == fr_authend) + softa->ipf_auth_start = i; + if (i == softa->ipf_auth_end) break; } - if (fr_authstart == fr_authend) { - fr_authnext = 0; - fr_authstart = fr_authend = 0; + if (softa->ipf_auth_start == softa->ipf_auth_end) { + softa->ipf_auth_next = 0; + softa->ipf_auth_start = 0; + softa->ipf_auth_end = 0; } } - RWLOCK_EXIT(&ipf_auth); + RWLOCK_EXIT(&softa->ipf_authlk); } #endif /* _KERNEL */ SPL_X(s); return 0; } + + +u_32_t +ipf_auth_pre_scanlist(softc, fin, pass) + ipf_main_softc_t *softc; + fr_info_t *fin; + u_32_t pass; +{ + ipf_auth_softc_t *softa = softc->ipf_auth_soft; + + if (softa->ipf_auth_ip != NULL) + return ipf_scanlist(fin, softc->ipf_pass); + + return pass; +} + + +frentry_t ** +ipf_auth_rulehead(softc) + ipf_main_softc_t *softc; +{ + ipf_auth_softc_t *softa = softc->ipf_auth_soft; + + return &softa->ipf_auth_ip; +} diff --git a/sys/contrib/ipfilter/netinet/ip_auth.h b/sys/contrib/ipfilter/netinet/ip_auth.h index 36c4bacf8f93..914f9996ef0e 100644 --- a/sys/contrib/ipfilter/netinet/ip_auth.h +++ b/sys/contrib/ipfilter/netinet/ip_auth.h @@ -1,7 +1,7 @@ /* $FreeBSD$ */ /* - * Copyright (C) 1997-2001 by Darren Reed & Guido Van Rooij. + * Copyright (C) 2012 by Darren Reed. * * See the IPFILTER.LICENCE file for details on licencing. * @@ -21,6 +21,7 @@ typedef struct frauth { u_32_t fra_pass; fr_info_t fra_info; char *fra_buf; + u_32_t fra_flx; #ifdef MENTAT queue_t *fra_q; mb_t *fra_m; @@ -35,7 +36,7 @@ typedef struct frauthent { int fae_ref; } frauthent_t; -typedef struct fr_authstat { +typedef struct ipf_authstat { U_QUAD_T fas_hits; U_QUAD_T fas_miss; u_long fas_nospace; @@ -46,26 +47,28 @@ typedef struct fr_authstat { u_long fas_quefail; u_long fas_expire; frauthent_t *fas_faelist; -} fr_authstat_t; +} ipf_authstat_t; -extern frentry_t *ipauth; -extern struct fr_authstat fr_authstats; -extern int fr_defaultauthage; -extern int fr_authstart; -extern int fr_authend; -extern int fr_authsize; -extern int fr_authused; -extern int fr_auth_lock; -extern frentry_t *fr_checkauth __P((fr_info_t *, u_32_t *)); -extern void fr_authexpire __P((void)); -extern int fr_authinit __P((void)); -extern void fr_authunload __P((void)); -extern int fr_authflush __P((void)); -extern mb_t **fr_authpkts; -extern int fr_newauth __P((mb_t *, fr_info_t *)); -extern int fr_preauthcmd __P((ioctlcmd_t, frentry_t *, frentry_t **)); -extern int fr_auth_ioctl __P((caddr_t, ioctlcmd_t, int, int, void *)); -extern int fr_auth_waiting __P((void)); +extern frentry_t *ipf_auth_check __P((fr_info_t *, u_32_t *)); +extern void ipf_auth_expire __P((ipf_main_softc_t *)); +extern int ipf_auth_ioctl __P((ipf_main_softc_t *, caddr_t, ioctlcmd_t, + int, int, void *)); +extern int ipf_auth_init __P((void)); +extern int ipf_auth_main_load __P((void)); +extern int ipf_auth_main_unload __P((void)); +extern void ipf_auth_soft_destroy __P((ipf_main_softc_t *, void *)); +extern void *ipf_auth_soft_create __P((ipf_main_softc_t *)); +extern int ipf_auth_new __P((mb_t *, fr_info_t *)); +extern int ipf_auth_precmd __P((ipf_main_softc_t *, ioctlcmd_t, + frentry_t *, frentry_t **)); +extern void ipf_auth_unload __P((ipf_main_softc_t *)); +extern int ipf_auth_waiting __P((ipf_main_softc_t *)); +extern void ipf_auth_setlock __P((void *, int)); +extern int ipf_auth_soft_init __P((ipf_main_softc_t *, void *)); +extern int ipf_auth_soft_fini __P((ipf_main_softc_t *, void *)); +extern u_32_t ipf_auth_pre_scanlist __P((ipf_main_softc_t *, fr_info_t *, + u_32_t)); +extern frentry_t **ipf_auth_rulehead __P((ipf_main_softc_t *)); #endif /* __IP_AUTH_H__ */ diff --git a/sys/contrib/ipfilter/netinet/ip_compat.h b/sys/contrib/ipfilter/netinet/ip_compat.h index 4305c48e54a5..6cce5912f2c1 100644 --- a/sys/contrib/ipfilter/netinet/ip_compat.h +++ b/sys/contrib/ipfilter/netinet/ip_compat.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 1993-2001, 2003 by Darren Reed. + * Copyright (C) 2012 by Darren Reed. * * See the IPFILTER.LICENCE file for details on licencing. * @@ -32,14 +32,7 @@ # define __KERNEL__ #endif -#ifndef SOLARIS #define SOLARIS (defined(sun) && (defined(__svr4__) || defined(__SVR4))) -#endif -#if (defined(SOLARIS2) && (SOLARIS2 >= 8)) -# ifndef USE_INET6 -# define USE_INET6 -# endif -#endif #if defined(__FreeBSD_version) && (__FreeBSD_version >= 400000) && \ !defined(_KERNEL) && !defined(USE_INET6) && !defined(NOINET6) # define USE_INET6 @@ -47,26 +40,22 @@ #if defined(__NetBSD_Version__) && (__NetBSD_Version__ >= 105000000) && \ !defined(_KERNEL) && !defined(USE_INET6) # define USE_INET6 +#endif +#if defined(__NetBSD_Version__) && (__NetBSD_Version__ >= 106140000) && \ + defined(_KERNEL) && \ + (!defined(IPFILTER_LKM) || (__NetBSD_Version__ >= 399000100)) # define IPFILTER_M_IPFILTER #endif -#if defined(OpenBSD) && (OpenBSD >= 200206) && \ +#if !defined(USE_INET6) +# if defined(OpenBSD) && (OpenBSD >= 200206) && \ !defined(_KERNEL) && !defined(USE_INET6) -# define USE_INET6 -#endif -#if defined(__osf__) -# define USE_INET6 -#endif -#if defined(linux) && (!defined(_KERNEL) || defined(CONFIG_IPV6)) -# define USE_INET6 -#endif -#if defined(HPUXREV) && (HPUXREV >= 1111) -# define USE_INET6 +# define USE_INET6 +# endif +# if defined(HPUXREV) && (HPUXREV >= 1111) +# define USE_INET6 +# endif #endif -#if defined(BSD) && (BSD < 199103) && defined(__osf__) -# undef BSD -# define BSD 199103 -#endif #if defined(__SVR4) || defined(__svr4__) || defined(__sgi) # define index strchr @@ -95,862 +84,120 @@ struct ether_addr { }; #endif -#if defined(__sgi) && !defined(IPFILTER_LKM) -# ifdef __STDC__ -# define IPL_EXTERN(ep) ipfilter##ep -# else -# define IPL_EXTERN(ep) ipfilter/**/ep -# endif -#else # ifdef __STDC__ # define IPL_EXTERN(ep) ipl##ep # else # define IPL_EXTERN(ep) ipl/**/ep # endif -#endif /* * This is a workaround for troubles on FreeBSD and OpenBSD. */ -#ifndef linux # ifndef _KERNEL # define ADD_KERNEL # define _KERNEL # define KERNEL # endif -# ifdef __OpenBSD__ -struct file; -# endif # include # ifdef ADD_KERNEL # undef _KERNEL # undef KERNEL # endif -#endif - -/* ----------------------------------------------------------------------- */ -/* S O L A R I S */ -/* ----------------------------------------------------------------------- */ -#if SOLARIS -# define MENTAT 1 -# include -# include -# include -# include -# include -# include -# if defined(SOLARIS2) && SOLARIS2 >= 10 -# include -# include -# include -# include -# endif -/* - * because Solaris 2 defines these in two places :-/ - */ -# ifndef KERNEL -# define _KERNEL -# undef RES_INIT -# endif /* _KERNEL */ - -# if defined(SOLARIS2) && SOLARIS2 >= 8 -# include -# include -# endif - -# include -/* These 5 are defined in and */ -# undef IPOPT_EOL -# undef IPOPT_NOP -# undef IPOPT_LSRR -# undef IPOPT_RR -# undef IPOPT_SSRR -# ifdef i386 -# define _SYS_PROMIF_H -# endif -# ifndef _KERNEL -# include "radix_ipf.h" -# else -# include "radix_ipf_local.h" -# endif -# include -# undef COPYOUT -# include -# ifndef KERNEL -# undef _KERNEL -# endif -# if defined(SOLARIS2) && SOLARIS2 >= 8 -# define SNPRINTF snprintf - -# include -# define ipif_local_addr ipif_lcl_addr -/* Only defined in private include file */ -# ifndef V4_PART_OF_V6 -# define V4_PART_OF_V6(v6) v6.s6_addr32[3] -# endif -struct ip6_ext { - u_char ip6e_nxt; - u_char ip6e_len; -}; -# endif /* SOLARIS2 >= 8 */ - -# if defined(SOLARIS2) && SOLARIS2 >= 6 -# include -typedef uint32_t u_32_t; -# else -typedef unsigned int u_32_t; -# endif -# define U_32_T 1 - -# ifdef _KERNEL -# define NEED_LOCAL_RAND 1 -# define ipf_random arc4random -# define KRWLOCK_T krwlock_t -# define KMUTEX_T kmutex_t - -# if !defined(FW_HOOKS) -# include "qif.h" -# include "pfil.h" -# else -# include - -extern net_data_t ipfipv4; -extern net_data_t ipfipv6; - -typedef struct qpktinfo { - void *qpi_data; - mblk_t **qpi_mp; - mblk_t *qpi_m; - uintptr_t qpi_real; - int qpi_flags; - int qpi_num; - int qpi_off; -} qpktinfo_t; -# define QF_GROUP 0x01 -# endif - -# if SOLARIS2 >= 6 -# if SOLARIS2 == 6 -# define ATOMIC_INCL(x) atomic_add_long((uint32_t*)&(x), 1) -# define ATOMIC_DECL(x) atomic_add_long((uint32_t*)&(x), -1) -# else -# define ATOMIC_INCL(x) atomic_add_long(&(x), 1) -# define ATOMIC_DECL(x) atomic_add_long(&(x), -1) -# endif /* SOLARIS2 == 6 */ -# define ATOMIC_INC64(x) atomic_add_64((uint64_t*)&(x), 1) -# define ATOMIC_INC32(x) atomic_add_32((uint32_t*)&(x), 1) -# define ATOMIC_INC16(x) atomic_add_16((uint16_t*)&(x), 1) -# define ATOMIC_DEC64(x) atomic_add_64((uint64_t*)&(x), -1) -# define ATOMIC_DEC32(x) atomic_add_32((uint32_t*)&(x), -1) -# define ATOMIC_DEC16(x) atomic_add_16((uint16_t*)&(x), -1) -# else -# define ATOMIC_INC(x) { mutex_enter(&ipf_rw); (x)++; \ - mutex_exit(&ipf_rw); } -# define ATOMIC_DEC(x) { mutex_enter(&ipf_rw); (x)--; \ - mutex_exit(&ipf_rw); } -# endif /* SOLARIS2 >= 6 */ -# define USE_MUTEXES -# define MUTEX_ENTER(x) mutex_enter(&(x)->ipf_lk) -# define READ_ENTER(x) rw_enter(&(x)->ipf_lk, RW_READER) -# define WRITE_ENTER(x) rw_enter(&(x)->ipf_lk, RW_WRITER) -# define MUTEX_DOWNGRADE(x) rw_downgrade(&(x)->ipf_lk) -# define RWLOCK_INIT(x, y) rw_init(&(x)->ipf_lk, (y), \ - RW_DRIVER, NULL) -# define RWLOCK_EXIT(x) rw_exit(&(x)->ipf_lk) -# define RW_DESTROY(x) rw_destroy(&(x)->ipf_lk) -# define MUTEX_INIT(x, y) mutex_init(&(x)->ipf_lk, (y), \ - MUTEX_DRIVER, NULL) -# define MUTEX_DESTROY(x) mutex_destroy(&(x)->ipf_lk) -# define MUTEX_NUKE(x) bzero((x), sizeof(*(x))) -# define MUTEX_EXIT(x) mutex_exit(&(x)->ipf_lk) -# define COPYIN(a,b,c) copyin((caddr_t)(a), (caddr_t)(b), (c)) -# define COPYOUT(a,b,c) copyout((caddr_t)(a), (caddr_t)(b), (c)) -# define BCOPYIN(a,b,c) copyin((caddr_t)(a), (caddr_t)(b), (c)) -# define BCOPYOUT(a,b,c) copyout((caddr_t)(a), (caddr_t)(b), (c)) -# define UIOMOVE(a,b,c,d) uiomove((caddr_t)a,b,c,d) -# define KFREE(x) kmem_free((char *)(x), sizeof(*(x))) -# define KFREES(x,s) kmem_free((char *)(x), (s)) -# define SPL_SCHED(x) ; -# define SPL_NET(x) ; -# define SPL_IMP(x) ; -# undef SPL_X -# define SPL_X(x) ; -# ifdef sparc -# define ntohs(x) (x) -# define ntohl(x) (x) -# define htons(x) (x) -# define htonl(x) (x) -# endif /* sparc */ -# define KMALLOC(a,b) (a) = (b)kmem_alloc(sizeof(*(a)), KM_NOSLEEP) -# define KMALLOCS(a,b,c) (a) = (b)kmem_alloc((c), KM_NOSLEEP) -# define GET_MINOR(x) getminor(x) -extern void *get_unit __P((char *, int)); -# define GETIFP(n, v) get_unit(n, v) -# if defined(_INET_IP_STACK_H) -# define COPYIFNAME(v, x, b) \ - do { \ - if ((v) == 4) { \ - (void) net_getifname(ipfipv4,\ - (uintptr_t)x, b, \ - LIFNAMSIZ); \ - } else { \ - (void) net_getifname(ipfipv6,\ - (uintptr_t)x, b, \ - LIFNAMSIZ); \ - } \ - } while (0) -# else -# define COPYIFNAME(v, x, b) \ - (void) strncpy(b, ((qif_t *)x)->qf_name, \ - LIFNAMSIZ) -# endif -# define GETKTIME(x) uniqtime((struct timeval *)x) -# define MSGDSIZE(x) msgdsize(x) -# define M_LEN(x) ((x)->b_wptr - (x)->b_rptr) -# define M_DUPLICATE(x) dupmsg((x)) -# define MTOD(m,t) ((t)((m)->b_rptr)) -# define MTYPE(m) ((m)->b_datap->db_type) -# define FREE_MB_T(m) freemsg(m) -# define m_next b_cont -# if !defined(_INET_IP_STACK_H) -# define CACHE_HASH(x) (((qpktinfo_t *)(x)->fin_qpi)->qpi_num & 7) -# else -# define CACHE_HASH(x) ((uintptr_t)(x)->fin_ifp & 7) -# endif -# define IPF_PANIC(x,y) if (x) { printf y; cmn_err(CE_PANIC, "ipf_panic"); } -typedef mblk_t mb_t; -# endif /* _KERNEL */ - -# if defined(SOLARIS2) && (SOLARIS2 >= 7) -# ifdef lint -# define ALIGN32(ptr) (ptr ? 0L : 0L) -# define ALIGN16(ptr) (ptr ? 0L : 0L) -# else -# define ALIGN32(ptr) (ptr) -# define ALIGN16(ptr) (ptr) -# endif -# endif - -# if defined(SOLARIS2) && SOLARIS2 < 6 -typedef struct uio uio_t; -# endif -typedef int ioctlcmd_t; -typedef uint8_t u_int8_t; - -# define OS_RECOGNISED 1 - -#endif /* SOLARIS */ - -/* ----------------------------------------------------------------------- */ -/* H P U X */ -/* ----------------------------------------------------------------------- */ -#ifdef __hpux -# define MENTAT 1 -# include -# include -# include -# include -# ifdef USE_INET6 -# include -# include -# include -typedef struct ip6_hdr ip6_t; -# endif - -# ifdef _KERNEL -# define SNPRINTF sprintf -# if (HPUXREV >= 1111) -# define IPL_SELECT -# ifdef IPL_SELECT -# include -# include -# define READ_COLLISION 0x01 - -typedef struct iplog_select_s { - kthread_t *read_waiter; - int state; -} iplog_select_t; -# endif -# endif - -# define GETKTIME(x) uniqtime((struct timeval *)x) - -# if HPUXREV == 1111 -# include "kern_svcs.h" -# else -# include -# endif -# undef ti_flags -# undef TCP_NODELAY -# undef TCP_MAXSEG -# include -# include "../netinet/ip_info.h" -/* - * According to /usr/include/sys/spinlock.h on HP-UX 11.00, these functions - * are available. Attempting to use them actually results in unresolved - * symbols when it comes time to load the module. - * This has been fixed! Yipee! - */ -# if 1 -# ifdef __LP64__ -# define ATOMIC_INCL(x) lock_and_incr_int64(&ipf_rw.ipf_lk, &(x), 1) -# define ATOMIC_DECL(x) lock_and_incr_int64(&ipf_rw.ipf_lk, &(x), -1) -# else -# define ATOMIC_INCL(x) lock_and_incr_int32(&ipf_rw.ipf_lk, &(x), 1) -# define ATOMIC_DECL(x) lock_and_incr_int32(&ipf_rw.ipf_lk, &(x), -1) -# endif -# define ATOMIC_INC64(x) lock_and_incr_int64(&ipf_rw.ipf_lk, &(x), 1) -# define ATOMIC_INC32(x) lock_and_incr_int32(&ipf_rw.ipf_lk, &(x), 1) -# define ATOMIC_INC16(x) lock_and_incr_int16(&ipf_rw.ipf_lk, &(x), 1) -# define ATOMIC_DEC64(x) lock_and_incr_int64(&ipf_rw.ipf_lk, &(x), -1) -# define ATOMIC_DEC32(x) lock_and_incr_int32(&ipf_rw.ipf_lk, &(x), -1) -# define ATOMIC_DEC16(x) lock_and_incr_int16(&ipf_rw.ipf_lk, &(x), -1) -# else /* 0 */ -# define ATOMIC_INC64(x) { MUTEX_ENTER(&ipf_rw); (x)++; \ - MUTEX_EXIT(&ipf_rw); } -# define ATOMIC_DEC64(x) { MUTEX_ENTER(&ipf_rw); (x)--; \ - MUTEX_EXIT(&ipf_rw); } -# define ATOMIC_INC32(x) { MUTEX_ENTER(&ipf_rw); (x)++; \ - MUTEX_EXIT(&ipf_rw); } -# define ATOMIC_DEC32(x) { MUTEX_ENTER(&ipf_rw); (x)--; \ - MUTEX_EXIT(&ipf_rw); } -# define ATOMIC_INCL(x) { MUTEX_ENTER(&ipf_rw); (x)++; \ - MUTEX_EXIT(&ipf_rw); } -# define ATOMIC_DECL(x) { MUTEX_ENTER(&ipf_rw); (x)--; \ - MUTEX_EXIT(&ipf_rw); } -# define ATOMIC_INC(x) { MUTEX_ENTER(&ipf_rw); (x)++; \ - MUTEX_EXIT(&ipf_rw); } -# define ATOMIC_DEC(x) { MUTEX_ENTER(&ipf_rw); (x)--; \ - MUTEX_EXIT(&ipf_rw); } -# endif -# define ip_cksum ip_csuma -# define memcpy(a,b,c) bcopy((caddr_t)b, (caddr_t)a, c) -# define USE_MUTEXES -# define MUTEX_INIT(x, y) initlock(&(x)->ipf_lk, 0, 0, (y)) -# define MUTEX_ENTER(x) spinlock(&(x)->ipf_lk) -# define MUTEX_EXIT(x) spinunlock(&(x)->ipf_lk); -# define MUTEX_DESTROY(x) -# define MUTEX_NUKE(x) bzero((char *)(x), sizeof(*(x))) -# define KMUTEX_T lock_t -# define kmutex_t lock_t /* for pfil.h */ -# define krwlock_t lock_t /* for pfil.h */ -/* - * The read-write lock implementation in HP-UX 11.0 is crippled - it can - * only be used by threads working in a user context! - * This has been fixed! Yipee! (Or at least it does in 11.00, not 11.11..) - */ -# if HPUXREV < 1111 -# define MUTEX_DOWNGRADE(x) lock_write_to_read(x) -# define KRWLOCK_T struct rw_lock -# define READ_ENTER(x) lock_read(&(x)->ipf_lk) -# define WRITE_ENTER(x) lock_write(&(x)->ipf_lk) -# if HPUXREV >= 1111 -# define RWLOCK_INIT(x, y) rwlock_init4(&(x)->ipf_lk, 0, RWLCK_CANSLEEP, 0, y) -# else -# define RWLOCK_INIT(x, y) lock_init3(&(x)->ipf_lk, 0, 1, 0, 0, y) -# endif -# define RWLOCK_EXIT(x) lock_done(&(x)->ipf_lk) -# else -# define KRWLOCK_T lock_t -# define KMUTEX_T lock_t -# define READ_ENTER(x) MUTEX_ENTER(x) -# define WRITE_ENTER(x) MUTEX_ENTER(x) -# define MUTEX_DOWNGRADE(x) -# define RWLOCK_INIT(x, y) initlock(&(x)->ipf_lk, 0, 0, y) -# define RWLOCK_EXIT(x) MUTEX_EXIT(x) -# endif -# define RW_DESTROY(x) -# define COPYIN(a,b,c) copyin((caddr_t)(a), (caddr_t)(b), (c)) -# define COPYOUT(a,b,c) copyout((caddr_t)(a), (caddr_t)(b), (c)) -# define SPL_SCHED(x) ; -# define SPL_NET(x) ; -# define SPL_IMP(x) ; -# undef SPL_X -# define SPL_X(x) ; -extern void *get_unit __P((char *, int)); -# define GETIFP(n, v) get_unit(n, v) -# define COPYIFNAME(v, x, b) \ - (void) strncpy(b, ((qif_t *)x)->qf_name, \ - LIFNAMSIZ) -# define UIOMOVE(a,b,c,d) uiomove((caddr_t)a,b,c,d) -# define SLEEP(id, n) { lock_t *_l = get_sleep_lock((caddr_t)id); \ - sleep(id, PZERO+1); \ - spinunlock(_l); \ - } -# define WAKEUP(id,x) { lock_t *_l = get_sleep_lock((caddr_t)id); \ - wakeup(id + x); \ - spinunlock(_l); \ - } -# define POLLWAKEUP(x) ; -# define KMALLOC(a, b) MALLOC((a), b, sizeof(*(a)), M_IOSYS, M_NOWAIT) -# define KMALLOCS(a, b, c) MALLOC((a), b, (c), M_IOSYS, M_NOWAIT) -# define KFREE(x) kmem_free((char *)(x), sizeof(*(x))) -# define KFREES(x,s) kmem_free((char *)(x), (s)) -# define MSGDSIZE(x) msgdsize(x) -# define M_LEN(x) ((x)->b_wptr - (x)->b_rptr) -# define M_DUPLICATE(x) dupmsg((x)) -# define MTOD(m,t) ((t)((m)->b_rptr)) -# define MTYPE(m) ((m)->b_datap->db_type) -# define FREE_MB_T(m) freemsg(m) -# define m_next b_cont -# define IPF_PANIC(x,y) if (x) { printf y; panic("ipf_panic"); } -typedef mblk_t mb_t; - -# define CACHE_HASH(x) (((qpktinfo_t *)(x)->fin_qpi)->qpi_num & 7) - -# include "qif.h" -# include "pfil.h" - -# else /* _KERNEL */ - -typedef unsigned char uchar_t; - -# ifndef _SYS_STREAM_INCLUDED -typedef char * mblk_t; -typedef void * queue_t; -typedef u_long ulong; -# endif -# include - -# endif /* _KERNEL */ - -# ifdef lint -# define ALIGN32(ptr) (ptr ? 0L : 0L) -# define ALIGN16(ptr) (ptr ? 0L : 0L) -# else -# define ALIGN32(ptr) (ptr) -# define ALIGN16(ptr) (ptr) -# endif - -typedef struct uio uio_t; -typedef int ioctlcmd_t; -typedef int minor_t; -typedef unsigned int u_32_t; -# define U_32_T 1 - -# define OS_RECOGNISED 1 - -#endif /* __hpux */ - -/* ----------------------------------------------------------------------- */ -/* I R I X */ -/* ----------------------------------------------------------------------- */ -#ifdef __sgi -# undef MENTAT -# if IRIX < 60500 -typedef struct uio uio_t; -# endif -typedef int ioctlcmd_t; -typedef u_int32_t u_32_t; -# define U_32_T 1 - -# ifdef INET6 -# define USE_INET6 -# endif - -# define hz HZ -# include -# define IPF_LOCK_PL plhi -# include -# undef kmutex_t -typedef struct { - lock_t *l; - int pl; -} kmutex_t; - -# ifdef MUTEX_INIT -# define KMUTEX_T mutex_t -# else -# define KMUTEX_T kmutex_t -# define KRWLOCK_T kmutex_t -# endif - -# ifdef _KERNEL -# define NEED_LOCAL_RAND 1 -# define ipf_random arc4random -# define ATOMIC_INC(x) { MUTEX_ENTER(&ipf_rw); \ - (x)++; MUTEX_EXIT(&ipf_rw); } -# define ATOMIC_DEC(x) { MUTEX_ENTER(&ipf_rw); \ - (x)--; MUTEX_EXIT(&ipf_rw); } -# define USE_MUTEXES -# ifdef MUTEX_INIT -# include -# define ATOMIC_INCL(x) atomicAddUlong(&(x), 1) -# define ATOMIC_INC64(x) atomicAddUint64(&(x), 1) -# define ATOMIC_INC32(x) atomicAddUint(&(x), 1) -# define ATOMIC_INC16 ATOMIC_INC -# define ATOMIC_DECL(x) atomicAddUlong(&(x), -1) -# define ATOMIC_DEC64(x) atomicAddUint64(&(x), -1) -# define ATOMIC_DEC32(x) atomicAddUint(&(x), -1) -# define ATOMIC_DEC16 ATOMIC_DEC -# undef MUTEX_INIT -# define MUTEX_INIT(x, y) mutex_init(&(x)->ipf_lk, \ - MUTEX_DEFAULT, y) -# undef MUTEX_ENTER -# define MUTEX_ENTER(x) mutex_lock(&(x)->ipf_lk, 0) -# undef MUTEX_EXIT -# define MUTEX_EXIT(x) mutex_unlock(&(x)->ipf_lk) -# undef MUTEX_DESTROY -# define MUTEX_DESTROY(x) mutex_destroy(&(x)->ipf_lk) -# define MUTEX_DOWNGRADE(x) mrdemote(&(x)->ipf_lk) -# define KRWLOCK_T mrlock_t -# define RWLOCK_INIT(x, y) mrinit(&(x)->ipf_lk, y) -# undef RW_DESTROY -# define RW_DESTROY(x) mrfree(&(x)->ipf_lk) -# define READ_ENTER(x) RW_RDLOCK(&(x)->ipf_lk) -# define WRITE_ENTER(x) RW_WRLOCK(&(x)->ipf_lk) -# define RWLOCK_EXIT(x) RW_UNLOCK(&(x)->ipf_lk) -# else -# define READ_ENTER(x) MUTEX_ENTER(&(x)->ipf_lk) -# define WRITE_ENTER(x) MUTEX_ENTER(&(x)->ipf_lk) -# define MUTEX_DOWNGRADE(x) ; -# define RWLOCK_EXIT(x) MUTEX_EXIT(&(x)->ipf_lk) -# define MUTEX_EXIT(x) UNLOCK((x)->ipf_lk.l, (x)->ipf_lk.pl); -# define MUTEX_INIT(x,y) (x)->ipf_lk.l = LOCK_ALLOC((uchar_t)-1, IPF_LOCK_PL, (lkinfo_t *)-1, KM_NOSLEEP) -# define MUTEX_DESTROY(x) LOCK_DEALLOC((x)->ipf_lk.l) -# define MUTEX_ENTER(x) (x)->ipf_lk.pl = LOCK((x)->ipf_lk.l, \ - IPF_LOCK_PL); -# endif -# define MUTEX_NUKE(x) bzero((x), sizeof(*(x))) -# define FREE_MB_T(m) m_freem(m) -# define MTOD(m,t) mtod(m,t) -# define COPYIN(a,b,c) (bcopy((caddr_t)(a), (caddr_t)(b), (c)), 0) -# define COPYOUT(a,b,c) (bcopy((caddr_t)(a), (caddr_t)(b), (c)), 0) -# define UIOMOVE(a,b,c,d) uiomove((caddr_t)a,b,c,d) -# define SLEEP(id, n) sleep((id), PZERO+1) -# define WAKEUP(id,x) wakeup(id+x) -# define POLLWAKEUP(x) ; -# define KFREE(x) kmem_free((char *)(x), sizeof(*(x))) -# define KFREES(x,s) kmem_free((char *)(x), (s)) -# define GETIFP(n,v) ifunit(n) -# include -# include -# define KMALLOC(a,b) (a) = (b)kmem_alloc(sizeof(*(a)), KM_NOSLEEP) -# define KMALLOCS(a,b,c) (a) = (b)kmem_alloc((c), KM_NOSLEEP) -# define GET_MINOR(x) getminor(x) -# define USE_SPL 1 -# define SPL_IMP(x) (x) = splimp() -# define SPL_NET(x) (x) = splnet() -# define SPL_SCHED(x) (x) = splsched() -# define SPL_X(x) (void) splx(x) -extern void m_copydata __P((struct mbuf *, int, int, caddr_t)); -extern void m_copyback __P((struct mbuf *, int, int, caddr_t)); -# define MSGDSIZE(x) mbufchainlen(x) -# define M_LEN(x) (x)->m_len -# define M_DUPLICATE(x) m_copy((x), 0, M_COPYALL) -# define GETKTIME(x) microtime((struct timeval *)x) -# define IFNAME(x) ((struct ifnet *)x)->if_name -# define CACHE_HASH(x) ((IFNAME(fin->fin_ifp)[0] + \ - ((struct ifnet *)fin->fin_ifp)->if_unit) & 7) -# define IPF_PANIC(x,y) if (x) { printf y; panic("ipf_panic"); } -typedef struct mbuf mb_t; -# else -# undef RW_DESTROY -# undef MUTEX_INIT -# undef MUTEX_DESTROY -# endif /* _KERNEL */ - -# define OS_RECOGNISED 1 - -#endif /* __sgi */ - -/* ----------------------------------------------------------------------- */ -/* T R U 6 4 */ -/* ----------------------------------------------------------------------- */ -#ifdef __osf__ -# undef MENTAT - -# include -# include - -# ifdef _KERNEL -# define NEED_LOCAL_RAND 1 -# define ipf_random arc4random -# define KMUTEX_T simple_lock_data_t -# define KRWLOCK_T lock_data_t -# include -# define USE_MUTEXES -# define READ_ENTER(x) lock_read(&(x)->ipf_lk) -# define WRITE_ENTER(x) lock_write(&(x)->ipf_lk) -# define MUTEX_DOWNGRADE(x) lock_write_to_read(&(x)->ipf_lk) -# define RWLOCK_INIT(x, y) lock_init(&(x)->ipf_lk, TRUE) -# define RWLOCK_EXIT(x) lock_done(&(x)->ipf_lk) -# define RW_DESTROY(x) lock_terminate(&(x)->ipf_lk) -# define MUTEX_ENTER(x) simple_lock(&(x)->ipf_lk) -# define MUTEX_INIT(x, y) simple_lock_init(&(x)->ipf_lk) -# define MUTEX_DESTROY(x) simple_lock_terminate(&(x)->ipf_lk) -# define MUTEX_EXIT(x) simple_unlock(&(x)->ipf_lk) -# define MUTEX_NUKE(x) bzero(x, sizeof(*(x))) -# define ATOMIC_INC64(x) atomic_incq((uint64_t*)&(x)) -# define ATOMIC_DEC64(x) atomic_decq((uint64_t*)&(x)) -# define ATOMIC_INC32(x) atomic_incl((uint32_t*)&(x)) -# define ATOMIC_DEC32(x) atomic_decl((uint32_t*)&(x)) -# define ATOMIC_INC16(x) { simple_lock(&ipf_rw); (x)++; \ - simple_unlock(&ipf_rw); } -# define ATOMIC_DEC16(x) { simple_lock(&ipf_rw); (x)--; \ - simple_unlock(&ipf_rw); } -# define ATOMIC_INCL(x) atomic_incl((uint32_t*)&(x)) -# define ATOMIC_DECL(x) atomic_decl((uint32_t*)&(x)) -# define ATOMIC_INC(x) { simple_lock(&ipf_rw); (x)++; \ - simple_unlock(&ipf_rw); } -# define ATOMIC_DEC(x) { simple_lock(&ipf_rw); (x)--; \ - simple_unlock(&ipf_rw); } -# define SPL_SCHED(x) ; -# define SPL_NET(x) ; -# define SPL_IMP(x) ; -# undef SPL_X -# define SPL_X(x) ; -# define UIOMOVE(a,b,c,d) uiomove((caddr_t)a, b, d) -# define FREE_MB_T(m) m_freem(m) -# define MTOD(m,t) mtod(m,t) -# define GETIFP(n, v) ifunit(n) -# define GET_MINOR getminor -# define WAKEUP(id,x) wakeup(id + x) -# define POLLWAKEUP(x) ; -# define COPYIN(a,b,c) copyin((caddr_t)(a), (caddr_t)(b), (c)) -# define COPYOUT(a,b,c) copyout((caddr_t)(a), (caddr_t)(b), (c)) -# define KMALLOC(a, b) MALLOC((a), b, sizeof(*(a)), M_PFILT, M_NOWAIT) -# define KMALLOCS(a, b, c) MALLOC((a), b, (c), M_PFILT, \ - ((c) > 4096) ? M_WAITOK : M_NOWAIT) -# define KFREE(x) FREE((x), M_PFILT) -# define KFREES(x,s) FREE((x), M_PFILT) -# define MSGDSIZE(x) mbufchainlen(x) -# define M_LEN(x) (x)->m_len -# define M_DUPLICATE(x) m_copy((x), 0, M_COPYALL) -# define GETKTIME(x) microtime((struct timeval *)x) -# define IFNAME(x) ((struct ifnet *)x)->if_name -# define CACHE_HASH(x) ((IFNAME(fin->fin_ifp)[0] + \ - ((struct ifnet *)fin->fin_ifp)->if_unit) & 7) -# define IPF_PANIC(x,y) if (x) { printf y; panic("ipf_panic"); } -typedef struct mbuf mb_t; -# endif /* _KERNEL */ - -# if (defined(_KERNEL) || defined(_NO_BITFIELDS) || (__STDC__ == 1)) -# define IP_V(x) ((x)->ip_vhl >> 4) -# define IP_HL(x) ((x)->ip_vhl & 0xf) -# define IP_V_A(x,y) (x)->ip_vhl |= (((y) << 4) & 0xf0) -# define IP_HL_A(x,y) (x)->ip_vhl |= ((y) & 0xf) -# define TCP_X2(x) ((x)->th_xoff & 0xf) -# define TCP_X2_A(x,y) (x)->th_xoff |= ((y) & 0xf) -# define TCP_OFF(x) ((x)->th_xoff >> 4) -# define TCP_OFF_A(x,y) (x)->th_xoff |= (((y) << 4) & 0xf0) -# endif - -/* - * These are from's Solaris' #defines for little endian. - */ -#define IP6F_MORE_FRAG 0x0100 -#define IP6F_RESERVED_MASK 0x0600 -#define IP6F_OFF_MASK 0xf8ff - -struct ip6_ext { - u_char ip6e_nxt; - u_char ip6e_len; -}; - -typedef int ioctlcmd_t; -/* - * Really, any arch where sizeof(long) != sizeof(int). - */ -typedef unsigned int u_32_t; -# define U_32_T 1 - -# define OS_RECOGNISED 1 -#endif /* __osf__ */ - -/* ----------------------------------------------------------------------- */ -/* N E T B S D */ -/* ----------------------------------------------------------------------- */ -#ifdef __NetBSD__ -# if (NetBSD >= 199905) && !defined(IPFILTER_LKM) && defined(_KERNEL) -# include "opt_ipfilter.h" -# endif -# if defined(_KERNEL) -# include -# else -# include -# endif -# if defined(_KERNEL) && !defined(IPFILTER_LKM) -# include "bpfilter.h" -# if defined(__NetBSD_Version__) && (__NetBSD_Version__ >= 104110000) -# include "opt_inet.h" -# endif -# ifdef INET6 -# define USE_INET6 -# endif -# if (__NetBSD_Version__ >= 105000000) -# define HAVE_M_PULLDOWN 1 -# endif -# endif - -# if (__NetBSD_Version__ >= 499000000) -typedef char * caddr_t; -# endif - -# define ipf_random arc4random - -# ifdef _KERNEL -# if (__NetBSD_Version__ >= 399001400) -# define KMALLOCS(a, b, c) (a) = (b)malloc((c), _M_IPF, M_NOWAIT) -# endif -# define MSGDSIZE(x) mbufchainlen(x) -# define M_LEN(x) (x)->m_len -# define M_DUPLICATE(x) m_copy((x), 0, M_COPYALL) -# define GETKTIME(x) microtime((struct timeval *)x) -# define IPF_PANIC(x,y) if (x) { printf y; panic("ipf_panic"); } -# define COPYIN(a,b,c) copyin((caddr_t)(a), (caddr_t)(b), (c)) -# define COPYOUT(a,b,c) copyout((caddr_t)(a), (caddr_t)(b), (c)) -typedef struct mbuf mb_t; -# endif /* _KERNEL */ -# if (NetBSD <= 1991011) && (NetBSD >= 199606) -# define IFNAME(x) ((struct ifnet *)x)->if_xname -# define COPYIFNAME(v, x, b) \ - (void) strncpy(b, \ - ((struct ifnet *)x)->if_xname, \ - LIFNAMSIZ) -# define CACHE_HASH(x) ((((struct ifnet *)fin->fin_ifp)->if_index)&7) -# else -# define IFNAME(x) ((struct ifnet *)x)->if_name -# define CACHE_HASH(x) ((IFNAME(fin->fin_ifp)[0] + \ - ((struct ifnet *)fin->fin_ifp)->if_unit) & 7) -# endif -typedef struct uio uio_t; -typedef u_long ioctlcmd_t; -typedef int minor_t; -typedef u_int32_t u_32_t; -# define U_32_T 1 - -# define OS_RECOGNISED 1 -#endif /* __NetBSD__ */ +#define NETBSD_GE_REV(x) (defined(__NetBSD_Version__) && \ + (__NetBSD_Version__ >= (x))) +#define NETBSD_GT_REV(x) (defined(__NetBSD_Version__) && \ + (__NetBSD_Version__ > (x))) +#define NETBSD_LT_REV(x) (defined(__NetBSD_Version__) && \ + (__NetBSD_Version__ < (x))) +#define FREEBSD_GE_REV(x) (defined(__FreeBSD_version) && \ + (__FreeBSD_version >= (x))) +#define FREEBSD_GT_REV(x) (defined(__FreeBSD_version) && \ + (__FreeBSD_version > (x))) +#define FREEBSD_LT_REV(x) (defined(__FreeBSD_version) && \ + (__FreeBSD_version < (x))) +#define BSDOS_GE_REV(x) (defined(_BSDI_VERSION) && \ + (_BSDI_VERSION >= (x))) +#define BSDOS_GT_REV(x) (defined(_BSDI_VERSION) && \ + (_BSDI_VERSION > (x))) +#define BSDOS_LT_REV(x) (defined(_BSDI_VERSION) && \ + (_BSDI_VERSION < (x))) +#define OPENBSD_GE_REV(x) (defined(OpenBSD) && (OpenBSD >= (x))) +#define OPENBSD_GT_REV(x) (defined(OpenBSD) && (OpenBSD > (x))) +#define OPENBSD_LT_REV(x) (defined(OpenBSD) && (OpenBSD < (x))) +#define BSD_GE_YEAR(x) (defined(BSD) && (BSD >= (x))) +#define BSD_GT_YEAR(x) (defined(BSD) && (BSD > (x))) +#define BSD_LT_YEAR(x) (defined(BSD) && (BSD < (x))) /* ----------------------------------------------------------------------- */ /* F R E E B S D */ /* ----------------------------------------------------------------------- */ -#ifdef __FreeBSD__ -# if (__FreeBSD_version < 400000) -# define NEED_LOCAL_RAND 1 -# else -# define ipf_random arc4random -# endif +# define HAS_SYS_MD5_H 1 # if defined(_KERNEL) -# if (__FreeBSD_version >= 500000) # include "opt_bpf.h" -# else -# include "bpf.h" -# endif -# if defined(__FreeBSD_version) && (__FreeBSD_version >= 400000) # include "opt_inet6.h" -# endif # if defined(INET6) && !defined(USE_INET6) # define USE_INET6 # endif # endif # if defined(_KERNEL) -# if (__FreeBSD_version >= 400000) +# include +# define p_cred td_ucred +# define p_uid td_ucred->cr_ruid + /* * When #define'd, the 5.2.1 kernel panics when used with the ftp proxy. * There may be other, safe, kernels but this is not extensively tested yet. */ # define HAVE_M_PULLDOWN -# endif # if !defined(IPFILTER_LKM) && (__FreeBSD_version >= 300000) # include "opt_ipfilter.h" # endif # define COPYIN(a,b,c) copyin((caddr_t)(a), (caddr_t)(b), (c)) # define COPYOUT(a,b,c) copyout((caddr_t)(a), (caddr_t)(b), (c)) -# if (__FreeBSD_version >= 500043) # define NETBSD_PF -# endif +# else +# include # endif /* _KERNEL */ -# if (__FreeBSD_version >= 500043) +# include # include -# if (__FreeBSD_version > 700014) +# define KRWLOCK_FILL_SZ 56 +# define KMUTEX_FILL_SZ 56 # include -# define KRWLOCK_T struct rwlock -# ifdef _KERNEL -# define READ_ENTER(x) rw_rlock(&(x)->ipf_lk) -# define WRITE_ENTER(x) rw_wlock(&(x)->ipf_lk) -# define MUTEX_DOWNGRADE(x) rw_downgrade(&(x)->ipf_lk) -# define RWLOCK_INIT(x, y) rw_init(&(x)->ipf_lk, (y)) -# define RW_DESTROY(x) rw_destroy(&(x)->ipf_lk) -# define RWLOCK_EXIT(x) do { \ +# define KMUTEX_T struct mtx +# define KRWLOCK_T struct rwlock +# ifdef _KERNEL +# define READ_ENTER(x) rw_rlock(&(x)->ipf_lk) +# define WRITE_ENTER(x) rw_wlock(&(x)->ipf_lk) +# define MUTEX_DOWNGRADE(x) rw_downgrade(&(x)->ipf_lk) +# define RWLOCK_INIT(x,y) rw_init(&(x)->ipf_lk, (y)) +# define RW_DESTROY(x) rw_destroy(&(x)->ipf_lk) +# define RWLOCK_EXIT(x) do { \ if (rw_wowned(&(x)->ipf_lk)) \ - rw_wunlock(&(x)->ipf_lk); \ - else \ + rw_wunlock(&(x)->ipf_lk); \ + else \ rw_runlock(&(x)->ipf_lk); \ } while (0) # endif -# else -# include -/* - * Whilst the sx(9) locks on FreeBSD have the right semantics and interface - * for what we want to use them for, despite testing showing they work - - * with a WITNESS kernel, it generates LOR messages. - */ -# ifdef _KERNEL -# if (__FreeBSD_version < 700000) -# define KRWLOCK_T struct mtx -# define READ_ENTER(x) mtx_lock(&(x)->ipf_lk) -# define WRITE_ENTER(x) mtx_lock(&(x)->ipf_lk) -# define RWLOCK_EXIT(x) mtx_unlock(&(x)->ipf_lk) -# define MUTEX_DOWNGRADE(x) ; -# define RWLOCK_INIT(x,y) mtx_init(&(x)->ipf_lk, (y), NULL,\ - MTX_DEF) -# define RW_DESTROY(x) mtx_destroy(&(x)->ipf_lk) -# else -# define KRWLOCK_T struct sx -# define READ_ENTER(x) sx_slock(&(x)->ipf_lk) -# define WRITE_ENTER(x) sx_xlock(&(x)->ipf_lk) -# define MUTEX_DOWNGRADE(x) sx_downgrade(&(x)->ipf_lk) -# define RWLOCK_INIT(x, y) sx_init(&(x)->ipf_lk, (y)) -# define RW_DESTROY(x) sx_destroy(&(x)->ipf_lk) -# ifdef sx_unlock -# define RWLOCK_EXIT(x) sx_unlock(&(x)->ipf_lk) -# else -# define RWLOCK_EXIT(x) do { \ - if ((x)->ipf_lk.sx_cnt < 0) \ - sx_xunlock(&(x)->ipf_lk); \ - else \ - sx_sunlock(&(x)->ipf_lk); \ - } while (0) -# endif -# endif -# endif -# endif -# define KMUTEX_T struct mtx -# endif -# if (__FreeBSD_version >= 501113) # include # define IFNAME(x) ((struct ifnet *)x)->if_xname # define COPYIFNAME(v, x, b) \ (void) strncpy(b, \ ((struct ifnet *)x)->if_xname, \ LIFNAMSIZ) -# endif -# if (__FreeBSD_version >= 500043) -# define CACHE_HASH(x) ((((struct ifnet *)fin->fin_ifp)->if_index) & 7) -# else -# define IFNAME(x) ((struct ifnet *)x)->if_name -# define CACHE_HASH(x) ((IFNAME(fin->fin_ifp)[0] + \ - ((struct ifnet *)fin->fin_ifp)->if_unit) & 7) -# endif # ifdef _KERNEL # define GETKTIME(x) microtime((struct timeval *)x) -# if (__FreeBSD_version >= 500002) # include # include # include -# endif -# if (__FreeBSD_version >= 500043) # define USE_MUTEXES # define MUTEX_ENTER(x) mtx_lock(&(x)->ipf_lk) # define MUTEX_EXIT(x) mtx_unlock(&(x)->ipf_lk) @@ -958,460 +205,47 @@ typedef u_int32_t u_32_t; MTX_DEF) # define MUTEX_DESTROY(x) mtx_destroy(&(x)->ipf_lk) # define MUTEX_NUKE(x) bzero((x), sizeof(*(x))) +/* + * Whilst the sx(9) locks on FreeBSD have the right semantics and interface + * for what we want to use them for, despite testing showing they work - + * with a WITNESS kernel, it generates LOR messages. + */ # include -# define ATOMIC_INC(x) { mtx_lock(&ipf_rw.ipf_lk); (x)++; \ - mtx_unlock(&ipf_rw.ipf_lk); } -# define ATOMIC_DEC(x) { mtx_lock(&ipf_rw.ipf_lk); (x)--; \ - mtx_unlock(&ipf_rw.ipf_lk); } +# define ATOMIC_INC(x) { mtx_lock(&softc->ipf_rw.ipf_lk); (x)++; \ + mtx_unlock(&softc->ipf_rw.ipf_lk); } +# define ATOMIC_DEC(x) { mtx_lock(&softc->ipf_rw.ipf_lk); (x)--; \ + mtx_unlock(&softc->ipf_rw.ipf_lk); } # define ATOMIC_INCL(x) atomic_add_long(&(x), 1) # define ATOMIC_INC64(x) ATOMIC_INC(x) # define ATOMIC_INC32(x) atomic_add_32((u_int *)&(x), 1) -# define ATOMIC_INC16(x) atomic_add_16(&(x), 1) # define ATOMIC_DECL(x) atomic_add_long(&(x), -1) # define ATOMIC_DEC64(x) ATOMIC_DEC(x) # define ATOMIC_DEC32(x) atomic_add_32((u_int *)&(x), -1) -# define ATOMIC_DEC16(x) atomic_add_16(&(x), -1) # define SPL_X(x) ; # define SPL_NET(x) ; # define SPL_IMP(x) ; # define SPL_SCHED(x) ; -# else -# define SPL_SCHED(x) x = splhigh() -# endif /* __FreeBSD_version >= 500043 */ -# define MSGDSIZE(x) mbufchainlen(x) -# define M_LEN(x) (x)->m_len -# define M_DUPLICATE(x) m_copy((x), 0, M_COPYALL) +# define GET_MINOR dev2unit +# define MSGDSIZE(m) mbufchainlen(m) +# define M_LEN(m) (m)->m_len +# define M_ADJ(m,x) m_adj(m, x) +# define M_COPY(x) m_copy((x), 0, M_COPYALL) +# define M_DUP(m) m_dup(m, M_NOWAIT) # define IPF_PANIC(x,y) if (x) { printf y; panic("ipf_panic"); } typedef struct mbuf mb_t; # endif /* _KERNEL */ -# if __FreeBSD_version < 300000 -# include -# else -# if __FreeBSD_version < 400000 -# if defined(IPFILTER_LKM) && !defined(ACTUALLY_LKM_NOT_KERNEL) -# define ACTUALLY_LKM_NOT_KERNEL -# endif -# endif -# endif -# if (__FreeBSD_version >= 300000) typedef u_long ioctlcmd_t; -# else -typedef int ioctlcmd_t; -# endif typedef struct uio uio_t; typedef int minor_t; typedef u_int32_t u_32_t; # define U_32_T 1 -# define OS_RECOGNISED 1 -#endif /* __FreeBSD__ */ - - -/* ----------------------------------------------------------------------- */ -/* O P E N B S D */ -/* ----------------------------------------------------------------------- */ -#ifdef __OpenBSD__ -# ifdef INET6 -# define USE_INET6 -# endif - -# ifdef _KERNEL -# if !defined(IPFILTER_LKM) -# include "bpfilter.h" -# endif -# if (OpenBSD >= 200311) -# define SNPRINTF snprintf -# if defined(USE_INET6) -# include "netinet6/in6_var.h" -# include "netinet6/nd6.h" -# endif -# endif -# if (OpenBSD >= 200012) -# define HAVE_M_PULLDOWN 1 -# endif -# define COPYIN(a,b,c) copyin((caddr_t)(a), (caddr_t)(b), (c)) -# define COPYOUT(a,b,c) copyout((caddr_t)(a), (caddr_t)(b), (c)) -# define GETKTIME(x) microtime((struct timeval *)x) -# define MSGDSIZE(x) mbufchainlen(x) -# define M_LEN(x) (x)->m_len -# define M_DUPLICATE(x) m_copy((x), 0, M_COPYALL) -# define IPF_PANIC(x,y) if (x) { printf y; panic("ipf_panic"); } -typedef struct mbuf mb_t; -# endif /* _KERNEL */ -# if (OpenBSD >= 199603) -# define IFNAME(x, b) ((struct ifnet *)x)->if_xname -# define COPYIFNAME(v, x, b) \ - (void) strncpy(b, \ - ((struct ifnet *)x)->if_xname, \ - LIFNAMSIZ) -# define CACHE_HASH(x) ((((struct ifnet *)fin->fin_ifp)->if_index)&7) -# else -# define IFNAME(x, b) ((struct ifnet *)x)->if_name -# define CACHE_HASH(x) ((IFNAME(fin->fin_ifp)[0] + \ - ((struct ifnet *)fin->fin_ifp)->if_unit) & 7) -# endif - -typedef struct uio uio_t; -typedef u_long ioctlcmd_t; -typedef int minor_t; -typedef u_int32_t u_32_t; -# define U_32_T 1 - -# define OS_RECOGNISED 1 -#endif /* __OpenBSD__ */ - - -/* ----------------------------------------------------------------------- */ -/* B S D O S */ -/* ----------------------------------------------------------------------- */ -#ifdef _BSDI_VERSION -# ifdef INET6 -# define USE_INET6 -# endif - -# ifdef _KERNEL -# define GETKTIME(x) microtime((struct timeval *)x) -# define MSGDSIZE(x) mbufchainlen(x) -# define M_LEN(x) (x)->m_len -# define M_DUPLICATE(x) m_copy((x), 0, M_COPYALL) -# define IFNAME(x, b) ((struct ifnet *)x)->if_name -# define CACHE_HASH(x) ((IFNAME(fin->fin_ifp)[0] + \ - ((struct ifnet *)fin->fin_ifp)->if_unit) & 7) -typedef struct mbuf mb_t; -# endif /* _KERNEL */ - -# if (_BSDI_VERSION >= 199701) -typedef u_long ioctlcmd_t; -# else -typedef int ioctlcmd_t; -# endif -typedef u_int32_t u_32_t; -# define U_32_T 1 - -#endif /* _BSDI_VERSION */ - - -/* ----------------------------------------------------------------------- */ -/* S U N O S 4 */ -/* ----------------------------------------------------------------------- */ -#if defined(sun) && !defined(OS_RECOGNISED) /* SunOS4 */ -# ifdef _KERNEL -# include -# define GETKTIME(x) uniqtime((struct timeval *)x) -# define MSGDSIZE(x) mbufchainlen(x) -# define M_LEN(x) (x)->m_len -# define M_DUPLICATE(x) m_copy((x), 0, M_COPYALL) -# define IFNAME(x, b) ((struct ifnet *)x)->if_name -# define CACHE_HASH(x) ((IFNAME(fin->fin_ifp)[0] + \ - ((struct ifnet *)fin->fin_ifp)->if_unit) & 7) -# define GETIFP(n, v) ifunit(n, IFNAMSIZ) -# define KFREE(x) kmem_free((char *)(x), sizeof(*(x))) -# define KFREES(x,s) kmem_free((char *)(x), (s)) -# define SLEEP(id, n) sleep((id), PZERO+1) -# define WAKEUP(id,x) wakeup(id + x) -# define POLLWAKEUP(x) ; -# define UIOMOVE(a,b,c,d) uiomove((caddr_t)a,b,c,d) -# define IPF_PANIC(x,y) if (x) { printf y; panic("ipf_panic"); } - -extern void m_copydata __P((struct mbuf *, int, int, caddr_t)); -extern void m_copyback __P((struct mbuf *, int, int, caddr_t)); - -typedef struct mbuf mb_t; -# endif - -typedef struct uio uio_t; -typedef int ioctlcmd_t; -typedef int minor_t; -typedef unsigned int u_32_t; -# define U_32_T 1 - -# define OS_RECOGNISED 1 - -#endif /* SunOS 4 */ - -/* ----------------------------------------------------------------------- */ -/* L I N U X */ -/* ----------------------------------------------------------------------- */ -#if defined(linux) && !defined(OS_RECOGNISED) -#include -#include -# if (LINUX >= 20600) && defined(_KERNEL) -# define HDR_T_PRIVATE 1 -# endif -# undef USE_INET6 -# ifdef USE_INET6 -struct ip6_ext { - u_char ip6e_nxt; - u_char ip6e_len; -}; -# endif - -# ifdef _KERNEL -# define IPF_PANIC(x,y) if (x) { printf y; panic("ipf_panic"); } -# define COPYIN(a,b,c) copy_from_user((caddr_t)(b), (caddr_t)(a), (c)) -# define COPYOUT(a,b,c) copy_to_user((caddr_t)(b), (caddr_t)(a), (c)) -# define FREE_MB_T(m) kfree_skb(m) -# define GETKTIME(x) do_gettimeofday((struct timeval *)x) -# define POLLWAKEUP(x) ; -# ifdef wait_event_interruptible -# define SLEEP(x,s) wait_event_interruptible((*(x##_linux)), 0) -# else -# define SLEEP(x,s) 0, interruptible_sleep_on(x##_linux) -# endif -# define WAKEUP(x,y) wake_up(x##_linux + y) -# define UIOMOVE(a,b,c,d) uiomove((caddr_t)a,b,c,d) -# define USE_MUTEXES -# define KRWLOCK_T rwlock_t -# define KMUTEX_T spinlock_t -# define MUTEX_INIT(x,y) spin_lock_init(&(x)->ipf_lk) -# define MUTEX_ENTER(x) spin_lock(&(x)->ipf_lk) -# define MUTEX_EXIT(x) spin_unlock(&(x)->ipf_lk) -# define MUTEX_DESTROY(x) do { } while (0) -# define MUTEX_NUKE(x) bzero(&(x)->ipf_lk, sizeof((x)->ipf_lk)) -# define READ_ENTER(x) ipf_read_enter(x) -# define WRITE_ENTER(x) ipf_write_enter(x) -# define RWLOCK_INIT(x,y) ipf_rw_init(x, y) -# define RW_DESTROY(x) do { } while (0) -# define RWLOCK_EXIT(x) ipf_rw_exit(x) -# define MUTEX_DOWNGRADE(x) ipf_rw_downgrade(x) -# define ATOMIC_INCL(x) MUTEX_ENTER(&ipf_rw); (x)++; \ - MUTEX_EXIT(&ipf_rw) -# define ATOMIC_DECL(x) MUTEX_ENTER(&ipf_rw); (x)--; \ - MUTEX_EXIT(&ipf_rw) -# define ATOMIC_INC64(x) MUTEX_ENTER(&ipf_rw); (x)++; \ - MUTEX_EXIT(&ipf_rw) -# define ATOMIC_INC32(x) MUTEX_ENTER(&ipf_rw); (x)++; \ - MUTEX_EXIT(&ipf_rw) -# define ATOMIC_INC16(x) MUTEX_ENTER(&ipf_rw); (x)++; \ - MUTEX_EXIT(&ipf_rw) -# define ATOMIC_DEC64(x) MUTEX_ENTER(&ipf_rw); (x)--; \ - MUTEX_EXIT(&ipf_rw) -# define ATOMIC_DEC32(x) MUTEX_ENTER(&ipf_rw); (x)--; \ - MUTEX_EXIT(&ipf_rw) -# define ATOMIC_DEC16(x) MUTEX_ENTER(&ipf_rw); (x)--; \ - MUTEX_EXIT(&ipf_rw) -# define SPL_SCHED(x) do { } while (0) -# define SPL_IMP(x) do { } while (0) -# define SPL_NET(x) do { } while (0) -# define SPL_X(x) do { } while (0) -# define IFNAME(x) ((struct net_device*)x)->name -# define CACHE_HASH(x) ((IFNAME(fin->fin_ifp)[0] + \ - ((struct net_device *)fin->fin_ifp)->ifindex) & 7) -typedef struct sk_buff mb_t; -extern void m_copydata __P((mb_t *, int, int, caddr_t)); -extern void m_copyback __P((mb_t *, int, int, caddr_t)); -extern void m_adj __P((mb_t *, int)); -extern mb_t *m_pullup __P((mb_t *, int)); -# define mbuf sk_buff - -# define mtod(m, t) ((t)(m)->data) -# define m_data data -# define m_len len -# define m_next next -# define M_DUPLICATE(m) skb_clone((m), in_interrupt() ? GFP_ATOMIC : \ - GFP_KERNEL) -# define MSGDSIZE(m) (m)->len -# define M_LEN(m) (m)->len - -# define splnet(x) ; -# define printf printk -# define bcopy(s,d,z) memmove(d, s, z) -# define bzero(s,z) memset(s, 0, z) -# define bcmp(a,b,z) memcmp(a, b, z) - -# define ifnet net_device -# define if_xname name -# define if_unit ifindex - -# define KMALLOC(x,t) (x) = (t)kmalloc(sizeof(*(x)), \ - in_interrupt() ? GFP_ATOMIC : GFP_KERNEL) -# define KFREE(x) kfree(x) -# define KMALLOCS(x,t,s) (x) = (t)kmalloc((s), \ - in_interrupt() ? GFP_ATOMIC : GFP_KERNEL) -# define KFREES(x,s) kfree(x) - -# define GETIFP(n,v) dev_get_by_name(n) - -# else -# include - -struct mbuf { -}; - -# ifndef _NET_ROUTE_H -struct rtentry { -}; -# endif - -struct ifnet { - char if_xname[IFNAMSIZ]; - int if_unit; - int (* if_output) __P((struct ifnet *, struct mbuf *, struct sockaddr *, struct rtentry *)); - struct ifaddr *if_addrlist; -}; -# define IFNAME(x) ((struct ifnet *)x)->if_xname - -# endif /* _KERNEL */ - -# define COPYIFNAME(v, x, b) \ - (void) strncpy(b, \ - ((struct ifnet *)x)->if_xname, \ - LIFNAMSIZ) - -# include -# define FWRITE FMODE_WRITE -# define FREAD FMODE_READ - -# define __USE_MISC 1 -# define __FAVOR_BSD 1 - -typedef struct uio { - struct iovec *uio_iov; - void *uio_file; - char *uio_buf; - int uio_iovcnt; - int uio_offset; - size_t uio_resid; - int uio_rw; -} uio_t; - -extern int uiomove __P((caddr_t, size_t, int, struct uio *)); - -# define UIO_READ 1 -# define UIO_WRITE 2 - -typedef u_long ioctlcmd_t; -typedef int minor_t; -typedef u_int32_t u_32_t; -# define U_32_T 1 - -# define OS_RECOGNISED 1 - -#endif - - -/* ----------------------------------------------------------------------- */ -/* A I X */ -/* ----------------------------------------------------------------------- */ -#if defined(_AIX51) -# undef MENTAT - -# include -# include - -# ifdef _KERNEL -# define rw_read_locked(x) 0 -# include -# include -# define KMUTEX_T simple_lock_t -# define KRWLOCK_T complex_lock_t -# define USE_MUTEXES 1 -# define USE_SPL 1 -# define READ_ENTER(x) lock_read((x)->ipf_lk) -# define WRITE_ENTER(x) lock_write((x)->ipf_lk) -# define MUTEX_DOWNGRADE(x) lock_write_to_read((x)->ipf_lk) -# define RWLOCK_INIT(x, y) lock_alloc(&(x)->ipf_lk, \ - LOCK_ALLOC_PIN, \ - (u_short)y, 0); \ - lock_init((x)->ipf_lk, TRUE) -# define RWLOCK_EXIT(x) lock_done((x)->ipf_lk) -# define RW_DESTROY(x) lock_free(&(x)->ipf_lk) -# define MUTEX_ENTER(x) simple_lock((x)->ipf_lk) -# define MUTEX_INIT(x, y) lock_alloc(&(x)->ipf_lk, \ - LOCK_ALLOC_PIN, \ - (u_short)y, 0); \ - simple_lock_init((x)->ipf_lk) -# define MUTEX_DESTROY(x) lock_free(&(x)->ipf_lk) -# define MUTEX_EXIT(x) simple_unlock((x)->ipf_lk) -# define MUTEX_NUKE(x) bzero(&(x)->ipf_lk, sizeof((x)->ipf_lk)) -# define ATOMIC_INC64(x) { MUTEX_ENTER(&ipf_rw); (x)++; \ - MUTEX_EXIT(&ipf_rw); } -# define ATOMIC_DEC64(x) { MUTEX_ENTER(&ipf_rw); (x)--; \ - MUTEX_EXIT(&ipf_rw); } -# define ATOMIC_INC32(x) { MUTEX_ENTER(&ipf_rw); (x)++; \ - MUTEX_EXIT(&ipf_rw); } -# define ATOMIC_DEC32(x) { MUTEX_ENTER(&ipf_rw); (x)--; \ - MUTEX_EXIT(&ipf_rw); } -# define ATOMIC_INCL(x) { MUTEX_ENTER(&ipf_rw); (x)++; \ - MUTEX_EXIT(&ipf_rw); } -# define ATOMIC_DECL(x) { MUTEX_ENTER(&ipf_rw); (x)--; \ - MUTEX_EXIT(&ipf_rw); } -# define ATOMIC_INC(x) { MUTEX_ENTER(&ipf_rw); (x)++; \ - MUTEX_EXIT(&ipf_rw); } -# define ATOMIC_DEC(x) { MUTEX_ENTER(&ipf_rw); (x)--; \ - MUTEX_EXIT(&ipf_rw); } -# define SPL_SCHED(x) x = splsched() -# define SPL_NET(x) x = splnet() -# define SPL_IMP(x) x = splimp() -# undef SPL_X -# define SPL_X(x) splx(x) -# define UIOMOVE(a,b,c,d) uiomove((caddr_t)a,b,c,d) -extern void* getifp __P((char *, int)); -# define GETIFP(n, v) getifp(n, v) -# define GET_MINOR minor -# define SLEEP(id, n) sleepx((id), PZERO+1, 0) -# define WAKEUP(id,x) wakeup(id) -# define POLLWAKEUP(x) ; -# define COPYIN(a,b,c) copyin((caddr_t)(a), (caddr_t)(b), (c)) -# define COPYOUT(a,b,c) copyout((caddr_t)(a), (caddr_t)(b), (c)) -# define KMALLOC(a, b) MALLOC((a), b, sizeof(*(a)), M_TEMP, M_NOWAIT) -# define KMALLOCS(a, b, c) MALLOC((a), b, (c), M_TEMP, \ - ((c) > 4096) ? M_WAITOK : M_NOWAIT) -# define KFREE(x) FREE((x), M_TEMP) -# define KFREES(x,s) FREE((x), M_TEMP) -# define MSGDSIZE(x) mbufchainlen(x) -# define M_LEN(x) (x)->m_len -# define M_DUPLICATE(x) m_copy((x), 0, M_COPYALL) -# define GETKTIME(x) -# define IFNAME(x, b) ((struct ifnet *)x)->if_name -# define CACHE_HASH(x) ((IFNAME(fin->fin_ifp)[0] + \ - ((struct ifnet *)fin->fin_ifp)->if_unit) & 7) -# define IPF_PANIC(x,y) -typedef struct mbuf mb_t; -# endif /* _KERNEL */ - -/* - * These are from's Solaris' #defines for little endian. - */ -#if !defined(IP6F_MORE_FRAG) -# define IP6F_MORE_FRAG 0x0100 -#endif -#if !defined(IP6F_RESERVED_MASK) -# define IP6F_RESERVED_MASK 0x0600 -#endif -#if !defined(IP6F_OFF_MASK) -# define IP6F_OFF_MASK 0xf8ff -#endif - -struct ip6_ext { - u_char ip6e_nxt; - u_char ip6e_len; -}; - -typedef int ioctlcmd_t; -typedef int minor_t; -/* - * Really, any arch where sizeof(long) != sizeof(int). - */ -typedef unsigned int u_32_t; -# define U_32_T 1 - -# define OS_RECOGNISED 1 -#endif /* _AIX51 */ - - -#ifndef OS_RECOGNISED -#error ip_compat.h does not recognise this platform/OS. -#endif - /* ----------------------------------------------------------------------- */ /* G E N E R I C */ /* ----------------------------------------------------------------------- */ -#ifndef OS_RECOGNISED -#endif /* * For BSD kernels, if bpf is in the kernel, enable ipfilter to use bpf in @@ -1427,15 +261,21 @@ typedef unsigned int u_32_t; /* * Userland locking primitives */ +#ifndef _KERNEL +#if !defined(KMUTEX_FILL_SZ) +# define KMUTEX_FILL_SZ 1 +#endif +#if !defined(KRWLOCK_FILL_SZ) +# define KRWLOCK_FILL_SZ 1 +#endif +#endif + typedef struct { char *eMm_owner; char *eMm_heldin; u_int eMm_magic; int eMm_held; int eMm_heldat; -#if defined(__hpux) || defined(__linux) - char eMm_fill[8]; -#endif } eMmutex_t; typedef struct { @@ -1445,26 +285,25 @@ typedef struct { short eMrw_read; short eMrw_write; int eMrw_heldat; -#ifdef __hpux - char eMm_fill[24]; -#endif } eMrwlock_t; typedef union { + char _fill[KMUTEX_FILL_SZ]; #ifdef KMUTEX_T struct { KMUTEX_T ipf_slk; - char *ipf_lname; + const char *ipf_lname; } ipf_lkun_s; #endif eMmutex_t ipf_emu; } ipfmutex_t; typedef union { + char _fill[KRWLOCK_FILL_SZ]; #ifdef KRWLOCK_T struct { KRWLOCK_T ipf_slk; - char *ipf_lname; + const char *ipf_lname; int ipf_sr; int ipf_sw; u_int ipf_magic; @@ -1488,14 +327,12 @@ typedef union { # define INLINE __inline__ #endif -#if defined(linux) && defined(_KERNEL) -extern void ipf_read_enter __P((ipfrwlock_t *)); -extern void ipf_write_enter __P((ipfrwlock_t *)); -extern void ipf_rw_exit __P((ipfrwlock_t *)); -extern void ipf_rw_init __P((ipfrwlock_t *, char *)); -extern void ipf_rw_downgrade __P((ipfrwlock_t *)); +#if defined(__FreeBSD_version) && defined(_KERNEL) + CTASSERT(sizeof(ipfrwlock_t) == KRWLOCK_FILL_SZ); + CTASSERT(sizeof(ipfmutex_t) == KMUTEX_FILL_SZ); #endif + /* * In a non-kernel environment, there are a lot of macros that need to be * filled in to be null-ops or to point to some compatibility function, @@ -1504,18 +341,40 @@ extern void ipf_rw_downgrade __P((ipfrwlock_t *)); #ifndef _KERNEL typedef struct mb_s { struct mb_s *mb_next; + char *mb_data; + void *mb_ifp; int mb_len; + int mb_flags; u_long mb_buf[2048]; } mb_t; # undef m_next # define m_next mb_next -# define MSGDSIZE(x) (x)->mb_len /* XXX - from ipt.c */ -# define M_LEN(x) (x)->mb_len -# define M_DUPLICATE(x) (x) +# undef m_len +# define m_len mb_len +# undef m_flags +# define m_flags mb_flags +# undef m_data +# define m_data mb_data +# undef M_MCAST +# define M_MCAST 0x01 +# undef M_BCAST +# define M_BCAST 0x02 +# undef M_MBCAST +# define M_MBCAST 0x04 +# define MSGDSIZE(m) msgdsize(m) +# define M_LEN(m) (m)->mb_len +# define M_ADJ(m,x) (m)->mb_len += x +# define M_COPY(m) dupmbt(m) +# define M_DUP(m) dupmbt(m) # define GETKTIME(x) gettimeofday((struct timeval *)(x), NULL) -# undef MTOD -# define MTOD(m, t) ((t)(m)->mb_buf) -# define FREE_MB_T(x) +# define MTOD(m, t) ((t)(m)->mb_data) +# define FREE_MB_T(m) freembt(m) +# define ALLOC_MB_T(m,l) (m) = allocmbt(l) +# define PREP_MB_T(f, m) do { \ + (m)->mb_next = *(f)->fin_mp; \ + *(fin)->fin_mp = (m); \ + (f)->fin_m = (m); \ + } while (0) # define SLEEP(x,y) 1; # define WAKEUP(x,y) ; # define POLLWAKEUP(y) ; @@ -1530,6 +389,8 @@ typedef struct mb_s { # define KFREE(x) free(x) # define KFREES(x,s) free(x) # define GETIFP(x, v) get_unit(x,v) +# define GETIFMTU_4(x) 2048 +# define GETIFMTU_6(x) 2048 # define COPYIN(a,b,c) bcopywrap((a), (b), (c)) # define COPYOUT(a,b,c) bcopywrap((a), (b), (c)) # define COPYDATA(m, o, l, b) bcopy(MTOD((mb_t *)m, char *) + (o), \ @@ -1541,16 +402,18 @@ typedef struct mb_s { extern void m_copydata __P((mb_t *, int, int, caddr_t)); extern int ipfuiomove __P((caddr_t, int, int, struct uio *)); extern int bcopywrap __P((void *, void *, size_t)); -# ifndef CACHE_HASH -# define CACHE_HASH(x) ((IFNAME(fin->fin_ifp)[0] + \ - ((struct ifnet *)fin->fin_ifp)->if_unit) & 7) -# endif +extern mb_t *allocmbt __P((size_t)); +extern mb_t *dupmbt __P((mb_t *)); +extern void freembt __P((mb_t *)); -# define MUTEX_DESTROY(x) eMmutex_destroy(&(x)->ipf_emu) +# define MUTEX_DESTROY(x) eMmutex_destroy(&(x)->ipf_emu, \ + __FILE__, __LINE__) # define MUTEX_ENTER(x) eMmutex_enter(&(x)->ipf_emu, \ __FILE__, __LINE__) -# define MUTEX_EXIT(x) eMmutex_exit(&(x)->ipf_emu) -# define MUTEX_INIT(x,y) eMmutex_init(&(x)->ipf_emu, y) +# define MUTEX_EXIT(x) eMmutex_exit(&(x)->ipf_emu, \ + __FILE__, __LINE__) +# define MUTEX_INIT(x,y) eMmutex_init(&(x)->ipf_emu, y, \ + __FILE__, __LINE__) # define MUTEX_NUKE(x) bzero((x), sizeof(*(x))) # define MUTEX_DOWNGRADE(x) eMrwlock_downgrade(&(x)->ipf_emu, \ @@ -1566,10 +429,10 @@ extern int bcopywrap __P((void *, void *, size_t)); # define USE_MUTEXES 1 -extern void eMmutex_destroy __P((eMmutex_t *)); +extern void eMmutex_destroy __P((eMmutex_t *, char *, int)); extern void eMmutex_enter __P((eMmutex_t *, char *, int)); -extern void eMmutex_exit __P((eMmutex_t *)); -extern void eMmutex_init __P((eMmutex_t *, char *)); +extern void eMmutex_exit __P((eMmutex_t *, char *, int)); +extern void eMmutex_init __P((eMmutex_t *, char *, char *, int)); extern void eMrwlock_destroy __P((eMrwlock_t *)); extern void eMrwlock_exit __P((eMrwlock_t *)); extern void eMrwlock_init __P((eMrwlock_t *, char *)); @@ -1579,6 +442,8 @@ extern void eMrwlock_downgrade __P((eMrwlock_t *, char *, int)); #endif +extern mb_t *allocmbt(size_t); + #define MAX_IPV4HDR ((0xf << 2) + sizeof(struct icmp) + sizeof(ip_t) + 8) #ifndef IP_OFFMASK @@ -1590,13 +455,15 @@ extern void eMrwlock_downgrade __P((eMrwlock_t *, char *, int)); * On BSD's use quad_t as a guarantee for getting at least a 64bit sized * object. */ -#if (BSD > 199306) +#if !defined(__amd64__) && BSD_GT_YEAR(199306) # define USE_QUAD_T # define U_QUAD_T unsigned long long # define QUAD_T long long #else /* BSD > 199306 */ -# define U_QUAD_T u_long -# define QUAD_T long +# if !defined(U_QUAD_T) +# define U_QUAD_T u_long +# define QUAD_T long +# endif #endif /* BSD > 199306 */ @@ -1605,11 +472,9 @@ extern void eMrwlock_downgrade __P((eMrwlock_t *, char *, int)); defined(__osf__) || defined(linux) # include # include -# if !defined(linux) # if defined(_KERNEL) && !defined(__osf__) # include # endif -# endif typedef struct ip6_hdr ip6_t; # endif #endif @@ -1619,23 +484,20 @@ typedef struct ip6_hdr ip6_t; #endif #if defined(_KERNEL) -# ifdef MENTAT +# if defined(MENTAT) && !defined(INSTANCES) # define COPYDATA mb_copydata # define COPYBACK mb_copyback # else # define COPYDATA m_copydata # define COPYBACK m_copyback # endif -# if (BSD >= 199306) || defined(__FreeBSD__) # if (defined(__NetBSD_Version__) && (__NetBSD_Version__ < 105180000)) || \ defined(__FreeBSD__) || (defined(OpenBSD) && (OpenBSD < 200206)) || \ defined(_BSDI_VERSION) # include # endif -# if !defined(__FreeBSD__) || (defined (__FreeBSD_version) && \ - (__FreeBSD_version >= 300000)) -# if (defined(__NetBSD_Version__) && (__NetBSD_Version__ >= 105180000)) || \ - (defined(OpenBSD) && (OpenBSD >= 200111)) +# if !defined(__FreeBSD__) || FREEBSD_GE_REV(300000) +# if NETBSD_GE_REV(105180000) || OPENBSD_GE_REV(200111) # include # else # include @@ -1661,33 +523,31 @@ MALLOC_DECLARE(M_IPFILTER); # endif /* M_IPFILTER */ # endif /* M_PFIL */ # endif /* IPFILTER_M_IPFILTER */ -# if defined(__FreeBSD__) && __FreeBSD_version >= 800051 -# define KMALLOC(a, b) do { \ - a = (b)malloc(sizeof(*(a)), _M_IPF, M_NOWAIT); \ - } while (0) -# define KMALLOCS(a, b, c) do { \ - a = (b)malloc((c), _M_IPF, ((c) > 4096) ? M_WAITOK : M_NOWAIT); \ - } while (0) -# define KFREE(x) free((x), _M_IPF) -# define KFREES(x,s) free((x), _M_IPF) -# else +# if !defined(KMALLOC) # define KMALLOC(a, b) MALLOC((a), b, sizeof(*(a)), _M_IPF, M_NOWAIT) -# if !defined(KMALLOCS) -# define KMALLOCS(a, b, c) MALLOC((a), b, (c), _M_IPF, M_NOWAIT) -# endif +# endif +# if !defined(KMALLOCS) +# define KMALLOCS(a, b, c) MALLOC((a), b, (c), _M_IPF, M_NOWAIT) +# endif +# if !defined(KFREE) # define KFREE(x) FREE((x), _M_IPF) -# define KFREES(x,s) FREE((x), _M_IPF) +# endif +# if !defined(KFREES) +# define KFREES(x,s) FREE((x), _M_IPF) # endif # define UIOMOVE(a,b,c,d) uiomove((caddr_t)a,b,d) # define SLEEP(id, n) tsleep((id), PPAUSE|PCATCH, n, 0) # define WAKEUP(id,x) wakeup(id+x) -# define POLLWAKEUP(x) selwakeup(ipfselwait+x) +# if !defined(POLLWAKEUP) +# define POLLWAKEUP(x) selwakeup(softc->ipf_selwait+x) +# endif # define GETIFP(n, v) ifunit(n) -# endif /* (Free)BSD */ +# define GETIFMTU_4(x) ((struct ifnet *)x)->if_mtu +# define GETIFMTU_6(x) ((struct ifnet *)x)->if_mtu # if !defined(USE_MUTEXES) && !defined(SPL_NET) # if (defined(NetBSD) && (NetBSD <= 1991011) && (NetBSD >= 199407)) || \ - (defined(OpenBSD) && (OpenBSD >= 200006)) + OPENBSD_GE_REV(200006) # define SPL_NET(x) x = splsoftnet() # else # define SPL_IMP(x) x = splimp() @@ -1702,6 +562,45 @@ MALLOC_DECLARE(M_IPFILTER); # ifndef FREE_MB_T # define FREE_MB_T(m) m_freem(m) # endif +# ifndef ALLOC_MB_T +# ifdef MGETHDR +# define ALLOC_MB_T(m,l) do { \ + MGETHDR((m), M_DONTWAIT, MT_HEADER); \ + if ((m) != NULL) { \ + (m)->m_len = (l); \ + (m)->m_pkthdr.len = (l); \ + } \ + } while (0) +# else +# define ALLOC_MB_T(m,l) do { \ + MGET((m), M_DONTWAIT, MT_HEADER); \ + if ((m) != NULL) { \ + (m)->m_len = (l); \ + (m)->m_pkthdr.len = (l); \ + } \ + } while (0) +# endif +# endif +# ifndef PREP_MB_T +# define PREP_MB_T(f, m) do { \ + mb_t *_o = *(f)->fin_mp; \ + (m)->m_next = _o; \ + *(fin)->fin_mp = (m); \ + if (_o->m_flags & M_PKTHDR) { \ + (m)->m_pkthdr.len += \ + _o->m_pkthdr.len; \ + (m)->m_pkthdr.rcvif = \ + _o->m_pkthdr.rcvif; \ + } \ + } while (0) +# endif +# ifndef M_DUP +# ifdef M_COPYALL +# define M_DUP(m) m_dup(m, 0, M_COPYALL, 0) +# else +# define M_DUP(m) m_dup(m) +# endif +# endif # ifndef MTOD # define MTOD(m,t) mtod(m,t) @@ -1725,13 +624,13 @@ MALLOC_DECLARE(M_IPFILTER); #endif /* _KERNEL */ #if !defined(IFNAME) && !defined(_KERNEL) -# define IFNAME(x) ((struct ifnet *)x)->if_name +# define IFNAME(x) get_ifname((struct ifnet *)x) #endif #ifndef COPYIFNAME # define NEED_FRGETIFNAME -extern char *fr_getifname __P((struct ifnet *, char *)); +extern char *ipf_getifname __P((struct ifnet *, char *)); # define COPYIFNAME(v, x, b) \ - fr_getifname((struct ifnet *)x, b) + ipf_getifname((struct ifnet *)x, b) #endif #ifndef ASSERT @@ -1753,9 +652,7 @@ extern char *fr_getifname __P((struct ifnet *, char *)); */ #define ISALNUM(x) isalnum((u_char)(x)) #define ISALPHA(x) isalpha((u_char)(x)) -#define ISASCII(x) isascii((u_char)(x)) #define ISDIGIT(x) isdigit((u_char)(x)) -#define ISPRINT(x) isprint((u_char)(x)) #define ISSPACE(x) isspace((u_char)(x)) #define ISUPPER(x) isupper((u_char)(x)) #define ISXDIGIT(x) isxdigit((u_char)(x)) @@ -1803,11 +700,9 @@ extern char *fr_getifname __P((struct ifnet *, char *)); # define ATOMIC_INCL ATOMIC_INC # define ATOMIC_INC64 ATOMIC_INC # define ATOMIC_INC32 ATOMIC_INC -# define ATOMIC_INC16 ATOMIC_INC # define ATOMIC_DECL ATOMIC_DEC # define ATOMIC_DEC64 ATOMIC_DEC # define ATOMIC_DEC32 ATOMIC_DEC -# define ATOMIC_DEC16 ATOMIC_DEC #endif #ifndef HDR_T_PRIVATE @@ -1824,7 +719,10 @@ typedef struct tcpiphdr tcpiphdr_t; #endif #ifndef offsetof -# define offsetof(t,m) (int)((&((t *)0L)->m)) +# define offsetof(t,m) (size_t)((&((t *)0L)->m)) +#endif +#ifndef stsizeof +# define stsizeof(t,m) sizeof(((t *)0L)->m) #endif /* @@ -1871,9 +769,9 @@ typedef struct tcpiphdr tcpiphdr_t; #define TCPF_ALL (TH_FIN|TH_SYN|TH_RST|TH_PUSH|TH_ACK|TH_URG|\ TH_ECN|TH_CWR) -#if (BSD >= 199306) && !defined(m_act) +#if BSD_GE_YEAR(199306) && !defined(m_act) # define m_act m_nextpkt -#endif +#endif /* * Security Options for Intenet Protocol (IPSO) as defined in RFC 1108. @@ -1910,7 +808,7 @@ typedef struct tcpiphdr tcpiphdr_t; * IP option #defines */ #undef IPOPT_RR -#define IPOPT_RR 7 +#define IPOPT_RR 7 #undef IPOPT_ZSU #define IPOPT_ZSU 10 /* ZSU */ #undef IPOPT_MTUP @@ -1958,6 +856,8 @@ typedef struct tcpiphdr tcpiphdr_t; #define IPOPT_UMP 152 #undef IPOPT_FINN #define IPOPT_FINN 205 /* FINN */ +#undef IPOPT_AH +#define IPOPT_AH 256+IPPROTO_AH #ifndef TCPOPT_EOL # define TCPOPT_EOL 0 @@ -2236,8 +1136,11 @@ typedef struct tcpiphdr tcpiphdr_t; #ifndef IPPROTO_HOPOPTS # define IPPROTO_HOPOPTS 0 #endif +#ifndef IPPROTO_IPIP +# define IPPROTO_IPIP 4 +#endif #ifndef IPPROTO_ENCAP -# define IPPROTO_ENCAP 4 +# define IPPROTO_ENCAP 98 #endif #ifndef IPPROTO_IPV6 # define IPPROTO_IPV6 41 @@ -2436,6 +1339,38 @@ typedef struct tcpiphdr tcpiphdr_t; # define ICMP6_NI_SUBJ_IPV4 2 #endif +#ifndef MLD_MTRACE_RESP +# define MLD_MTRACE_RESP 200 +#endif +#ifndef MLD_MTRACE +# define MLD_MTRACE 201 +#endif +#ifndef MLD6_MTRACE_RESP +# define MLD6_MTRACE_RESP MLD_MTRACE_RESP +#endif +#ifndef MLD6_MTRACE +# define MLD6_MTRACE MLD_MTRACE +#endif + +#if !defined(IPV6_FLOWINFO_MASK) +# if (BYTE_ORDER == BIG_ENDIAN) || defined(_BIG_ENDIAN) +# define IPV6_FLOWINFO_MASK 0x0fffffff /* flow info (28 bits) */ +# else +# if(BYTE_ORDER == LITTLE_ENDIAN) || !defined(_BIG_ENDIAN) +# define IPV6_FLOWINFO_MASK 0xffffff0f /* flow info (28 bits) */ +# endif /* LITTLE_ENDIAN */ +# endif +#endif +#if !defined(IPV6_FLOWLABEL_MASK) +# if (BYTE_ORDER == BIG_ENDIAN) || defined(_BIG_ENDIAN) +# define IPV6_FLOWLABEL_MASK 0x000fffff /* flow label (20 bits) */ +# else +# if (BYTE_ORDER == LITTLE_ENDIAN) || !defined(_BIG_ENDIAN) +# define IPV6_FLOWLABEL_MASK 0xffff0f00 /* flow label (20 bits) */ +# endif /* LITTLE_ENDIAN */ +# endif +#endif + /* * ECN is a new addition to TCP - RFC 2481 */ @@ -2516,14 +1451,50 @@ typedef struct tcpiphdr tcpiphdr_t; # define MIN(a,b) (((a)<(b))?(a):(b)) #endif +#ifdef RESCUE +# undef IPFILTER_BPF +#endif + #ifdef IPF_DEBUG # define DPRINT(x) printf x #else # define DPRINT(x) #endif -#ifdef RESCUE -# undef IPFILTER_BPF +#ifndef AF_INET6 +# define AF_INET6 26 #endif +#ifdef DTRACE_PROBE +# ifdef _KERNEL +# define DT(_n) DTRACE_PROBE(_n) +# define DT1(_n,_a,_b) DTRACE_PROBE1(_n,_a,_b) +# define DT2(_n,_a,_b,_c,_d) DTRACE_PROBE2(_n,_a,_b,_c,_d) +# define DT3(_n,_a,_b,_c,_d,_e,_f) \ + DTRACE_PROBE3(_n,_a,_b,_c,_d,_e,_f) +# define DT4(_n,_a,_b,_c,_d,_e,_f,_g,_h) \ + DTRACE_PROBE4(_n,_a,_b,_c,_d,_e,_f,_g,_h) +# else +# define DT(_n) +# define DT1(_n,_a,_b) +# define DT2(_n,_a,_b,_c,_d) +# define DT3(_n,_a,_b,_c,_d,_e,_f) +# define DT4(_n,_a,_b,_c,_d,_e,_f,_g,_h) +# endif +#else +# define DT(_n) +# define DT1(_n,_a,_b) +# define DT2(_n,_a,_b,_c,_d) +# define DT3(_n,_a,_b,_c,_d,_e,_f) +# define DT4(_n,_a,_b,_c,_d,_e,_f,_g,_h) +#endif + +struct ip6_routing { + u_char ip6r_nxt; /* next header */ + u_char ip6r_len; /* length in units of 8 octets */ + u_char ip6r_type; /* always zero */ + u_char ip6r_segleft; /* segments left */ + u_32_t ip6r_reserved; /* reserved field */ +}; + #endif /* __IP_COMPAT_H__ */ diff --git a/sys/contrib/ipfilter/netinet/ip_dns_pxy.c b/sys/contrib/ipfilter/netinet/ip_dns_pxy.c new file mode 100644 index 000000000000..df863b8f6fb6 --- /dev/null +++ b/sys/contrib/ipfilter/netinet/ip_dns_pxy.c @@ -0,0 +1,402 @@ +/* + * Copyright (C) 2012 by Darren Reed. + * + * See the IPFILTER.LICENCE file for details on licencing. + * + * $Id: ip_dns_pxy.c,v 1.1.2.10 2012/07/22 08:04:23 darren_r Exp $ + */ + +#define IPF_DNS_PROXY + +/* + * map ... proxy port dns/udp 53 { block .cnn.com; } + */ +typedef struct ipf_dns_filter { + struct ipf_dns_filter *idns_next; + char *idns_name; + int idns_namelen; + int idns_pass; +} ipf_dns_filter_t; + + +typedef struct ipf_dns_softc_s { + ipf_dns_filter_t *ipf_p_dns_list; + ipfrwlock_t ipf_p_dns_rwlock; + u_long ipf_p_dns_compress; + u_long ipf_p_dns_toolong; + u_long ipf_p_dns_nospace; +} ipf_dns_softc_t; + +int ipf_p_dns_allow_query __P((ipf_dns_softc_t *, dnsinfo_t *)); +int ipf_p_dns_ctl __P((ipf_main_softc_t *, void *, ap_ctl_t *)); +int ipf_p_dns_del __P((ipf_main_softc_t *, ap_session_t *)); +int ipf_p_dns_get_name __P((ipf_dns_softc_t *, char *, int, char *, int)); +int ipf_p_dns_inout __P((void *, fr_info_t *, ap_session_t *, nat_t *)); +int ipf_p_dns_match __P((fr_info_t *, ap_session_t *, nat_t *)); +int ipf_p_dns_match_names __P((ipf_dns_filter_t *, char *, int)); +int ipf_p_dns_new __P((void *, fr_info_t *, ap_session_t *, nat_t *)); +void *ipf_p_dns_soft_create __P((ipf_main_softc_t *)); +void ipf_p_dns_soft_destroy __P((ipf_main_softc_t *, void *)); + +typedef struct { + u_char dns_id[2]; + u_short dns_ctlword; + u_short dns_qdcount; + u_short dns_ancount; + u_short dns_nscount; + u_short dns_arcount; +} ipf_dns_hdr_t; + +#define DNS_QR(x) ((ntohs(x) & 0x8000) >> 15) +#define DNS_OPCODE(x) ((ntohs(x) & 0x7800) >> 11) +#define DNS_AA(x) ((ntohs(x) & 0x0400) >> 10) +#define DNS_TC(x) ((ntohs(x) & 0x0200) >> 9) +#define DNS_RD(x) ((ntohs(x) & 0x0100) >> 8) +#define DNS_RA(x) ((ntohs(x) & 0x0080) >> 7) +#define DNS_Z(x) ((ntohs(x) & 0x0070) >> 4) +#define DNS_RCODE(x) ((ntohs(x) & 0x000f) >> 0) + + +void * +ipf_p_dns_soft_create(softc) + ipf_main_softc_t *softc; +{ + ipf_dns_softc_t *softd; + + KMALLOC(softd, ipf_dns_softc_t *); + if (softd == NULL) + return NULL; + + bzero((char *)softd, sizeof(*softd)); + RWLOCK_INIT(&softd->ipf_p_dns_rwlock, "ipf dns rwlock"); + + return softd; +} + + +void +ipf_p_dns_soft_destroy(softc, arg) + ipf_main_softc_t *softc; + void *arg; +{ + ipf_dns_softc_t *softd = arg; + ipf_dns_filter_t *idns; + + while ((idns = softd->ipf_p_dns_list) != NULL) { + KFREES(idns->idns_name, idns->idns_namelen); + idns->idns_name = NULL; + idns->idns_namelen = 0; + softd->ipf_p_dns_list = idns->idns_next; + KFREE(idns); + } + RW_DESTROY(&softd->ipf_p_dns_rwlock); + + KFREE(softd); +} + + +int +ipf_p_dns_ctl(softc, arg, ctl) + ipf_main_softc_t *softc; + void *arg; + ap_ctl_t *ctl; +{ + ipf_dns_softc_t *softd = arg; + ipf_dns_filter_t *tmp, *idns, **idnsp; + int error = 0; + + /* + * To make locking easier. + */ + KMALLOC(tmp, ipf_dns_filter_t *); + + WRITE_ENTER(&softd->ipf_p_dns_rwlock); + for (idnsp = &softd->ipf_p_dns_list; (idns = *idnsp) != NULL; + idnsp = &idns->idns_next) { + if (idns->idns_namelen != ctl->apc_dsize) + continue; + if (!strncmp(ctl->apc_data, idns->idns_name, + idns->idns_namelen)) + break; + } + + switch (ctl->apc_cmd) + { + case APC_CMD_DEL : + if (idns == NULL) { + IPFERROR(80006); + error = ESRCH; + break; + } + *idnsp = idns->idns_next; + idns->idns_next = NULL; + KFREES(idns->idns_name, idns->idns_namelen); + idns->idns_name = NULL; + idns->idns_namelen = 0; + KFREE(idns); + break; + case APC_CMD_ADD : + if (idns != NULL) { + IPFERROR(80007); + error = EEXIST; + break; + } + if (tmp == NULL) { + IPFERROR(80008); + error = ENOMEM; + break; + } + idns = tmp; + tmp = NULL; + idns->idns_namelen = ctl->apc_dsize; + idns->idns_name = ctl->apc_data; + idns->idns_pass = ctl->apc_arg; + idns->idns_next = NULL; + *idnsp = idns; + ctl->apc_data = NULL; + ctl->apc_dsize = 0; + break; + default : + IPFERROR(80009); + error = EINVAL; + break; + } + RWLOCK_EXIT(&softd->ipf_p_dns_rwlock); + + if (tmp != NULL) { + KFREE(tmp); + tmp = NULL; + } + + return error; +} + + +/* ARGSUSED */ +int +ipf_p_dns_new(arg, fin, aps, nat) + void *arg; + fr_info_t *fin; + ap_session_t *aps; + nat_t *nat; +{ + dnsinfo_t *di; + int dlen; + + if (fin->fin_v != 4) + return -1; + + dlen = fin->fin_dlen - sizeof(udphdr_t); + if (dlen < sizeof(ipf_dns_hdr_t)) { + /* + * No real DNS packet is smaller than that. + */ + return -1; + } + + aps->aps_psiz = sizeof(dnsinfo_t); + KMALLOCS(di, dnsinfo_t *, sizeof(dnsinfo_t)); + if (di == NULL) { + printf("ipf_dns_new:KMALLOCS(%d) failed\n", sizeof(*di)); + return -1; + } + + MUTEX_INIT(&di->dnsi_lock, "dns lock"); + + aps->aps_data = di; + + dlen = fin->fin_dlen - sizeof(udphdr_t); + COPYDATA(fin->fin_m, fin->fin_hlen + sizeof(udphdr_t), + MIN(dlen, sizeof(di->dnsi_buffer)), di->dnsi_buffer); + di->dnsi_id = (di->dnsi_buffer[0] << 8) | di->dnsi_buffer[1]; + return 0; +} + + +/* ARGSUSED */ +int +ipf_p_dns_del(softc, aps) + ipf_main_softc_t *softc; + ap_session_t *aps; +{ +#ifdef USE_MUTEXES + dnsinfo_t *di = aps->aps_data; + + MUTEX_DESTROY(&di->dnsi_lock); +#endif + KFREES(aps->aps_data, aps->aps_psiz); + aps->aps_data = NULL; + aps->aps_psiz = 0; + return 0; +} + + +/* + * Tries to match the base string (in our ACL) with the query from a packet. + */ +int +ipf_p_dns_match_names(idns, query, qlen) + ipf_dns_filter_t *idns; + char *query; + int qlen; +{ + int blen; + char *base; + + blen = idns->idns_namelen; + base = idns->idns_name; + + if (blen > qlen) + return 1; + + if (blen == qlen) + return strncasecmp(base, query, qlen); + + /* + * If the base string string is shorter than the query, allow the + * tail of the base to match the same length tail of the query *if*: + * - the base string starts with a '*' (*cnn.com) + * - the base string represents a domain (.cnn.com) + * as otherwise it would not be possible to block just "cnn.com" + * without also impacting "foocnn.com", etc. + */ + if (*base == '*') { + base++; + blen--; + } else if (*base != '.') + return 1; + + return strncasecmp(base, query + qlen - blen, blen); +} + + +int +ipf_p_dns_get_name(softd, start, len, buffer, buflen) + ipf_dns_softc_t *softd; + char *start; + int len; + char *buffer; + int buflen; +{ + char *s, *t, clen; + int slen, blen; + + s = start; + t = buffer; + slen = len; + blen = buflen - 1; /* Always make room for trailing \0 */ + + while (*s != '\0') { + clen = *s; + if ((clen & 0xc0) == 0xc0) { /* Doesn't do compression */ + softd->ipf_p_dns_compress++; + return 0; + } + if (clen > slen) { + softd->ipf_p_dns_toolong++; + return 0; /* Does the name run off the end? */ + } + if ((clen + 1) > blen) { + softd->ipf_p_dns_nospace++; + return 0; /* Enough room for name+.? */ + } + s++; + bcopy(s, t, clen); + t += clen; + s += clen; + *t++ = '.'; + slen -= clen; + blen -= (clen + 1); + } + + *(t - 1) = '\0'; + return s - start; +} + + +int +ipf_p_dns_allow_query(softd, dnsi) + ipf_dns_softc_t *softd; + dnsinfo_t *dnsi; +{ + ipf_dns_filter_t *idns; + int len; + + len = strlen(dnsi->dnsi_buffer); + + for (idns = softd->ipf_p_dns_list; idns != NULL; idns = idns->idns_next) + if (ipf_p_dns_match_names(idns, dnsi->dnsi_buffer, len) == 0) + return idns->idns_pass; + return 0; +} + + +/* ARGSUSED */ +int +ipf_p_dns_inout(arg, fin, aps, nat) + void *arg; + fr_info_t *fin; + ap_session_t *aps; + nat_t *nat; +{ + ipf_dns_softc_t *softd = arg; + ipf_dns_hdr_t *dns; + dnsinfo_t *di; + char *data; + int dlen, q, rc = 0; + + if (fin->fin_dlen < sizeof(*dns)) + return APR_ERR(1); + + dns = (ipf_dns_hdr_t *)((char *)fin->fin_dp + sizeof(udphdr_t)); + + q = dns->dns_qdcount; + + data = (char *)(dns + 1); + dlen = fin->fin_dlen - sizeof(*dns) - sizeof(udphdr_t); + + di = aps->aps_data; + + READ_ENTER(&softd->ipf_p_dns_rwlock); + MUTEX_ENTER(&di->dnsi_lock); + + for (; (dlen > 0) && (q > 0); q--) { + int len; + + len = ipf_p_dns_get_name(softd, data, dlen, di->dnsi_buffer, + sizeof(di->dnsi_buffer)); + if (len == 0) { + rc = 1; + break; + } + rc = ipf_p_dns_allow_query(softd, di); + if (rc != 0) + break; + data += len; + dlen -= len; + } + MUTEX_EXIT(&di->dnsi_lock); + RWLOCK_EXIT(&softd->ipf_p_dns_rwlock); + + return APR_ERR(rc); +} + + +/* ARGSUSED */ +int +ipf_p_dns_match(fin, aps, nat) + fr_info_t *fin; + ap_session_t *aps; + nat_t *nat; +{ + dnsinfo_t *di = aps->aps_data; + ipf_dns_hdr_t *dnh; + + if ((fin->fin_dlen < sizeof(u_short)) || (fin->fin_flx & FI_FRAG)) + return -1; + + dnh = (ipf_dns_hdr_t *)((char *)fin->fin_dp + sizeof(udphdr_t)); + if (((dnh->dns_id[0] << 8) | dnh->dns_id[1]) != di->dnsi_id) + return -1; + return 0; +} diff --git a/sys/contrib/ipfilter/netinet/ip_dstlist.c b/sys/contrib/ipfilter/netinet/ip_dstlist.c new file mode 100644 index 000000000000..ce2e72e8130f --- /dev/null +++ b/sys/contrib/ipfilter/netinet/ip_dstlist.c @@ -0,0 +1,1351 @@ +/* + * Copyright (C) 2012 by Darren Reed. + * + * See the IPFILTER.LICENCE file for details on licencing. + */ +#if defined(KERNEL) || defined(_KERNEL) +# undef KERNEL +# undef _KERNEL +# define KERNEL 1 +# define _KERNEL 1 +#endif +#if defined(__osf__) +# define _PROTO_NET_H_ +#endif +#include +#include +#include +#include +#if !defined(_KERNEL) && !defined(__KERNEL__) +# include +# include +# include +# define _KERNEL +# ifdef __OpenBSD__ +struct file; +# endif +# include +# undef _KERNEL +#else +# include +# if defined(NetBSD) && (__NetBSD_Version__ >= 104000000) +# include +# endif +#endif +#include +#if !defined(linux) +# include +#endif +#include +#if defined(_KERNEL) && (!defined(__SVR4) && !defined(__svr4__)) +# include +#endif +#if defined(__SVR4) || defined(__svr4__) +# include +# include +# ifdef _KERNEL +# include +# endif +# include +# include +#endif +#if defined(__FreeBSD_version) && (__FreeBSD_version >= 300000) +# include +#endif + +#include +#include + +#include "netinet/ip_compat.h" +#include "netinet/ip_fil.h" +#include "netinet/ip_nat.h" +#include "netinet/ip_lookup.h" +#include "netinet/ip_dstlist.h" + +/* END OF INCLUDES */ + +#ifdef HAS_SYS_MD5_H +# include +#else +# include "md5.h" +#endif + +#if !defined(lint) +static const char rcsid[] = "@(#)$Id: ip_dstlist.c,v 1.13.2.12 2012/07/20 08:40:19 darren_r Exp $"; +#endif + +typedef struct ipf_dstl_softc_s { + ippool_dst_t *dstlist[LOOKUP_POOL_SZ]; + ippool_dst_t **tails[LOOKUP_POOL_SZ]; + ipf_dstl_stat_t stats; +} ipf_dstl_softc_t; + + +static void *ipf_dstlist_soft_create __P((ipf_main_softc_t *)); +static void ipf_dstlist_soft_destroy __P((ipf_main_softc_t *, void *)); +static int ipf_dstlist_soft_init __P((ipf_main_softc_t *, void *)); +static void ipf_dstlist_soft_fini __P((ipf_main_softc_t *, void *)); +static int ipf_dstlist_addr_find __P((ipf_main_softc_t *, void *, int, + void *, u_int)); +static size_t ipf_dstlist_flush __P((ipf_main_softc_t *, void *, + iplookupflush_t *)); +static int ipf_dstlist_iter_deref __P((ipf_main_softc_t *, void *, int, int, + void *)); +static int ipf_dstlist_iter_next __P((ipf_main_softc_t *, void *, ipftoken_t *, + ipflookupiter_t *)); +static int ipf_dstlist_node_add __P((ipf_main_softc_t *, void *, + iplookupop_t *, int)); +static int ipf_dstlist_node_del __P((ipf_main_softc_t *, void *, + iplookupop_t *, int)); +static int ipf_dstlist_stats_get __P((ipf_main_softc_t *, void *, + iplookupop_t *)); +static int ipf_dstlist_table_add __P((ipf_main_softc_t *, void *, + iplookupop_t *)); +static int ipf_dstlist_table_del __P((ipf_main_softc_t *, void *, + iplookupop_t *)); +static int ipf_dstlist_table_deref __P((ipf_main_softc_t *, void *, void *)); +static void *ipf_dstlist_table_find __P((void *, int, char *)); +static void ipf_dstlist_table_free __P((ipf_dstl_softc_t *, ippool_dst_t *)); +static void ipf_dstlist_table_remove __P((ipf_main_softc_t *, + ipf_dstl_softc_t *, ippool_dst_t *)); +static void ipf_dstlist_table_clearnodes __P((ipf_dstl_softc_t *, + ippool_dst_t *)); +static ipf_dstnode_t *ipf_dstlist_select __P((fr_info_t *, ippool_dst_t *)); +static void *ipf_dstlist_select_ref __P((void *, int, char *)); +static void ipf_dstlist_node_free __P((ipf_dstl_softc_t *, ippool_dst_t *, ipf_dstnode_t *)); +static int ipf_dstlist_node_deref __P((void *, ipf_dstnode_t *)); +static void ipf_dstlist_expire __P((ipf_main_softc_t *, void *)); +static void ipf_dstlist_sync __P((ipf_main_softc_t *, void *)); + +ipf_lookup_t ipf_dstlist_backend = { + IPLT_DSTLIST, + ipf_dstlist_soft_create, + ipf_dstlist_soft_destroy, + ipf_dstlist_soft_init, + ipf_dstlist_soft_fini, + ipf_dstlist_addr_find, + ipf_dstlist_flush, + ipf_dstlist_iter_deref, + ipf_dstlist_iter_next, + ipf_dstlist_node_add, + ipf_dstlist_node_del, + ipf_dstlist_stats_get, + ipf_dstlist_table_add, + ipf_dstlist_table_del, + ipf_dstlist_table_deref, + ipf_dstlist_table_find, + ipf_dstlist_select_ref, + ipf_dstlist_select_node, + ipf_dstlist_expire, + ipf_dstlist_sync +}; + + +/* ------------------------------------------------------------------------ */ +/* Function: ipf_dstlist_soft_create */ +/* Returns: int - 0 = success, else error */ +/* Parameters: softc(I) - pointer to soft context main structure */ +/* */ +/* Allocating a chunk of memory filled with 0's is enough for the current */ +/* soft context used with destination lists. */ +/* ------------------------------------------------------------------------ */ +static void * +ipf_dstlist_soft_create(softc) + ipf_main_softc_t *softc; +{ + ipf_dstl_softc_t *softd; + int i; + + KMALLOC(softd, ipf_dstl_softc_t *); + if (softd == NULL) { + IPFERROR(120028); + return NULL; + } + + bzero((char *)softd, sizeof(*softd)); + for (i = 0; i <= IPL_LOGMAX; i++) + softd->tails[i] = &softd->dstlist[i]; + + return softd; +} + + +/* ------------------------------------------------------------------------ */ +/* Function: ipf_dstlist_soft_destroy */ +/* Returns: Nil */ +/* Parameters: softc(I) - pointer to soft context main structure */ +/* arg(I) - pointer to local context to use */ +/* */ +/* For destination lists, the only thing we have to do when destroying the */ +/* soft context is free it! */ +/* ------------------------------------------------------------------------ */ +static void +ipf_dstlist_soft_destroy(softc, arg) + ipf_main_softc_t *softc; + void *arg; +{ + ipf_dstl_softc_t *softd = arg; + + KFREE(softd); +} + + +/* ------------------------------------------------------------------------ */ +/* Function: ipf_dstlist_soft_init */ +/* Returns: int - 0 = success, else error */ +/* Parameters: softc(I) - pointer to soft context main structure */ +/* arg(I) - pointer to local context to use */ +/* */ +/* There is currently no soft context for destination list management. */ +/* ------------------------------------------------------------------------ */ +static int +ipf_dstlist_soft_init(softc, arg) + ipf_main_softc_t *softc; + void *arg; +{ + return 0; +} + + +/* ------------------------------------------------------------------------ */ +/* Function: ipf_dstlist_soft_fini */ +/* Returns: Nil */ +/* Parameters: softc(I) - pointer to soft context main structure */ +/* arg(I) - pointer to local context to use */ +/* */ +/* There is currently no soft context for destination list management. */ +/* ------------------------------------------------------------------------ */ +static void +ipf_dstlist_soft_fini(softc, arg) + ipf_main_softc_t *softc; + void *arg; +{ + ipf_dstl_softc_t *softd = arg; + int i; + + for (i = -1; i <= IPL_LOGMAX; i++) { + while (softd->dstlist[i + 1] != NULL) { + ipf_dstlist_table_remove(softc, softd, + softd->dstlist[i + 1]); + } + } + + ASSERT(softd->stats.ipls_numderefnodes == 0); +} + + +/* ------------------------------------------------------------------------ */ +/* Function: ipf_dstlist_addr_find */ +/* Returns: int - 0 = success, else error */ +/* Parameters: softc(I) - pointer to soft context main structure */ +/* arg1(I) - pointer to local context to use */ +/* arg2(I) - pointer to local context to use */ +/* arg3(I) - pointer to local context to use */ +/* arg4(I) - pointer to local context to use */ +/* */ +/* There is currently no such thing as searching a destination list for an */ +/* address so this function becomes a no-op. Its presence is required as */ +/* ipf_lookup_res_name() stores the "addr_find" function pointer in the */ +/* pointer passed in to it as funcptr, although it could be a generic null- */ +/* op function rather than a specific one. */ +/* ------------------------------------------------------------------------ */ +/*ARGSUSED*/ +static int +ipf_dstlist_addr_find(softc, arg1, arg2, arg3, arg4) + ipf_main_softc_t *softc; + void *arg1, *arg3; + int arg2; + u_int arg4; +{ + return -1; +} + + +/* ------------------------------------------------------------------------ */ +/* Function: ipf_dstlist_flush */ +/* Returns: int - number of objects deleted */ +/* Parameters: softc(I) - pointer to soft context main structure */ +/* arg(I) - pointer to local context to use */ +/* fop(I) - pointer to lookup flush operation data */ +/* */ +/* Flush all of the destination tables that match the data passed in with */ +/* the iplookupflush_t. There are two ways to match objects: the device for */ +/* which they are to be used with and their name. */ +/* ------------------------------------------------------------------------ */ +static size_t +ipf_dstlist_flush(softc, arg, fop) + ipf_main_softc_t *softc; + void *arg; + iplookupflush_t *fop; +{ + ipf_dstl_softc_t *softd = arg; + ippool_dst_t *node, *next; + int n, i; + + for (n = 0, i = -1; i <= IPL_LOGMAX; i++) { + if (fop->iplf_unit != IPLT_ALL && fop->iplf_unit != i) + continue; + for (node = softd->dstlist[i + 1]; node != NULL; node = next) { + next = node->ipld_next; + + if ((*fop->iplf_name != '\0') && + strncmp(fop->iplf_name, node->ipld_name, + FR_GROUPLEN)) + continue; + + ipf_dstlist_table_remove(softc, softd, node); + n++; + } + } + return n; +} + + +/* ------------------------------------------------------------------------ */ +/* Function: ipf_dstlist_iter_deref */ +/* Returns: int - 0 = success, else error */ +/* Parameters: softc(I) - pointer to soft context main structure */ +/* arg(I) - pointer to local context to use */ +/* otype(I) - type of data structure to iterate through */ +/* unit(I) - device we are working with */ +/* data(I) - address of object in kernel space */ +/* */ +/* This function is called when the iteration token is being free'd and is */ +/* responsible for dropping the reference count of the structure it points */ +/* to. */ +/* ------------------------------------------------------------------------ */ +static int +ipf_dstlist_iter_deref(softc, arg, otype, unit, data) + ipf_main_softc_t *softc; + void *arg; + int otype, unit; + void *data; +{ + if (data == NULL) { + IPFERROR(120001); + return EINVAL; + } + + if (unit < -1 || unit > IPL_LOGMAX) { + IPFERROR(120002); + return EINVAL; + } + + switch (otype) + { + case IPFLOOKUPITER_LIST : + ipf_dstlist_table_deref(softc, arg, (ippool_dst_t *)data); + break; + + case IPFLOOKUPITER_NODE : + ipf_dstlist_node_deref(arg, (ipf_dstnode_t *)data); + break; + } + + return 0; +} + + +/* ------------------------------------------------------------------------ */ +/* Function: ipf_dstlist_iter_next */ +/* Returns: int - 0 = success, else error */ +/* Parameters: softc(I) - pointer to soft context main structure */ +/* arg(I) - pointer to local context to use */ +/* op(I) - pointer to lookup operation data */ +/* uid(I) - uid of process doing the ioctl */ +/* */ +/* This function is responsible for either selecting the next destination */ +/* list or node on a destination list to be returned as a user process */ +/* iterates through the list of destination lists or nodes. */ +/* ------------------------------------------------------------------------ */ +static int +ipf_dstlist_iter_next(softc, arg, token, iter) + ipf_main_softc_t *softc; + void *arg; + ipftoken_t *token; + ipflookupiter_t *iter; +{ + ipf_dstnode_t zn, *nextnode = NULL, *node = NULL; + ippool_dst_t zero, *next = NULL, *dsttab = NULL; + ipf_dstl_softc_t *softd = arg; + int err = 0; + void *hint; + + switch (iter->ili_otype) + { + case IPFLOOKUPITER_LIST : + dsttab = token->ipt_data; + if (dsttab == NULL) { + next = softd->dstlist[(int)iter->ili_unit + 1]; + } else { + next = dsttab->ipld_next; + } + + if (next != NULL) { + ATOMIC_INC32(next->ipld_ref); + token->ipt_data = next; + hint = next->ipld_next; + } else { + bzero((char *)&zero, sizeof(zero)); + next = &zero; + token->ipt_data = NULL; + hint = NULL; + } + break; + + case IPFLOOKUPITER_NODE : + node = token->ipt_data; + if (node == NULL) { + dsttab = ipf_dstlist_table_find(arg, iter->ili_unit, + iter->ili_name); + if (dsttab == NULL) { + IPFERROR(120004); + err = ESRCH; + nextnode = NULL; + } else { + if (dsttab->ipld_dests == NULL) + nextnode = NULL; + else + nextnode = *dsttab->ipld_dests; + dsttab = NULL; + } + } else { + nextnode = node->ipfd_next; + } + + if (nextnode != NULL) { + MUTEX_ENTER(&nextnode->ipfd_lock); + nextnode->ipfd_ref++; + MUTEX_EXIT(&nextnode->ipfd_lock); + token->ipt_data = nextnode; + hint = nextnode->ipfd_next; + } else { + bzero((char *)&zn, sizeof(zn)); + nextnode = &zn; + token->ipt_data = NULL; + hint = NULL; + } + break; + default : + IPFERROR(120003); + err = EINVAL; + break; + } + + if (err != 0) + return err; + + switch (iter->ili_otype) + { + case IPFLOOKUPITER_LIST : + if (dsttab != NULL) + ipf_dstlist_table_deref(softc, arg, dsttab); + err = COPYOUT(next, iter->ili_data, sizeof(*next)); + if (err != 0) { + IPFERROR(120005); + err = EFAULT; + } + break; + + case IPFLOOKUPITER_NODE : + if (node != NULL) + ipf_dstlist_node_deref(arg, node); + err = COPYOUT(nextnode, iter->ili_data, sizeof(*nextnode)); + if (err != 0) { + IPFERROR(120006); + err = EFAULT; + } + break; + } + + if (hint == NULL) + ipf_token_mark_complete(token); + + return err; +} + + +/* ------------------------------------------------------------------------ */ +/* Function: ipf_dstlist_node_add */ +/* Returns: int - 0 = success, else error */ +/* Parameters: softc(I) - pointer to soft context main structure */ +/* arg(I) - pointer to local context to use */ +/* op(I) - pointer to lookup operation data */ +/* uid(I) - uid of process doing the ioctl */ +/* Locks: WRITE(ipf_poolrw) */ +/* */ +/* Add a new node to a destination list. To do this, we only copy in the */ +/* frdest_t structure because that contains the only data required from the */ +/* application to create a new node. The frdest_t doesn't contain the name */ +/* itself. When loading filter rules, fd_name is a 'pointer' to the name. */ +/* In this case, the 'pointer' does not work, instead it is the length of */ +/* the name and the name is immediately following the frdest_t structure. */ +/* fd_name must include the trailing \0, so it should be strlen(str) + 1. */ +/* For simple sanity checking, an upper bound on the size of fd_name is */ +/* imposed - 128. */ +/* ------------------------------------------------------------------------ */ +static int +ipf_dstlist_node_add(softc, arg, op, uid) + ipf_main_softc_t *softc; + void *arg; + iplookupop_t *op; + int uid; +{ + ipf_dstl_softc_t *softd = arg; + ipf_dstnode_t *node, **nodes; + ippool_dst_t *d; + frdest_t dest; + int err; + + if (op->iplo_size < sizeof(frdest_t)) { + IPFERROR(120007); + return EINVAL; + } + + err = COPYIN(op->iplo_struct, &dest, sizeof(dest)); + if (err != 0) { + IPFERROR(120009); + return EFAULT; + } + + d = ipf_dstlist_table_find(arg, op->iplo_unit, op->iplo_name); + if (d == NULL) { + IPFERROR(120010); + return ESRCH; + } + + switch (dest.fd_addr.adf_family) + { + case AF_INET : + case AF_INET6 : + break; + default : + IPFERROR(120019); + return EINVAL; + } + + if (dest.fd_name < -1 || dest.fd_name > 128) { + IPFERROR(120018); + return EINVAL; + } + + KMALLOCS(node, ipf_dstnode_t *, sizeof(*node) + dest.fd_name); + if (node == NULL) { + softd->stats.ipls_nomem++; + IPFERROR(120008); + return ENOMEM; + } + bzero((char *)node, sizeof(*node) + dest.fd_name); + + bcopy(&dest, &node->ipfd_dest, sizeof(dest)); + node->ipfd_size = sizeof(*node) + dest.fd_name; + + if (dest.fd_name > 0) { + /* + * fd_name starts out as the length of the string to copy + * in (including \0) and ends up being the offset from + * fd_names (0). + */ + err = COPYIN((char *)op->iplo_struct + sizeof(dest), + node->ipfd_names, dest.fd_name); + if (err != 0) { + IPFERROR(120017); + KFREES(node, node->ipfd_size); + return EFAULT; + } + node->ipfd_dest.fd_name = 0; + } else { + node->ipfd_dest.fd_name = -1; + } + + if (d->ipld_nodes == d->ipld_maxnodes) { + KMALLOCS(nodes, ipf_dstnode_t **, + sizeof(*nodes) * (d->ipld_maxnodes + 1)); + if (nodes == NULL) { + softd->stats.ipls_nomem++; + IPFERROR(120022); + KFREES(node, node->ipfd_size); + return ENOMEM; + } + if (d->ipld_dests != NULL) { + bcopy(d->ipld_dests, nodes, + sizeof(*nodes) * d->ipld_maxnodes); + KFREES(d->ipld_dests, sizeof(*nodes) * d->ipld_nodes); + nodes[0]->ipfd_pnext = nodes; + } + d->ipld_dests = nodes; + d->ipld_maxnodes++; + } + d->ipld_dests[d->ipld_nodes] = node; + d->ipld_nodes++; + + if (d->ipld_nodes == 1) { + node->ipfd_pnext = d->ipld_dests; + } else if (d->ipld_nodes > 1) { + node->ipfd_pnext = &d->ipld_dests[d->ipld_nodes - 2]->ipfd_next; + } + *node->ipfd_pnext = node; + + MUTEX_INIT(&node->ipfd_lock, "ipf dst node lock"); + node->ipfd_uid = uid; + node->ipfd_ref = 1; + if (node->ipfd_dest.fd_name == 0) + (void) ipf_resolvedest(softc, node->ipfd_names, + &node->ipfd_dest, AF_INET); +#ifdef USE_INET6 + if (node->ipfd_dest.fd_name == 0 && + node->ipfd_dest.fd_ptr == (void *)-1) + (void) ipf_resolvedest(softc, node->ipfd_names, + &node->ipfd_dest, AF_INET6); +#endif + + softd->stats.ipls_numnodes++; + + return 0; +} + + +/* ------------------------------------------------------------------------ */ +/* Function: ipf_dstlist_node_deref */ +/* Returns: int - 0 = success, else error */ +/* Parameters: arg(I) - pointer to local context to use */ +/* node(I) - pointer to destionation node to free */ +/* */ +/* Dereference the use count by one. If it drops to zero then we can assume */ +/* that it has been removed from any lists/tables and is ripe for freeing. */ +/* The pointer to context is required for the purpose of maintaining */ +/* statistics. */ +/* ------------------------------------------------------------------------ */ +static int +ipf_dstlist_node_deref(arg, node) + void *arg; + ipf_dstnode_t *node; +{ + ipf_dstl_softc_t *softd = arg; + int ref; + + MUTEX_ENTER(&node->ipfd_lock); + ref = --node->ipfd_ref; + MUTEX_EXIT(&node->ipfd_lock); + + if (ref > 0) + return 0; + + if ((node->ipfd_flags & IPDST_DELETE) != 0) + softd->stats.ipls_numderefnodes--; + MUTEX_DESTROY(&node->ipfd_lock); + KFREES(node, node->ipfd_size); + softd->stats.ipls_numnodes--; + + return 0; +} + + +/* ------------------------------------------------------------------------ */ +/* Function: ipf_dstlist_node_del */ +/* Returns: int - 0 = success, else error */ +/* Parameters: softc(I) - pointer to soft context main structure */ +/* arg(I) - pointer to local context to use */ +/* op(I) - pointer to lookup operation data */ +/* uid(I) - uid of process doing the ioctl */ +/* */ +/* Look for a matching destination node on the named table and free it if */ +/* found. Because the name embedded in the frdest_t is variable in length, */ +/* it is necessary to allocate some memory locally, to complete this op. */ +/* ------------------------------------------------------------------------ */ +static int +ipf_dstlist_node_del(softc, arg, op, uid) + ipf_main_softc_t *softc; + void *arg; + iplookupop_t *op; + int uid; +{ + ipf_dstl_softc_t *softd = arg; + ipf_dstnode_t *node; + frdest_t frd, *temp; + ippool_dst_t *d; + size_t size; + int err; + + d = ipf_dstlist_table_find(arg, op->iplo_unit, op->iplo_name); + if (d == NULL) { + IPFERROR(120012); + return ESRCH; + } + + err = COPYIN(op->iplo_struct, &frd, sizeof(frd)); + if (err != 0) { + IPFERROR(120011); + return EFAULT; + } + + size = sizeof(*temp) + frd.fd_name; + KMALLOCS(temp, frdest_t *, size); + if (temp == NULL) { + softd->stats.ipls_nomem++; + IPFERROR(120026); + return ENOMEM; + } + + err = COPYIN(op->iplo_struct, temp, size); + if (err != 0) { + IPFERROR(120027); + return EFAULT; + } + + MUTEX_ENTER(&d->ipld_lock); + for (node = *d->ipld_dests; node != NULL; node = node->ipfd_next) { + if ((uid != 0) && (node->ipfd_uid != uid)) + continue; + if (node->ipfd_size != size) + continue; + if (!bcmp(&node->ipfd_dest.fd_ip6, &frd.fd_ip6, + size - offsetof(frdest_t, fd_ip6))) { + ipf_dstlist_node_free(softd, d, node); + MUTEX_EXIT(&d->ipld_lock); + KFREES(temp, size); + return 0; + } + } + MUTEX_EXIT(&d->ipld_lock); + KFREES(temp, size); + + return ESRCH; +} + + +/* ------------------------------------------------------------------------ */ +/* Function: ipf_dstlist_node_free */ +/* Returns: Nil */ +/* Parameters: softd(I) - pointer to the destination list context */ +/* d(I) - pointer to destination list */ +/* node(I) - pointer to node to free */ +/* Locks: MUTEX(ipld_lock) or WRITE(ipf_poolrw) */ +/* */ +/* Free the destination node by first removing it from any lists and then */ +/* checking if this was the last reference held to the object. While the */ +/* array of pointers to nodes is compacted, its size isn't reduced (by way */ +/* of allocating a new smaller one and copying) because the belief is that */ +/* it is likely the array will again reach that size. */ +/* ------------------------------------------------------------------------ */ +static void +ipf_dstlist_node_free(softd, d, node) + ipf_dstl_softc_t *softd; + ippool_dst_t *d; + ipf_dstnode_t *node; +{ + int i; + + /* + * Compact the array of pointers to nodes. + */ + for (i = 0; i < d->ipld_nodes; i++) + if (d->ipld_dests[i] == node) + break; + if (d->ipld_nodes - i > 1) { + bcopy(&d->ipld_dests[i + 1], &d->ipld_dests[i], + sizeof(*d->ipld_dests) * (d->ipld_nodes - i - 1)); + } + d->ipld_nodes--; + + if (node->ipfd_pnext != NULL) + *node->ipfd_pnext = node->ipfd_next; + if (node->ipfd_next != NULL) + node->ipfd_next->ipfd_pnext = node->ipfd_pnext; + node->ipfd_pnext = NULL; + node->ipfd_next = NULL; + + if ((node->ipfd_flags & IPDST_DELETE) == 0) { + softd->stats.ipls_numderefnodes++; + node->ipfd_flags |= IPDST_DELETE; + } + + ipf_dstlist_node_deref(softd, node); +} + + +/* ------------------------------------------------------------------------ */ +/* Function: ipf_dstlist_stats_get */ +/* Returns: int - 0 = success, else error */ +/* Parameters: softc(I) - pointer to soft context main structure */ +/* arg(I) - pointer to local context to use */ +/* op(I) - pointer to lookup operation data */ +/* */ +/* Return the current statistics for destination lists. This may be for all */ +/* of them or just information pertaining to a particular table. */ +/* ------------------------------------------------------------------------ */ +/*ARGSUSED*/ +static int +ipf_dstlist_stats_get(softc, arg, op) + ipf_main_softc_t *softc; + void *arg; + iplookupop_t *op; +{ + ipf_dstl_softc_t *softd = arg; + ipf_dstl_stat_t stats; + int unit, i, err = 0; + + if (op->iplo_size != sizeof(ipf_dstl_stat_t)) { + IPFERROR(120023); + return EINVAL; + } + + stats = softd->stats; + unit = op->iplo_unit; + if (unit == IPL_LOGALL) { + for (i = 0; i <= IPL_LOGMAX; i++) + stats.ipls_list[i] = softd->dstlist[i]; + } else if (unit >= 0 && unit <= IPL_LOGMAX) { + void *ptr; + + if (op->iplo_name[0] != '\0') + ptr = ipf_dstlist_table_find(softd, unit, + op->iplo_name); + else + ptr = softd->dstlist[unit + 1]; + stats.ipls_list[unit] = ptr; + } else { + IPFERROR(120024); + err = EINVAL; + } + + if (err == 0) { + err = COPYOUT(&stats, op->iplo_struct, sizeof(stats)); + if (err != 0) { + IPFERROR(120025); + return EFAULT; + } + } + return 0; +} + + +/* ------------------------------------------------------------------------ */ +/* Function: ipf_dstlist_table_add */ +/* Returns: int - 0 = success, else error */ +/* Parameters: softc(I) - pointer to soft context main structure */ +/* arg(I) - pointer to local context to use */ +/* op(I) - pointer to lookup operation data */ +/* */ +/* Add a new destination table to the list of those available for the given */ +/* device. Because we seldom operate on these objects (find/add/delete), */ +/* they are just kept in a simple linked list. */ +/* ------------------------------------------------------------------------ */ +static int +ipf_dstlist_table_add(softc, arg, op) + ipf_main_softc_t *softc; + void *arg; + iplookupop_t *op; +{ + ipf_dstl_softc_t *softd = arg; + ippool_dst_t user, *d, *new; + int unit, err; + + d = ipf_dstlist_table_find(arg, op->iplo_unit, op->iplo_name); + if (d != NULL) { + IPFERROR(120013); + return EEXIST; + } + + err = COPYIN(op->iplo_struct, &user, sizeof(user)); + if (err != 0) { + IPFERROR(120021); + return EFAULT; + } + + KMALLOC(new, ippool_dst_t *); + if (new == NULL) { + softd->stats.ipls_nomem++; + IPFERROR(120014); + return ENOMEM; + } + bzero((char *)new, sizeof(*new)); + + MUTEX_INIT(&new->ipld_lock, "ipf dst table lock"); + + strncpy(new->ipld_name, op->iplo_name, FR_GROUPLEN); + unit = op->iplo_unit; + new->ipld_unit = unit; + new->ipld_policy = user.ipld_policy; + new->ipld_seed = ipf_random(); + new->ipld_ref = 1; + + new->ipld_pnext = softd->tails[unit + 1]; + *softd->tails[unit + 1] = new; + softd->tails[unit + 1] = &new->ipld_next; + softd->stats.ipls_numlists++; + + return 0; +} + + +/* ------------------------------------------------------------------------ */ +/* Function: ipf_dstlist_table_del */ +/* Returns: int - 0 = success, else error */ +/* Parameters: softc(I) - pointer to soft context main structure */ +/* arg(I) - pointer to local context to use */ +/* op(I) - pointer to lookup operation data */ +/* */ +/* Find a named destinstion list table and delete it. If there are other */ +/* references to it, the caller isn't told. */ +/* ------------------------------------------------------------------------ */ +static int +ipf_dstlist_table_del(softc, arg, op) + ipf_main_softc_t *softc; + void *arg; + iplookupop_t *op; +{ + ippool_dst_t *d; + + d = ipf_dstlist_table_find(arg, op->iplo_unit, op->iplo_name); + if (d == NULL) { + IPFERROR(120015); + return ESRCH; + } + + if (d->ipld_dests != NULL) { + IPFERROR(120016); + return EBUSY; + } + + ipf_dstlist_table_remove(softc, arg, d); + + return 0; +} + + +/* ------------------------------------------------------------------------ */ +/* Function: ipf_dstlist_table_remove */ +/* Returns: Nil */ +/* Parameters: softc(I) - pointer to soft context main structure */ +/* softd(I) - pointer to the destination list context */ +/* d(I) - pointer to destination list */ +/* */ +/* Remove a given destination list from existance. While the IPDST_DELETE */ +/* flag is set every time we call this function and the reference count is */ +/* non-zero, the "numdereflists" counter is always incremented because the */ +/* decision about whether it will be freed or not is not made here. This */ +/* means that the only action the code can take here is to treat it as if */ +/* it will become a detached. */ +/* ------------------------------------------------------------------------ */ +static void +ipf_dstlist_table_remove(softc, softd, d) + ipf_main_softc_t *softc; + ipf_dstl_softc_t *softd; + ippool_dst_t *d; +{ + + if (softd->tails[d->ipld_unit + 1] == &d->ipld_next) + softd->tails[d->ipld_unit + 1] = d->ipld_pnext; + + if (d->ipld_pnext != NULL) + *d->ipld_pnext = d->ipld_next; + if (d->ipld_next != NULL) + d->ipld_next->ipld_pnext = d->ipld_pnext; + d->ipld_pnext = NULL; + d->ipld_next = NULL; + + ipf_dstlist_table_clearnodes(softd, d); + + softd->stats.ipls_numdereflists++; + d->ipld_flags |= IPDST_DELETE; + + ipf_dstlist_table_deref(softc, softd, d); +} + + +/* ------------------------------------------------------------------------ */ +/* Function: ipf_dstlist_table_free */ +/* Returns: Nil */ +/* Parameters: softd(I) - pointer to the destination list context */ +/* d(I) - pointer to destination list */ +/* */ +/* Free up a destination list data structure and any other memory that was */ +/* directly allocated as part of creating it. Individual destination list */ +/* nodes are not freed. It is assumed the caller will have already emptied */ +/* the destination list. */ +/* ------------------------------------------------------------------------ */ +static void +ipf_dstlist_table_free(softd, d) + ipf_dstl_softc_t *softd; + ippool_dst_t *d; +{ + MUTEX_DESTROY(&d->ipld_lock); + + if ((d->ipld_flags & IPDST_DELETE) != 0) + softd->stats.ipls_numdereflists--; + softd->stats.ipls_numlists--; + + if (d->ipld_dests != NULL) { + KFREES(d->ipld_dests, + d->ipld_maxnodes * sizeof(*d->ipld_dests)); + } + + KFREE(d); +} + + +/* ------------------------------------------------------------------------ */ +/* Function: ipf_dstlist_table_deref */ +/* Returns: int - 0 = success, else error */ +/* Parameters: softc(I) - pointer to soft context main structure */ +/* arg(I) - pointer to local context to use */ +/* op(I) - pointer to lookup operation data */ +/* */ +/* Drops the reference count on a destination list table object and free's */ +/* it if 0 has been reached. */ +/* ------------------------------------------------------------------------ */ +static int +ipf_dstlist_table_deref(softc, arg, table) + ipf_main_softc_t *softc; + void *arg; + void *table; +{ + ippool_dst_t *d = table; + + d->ipld_ref--; + if (d->ipld_ref > 0) + return d->ipld_ref; + + ipf_dstlist_table_free(arg, d); + + return 0; +} + + +/* ------------------------------------------------------------------------ */ +/* Function: ipf_dstlist_table_clearnodes */ +/* Returns: Nil */ +/* Parameters: softd(I) - pointer to the destination list context */ +/* dst(I) - pointer to destination list */ +/* */ +/* Free all of the destination nodes attached to the given table. */ +/* ------------------------------------------------------------------------ */ +static void +ipf_dstlist_table_clearnodes(softd, dst) + ipf_dstl_softc_t *softd; + ippool_dst_t *dst; +{ + ipf_dstnode_t *node; + + if (dst->ipld_dests == NULL) + return; + + while ((node = *dst->ipld_dests) != NULL) { + ipf_dstlist_node_free(softd, dst, node); + } +} + + +/* ------------------------------------------------------------------------ */ +/* Function: ipf_dstlist_table_find */ +/* Returns: int - 0 = success, else error */ +/* Parameters: arg(I) - pointer to local context to use */ +/* unit(I) - device we are working with */ +/* name(I) - destination table name to find */ +/* */ +/* Return a pointer to a destination table that matches the unit+name that */ +/* is passed in. */ +/* ------------------------------------------------------------------------ */ +static void * +ipf_dstlist_table_find(arg, unit, name) + void *arg; + int unit; + char *name; +{ + ipf_dstl_softc_t *softd = arg; + ippool_dst_t *d; + + for (d = softd->dstlist[unit + 1]; d != NULL; d = d->ipld_next) { + if ((d->ipld_unit == unit) && + !strncmp(d->ipld_name, name, FR_GROUPLEN)) { + return d; + } + } + + return NULL; +} + + +/* ------------------------------------------------------------------------ */ +/* Function: ipf_dstlist_select_ref */ +/* Returns: void * - NULL = failure, else pointer to table */ +/* Parameters: arg(I) - pointer to local context to use */ +/* unit(I) - device we are working with */ +/* name(I) - destination table name to find */ +/* */ +/* Attempt to find a destination table that matches the name passed in and */ +/* if successful, bump up the reference count on it because we intend to */ +/* store the pointer to it somewhere else. */ +/* ------------------------------------------------------------------------ */ +static void * +ipf_dstlist_select_ref(arg, unit, name) + void *arg; + int unit; + char *name; +{ + ippool_dst_t *d; + + d = ipf_dstlist_table_find(arg, unit, name); + if (d != NULL) { + MUTEX_ENTER(&d->ipld_lock); + d->ipld_ref++; + MUTEX_EXIT(&d->ipld_lock); + } + return d; +} + + +/* ------------------------------------------------------------------------ */ +/* Function: ipf_dstlist_select */ +/* Returns: void * - NULL = failure, else pointer to table */ +/* Parameters: fin(I) - pointer to packet information */ +/* d(I) - pointer to destination list */ +/* */ +/* Find the next node in the destination list to be used according to the */ +/* defined policy. Of these, "connection" is the most expensive policy to */ +/* implement as it always looks for the node with the least number of */ +/* connections associated with it. */ +/* */ +/* The hashes exclude the port numbers so that all protocols map to the */ +/* same destination. Otherwise, someone doing a ping would target a */ +/* different server than their TCP connection, etc. MD-5 is used to */ +/* transform the addressese into something random that the other end could */ +/* not easily guess and use in an attack. ipld_seed introduces an unknown */ +/* into the hash calculation to increase the difficult of an attacker */ +/* guessing the bucket. */ +/* */ +/* One final comment: mixing different address families in a single pool */ +/* will currently result in failures as the address family of the node is */ +/* only matched up with that in the packet as the last step. While this can */ +/* be coded around for the weighted connection and round-robin models, it */ +/* cannot be supported for the hash/random models as they do not search and */ +/* nor is the algorithm conducive to searching. */ +/* ------------------------------------------------------------------------ */ +static ipf_dstnode_t * +ipf_dstlist_select(fin, d) + fr_info_t *fin; + ippool_dst_t *d; +{ + ipf_dstnode_t *node, *sel; + int connects; + u_32_t hash[4]; + MD5_CTX ctx; + int family; + int x; + + if (d->ipld_dests == NULL || *d->ipld_dests == NULL) + return NULL; + + family = fin->fin_family; + + MUTEX_ENTER(&d->ipld_lock); + + switch (d->ipld_policy) + { + case IPLDP_ROUNDROBIN: + sel = d->ipld_selected; + if (sel == NULL) { + sel = *d->ipld_dests; + } else { + sel = sel->ipfd_next; + if (sel == NULL) + sel = *d->ipld_dests; + } + break; + + case IPLDP_CONNECTION: + if (d->ipld_selected == NULL) { + sel = *d->ipld_dests; + break; + } + + sel = d->ipld_selected; + connects = 0x7fffffff; + node = sel->ipfd_next; + if (node == NULL) + node = *d->ipld_dests; + while (node != d->ipld_selected) { + if (node->ipfd_states == 0) { + sel = node; + break; + } + if (node->ipfd_states < connects) { + sel = node; + connects = node->ipfd_states; + } + node = node->ipfd_next; + if (node == NULL) + node = *d->ipld_dests; + } + break; + + case IPLDP_RANDOM : + x = ipf_random() % d->ipld_nodes; + sel = d->ipld_dests[x]; + break; + + case IPLDP_HASHED : + MD5Init(&ctx); + MD5Update(&ctx, (u_char *)&d->ipld_seed, sizeof(d->ipld_seed)); + MD5Update(&ctx, (u_char *)&fin->fin_src6, + sizeof(fin->fin_src6)); + MD5Update(&ctx, (u_char *)&fin->fin_dst6, + sizeof(fin->fin_dst6)); + MD5Final((u_char *)hash, &ctx); + x = hash[0] % d->ipld_nodes; + sel = d->ipld_dests[x]; + break; + + case IPLDP_SRCHASH : + MD5Init(&ctx); + MD5Update(&ctx, (u_char *)&d->ipld_seed, sizeof(d->ipld_seed)); + MD5Update(&ctx, (u_char *)&fin->fin_src6, + sizeof(fin->fin_src6)); + MD5Final((u_char *)hash, &ctx); + x = hash[0] % d->ipld_nodes; + sel = d->ipld_dests[x]; + break; + + case IPLDP_DSTHASH : + MD5Init(&ctx); + MD5Update(&ctx, (u_char *)&d->ipld_seed, sizeof(d->ipld_seed)); + MD5Update(&ctx, (u_char *)&fin->fin_dst6, + sizeof(fin->fin_dst6)); + MD5Final((u_char *)hash, &ctx); + x = hash[0] % d->ipld_nodes; + sel = d->ipld_dests[x]; + break; + + default : + sel = NULL; + break; + } + + if (sel->ipfd_dest.fd_addr.adf_family != family) + sel = NULL; + d->ipld_selected = sel; + + MUTEX_EXIT(&d->ipld_lock); + + return sel; +} + + +/* ------------------------------------------------------------------------ */ +/* Function: ipf_dstlist_select_node */ +/* Returns: int - -1 == failure, 0 == success */ +/* Parameters: fin(I) - pointer to packet information */ +/* group(I) - destination pool to search */ +/* addr(I) - pointer to store selected address */ +/* pfdp(O) - pointer to storage for selected destination node */ +/* */ +/* This function is only responsible for obtaining the next IP address for */ +/* use and storing it in the caller's address space (addr). "addr" is only */ +/* used for storage if pfdp is NULL. No permanent reference is currently */ +/* kept on the node. */ +/* ------------------------------------------------------------------------ */ +int +ipf_dstlist_select_node(fin, group, addr, pfdp) + fr_info_t *fin; + void *group; + u_32_t *addr; + frdest_t *pfdp; +{ +#ifdef USE_MUTEXES + ipf_main_softc_t *softc = fin->fin_main_soft; +#endif + ippool_dst_t *d = group; + ipf_dstnode_t *node; + frdest_t *fdp; + + READ_ENTER(&softc->ipf_poolrw); + + node = ipf_dstlist_select(fin, d); + if (node == NULL) { + RWLOCK_EXIT(&softc->ipf_poolrw); + return -1; + } + + if (pfdp != NULL) { + bcopy(&node->ipfd_dest, pfdp, sizeof(*pfdp)); + } else { + if (fin->fin_family == AF_INET) { + addr[0] = node->ipfd_dest.fd_addr.adf_addr.i6[0]; + } else if (fin->fin_family == AF_INET6) { + addr[0] = node->ipfd_dest.fd_addr.adf_addr.i6[0]; + addr[1] = node->ipfd_dest.fd_addr.adf_addr.i6[1]; + addr[2] = node->ipfd_dest.fd_addr.adf_addr.i6[2]; + addr[3] = node->ipfd_dest.fd_addr.adf_addr.i6[3]; + } + } + + fdp = &node->ipfd_dest; + if (fdp->fd_ptr == NULL) + fdp->fd_ptr = fin->fin_ifp; + + MUTEX_ENTER(&node->ipfd_lock); + node->ipfd_states++; + MUTEX_EXIT(&node->ipfd_lock); + + RWLOCK_EXIT(&softc->ipf_poolrw); + + return 0; +} + + +/* ------------------------------------------------------------------------ */ +/* Function: ipf_dstlist_expire */ +/* Returns: Nil */ +/* Parameters: softc(I) - pointer to soft context main structure */ +/* arg(I) - pointer to local context to use */ +/* */ +/* There are currently no objects to expire in destination lists. */ +/* ------------------------------------------------------------------------ */ +static void +ipf_dstlist_expire(softc, arg) + ipf_main_softc_t *softc; + void *arg; +{ + return; +} + + +/* ------------------------------------------------------------------------ */ +/* Function: ipf_dstlist_sync */ +/* Returns: Nil */ +/* Parameters: softc(I) - pointer to soft context main structure */ +/* arg(I) - pointer to local context to use */ +/* */ +/* When a network interface appears or disappears, we need to revalidate */ +/* all of the network interface names that have been configured as a target */ +/* in a destination list. */ +/* ------------------------------------------------------------------------ */ +void +ipf_dstlist_sync(softc, arg) + ipf_main_softc_t *softc; + void *arg; +{ + ipf_dstl_softc_t *softd = arg; + ipf_dstnode_t *node; + ippool_dst_t *list; + int i; + int j; + + for (i = 0; i < IPL_LOGMAX; i++) { + for (list = softd->dstlist[i]; list != NULL; + list = list->ipld_next) { + for (j = 0; j < list->ipld_maxnodes; j++) { + node = list->ipld_dests[j]; + if (node == NULL) + continue; + if (node->ipfd_dest.fd_name == -1) + continue; + (void) ipf_resolvedest(softc, + node->ipfd_names, + &node->ipfd_dest, + AF_INET); + } + } + } +} diff --git a/sys/contrib/ipfilter/netinet/ip_dstlist.h b/sys/contrib/ipfilter/netinet/ip_dstlist.h new file mode 100644 index 000000000000..e2885e5c47ad --- /dev/null +++ b/sys/contrib/ipfilter/netinet/ip_dstlist.h @@ -0,0 +1,68 @@ +/* + * Copyright (C) 2012 by Darren Reed. + * + * See the IPFILTER.LICENCE file for details on licencing. + * + * $Id: ip_dstlist.h,v 1.5.2.6 2012/07/22 08:04:23 darren_r Exp $ + */ + +#ifndef __IP_DSTLIST_H__ +#define __IP_DSTLIST_H__ + +typedef struct ipf_dstnode { + struct ipf_dstnode *ipfd_next; + struct ipf_dstnode **ipfd_pnext; + ipfmutex_t ipfd_lock; + frdest_t ipfd_dest; + u_long ipfd_syncat; + int ipfd_flags; + int ipfd_size; + int ipfd_states; + int ipfd_ref; + int ipfd_uid; + char ipfd_names[1]; +} ipf_dstnode_t; + +typedef enum ippool_policy_e { + IPLDP_NONE = 0, + IPLDP_ROUNDROBIN, + IPLDP_CONNECTION, + IPLDP_RANDOM, + IPLDP_HASHED, + IPLDP_SRCHASH, + IPLDP_DSTHASH +} ippool_policy_t; + +typedef struct ippool_dst { + struct ippool_dst *ipld_next; + struct ippool_dst **ipld_pnext; + ipfmutex_t ipld_lock; + int ipld_seed; + int ipld_unit; + int ipld_ref; + int ipld_flags; + int ipld_nodes; + int ipld_maxnodes; + ippool_policy_t ipld_policy; + ipf_dstnode_t **ipld_dests; + ipf_dstnode_t *ipld_selected; + char ipld_name[FR_GROUPLEN]; +} ippool_dst_t; + +#define IPDST_DELETE 0x01 + +typedef struct dstlist_stat_s { + void *ipls_list[LOOKUP_POOL_SZ]; + int ipls_numlists; + u_long ipls_nomem; + int ipls_numnodes; + int ipls_numdereflists; + int ipls_numderefnodes; +} ipf_dstl_stat_t; + +extern ipf_lookup_t ipf_dstlist_backend; + +extern int ipf_dstlist_select_node __P((fr_info_t *, void *, u_32_t *, + frdest_t *)); + +#endif /* __IP_DSTLIST_H__ */ diff --git a/sys/contrib/ipfilter/netinet/ip_fil.h b/sys/contrib/ipfilter/netinet/ip_fil.h index 0cd84b995a89..22a11c341c2f 100644 --- a/sys/contrib/ipfilter/netinet/ip_fil.h +++ b/sys/contrib/ipfilter/netinet/ip_fil.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 1993-2001, 2003 by Darren Reed. + * Copyright (C) 2012 by Darren Reed. * * See the IPFILTER.LICENCE file for details on licencing. * @@ -12,6 +12,21 @@ #define __IP_FIL_H__ #include "netinet/ip_compat.h" +#include "netinet/ipf_rb.h" +#if NETBSD_GE_REV(104040000) +# include +#endif +#if defined(BSD) && defined(_KERNEL) +# if NETBSD_LT_REV(399000000) || defined(__osf__) || FREEBSD_LT_REV(500043) +# include +# else +# include +# endif +#endif + +#if !defined(linux) || !defined(_KERNEL) +# include +#endif #ifndef SOLARIS # define SOLARIS (defined(sun) && (defined(__svr4__) || defined(__SVR4))) @@ -63,6 +78,8 @@ # define SIOCIPFDELTOK _IOWR('r', 94, int) # define SIOCLOOKUPITER _IOWR('r', 95, struct ipfobj) # define SIOCGTQTAB _IOWR('r', 96, struct ipfobj) +# define SIOCMATCHFLUSH _IOWR('r', 97, struct ipfobj) +# define SIOCIPFINTERROR _IOR('r', 98, int) #else # define SIOCADAFR _IOW(r, 60, struct ipfobj) # define SIOCRMAFR _IOW(r, 61, struct ipfobj) @@ -101,6 +118,8 @@ # define SIOCIPFDELTOK _IOWR(r, 94, int) # define SIOCLOOKUPITER _IOWR(r, 95, struct ipfobj) # define SIOCGTQTAB _IOWR(r, 96, struct ipfobj) +# define SIOCMATCHFLUSH _IOWR(r, 97, struct ipfobj) +# define SIOCIPFINTERROR _IOR(r, 98, int) #endif #define SIOCADDFR SIOCADAFR #define SIOCDELFR SIOCRMAFR @@ -111,9 +130,10 @@ struct ipscan; struct ifnet; +struct ipf_main_softc_s; - -typedef int (* lookupfunc_t) __P((void *, int, void *)); +typedef int (* lookupfunc_t) __P((struct ipf_main_softc_s *, void *, + int, void *, u_int)); /* * i6addr is used as a container for both IPv4 and IPv6 addresses, as well @@ -129,7 +149,7 @@ typedef union i6addr { struct { u_short type; u_short subtype; - char label[12]; + int name; } i6un; } i6addr_t; #else @@ -141,14 +161,14 @@ typedef union i6addr { struct { u_short type; u_short subtype; - char label[12]; + int name; } i6un; } i6addr_t; #endif #define in4_addr in4.s_addr #define iplookupnum i6[1] -#define iplookupname i6un.label +#define iplookupname i6un.name #define iplookuptype i6un.type #define iplookupsubtype i6un.subtype /* @@ -172,17 +192,25 @@ typedef union i6addr { (I61(a) != I61(b)) || (I60(a) != I60(b))) #define IP6_ISZERO(a) ((I60(a) | I61(a) | I62(a) | I63(a)) == 0) #define IP6_NOTZERO(a) ((I60(a) | I61(a) | I62(a) | I63(a)) != 0) -#define IP6_GT(a,b) (HI60(a) > HI60(b) || (HI60(a) == HI60(b) && \ - (HI61(a) > HI61(b) || (HI61(a) == HI61(b) && \ - (HI62(a) > HI62(b) || (HI62(a) == HI62(b) && \ - HI63(a) > HI63(b))))))) -#define IP6_LT(a,b) (HI60(a) < HI60(b) || (HI60(a) == HI60(b) && \ - (HI61(a) < HI61(b) || (HI61(a) == HI61(b) && \ - (HI62(a) < HI62(b) || (HI62(a) == HI62(b) && \ - HI63(a) < HI63(b))))))) +#define IP6_ISONES(a) ((I63(a) == 0xffffffff) && (I62(a) == 0xffffffff) && \ + (I61(a) == 0xffffffff) && (I60(a) == 0xffffffff)) +#define IP6_GT(a,b) (ntohl(HI60(a)) > ntohl(HI60(b)) || \ + (HI60(a) == HI60(b) && \ + (ntohl(HI61(a)) > ntohl(HI61(b)) || \ + (HI61(a) == HI61(b) && \ + (ntohl(HI62(a)) > ntohl(HI62(b)) || \ + (HI62(a) == HI62(b) && \ + ntohl(HI63(a)) > ntohl(HI63(b)))))))) +#define IP6_LT(a,b) (ntohl(HI60(a)) < ntohl(HI60(b)) || \ + (HI60(a) == HI60(b) && \ + (ntohl(HI61(a)) < ntohl(HI61(b)) || \ + (HI61(a) == HI61(b) && \ + (ntohl(HI62(a)) < ntohl(HI62(b)) || \ + (HI62(a) == HI62(b) && \ + ntohl(HI63(a)) < ntohl(HI63(b)))))))) #define NLADD(n,x) htonl(ntohl(n) + (x)) #define IP6_INC(a) \ - { u_32_t *_i6 = (u_32_t *)(a); \ + do { u_32_t *_i6 = (u_32_t *)(a); \ _i6[3] = NLADD(_i6[3], 1); \ if (_i6[3] == 0) { \ _i6[2] = NLADD(_i6[2], 1); \ @@ -193,9 +221,9 @@ typedef union i6addr { } \ } \ } \ - } + } while (0) #define IP6_ADD(a,x,d) \ - { i6addr_t *_s = (i6addr_t *)(a); \ + do { i6addr_t *_s = (i6addr_t *)(a); \ i6addr_t *_d = (i6addr_t *)(d); \ _d->i6[0] = NLADD(_s->i6[0], x); \ if (ntohl(_d->i6[0]) < ntohl(_s->i6[0])) { \ @@ -207,26 +235,65 @@ typedef union i6addr { } \ } \ } \ - } -#define IP6_AND(a,b,d) { i6addr_t *_s1 = (i6addr_t *)(a); \ - i6addr_t *_s2 = (i6addr_t *)(d); \ + } while (0) +#define IP6_AND(a,b,d) do { i6addr_t *_s1 = (i6addr_t *)(a); \ + i6addr_t *_s2 = (i6addr_t *)(b); \ i6addr_t *_d = (i6addr_t *)(d); \ _d->i6[0] = _s1->i6[0] & _s2->i6[0]; \ _d->i6[1] = _s1->i6[1] & _s2->i6[1]; \ _d->i6[2] = _s1->i6[2] & _s2->i6[2]; \ _d->i6[3] = _s1->i6[3] & _s2->i6[3]; \ - } + } while (0) +#define IP6_ANDASSIGN(a,m) \ + do { i6addr_t *_d = (i6addr_t *)(a); \ + i6addr_t *_m = (i6addr_t *)(m); \ + _d->i6[0] &= _m->i6[0]; \ + _d->i6[1] &= _m->i6[1]; \ + _d->i6[2] &= _m->i6[2]; \ + _d->i6[3] &= _m->i6[3]; \ + } while (0) +#define IP6_MASKEQ(a,m,b) \ + (((I60(a) & I60(m)) == I60(b)) && \ + ((I61(a) & I61(m)) == I61(b)) && \ + ((I62(a) & I62(m)) == I62(b)) && \ + ((I63(a) & I63(m)) == I63(b))) +#define IP6_MASKNEQ(a,m,b) \ + (((I60(a) & I60(m)) != I60(b)) || \ + ((I61(a) & I61(m)) != I61(b)) || \ + ((I62(a) & I62(m)) != I62(b)) || \ + ((I63(a) & I63(m)) != I63(b))) #define IP6_MERGE(a,b,c) \ - { i6addr_t *_d, *_s1, *_s2; \ + do { i6addr_t *_d, *_s1, *_s2; \ _d = (i6addr_t *)(a); \ _s1 = (i6addr_t *)(b); \ _s2 = (i6addr_t *)(c); \ _d->i6[0] |= _s1->i6[0] & ~_s2->i6[0]; \ _d->i6[1] |= _s1->i6[1] & ~_s2->i6[1]; \ _d->i6[2] |= _s1->i6[2] & ~_s2->i6[2]; \ - _d->i6[2] |= _s1->i6[3] & ~_s2->i6[3]; \ - } + _d->i6[3] |= _s1->i6[3] & ~_s2->i6[3]; \ + } while (0) +#define IP6_MASK(a,b,c) \ + do { i6addr_t *_d, *_s1, *_s2; \ + _d = (i6addr_t *)(a); \ + _s1 = (i6addr_t *)(b); \ + _s2 = (i6addr_t *)(c); \ + _d->i6[0] = _s1->i6[0] & ~_s2->i6[0]; \ + _d->i6[1] = _s1->i6[1] & ~_s2->i6[1]; \ + _d->i6[2] = _s1->i6[2] & ~_s2->i6[2]; \ + _d->i6[3] = _s1->i6[3] & ~_s2->i6[3]; \ + } while (0) +#define IP6_SETONES(a) \ + do { i6addr_t *_d = (i6addr_t *)(a); \ + _d->i6[0] = 0xffffffff; \ + _d->i6[1] = 0xffffffff; \ + _d->i6[2] = 0xffffffff; \ + _d->i6[3] = 0xffffffff; \ + } while (0) +typedef union ipso_u { + u_short ipso_ripso[2]; + u_32_t ipso_doi; +} ipso_t; typedef struct fr_ip { u_32_t fi_v:4; /* IP version */ @@ -237,11 +304,13 @@ typedef struct fr_ip { u_32_t fi_optmsk; /* bitmask composed from IP options */ i6addr_t fi_src; /* source address from packet */ i6addr_t fi_dst; /* destination address from packet */ - u_short fi_secmsk; /* bitmask composed from IP security options */ - u_short fi_auth; /* authentication code from IP sec. options */ + ipso_t fi_ipso; /* IP security options */ u_32_t fi_flx; /* packet flags */ u_32_t fi_tcpmsk; /* TCP options set/reset */ - u_32_t fi_res1; /* RESERVED */ + u_32_t fi_ports[2]; /* TCP ports */ + u_char fi_tcpf; /* TCP flags */ + u_char fi_sensitivity; + u_char fi_xxx[2]; /* pad */ } fr_ip_t; /* @@ -263,16 +332,23 @@ typedef struct fr_ip { #define FI_FRAGBODY 0x2000 #define FI_BADSRC 0x4000 #define FI_LOWTTL 0x8000 -#define FI_CMP 0xcf03 /* Not FI_FRAG,FI_NATED,FI_FRAGTAIL,broadcast */ +#define FI_CMP 0x5cfe3 /* Not FI_FRAG,FI_NATED,FI_FRAGTAIL */ #define FI_ICMPCMP 0x0003 /* Flags we can check for ICMP error packets */ -#define FI_WITH 0xeffe /* Not FI_TCPUDP */ +#define FI_WITH 0x5effe /* Not FI_TCPUDP */ #define FI_V6EXTHDR 0x10000 #define FI_COALESCE 0x20000 #define FI_NEWNAT 0x40000 +#define FI_ICMPQUERY 0x80000 +#define FI_ENCAP 0x100000 /* encap/decap with NAT */ +#define FI_AH 0x200000 /* AH header present */ +#define FI_DOCKSUM 0x10000000 /* Proxy wants L4 recalculation */ #define FI_NOCKSUM 0x20000000 /* don't do a L4 checksum validation */ -#define FI_DONTCACHE 0x40000000 /* don't cache the result */ +#define FI_NOWILD 0x40000000 /* Do not do wildcard searches */ #define FI_IGNORE 0x80000000 +#define fi_secmsk fi_ipso.ipso_ripso[0] +#define fi_auth fi_ipso.ipso_ripso[1] +#define fi_doi fi_ipso.ipso_doi #define fi_saddr fi_src.in4.s_addr #define fi_daddr fi_dst.in4.s_addr #define fi_srcnum fi_src.iplookupnum @@ -303,37 +379,87 @@ typedef struct fr_ip { #define SI_NEWFR 0x00001000 #define SI_CLONE 0x00002000 #define SI_CLONED 0x00004000 +#define SI_NEWCLONE 0x00008000 +typedef struct { + u_short fda_ports[2]; + u_char fda_tcpf; /* TCP header flags (SYN, ACK, etc) */ +} frdat_t; + +typedef enum fr_breasons_e { + FRB_BLOCKED = 0, + FRB_LOGFAIL = 1, + FRB_PPSRATE = 2, + FRB_JUMBO = 3, + FRB_MAKEFRIP = 4, + FRB_STATEADD = 5, + FRB_UPDATEIPID = 6, + FRB_LOGFAIL2 = 7, + FRB_DECAPFRIP = 8, + FRB_AUTHNEW = 9, + FRB_AUTHCAPTURE = 10, + FRB_COALESCE = 11, + FRB_PULLUP = 12, + FRB_AUTHFEEDBACK = 13, + FRB_BADFRAG = 14, + FRB_NATV4 = 15, + FRB_NATV6 = 16, +} fr_breason_t; + +#define FRB_MAX_VALUE 16 + +typedef enum ipf_cksum_e { + FI_CK_BAD = -1, + FI_CK_NEEDED = 0, + FI_CK_SUMOK = 1, + FI_CK_L4PART = 2, + FI_CK_L4FULL = 4 +} ipf_cksum_t; typedef struct fr_info { + void *fin_main_soft; void *fin_ifp; /* interface packet is `on' */ - fr_ip_t fin_fi; /* IP Packet summary */ - union { - u_short fid_16[2]; /* TCP/UDP ports, ICMP code/type */ - u_32_t fid_32; - } fin_dat; - int fin_out; /* in or out ? 1 == out, 0 == in */ - int fin_rev; /* state only: 1 = reverse */ - u_short fin_hlen; /* length of IP header in bytes */ - u_char fin_tcpf; /* TCP header flags (SYN, ACK, etc) */ - u_char fin_icode; /* ICMP error to return */ - u_32_t fin_rule; /* rule # last matched */ - char fin_group[FR_GROUPLEN]; /* group number, -1 for none */ struct frentry *fin_fr; /* last matching rule */ - void *fin_dp; /* start of data past IP header */ + int fin_out; /* in or out ? 1 == out, 0 == in */ + fr_ip_t fin_fi; /* IP Packet summary */ + frdat_t fin_dat; /* TCP/UDP ports, ICMP code/type */ int fin_dlen; /* length of data portion of packet */ int fin_plen; + u_32_t fin_rule; /* rule # last matched */ + u_short fin_hlen; /* length of IP header in bytes */ + char fin_group[FR_GROUPLEN]; /* group number, -1 for none */ + void *fin_dp; /* start of data past IP header */ + /* + * Fields after fin_dp aren't used for compression of log records. + * fin_fi contains the IP version (fin_family) + * fin_rule isn't included because adding a new rule can change it but + * not change fin_fr. fin_rule is the rule number reported. + * It isn't necessary to include fin_crc because that is checked + * for explicitly, before calling bcmp. + */ + u_32_t fin_crc; /* Simple calculation for logging */ + int fin_family; /* AF_INET, etc. */ + int fin_icode; /* ICMP error to return */ + int fin_mtu; /* MTU input for ICMP need-frag */ + int fin_rev; /* state only: 1 = reverse */ int fin_ipoff; /* # bytes from buffer start to hdr */ - u_short fin_id; /* IP packet id field */ + u_32_t fin_id; /* IP packet id field */ + u_short fin_l4hlen; /* length of L4 header, if known */ u_short fin_off; int fin_depth; /* Group nesting depth */ int fin_error; /* Error code to return */ - int fin_cksum; /* -1 bad, 1 good, 0 not done */ - void *fin_nat; - void *fin_state; + ipf_cksum_t fin_cksum; /* -1 = bad, 1 = good, 0 = not done */ + fr_breason_t fin_reason; /* why auto blocked */ + u_int fin_pktnum; void *fin_nattag; - void *fin_exthdr; - ip_t *fin_ip; + struct frdest *fin_dif; + struct frdest *fin_tif; + union { + ip_t *fip_ip; +#ifdef USE_INET6 + ip6_t *fip_ip6; +#endif + } fin_ipu; mb_t **fin_mp; /* pointer to pointer to mbuf */ mb_t *fin_m; /* pointer to mbuf */ #ifdef MENTAT @@ -344,35 +470,42 @@ typedef struct fr_info { #ifdef __sgi void *fin_hbuf; #endif + void *fin_fraghdr; /* pointer to start of ipv6 frag hdr */ } fr_info_t; +#define fin_ip fin_ipu.fip_ip +#define fin_ip6 fin_ipu.fip_ip6 #define fin_v fin_fi.fi_v #define fin_p fin_fi.fi_p #define fin_flx fin_fi.fi_flx #define fin_optmsk fin_fi.fi_optmsk #define fin_secmsk fin_fi.fi_secmsk +#define fin_doi fin_fi.fi_doi #define fin_auth fin_fi.fi_auth #define fin_src fin_fi.fi_src.in4 -#define fin_src6 fin_fi.fi_src.in6 #define fin_saddr fin_fi.fi_saddr #define fin_dst fin_fi.fi_dst.in4 -#define fin_dst6 fin_fi.fi_dst.in6 #define fin_daddr fin_fi.fi_daddr -#define fin_data fin_dat.fid_16 -#define fin_sport fin_dat.fid_16[0] -#define fin_dport fin_dat.fid_16[1] -#define fin_ports fin_dat.fid_32 +#define fin_data fin_fi.fi_ports +#define fin_sport fin_fi.fi_ports[0] +#define fin_dport fin_fi.fi_ports[1] +#define fin_tcpf fin_fi.fi_tcpf +#define fin_src6 fin_fi.fi_src +#define fin_dst6 fin_fi.fi_dst +#define fin_srcip6 fin_fi.fi_src.in6 +#define fin_dstip6 fin_fi.fi_dst.in6 #define IPF_IN 0 #define IPF_OUT 1 typedef struct frentry *(*ipfunc_t) __P((fr_info_t *, u_32_t *)); -typedef int (*ipfuncinit_t) __P((struct frentry *)); +typedef int (*ipfuncinit_t) __P((struct ipf_main_softc_s *, struct frentry *)); typedef struct ipfunc_resolve { char ipfu_name[32]; ipfunc_t ipfu_addr; ipfuncinit_t ipfu_init; + ipfuncinit_t ipfu_fini; } ipfunc_resolve_t; /* @@ -401,39 +534,78 @@ typedef struct { #define ipt_tag ipt_un.iptu_tag #define ipt_num ipt_un.iptu_num +/* + * Structure to define address for pool lookups. + */ +typedef struct { + u_char adf_len; + sa_family_t adf_family; + u_char adf_xxx[2]; + i6addr_t adf_addr; +} addrfamily_t; + +RBI_LINK(ipf_rb, host_node_s); + +typedef struct host_node_s { + RBI_FIELD(ipf_rb) hn_entry; + addrfamily_t hn_addr; + int hn_active; +} host_node_t; + +typedef RBI_HEAD(ipf_rb, host_node_s) ipf_rb_head_t; + +typedef struct host_track_s { + ipf_rb_head_t ht_root; + int ht_max_nodes; + int ht_max_per_node; + int ht_netmask; + int ht_cur_nodes; +} host_track_t; + + +typedef enum fr_dtypes_e { + FRD_NORMAL = 0, + FRD_DSTLIST +} fr_dtypes_t; /* * This structure is used to hold information about the next hop for where * to forward a packet. */ typedef struct frdest { - void *fd_ifp; - i6addr_t fd_ip6; - char fd_ifname[LIFNAMSIZ]; + void *fd_ptr; + addrfamily_t fd_addr; + fr_dtypes_t fd_type; + int fd_name; + int fd_local; } frdest_t; +#define fd_ip6 fd_addr.adf_addr #define fd_ip fd_ip6.in4 +typedef enum fr_ctypes_e { + FR_NONE = 0, + FR_EQUAL, + FR_NEQUAL, + FR_LESST, + FR_GREATERT, + FR_LESSTE, + FR_GREATERTE, + FR_OUTRANGE, + FR_INRANGE, + FR_INCRANGE +} fr_ctypes_t; + /* * This structure holds information about a port comparison. */ typedef struct frpcmp { - int frp_cmp; /* data for port comparisons */ - u_short frp_port; /* top port for <> and >< */ - u_short frp_top; /* top port for <> and >< */ + fr_ctypes_t frp_cmp; /* data for port comparisons */ + u_32_t frp_port; /* top port for <> and >< */ + u_32_t frp_top; /* top port for <> and >< */ } frpcmp_t; -#define FR_NONE 0 -#define FR_EQUAL 1 -#define FR_NEQUAL 2 -#define FR_LESST 3 -#define FR_GREATERT 4 -#define FR_LESSTE 5 -#define FR_GREATERTE 6 -#define FR_OUTRANGE 7 -#define FR_INRANGE 8 -#define FR_INCRANGE 9 /* * Structure containing all the relevant TCP things that can be checked in @@ -455,23 +627,37 @@ typedef struct frtuc { #define FR_TCPFMAX 0x3f +typedef enum fr_atypes_e { + FRI_NONE = -1, /* For LHS of NAT */ + FRI_NORMAL = 0, /* Normal address */ + FRI_DYNAMIC, /* dynamic address */ + FRI_LOOKUP, /* address is a pool # */ + FRI_RANGE, /* address/mask is a range */ + FRI_NETWORK, /* network address from if */ + FRI_BROADCAST, /* broadcast address from if */ + FRI_PEERADDR, /* Peer address for P-to-P */ + FRI_NETMASKED, /* network address with netmask from if */ + FRI_SPLIT, /* For NAT compatibility */ + FRI_INTERFACE /* address is based on interface name */ +} fr_atypes_t; + /* * This structure makes up what is considered to be the IPFilter specific * matching components of a filter rule, as opposed to the data structures * used to define the result which are in frentry_t and not here. */ typedef struct fripf { - fr_ip_t fri_ip; - fr_ip_t fri_mip; /* mask structure */ + fr_ip_t fri_ip; + fr_ip_t fri_mip; /* mask structure */ - u_short fri_icmpm; /* data for ICMP packets (mask) */ - u_short fri_icmp; + u_short fri_icmpm; /* data for ICMP packets (mask) */ + u_short fri_icmp; - frtuc_t fri_tuc; - int fri_satype; /* addres type */ - int fri_datype; /* addres type */ - int fri_sifpidx; /* doing dynamic addressing */ - int fri_difpidx; /* index into fr_ifps[] to use when */ + frtuc_t fri_tuc; + fr_atypes_t fri_satype; /* addres type */ + fr_atypes_t fri_datype; /* addres type */ + int fri_sifpidx; /* doing dynamic addressing */ + int fri_difpidx; /* index into fr_ifps[] to use when */ } fripf_t; #define fri_dlookup fri_mip.fi_dst @@ -483,28 +669,42 @@ typedef struct fripf { #define fri_dstptr fri_mip.fi_dstptr #define fri_srcptr fri_mip.fi_srcptr -#define FRI_NORMAL 0 /* Normal address */ -#define FRI_DYNAMIC 1 /* dynamic address */ -#define FRI_LOOKUP 2 /* address is a pool # */ -#define FRI_RANGE 3 /* address/mask is a range */ -#define FRI_NETWORK 4 /* network address from if */ -#define FRI_BROADCAST 5 /* broadcast address from if */ -#define FRI_PEERADDR 6 /* Peer address for P-to-P */ -#define FRI_NETMASKED 7 /* network address with netmask from if */ +typedef enum fr_rtypes_e { + FR_T_NONE = 0, + FR_T_IPF, /* IPF structures */ + FR_T_BPFOPC, /* BPF opcode */ + FR_T_CALLFUNC, /* callout to function in fr_func only */ + FR_T_COMPIPF, /* compiled C code */ + FR_T_IPFEXPR, /* IPF expression */ + FR_T_BUILTIN = 0x40000000, /* rule is in kernel space */ + FR_T_IPF_BUILTIN, + FR_T_BPFOPC_BUILTIN, + FR_T_CALLFUNC_BUILTIN, + FR_T_COMPIPF_BUILTIN, + FR_T_IPFEXPR_BUILTIN +} fr_rtypes_t; typedef struct frentry * (* frentfunc_t) __P((fr_info_t *)); typedef struct frentry { ipfmutex_t fr_lock; struct frentry *fr_next; - struct frentry **fr_grp; + struct frentry **fr_pnext; + struct frgroup *fr_grp; + struct frgroup *fr_grphead; + struct frgroup *fr_icmpgrp; struct ipscan *fr_isc; + struct frentry *fr_dnext; /* 2 fr_die linked list pointers */ + struct frentry **fr_pdnext; void *fr_ifas[4]; void *fr_ptr; /* for use with fr_arg */ - char *fr_comment; /* text comment for rule */ - int fr_ref; /* reference count - for grouping */ + int fr_comment; /* text comment for rule */ + int fr_size; /* size of this structure */ + int fr_ref; /* reference count */ int fr_statecnt; /* state count - for limit rules */ + u_32_t fr_die; /* only used on loading the rule */ + u_int fr_cksum; /* checksum on filter rules for performance */ /* * The line number from a file is here because we need to be able to * match the rule generated with ``grep rule ipf.conf | ipf -rf -'' @@ -521,13 +721,18 @@ typedef struct frentry { /* * For PPS rate limiting + * fr_lpu is used to always have the same size for this field, + * allocating 64bits for seconds and 32bits for milliseconds. */ - struct timeval fr_lastpkt; + union { + struct timeval frp_lastpkt; + char frp_bytes[12]; + } fr_lpu; int fr_curpps; union { void *fru_data; - caddr_t fru_caddr; + char *fru_caddr; fripf_t *fru_ipf; frentfunc_t fru_func; } fr_dun; @@ -538,29 +743,38 @@ typedef struct frentry { ipfunc_t fr_func; /* call this function */ int fr_dsize; int fr_pps; - int fr_statemax; /* max reference count */ - u_32_t fr_type; + fr_rtypes_t fr_type; u_32_t fr_flags; /* per-rule flags && options (see below) */ u_32_t fr_logtag; /* user defined log tag # */ u_32_t fr_collect; /* collection number */ - u_int fr_arg; /* misc. numeric arg for rule */ + u_int fr_arg; /* misc. numeric arg for rule */ u_int fr_loglevel; /* syslog log facility + priority */ - u_int fr_age[2]; /* non-TCP timeouts */ - u_char fr_v; + u_char fr_family; u_char fr_icode; /* return ICMP code */ - char fr_group[FR_GROUPLEN]; /* group to which this rule belongs */ - char fr_grhead[FR_GROUPLEN]; /* group # which this rule starts */ + int fr_group; /* group to which this rule belongs */ + int fr_grhead; /* group # which this rule starts */ + int fr_ifnames[4]; + int fr_isctag; + int fr_rpc; /* XID Filtering */ ipftag_t fr_nattag; - char fr_ifnames[4][LIFNAMSIZ]; - char fr_isctag[16]; frdest_t fr_tifs[2]; /* "to"/"reply-to" interface */ frdest_t fr_dif; /* duplicate packet interface */ /* - * This must be last and will change after loaded into the kernel. + * These are all options related to stateful filtering */ - u_int fr_cksum; /* checksum on filter rules for performance */ + host_track_t fr_srctrack; + int fr_nostatelog; + int fr_statemax; /* max reference count */ + int fr_icmphead; /* ICMP group for state options */ + u_int fr_age[2]; /* non-TCP state timeouts */ + /* + * How big is the name buffer at the end? + */ + int fr_namelen; + char fr_names[1]; } frentry_t; +#define fr_lastpkt fr_lpu.frp_lastpkt #define fr_caddr fr_dun.fru_caddr #define fr_data fr_dun.fru_data #define fr_dfunc fr_dun.fru_func @@ -589,12 +803,16 @@ typedef struct frentry { #define fr_stop fr_tuc.ftu_stop #define fr_dtop fr_tuc.ftu_dtop #define fr_dst fr_ip.fi_dst.in4 +#define fr_dst6 fr_ip.fi_dst #define fr_daddr fr_ip.fi_dst.in4.s_addr #define fr_src fr_ip.fi_src.in4 +#define fr_src6 fr_ip.fi_src #define fr_saddr fr_ip.fi_src.in4.s_addr #define fr_dmsk fr_mip.fi_dst.in4 +#define fr_dmsk6 fr_mip.fi_dst #define fr_dmask fr_mip.fi_dst.in4.s_addr #define fr_smsk fr_mip.fi_src.in4 +#define fr_smsk6 fr_mip.fi_src #define fr_smask fr_mip.fi_src.in4.s_addr #define fr_dstnum fr_ip.fi_dstnum #define fr_srcnum fr_ip.fi_srcnum @@ -616,10 +834,10 @@ typedef struct frentry { #define fr_secmask fr_mip.fi_secmsk #define fr_authbits fr_ip.fi_auth #define fr_authmask fr_mip.fi_auth +#define fr_doi fr_ip.fi_doi +#define fr_doimask fr_mip.fi_doi #define fr_flx fr_ip.fi_flx #define fr_mflx fr_mip.fi_flx -#define fr_ifname fr_ifnames[0] -#define fr_oifname fr_ifnames[2] #define fr_ifa fr_ifas[0] #define fr_oifa fr_ifas[2] #define fr_tif fr_tifs[0] @@ -627,33 +845,22 @@ typedef struct frentry { #define FR_NOLOGTAG 0 -#ifndef offsetof -#define offsetof(t,m) (int)((&((t *)0L)->m)) -#endif #define FR_CMPSIZ (sizeof(struct frentry) - \ offsetof(struct frentry, fr_func)) +#define FR_NAME(_f, _n) (_f)->fr_names + (_f)->_n -/* - * fr_type - */ -#define FR_T_NONE 0 -#define FR_T_IPF 1 /* IPF structures */ -#define FR_T_BPFOPC 2 /* BPF opcode */ -#define FR_T_CALLFUNC 3 /* callout to function in fr_func only */ -#define FR_T_COMPIPF 4 /* compiled C code */ -#define FR_T_BUILTIN 0x80000000 /* rule is in kernel space */ /* * fr_flags */ -#define FR_CALL 0x00000 /* call rule */ #define FR_BLOCK 0x00001 /* do not allow packet to pass */ #define FR_PASS 0x00002 /* allow packet to pass */ #define FR_AUTH 0x00003 /* use authentication */ #define FR_PREAUTH 0x00004 /* require preauthentication */ #define FR_ACCOUNT 0x00005 /* Accounting rule */ #define FR_SKIP 0x00006 /* skip rule */ -#define FR_DIVERT 0x00007 /* divert rule */ +#define FR_DECAPSULATE 0x00008 /* decapsulate rule */ +#define FR_CALL 0x00009 /* call rule */ #define FR_CMDMASK 0x0000f #define FR_LOG 0x00010 /* Log */ #define FR_LOGB 0x00011 /* Log-fail */ @@ -674,19 +881,19 @@ typedef struct frentry { #define FR_LOGBODY 0x10000 /* Log the body */ #define FR_LOGFIRST 0x20000 /* Log the first byte if state held */ #define FR_LOGORBLOCK 0x40000 /* block the packet if it can't be logged */ -#define FR_DUP 0x80000 /* duplicate packet */ +#define FR_STLOOSE 0x80000 /* loose state checking */ #define FR_FRSTRICT 0x100000 /* strict frag. cache */ #define FR_STSTRICT 0x200000 /* strict keep state */ #define FR_NEWISN 0x400000 /* new ISN for outgoing TCP */ #define FR_NOICMPERR 0x800000 /* do not match ICMP errors in state */ #define FR_STATESYNC 0x1000000 /* synchronize state to slave */ +#define FR_COPIED 0x2000000 /* copied from user space */ +#define FR_INACTIVE 0x4000000 /* only used when flush'ing rules */ #define FR_NOMATCH 0x8000000 /* no match occured */ /* 0x10000000 FF_LOGPASS */ /* 0x20000000 FF_LOGBLOCK */ /* 0x40000000 FF_LOGNOMATCH */ /* 0x80000000 FF_BLOCKNONIP */ -#define FR_COPIED 0x40000000 /* copied from user space */ -#define FR_INACTIVE 0x80000000 /* only used when flush'ing rules */ #define FR_RETMASK (FR_RETICMP|FR_RETRST|FR_FAKEICMP) #define FR_ISBLOCK(x) (((x) & FR_CMDMASK) == FR_BLOCK) @@ -695,6 +902,7 @@ typedef struct frentry { #define FR_ISPREAUTH(x) (((x) & FR_CMDMASK) == FR_PREAUTH) #define FR_ISACCOUNT(x) (((x) & FR_CMDMASK) == FR_ACCOUNT) #define FR_ISSKIP(x) (((x) & FR_CMDMASK) == FR_SKIP) +#define FR_ISDECAPS(x) (((x) & FR_CMDMASK) == FR_DECAPSULATE) #define FR_ISNOMATCH(x) ((x) & FR_NOMATCH) #define FR_INOUT (FR_INQUE|FR_OUTQUE) @@ -712,8 +920,8 @@ typedef struct frentry { * Structure that passes information on what/how to flush to the kernel. */ typedef struct ipfflush { - int ipflu_how; - int ipflu_arg; + int ipflu_how; + int ipflu_arg; } ipfflush_t; @@ -721,12 +929,12 @@ typedef struct ipfflush { * */ typedef struct ipfgetctl { - u_int ipfg_min; /* min value */ - u_int ipfg_current; /* current value */ - u_int ipfg_max; /* max value */ - u_int ipfg_default; /* default value */ - u_int ipfg_steps; /* value increments */ - char ipfg_name[40]; /* tag name for this control */ + u_int ipfg_min; /* min value */ + u_int ipfg_current; /* current value */ + u_int ipfg_max; /* max value */ + u_int ipfg_default; /* default value */ + u_int ipfg_steps; /* value increments */ + char ipfg_name[40]; /* tag name for this control */ } ipfgetctl_t; typedef struct ipfsetctl { @@ -741,7 +949,43 @@ typedef struct ipfsetctl { * in this single structure so that they can all easily be collected and * copied back as required. */ -typedef struct filterstats { +typedef struct ipf_statistics { + u_long fr_icmp_coalesce; + u_long fr_tcp_frag; + u_long fr_tcp_pullup; + u_long fr_tcp_short; + u_long fr_tcp_small; + u_long fr_tcp_bad_flags; + u_long fr_udp_pullup; + u_long fr_ip_freed; + u_long fr_v6_ah_bad; + u_long fr_v6_bad; + u_long fr_v6_badfrag; + u_long fr_v6_dst_bad; + u_long fr_v6_esp_pullup; + u_long fr_v6_ext_short; + u_long fr_v6_ext_pullup; + u_long fr_v6_ext_hlen; + u_long fr_v6_frag_bad; + u_long fr_v6_frag_pullup; + u_long fr_v6_frag_size; + u_long fr_v6_gre_pullup; + u_long fr_v6_icmp6_pullup; + u_long fr_v6_rh_bad; + u_long fr_v6_badttl; /* TTL in packet doesn't reach minimum */ + u_long fr_v4_ah_bad; + u_long fr_v4_ah_pullup; + u_long fr_v4_esp_pullup; + u_long fr_v4_cipso_bad; + u_long fr_v4_cipso_tlen; + u_long fr_v4_gre_frag; + u_long fr_v4_gre_pullup; + u_long fr_v4_icmp_frag; + u_long fr_v4_icmp_pullup; + u_long fr_v4_badttl; /* TTL in packet doesn't reach minimum */ + u_long fr_v4_badsrc; /* source received doesn't match route */ + u_long fr_l4_badcksum; /* layer 4 header checksum failure */ + u_long fr_badcoalesces; u_long fr_pass; /* packets allowed */ u_long fr_block; /* packets denied */ u_long fr_nom; /* packets which don't match any rule */ @@ -749,8 +993,6 @@ typedef struct filterstats { u_long fr_ppkl; /* packets allowed and logged */ u_long fr_bpkl; /* packets denied and logged */ u_long fr_npkl; /* packets unmatched and logged */ - u_long fr_pkl; /* packets logged */ - u_long fr_skip; /* packets to be logged but buffer full */ u_long fr_ret; /* packets for which a return is sent */ u_long fr_acct; /* packets for which counting was performed */ u_long fr_bnfr; /* bad attempts to allocate fragment state */ @@ -759,15 +1001,15 @@ typedef struct filterstats { u_long fr_bads; /* bad attempts to allocate packet state */ u_long fr_ads; /* new packet state kept */ u_long fr_chit; /* cached hit */ + u_long fr_cmiss; /* cached miss */ u_long fr_tcpbad; /* TCP checksum check failures */ u_long fr_pull[2]; /* good and bad pullup attempts */ - u_long fr_badsrc; /* source received doesn't match route */ - u_long fr_badttl; /* TTL in packet doesn't reach minimum */ u_long fr_bad; /* bad IP packets to the filter */ u_long fr_ipv6; /* IPv6 packets in/out */ u_long fr_ppshit; /* dropped because of pps ceiling */ u_long fr_ipud; /* IP id update failures */ -} filterstats_t; + u_long fr_blocked[FRB_MAX_VALUE + 1]; +} ipf_statistics_t; /* * Log structure. Each packet header logged is prepended by one of these. @@ -777,6 +1019,7 @@ typedef struct filterstats { typedef struct iplog { u_32_t ipl_magic; u_int ipl_count; + u_32_t ipl_seqnum; struct timeval ipl_time; size_t ipl_dsize; struct iplog *ipl_next; @@ -796,18 +1039,19 @@ typedef struct ipflog { #else u_int fl_unit; #endif - u_32_t fl_rule; - u_32_t fl_flags; - u_32_t fl_lflags; - u_32_t fl_logtag; + u_32_t fl_rule; + u_32_t fl_flags; + u_32_t fl_lflags; + u_32_t fl_logtag; ipftag_t fl_nattag; - u_short fl_plen; /* extra data after hlen */ - u_short fl_loglevel; /* syslog log level */ - char fl_group[FR_GROUPLEN]; - u_char fl_hlen; /* length of IP headers saved */ - u_char fl_dir; - u_char fl_xxx[2]; /* pad */ - char fl_ifname[LIFNAMSIZ]; + u_short fl_plen; /* extra data after hlen */ + u_short fl_loglevel; /* syslog log level */ + char fl_group[FR_GROUPLEN]; + u_char fl_hlen; /* length of IP headers saved */ + u_char fl_dir; + u_char fl_breason; /* from fin_reason */ + u_char fl_family; /* address family of packet logged */ + char fl_ifname[LIFNAMSIZ]; } ipflog_t; #ifndef IPF_LOGGING @@ -817,12 +1061,12 @@ typedef struct ipflog { # define IPF_DEFAULT_PASS FR_PASS #endif -#define DEFAULT_IPFLOGSIZE 8192 +#define DEFAULT_IPFLOGSIZE 32768 #ifndef IPFILTER_LOGSIZE # define IPFILTER_LOGSIZE DEFAULT_IPFLOGSIZE #else -# if IPFILTER_LOGSIZE < DEFAULT_IPFLOGSIZE -# error IPFILTER_LOGSIZE too small. Must be >= DEFAULT_IPFLOGSIZE +# if IPFILTER_LOGSIZE < 8192 +# error IPFILTER_LOGSIZE too small. Must be >= 8192 # endif #endif @@ -867,34 +1111,30 @@ typedef struct ipflog { * For SIOCGETFS */ typedef struct friostat { - struct filterstats f_st[2]; - struct frentry *f_ipf[2][2]; - struct frentry *f_acct[2][2]; - struct frentry *f_ipf6[2][2]; - struct frentry *f_acct6[2][2]; - struct frentry *f_auth; - struct frgroup *f_groups[IPL_LOGSIZE][2]; - u_long f_froute[2]; - u_long f_ticks; - int f_locks[IPL_LOGMAX]; - size_t f_kmutex_sz; - size_t f_krwlock_sz; - int f_defpass; /* default pass - from fr_pass */ - int f_active; /* 1 or 0 - active rule set */ - int f_running; /* 1 if running, else 0 */ - int f_logging; /* 1 if enabled, else 0 */ - int f_features; - char f_version[32]; /* version string */ + ipf_statistics_t f_st[2]; + frentry_t *f_ipf[2][2]; + frentry_t *f_acct[2][2]; + frentry_t *f_auth; + struct frgroup *f_groups[IPL_LOGSIZE][2]; + u_long f_froute[2]; + u_long f_log_ok; + u_long f_log_fail; + u_long f_rb_no_mem; + u_long f_rb_node_max; + u_32_t f_ticks; + int f_locks[IPL_LOGSIZE]; + int f_defpass; /* default pass - from fr_pass */ + int f_active; /* 1 or 0 - active rule set */ + int f_running; /* 1 if running, else 0 */ + int f_logging; /* 1 if enabled, else 0 */ + int f_features; + char f_version[32]; /* version string */ } friostat_t; #define f_fin f_ipf[0] -#define f_fin6 f_ipf6[0] #define f_fout f_ipf[1] -#define f_fout6 f_ipf6[1] #define f_acctin f_acct[0] -#define f_acctin6 f_acct6[0] #define f_acctout f_acct[1] -#define f_acctout6 f_acct6[1] #define IPF_FEAT_LKM 0x001 #define IPF_FEAT_LOG 0x002 @@ -916,12 +1156,13 @@ typedef struct optlist { * Group list structure. */ typedef struct frgroup { - struct frgroup *fg_next; - struct frentry *fg_head; - struct frentry *fg_start; - u_32_t fg_flags; - int fg_ref; - char fg_name[FR_GROUPLEN]; + struct frgroup *fg_next; + struct frentry *fg_head; + struct frentry *fg_start; + struct frgroup **fg_set; + u_32_t fg_flags; + int fg_ref; + char fg_name[FR_GROUPLEN]; } frgroup_t; #define FG_NAME(g) (*(g)->fg_name == '\0' ? "" : (g)->fg_name) @@ -931,24 +1172,24 @@ typedef struct frgroup { * Used by state and NAT tables */ typedef struct icmpinfo { - u_short ici_id; - u_short ici_seq; - u_char ici_type; + u_short ici_id; + u_short ici_seq; + u_char ici_type; } icmpinfo_t; typedef struct udpinfo { - u_short us_sport; - u_short us_dport; + u_short us_sport; + u_short us_dport; } udpinfo_t; typedef struct tcpdata { - u_32_t td_end; - u_32_t td_maxend; - u_32_t td_maxwin; - u_32_t td_winscale; - u_32_t td_maxseg; - int td_winflags; + u_32_t td_end; + u_32_t td_maxend; + u_32_t td_maxwin; + u_32_t td_winscale; + u_32_t td_maxseg; + int td_winflags; } tcpdata_t; #define TCP_WSCALE_MAX 14 @@ -959,9 +1200,9 @@ typedef struct tcpdata { typedef struct tcpinfo { - u_short ts_sport; - u_short ts_dport; - tcpdata_t ts_data[2]; + u_32_t ts_sport; + u_32_t ts_dport; + tcpdata_t ts_data[2]; } tcpinfo_t; @@ -969,16 +1210,28 @@ typedef struct tcpinfo { * Structures to define a GRE header as seen in a packet. */ struct grebits { - u_32_t grb_C:1; - u_32_t grb_R:1; - u_32_t grb_K:1; - u_32_t grb_S:1; - u_32_t grb_s:1; - u_32_t grb_recur:1; - u_32_t grb_A:1; - u_32_t grb_flags:3; - u_32_t grb_ver:3; - u_short grb_ptype; +#if defined(sparc) + u_32_t grb_ver:3; + u_32_t grb_flags:3; + u_32_t grb_A:1; + u_32_t grb_recur:1; + u_32_t grb_s:1; + u_32_t grb_S:1; + u_32_t grb_K:1; + u_32_t grb_R:1; + u_32_t grb_C:1; +#else + u_32_t grb_C:1; + u_32_t grb_R:1; + u_32_t grb_K:1; + u_32_t grb_S:1; + u_32_t grb_s:1; + u_32_t grb_recur:1; + u_32_t grb_A:1; + u_32_t grb_flags:3; + u_32_t grb_ver:3; +#endif + u_short grb_ptype; }; typedef struct grehdr { @@ -986,8 +1239,8 @@ typedef struct grehdr { struct grebits gru_bits; u_short gru_flags; } gr_un; - u_short gr_len; - u_short gr_call; + u_short gr_len; + u_short gr_call; } grehdr_t; #define gr_flags gr_un.gru_flags @@ -1006,9 +1259,9 @@ typedef struct grehdr { * GRE information tracked by "keep state" */ typedef struct greinfo { - u_short gs_call[2]; - u_short gs_flags; - u_short gs_ptype; + u_short gs_call[2]; + u_short gs_flags; + u_short gs_ptype; } greinfo_t; #define GRE_REV(x) ((ntohs(x) >> 13) & 7) @@ -1018,11 +1271,11 @@ typedef struct greinfo { * Format of an Authentication header */ typedef struct authhdr { - u_char ah_next; - u_char ah_plen; - u_short ah_reserved; - u_32_t ah_spi; - u_32_t ah_seq; + u_char ah_next; + u_char ah_plen; + u_short ah_reserved; + u_32_t ah_spi; + u_32_t ah_seq; /* Following the sequence number field is 0 or more bytes of */ /* authentication data, as specified by ah_plen - RFC 2402. */ } authhdr_t; @@ -1035,14 +1288,15 @@ typedef struct ipftqent { struct ipftqent **tqe_pnext; struct ipftqent *tqe_next; struct ipftq *tqe_ifq; - void *tqe_parent; /* pointer back to NAT/state struct */ - u_long tqe_die; /* when this entriy is to die */ - u_long tqe_touched; - int tqe_flags; - int tqe_state[2]; /* current state of this entry */ + void *tqe_parent; /* pointer back to NAT/state struct */ + u_32_t tqe_die; /* when this entriy is to die */ + u_32_t tqe_touched; + int tqe_flags; + int tqe_state[2]; /* current state of this entry */ } ipftqent_t; #define TQE_RULEBASED 0x00000001 +#define TQE_DELETE 0x00000002 /* @@ -1050,45 +1304,46 @@ typedef struct ipftqent { */ typedef struct ipftq { ipfmutex_t ifq_lock; - u_int ifq_ttl; + u_int ifq_ttl; ipftqent_t *ifq_head; ipftqent_t **ifq_tail; - struct ipftq *ifq_next; - struct ipftq **ifq_pnext; - int ifq_ref; - u_int ifq_flags; + struct ipftq *ifq_next; + struct ipftq **ifq_pnext; + int ifq_ref; + u_int ifq_flags; } ipftq_t; #define IFQF_USER 0x01 /* User defined aging */ #define IFQF_DELETE 0x02 /* Marked for deletion */ #define IFQF_PROXY 0x04 /* Timeout queue in use by a proxy */ +#define IPFTQ_INIT(x,y,z) do { \ + (x)->ifq_ttl = (y); \ + (x)->ifq_head = NULL; \ + (x)->ifq_ref = 1; \ + (x)->ifq_tail = &(x)->ifq_head; \ + MUTEX_INIT(&(x)->ifq_lock, (z)); \ + } while (0) + #define IPF_HZ_MULT 1 #define IPF_HZ_DIVIDE 2 /* How many times a second ipfilter */ /* checks its timeout queues. */ #define IPF_TTLVAL(x) (((x) / IPF_HZ_MULT) * IPF_HZ_DIVIDE) -typedef int (*ipftq_delete_fn_t)(void *); - -/* - * Structure to define address for pool lookups. - */ -typedef struct { - u_char adf_len; - i6addr_t adf_addr; -} addrfamily_t; +typedef int (*ipftq_delete_fn_t)(struct ipf_main_softc_s *, void *); /* * Object structure description. For passing through in ioctls. */ typedef struct ipfobj { - u_32_t ipfo_rev; /* IPFilter version number */ - u_32_t ipfo_size; /* size of object at ipfo_ptr */ - void *ipfo_ptr; /* pointer to object */ - int ipfo_type; /* type of object being pointed to */ - int ipfo_offset; /* bytes from ipfo_ptr where to start */ - u_char ipfo_xxxpad[32]; /* reserved for future use */ + u_32_t ipfo_rev; /* IPFilter version number */ + u_32_t ipfo_size; /* size of object at ipfo_ptr */ + void *ipfo_ptr; /* pointer to object */ + int ipfo_type; /* type of object being pointed to */ + int ipfo_offset; /* bytes from ipfo_ptr where to start */ + int ipfo_retval; /* return value */ + u_char ipfo_xxxpad[28]; /* reserved for future use */ } ipfobj_t; #define IPFOBJ_FRENTRY 0 /* struct frentry */ @@ -1110,18 +1365,32 @@ typedef struct ipfobj { #define IPFOBJ_GENITER 16 /* struct ipfgeniter */ #define IPFOBJ_GTABLE 17 /* struct ipftable */ #define IPFOBJ_LOOKUPITER 18 /* struct ipflookupiter */ -#define IPFOBJ_STATETQTAB 19 /* struct ipftq [NSTATES] */ -#define IPFOBJ_COUNT 20 /* How many #defines are above this? */ +#define IPFOBJ_STATETQTAB 19 /* struct ipftq * NSTATES */ +#define IPFOBJ_IPFEXPR 20 +#define IPFOBJ_PROXYCTL 21 /* strct ap_ctl */ +#define IPFOBJ_FRIPF 22 /* structfripf */ +#define IPFOBJ_COUNT 23 /* How many #defines are above this? */ typedef union ipftunevalptr { - void *ipftp_void; - u_long *ipftp_long; - u_int *ipftp_int; - u_short *ipftp_short; - u_char *ipftp_char; + void *ipftp_void; + u_long *ipftp_long; + u_int *ipftp_int; + u_short *ipftp_short; + u_char *ipftp_char; + u_long ipftp_offset; } ipftunevalptr_t; +typedef union ipftuneval { + u_long ipftu_long; + u_int ipftu_int; + u_short ipftu_short; + u_char ipftu_char; +} ipftuneval_t; + +struct ipftuneable; +typedef int (* ipftunefunc_t) __P((struct ipf_main_softc_s *, struct ipftuneable *, ipftuneval_t *)); + typedef struct ipftuneable { ipftunevalptr_t ipft_una; const char *ipft_name; @@ -1130,6 +1399,7 @@ typedef struct ipftuneable { int ipft_sz; int ipft_flags; struct ipftuneable *ipft_next; + ipftunefunc_t ipft_func; } ipftuneable_t; #define ipft_addr ipft_una.ipftp_void @@ -1141,13 +1411,6 @@ typedef struct ipftuneable { #define IPFT_RDONLY 1 /* read-only */ #define IPFT_WRDISABLED 2 /* write when disabled only */ -typedef union ipftuneval { - u_long ipftu_long; - u_int ipftu_int; - u_short ipftu_short; - u_char ipftu_char; -} ipftuneval_t; - typedef struct ipftune { void *ipft_cookie; ipftuneval_t ipft_un; @@ -1163,6 +1426,53 @@ typedef struct ipftune { #define ipft_vshort ipft_un.ipftu_short #define ipft_vchar ipft_un.ipftu_char +/* + * Hash table header + */ +#define IPFHASH(x,y) typedef struct { \ + ipfrwlock_t ipfh_lock; \ + struct x *ipfh_head; \ + } y + +/* +** HPUX Port +*/ +#ifdef __hpux +/* HP-UX locking sequence deadlock detection module lock MAJOR ID */ +# define IPF_SMAJ 0 /* temp assignment XXX, not critical */ +#endif + +#if !defined(CDEV_MAJOR) && defined (__FreeBSD_version) && \ + (__FreeBSD_version >= 220000) +# define CDEV_MAJOR 79 +#endif + +/* + * Post NetBSD 1.2 has the PFIL interface for packet filters. This turns + * on those hooks. We don't need any special mods in non-IP Filter code + * with this! + */ +#if (defined(NetBSD) && (NetBSD > 199609) && (NetBSD <= 1991011)) || \ + (defined(NetBSD1_2) && NetBSD1_2 > 1) || \ + (defined(__FreeBSD__) && (__FreeBSD_version >= 500043)) +# if (defined(NetBSD) && NetBSD >= 199905) +# define PFIL_HOOKS +# endif +# ifdef PFIL_HOOKS +# define NETBSD_PF +# endif +#endif + +#ifdef _KERNEL +# define FR_VERBOSE(verb_pr) +# define FR_DEBUG(verb_pr) +#else +extern void ipfkdebug __P((char *, ...)); +extern void ipfkverbose __P((char *, ...)); +# define FR_VERBOSE(verb_pr) ipfkverbose verb_pr +# define FR_DEBUG(verb_pr) ipfkdebug verb_pr +#endif + /* * */ @@ -1171,7 +1481,7 @@ typedef struct ipfruleiter { char iri_group[FR_GROUPLEN]; int iri_active; int iri_nrules; - int iri_v; + int iri_v; /* No longer used (compatibility) */ frentry_t *iri_rule; } ipfruleiter_t; @@ -1210,6 +1520,19 @@ typedef struct ipftable { #define IPFTABLE_BUCKETS_NATOUT 3 +typedef struct ipf_v4_masktab_s { + u_32_t imt4_active[33]; + int imt4_masks[33]; + int imt4_max; +} ipf_v4_masktab_t; + +typedef struct ipf_v6_masktab_s { + i6addr_t imt6_active[129]; + int imt6_masks[129]; + int imt6_max; +} ipf_v6_masktab_t; + + /* * */ @@ -1222,190 +1545,246 @@ typedef struct ipftoken { int ipt_type; int ipt_uid; int ipt_subtype; - int ipt_alive; + int ipt_ref; + int ipt_complete; } ipftoken_t; /* -** HPUX Port -*/ -#ifdef __hpux -/* HP-UX locking sequence deadlock detection module lock MAJOR ID */ -# define IPF_SMAJ 0 /* temp assignment XXX, not critical */ -#endif - -#if !defined(CDEV_MAJOR) && defined (__FreeBSD_version) && \ - (__FreeBSD_version >= 220000) -# define CDEV_MAJOR 79 -#endif + * + */ +typedef struct ipfexp { + int ipfe_cmd; + int ipfe_not; + int ipfe_narg; + int ipfe_size; + int ipfe_arg0[1]; +} ipfexp_t; /* - * Post NetBSD 1.2 has the PFIL interface for packet filters. This turns - * on those hooks. We don't need any special mods in non-IP Filter code - * with this! + * Currently support commands (ipfe_cmd) + * 32bits is split up follows: + * aabbcccc + * aa = 0 = packet matching, 1 = meta data matching + * bb = IP protocol number + * cccc = command */ -#if (defined(NetBSD) && (NetBSD > 199609) && (NetBSD <= 1991011)) || \ - (defined(NetBSD1_2) && NetBSD1_2 > 1) || \ - (defined(__FreeBSD__) && (__FreeBSD_version >= 500043)) -# if defined(NetBSD) && (NetBSD >= 199905) -# define PFIL_HOOKS -# endif -# ifdef PFIL_HOOKS -# define NETBSD_PF +#define IPF_EXP_IP_PR 0x00000001 +#define IPF_EXP_IP_ADDR 0x00000002 +#define IPF_EXP_IP_SRCADDR 0x00000003 +#define IPF_EXP_IP_DSTADDR 0x00000004 +#define IPF_EXP_IP6_ADDR 0x00000005 +#define IPF_EXP_IP6_SRCADDR 0x00000006 +#define IPF_EXP_IP6_DSTADDR 0x00000007 +#define IPF_EXP_TCP_FLAGS 0x00060001 +#define IPF_EXP_TCP_PORT 0x00060002 +#define IPF_EXP_TCP_SPORT 0x00060003 +#define IPF_EXP_TCP_DPORT 0x00060004 +#define IPF_EXP_UDP_PORT 0x00110002 +#define IPF_EXP_UDP_SPORT 0x00110003 +#define IPF_EXP_UDP_DPORT 0x00110004 +#define IPF_EXP_IDLE_GT 0x01000001 +#define IPF_EXP_TCP_STATE 0x01060002 +#define IPF_EXP_END 0xffffffff + +#define ONE_DAY IPF_TTLVAL(1 * 86400) /* 1 day */ +#define FIVE_DAYS (5 * ONE_DAY) + +typedef struct ipf_main_softc_s { + struct ipf_main_softc_s *ipf_next; + ipfmutex_t ipf_rw; + ipfmutex_t ipf_timeoutlock; + ipfrwlock_t ipf_mutex; + ipfrwlock_t ipf_frag; + ipfrwlock_t ipf_global; + ipfrwlock_t ipf_tokens; + ipfrwlock_t ipf_state; + ipfrwlock_t ipf_nat; + ipfrwlock_t ipf_natfrag; + ipfrwlock_t ipf_poolrw; + int ipf_dynamic_softc; + int ipf_refcnt; + int ipf_running; + int ipf_flags; + int ipf_active; + int ipf_control_forwarding; + int ipf_update_ipid; + int ipf_chksrc; /* causes a system crash if enabled */ + int ipf_pass; + int ipf_minttl; + int ipf_icmpminfragmtu; + int ipf_interror; /* Should be in a struct that is per */ + /* thread or process. Does not belong */ + /* here but there's a lot more work */ + /* in doing that properly. For now, */ + /* it is squatting. */ + u_int ipf_tcpidletimeout; + u_int ipf_tcpclosewait; + u_int ipf_tcplastack; + u_int ipf_tcptimewait; + u_int ipf_tcptimeout; + u_int ipf_tcpsynsent; + u_int ipf_tcpsynrecv; + u_int ipf_tcpclosed; + u_int ipf_tcphalfclosed; + u_int ipf_udptimeout; + u_int ipf_udpacktimeout; + u_int ipf_icmptimeout; + u_int ipf_icmpacktimeout; + u_int ipf_iptimeout; + u_long ipf_ticks; + u_long ipf_userifqs; + u_long ipf_rb_no_mem; + u_long ipf_rb_node_max; + u_long ipf_frouteok[2]; + ipftuneable_t *ipf_tuners; + void *ipf_frag_soft; + void *ipf_nat_soft; + void *ipf_state_soft; + void *ipf_auth_soft; + void *ipf_proxy_soft; + void *ipf_sync_soft; + void *ipf_lookup_soft; + void *ipf_log_soft; + struct frgroup *ipf_groups[IPL_LOGSIZE][2]; + frentry_t *ipf_rules[2][2]; + frentry_t *ipf_acct[2][2]; + frentry_t *ipf_rule_explist[2]; + ipftoken_t *ipf_token_head; + ipftoken_t **ipf_token_tail; +#if defined(__FreeBSD_version) && (__FreeBSD_version >= 300000) && \ + defined(_KERNEL) + struct callout_handle ipf_slow_ch; +#endif +#if defined(linux) && defined(_KERNEL) + struct timer_list ipf_timer; +#endif +#if NETBSD_GE_REV(104040000) + struct callout ipf_slow_ch; +#endif +#if SOLARIS +# if SOLARIS2 >= 7 + timeout_id_t ipf_slow_ch; +# else + int ipf_slow_ch; # endif #endif - -#ifdef _KERNEL -# define FR_VERBOSE(verb_pr) -# define FR_DEBUG(verb_pr) -#else -extern void debug __P((char *, ...)); -extern void verbose __P((char *, ...)); -# define FR_VERBOSE(verb_pr) verbose verb_pr -# define FR_DEBUG(verb_pr) debug verb_pr +#if defined(_KERNEL) +# if SOLARIS + struct pollhead ipf_poll_head[IPL_LOGSIZE]; + void *ipf_dip; +# if defined(INSTANCES) + int ipf_get_loopback; + u_long ipf_idnum; + net_handle_t ipf_nd_v4; + net_handle_t ipf_nd_v6; + hook_t *ipf_hk_v4_in; + hook_t *ipf_hk_v4_out; + hook_t *ipf_hk_v4_nic; + hook_t *ipf_hk_v6_in; + hook_t *ipf_hk_v6_out; + hook_t *ipf_hk_v6_nic; + hook_t *ipf_hk_loop_v4_in; + hook_t *ipf_hk_loop_v4_out; + hook_t *ipf_hk_loop_v6_in; + hook_t *ipf_hk_loop_v6_out; +# endif +# else +# if defined(linux) && defined(_KERNEL) + struct poll_table_struct ipf_selwait[IPL_LOGSIZE]; + wait_queue_head_t iplh_linux[IPL_LOGSIZE]; +# else + struct selinfo ipf_selwait[IPL_LOGSIZE]; +# endif +# endif #endif + void *ipf_slow; + ipf_statistics_t ipf_stats[2]; + u_char ipf_iss_secret[32]; + u_short ipf_ip_id; +} ipf_main_softc_t; +#define IPFERROR(_e) do { softc->ipf_interror = (_e); \ + DT1(user_error, int, _e); \ + } while (0) #ifndef _KERNEL -extern int fr_check __P((struct ip *, int, void *, int, mb_t **)); -extern int (*fr_checkp) __P((ip_t *, int, void *, int, mb_t **)); -extern int ipf_log __P((void)); +extern int ipf_check __P((void *, struct ip *, int, void *, int, mb_t **)); +extern int (*ipf_checkp) __P((ip_t *, int, void *, int, mb_t **)); extern struct ifnet *get_unit __P((char *, int)); extern char *get_ifname __P((struct ifnet *)); -# if defined(__NetBSD__) || defined(__OpenBSD__) || \ - (_BSDI_VERSION >= 199701) || (__FreeBSD_version >= 300000) -extern int iplioctl __P((int, ioctlcmd_t, caddr_t, int)); -# else -extern int iplioctl __P((int, ioctlcmd_t, caddr_t, int)); -# endif -extern int iplopen __P((dev_t, int)); -extern int iplclose __P((dev_t, int)); +extern int ipfioctl __P((ipf_main_softc_t *, int, ioctlcmd_t, + caddr_t, int)); extern void m_freem __P((mb_t *)); +extern size_t msgdsize __P((mb_t *)); extern int bcopywrap __P((void *, void *, size_t)); #else /* #ifndef _KERNEL */ -# ifdef BSD -# if (defined(__NetBSD__) && (__NetBSD_Version__ < 399000000)) || \ - defined(__osf__) || \ - (defined(__FreeBSD_version) && (__FreeBSD_version < 500043)) -# include -# else -# include -# endif -extern struct selinfo ipfselwait[IPL_LOGSIZE]; -# endif # if defined(__NetBSD__) && defined(PFIL_HOOKS) extern void ipfilterattach __P((int)); # endif extern int ipl_enable __P((void)); extern int ipl_disable __P((void)); -extern int ipf_inject __P((fr_info_t *, mb_t *)); # ifdef MENTAT -extern int fr_check __P((struct ip *, int, void *, int, void *, - mblk_t **)); +extern int ipf_check __P((void *, struct ip *, int, void *, int, void *, + mblk_t **)); # if SOLARIS +extern void ipf_prependmbt(fr_info_t *, mblk_t *); # if SOLARIS2 >= 7 -extern int iplioctl __P((dev_t, int, intptr_t, int, cred_t *, int *)); +extern int ipfioctl __P((dev_t, int, intptr_t, int, cred_t *, int *)); # else -extern int iplioctl __P((dev_t, int, int *, int, cred_t *, int *)); +extern int ipfioctl __P((dev_t, int, int *, int, cred_t *, int *)); # endif -extern int iplopen __P((dev_t *, int, int, cred_t *)); -extern int iplclose __P((dev_t, int, int, cred_t *)); -extern int iplread __P((dev_t, uio_t *, cred_t *)); -extern int iplwrite __P((dev_t, uio_t *, cred_t *)); # endif # ifdef __hpux -extern int iplopen __P((dev_t, int, intptr_t, int)); -extern int iplclose __P((dev_t, int, int)); -extern int iplioctl __P((dev_t, int, caddr_t, int)); -extern int iplread __P((dev_t, uio_t *)); -extern int iplwrite __P((dev_t, uio_t *)); -extern int iplselect __P((dev_t, int)); +extern int ipfioctl __P((dev_t, int, caddr_t, int)); +extern int ipf_select __P((dev_t, int)); # endif -extern int fr_qout __P((queue_t *, mblk_t *)); +extern int ipf_qout __P((queue_t *, mblk_t *)); # else /* MENTAT */ -extern int fr_check __P((struct ip *, int, void *, int, mb_t **)); +extern int ipf_check __P((void *, struct ip *, int, void *, int, mb_t **)); extern int (*fr_checkp) __P((ip_t *, int, void *, int, mb_t **)); extern size_t mbufchainlen __P((mb_t *)); # ifdef __sgi # include -extern int iplioctl __P((dev_t, int, caddr_t, int, cred_t *, int *)); -extern int iplopen __P((dev_t *, int, int, cred_t *)); -extern int iplclose __P((dev_t, int, int, cred_t *)); -extern int iplread __P((dev_t, uio_t *, cred_t *)); -extern int iplwrite __P((dev_t, uio_t *, cred_t *)); +extern int ipfioctl __P((dev_t, int, caddr_t, int, cred_t *, int *)); extern int ipfilter_sgi_attach __P((void)); extern void ipfilter_sgi_detach __P((void)); extern void ipfilter_sgi_intfsync __P((void)); # else # ifdef IPFILTER_LKM -extern int iplidentify __P((char *)); +extern int ipf_identify __P((char *)); # endif -# if (defined(_BSDI_VERSION) && _BSDI_VERSION >= 199510) || \ - (__FreeBSD_version >= 220000) || \ - (NetBSD >= 199511) || defined(__OpenBSD__) -# if defined(__NetBSD__) || \ - (defined(_BSDI_VERSION) && _BSDI_VERSION >= 199701) || \ - defined(__OpenBSD__) || (__FreeBSD_version >= 300000) +# if BSDOS_GE_REV(199510) || FREEBSD_GE_REV(220000) || \ + (defined(NetBSD) && (NetBSD >= 199511)) || defined(__OpenBSD__) +# if defined(__NetBSD__) || BSDOS_GE_REV(199701) || \ + defined(__OpenBSD__) || FREEBSD_GE_REV(300000) # if (__FreeBSD_version >= 500024) # if (__FreeBSD_version >= 502116) -extern int iplioctl __P((struct cdev*, u_long, caddr_t, int, struct thread *)); +extern int ipfioctl __P((struct cdev*, u_long, caddr_t, int, struct thread *)); # else -extern int iplioctl __P((dev_t, u_long, caddr_t, int, struct thread *)); +extern int ipfioctl __P((dev_t, u_long, caddr_t, int, struct thread *)); # endif /* __FreeBSD_version >= 502116 */ # else -# if (__NetBSD_Version__ >= 499001000) -extern int iplioctl __P((dev_t, u_long, void *, int, struct lwp *)); +# if NETBSD_GE_REV(499001000) +extern int ipfioctl __P((dev_t, u_long, void *, int, struct lwp *)); # else -# if (__NetBSD_Version__ >= 399001400) -extern int iplioctl __P((dev_t, u_long, caddr_t, int, struct lwp *)); +# if NETBSD_GE_REV(399001400) +extern int ipfioctl __P((dev_t, u_long, caddr_t, int, struct lwp *)); # else -extern int iplioctl __P((dev_t, u_long, caddr_t, int, struct proc *)); +extern int ipfioctl __P((dev_t, u_long, caddr_t, int, struct proc *)); # endif # endif # endif /* __FreeBSD_version >= 500024 */ # else -extern int iplioctl __P((dev_t, int, caddr_t, int, struct thread *)); +extern int ipfioctl __P((dev_t, int, caddr_t, int, struct proc *)); # endif -# if (__FreeBSD_version >= 500024) -# if (__FreeBSD_version >= 502116) -extern int iplopen __P((struct cdev*, int, int, struct thread *)); -extern int iplclose __P((struct cdev*, int, int, struct thread *)); -# else -extern int iplopen __P((dev_t, int, int, struct thread *)); -extern int iplclose __P((dev_t, int, int, struct thread *)); -# endif /* __FreeBSD_version >= 502116 */ -# else -# if (__NetBSD_Version__ >= 399001400) -extern int iplopen __P((dev_t, int, int, struct lwp *)); -extern int iplclose __P((dev_t, int, int, struct lwp *)); -# else -extern int iplopen __P((dev_t, int, int, struct proc *)); -extern int iplclose __P((dev_t, int, int, struct proc *)); -# endif /* __NetBSD_Version__ >= 399001400 */ -# endif /* __FreeBSD_version >= 500024 */ # else # ifdef linux -extern int iplioctl __P((struct inode *, struct file *, u_int, u_long)); +extern int ipfioctl __P((struct inode *, struct file *, u_int, u_long)); # else -extern int iplopen __P((dev_t, int)); -extern int iplclose __P((dev_t, int)); -extern int iplioctl __P((dev_t, int, caddr_t, int)); +extern int ipfioctl __P((dev_t, int, caddr_t, int)); # endif # endif /* (_BSDI_VERSION >= 199510) */ -# if BSD >= 199306 -# if (__FreeBSD_version >= 502116) -extern int iplread __P((struct cdev*, struct uio *, int)); -extern int iplwrite __P((struct cdev*, struct uio *, int)); -# else -extern int iplread __P((dev_t, struct uio *, int)); -extern int iplwrite __P((dev_t, struct uio *, int)); -# endif /* __FreeBSD_version >= 502116 */ -# else -# ifndef linux -extern int iplread __P((dev_t, struct uio *)); -extern int iplwrite __P((dev_t, struct uio *)); -# endif -# endif /* BSD >= 199306 */ # endif /* __ sgi */ # endif /* MENTAT */ @@ -1416,153 +1795,206 @@ extern void ipf_event_reg __P((void)); extern void ipf_event_dereg __P((void)); # endif -#endif /* #ifndef _KERNEL */ +# if defined(INSTANCES) +extern ipf_main_softc_t *ipf_find_softc __P((u_long)); +extern int ipf_set_loopback __P((ipf_main_softc_t *, ipftuneable_t *, + ipftuneval_t *)); +# endif -extern ipfmutex_t ipl_mutex, ipf_authmx, ipf_rw, ipf_hostmap; -extern ipfmutex_t ipf_timeoutlock, ipf_stinsert, ipf_natio, ipf_nat_new; -extern ipfrwlock_t ipf_mutex, ipf_global, ip_poolrw, ipf_ipidfrag; -extern ipfrwlock_t ipf_frag, ipf_state, ipf_nat, ipf_natfrag, ipf_auth; -extern ipfrwlock_t ipf_frcache, ipf_tokens; +#endif /* #ifndef _KERNEL */ extern char *memstr __P((const char *, char *, size_t, size_t)); extern int count4bits __P((u_32_t)); -extern int frrequest __P((int, ioctlcmd_t, caddr_t, int, int)); -extern char *getifname __P((struct ifnet *)); -extern int ipfattach __P((void)); -extern int ipfdetach __P((void)); -extern u_short ipf_cksum __P((u_short *, int)); -extern int copyinptr __P((void *, void *, size_t)); -extern int copyoutptr __P((void *, void *, size_t)); -extern int fr_fastroute __P((mb_t *, mb_t **, fr_info_t *, frdest_t *)); -extern int fr_inobj __P((void *, void *, int)); -extern int fr_inobjsz __P((void *, void *, int, int)); -extern int fr_ioctlswitch __P((int, void *, ioctlcmd_t, int, int, void *)); -extern int fr_ipf_ioctl __P((caddr_t, ioctlcmd_t, int, int, void *)); -extern int fr_ipftune __P((ioctlcmd_t, void *)); -extern int fr_outobj __P((void *, void *, int)); -extern int fr_outobjsz __P((void *, void *, int, int)); -extern void *fr_pullup __P((mb_t *, fr_info_t *, int)); -extern void fr_resolvedest __P((struct frdest *, int)); -extern int fr_resolvefunc __P((void *)); -extern void *fr_resolvenic __P((char *, int)); -extern int fr_send_icmp_err __P((int, fr_info_t *, int)); -extern int fr_send_reset __P((fr_info_t *)); -#if (__FreeBSD_version < 501000) || !defined(_KERNEL) -extern int ppsratecheck __P((struct timeval *, int *, int)); +#ifdef USE_INET6 +extern int count6bits __P((u_32_t *)); #endif -extern ipftq_t *fr_addtimeoutqueue __P((ipftq_t **, u_int)); -extern void fr_deletequeueentry __P((ipftqent_t *)); -extern int fr_deletetimeoutqueue __P((ipftq_t *)); -extern void fr_freetimeoutqueue __P((ipftq_t *)); -extern void fr_movequeue __P((ipftqent_t *, ipftq_t *, ipftq_t *)); -extern void fr_queueappend __P((ipftqent_t *, ipftq_t *, void *)); -extern void fr_queueback __P((ipftqent_t *)); -extern void fr_queuefront __P((ipftqent_t *)); -extern void fr_checkv4sum __P((fr_info_t *)); -extern int fr_checkl4sum __P((fr_info_t *)); -extern int fr_ifpfillv4addr __P((int, struct sockaddr_in *, +extern int frrequest __P((ipf_main_softc_t *, int, ioctlcmd_t, caddr_t, + int, int)); +extern char *getifname __P((struct ifnet *)); +extern int ipfattach __P((ipf_main_softc_t *)); +extern int ipfdetach __P((ipf_main_softc_t *)); +extern u_short ipf_cksum __P((u_short *, int)); +extern int copyinptr __P((ipf_main_softc_t *, void *, void *, size_t)); +extern int copyoutptr __P((ipf_main_softc_t *, void *, void *, size_t)); +extern int ipf_fastroute __P((mb_t *, mb_t **, fr_info_t *, frdest_t *)); +extern int ipf_inject __P((fr_info_t *, mb_t *)); +extern int ipf_inobj __P((ipf_main_softc_t *, void *, ipfobj_t *, + void *, int)); +extern int ipf_inobjsz __P((ipf_main_softc_t *, void *, void *, + int , int)); +extern int ipf_ioctlswitch __P((ipf_main_softc_t *, int, void *, + ioctlcmd_t, int, int, void *)); +extern int ipf_ipf_ioctl __P((ipf_main_softc_t *, caddr_t, ioctlcmd_t, + int, int, void *)); +extern int ipf_ipftune __P((ipf_main_softc_t *, ioctlcmd_t, void *)); +extern int ipf_matcharray_load __P((ipf_main_softc_t *, caddr_t, + ipfobj_t *, int **)); +extern int ipf_matcharray_verify __P((int *, int)); +extern int ipf_outobj __P((ipf_main_softc_t *, void *, void *, int)); +extern int ipf_outobjk __P((ipf_main_softc_t *, ipfobj_t *, void *)); +extern int ipf_outobjsz __P((ipf_main_softc_t *, void *, void *, + int, int)); +extern void *ipf_pullup __P((mb_t *, fr_info_t *, int)); +extern int ipf_resolvedest __P((ipf_main_softc_t *, char *, + struct frdest *, int)); +extern int ipf_resolvefunc __P((ipf_main_softc_t *, void *)); +extern void *ipf_resolvenic __P((ipf_main_softc_t *, char *, int)); +extern int ipf_send_icmp_err __P((int, fr_info_t *, int)); +extern int ipf_send_reset __P((fr_info_t *)); +#if (defined(__FreeBSD_version) && (__FreeBSD_version < 501000)) || \ + !defined(_KERNEL) || defined(linux) +#endif +extern void ipf_apply_timeout __P((ipftq_t *, u_int)); +extern ipftq_t *ipf_addtimeoutqueue __P((ipf_main_softc_t *, ipftq_t **, + u_int)); +extern void ipf_deletequeueentry __P((ipftqent_t *)); +extern int ipf_deletetimeoutqueue __P((ipftq_t *)); +extern void ipf_freetimeoutqueue __P((ipf_main_softc_t *, ipftq_t *)); +extern void ipf_movequeue __P((u_long, ipftqent_t *, ipftq_t *, + ipftq_t *)); +extern void ipf_queueappend __P((u_long, ipftqent_t *, ipftq_t *, void *)); +extern void ipf_queueback __P((u_long, ipftqent_t *)); +extern int ipf_queueflush __P((ipf_main_softc_t *, ipftq_delete_fn_t, + ipftq_t *, ipftq_t *, u_int *, int, int)); +extern void ipf_queuefront __P((ipftqent_t *)); +extern int ipf_settimeout_tcp __P((ipftuneable_t *, ipftuneval_t *, + ipftq_t *)); +extern int ipf_checkv4sum __P((fr_info_t *)); +extern int ipf_checkl4sum __P((fr_info_t *)); +extern int ipf_ifpfillv4addr __P((int, struct sockaddr_in *, struct sockaddr_in *, struct in_addr *, struct in_addr *)); -extern int fr_coalesce __P((fr_info_t *)); +extern int ipf_coalesce __P((fr_info_t *)); #ifdef USE_INET6 -extern void fr_checkv6sum __P((fr_info_t *)); -extern int fr_ifpfillv6addr __P((int, struct sockaddr_in6 *, - struct sockaddr_in6 *, struct in_addr *, - struct in_addr *)); +extern int ipf_checkv6sum __P((fr_info_t *)); +extern int ipf_ifpfillv6addr __P((int, struct sockaddr_in6 *, + struct sockaddr_in6 *, i6addr_t *, + i6addr_t *)); #endif -extern int fr_addipftune __P((ipftuneable_t *)); -extern int fr_delipftune __P((ipftuneable_t *)); +extern int ipf_tune_add __P((ipf_main_softc_t *, ipftuneable_t *)); +extern int ipf_tune_add_array __P((ipf_main_softc_t *, ipftuneable_t *)); +extern int ipf_tune_del __P((ipf_main_softc_t *, ipftuneable_t *)); +extern int ipf_tune_del_array __P((ipf_main_softc_t *, ipftuneable_t *)); +extern int ipf_tune_array_link __P((ipf_main_softc_t *, ipftuneable_t *)); +extern int ipf_tune_array_unlink __P((ipf_main_softc_t *, + ipftuneable_t *)); +extern ipftuneable_t *ipf_tune_array_copy __P((void *, size_t, + ipftuneable_t *)); -extern int frflush __P((minor_t, int, int)); -extern void frsync __P((void *)); -extern frgroup_t *fr_addgroup __P((char *, void *, u_32_t, minor_t, int)); -extern int fr_derefrule __P((frentry_t **)); -extern void fr_delgroup __P((char *, minor_t, int)); -extern frgroup_t *fr_findgroup __P((char *, minor_t, int, frgroup_t ***)); +extern int ipf_pr_pullup __P((fr_info_t *, int)); -extern int fr_loginit __P((void)); -extern int ipflog_canread __P((int)); -extern int ipflog_clear __P((minor_t)); -extern int ipflog_read __P((minor_t, uio_t *)); -extern int ipflog __P((fr_info_t *, u_int)); -extern int ipllog __P((int, fr_info_t *, void **, size_t *, int *, int)); -extern void fr_logunload __P((void)); +extern int ipf_flush __P((ipf_main_softc_t *, minor_t, int)); +extern frgroup_t *ipf_group_add __P((ipf_main_softc_t *, char *, void *, + u_32_t, minor_t, int)); +extern void ipf_group_del __P((ipf_main_softc_t *, frgroup_t *, + frentry_t *)); +extern int ipf_derefrule __P((ipf_main_softc_t *, frentry_t **)); +extern frgroup_t *ipf_findgroup __P((ipf_main_softc_t *, char *, minor_t, + int, frgroup_t ***)); -extern frentry_t *fr_acctpkt __P((fr_info_t *, u_32_t *)); -extern int fr_copytolog __P((int, char *, int)); -extern u_short fr_cksum __P((mb_t *, ip_t *, int, void *, int)); -extern void fr_deinitialise __P((void)); -extern frentry_t *fr_dolog __P((fr_info_t *, u_32_t *)); -extern frentry_t *fr_dstgrpmap __P((fr_info_t *, u_32_t *)); -extern void fr_fixskip __P((frentry_t **, frentry_t *, int)); -extern void fr_forgetifp __P((void *)); -extern frentry_t *fr_getrulen __P((int, char *, u_32_t)); -extern void fr_getstat __P((struct friostat *)); -extern int fr_ifpaddr __P((int, int, void *, - struct in_addr *, struct in_addr *)); -extern int fr_initialise __P((void)); -extern int fr_lock __P((caddr_t, int *)); -extern int fr_makefrip __P((int, ip_t *, fr_info_t *)); -extern int fr_matchtag __P((ipftag_t *, ipftag_t *)); -extern int fr_matchicmpqueryreply __P((int, icmpinfo_t *, - struct icmp *, int)); -extern u_32_t fr_newisn __P((fr_info_t *)); -extern u_short fr_nextipid __P((fr_info_t *)); -extern int ipf_queueflush __P((ipftq_delete_fn_t, ipftq_t *, ipftq_t *)); -extern int fr_rulen __P((int, frentry_t *)); -extern int fr_scanlist __P((fr_info_t *, u_32_t)); -extern frentry_t *fr_srcgrpmap __P((fr_info_t *, u_32_t *)); -extern int fr_tcpudpchk __P((fr_info_t *, frtuc_t *)); -extern int fr_verifysrc __P((fr_info_t *fin)); -extern int fr_zerostats __P((void *)); -extern ipftoken_t *ipf_findtoken __P((int, int, void *)); -extern int ipf_getnextrule __P((ipftoken_t *, void *)); -extern void ipf_expiretokens __P((void)); -extern void ipf_freetoken __P((ipftoken_t *)); -extern int ipf_deltoken __P((int,int, void *)); -extern int ipfsync __P((void)); -extern int ipf_genericiter __P((void *, int, void *)); -#ifndef ipf_random +extern int ipf_log_init __P((void)); +extern int ipf_log_bytesused __P((ipf_main_softc_t *, int)); +extern int ipf_log_canread __P((ipf_main_softc_t *, int)); +extern int ipf_log_clear __P((ipf_main_softc_t *, minor_t)); +extern u_long ipf_log_failures __P((ipf_main_softc_t *, int)); +extern int ipf_log_read __P((ipf_main_softc_t *, minor_t, uio_t *)); +extern int ipf_log_items __P((ipf_main_softc_t *, int, fr_info_t *, + void **, size_t *, int *, int)); +extern u_long ipf_log_logok __P((ipf_main_softc_t *, int)); +extern void ipf_log_unload __P((ipf_main_softc_t *)); +extern int ipf_log_pkt __P((fr_info_t *, u_int)); + +extern frentry_t *ipf_acctpkt __P((fr_info_t *, u_32_t *)); +extern u_short fr_cksum __P((fr_info_t *, ip_t *, int, void *)); +extern void ipf_deinitialise __P((ipf_main_softc_t *)); +extern int ipf_deliverlocal __P((ipf_main_softc_t *, int, void *, + i6addr_t *)); +extern frentry_t *ipf_dstgrpmap __P((fr_info_t *, u_32_t *)); +extern void ipf_fixskip __P((frentry_t **, frentry_t *, int)); +extern void ipf_forgetifp __P((ipf_main_softc_t *, void *)); +extern frentry_t *ipf_getrulen __P((ipf_main_softc_t *, int, char *, + u_32_t)); +extern int ipf_ifpaddr __P((ipf_main_softc_t *, int, int, void *, + i6addr_t *, i6addr_t *)); +extern void ipf_inet_mask_add __P((int, ipf_v4_masktab_t *)); +extern void ipf_inet_mask_del __P((int, ipf_v4_masktab_t *)); +#ifdef USE_INET6 +extern void ipf_inet6_mask_add __P((int, i6addr_t *, + ipf_v6_masktab_t *)); +extern void ipf_inet6_mask_del __P((int, i6addr_t *, + ipf_v6_masktab_t *)); +#endif +extern int ipf_initialise __P((void)); +extern int ipf_lock __P((caddr_t, int *)); +extern int ipf_makefrip __P((int, ip_t *, fr_info_t *)); +extern int ipf_matchtag __P((ipftag_t *, ipftag_t *)); +extern int ipf_matchicmpqueryreply __P((int, icmpinfo_t *, + struct icmp *, int)); +extern u_32_t ipf_newisn __P((fr_info_t *)); +extern u_short ipf_nextipid __P((fr_info_t *)); +extern u_int ipf_pcksum __P((fr_info_t *, int, u_int)); +extern void ipf_rule_expire __P((ipf_main_softc_t *)); +extern int ipf_scanlist __P((fr_info_t *, u_32_t)); +extern frentry_t *ipf_srcgrpmap __P((fr_info_t *, u_32_t *)); +extern int ipf_tcpudpchk __P((fr_ip_t *, frtuc_t *)); +extern int ipf_verifysrc __P((fr_info_t *fin)); +extern int ipf_zerostats __P((ipf_main_softc_t *, char *)); +extern int ipf_getnextrule __P((ipf_main_softc_t *, ipftoken_t *, + void *)); +extern int ipf_sync __P((ipf_main_softc_t *, void *)); +extern int ipf_token_deref __P((ipf_main_softc_t *, ipftoken_t *)); +extern void ipf_token_expire __P((ipf_main_softc_t *)); +extern ipftoken_t *ipf_token_find __P((ipf_main_softc_t *, int, int, + void *)); +extern int ipf_token_del __P((ipf_main_softc_t *, int, int, + void *)); +extern void ipf_token_mark_complete __P((ipftoken_t *)); +extern int ipf_genericiter __P((ipf_main_softc_t *, void *, + int, void *)); +#ifdef IPFILTER_LOOKUP +extern void *ipf_resolvelookup __P((int, u_int, u_int, + lookupfunc_t *)); +#endif extern u_32_t ipf_random __P((void)); -#endif -#ifdef NEED_LOCAL_RAND -extern void ipf_rand_push __P((void *, int)); -#endif -extern int fr_running; -extern u_long fr_frouteok[2]; -extern int fr_pass; -extern int fr_flags; -extern int fr_active; -extern int fr_chksrc; -extern int fr_minttl; -extern int fr_refcnt; -extern int fr_control_forwarding; -extern int fr_update_ipid; -extern int nat_logging; -extern int ipstate_logging; -extern int ipl_suppress; -extern int ipl_logmax; -extern int ipl_logall; -extern int ipl_logsize; -extern u_long fr_ticks; -extern fr_info_t frcache[2][8]; +extern int ipf_main_load __P((void)); +extern void *ipf_main_soft_create __P((void *)); +extern void ipf_main_soft_destroy __P((ipf_main_softc_t *)); +extern int ipf_main_soft_init __P((ipf_main_softc_t *)); +extern int ipf_main_soft_fini __P((ipf_main_softc_t *)); +extern int ipf_main_unload __P((void)); +extern int ipf_load_all __P((void)); +extern int ipf_unload_all __P((void)); +extern void ipf_destroy_all __P((ipf_main_softc_t *)); +extern ipf_main_softc_t *ipf_create_all __P((void *)); +extern int ipf_init_all __P((ipf_main_softc_t *)); +extern int ipf_fini_all __P((ipf_main_softc_t *)); +extern void ipf_log_soft_destroy __P((ipf_main_softc_t *, void *)); +extern void *ipf_log_soft_create __P((ipf_main_softc_t *)); +extern int ipf_log_soft_init __P((ipf_main_softc_t *, void *)); +extern int ipf_log_soft_fini __P((ipf_main_softc_t *, void *)); +extern int ipf_log_main_load __P((void)); +extern int ipf_log_main_unload __P((void)); + + extern char ipfilter_version[]; -extern iplog_t **iplh[IPL_LOGMAX+1], *iplt[IPL_LOGMAX+1]; -extern int iplused[IPL_LOGMAX + 1]; -extern struct frentry *ipfilter[2][2], *ipacct[2][2]; #ifdef USE_INET6 -extern struct frentry *ipfilter6[2][2], *ipacct6[2][2]; extern int icmptoicmp6types[ICMP_MAXTYPE+1]; extern int icmptoicmp6unreach[ICMP_MAX_UNREACH]; extern int icmpreplytype6[ICMP6_MAXTYPE + 1]; #endif +#ifdef IPFILTER_COMPAT +extern int ipf_in_compat __P((ipf_main_softc_t *, ipfobj_t *, void *,int)); +extern int ipf_out_compat __P((ipf_main_softc_t *, ipfobj_t *, void *)); +#endif extern int icmpreplytype4[ICMP_MAXTYPE + 1]; -extern struct frgroup *ipfgroups[IPL_LOGSIZE][2]; -extern struct filterstats frstats[]; -extern frentry_t *ipfrule_match __P((fr_info_t *)); -extern u_char ipf_iss_secret[32]; -extern ipftuneable_t ipf_tuneables[]; + +extern int ipf_ht_node_add __P((ipf_main_softc_t *, host_track_t *, + int, i6addr_t *)); +extern int ipf_ht_node_del __P((host_track_t *, int, i6addr_t *)); +extern void ipf_rb_ht_flush __P((host_track_t *)); +extern void ipf_rb_ht_freenode __P((host_node_t *, void *)); +extern void ipf_rb_ht_init __P((host_track_t *)); #endif /* __IP_FIL_H__ */ diff --git a/sys/contrib/ipfilter/netinet/ip_fil_freebsd.c b/sys/contrib/ipfilter/netinet/ip_fil_freebsd.c index 338b69a50c65..9d2619309fc5 100644 --- a/sys/contrib/ipfilter/netinet/ip_fil_freebsd.c +++ b/sys/contrib/ipfilter/netinet/ip_fil_freebsd.c @@ -1,13 +1,13 @@ /* $FreeBSD$ */ /* - * Copyright (C) 1993-2003 by Darren Reed. + * Copyright (C) 2012 by Darren Reed. * * See the IPFILTER.LICENCE file for details on licencing. */ #if !defined(lint) static const char sccsid[] = "@(#)ip_fil.c 2.41 6/5/96 (C) 1993-2000 Darren Reed"; -static const char rcsid[] = "@(#)$Id: ip_fil_freebsd.c,v 2.53.2.50 2007/09/20 12:51:50 darrenr Exp $"; +static const char rcsid[] = "@(#)$Id$"; #endif #if defined(KERNEL) || defined(_KERNEL) @@ -25,60 +25,26 @@ static const char rcsid[] = "@(#)$Id: ip_fil_freebsd.c,v 2.53.2.50 2007/09/20 12 # include "opt_random_ip_id.h" #endif #include -#if defined(__FreeBSD__) && !defined(__FreeBSD_version) -# if defined(IPFILTER_LKM) -# ifndef __FreeBSD_cc_version -# include -# else -# if __FreeBSD_cc_version < 430000 -# include -# endif -# endif -# endif -#endif #include #include #include -#if __FreeBSD_version >= 220000 # include # include -#else -# include -#endif #include #include -#if (__FreeBSD_version >= 300000) # include -#else -# include -#endif +# include +# include #if !defined(__hpux) # include #endif -#include #include -#if __FreeBSD_version >= 500043 # include -#else -# include -#endif -#if __FreeBSD_version >= 800044 # include -#else -#define V_path_mtu_discovery path_mtu_discovery -#define V_ipforwarding ipforwarding -#endif #include -#if __FreeBSD_version >= 300000 # include -# if __FreeBSD_version >= 500043 # include -# endif -# if !defined(IPFILTER_LKM) -# include "opt_ipfilter.h" -# endif -#endif #include #include #include @@ -92,9 +58,6 @@ static const char rcsid[] = "@(#)$Id: ip_fil_freebsd.c,v 2.53.2.50 2007/09/20 12 #include #include #include -#ifndef _KERNEL -# include "netinet/ipf.h" -#endif #include "netinet/ip_compat.h" #ifdef USE_INET6 # include @@ -105,101 +68,94 @@ static const char rcsid[] = "@(#)$Id: ip_fil_freebsd.c,v 2.53.2.50 2007/09/20 12 #include "netinet/ip_state.h" #include "netinet/ip_proxy.h" #include "netinet/ip_auth.h" -#ifdef IPFILTER_SYNC #include "netinet/ip_sync.h" -#endif +#include "netinet/ip_lookup.h" +#include "netinet/ip_dstlist.h" #ifdef IPFILTER_SCAN #include "netinet/ip_scan.h" #endif #include "netinet/ip_pool.h" -#if defined(__FreeBSD_version) && (__FreeBSD_version >= 300000) # include -#endif #include #ifdef CSUM_DATA_VALID #include #endif extern int ip_optcopy __P((struct ip *, struct ip *)); -#if (__FreeBSD_version > 460000) && (__FreeBSD_version < 800055) -extern int path_mtu_discovery; -#endif # ifdef IPFILTER_M_IPFILTER MALLOC_DEFINE(M_IPFILTER, "ipfilter", "IP Filter packet filter data structures"); # endif -#if !defined(__osf__) -extern struct protosw inetsw[]; -#endif - -static int (*fr_savep) __P((ip_t *, int, void *, int, struct mbuf **)); -static int fr_send_ip __P((fr_info_t *, mb_t *, mb_t **)); -# ifdef USE_MUTEXES -ipfmutex_t ipl_mutex, ipf_authmx, ipf_rw, ipf_stinsert; -ipfmutex_t ipf_nat_new, ipf_natio, ipf_timeoutlock; -ipfrwlock_t ipf_mutex, ipf_global, ipf_ipidfrag, ipf_frcache, ipf_tokens; -ipfrwlock_t ipf_frag, ipf_state, ipf_nat, ipf_natfrag, ipf_auth; -# endif +static u_short ipid = 0; +static int (*ipf_savep) __P((void *, ip_t *, int, void *, int, struct mbuf **)); +static int ipf_send_ip __P((fr_info_t *, mb_t *)); +static void ipf_timer_func __P((void *arg)); int ipf_locks_done = 0; -#if (__FreeBSD_version >= 300000) -struct callout_handle fr_slowtimer_ch; -#endif -struct selinfo ipfselwait[IPL_LOGSIZE]; +ipf_main_softc_t ipfmain; -#if (__FreeBSD_version >= 500011) # include # if defined(NETBSD_PF) # include -# if (__FreeBSD_version < 501108) -# include -# endif -/* - * We provide the fr_checkp name just to minimize changes later. - */ -int (*fr_checkp) __P((ip_t *ip, int hlen, void *ifp, int out, mb_t **mp)); # endif /* NETBSD_PF */ -#endif /* __FreeBSD_version >= 500011 */ +/* + * We provide the ipf_checkp name just to minimize changes later. + */ +int (*ipf_checkp) __P((void *, ip_t *ip, int hlen, void *ifp, int out, mb_t **mp)); -#if (__FreeBSD_version >= 502103) static eventhandler_tag ipf_arrivetag, ipf_departtag, ipf_clonetag; static void ipf_ifevent(void *arg); static void ipf_ifevent(arg) -void *arg; + void *arg; { - frsync(NULL); + ipf_sync(arg, NULL); } -#endif -#if (__FreeBSD_version >= 501108) && defined(_KERNEL) static int -fr_check_wrapper(void *arg, struct mbuf **mp, struct ifnet *ifp, int dir) +ipf_check_wrapper(void *arg, struct mbuf **mp, struct ifnet *ifp, int dir) { struct ip *ip = mtod(*mp, struct ip *); - return fr_check(ip, ip->ip_hl << 2, ifp, (dir == PFIL_OUT), mp); + int rv; + + /* + * IPFilter expects evreything in network byte order + */ +#if (__FreeBSD_version < 1000019) + ip->ip_len = htons(ip->ip_len); + ip->ip_off = htons(ip->ip_off); +#endif + rv = ipf_check(&ipfmain, ip, ip->ip_hl << 2, ifp, (dir == PFIL_OUT), + mp); +#if (__FreeBSD_version < 1000019) + if ((rv == 0) && (*mp != NULL)) { + ip = mtod(*mp, struct ip *); + ip->ip_len = ntohs(ip->ip_len); + ip->ip_off = ntohs(ip->ip_off); + } +#endif + return rv; } # ifdef USE_INET6 # include static int -fr_check_wrapper6(void *arg, struct mbuf **mp, struct ifnet *ifp, int dir) +ipf_check_wrapper6(void *arg, struct mbuf **mp, struct ifnet *ifp, int dir) { - return (fr_check(mtod(*mp, struct ip *), sizeof(struct ip6_hdr), - ifp, (dir == PFIL_OUT), mp)); + return (ipf_check(&ipfmain, mtod(*mp, struct ip *), + sizeof(struct ip6_hdr), ifp, (dir == PFIL_OUT), mp)); } # endif -#endif /* __FreeBSD_version >= 501108 */ #if defined(IPFILTER_LKM) -int iplidentify(s) -char *s; +int ipf_identify(s) + char *s; { if (strcmp(s, "ipl") == 0) return 1; @@ -208,49 +164,67 @@ char *s; #endif /* IPFILTER_LKM */ -int ipfattach() +static void +ipf_timer_func(arg) + void *arg; +{ + ipf_main_softc_t *softc = arg; + SPL_INT(s); + + SPL_NET(s); + READ_ENTER(&softc->ipf_global); + + if (softc->ipf_running > 0) + ipf_slowtimer(softc); + + if (softc->ipf_running == -1 || softc->ipf_running == 1) { +#if FREEBSD_GE_REV(300000) + softc->ipf_slow_ch = timeout(ipf_timer_func, softc, hz/2); +#else + timeout(ipf_timer_func, softc, hz/2); +#endif + } + RWLOCK_EXIT(&softc->ipf_global); + SPL_X(s); +} + + +int +ipfattach(softc) + ipf_main_softc_t *softc; { #ifdef USE_SPL int s; #endif SPL_NET(s); - if (fr_running > 0) { + if (softc->ipf_running > 0) { SPL_X(s); return EBUSY; } - MUTEX_INIT(&ipf_rw, "ipf rw mutex"); - MUTEX_INIT(&ipf_timeoutlock, "ipf timeout queue mutex"); - RWLOCK_INIT(&ipf_ipidfrag, "ipf IP NAT-Frag rwlock"); - RWLOCK_INIT(&ipf_tokens, "ipf token rwlock"); - ipf_locks_done = 1; - - if (fr_initialise() < 0) { + if (ipf_init_all(softc) < 0) { SPL_X(s); return EIO; } - if (fr_checkp != fr_check) { - fr_savep = fr_checkp; - fr_checkp = fr_check; + if (ipf_checkp != ipf_check) { + ipf_savep = ipf_checkp; + ipf_checkp = ipf_check; } - bzero((char *)ipfselwait, sizeof(ipfselwait)); - bzero((char *)frcache, sizeof(frcache)); - fr_running = 1; + bzero((char *)ipfmain.ipf_selwait, sizeof(ipfmain.ipf_selwait)); + softc->ipf_running = 1; - if (fr_control_forwarding & 1) + if (softc->ipf_control_forwarding & 1) V_ipforwarding = 1; + ipid = 0; + SPL_X(s); -#if (__FreeBSD_version >= 300000) - fr_slowtimer_ch = timeout(fr_slowtimer, NULL, - (hz / IPF_HZ_DIVIDE) * IPF_HZ_MULT); -#else - timeout(fr_slowtimer, NULL, (hz / IPF_HZ_DIVIDE) * IPF_HZ_MULT); -#endif + softc->ipf_slow_ch = timeout(ipf_timer_func, softc, + (hz / IPF_HZ_DIVIDE) * IPF_HZ_MULT); return 0; } @@ -259,44 +233,32 @@ int ipfattach() * Disable the filter by removing the hooks from the IP input/output * stream. */ -int ipfdetach() +int +ipfdetach(softc) + ipf_main_softc_t *softc; { #ifdef USE_SPL int s; #endif - if (fr_control_forwarding & 2) + + if (softc->ipf_control_forwarding & 2) V_ipforwarding = 0; SPL_NET(s); -#if (__FreeBSD_version >= 300000) - if (fr_slowtimer_ch.callout != NULL) - untimeout(fr_slowtimer, NULL, fr_slowtimer_ch); - bzero(&fr_slowtimer_ch, sizeof(fr_slowtimer_ch)); -#else - untimeout(fr_slowtimer, NULL); -#endif /* FreeBSD */ + if (softc->ipf_slow_ch.callout != NULL) + untimeout(ipf_timer_func, softc, softc->ipf_slow_ch); + bzero(&softc->ipf_slow, sizeof(softc->ipf_slow)); #ifndef NETBSD_PF - if (fr_checkp != NULL) - fr_checkp = fr_savep; - fr_savep = NULL; + if (ipf_checkp != NULL) + ipf_checkp = ipf_savep; + ipf_savep = NULL; #endif - fr_deinitialise(); + ipf_fini_all(softc); - fr_running = -2; - - (void) frflush(IPL_LOGIPF, 0, FR_INQUE|FR_OUTQUE|FR_INACTIVE); - (void) frflush(IPL_LOGIPF, 0, FR_INQUE|FR_OUTQUE); - - if (ipf_locks_done == 1) { - MUTEX_DESTROY(&ipf_timeoutlock); - MUTEX_DESTROY(&ipf_rw); - RW_DESTROY(&ipf_ipidfrag); - RW_DESTROY(&ipf_tokens); - ipf_locks_done = 0; - } + softc->ipf_running = -2; SPL_X(s); @@ -307,62 +269,51 @@ int ipfdetach() /* * Filter ioctl interface. */ -int iplioctl(dev, cmd, data, mode -# if defined(_KERNEL) && ((BSD >= 199506) || (__FreeBSD_version >= 220000)) +int +ipfioctl(dev, cmd, data, mode , p) -# if (__FreeBSD_version >= 500024) -struct thread *p; -# if (__FreeBSD_version >= 500043) + struct thread *p; # define p_cred td_ucred # define p_uid td_ucred->cr_ruid -# else -# define p_cred t_proc->p_cred -# define p_uid t_proc->p_cred->p_ruid -# endif -# else -struct proc *p; -# define p_uid p_cred->p_ruid -# endif /* __FreeBSD_version >= 500024 */ -# else -) -# endif -#if defined(_KERNEL) && (__FreeBSD_version >= 502116) -struct cdev *dev; -#else -dev_t dev; -#endif -ioctlcmd_t cmd; -caddr_t data; -int mode; + struct cdev *dev; + ioctlcmd_t cmd; + caddr_t data; + int mode; { int error = 0, unit = 0; SPL_INT(s); -#if (BSD >= 199306) && defined(_KERNEL) -# if (__FreeBSD_version >= 500034) - if (securelevel_ge(p->p_cred, 3) && (mode & FWRITE)) -# else - if ((securelevel >= 3) && (mode & FWRITE)) -# endif +#if (BSD >= 199306) + if (securelevel_ge(p->p_cred, 3) && (mode & FWRITE)) + { + ipfmain.ipf_interror = 130001; return EPERM; + } #endif unit = GET_MINOR(dev); - if ((IPL_LOGMAX < unit) || (unit < 0)) + if ((IPL_LOGMAX < unit) || (unit < 0)) { + ipfmain.ipf_interror = 130002; return ENXIO; + } - if (fr_running <= 0) { - if (unit != IPL_LOGIPF) + if (ipfmain.ipf_running <= 0) { + if (unit != IPL_LOGIPF && cmd != SIOCIPFINTERROR) { + ipfmain.ipf_interror = 130003; return EIO; + } if (cmd != SIOCIPFGETNEXT && cmd != SIOCIPFGET && cmd != SIOCIPFSET && cmd != SIOCFRENB && - cmd != SIOCGETFS && cmd != SIOCGETFF) + cmd != SIOCGETFS && cmd != SIOCGETFF && + cmd != SIOCIPFINTERROR) { + ipfmain.ipf_interror = 130004; return EIO; + } } SPL_NET(s); - error = fr_ioctlswitch(unit, data, cmd, mode, p->p_uid, p); + error = ipf_ioctlswitch(&ipfmain, unit, data, cmd, mode, p->p_uid, p); if (error != -1) { SPL_X(s); return error; @@ -374,182 +325,13 @@ int mode; } -#if 0 -void fr_forgetifp(ifp) -void *ifp; -{ - register frentry_t *f; - - WRITE_ENTER(&ipf_mutex); - for (f = ipacct[0][fr_active]; (f != NULL); f = f->fr_next) - if (f->fr_ifa == ifp) - f->fr_ifa = (void *)-1; - for (f = ipacct[1][fr_active]; (f != NULL); f = f->fr_next) - if (f->fr_ifa == ifp) - f->fr_ifa = (void *)-1; - for (f = ipfilter[0][fr_active]; (f != NULL); f = f->fr_next) - if (f->fr_ifa == ifp) - f->fr_ifa = (void *)-1; - for (f = ipfilter[1][fr_active]; (f != NULL); f = f->fr_next) - if (f->fr_ifa == ifp) - f->fr_ifa = (void *)-1; -#ifdef USE_INET6 - for (f = ipacct6[0][fr_active]; (f != NULL); f = f->fr_next) - if (f->fr_ifa == ifp) - f->fr_ifa = (void *)-1; - for (f = ipacct6[1][fr_active]; (f != NULL); f = f->fr_next) - if (f->fr_ifa == ifp) - f->fr_ifa = (void *)-1; - for (f = ipfilter6[0][fr_active]; (f != NULL); f = f->fr_next) - if (f->fr_ifa == ifp) - f->fr_ifa = (void *)-1; - for (f = ipfilter6[1][fr_active]; (f != NULL); f = f->fr_next) - if (f->fr_ifa == ifp) - f->fr_ifa = (void *)-1; -#endif - RWLOCK_EXIT(&ipf_mutex); - fr_natsync(ifp); -} -#endif - - /* - * routines below for saving IP headers to buffer - */ -int iplopen(dev, flags -#if ((BSD >= 199506) || (__FreeBSD_version >= 220000)) && defined(_KERNEL) -, devtype, p) -int devtype; -# if (__FreeBSD_version >= 500024) -struct thread *p; -# else -struct proc *p; -# endif /* __FreeBSD_version >= 500024 */ -#else -) -#endif -#if defined(_KERNEL) && (__FreeBSD_version >= 502116) -struct cdev *dev; -#else -dev_t dev; -#endif -int flags; -{ - u_int min = GET_MINOR(dev); - - if (IPL_LOGMAX < min) - min = ENXIO; - else - min = 0; - return min; -} - - -int iplclose(dev, flags -#if ((BSD >= 199506) || (__FreeBSD_version >= 220000)) && defined(_KERNEL) -, devtype, p) -int devtype; -# if (__FreeBSD_version >= 500024) -struct thread *p; -# else -struct proc *p; -# endif /* __FreeBSD_version >= 500024 */ -#else -) -#endif -#if defined(_KERNEL) && (__FreeBSD_version >= 502116) -struct cdev *dev; -#else -dev_t dev; -#endif -int flags; -{ - u_int min = GET_MINOR(dev); - - if (IPL_LOGMAX < min) - min = ENXIO; - else - min = 0; - return min; -} - -/* - * iplread/ipllog - * both of these must operate with at least splnet() lest they be - * called during packet processing and cause an inconsistancy to appear in - * the filter lists. - */ -#if (BSD >= 199306) -int iplread(dev, uio, ioflag) -int ioflag; -#else -int iplread(dev, uio) -#endif -#if defined(_KERNEL) && (__FreeBSD_version >= 502116) -struct cdev *dev; -#else -dev_t dev; -#endif -register struct uio *uio; -{ - u_int xmin = GET_MINOR(dev); - - if (fr_running < 1) - return EIO; - - if (xmin < 0) - return ENXIO; - -# ifdef IPFILTER_SYNC - if (xmin == IPL_LOGSYNC) - return ipfsync_read(uio); -# endif - -#ifdef IPFILTER_LOG - return ipflog_read(xmin, uio); -#else - return ENXIO; -#endif -} - - -/* - * iplwrite - * both of these must operate with at least splnet() lest they be - * called during packet processing and cause an inconsistancy to appear in - * the filter lists. - */ -#if (BSD >= 199306) -int iplwrite(dev, uio, ioflag) -int ioflag; -#else -int iplwrite(dev, uio) -#endif -#if defined(_KERNEL) && (__FreeBSD_version >= 502116) -struct cdev *dev; -#else -dev_t dev; -#endif -register struct uio *uio; -{ - - if (fr_running < 1) - return EIO; - -#ifdef IPFILTER_SYNC - if (GET_MINOR(dev) == IPL_LOGSYNC) - return ipfsync_write(uio); -#endif - return ENXIO; -} - - -/* - * fr_send_reset - this could conceivably be a call to tcp_respond(), but that + * ipf_send_reset - this could conceivably be a call to tcp_respond(), but that * requires a large amount of setting up and isn't any more efficient. */ -int fr_send_reset(fin) -fr_info_t *fin; +int +ipf_send_reset(fin) + fr_info_t *fin; { struct tcphdr *tcp, *tcp2; int tlen = 0, hlen; @@ -563,7 +345,7 @@ fr_info_t *fin; if (tcp->th_flags & TH_RST) return -1; /* feedback loop */ - if (fr_checkl4sum(fin) == -1) + if (ipf_checkl4sum(fin) == -1) return -1; tlen = fin->fin_dlen - (TCP_OFF(tcp) << 2) + @@ -628,11 +410,11 @@ fr_info_t *fin; ip6->ip6_plen = htons(sizeof(struct tcphdr)); ip6->ip6_nxt = IPPROTO_TCP; ip6->ip6_hlim = 0; - ip6->ip6_src = fin->fin_dst6; - ip6->ip6_dst = fin->fin_src6; + ip6->ip6_src = fin->fin_dst6.in6; + ip6->ip6_dst = fin->fin_src6.in6; tcp2->th_sum = in6_cksum(m, IPPROTO_TCP, sizeof(*ip6), sizeof(*tcp2)); - return fr_send_ip(fin, m, &m); + return ipf_send_ip(fin, m); } #endif ip->ip_p = IPPROTO_TCP; @@ -640,14 +422,18 @@ fr_info_t *fin; ip->ip_src.s_addr = fin->fin_daddr; ip->ip_dst.s_addr = fin->fin_saddr; tcp2->th_sum = in_cksum(m, hlen + sizeof(*tcp2)); - ip->ip_len = hlen + sizeof(*tcp2); - return fr_send_ip(fin, m, &m); + ip->ip_len = htons(hlen + sizeof(*tcp2)); + return ipf_send_ip(fin, m); } -static int fr_send_ip(fin, m, mpp) -fr_info_t *fin; -mb_t *m, **mpp; +/* + * ip_len must be in network byte order when called. + */ +static int +ipf_send_ip(fin, m) + fr_info_t *fin; + mb_t *m; { fr_info_t fnew; ip_t *ip, *oip; @@ -655,24 +441,27 @@ mb_t *m, **mpp; ip = mtod(m, ip_t *); bzero((char *)&fnew, sizeof(fnew)); + fnew.fin_main_soft = fin->fin_main_soft; IP_V_A(ip, fin->fin_v); switch (fin->fin_v) { case 4 : - fnew.fin_v = 4; oip = fin->fin_ip; + hlen = sizeof(*oip); + fnew.fin_v = 4; + fnew.fin_p = ip->ip_p; + fnew.fin_plen = ntohs(ip->ip_len); IP_HL_A(ip, sizeof(*oip) >> 2); ip->ip_tos = oip->ip_tos; ip->ip_id = fin->fin_ip->ip_id; -#if (__FreeBSD_version > 460000) - ip->ip_off = V_path_mtu_discovery ? IP_DF : 0; +#if defined(FreeBSD) && (__FreeBSD_version > 460000) + ip->ip_off = htons(path_mtu_discovery ? IP_DF : 0); #else ip->ip_off = 0; #endif ip->ip_ttl = V_ip_defttl; ip->ip_sum = 0; - hlen = sizeof(*oip); break; #ifdef USE_INET6 case 6 : @@ -682,8 +471,10 @@ mb_t *m, **mpp; ip6->ip6_vfc = 0x60; ip6->ip6_hlim = IPDEFTTL; - fnew.fin_v = 6; hlen = sizeof(*ip6); + fnew.fin_p = ip6->ip6_nxt; + fnew.fin_v = 6; + fnew.fin_plen = ntohs(ip6->ip6_plen) + hlen; break; } #endif @@ -698,28 +489,29 @@ mb_t *m, **mpp; fnew.fin_flx = FI_NOCKSUM; fnew.fin_m = m; fnew.fin_ip = ip; - fnew.fin_mp = mpp; + fnew.fin_mp = &m; fnew.fin_hlen = hlen; fnew.fin_dp = (char *)ip + hlen; - (void) fr_makefrip(hlen, ip, &fnew); + (void) ipf_makefrip(hlen, ip, &fnew); - return fr_fastroute(m, mpp, &fnew, NULL); + return ipf_fastroute(m, &m, &fnew, NULL); } -int fr_send_icmp_err(type, fin, dst) -int type; -fr_info_t *fin; -int dst; +int +ipf_send_icmp_err(type, fin, dst) + int type; + fr_info_t *fin; + int dst; { int err, hlen, xtra, iclen, ohlen, avail, code; struct in_addr dst4; struct icmp *icmp; struct mbuf *m; + i6addr_t dst6; void *ifp; #ifdef USE_INET6 ip6_t *ip6; - struct in6_addr dst6; #endif ip_t *ip, *ip2; @@ -728,11 +520,17 @@ int dst; code = fin->fin_icode; #ifdef USE_INET6 - if ((code < 0) || (code > sizeof(icmptoicmp6unreach)/sizeof(int))) +#if 0 + /* XXX Fix an off by one error: s/>/>=/ + was: + if ((code < 0) || (code > sizeof(icmptoicmp6unreach)/sizeof(int))) + Fix obtained from NetBSD ip_fil_netbsd.c r1.4: */ +#endif + if ((code < 0) || (code >= sizeof(icmptoicmp6unreach)/sizeof(int))) return -1; #endif - if (fr_checkl4sum(fin) == -1) + if (ipf_checkl4sum(fin) == -1) return -1; #ifdef MGETHDR MGETHDR(m, M_DONTWAIT, MT_HEADER); @@ -746,10 +544,10 @@ int dst; xtra = 0; hlen = 0; ohlen = 0; + dst4.s_addr = 0; ifp = fin->fin_ifp; if (fin->fin_v == 4) { - if ((fin->fin_p == IPPROTO_ICMP) && - !(fin->fin_flx & FI_SHORT)) + if ((fin->fin_p == IPPROTO_ICMP) && !(fin->fin_flx & FI_SHORT)) switch (ntohs(fin->fin_data[0]) >> 8) { case ICMP_ECHO : @@ -763,16 +561,18 @@ int dst; } if (dst == 0) { - if (fr_ifpaddr(4, FRI_NORMAL, ifp, - &dst4, NULL) == -1) { + if (ipf_ifpaddr(&ipfmain, 4, FRI_NORMAL, ifp, + &dst6, NULL) == -1) { FREE_MB_T(m); return -1; } + dst4 = dst6.in4; } else dst4.s_addr = fin->fin_daddr; hlen = sizeof(ip_t); ohlen = fin->fin_hlen; + iclen = hlen + offsetof(struct icmp, icmp_ip) + ohlen; if (fin->fin_hlen < fin->fin_plen) xtra = MIN(fin->fin_dlen, 8); else @@ -783,12 +583,12 @@ int dst; else if (fin->fin_v == 6) { hlen = sizeof(ip6_t); ohlen = sizeof(ip6_t); + iclen = hlen + offsetof(struct icmp, icmp_ip) + ohlen; type = icmptoicmp6types[type]; if (type == ICMP6_DST_UNREACH) code = icmptoicmp6unreach[code]; - if (hlen + sizeof(*icmp) + max_linkhdr + - fin->fin_plen > avail) { + if (iclen + max_linkhdr + fin->fin_plen > avail) { MCLGET(m, M_DONTWAIT); if ((m->m_flags & M_EXT) == 0) { FREE_MB_T(m); @@ -796,11 +596,11 @@ int dst; } avail = MCLBYTES; } - xtra = MIN(fin->fin_plen, - avail - hlen - sizeof(*icmp) - max_linkhdr); + xtra = MIN(fin->fin_plen, avail - iclen - max_linkhdr); + xtra = MIN(xtra, IPV6_MMTU - iclen); if (dst == 0) { - if (fr_ifpaddr(6, FRI_NORMAL, ifp, - (struct in_addr *)&dst6, NULL) == -1) { + if (ipf_ifpaddr(&ipfmain, 6, FRI_NORMAL, ifp, + &dst6, NULL) == -1) { FREE_MB_T(m); return -1; } @@ -813,7 +613,6 @@ int dst; return -1; } - iclen = hlen + sizeof(*icmp); avail -= (max_linkhdr + iclen); if (avail < 0) { FREE_MB_T(m); @@ -834,9 +633,17 @@ int dst; icmp->icmp_code = fin->fin_icode; icmp->icmp_cksum = 0; #ifdef icmp_nextmtu - if (type == ICMP_UNREACH && - fin->fin_icode == ICMP_UNREACH_NEEDFRAG && ifp) - icmp->icmp_nextmtu = htons(((struct ifnet *)ifp)->if_mtu); + if (type == ICMP_UNREACH && fin->fin_icode == ICMP_UNREACH_NEEDFRAG) { + if (fin->fin_mtu != 0) { + icmp->icmp_nextmtu = htons(fin->fin_mtu); + + } else if (ifp != NULL) { + icmp->icmp_nextmtu = htons(GETIFMTU_4(ifp)); + + } else { /* make up a number... */ + icmp->icmp_nextmtu = htons(fin->fin_plen - 20); + } + } #endif bcopy((char *)fin->fin_ip, (char *)ip2, ohlen); @@ -848,8 +655,8 @@ int dst; ip6->ip6_plen = htons(iclen - hlen); ip6->ip6_nxt = IPPROTO_ICMPV6; ip6->ip6_hlim = 0; - ip6->ip6_src = dst6; - ip6->ip6_dst = fin->fin_src6; + ip6->ip6_src = dst6.in6; + ip6->ip6_dst = fin->fin_src6.in6; if (xtra > 0) bcopy((char *)fin->fin_ip + ohlen, (char *)&icmp->icmp_ip + ohlen, xtra); @@ -858,8 +665,6 @@ int dst; } else #endif { - ip2->ip_len = htons(ip2->ip_len); - ip2->ip_off = htons(ip2->ip_off); ip->ip_p = IPPROTO_ICMP; ip->ip_src.s_addr = dst4.s_addr; ip->ip_dst.s_addr = fin->fin_saddr; @@ -869,41 +674,25 @@ int dst; (char *)&icmp->icmp_ip + ohlen, xtra); icmp->icmp_cksum = ipf_cksum((u_short *)icmp, sizeof(*icmp) + 8); - ip->ip_len = iclen; + ip->ip_len = htons(iclen); ip->ip_p = IPPROTO_ICMP; } - err = fr_send_ip(fin, m, &m); + err = ipf_send_ip(fin, m); return err; } -#if !defined(IPFILTER_LKM) && (__FreeBSD_version < 300000) -# if (BSD < 199306) -int iplinit __P((void)); - -int -# else -void iplinit __P((void)); - -void -# endif -iplinit() -{ - if (ipfattach() != 0) - printf("IP Filter failed to attach\n"); - ip_init(); -} -#endif /* __FreeBSD_version < 300000 */ /* * m0 - pointer to mbuf where the IP packet starts * mpp - pointer to the mbuf pointer that is the start of the mbuf chain */ -int fr_fastroute(m0, mpp, fin, fdp) -mb_t *m0, **mpp; -fr_info_t *fin; -frdest_t *fdp; +int +ipf_fastroute(m0, mpp, fin, fdp) + mb_t *m0, **mpp; + fr_info_t *fin; + frdest_t *fdp; { register struct ip *ip, *mhip; register struct mbuf *m = *mpp; @@ -913,6 +702,7 @@ frdest_t *fdp; struct sockaddr_in *dst; struct route iproute; u_short ip_off; + frdest_t node; frentry_t *fr; ro = NULL; @@ -949,33 +739,36 @@ frdest_t *fdp; * currently "to " and "to :ip#" are not supported * for IPv6 */ -#if (__FreeBSD_version >= 490000) - return ip6_output(m0, NULL, NULL, 0, NULL, NULL, NULL); -#else - return ip6_output(m0, NULL, NULL, 0, NULL, NULL); -#endif + return ip6_output(m, NULL, NULL, 0, NULL, NULL, NULL); } #endif hlen = fin->fin_hlen; ip = mtod(m0, struct ip *); + ifp = NULL; /* * Route packet. */ ro = &iproute; - bzero((caddr_t)ro, sizeof (*ro)); + bzero(ro, sizeof (*ro)); dst = (struct sockaddr_in *)&ro->ro_dst; dst->sin_family = AF_INET; dst->sin_addr = ip->ip_dst; fr = fin->fin_fr; + if ((fr != NULL) && !(fr->fr_flags & FR_KEEPSTATE) && (fdp != NULL) && + (fdp->fd_type == FRD_DSTLIST)) { + if (ipf_dstlist_select_node(fin, fdp->fd_ptr, NULL, &node) == 0) + fdp = &node; + } + if (fdp != NULL) - ifp = fdp->fd_ifp; + ifp = fdp->fd_ptr; else ifp = fin->fin_ifp; - if ((ifp == NULL) && (!fr || !(fr->fr_flags & FR_FASTROUTE))) { + if ((ifp == NULL) && ((fr == NULL) || !(fr->fr_flags & FR_FASTROUTE))) { error = -2; goto bad; } @@ -1012,21 +805,19 @@ frdest_t *fdp; sifp = fin->fin_ifp; fin->fin_ifp = ifp; fin->fin_out = 1; - (void) fr_acctpkt(fin, NULL); + (void) ipf_acctpkt(fin, NULL); fin->fin_fr = NULL; if (!fr || !(fr->fr_flags & FR_RETMASK)) { u_32_t pass; - if (fr_checkstate(fin, &pass) != NULL) - fr_statederef((ipstate_t **)&fin->fin_state); + (void) ipf_state_check(fin, &pass); } - switch (fr_checknatout(fin, NULL)) + switch (ipf_nat_checkout(fin, NULL)) { case 0 : break; case 1 : - fr_natderef((nat_t **)&fin->fin_nat); ip->ip_sum = 0; break; case -1 : @@ -1042,14 +833,12 @@ frdest_t *fdp; /* * If small enough for interface, can just send directly. */ - if (ip->ip_len <= ifp->if_mtu) { - ip->ip_len = htons(ip->ip_len); - ip->ip_off = htons(ip->ip_off); - + if (ntohs(ip->ip_len) <= ifp->if_mtu) { if (!ip->ip_sum) ip->ip_sum = in_cksum(m, hlen); error = (*ifp->if_output)(ifp, m, (struct sockaddr *)dst, - ro); + ro + ); goto done; } /* @@ -1077,7 +866,7 @@ frdest_t *fdp; */ m0 = m; mhlen = sizeof (struct ip); - for (off = hlen + len; off < ip->ip_len; off += len) { + for (off = hlen + len; off < ntohs(ip->ip_len); off += len) { #ifdef MGETHDR MGETHDR(m, M_DONTWAIT, MT_HEADER); #else @@ -1097,8 +886,8 @@ frdest_t *fdp; } m->m_len = mhlen; mhip->ip_off = ((off - hlen) >> 3) + ip_off; - if (off + len >= ip->ip_len) - len = ip->ip_len - off; + if (off + len >= ntohs(ip->ip_len)) + len = ntohs(ip->ip_len) - off; else mhip->ip_off |= IP_MF; mhip->ip_len = htons((u_short)(len + mhlen)); @@ -1130,21 +919,22 @@ frdest_t *fdp; m->m_act = 0; if (error == 0) error = (*ifp->if_output)(ifp, m, - (struct sockaddr *)dst, ro); + (struct sockaddr *)dst, + ro + ); else FREE_MB_T(m); } - } + } done: if (!error) - fr_frouteok[0]++; + ipfmain.ipf_frouteok[0]++; else - fr_frouteok[1]++; + ipfmain.ipf_frouteok[1]++; if ((ro != NULL) && (ro->ro_rt != NULL)) { RTFREE(ro->ro_rt); } - *mpp = NULL; return 0; bad: if (error == EMSGSIZE) { @@ -1152,7 +942,7 @@ frdest_t *fdp; code = fin->fin_icode; fin->fin_icode = ICMP_UNREACH_NEEDFRAG; fin->fin_ifp = ifp; - (void) fr_send_icmp_err(ICMP_UNREACH, fin, 1); + (void) ipf_send_icmp_err(ICMP_UNREACH, fin, 1); fin->fin_ifp = sifp; fin->fin_icode = code; } @@ -1161,8 +951,9 @@ frdest_t *fdp; } -int fr_verifysrc(fin) -fr_info_t *fin; +int +ipf_verifysrc(fin) + fr_info_t *fin; { struct sockaddr_in *dst; struct route iproute; @@ -1182,10 +973,12 @@ fr_info_t *fin; /* * return the first IP Address associated with an interface */ -int fr_ifpaddr(v, atype, ifptr, inp, inpmask) -int v, atype; -void *ifptr; -struct in_addr *inp, *inpmask; +int +ipf_ifpaddr(softc, v, atype, ifptr, inp, inpmask) + ipf_main_softc_t *softc; + int v, atype; + void *ifptr; + i6addr_t *inp, *inpmask; { #ifdef USE_INET6 struct in6_addr *inp6 = NULL; @@ -1202,16 +995,12 @@ struct in_addr *inp, *inpmask; ifp = ifptr; if (v == 4) - inp->s_addr = 0; + inp->in4.s_addr = 0; #ifdef USE_INET6 else if (v == 6) - bzero((char *)inp, sizeof(struct in6_addr)); + bzero((char *)inp, sizeof(*inp)); #endif -#if (__FreeBSD_version >= 300000) ifa = TAILQ_FIRST(&ifp->if_addrhead); -#else - ifa = ifp->if_addrlist; -#endif /* __FreeBSD_version >= 300000 */ sock = ifa->ifa_addr; while (sock != NULL && ifa != NULL) { @@ -1226,11 +1015,7 @@ struct in_addr *inp, *inpmask; break; } #endif -#if (__FreeBSD_version >= 300000) ifa = TAILQ_NEXT(ifa, ifa_link); -#else - ifa = ifa->ifa_next; -#endif /* __FreeBSD_version >= 300000 */ if (ifa != NULL) sock = ifa->ifa_addr; } @@ -1249,79 +1034,45 @@ struct in_addr *inp, *inpmask; #ifdef USE_INET6 if (v == 6) { - return fr_ifpfillv6addr(atype, (struct sockaddr_in6 *)sock, - (struct sockaddr_in6 *)mask, - inp, inpmask); + return ipf_ifpfillv6addr(atype, (struct sockaddr_in6 *)sock, + (struct sockaddr_in6 *)mask, + inp, inpmask); } #endif - return fr_ifpfillv4addr(atype, (struct sockaddr_in *)sock, - (struct sockaddr_in *)mask, inp, inpmask); + return ipf_ifpfillv4addr(atype, (struct sockaddr_in *)sock, + (struct sockaddr_in *)mask, + &inp->in4, &inpmask->in4); } -u_32_t fr_newisn(fin) -fr_info_t *fin; +u_32_t +ipf_newisn(fin) + fr_info_t *fin; { u_32_t newiss; -#if (__FreeBSD_version >= 400000) newiss = arc4random(); -#else - static iss_seq_off = 0; - u_char hash[16]; - MD5_CTX ctx; - - /* - * Compute the base value of the ISS. It is a hash - * of (saddr, sport, daddr, dport, secret). - */ - MD5Init(&ctx); - - MD5Update(&ctx, (u_char *) &fin->fin_fi.fi_src, - sizeof(fin->fin_fi.fi_src)); - MD5Update(&ctx, (u_char *) &fin->fin_fi.fi_dst, - sizeof(fin->fin_fi.fi_dst)); - MD5Update(&ctx, (u_char *) &fin->fin_dat, sizeof(fin->fin_dat)); - - MD5Update(&ctx, ipf_iss_secret, sizeof(ipf_iss_secret)); - - MD5Final(hash, &ctx); - - memcpy(&newiss, hash, sizeof(newiss)); - - /* - * Now increment our "timer", and add it in to - * the computed value. - * - * XXX Use `addin'? - * XXX TCP_ISSINCR too large to use? - */ - iss_seq_off += 0x00010000; - newiss += iss_seq_off; -#endif return newiss; } /* ------------------------------------------------------------------------ */ -/* Function: fr_nextipid */ +/* Function: ipf_nextipid */ /* Returns: int - 0 == success, -1 == error (packet should be droppped) */ /* Parameters: fin(I) - pointer to packet information */ /* */ /* Returns the next IPv4 ID to use for this packet. */ /* ------------------------------------------------------------------------ */ -u_short fr_nextipid(fin) -fr_info_t *fin; +u_short +ipf_nextipid(fin) + fr_info_t *fin; { + u_short id; + #ifndef RANDOM_IP_ID - static u_short ipid = 0; - u_short id; - - MUTEX_ENTER(&ipf_rw); + MUTEX_ENTER(&ipfmain.ipf_rw); id = ipid++; - MUTEX_EXIT(&ipf_rw); + MUTEX_EXIT(&ipfmain.ipf_rw); #else - u_short id; - id = ip_randomid(); #endif @@ -1329,8 +1080,9 @@ fr_info_t *fin; } -INLINE void fr_checkv4sum(fin) -fr_info_t *fin; +INLINE int +ipf_checkv4sum(fin) + fr_info_t *fin; { #ifdef CSUM_DATA_VALID int manual = 0; @@ -1339,10 +1091,13 @@ fr_info_t *fin; mb_t *m; if ((fin->fin_flx & FI_NOCKSUM) != 0) - return; + return 0; - if (fin->fin_cksum != 0) - return; + if ((fin->fin_flx & FI_SHORT) != 0) + return 1; + + if (fin->fin_cksum != FI_CK_NEEDED) + return (fin->fin_cksum > FI_CK_NEEDED) ? 0 : -1; m = fin->fin_m; if (m == NULL) { @@ -1351,56 +1106,86 @@ fr_info_t *fin; } ip = fin->fin_ip; + if ((m->m_pkthdr.csum_flags & (CSUM_IP_CHECKED|CSUM_IP_VALID)) == + CSUM_IP_CHECKED) { + fin->fin_cksum = FI_CK_BAD; + fin->fin_flx |= FI_BAD; + return -1; + } if (m->m_pkthdr.csum_flags & CSUM_DATA_VALID) { if (m->m_pkthdr.csum_flags & CSUM_PSEUDO_HDR) sum = m->m_pkthdr.csum_data; else sum = in_pseudo(ip->ip_src.s_addr, ip->ip_dst.s_addr, htonl(m->m_pkthdr.csum_data + - fin->fin_ip->ip_len - - (fin->fin_ip->ip_hl << 2) + - fin->fin_p)); + fin->fin_dlen + fin->fin_p)); sum ^= 0xffff; if (sum != 0) { + fin->fin_cksum = FI_CK_BAD; fin->fin_flx |= FI_BAD; - fin->fin_cksum = -1; } else { - fin->fin_cksum = 1; + fin->fin_cksum = FI_CK_SUMOK; + return 0; } - } else - manual = 1; + } else { + if (m->m_pkthdr.csum_flags == CSUM_DELAY_DATA) { + fin->fin_cksum = FI_CK_L4FULL; + return 0; + } else if (m->m_pkthdr.csum_flags == CSUM_TCP || + m->m_pkthdr.csum_flags == CSUM_UDP) { + fin->fin_cksum = FI_CK_L4PART; + return 0; + } else if (m->m_pkthdr.csum_flags == CSUM_IP) { + fin->fin_cksum = FI_CK_L4PART; + return 0; + } else { + manual = 1; + } + } skipauto: -# ifdef IPFILTER_CKSUM - if (manual != 0) - if (fr_checkl4sum(fin) == -1) + if (manual != 0) { + if (ipf_checkl4sum(fin) == -1) { fin->fin_flx |= FI_BAD; -# else - ; -# endif + return -1; + } + } #else -# ifdef IPFILTER_CKSUM - if (fr_checkl4sum(fin) == -1) + if (ipf_checkl4sum(fin) == -1) { fin->fin_flx |= FI_BAD; -# endif + return -1; + } #endif + return 0; } #ifdef USE_INET6 -INLINE void fr_checkv6sum(fin) -fr_info_t *fin; +INLINE int +ipf_checkv6sum(fin) + fr_info_t *fin; { -# ifdef IPFILTER_CKSUM - if (fr_checkl4sum(fin) == -1) + if ((fin->fin_flx & FI_NOCKSUM) != 0) + return 0; + + if ((fin->fin_flx & FI_SHORT) != 0) + return 1; + + if (fin->fin_cksum != FI_CK_NEEDED) + return (fin->fin_cksum > FI_CK_NEEDED) ? 0 : -1; + + if (ipf_checkl4sum(fin) == -1) { fin->fin_flx |= FI_BAD; -# endif + return -1; + } + return 0; } #endif /* USE_INET6 */ -size_t mbufchainlen(m0) -struct mbuf *m0; -{ +size_t +mbufchainlen(m0) + struct mbuf *m0; + { size_t len; if ((m0->m_flags & M_PKTHDR) != 0) { @@ -1416,29 +1201,30 @@ struct mbuf *m0; /* ------------------------------------------------------------------------ */ -/* Function: fr_pullup */ +/* Function: ipf_pullup */ /* Returns: NULL == pullup failed, else pointer to protocol header */ -/* Parameters: m(I) - pointer to buffer where data packet starts */ +/* Parameters: xmin(I)- pointer to buffer where data packet starts */ /* fin(I) - pointer to packet information */ /* len(I) - number of bytes to pullup */ /* */ /* Attempt to move at least len bytes (from the start of the buffer) into a */ /* single buffer for ease of access. Operating system native functions are */ /* used to manage buffers - if necessary. If the entire packet ends up in */ -/* a single buffer, set the FI_COALESCE flag even though fr_coalesce() has */ +/* a single buffer, set the FI_COALESCE flag even though ipf_coalesce() has */ /* not been called. Both fin_ip and fin_dp are updated before exiting _IF_ */ /* and ONLY if the pullup succeeds. */ /* */ -/* We assume that 'min' is a pointer to a buffer that is part of the chain */ +/* We assume that 'xmin' is a pointer to a buffer that is part of the chain */ /* of buffers that starts at *fin->fin_mp. */ /* ------------------------------------------------------------------------ */ -void *fr_pullup(min, fin, len) -mb_t *min; -fr_info_t *fin; -int len; +void * +ipf_pullup(xmin, fin, len) + mb_t *xmin; + fr_info_t *fin; + int len; { - int out = fin->fin_out, dpoff, ipoff; - mb_t *m = min; + int dpoff, ipoff; + mb_t *m = xmin; char *ip; if (m == NULL) @@ -1455,12 +1241,25 @@ int len; dpoff = 0; if (M_LEN(m) < len) { -#ifdef MHLEN + mb_t *n = *fin->fin_mp; /* * Assume that M_PKTHDR is set and just work with what is left * rather than check.. * Should not make any real difference, anyway. */ + if (m != n) { + /* + * Record the mbuf that points to the mbuf that we're + * about to go to work on so that we can update the + * m_next appropriately later. + */ + for (; n->m_next != m; n = n->m_next) + ; + } else { + n = NULL; + } + +#ifdef MHLEN if (len > MHLEN) #else if (len > MLEN) @@ -1472,29 +1271,46 @@ int len; #else FREE_MB_T(*fin->fin_mp); m = NULL; + n = NULL; #endif } else { m = m_pullup(m, len); } - *fin->fin_mp = m; + if (n != NULL) + n->m_next = m; if (m == NULL) { + /* + * When n is non-NULL, it indicates that m pointed to + * a sub-chain (tail) of the mbuf and that the head + * of this chain has not yet been free'd. + */ + if (n != NULL) { + FREE_MB_T(*fin->fin_mp); + } + + *fin->fin_mp = NULL; fin->fin_m = NULL; - ATOMIC_INCL(frstats[out].fr_pull[1]); return NULL; } + if (n == NULL) + *fin->fin_mp = m; + while (M_LEN(m) == 0) { m = m->m_next; } fin->fin_m = m; ip = MTOD(m, char *) + ipoff; - } - ATOMIC_INCL(frstats[out].fr_pull[0]); - fin->fin_ip = (ip_t *)ip; - if (fin->fin_dp != NULL) - fin->fin_dp = (char *)fin->fin_ip + dpoff; + fin->fin_ip = (ip_t *)ip; + if (fin->fin_dp != NULL) + fin->fin_dp = (char *)fin->fin_ip + dpoff; + if (fin->fin_fraghdr != NULL) + fin->fin_fraghdr = (char *)ip + + ((char *)fin->fin_fraghdr - + (char *)fin->fin_ip); + } if (len == fin->fin_plen) fin->fin_flx |= FI_COALESCE; @@ -1502,45 +1318,19 @@ int len; } -int ipf_inject(fin, m) -fr_info_t *fin; -mb_t *m; +int +ipf_inject(fin, m) + fr_info_t *fin; + mb_t *m; { int error = 0; if (fin->fin_out == 0) { -#if (__FreeBSD_version >= 501000) netisr_dispatch(NETISR_IP, m); -#else - struct ifqueue *ifq; - - ifq = &ipintrq; - -# ifdef _IF_QFULL - if (_IF_QFULL(ifq)) -# else - if (IF_QFULL(ifq)) -# endif - { -# ifdef _IF_DROP - _IF_DROP(ifq); -# else - IF_DROP(ifq); -# endif - FREE_MB_T(m); - error = ENOBUFS; - } else { - IF_ENQUEUE(ifq, m); - } -#endif } else { fin->fin_ip->ip_len = ntohs(fin->fin_ip->ip_len); fin->fin_ip->ip_off = ntohs(fin->fin_ip->ip_off); -#if (__FreeBSD_version >= 470102) error = ip_output(m, NULL, NULL, IP_FORWARDING, NULL, NULL); -#else - error = ip_output(m, NULL, NULL, IP_FORWARDING, NULL); -#endif } return error; @@ -1548,38 +1338,22 @@ mb_t *m; int ipf_pfil_unhook(void) { #if defined(NETBSD_PF) && (__FreeBSD_version >= 500011) -# if __FreeBSD_version >= 501108 struct pfil_head *ph_inet; # ifdef USE_INET6 struct pfil_head *ph_inet6; # endif -# endif #endif #ifdef NETBSD_PF -# if (__FreeBSD_version >= 500011) -# if (__FreeBSD_version >= 501108) ph_inet = pfil_head_get(PFIL_TYPE_AF, AF_INET); if (ph_inet != NULL) - pfil_remove_hook((void *)fr_check_wrapper, NULL, + pfil_remove_hook((void *)ipf_check_wrapper, NULL, PFIL_IN|PFIL_OUT|PFIL_WAITOK, ph_inet); -# else - pfil_remove_hook((void *)fr_check, PFIL_IN|PFIL_OUT|PFIL_WAITOK, - &inetsw[ip_protox[IPPROTO_IP]].pr_pfh); -# endif -# else - pfil_remove_hook((void *)fr_check, PFIL_IN|PFIL_OUT|PFIL_WAITOK); -# endif # ifdef USE_INET6 -# if (__FreeBSD_version >= 501108) ph_inet6 = pfil_head_get(PFIL_TYPE_AF, AF_INET6); if (ph_inet6 != NULL) - pfil_remove_hook((void *)fr_check_wrapper6, NULL, + pfil_remove_hook((void *)ipf_check_wrapper6, NULL, PFIL_IN|PFIL_OUT|PFIL_WAITOK, ph_inet6); -# else - pfil_remove_hook((void *)fr_check, PFIL_IN|PFIL_OUT|PFIL_WAITOK, - &inet6sw[ip6_protox[IPPROTO_IPV6]].pr_pfh); -# endif # endif #endif @@ -1588,17 +1362,13 @@ int ipf_pfil_unhook(void) { int ipf_pfil_hook(void) { #if defined(NETBSD_PF) && (__FreeBSD_version >= 500011) -# if __FreeBSD_version >= 501108 struct pfil_head *ph_inet; # ifdef USE_INET6 struct pfil_head *ph_inet6; # endif -# endif #endif # ifdef NETBSD_PF -# if __FreeBSD_version >= 500011 -# if __FreeBSD_version >= 501108 ph_inet = pfil_head_get(PFIL_TYPE_AF, AF_INET); # ifdef USE_INET6 ph_inet6 = pfil_head_get(PFIL_TYPE_AF, AF_INET6); @@ -1607,28 +1377,17 @@ int ipf_pfil_hook(void) { # ifdef USE_INET6 && ph_inet6 == NULL # endif - ) + ) { return ENODEV; + } if (ph_inet != NULL) - pfil_add_hook((void *)fr_check_wrapper, NULL, + pfil_add_hook((void *)ipf_check_wrapper, NULL, PFIL_IN|PFIL_OUT|PFIL_WAITOK, ph_inet); -# else - pfil_add_hook((void *)fr_check, PFIL_IN|PFIL_OUT|PFIL_WAITOK, - &inetsw[ip_protox[IPPROTO_IP]].pr_pfh); -# endif -# else - pfil_add_hook((void *)fr_check, PFIL_IN|PFIL_OUT|PFIL_WAITOK); -# endif # ifdef USE_INET6 -# if __FreeBSD_version >= 501108 if (ph_inet6 != NULL) - pfil_add_hook((void *)fr_check_wrapper6, NULL, + pfil_add_hook((void *)ipf_check_wrapper6, NULL, PFIL_IN|PFIL_OUT|PFIL_WAITOK, ph_inet6); -# else - pfil_add_hook((void *)fr_check, PFIL_IN|PFIL_OUT|PFIL_WAITOK, - &inet6sw[ip6_protox[IPPROTO_IPV6]].pr_pfh); -# endif # endif # endif return (0); @@ -1637,22 +1396,19 @@ int ipf_pfil_hook(void) { void ipf_event_reg(void) { -#if (__FreeBSD_version >= 502103) - ipf_arrivetag = EVENTHANDLER_REGISTER(ifnet_arrival_event, \ - ipf_ifevent, NULL, \ + ipf_arrivetag = EVENTHANDLER_REGISTER(ifnet_arrival_event, \ + ipf_ifevent, &ipfmain, \ EVENTHANDLER_PRI_ANY); - ipf_departtag = EVENTHANDLER_REGISTER(ifnet_departure_event, \ - ipf_ifevent, NULL, \ + ipf_departtag = EVENTHANDLER_REGISTER(ifnet_departure_event, \ + ipf_ifevent, &ipfmain, \ EVENTHANDLER_PRI_ANY); - ipf_clonetag = EVENTHANDLER_REGISTER(if_clone_event, ipf_ifevent, \ - NULL, EVENTHANDLER_PRI_ANY); -#endif + ipf_clonetag = EVENTHANDLER_REGISTER(if_clone_event, ipf_ifevent, \ + &ipfmain, EVENTHANDLER_PRI_ANY); } void ipf_event_dereg(void) { -#if (__FreeBSD_version >= 502103) if (ipf_arrivetag != NULL) { EVENTHANDLER_DEREGISTER(ifnet_arrival_event, ipf_arrivetag); } @@ -1662,5 +1418,40 @@ ipf_event_dereg(void) if (ipf_clonetag != NULL) { EVENTHANDLER_DEREGISTER(if_clone_event, ipf_clonetag); } -#endif +} + + +u_32_t +ipf_random() +{ + return arc4random(); +} + + +u_int +ipf_pcksum(fin, hlen, sum) + fr_info_t *fin; + int hlen; + u_int sum; +{ + struct mbuf *m; + u_int sum2; + int off; + + m = fin->fin_m; + off = (char *)fin->fin_dp - (char *)fin->fin_ip; + m->m_data += hlen; + m->m_len -= hlen; + sum2 = in_cksum(fin->fin_m, fin->fin_plen - off); + m->m_len += hlen; + m->m_data -= hlen; + + /* + * Both sum and sum2 are partial sums, so combine them together. + */ + sum += ~sum2 & 0xffff; + while (sum > 0xffff) + sum = (sum & 0xffff) + (sum >> 16); + sum2 = ~sum & 0xffff; + return sum2; } diff --git a/sys/contrib/ipfilter/netinet/ip_frag.c b/sys/contrib/ipfilter/netinet/ip_frag.c index fb21bd1d4846..87e5b7bff4f5 100644 --- a/sys/contrib/ipfilter/netinet/ip_frag.c +++ b/sys/contrib/ipfilter/netinet/ip_frag.c @@ -1,7 +1,7 @@ /* $FreeBSD$ */ /* - * Copyright (C) 1993-2003 by Darren Reed. + * Copyright (C) 2012 by Darren Reed. * * See the IPFILTER.LICENCE file for details on licencing. */ @@ -30,7 +30,8 @@ struct file; # include # undef _KERNEL #endif -#if defined(_KERNEL) && (__FreeBSD_version >= 220000) +#if defined(_KERNEL) && \ + defined(__FreeBSD_version) && (__FreeBSD_version >= 220000) # include # include #else @@ -62,7 +63,6 @@ struct file; #ifdef sun # include #endif -#include #include #include #include @@ -79,25 +79,9 @@ struct file; #include "netinet/ip_frag.h" #include "netinet/ip_state.h" #include "netinet/ip_auth.h" +#include "netinet/ip_lookup.h" #include "netinet/ip_proxy.h" -#if (__FreeBSD_version >= 300000) -# include -# if defined(_KERNEL) -# ifndef IPFILTER_LKM -# include -# include -# endif -extern struct callout_handle fr_slowtimer_ch; -# endif -#endif -#if defined(__NetBSD__) && (__NetBSD_Version__ >= 104230000) -# include -extern struct callout fr_slowtimer_ch; -#endif -#if defined(__OpenBSD__) -# include -extern struct timeout fr_slowtimer_ch; -#endif +#include "netinet/ip_sync.h" /* END OF INCLUDES */ #if !defined(lint) @@ -107,180 +91,398 @@ static const char rcsid[] = "@(#)$FreeBSD$"; #endif -ipfr_t *ipfr_list = NULL; -ipfr_t **ipfr_tail = &ipfr_list; - -ipfr_t *ipfr_natlist = NULL; -ipfr_t **ipfr_nattail = &ipfr_natlist; - -ipfr_t *ipfr_ipidlist = NULL; -ipfr_t **ipfr_ipidtail = &ipfr_ipidlist; - -static ipfr_t **ipfr_heads; -static ipfr_t **ipfr_nattab; -static ipfr_t **ipfr_ipidtab; - -static ipfrstat_t ipfr_stats; -static int ipfr_inuse = 0; -int ipfr_size = IPFT_SIZE; - -int fr_ipfrttl = 120; /* 60 seconds */ -int fr_frag_lock = 0; -int fr_frag_init = 0; -u_long fr_ticks = 0; +typedef struct ipf_frag_softc_s { + ipfrwlock_t ipfr_ipidfrag; + ipfrwlock_t ipfr_frag; + ipfrwlock_t ipfr_natfrag; + int ipfr_size; + int ipfr_ttl; + int ipfr_lock; + int ipfr_inited; + ipfr_t *ipfr_list; + ipfr_t **ipfr_tail; + ipfr_t *ipfr_natlist; + ipfr_t **ipfr_nattail; + ipfr_t *ipfr_ipidlist; + ipfr_t **ipfr_ipidtail; + ipfr_t **ipfr_heads; + ipfr_t **ipfr_nattab; + ipfr_t **ipfr_ipidtab; + ipfrstat_t ipfr_stats; +} ipf_frag_softc_t; -static ipfr_t *ipfr_newfrag __P((fr_info_t *, u_32_t, ipfr_t **)); -static ipfr_t *fr_fraglookup __P((fr_info_t *, ipfr_t **)); -static void fr_fragdelete __P((ipfr_t *, ipfr_t ***)); -static void fr_fragfree __P((ipfr_t *)); +#ifdef USE_MUTEXES +static ipfr_t *ipfr_frag_new __P((ipf_main_softc_t *, ipf_frag_softc_t *, + fr_info_t *, u_32_t, ipfr_t **, + ipfrwlock_t *)); +static ipfr_t *ipf_frag_lookup __P((ipf_main_softc_t *, ipf_frag_softc_t *, fr_info_t *, ipfr_t **, ipfrwlock_t *)); +static void ipf_frag_deref __P((void *, ipfr_t **, ipfrwlock_t *)); +static int ipf_frag_next __P((ipf_main_softc_t *, ipftoken_t *, ipfgeniter_t *, + ipfr_t **, ipfrwlock_t *)); +#else +static ipfr_t *ipfr_frag_new __P((ipf_main_softc_t *, ipf_frag_softc_t *, + fr_info_t *, u_32_t, ipfr_t **)); +static ipfr_t *ipf_frag_lookup __P((ipf_main_softc_t *, ipf_frag_softc_t *, fr_info_t *, ipfr_t **)); +static void ipf_frag_deref __P((void *, ipfr_t **)); +static int ipf_frag_next __P((ipf_main_softc_t *, ipftoken_t *, ipfgeniter_t *, + ipfr_t **)); +#endif +static void ipf_frag_delete __P((ipf_main_softc_t *, ipfr_t *, ipfr_t ***)); +static void ipf_frag_free __P((ipf_frag_softc_t *, ipfr_t *)); + +static frentry_t ipfr_block; + +ipftuneable_t ipf_tuneables[] = { + { { (void *)offsetof(ipf_frag_softc_t, ipfr_size) }, + "frag_size", 1, 0x7fffffff, + stsizeof(ipf_frag_softc_t, ipfr_size), + IPFT_WRDISABLED, NULL, NULL }, + { { (void *)offsetof(ipf_frag_softc_t, ipfr_ttl) }, + "frag_ttl", 1, 0x7fffffff, + stsizeof(ipf_frag_softc_t, ipfr_ttl), + 0, NULL, NULL }, + { { NULL }, + NULL, 0, 0, + 0, + 0, NULL, NULL } +}; + +#define FBUMP(x) softf->ipfr_stats.x++ +#define FBUMPD(x) do { softf->ipfr_stats.x++; DT(x); } while (0) /* ------------------------------------------------------------------------ */ -/* Function: fr_fraginit */ +/* Function: ipf_frag_main_load */ /* Returns: int - 0 == success, -1 == error */ /* Parameters: Nil */ /* */ -/* Initialise the hash tables for the fragment cache lookups. */ +/* Initialise the filter rule associted with blocked packets - everyone can */ +/* use it. */ /* ------------------------------------------------------------------------ */ -int fr_fraginit() +int +ipf_frag_main_load() { - KMALLOCS(ipfr_heads, ipfr_t **, ipfr_size * sizeof(ipfr_t *)); - if (ipfr_heads == NULL) - return -1; - bzero((char *)ipfr_heads, ipfr_size * sizeof(ipfr_t *)); - - KMALLOCS(ipfr_nattab, ipfr_t **, ipfr_size * sizeof(ipfr_t *)); - if (ipfr_nattab == NULL) - return -1; - bzero((char *)ipfr_nattab, ipfr_size * sizeof(ipfr_t *)); - - KMALLOCS(ipfr_ipidtab, ipfr_t **, ipfr_size * sizeof(ipfr_t *)); - if (ipfr_ipidtab == NULL) - return -1; - bzero((char *)ipfr_ipidtab, ipfr_size * sizeof(ipfr_t *)); - - RWLOCK_INIT(&ipf_frag, "ipf fragment rwlock"); - fr_frag_init = 1; + bzero((char *)&ipfr_block, sizeof(ipfr_block)); + ipfr_block.fr_flags = FR_BLOCK|FR_QUICK; + ipfr_block.fr_ref = 1; return 0; } /* ------------------------------------------------------------------------ */ -/* Function: fr_fragunload */ -/* Returns: Nil */ +/* Function: ipf_frag_main_unload */ +/* Returns: int - 0 == success, -1 == error */ /* Parameters: Nil */ /* */ +/* A null-op function that exists as a placeholder so that the flow in */ +/* other functions is obvious. */ +/* ------------------------------------------------------------------------ */ +int +ipf_frag_main_unload() +{ + return 0; +} + + +/* ------------------------------------------------------------------------ */ +/* Function: ipf_frag_soft_create */ +/* Returns: void * - NULL = failure, else pointer to local context */ +/* Parameters: softc(I) - pointer to soft context main structure */ +/* */ +/* Allocate a new soft context structure to track fragment related info. */ +/* ------------------------------------------------------------------------ */ +/*ARGSUSED*/ +void * +ipf_frag_soft_create(softc) + ipf_main_softc_t *softc; +{ + ipf_frag_softc_t *softf; + + KMALLOC(softf, ipf_frag_softc_t *); + if (softf == NULL) + return NULL; + + bzero((char *)softf, sizeof(*softf)); + + RWLOCK_INIT(&softf->ipfr_ipidfrag, "frag ipid lock"); + RWLOCK_INIT(&softf->ipfr_frag, "ipf fragment rwlock"); + RWLOCK_INIT(&softf->ipfr_natfrag, "ipf NAT fragment rwlock"); + + softf->ipfr_size = IPFT_SIZE; + softf->ipfr_ttl = IPF_TTLVAL(60); + softf->ipfr_lock = 1; + softf->ipfr_tail = &softf->ipfr_list; + softf->ipfr_nattail = &softf->ipfr_natlist; + softf->ipfr_ipidtail = &softf->ipfr_ipidlist; + + return softf; +} + + +/* ------------------------------------------------------------------------ */ +/* Function: ipf_frag_soft_destroy */ +/* Returns: Nil */ +/* Parameters: softc(I) - pointer to soft context main structure */ +/* arg(I) - pointer to local context to use */ +/* */ +/* Initialise the hash tables for the fragment cache lookups. */ +/* ------------------------------------------------------------------------ */ +void +ipf_frag_soft_destroy(softc, arg) + ipf_main_softc_t *softc; + void *arg; +{ + ipf_frag_softc_t *softf = arg; + + RW_DESTROY(&softf->ipfr_ipidfrag); + RW_DESTROY(&softf->ipfr_frag); + RW_DESTROY(&softf->ipfr_natfrag); + + KFREE(softf); +} + + +/* ------------------------------------------------------------------------ */ +/* Function: ipf_frag_soft_init */ +/* Returns: int - 0 == success, -1 == error */ +/* Parameters: softc(I) - pointer to soft context main structure */ +/* arg(I) - pointer to local context to use */ +/* */ +/* Initialise the hash tables for the fragment cache lookups. */ +/* ------------------------------------------------------------------------ */ +/*ARGSUSED*/ +int +ipf_frag_soft_init(softc, arg) + ipf_main_softc_t *softc; + void *arg; +{ + ipf_frag_softc_t *softf = arg; + + KMALLOCS(softf->ipfr_heads, ipfr_t **, + softf->ipfr_size * sizeof(ipfr_t *)); + if (softf->ipfr_heads == NULL) + return -1; + + bzero((char *)softf->ipfr_heads, softf->ipfr_size * sizeof(ipfr_t *)); + + KMALLOCS(softf->ipfr_nattab, ipfr_t **, + softf->ipfr_size * sizeof(ipfr_t *)); + if (softf->ipfr_nattab == NULL) + return -2; + + bzero((char *)softf->ipfr_nattab, softf->ipfr_size * sizeof(ipfr_t *)); + + KMALLOCS(softf->ipfr_ipidtab, ipfr_t **, + softf->ipfr_size * sizeof(ipfr_t *)); + if (softf->ipfr_ipidtab == NULL) + return -3; + + bzero((char *)softf->ipfr_ipidtab, + softf->ipfr_size * sizeof(ipfr_t *)); + + softf->ipfr_lock = 0; + softf->ipfr_inited = 1; + + return 0; +} + + +/* ------------------------------------------------------------------------ */ +/* Function: ipf_frag_soft_fini */ +/* Returns: int - 0 == success, -1 == error */ +/* Parameters: softc(I) - pointer to soft context main structure */ +/* arg(I) - pointer to local context to use */ +/* */ /* Free all memory allocated whilst running and from initialisation. */ /* ------------------------------------------------------------------------ */ -void fr_fragunload() +int +ipf_frag_soft_fini(softc, arg) + ipf_main_softc_t *softc; + void *arg; { - if (fr_frag_init == 1) { - fr_fragclear(); + ipf_frag_softc_t *softf = arg; - RW_DESTROY(&ipf_frag); - fr_frag_init = 0; + softf->ipfr_lock = 1; + + if (softf->ipfr_inited == 1) { + ipf_frag_clear(softc); + + softf->ipfr_inited = 0; } - if (ipfr_heads != NULL) - KFREES(ipfr_heads, ipfr_size * sizeof(ipfr_t *)); - ipfr_heads = NULL; + if (softf->ipfr_heads != NULL) + KFREES(softf->ipfr_heads, + softf->ipfr_size * sizeof(ipfr_t *)); + softf->ipfr_heads = NULL; - if (ipfr_nattab != NULL) - KFREES(ipfr_nattab, ipfr_size * sizeof(ipfr_t *)); - ipfr_nattab = NULL; + if (softf->ipfr_nattab != NULL) + KFREES(softf->ipfr_nattab, + softf->ipfr_size * sizeof(ipfr_t *)); + softf->ipfr_nattab = NULL; - if (ipfr_ipidtab != NULL) - KFREES(ipfr_ipidtab, ipfr_size * sizeof(ipfr_t *)); - ipfr_ipidtab = NULL; + if (softf->ipfr_ipidtab != NULL) + KFREES(softf->ipfr_ipidtab, + softf->ipfr_size * sizeof(ipfr_t *)); + softf->ipfr_ipidtab = NULL; + + return 0; } /* ------------------------------------------------------------------------ */ -/* Function: fr_fragstats */ +/* Function: ipf_frag_set_lock */ +/* Returns: Nil */ +/* Parameters: arg(I) - pointer to local context to use */ +/* tmp(I) - new value for lock */ +/* */ +/* Stub function that allows for external manipulation of ipfr_lock */ +/* ------------------------------------------------------------------------ */ +void +ipf_frag_setlock(arg, tmp) + void *arg; + int tmp; +{ + ipf_frag_softc_t *softf = arg; + + softf->ipfr_lock = tmp; +} + + +/* ------------------------------------------------------------------------ */ +/* Function: ipf_frag_stats */ /* Returns: ipfrstat_t* - pointer to struct with current frag stats */ -/* Parameters: Nil */ +/* Parameters: arg(I) - pointer to local context to use */ /* */ /* Updates ipfr_stats with current information and returns a pointer to it */ /* ------------------------------------------------------------------------ */ -ipfrstat_t *fr_fragstats() +ipfrstat_t * +ipf_frag_stats(arg) + void *arg; { - ipfr_stats.ifs_table = ipfr_heads; - ipfr_stats.ifs_nattab = ipfr_nattab; - ipfr_stats.ifs_inuse = ipfr_inuse; - return &ipfr_stats; + ipf_frag_softc_t *softf = arg; + + softf->ipfr_stats.ifs_table = softf->ipfr_heads; + softf->ipfr_stats.ifs_nattab = softf->ipfr_nattab; + return &softf->ipfr_stats; } /* ------------------------------------------------------------------------ */ -/* Function: ipfr_newfrag */ +/* Function: ipfr_frag_new */ /* Returns: ipfr_t * - pointer to fragment cache state info or NULL */ /* Parameters: fin(I) - pointer to packet information */ /* table(I) - pointer to frag table to add to */ +/* lock(I) - pointer to lock to get a write hold of */ /* */ /* Add a new entry to the fragment cache, registering it as having come */ /* through this box, with the result of the filter operation. */ +/* */ +/* If this function succeeds, it returns with a write lock held on "lock". */ +/* If it fails, no lock is held on return. */ /* ------------------------------------------------------------------------ */ -static ipfr_t *ipfr_newfrag(fin, pass, table) -fr_info_t *fin; -u_32_t pass; -ipfr_t *table[]; +static ipfr_t * +ipfr_frag_new(softc, softf, fin, pass, table +#ifdef USE_MUTEXES +, lock +#endif +) + ipf_main_softc_t *softc; + ipf_frag_softc_t *softf; + fr_info_t *fin; + u_32_t pass; + ipfr_t *table[]; +#ifdef USE_MUTEXES + ipfrwlock_t *lock; +#endif { - ipfr_t *fra, frag; + ipfr_t *fra, frag, *fran; u_int idx, off; frentry_t *fr; - ip_t *ip; - if (ipfr_inuse >= IPFT_SIZE) + if (softf->ipfr_stats.ifs_inuse >= softf->ipfr_size) { + FBUMPD(ifs_maximum); return NULL; + } - if ((fin->fin_flx & (FI_FRAG|FI_BAD)) != FI_FRAG) + if ((fin->fin_flx & (FI_FRAG|FI_BAD)) != FI_FRAG) { + FBUMPD(ifs_newbad); return NULL; + } - ip = fin->fin_ip; - - if (pass & FR_FRSTRICT) - if (fin->fin_off != 0) + if (pass & FR_FRSTRICT) { + if (fin->fin_off != 0) { + FBUMPD(ifs_newrestrictnot0); return NULL; + } + } - frag.ipfr_p = ip->ip_p; - idx = ip->ip_p; - frag.ipfr_id = ip->ip_id; - idx += ip->ip_id; - frag.ipfr_tos = ip->ip_tos; - frag.ipfr_src.s_addr = ip->ip_src.s_addr; - idx += ip->ip_src.s_addr; - frag.ipfr_dst.s_addr = ip->ip_dst.s_addr; - idx += ip->ip_dst.s_addr; + frag.ipfr_v = fin->fin_v; + idx = fin->fin_v; + frag.ipfr_p = fin->fin_p; + idx += fin->fin_p; + frag.ipfr_id = fin->fin_id; + idx += fin->fin_id; + frag.ipfr_source = fin->fin_fi.fi_src; + idx += frag.ipfr_src.s_addr; + frag.ipfr_dest = fin->fin_fi.fi_dst; + idx += frag.ipfr_dst.s_addr; frag.ipfr_ifp = fin->fin_ifp; idx *= 127; - idx %= IPFT_SIZE; + idx %= softf->ipfr_size; frag.ipfr_optmsk = fin->fin_fi.fi_optmsk & IPF_OPTCOPY; frag.ipfr_secmsk = fin->fin_fi.fi_secmsk; frag.ipfr_auth = fin->fin_fi.fi_auth; + off = fin->fin_off >> 3; + if (off == 0) { + char *ptr; + int end; + +#ifdef USE_INET6 + if (fin->fin_v == 6) { + + ptr = (char *)fin->fin_fraghdr + + sizeof(struct ip6_frag); + } else +#endif + { + ptr = fin->fin_dp; + } + end = fin->fin_plen - (ptr - (char *)fin->fin_ip); + frag.ipfr_firstend = end >> 3; + } else { + frag.ipfr_firstend = 0; + } + + /* + * allocate some memory, if possible, if not, just record that we + * failed to do so. + */ + KMALLOC(fran, ipfr_t *); + if (fran == NULL) { + FBUMPD(ifs_nomem); + return NULL; + } + + WRITE_ENTER(lock); + /* * first, make sure it isn't already there... */ for (fra = table[idx]; (fra != NULL); fra = fra->ipfr_hnext) if (!bcmp((char *)&frag.ipfr_ifp, (char *)&fra->ipfr_ifp, IPFR_CMPSZ)) { - ipfr_stats.ifs_exists++; + RWLOCK_EXIT(lock); + FBUMPD(ifs_exists); + KFREE(fra); return NULL; } - /* - * allocate some memory, if possible, if not, just record that we - * failed to do so. - */ - KMALLOC(fra, ipfr_t *); - if (fra == NULL) { - ipfr_stats.ifs_nomem++; - return NULL; - } - + fra = fran; + fran = NULL; fr = fin->fin_fr; fra->ipfr_rule = fr; if (fr != NULL) { @@ -300,56 +502,63 @@ ipfr_t *table[]; fra->ipfr_data = NULL; table[idx] = fra; bcopy((char *)&frag.ipfr_ifp, (char *)&fra->ipfr_ifp, IPFR_CMPSZ); - fra->ipfr_ttl = fr_ticks + fr_ipfrttl; + fra->ipfr_v = fin->fin_v; + fra->ipfr_ttl = softc->ipf_ticks + softf->ipfr_ttl; + fra->ipfr_firstend = frag.ipfr_firstend; /* * Compute the offset of the expected start of the next packet. */ - off = ip->ip_off & IP_OFFMASK; if (off == 0) fra->ipfr_seen0 = 1; fra->ipfr_off = off + (fin->fin_dlen >> 3); fra->ipfr_pass = pass; fra->ipfr_ref = 1; - ipfr_stats.ifs_new++; - ipfr_inuse++; + fra->ipfr_pkts = 1; + fra->ipfr_bytes = fin->fin_plen; + FBUMP(ifs_inuse); + FBUMP(ifs_new); return fra; } /* ------------------------------------------------------------------------ */ -/* Function: fr_newfrag */ +/* Function: ipf_frag_new */ /* Returns: int - 0 == success, -1 == error */ /* Parameters: fin(I) - pointer to packet information */ /* */ /* Add a new entry to the fragment cache table based on the current packet */ /* ------------------------------------------------------------------------ */ -int fr_newfrag(fin, pass) -u_32_t pass; -fr_info_t *fin; +int +ipf_frag_new(softc, fin, pass) + ipf_main_softc_t *softc; + u_32_t pass; + fr_info_t *fin; { + ipf_frag_softc_t *softf = softc->ipf_frag_soft; ipfr_t *fra; - if ((fin->fin_v != 4) || (fr_frag_lock != 0)) + if (softf->ipfr_lock != 0) return -1; - WRITE_ENTER(&ipf_frag); - fra = ipfr_newfrag(fin, pass, ipfr_heads); +#ifdef USE_MUTEXES + fra = ipfr_frag_new(softc, softf, fin, pass, softf->ipfr_heads, &softc->ipf_frag); +#else + fra = ipfr_frag_new(softc, softf, fin, pass, softf->ipfr_heads); +#endif if (fra != NULL) { - *ipfr_tail = fra; - fra->ipfr_prev = ipfr_tail; - ipfr_tail = &fra->ipfr_next; - if (ipfr_list == NULL) - ipfr_list = fra; + *softf->ipfr_tail = fra; + fra->ipfr_prev = softf->ipfr_tail; + softf->ipfr_tail = &fra->ipfr_next; fra->ipfr_next = NULL; + RWLOCK_EXIT(&softc->ipf_frag); } - RWLOCK_EXIT(&ipf_frag); return fra ? 0 : -1; } /* ------------------------------------------------------------------------ */ -/* Function: fr_nat_newfrag */ +/* Function: ipf_frag_natnew */ /* Returns: int - 0 == success, -1 == error */ /* Parameters: fin(I) - pointer to packet information */ /* nat(I) - pointer to NAT structure */ @@ -357,33 +566,41 @@ fr_info_t *fin; /* Create a new NAT fragment cache entry based on the current packet and */ /* the NAT structure for this "session". */ /* ------------------------------------------------------------------------ */ -int fr_nat_newfrag(fin, pass, nat) -fr_info_t *fin; -u_32_t pass; -nat_t *nat; +int +ipf_frag_natnew(softc, fin, pass, nat) + ipf_main_softc_t *softc; + fr_info_t *fin; + u_32_t pass; + nat_t *nat; { + ipf_frag_softc_t *softf = softc->ipf_frag_soft; ipfr_t *fra; - if ((fin->fin_v != 4) || (fr_frag_lock != 0)) + if (softf->ipfr_lock != 0) return 0; - WRITE_ENTER(&ipf_natfrag); - fra = ipfr_newfrag(fin, pass, ipfr_nattab); +#ifdef USE_MUTEXES + fra = ipfr_frag_new(softc, softf, fin, pass, softf->ipfr_nattab, + &softf->ipfr_natfrag); +#else + fra = ipfr_frag_new(softc, softf, fin, pass, softf->ipfr_nattab); +#endif if (fra != NULL) { fra->ipfr_data = nat; nat->nat_data = fra; - *ipfr_nattail = fra; - fra->ipfr_prev = ipfr_nattail; - ipfr_nattail = &fra->ipfr_next; + *softf->ipfr_nattail = fra; + fra->ipfr_prev = softf->ipfr_nattail; + softf->ipfr_nattail = &fra->ipfr_next; fra->ipfr_next = NULL; + RWLOCK_EXIT(&softf->ipfr_natfrag); + return 0; } - RWLOCK_EXIT(&ipf_natfrag); - return fra ? 0 : -1; + return -1; } /* ------------------------------------------------------------------------ */ -/* Function: fr_ipid_newfrag */ +/* Function: ipf_frag_ipidnew */ /* Returns: int - 0 == success, -1 == error */ /* Parameters: fin(I) - pointer to packet information */ /* ipid(I) - new IP ID for this fragmented packet */ @@ -391,31 +608,37 @@ nat_t *nat; /* Create a new fragment cache entry for this packet and store, as a data */ /* pointer, the new IP ID value. */ /* ------------------------------------------------------------------------ */ -int fr_ipid_newfrag(fin, ipid) -fr_info_t *fin; -u_32_t ipid; +int +ipf_frag_ipidnew(fin, ipid) + fr_info_t *fin; + u_32_t ipid; { + ipf_main_softc_t *softc = fin->fin_main_soft; + ipf_frag_softc_t *softf = softc->ipf_frag_soft; ipfr_t *fra; - if ((fin->fin_v != 4) || (fr_frag_lock)) + if (softf->ipfr_lock) return 0; - WRITE_ENTER(&ipf_ipidfrag); - fra = ipfr_newfrag(fin, 0, ipfr_ipidtab); +#ifdef USE_MUTEXES + fra = ipfr_frag_new(softc, softf, fin, 0, softf->ipfr_ipidtab, &softf->ipfr_ipidfrag); +#else + fra = ipfr_frag_new(softc, softf, fin, 0, softf->ipfr_ipidtab); +#endif if (fra != NULL) { - fra->ipfr_data = (void *)(uintptr_t)ipid; - *ipfr_ipidtail = fra; - fra->ipfr_prev = ipfr_ipidtail; - ipfr_ipidtail = &fra->ipfr_next; + fra->ipfr_data = (void *)(intptr_t)ipid; + *softf->ipfr_ipidtail = fra; + fra->ipfr_prev = softf->ipfr_ipidtail; + softf->ipfr_ipidtail = &fra->ipfr_next; fra->ipfr_next = NULL; + RWLOCK_EXIT(&softf->ipfr_ipidfrag); } - RWLOCK_EXIT(&ipf_ipidfrag); return fra ? 0 : -1; } /* ------------------------------------------------------------------------ */ -/* Function: fr_fraglookup */ +/* Function: ipf_frag_lookup */ /* Returns: ipfr_t * - pointer to ipfr_t structure if there's a */ /* matching entry in the frag table, else NULL */ /* Parameters: fin(I) - pointer to packet information */ @@ -423,17 +646,44 @@ u_32_t ipid; /* */ /* Check the fragment cache to see if there is already a record of this */ /* packet with its filter result known. */ +/* */ +/* If this function succeeds, it returns with a write lock held on "lock". */ +/* If it fails, no lock is held on return. */ /* ------------------------------------------------------------------------ */ -static ipfr_t *fr_fraglookup(fin, table) -fr_info_t *fin; -ipfr_t *table[]; +static ipfr_t * +ipf_frag_lookup(softc, softf, fin, table +#ifdef USE_MUTEXES +, lock +#endif +) + ipf_main_softc_t *softc; + ipf_frag_softc_t *softf; + fr_info_t *fin; + ipfr_t *table[]; +#ifdef USE_MUTEXES + ipfrwlock_t *lock; +#endif { ipfr_t *f, frag; u_int idx; - ip_t *ip; - if ((fin->fin_flx & (FI_FRAG|FI_BAD)) != FI_FRAG) + /* + * We don't want to let short packets match because they could be + * compromising the security of other rules that want to match on + * layer 4 fields (and can't because they have been fragmented off.) + * Why do this check here? The counter acts as an indicator of this + * kind of attack, whereas if it was elsewhere, it wouldn't know if + * other matching packets had been seen. + */ + if (fin->fin_flx & FI_SHORT) { + FBUMPD(ifs_short); return NULL; + } + + if ((fin->fin_flx & FI_BAD) != 0) { + FBUMPD(ifs_bad); + return NULL; + } /* * For fragments, we record protocol, packet id, TOS and both IP#'s @@ -441,59 +691,58 @@ ipfr_t *table[]; * * build up a hash value to index the table with. */ - ip = fin->fin_ip; - frag.ipfr_p = ip->ip_p; - idx = ip->ip_p; - frag.ipfr_id = ip->ip_id; - idx += ip->ip_id; - frag.ipfr_tos = ip->ip_tos; - frag.ipfr_src.s_addr = ip->ip_src.s_addr; - idx += ip->ip_src.s_addr; - frag.ipfr_dst.s_addr = ip->ip_dst.s_addr; - idx += ip->ip_dst.s_addr; + frag.ipfr_v = fin->fin_v; + idx = fin->fin_v; + frag.ipfr_p = fin->fin_p; + idx += fin->fin_p; + frag.ipfr_id = fin->fin_id; + idx += fin->fin_id; + frag.ipfr_source = fin->fin_fi.fi_src; + idx += frag.ipfr_src.s_addr; + frag.ipfr_dest = fin->fin_fi.fi_dst; + idx += frag.ipfr_dst.s_addr; frag.ipfr_ifp = fin->fin_ifp; idx *= 127; - idx %= IPFT_SIZE; + idx %= softf->ipfr_size; frag.ipfr_optmsk = fin->fin_fi.fi_optmsk & IPF_OPTCOPY; frag.ipfr_secmsk = fin->fin_fi.fi_secmsk; frag.ipfr_auth = fin->fin_fi.fi_auth; + READ_ENTER(lock); + /* * check the table, careful to only compare the right amount of data */ - for (f = table[idx]; f; f = f->ipfr_hnext) + for (f = table[idx]; f; f = f->ipfr_hnext) { if (!bcmp((char *)&frag.ipfr_ifp, (char *)&f->ipfr_ifp, IPFR_CMPSZ)) { u_short off; - /* - * We don't want to let short packets match because - * they could be compromising the security of other - * rules that want to match on layer 4 fields (and - * can't because they have been fragmented off.) - * Why do this check here? The counter acts as an - * indicator of this kind of attack, whereas if it was - * elsewhere, it wouldn't know if other matching - * packets had been seen. - */ - if (fin->fin_flx & FI_SHORT) { - ATOMIC_INCL(ipfr_stats.ifs_short); - continue; - } - /* * XXX - We really need to be guarding against the * retransmission of (src,dst,id,offset-range) here * because a fragmented packet is never resent with * the same IP ID# (or shouldn't). */ - off = ip->ip_off & IP_OFFMASK; + off = fin->fin_off >> 3; if (f->ipfr_seen0) { if (off == 0) { - ATOMIC_INCL(ipfr_stats.ifs_retrans0); + FBUMPD(ifs_retrans0); continue; } + + /* + * Case 3. See comment for frpr_fragment6. + */ + if ((f->ipfr_firstend != 0) && + (off < f->ipfr_firstend)) { + FBUMP(ifs_overlap); + DT2(ifs_overlap, u_short, off, + ipfr_t *, f); + fin->fin_flx |= FI_BAD; + break; + } } else if (off == 0) f->ipfr_seen0 = 1; @@ -522,82 +771,124 @@ ipfr_t *table[]; * last (in order), shrink expiration time. */ if (off == f->ipfr_off) { - if (!(ip->ip_off & IP_MF)) - f->ipfr_ttl = fr_ticks + 1; f->ipfr_off = (fin->fin_dlen >> 3) + off; - } else if (f->ipfr_pass & FR_FRSTRICT) - continue; - ATOMIC_INCL(ipfr_stats.ifs_hits); + + /* + * Well, we could shrink the expiration time + * but only if every fragment has been seen + * in order upto this, the last. ipfr_badorder + * is used here to count those out of order + * and if it equals 0 when we get to the last + * fragment then we can assume all of the + * fragments have been seen and in order. + */ +#if 0 + /* + * Doing this properly requires moving it to + * the head of the list which is infesible. + */ + if ((more == 0) && (f->ipfr_badorder == 0)) + f->ipfr_ttl = softc->ipf_ticks + 1; +#endif + } else { + f->ipfr_badorder++; + FBUMPD(ifs_unordered); + if (f->ipfr_pass & FR_FRSTRICT) { + FBUMPD(ifs_strict); + continue; + } + } + f->ipfr_pkts++; + f->ipfr_bytes += fin->fin_plen; + FBUMP(ifs_hits); return f; } + } + + RWLOCK_EXIT(lock); + FBUMP(ifs_miss); return NULL; } /* ------------------------------------------------------------------------ */ -/* Function: fr_nat_knownfrag */ +/* Function: ipf_frag_natknown */ /* Returns: nat_t* - pointer to 'parent' NAT structure if frag table */ /* match found, else NULL */ /* Parameters: fin(I) - pointer to packet information */ /* */ /* Functional interface for NAT lookups of the NAT fragment cache */ /* ------------------------------------------------------------------------ */ -nat_t *fr_nat_knownfrag(fin) -fr_info_t *fin; +nat_t * +ipf_frag_natknown(fin) + fr_info_t *fin; { + ipf_main_softc_t *softc = fin->fin_main_soft; + ipf_frag_softc_t *softf = softc->ipf_frag_soft; nat_t *nat; ipfr_t *ipf; - if ((fin->fin_v != 4) || (fr_frag_lock) || !ipfr_natlist) + if ((softf->ipfr_lock) || !softf->ipfr_natlist) return NULL; - READ_ENTER(&ipf_natfrag); - ipf = fr_fraglookup(fin, ipfr_nattab); +#ifdef USE_MUTEXES + ipf = ipf_frag_lookup(softc, softf, fin, softf->ipfr_nattab, + &softf->ipfr_natfrag); +#else + ipf = ipf_frag_lookup(softc, softf, fin, softf->ipfr_nattab); +#endif if (ipf != NULL) { nat = ipf->ipfr_data; /* * This is the last fragment for this packet. */ - if ((ipf->ipfr_ttl == fr_ticks + 1) && (nat != NULL)) { + if ((ipf->ipfr_ttl == softc->ipf_ticks + 1) && (nat != NULL)) { nat->nat_data = NULL; ipf->ipfr_data = NULL; } + RWLOCK_EXIT(&softf->ipfr_natfrag); } else nat = NULL; - RWLOCK_EXIT(&ipf_natfrag); return nat; } /* ------------------------------------------------------------------------ */ -/* Function: fr_ipid_knownfrag */ +/* Function: ipf_frag_ipidknown */ /* Returns: u_32_t - IPv4 ID for this packet if match found, else */ /* return 0xfffffff to indicate no match. */ /* Parameters: fin(I) - pointer to packet information */ /* */ /* Functional interface for IP ID lookups of the IP ID fragment cache */ /* ------------------------------------------------------------------------ */ -u_32_t fr_ipid_knownfrag(fin) -fr_info_t *fin; +u_32_t +ipf_frag_ipidknown(fin) + fr_info_t *fin; { + ipf_main_softc_t *softc = fin->fin_main_soft; + ipf_frag_softc_t *softf = softc->ipf_frag_soft; ipfr_t *ipf; u_32_t id; - if ((fin->fin_v != 4) || (fr_frag_lock) || !ipfr_ipidlist) + if (softf->ipfr_lock || !softf->ipfr_ipidlist) return 0xffffffff; - READ_ENTER(&ipf_ipidfrag); - ipf = fr_fraglookup(fin, ipfr_ipidtab); - if (ipf != NULL) - id = (u_32_t)(uintptr_t)ipf->ipfr_data; - else +#ifdef USE_MUTEXES + ipf = ipf_frag_lookup(softc, softf, fin, softf->ipfr_ipidtab, + &softf->ipfr_ipidfrag); +#else + ipf = ipf_frag_lookup(softc, softf, fin, softf->ipfr_ipidtab); +#endif + if (ipf != NULL) { + id = (u_32_t)(intptr_t)ipf->ipfr_data; + RWLOCK_EXIT(&softf->ipfr_ipidfrag); + } else id = 0xffffffff; - RWLOCK_EXIT(&ipf_ipidfrag); return id; } /* ------------------------------------------------------------------------ */ -/* Function: fr_knownfrag */ +/* Function: ipf_frag_known */ /* Returns: frentry_t* - pointer to filter rule if a match is found in */ /* the frag cache table, else NULL. */ /* Parameters: fin(I) - pointer to packet information */ @@ -607,78 +898,82 @@ fr_info_t *fin; /* match is found, return the rule pointer and flags from the rule, except */ /* that if FR_LOGFIRST is set, reset FR_LOG. */ /* ------------------------------------------------------------------------ */ -frentry_t *fr_knownfrag(fin, passp) -fr_info_t *fin; -u_32_t *passp; +frentry_t * +ipf_frag_known(fin, passp) + fr_info_t *fin; + u_32_t *passp; { + ipf_main_softc_t *softc = fin->fin_main_soft; + ipf_frag_softc_t *softf = softc->ipf_frag_soft; frentry_t *fr = NULL; ipfr_t *fra; u_32_t pass; - if ((fin->fin_v != 4) || (fr_frag_lock) || (ipfr_list == NULL)) + if ((softf->ipfr_lock) || (softf->ipfr_list == NULL)) return NULL; - READ_ENTER(&ipf_frag); - fra = fr_fraglookup(fin, ipfr_heads); +#ifdef USE_MUTEXES + fra = ipf_frag_lookup(softc, softf, fin, softf->ipfr_heads, + &softc->ipf_frag); +#else + fra = ipf_frag_lookup(softc, softf, fin, softf->ipfr_heads); +#endif if (fra != NULL) { - fr = fra->ipfr_rule; + if (fin->fin_flx & FI_BAD) { + fr = &ipfr_block; + fin->fin_reason = FRB_BADFRAG; + } else { + fr = fra->ipfr_rule; + } fin->fin_fr = fr; if (fr != NULL) { pass = fr->fr_flags; + if ((pass & FR_KEEPSTATE) != 0) { + fin->fin_flx |= FI_STATE; + /* + * Reset the keep state flag here so that we + * don't try and add a new state entry because + * of a match here. That leads to blocking of + * the packet later because the add fails. + */ + pass &= ~FR_KEEPSTATE; + } if ((pass & FR_LOGFIRST) != 0) pass &= ~(FR_LOGFIRST|FR_LOG); *passp = pass; } + RWLOCK_EXIT(&softc->ipf_frag); } - RWLOCK_EXIT(&ipf_frag); return fr; } /* ------------------------------------------------------------------------ */ -/* Function: fr_forget */ -/* Returns: Nil */ -/* Parameters: ptr(I) - pointer to data structure */ -/* */ -/* Search through all of the fragment cache entries and wherever a pointer */ -/* is found to match ptr, reset it to NULL. */ -/* ------------------------------------------------------------------------ */ -void fr_forget(ptr) -void *ptr; -{ - ipfr_t *fr; - - WRITE_ENTER(&ipf_frag); - for (fr = ipfr_list; fr; fr = fr->ipfr_next) - if (fr->ipfr_data == ptr) - fr->ipfr_data = NULL; - RWLOCK_EXIT(&ipf_frag); -} - - -/* ------------------------------------------------------------------------ */ -/* Function: fr_forgetnat */ +/* Function: ipf_frag_natforget */ /* Returns: Nil */ /* Parameters: ptr(I) - pointer to data structure */ /* */ /* Search through all of the fragment cache entries for NAT and wherever a */ /* pointer is found to match ptr, reset it to NULL. */ /* ------------------------------------------------------------------------ */ -void fr_forgetnat(ptr) -void *ptr; +void +ipf_frag_natforget(softc, ptr) + ipf_main_softc_t *softc; + void *ptr; { + ipf_frag_softc_t *softf = softc->ipf_frag_soft; ipfr_t *fr; - WRITE_ENTER(&ipf_natfrag); - for (fr = ipfr_natlist; fr; fr = fr->ipfr_next) + WRITE_ENTER(&softf->ipfr_natfrag); + for (fr = softf->ipfr_natlist; fr; fr = fr->ipfr_next) if (fr->ipfr_data == ptr) fr->ipfr_data = NULL; - RWLOCK_EXIT(&ipf_natfrag); + RWLOCK_EXIT(&softf->ipfr_natfrag); } /* ------------------------------------------------------------------------ */ -/* Function: fr_fragdelete */ +/* Function: ipf_frag_delete */ /* Returns: Nil */ /* Parameters: fra(I) - pointer to fragment structure to delete */ /* tail(IO) - pointer to the pointer to the tail of the frag */ @@ -688,9 +983,12 @@ void *ptr; /* the filter rule it is associated with it if it is no longer used as a */ /* result of decreasing the reference count. */ /* ------------------------------------------------------------------------ */ -static void fr_fragdelete(fra, tail) -ipfr_t *fra, ***tail; +static void +ipf_frag_delete(softc, fra, tail) + ipf_main_softc_t *softc; + ipfr_t *fra, ***tail; { + ipf_frag_softc_t *softf = softc->ipf_frag_soft; if (fra->ipfr_next) fra->ipfr_next->ipfr_prev = fra->ipfr_prev; @@ -703,107 +1001,112 @@ ipfr_t *fra, ***tail; *fra->ipfr_hprev = fra->ipfr_hnext; if (fra->ipfr_rule != NULL) { - (void) fr_derefrule(&fra->ipfr_rule); + (void) ipf_derefrule(softc, &fra->ipfr_rule); } if (fra->ipfr_ref <= 0) - fr_fragfree(fra); + ipf_frag_free(softf, fra); } /* ------------------------------------------------------------------------ */ -/* Function: fr_fragfree */ +/* Function: ipf_frag_free */ /* Returns: Nil */ -/* Parameters: fra - pointer to frag structure to free */ /* */ -/* Take care of the details associated with deleting an entry from the frag */ -/* cache. Currently this just means bumping stats correctly after freeing */ /* ------------------------------------------------------------------------ */ -static void fr_fragfree(fra) -ipfr_t *fra; +static void +ipf_frag_free(softf, fra) + ipf_frag_softc_t *softf; + ipfr_t *fra; { KFREE(fra); - ipfr_stats.ifs_expire++; - ipfr_inuse--; + FBUMP(ifs_expire); + softf->ipfr_stats.ifs_inuse--; } /* ------------------------------------------------------------------------ */ -/* Function: fr_fragclear */ +/* Function: ipf_frag_clear */ /* Returns: Nil */ /* Parameters: Nil */ /* */ /* Free memory in use by fragment state information kept. Do the normal */ /* fragment state stuff first and then the NAT-fragment table. */ /* ------------------------------------------------------------------------ */ -void fr_fragclear() +void +ipf_frag_clear(softc) + ipf_main_softc_t *softc; { + ipf_frag_softc_t *softf = softc->ipf_frag_soft; ipfr_t *fra; nat_t *nat; - WRITE_ENTER(&ipf_frag); - while ((fra = ipfr_list) != NULL) { + WRITE_ENTER(&softc->ipf_frag); + while ((fra = softf->ipfr_list) != NULL) { fra->ipfr_ref--; - fr_fragdelete(fra, &ipfr_tail); + ipf_frag_delete(softc, fra, &softf->ipfr_tail); } - ipfr_tail = &ipfr_list; - RWLOCK_EXIT(&ipf_frag); + softf->ipfr_tail = &softf->ipfr_list; + RWLOCK_EXIT(&softc->ipf_frag); - WRITE_ENTER(&ipf_nat); - WRITE_ENTER(&ipf_natfrag); - while ((fra = ipfr_natlist) != NULL) { + WRITE_ENTER(&softc->ipf_nat); + WRITE_ENTER(&softf->ipfr_natfrag); + while ((fra = softf->ipfr_natlist) != NULL) { nat = fra->ipfr_data; if (nat != NULL) { if (nat->nat_data == fra) nat->nat_data = NULL; } fra->ipfr_ref--; - fr_fragdelete(fra, &ipfr_nattail); + ipf_frag_delete(softc, fra, &softf->ipfr_nattail); } - ipfr_nattail = &ipfr_natlist; - RWLOCK_EXIT(&ipf_natfrag); - RWLOCK_EXIT(&ipf_nat); + softf->ipfr_nattail = &softf->ipfr_natlist; + RWLOCK_EXIT(&softf->ipfr_natfrag); + RWLOCK_EXIT(&softc->ipf_nat); } /* ------------------------------------------------------------------------ */ -/* Function: fr_fragexpire */ +/* Function: ipf_frag_expire */ /* Returns: Nil */ /* Parameters: Nil */ /* */ /* Expire entries in the fragment cache table that have been there too long */ /* ------------------------------------------------------------------------ */ -void fr_fragexpire() +void +ipf_frag_expire(softc) + ipf_main_softc_t *softc; { + ipf_frag_softc_t *softf = softc->ipf_frag_soft; ipfr_t **fp, *fra; nat_t *nat; SPL_INT(s); - if (fr_frag_lock) + if (softf->ipfr_lock) return; SPL_NET(s); - WRITE_ENTER(&ipf_frag); + WRITE_ENTER(&softc->ipf_frag); /* * Go through the entire table, looking for entries to expire, - * which is indicated by the ttl being less than or equal to fr_ticks. + * which is indicated by the ttl being less than or equal to ipf_ticks. */ - for (fp = &ipfr_list; ((fra = *fp) != NULL); ) { - if (fra->ipfr_ttl > fr_ticks) + for (fp = &softf->ipfr_list; ((fra = *fp) != NULL); ) { + if (fra->ipfr_ttl > softc->ipf_ticks) break; fra->ipfr_ref--; - fr_fragdelete(fra, &ipfr_tail); + ipf_frag_delete(softc, fra, &softf->ipfr_tail); } - RWLOCK_EXIT(&ipf_frag); + RWLOCK_EXIT(&softc->ipf_frag); - WRITE_ENTER(&ipf_ipidfrag); - for (fp = &ipfr_ipidlist; ((fra = *fp) != NULL); ) { - if (fra->ipfr_ttl > fr_ticks) + WRITE_ENTER(&softf->ipfr_ipidfrag); + for (fp = &softf->ipfr_ipidlist; ((fra = *fp) != NULL); ) { + if (fra->ipfr_ttl > softc->ipf_ticks) break; fra->ipfr_ref--; - fr_fragdelete(fra, &ipfr_ipidtail); + ipf_frag_delete(softc, fra, &softf->ipfr_ipidtail); } - RWLOCK_EXIT(&ipf_ipidfrag); + RWLOCK_EXIT(&softf->ipfr_ipidfrag); /* * Same again for the NAT table, except that if the structure also @@ -815,11 +1118,11 @@ void fr_fragexpire() * operations - no need to do that if there are no entries in this * list, right? */ - if (ipfr_natlist != NULL) { - WRITE_ENTER(&ipf_nat); - WRITE_ENTER(&ipf_natfrag); - for (fp = &ipfr_natlist; ((fra = *fp) != NULL); ) { - if (fra->ipfr_ttl > fr_ticks) + if (softf->ipfr_natlist != NULL) { + WRITE_ENTER(&softc->ipf_nat); + WRITE_ENTER(&softf->ipfr_natfrag); + for (fp = &softf->ipfr_natlist; ((fra = *fp) != NULL); ) { + if (fra->ipfr_ttl > softc->ipf_ticks) break; nat = fra->ipfr_data; if (nat != NULL) { @@ -827,76 +1130,60 @@ void fr_fragexpire() nat->nat_data = NULL; } fra->ipfr_ref--; - fr_fragdelete(fra, &ipfr_nattail); + ipf_frag_delete(softc, fra, &softf->ipfr_nattail); } - RWLOCK_EXIT(&ipf_natfrag); - RWLOCK_EXIT(&ipf_nat); + RWLOCK_EXIT(&softf->ipfr_natfrag); + RWLOCK_EXIT(&softc->ipf_nat); } SPL_X(s); } /* ------------------------------------------------------------------------ */ -/* Function: fr_slowtimer */ -/* Returns: Nil */ -/* Parameters: Nil */ -/* */ -/* Slowly expire held state for fragments. Timeouts are set * in */ -/* expectation of this being called twice per second. */ +/* Function: ipf_frag_pkt_next */ /* ------------------------------------------------------------------------ */ -#if !defined(_KERNEL) || (!SOLARIS && !defined(__hpux) && !defined(__sgi) && \ - !defined(__osf__) && !defined(linux)) -# if defined(_KERNEL) && ((BSD >= 199103) || defined(__sgi)) -void fr_slowtimer __P((void *ptr)) -# else -int fr_slowtimer() -# endif +int +ipf_frag_pkt_next(softc, token, itp) + ipf_main_softc_t *softc; + ipftoken_t *token; + ipfgeniter_t *itp; { - READ_ENTER(&ipf_global); + ipf_frag_softc_t *softf = softc->ipf_frag_soft; - ipf_expiretokens(); - fr_fragexpire(); - fr_timeoutstate(); - fr_natexpire(); - fr_authexpire(); - fr_ticks++; - if (fr_running <= 0) - goto done; -# ifdef _KERNEL -# if defined(__NetBSD__) && (__NetBSD_Version__ >= 104240000) - callout_reset(&fr_slowtimer_ch, hz / 2, fr_slowtimer, NULL); -# else -# if defined(__OpenBSD__) - timeout_add(&fr_slowtimer_ch, hz/2); -# else -# if (__FreeBSD_version >= 300000) - fr_slowtimer_ch = timeout(fr_slowtimer, NULL, hz/2); -# else -# ifdef linux - ; -# else - timeout(fr_slowtimer, NULL, hz/2); -# endif -# endif /* FreeBSD */ -# endif /* OpenBSD */ -# endif /* NetBSD */ -# endif -done: - RWLOCK_EXIT(&ipf_global); -# if (BSD < 199103) || !defined(_KERNEL) - return 0; -# endif +#ifdef USE_MUTEXES + return ipf_frag_next(softc, token, itp, &softf->ipfr_list, + &softf->ipfr_frag); +#else + return ipf_frag_next(softc, token, itp, &softf->ipfr_list); +#endif } -#endif /* !SOLARIS && !defined(__hpux) && !defined(__sgi) */ /* ------------------------------------------------------------------------ */ -/* Function: fr_nextfrag */ +/* Function: ipf_frag_nat_next */ +/* ------------------------------------------------------------------------ */ +int +ipf_frag_nat_next(softc, token, itp) + ipf_main_softc_t *softc; + ipftoken_t *token; + ipfgeniter_t *itp; +{ + ipf_frag_softc_t *softf = softc->ipf_frag_soft;; + +#ifdef USE_MUTEXES + return ipf_frag_next(softc, token, itp, &softf->ipfr_natlist, + &softf->ipfr_natfrag); +#else + return ipf_frag_next(softc, token, itp, &softf->ipfr_natlist); +#endif +} + +/* ------------------------------------------------------------------------ */ +/* Function: ipf_frag_next */ /* Returns: int - 0 == success, else error */ /* Parameters: token(I) - pointer to token information for this caller */ /* itp(I) - pointer to generic iterator from caller */ /* top(I) - top of the fragment list */ -/* tail(I) - tail of the fragment list */ /* lock(I) - fragment cache lock */ /* */ /* This function is used to interate through the list of entries in the */ @@ -904,30 +1191,39 @@ int fr_slowtimer() /* being returned so that the caller can come back and resume from it later.*/ /* */ /* This function is used for both the NAT fragment cache as well as the ipf */ -/* fragment cache - hence the reason for passing in top, tail and lock. */ +/* fragment cache - hence the reason for passing in top and lock. */ /* ------------------------------------------------------------------------ */ -int fr_nextfrag(token, itp, top, tail +static int +ipf_frag_next(softc, token, itp, top #ifdef USE_MUTEXES , lock #endif ) -ipftoken_t *token; -ipfgeniter_t *itp; -ipfr_t **top, ***tail; + ipf_main_softc_t *softc; + ipftoken_t *token; + ipfgeniter_t *itp; + ipfr_t **top; #ifdef USE_MUTEXES -ipfrwlock_t *lock; + ipfrwlock_t *lock; #endif { ipfr_t *frag, *next, zero; int error = 0; - frag = token->ipt_data; - if (frag == (ipfr_t *)-1) { - ipf_freetoken(token); - return ESRCH; + if (itp->igi_data == NULL) { + IPFERROR(20001); + return EFAULT; } + if (itp->igi_nitems != 1) { + IPFERROR(20003); + return EFAULT; + } + + frag = token->ipt_data; + READ_ENTER(lock); + if (frag == NULL) next = *top; else @@ -941,26 +1237,72 @@ ipfrwlock_t *lock; next = &zero; token->ipt_data = NULL; } - RWLOCK_EXIT(lock); + if (next->ipfr_next == NULL) + ipf_token_mark_complete(token); - if (frag != NULL) { -#ifdef USE_MUTEXES - fr_fragderef(&frag, lock); -#else - fr_fragderef(&frag); -#endif - } + RWLOCK_EXIT(lock); error = COPYOUT(next, itp->igi_data, sizeof(*next)); if (error != 0) - error = EFAULT; + IPFERROR(20002); - return error; + if (frag != NULL) { +#ifdef USE_MUTEXES + ipf_frag_deref(softc, &frag, lock); +#else + ipf_frag_deref(softc, &frag); +#endif + } + return error; } /* ------------------------------------------------------------------------ */ -/* Function: fr_fragderef */ +/* Function: ipf_frag_pkt_deref */ +/* Returns: Nil */ +/* */ +/* ------------------------------------------------------------------------ */ +void +ipf_frag_pkt_deref(softc, data) + ipf_main_softc_t *softc; + void *data; +{ + ipfr_t **frp = data; + +#ifdef USE_MUTEXES + ipf_frag_softc_t *softf = softc->ipf_frag_soft; + + ipf_frag_deref(softc->ipf_frag_soft, frp, &softf->ipfr_frag); +#else + ipf_frag_deref(softc->ipf_frag_soft, frp); +#endif +} + + +/* ------------------------------------------------------------------------ */ +/* Function: ipf_frag_nat_deref */ +/* Returns: Nil */ +/* */ +/* ------------------------------------------------------------------------ */ +void +ipf_frag_nat_deref(softc, data) + ipf_main_softc_t *softc; + void *data; +{ + ipfr_t **frp = data; + +#ifdef USE_MUTEXES + ipf_frag_softc_t *softf = softc->ipf_frag_soft; + + ipf_frag_deref(softc->ipf_frag_soft, frp, &softf->ipfr_natfrag); +#else + ipf_frag_deref(softc->ipf_frag_soft, frp); +#endif +} + + +/* ------------------------------------------------------------------------ */ +/* Function: ipf_frag_deref */ /* Returns: Nil */ /* Parameters: frp(IO) - pointer to fragment structure to deference */ /* lock(I) - lock associated with the fragment */ @@ -970,16 +1312,19 @@ ipfrwlock_t *lock; /* not freed, to enforce the notion that the caller is no longer entitled */ /* to use the pointer it is dropping the reference to. */ /* ------------------------------------------------------------------------ */ -void fr_fragderef(frp +static void +ipf_frag_deref(arg, frp #ifdef USE_MUTEXES , lock #endif ) -ipfr_t **frp; + void *arg; + ipfr_t **frp; #ifdef USE_MUTEXES -ipfrwlock_t *lock; + ipfrwlock_t *lock; #endif { + ipf_frag_softc_t *softf = arg; ipfr_t *fra; fra = *frp; @@ -988,6 +1333,6 @@ ipfrwlock_t *lock; WRITE_ENTER(lock); fra->ipfr_ref--; if (fra->ipfr_ref <= 0) - fr_fragfree(fra); + ipf_frag_free(softf, fra); RWLOCK_EXIT(lock); } diff --git a/sys/contrib/ipfilter/netinet/ip_frag.h b/sys/contrib/ipfilter/netinet/ip_frag.h index 227dbcd55535..6b0c1be221e3 100644 --- a/sys/contrib/ipfilter/netinet/ip_frag.h +++ b/sys/contrib/ipfilter/netinet/ip_frag.h @@ -1,7 +1,7 @@ /* $FreeBSD$ */ /* - * Copyright (C) 1993-2001 by Darren Reed. + * Copyright (C) 2012 by Darren Reed. * * See the IPFILTER.LICENCE file for details on licencing. * @@ -21,26 +21,33 @@ typedef struct ipfr { void *ipfr_data; frentry_t *ipfr_rule; u_long ipfr_ttl; + u_int ipfr_pkts; + u_int ipfr_bytes; + u_int ipfr_badorder; int ipfr_ref; u_short ipfr_off; - u_short ipfr_seen0; + u_short ipfr_firstend; + u_char ipfr_p; + u_char ipfr_seen0; /* * All of the fields, from ipfr_ifp to ipfr_pass, are compared * using bcmp to see if an identical entry is present. It is * therefore important for this set to remain together. */ void *ipfr_ifp; - struct in_addr ipfr_src; - struct in_addr ipfr_dst; + i6addr_t ipfr_source; + i6addr_t ipfr_dest; u_32_t ipfr_optmsk; u_short ipfr_secmsk; u_short ipfr_auth; - u_short ipfr_id; - u_char ipfr_p; - u_char ipfr_tos; + u_32_t ipfr_id; u_32_t ipfr_pass; + int ipfr_v; } ipfr_t; +#define ipfr_src ipfr_source.in4 +#define ipfr_dst ipfr_dest.in4 + typedef struct ipfrstat { u_long ifs_exists; /* add & already exists */ @@ -51,6 +58,14 @@ typedef struct ipfrstat { u_long ifs_inuse; u_long ifs_retrans0; u_long ifs_short; + u_long ifs_bad; + u_long ifs_overlap; + u_long ifs_unordered; + u_long ifs_strict; + u_long ifs_miss; + u_long ifs_maximum; + u_long ifs_newbad; + u_long ifs_newrestrictnot0; struct ipfr **ifs_table; struct ipfr **ifs_nattab; } ipfrstat_t; @@ -58,51 +73,32 @@ typedef struct ipfrstat { #define IPFR_CMPSZ (offsetof(ipfr_t, ipfr_pass) - \ offsetof(ipfr_t, ipfr_ifp)) -extern ipfr_t *ipfr_list, **ipfr_tail; -extern ipfr_t *ipfr_natlist, **ipfr_nattail; -extern int ipfr_size; -extern int fr_ipfrttl; -extern int fr_frag_lock; -extern int fr_fraginit __P((void)); -extern void fr_fragunload __P((void)); -extern ipfrstat_t *fr_fragstats __P((void)); - -extern int fr_newfrag __P((fr_info_t *, u_32_t)); -extern frentry_t *fr_knownfrag __P((fr_info_t *, u_32_t *)); - -extern int fr_nat_newfrag __P((fr_info_t *, u_32_t, struct nat *)); -extern nat_t *fr_nat_knownfrag __P((fr_info_t *)); - -extern int fr_ipid_newfrag __P((fr_info_t *, u_32_t)); -extern u_32_t fr_ipid_knownfrag __P((fr_info_t *)); -#ifdef USE_MUTEXES -extern void fr_fragderef __P((ipfr_t **, ipfrwlock_t *)); -extern int fr_nextfrag __P((ipftoken_t *, ipfgeniter_t *, ipfr_t **, \ - ipfr_t ***, ipfrwlock_t *)); -#else -extern void fr_fragderef __P((ipfr_t **)); -extern int fr_nextfrag __P((ipftoken_t *, ipfgeniter_t *, ipfr_t **, \ - ipfr_t ***)); -#endif - -extern void fr_forget __P((void *)); -extern void fr_forgetnat __P((void *)); -extern void fr_fragclear __P((void)); -extern void fr_fragexpire __P((void)); - -#if defined(_KERNEL) && ((BSD >= 199306) || SOLARIS || defined(__sgi) \ - || defined(__osf__) || (defined(__sgi) && (IRIX >= 60500))) -# if defined(SOLARIS2) && (SOLARIS2 < 7) -extern void fr_slowtimer __P((void)); -# else -extern void fr_slowtimer __P((void *)); -# endif -#else -# if defined(linux) && defined(_KERNEL) -extern void fr_slowtimer __P((long)); -# else -extern int fr_slowtimer __P((void)); -# endif -#endif +extern void *ipf_frag_soft_create __P((ipf_main_softc_t *)); +extern int ipf_frag_soft_init __P((ipf_main_softc_t *, void *)); +extern int ipf_frag_soft_fini __P((ipf_main_softc_t *, void *)); +extern void ipf_frag_soft_destroy __P((ipf_main_softc_t *, void *)); +extern int ipf_frag_main_load __P((void)); +extern int ipf_frag_main_unload __P((void)); +extern int ipf_frag_load __P((void)); +extern void ipf_frag_clear __P((ipf_main_softc_t *)); +extern void ipf_frag_expire __P((ipf_main_softc_t *)); +extern void ipf_frag_forget __P((void *)); +extern int ipf_frag_init __P((void)); +extern u_32_t ipf_frag_ipidknown __P((fr_info_t *)); +extern int ipf_frag_ipidnew __P((fr_info_t *, u_32_t)); +extern frentry_t *ipf_frag_known __P((fr_info_t *, u_32_t *)); +extern void ipf_frag_natforget __P((ipf_main_softc_t *, void *)); +extern int ipf_frag_natnew __P((ipf_main_softc_t *, fr_info_t *, u_32_t, struct nat *)); +extern nat_t *ipf_frag_natknown __P((fr_info_t *)); +extern int ipf_frag_new __P((ipf_main_softc_t *, fr_info_t *, u_32_t)); +extern ipfrstat_t *ipf_frag_stats __P((void *)); +extern void ipf_frag_setlock __P((void *, int)); +extern void ipf_frag_pkt_deref __P((ipf_main_softc_t *, void *)); +extern int ipf_frag_pkt_next __P((ipf_main_softc_t *, ipftoken_t *, + ipfgeniter_t *)); +extern void ipf_frag_nat_deref __P((ipf_main_softc_t *, void *)); +extern int ipf_frag_nat_next __P((ipf_main_softc_t *, ipftoken_t *, + ipfgeniter_t *)); +extern void ipf_slowtimer __P((ipf_main_softc_t *)); #endif /* __IP_FRAG_H__ */ diff --git a/sys/contrib/ipfilter/netinet/ip_ftp_pxy.c b/sys/contrib/ipfilter/netinet/ip_ftp_pxy.c index f56a69044337..ff8397678dee 100644 --- a/sys/contrib/ipfilter/netinet/ip_ftp_pxy.c +++ b/sys/contrib/ipfilter/netinet/ip_ftp_pxy.c @@ -1,7 +1,7 @@ /* $FreeBSD$ */ /* - * Copyright (C) 1997-2003 by Darren Reed + * Copyright (C) 2012 by Darren Reed. * * See the IPFILTER.LICENCE file for details on licencing. * @@ -15,6 +15,7 @@ #define IPF_FTP_PROXY #define IPF_MINPORTLEN 18 +#define IPF_MINEPRTLEN 20 #define IPF_MAXPORTLEN 30 #define IPF_MIN227LEN 39 #define IPF_MAX227LEN 51 @@ -38,93 +39,197 @@ #define FTPXY_PASS_2 14 #define FTPXY_PAOK_2 15 +#define FTPXY_JUNK_OK 0 +#define FTPXY_JUNK_BAD 1 /* Ignore all commands for this connection */ +#define FTPXY_JUNK_EOL 2 /* consume the rest of this line only */ +#define FTPXY_JUNK_CONT 3 /* Saerching for next numeric */ + /* * Values for FTP commands. Numerics cover 0-999 */ #define FTPXY_C_PASV 1000 - -int ippr_ftp_client __P((fr_info_t *, ip_t *, nat_t *, ftpinfo_t *, int)); -int ippr_ftp_complete __P((char *, size_t)); -int ippr_ftp_in __P((fr_info_t *, ap_session_t *, nat_t *)); -int ippr_ftp_init __P((void)); -void ippr_ftp_fini __P((void)); -int ippr_ftp_new __P((fr_info_t *, ap_session_t *, nat_t *)); -int ippr_ftp_out __P((fr_info_t *, ap_session_t *, nat_t *)); -int ippr_ftp_pasv __P((fr_info_t *, ip_t *, nat_t *, ftpinfo_t *, int)); -int ippr_ftp_epsv __P((fr_info_t *, ip_t *, nat_t *, ftpside_t *, int)); -int ippr_ftp_port __P((fr_info_t *, ip_t *, nat_t *, ftpside_t *, int)); -int ippr_ftp_process __P((fr_info_t *, nat_t *, ftpinfo_t *, int)); -int ippr_ftp_server __P((fr_info_t *, ip_t *, nat_t *, ftpinfo_t *, int)); -int ippr_ftp_valid __P((ftpinfo_t *, int, char *, size_t)); -int ippr_ftp_server_valid __P((ftpside_t *, char *, size_t)); -int ippr_ftp_client_valid __P((ftpside_t *, char *, size_t)); -u_short ippr_ftp_atoi __P((char **)); -int ippr_ftp_pasvreply __P((fr_info_t *, ip_t *, nat_t *, ftpside_t *, - u_int, char *, char *, u_int)); +#define FTPXY_C_PORT 1001 +#define FTPXY_C_EPSV 1002 +#define FTPXY_C_EPRT 1003 -int ftp_proxy_init = 0; -int ippr_ftp_pasvonly = 0; -int ippr_ftp_insecure = 0; /* Do not require logins before transfers */ -int ippr_ftp_pasvrdr = 0; -int ippr_ftp_forcepasv = 0; /* PASV must be last command prior to 227 */ -#if defined(_KERNEL) -int ippr_ftp_debug = 0; -#else -int ippr_ftp_debug = 2; -#endif +typedef struct ipf_ftp_softc_s { + int ipf_p_ftp_pasvonly; + /* Do not require logins before transfers */ + int ipf_p_ftp_insecure; + int ipf_p_ftp_pasvrdr; + /* PASV must be last command prior to 227 */ + int ipf_p_ftp_forcepasv; + int ipf_p_ftp_debug; + int ipf_p_ftp_single_xfer; + void *ipf_p_ftp_tune; +} ipf_ftp_softc_t; + + +void ipf_p_ftp_main_load __P((void)); +void ipf_p_ftp_main_unload __P((void)); +void *ipf_p_ftp_soft_create __P((ipf_main_softc_t *)); +void ipf_p_ftp_soft_destroy __P((ipf_main_softc_t *, void *)); + +int ipf_p_ftp_client __P((ipf_ftp_softc_t *, fr_info_t *, ip_t *, nat_t *, + ftpinfo_t *, int)); +int ipf_p_ftp_complete __P((char *, size_t)); +int ipf_p_ftp_in __P((void *, fr_info_t *, ap_session_t *, nat_t *)); +int ipf_p_ftp_new __P((void *, fr_info_t *, ap_session_t *, nat_t *)); +void ipf_p_ftp_del __P((ipf_main_softc_t *, ap_session_t *)); +int ipf_p_ftp_out __P((void *, fr_info_t *, ap_session_t *, nat_t *)); +int ipf_p_ftp_pasv __P((ipf_ftp_softc_t *, fr_info_t *, ip_t *, nat_t *, + ftpinfo_t *, int)); +int ipf_p_ftp_epsv __P((ipf_ftp_softc_t *, fr_info_t *, ip_t *, nat_t *, + ftpinfo_t *, int)); +int ipf_p_ftp_port __P((ipf_ftp_softc_t *, fr_info_t *, ip_t *, nat_t *, + ftpinfo_t *, int)); +int ipf_p_ftp_process __P((ipf_ftp_softc_t *, fr_info_t *, nat_t *, + ftpinfo_t *, int)); +int ipf_p_ftp_server __P((ipf_ftp_softc_t *, fr_info_t *, ip_t *, nat_t *, + ftpinfo_t *, int)); +int ipf_p_ftp_valid __P((ipf_ftp_softc_t *, ftpinfo_t *, int, char *, size_t)); +int ipf_p_ftp_server_valid __P((ipf_ftp_softc_t *, ftpside_t *, char *, + size_t)); +int ipf_p_ftp_client_valid __P((ipf_ftp_softc_t *, ftpside_t *, char *, + size_t)); +u_short ipf_p_ftp_atoi __P((char **)); +int ipf_p_ftp_pasvreply __P((ipf_ftp_softc_t *, fr_info_t *, ip_t *, nat_t *, + ftpinfo_t *, u_int, char *, char *)); +int ipf_p_ftp_eprt __P((ipf_ftp_softc_t *, fr_info_t *, ip_t *, nat_t *, + ftpinfo_t *, int)); +int ipf_p_ftp_eprt4 __P((ipf_ftp_softc_t *, fr_info_t *, ip_t *, nat_t *, + ftpinfo_t *, int)); +int ipf_p_ftp_eprt6 __P((ipf_ftp_softc_t *, fr_info_t *, ip_t *, nat_t *, + ftpinfo_t *, int)); +int ipf_p_ftp_addport __P((ipf_ftp_softc_t *, fr_info_t *, ip_t *, nat_t *, + ftpinfo_t *, int, int, int)); +void ipf_p_ftp_setpending __P((ipf_main_softc_t *, ftpinfo_t *)); + /* - * 1 - security - * 2 - errors - * 3 - error debugging - * 4 - parsing errors - * 5 - parsing info - * 6 - parsing debug + * Debug levels */ +#define DEBUG_SECURITY 0x01 +#define DEBUG_ERROR 0x02 +#define DEBUG_INFO 0x04 +#define DEBUG_PARSE_ERR 0x08 +#define DEBUG_PARSE_INFO 0x10 +#define DEBUG_PARSE 0x20 +static int ipf_p_ftp_proxy_init = 0; static frentry_t ftppxyfr; -static ipftuneable_t ftptune = { - { &ippr_ftp_debug }, - "ippr_ftp_debug", - 0, - 10, - sizeof(ippr_ftp_debug), - 0, - NULL +static ipftuneable_t ipf_ftp_tuneables[] = { + { { (void *)offsetof(ipf_ftp_softc_t, ipf_p_ftp_debug) }, + "ftp_debug", 0, 0x7f, + stsizeof(ipf_ftp_softc_t, ipf_p_ftp_debug), + 0, NULL, NULL }, + { { (void *)offsetof(ipf_ftp_softc_t, ipf_p_ftp_pasvonly) }, + "ftp_pasvonly", 0, 1, + stsizeof(ipf_ftp_softc_t, ipf_p_ftp_pasvonly), + 0, NULL, NULL }, + { { (void *)offsetof(ipf_ftp_softc_t, ipf_p_ftp_insecure) }, + "ftp_insecure", 0, 1, + stsizeof(ipf_ftp_softc_t, ipf_p_ftp_insecure), + 0, NULL, NULL }, + { { (void *)offsetof(ipf_ftp_softc_t, ipf_p_ftp_pasvrdr) }, + "ftp_pasvrdr", 0, 1, + stsizeof(ipf_ftp_softc_t, ipf_p_ftp_pasvrdr), + 0, NULL, NULL }, + { { (void *)offsetof(ipf_ftp_softc_t, ipf_p_ftp_forcepasv) }, + "ftp_forcepasv", 0, 1, + stsizeof(ipf_ftp_softc_t, ipf_p_ftp_forcepasv), + 0, NULL, NULL }, + { { (void *)offsetof(ipf_ftp_softc_t, ipf_p_ftp_single_xfer) }, + "ftp_single_xfer", 0, 1, + stsizeof(ipf_ftp_softc_t, ipf_p_ftp_single_xfer), + 0, NULL, NULL }, + { { NULL }, NULL, 0, 0, 0, 0, NULL, NULL } }; +void +ipf_p_ftp_main_load() +{ + bzero((char *)&ftppxyfr, sizeof(ftppxyfr)); + ftppxyfr.fr_ref = 1; + ftppxyfr.fr_flags = FR_INQUE|FR_PASS|FR_QUICK|FR_KEEPSTATE; + + MUTEX_INIT(&ftppxyfr.fr_lock, "FTP Proxy Mutex"); + ipf_p_ftp_proxy_init = 1; +} + + +void +ipf_p_ftp_main_unload() +{ + + if (ipf_p_ftp_proxy_init == 1) { + MUTEX_DESTROY(&ftppxyfr.fr_lock); + ipf_p_ftp_proxy_init = 0; + } +} + + /* * Initialize local structures. */ -int ippr_ftp_init() +void * +ipf_p_ftp_soft_create(softc) + ipf_main_softc_t *softc; { - bzero((char *)&ftppxyfr, sizeof(ftppxyfr)); - ftppxyfr.fr_ref = 1; - ftppxyfr.fr_flags = FR_INQUE|FR_PASS|FR_QUICK|FR_KEEPSTATE; - MUTEX_INIT(&ftppxyfr.fr_lock, "FTP Proxy Mutex"); - ftp_proxy_init = 1; - (void) fr_addipftune(&ftptune); + ipf_ftp_softc_t *softf; - return 0; -} + KMALLOC(softf, ipf_ftp_softc_t *); + if (softf == NULL) + return NULL; + bzero((char *)softf, sizeof(*softf)); +#if defined(_KERNEL) + softf->ipf_p_ftp_debug = 0; +#else + softf->ipf_p_ftp_debug = DEBUG_PARSE_ERR; +#endif + softf->ipf_p_ftp_forcepasv = 1; -void ippr_ftp_fini() -{ - (void) fr_delipftune(&ftptune); - - if (ftp_proxy_init == 1) { - MUTEX_DESTROY(&ftppxyfr.fr_lock); - ftp_proxy_init = 0; + softf->ipf_p_ftp_tune = ipf_tune_array_copy(softf, + sizeof(ipf_ftp_tuneables), + ipf_ftp_tuneables); + if (softf->ipf_p_ftp_tune == NULL) { + ipf_p_ftp_soft_destroy(softc, softf); + return NULL; } + if (ipf_tune_array_link(softc, softf->ipf_p_ftp_tune) == -1) { + ipf_p_ftp_soft_destroy(softc, softf); + return NULL; + } + + return softf; } -int ippr_ftp_new(fin, aps, nat) -fr_info_t *fin; -ap_session_t *aps; -nat_t *nat; +void +ipf_p_ftp_soft_destroy(softc, arg) + ipf_main_softc_t *softc; + void *arg; +{ + ipf_ftp_softc_t *softf = arg; + + if (softf->ipf_p_ftp_tune != NULL) { + ipf_tune_array_unlink(softc, softf->ipf_p_ftp_tune); + KFREES(softf->ipf_p_ftp_tune, sizeof(ipf_ftp_tuneables)); + softf->ipf_p_ftp_tune = NULL; + } + + KFREE(softf); +} + + +int +ipf_p_ftp_new(arg, fin, aps, nat) + void *arg; + fr_info_t *fin; + ap_session_t *aps; + nat_t *nat; { ftpinfo_t *ftp; ftpside_t *f; @@ -133,11 +238,12 @@ nat_t *nat; if (ftp == NULL) return -1; - fin = fin; /* LINT */ nat = nat; /* LINT */ aps->aps_data = ftp; aps->aps_psiz = sizeof(ftpinfo_t); + aps->aps_sport = htons(fin->fin_sport); + aps->aps_dport = htons(fin->fin_dport); bzero((char *)ftp, sizeof(*ftp)); f = &ftp->ftp_side[0]; @@ -152,25 +258,53 @@ nat_t *nat; } -int ippr_ftp_port(fin, ip, nat, f, dlen) -fr_info_t *fin; -ip_t *ip; -nat_t *nat; -ftpside_t *f; -int dlen; +void +ipf_p_ftp_setpending(ipf_main_softc_t *softc, ftpinfo_t *ftp) +{ + if (ftp->ftp_pendnat != NULL) + ipf_nat_setpending(softc, ftp->ftp_pendnat); + + if (ftp->ftp_pendstate != NULL) { + READ_ENTER(&softc->ipf_state); + ipf_state_setpending(softc, ftp->ftp_pendstate); + RWLOCK_EXIT(&softc->ipf_state); + } +} + + +void +ipf_p_ftp_del(softc, aps) + ipf_main_softc_t *softc; + ap_session_t *aps; +{ + ftpinfo_t *ftp; + + ftp = aps->aps_data; + if (ftp != NULL) + ipf_p_ftp_setpending(softc, ftp); +} + + +int +ipf_p_ftp_port(softf, fin, ip, nat, ftp, dlen) + ipf_ftp_softc_t *softf; + fr_info_t *fin; + ip_t *ip; + nat_t *nat; + ftpinfo_t *ftp; + int dlen; { - tcphdr_t *tcp, tcph, *tcp2 = &tcph; char newbuf[IPF_FTPBUFSZ], *s; - struct in_addr swip, swip2; u_int a1, a2, a3, a4; - int inc, off, flags; u_short a5, a6, sp; size_t nlen, olen; - fr_info_t fi; - nat_t *nat2; + tcphdr_t *tcp; + int inc, off; + ftpside_t *f; mb_t *m; m = fin->fin_m; + f = &ftp->ftp_side[0]; tcp = (tcphdr_t *)fin->fin_dp; off = (char *)tcp - (char *)ip + (TCP_OFF(tcp) << 2) + fin->fin_ipoff; @@ -178,8 +312,10 @@ int dlen; * Check for client sending out PORT message. */ if (dlen < IPF_MINPORTLEN) { - if (ippr_ftp_debug > 1) - printf("ippr_ftp_port:dlen(%d) < IPF_MINPORTLEN\n", + DT3(ftp_PORT_error_dlen, nat_t *, nat, ftpside_t *, f, + u_int, dlen); + if (softf->ipf_p_ftp_debug & DEBUG_PARSE) + printf("ipf_p_ftp_port:dlen(%d) < IPF_MINPORTLEN\n", dlen); return 0; } @@ -190,16 +326,18 @@ int dlen; /* * Pick out the address components, two at a time. */ - a1 = ippr_ftp_atoi(&s); + a1 = ipf_p_ftp_atoi(&s); if (s == NULL) { - if (ippr_ftp_debug > 1) - printf("ippr_ftp_port:ippr_ftp_atoi(%d) failed\n", 1); + DT2(ftp_PORT_error_atoi_1, nat_t *, nat, ftpside_t *, f); + if (softf->ipf_p_ftp_debug & DEBUG_PARSE_ERR) + printf("ipf_p_ftp_port:ipf_p_ftp_atoi(%d) failed\n", 1); return 0; } - a2 = ippr_ftp_atoi(&s); + a2 = ipf_p_ftp_atoi(&s); if (s == NULL) { - if (ippr_ftp_debug > 1) - printf("ippr_ftp_port:ippr_ftp_atoi(%d) failed\n", 2); + DT2(ftp_PORT_error_atoi_2, nat_t *, nat, ftpside_t *, f); + if (softf->ipf_p_ftp_debug & DEBUG_PARSE_ERR) + printf("ipf_p_ftp_port:ipf_p_ftp_atoi(%d) failed\n", 2); return 0; } @@ -210,18 +348,21 @@ int dlen; a1 <<= 16; a1 |= a2; if (((nat->nat_dir == NAT_OUTBOUND) && - (a1 != ntohl(nat->nat_inip.s_addr))) || + (a1 != ntohl(nat->nat_osrcaddr))) || ((nat->nat_dir == NAT_INBOUND) && - (a1 != ntohl(nat->nat_oip.s_addr)))) { - if (ippr_ftp_debug > 0) - printf("ippr_ftp_port:%s != nat->nat_inip\n", "a1"); + (a1 != ntohl(nat->nat_nsrcaddr)))) { + DT3(ftp_PORT_error_address, nat_t *, nat, ftpside_t *, f, + u_int, a1); + if (softf->ipf_p_ftp_debug & DEBUG_ERROR) + printf("ipf_p_ftp_port:%s != nat->nat_inip\n", "a1"); return APR_ERR(1); } - a5 = ippr_ftp_atoi(&s); + a5 = ipf_p_ftp_atoi(&s); if (s == NULL) { - if (ippr_ftp_debug > 1) - printf("ippr_ftp_port:ippr_ftp_atoi(%d) failed\n", 3); + DT2(ftp_PORT_error_atoi_3, nat_t *, nat, ftpside_t *, f); + if (softf->ipf_p_ftp_debug & DEBUG_PARSE_ERR) + printf("ipf_p_ftp_port:ipf_p_ftp_atoi(%d) failed\n", 3); return 0; } if (*s == ')') @@ -232,34 +373,31 @@ int dlen; */ if (*s == '\n') s--; - if ((*s == '\r') && (*(s + 1) == '\n')) { - s += 2; - a6 = a5 & 0xff; - } else { - if (ippr_ftp_debug > 1) - printf("ippr_ftp_port:missing %s\n", "cr-lf"); + if ((*s != '\r') || (*(s + 1) != '\n')) { + DT2(ftp_PORT_error_no_crlf, nat_t *, nat, ftpside_t *, f); + if (softf->ipf_p_ftp_debug & DEBUG_PARSE_ERR) + printf("ipf_p_ftp_port:missing %s\n", "cr-lf"); return 0; } + s += 2; + a6 = a5 & 0xff; + /* + * Calculate the source port. Verification of > 1024 is in + * ipf_p_ftp_addport. + */ a5 >>= 8; a5 &= 0xff; sp = a5 << 8 | a6; - /* - * Don't allow the PORT command to specify a port < 1024 due to - * security crap. - */ - if (sp < 1024) { - if (ippr_ftp_debug > 0) - printf("ippr_ftp_port:sp(%d) < 1024\n", sp); - return 0; - } + /* * Calculate new address parts for PORT command */ if (nat->nat_dir == NAT_INBOUND) - a1 = ntohl(nat->nat_oip.s_addr); + a1 = ntohl(nat->nat_ndstaddr); else a1 = ntohl(ip->ip_src.s_addr); + a1 = ntohl(ip->ip_src.s_addr); a2 = (a1 >> 16) & 0xff; a3 = (a1 >> 8) & 0xff; a4 = a1 & 0xff; @@ -276,117 +414,213 @@ int dlen; nlen = strlen(newbuf); inc = nlen - olen; - if ((inc + ip->ip_len) > 65535) { - if (ippr_ftp_debug > 0) - printf("ippr_ftp_port:inc(%d) + ip->ip_len > 65535\n", + if ((inc + fin->fin_plen) > 65535) { + DT3(ftp_PORT_error_inc, nat_t *, nat, ftpside_t *, f, + int, inc); + if (softf->ipf_p_ftp_debug & DEBUG_ERROR) + printf("ipf_p_ftp_port:inc(%d) + ip->ip_len > 65535\n", inc); return 0; } #if !defined(_KERNEL) - bcopy(newbuf, MTOD(m, char *) + off, nlen); + M_ADJ(m, inc); #else -# if defined(MENTAT) - if (inc < 0) - (void)adjmsg(m, inc); -# else /* defined(MENTAT) */ /* * m_adj takes care of pkthdr.len, if required and treats inc<0 to * mean remove -len bytes from the end of the packet. * The mbuf chain will be extended if necessary by m_copyback(). */ if (inc < 0) - m_adj(m, inc); -# endif /* defined(MENTAT) */ + M_ADJ(m, inc); #endif /* !defined(_KERNEL) */ COPYBACK(m, off, nlen, newbuf); + fin->fin_flx |= FI_DOCKSUM; if (inc != 0) { - ip->ip_len += inc; - fin->fin_dlen += inc; fin->fin_plen += inc; + ip->ip_len = htons(fin->fin_plen); + fin->fin_dlen += inc; } + f->ftps_cmd = FTPXY_C_PORT; + return ipf_p_ftp_addport(softf, fin, ip, nat, ftp, dlen, sp, inc); +} + + +int +ipf_p_ftp_addport(softf, fin, ip, nat, ftp, dlen, nport, inc) + ipf_ftp_softc_t *softf; + fr_info_t *fin; + ip_t *ip; + nat_t *nat; + ftpinfo_t *ftp; + int dlen, nport, inc; +{ + tcphdr_t tcph, *tcp2 = &tcph; + ipf_main_softc_t *softc; + ipf_nat_softc_t *softn; + int direction; + fr_info_t fi; + ipnat_t *ipn; + nat_t *nat2; + u_short sp; + int flags; + + softc = fin->fin_main_soft; + softn = softc->ipf_nat_soft; + + if ((ftp->ftp_pendnat != NULL) || (ftp->ftp_pendstate != NULL)) { + if (softf->ipf_p_ftp_single_xfer != 0) { + DT2(ftp_PORT_error_add_active, nat_t *, nat, + ftpinfo_t *, ftp); + if (softf->ipf_p_ftp_debug & DEBUG_ERROR) + printf("ipf_p_ftp_addport:xfer active %p/%p\n", + ftp->ftp_pendnat, ftp->ftp_pendstate); + return 0; + } + ipf_p_ftp_setpending(softc, ftp); + } + + /* + * Add skeleton NAT entry for connection which will come back the + * other way. + */ + sp = nport; + /* + * Don't allow the PORT command to specify a port < 1024 due to + * security risks. + */ + if (sp < 1024) { + DT3(ftp_PORT_error_port, nat_t *, nat, ftpinfo_t *, ftp, + u_int, sp); + if (softf->ipf_p_ftp_debug & DEBUG_SECURITY) + printf("ipf_p_ftp_addport:sp(%d) < 1024\n", sp); + return 0; + } /* * The server may not make the connection back from port 20, but * it is the most likely so use it here to check for a conflicting * mapping. */ bcopy((char *)fin, (char *)&fi, sizeof(fi)); - fi.fin_state = NULL; - fi.fin_nat = NULL; fi.fin_flx |= FI_IGNORE; fi.fin_data[0] = sp; fi.fin_data[1] = fin->fin_data[1] - 1; + fi.fin_src6 = nat->nat_ndst6; + fi.fin_dst6 = nat->nat_nsrc6; + + if (nat->nat_v[0] == 6) { +#ifndef USE_INET6 + return APR_INC(inc); +#endif + } + /* * Add skeleton NAT entry for connection which will come back the * other way. */ - if (nat->nat_dir == NAT_OUTBOUND) - nat2 = nat_outlookup(&fi, NAT_SEARCH|IPN_TCP, nat->nat_p, - nat->nat_inip, nat->nat_oip); - else - nat2 = nat_inlookup(&fi, NAT_SEARCH|IPN_TCP, nat->nat_p, - nat->nat_inip, nat->nat_oip); - if (nat2 == NULL) { - int slen; - - slen = ip->ip_len; - ip->ip_len = fin->fin_hlen + sizeof(*tcp2); - bzero((char *)tcp2, sizeof(*tcp2)); - tcp2->th_win = htons(8192); - tcp2->th_sport = htons(sp); - TCP_OFF_A(tcp2, 5); - tcp2->th_flags = TH_SYN; - tcp2->th_dport = 0; /* XXX - don't specify remote port */ - fi.fin_data[1] = 0; - fi.fin_dlen = sizeof(*tcp2); - fi.fin_plen = fi.fin_hlen + sizeof(*tcp2); - fi.fin_dp = (char *)tcp2; - fi.fin_fr = &ftppxyfr; - fi.fin_out = nat->nat_dir; - fi.fin_flx &= FI_LOWTTL|FI_FRAG|FI_TCPUDP|FI_OPTIONS|FI_IGNORE; - swip = ip->ip_src; - swip2 = ip->ip_dst; +#ifdef USE_INET6 + if (nat->nat_v[0] == 6) { if (nat->nat_dir == NAT_OUTBOUND) { - fi.fin_fi.fi_saddr = nat->nat_inip.s_addr; - ip->ip_src = nat->nat_inip; - } else if (nat->nat_dir == NAT_INBOUND) { - fi.fin_fi.fi_saddr = nat->nat_oip.s_addr; - ip->ip_src = nat->nat_oip; + nat2 = ipf_nat6_outlookup(&fi, IPN_TCP|NAT_SEARCH, + nat->nat_pr[1], + &nat->nat_osrc6.in6, + &nat->nat_odst6.in6); + } else { + nat2 = ipf_nat6_inlookup(&fi, IPN_TCP|NAT_SEARCH, + nat->nat_pr[0], + &nat->nat_odst6.in6, + &nat->nat_osrc6.in6); } - - flags = NAT_SLAVE|IPN_TCP|SI_W_DPORT; - if (nat->nat_dir == NAT_INBOUND) - flags |= NAT_NOTRULEPORT; - nat2 = nat_new(&fi, nat->nat_ptr, NULL, flags, nat->nat_dir); - - if (nat2 != NULL) { - (void) nat_proto(&fi, nat2, IPN_TCP); - nat_update(&fi, nat2, nat->nat_ptr); - fi.fin_ifp = NULL; - if (nat->nat_dir == NAT_INBOUND) { - fi.fin_fi.fi_daddr = nat->nat_inip.s_addr; - ip->ip_dst = nat->nat_inip; - } - (void) fr_addstate(&fi, NULL, SI_W_DPORT); - if (fi.fin_state != NULL) - fr_statederef((ipstate_t **)&fi.fin_state); + } else +#endif + { + if (nat->nat_dir == NAT_OUTBOUND) { + nat2 = ipf_nat_outlookup(&fi, IPN_TCP|NAT_SEARCH, + nat->nat_pr[1], + nat->nat_osrcip, + nat->nat_odstip); + } else { + nat2 = ipf_nat_inlookup(&fi, IPN_TCP|NAT_SEARCH, + nat->nat_pr[0], + nat->nat_odstip, + nat->nat_osrcip); } - ip->ip_len = slen; - ip->ip_src = swip; - ip->ip_dst = swip2; } + if (nat2 != NULL) + return APR_INC(inc); + + ipn = ipf_proxy_rule_rev(nat); + if (ipn == NULL) + return APR_ERR(1); + ipn->in_use = 0; + + fi.fin_fr = &ftppxyfr; + fi.fin_dp = (char *)tcp2; + fi.fin_dlen = sizeof(*tcp2); + fi.fin_plen = fi.fin_hlen + sizeof(*tcp2); + fi.fin_flx &= FI_LOWTTL|FI_FRAG|FI_TCPUDP|FI_OPTIONS|FI_IGNORE; + fi.fin_data[1] = sp; + fi.fin_data[0] = 0; + + bzero((char *)tcp2, sizeof(*tcp2)); + tcp2->th_sport = 0; + tcp2->th_dport = htons(sp); + + tcp2->th_win = htons(8192); + TCP_OFF_A(tcp2, 5); + tcp2->th_flags = TH_SYN; + + if (nat->nat_dir == NAT_INBOUND) { + fi.fin_out = 1; + direction = NAT_OUTBOUND; + } else { + fi.fin_out = 0; + direction = NAT_INBOUND; + } + flags = SI_W_SPORT|NAT_SLAVE|IPN_TCP; + + MUTEX_ENTER(&softn->ipf_nat_new); + if (nat->nat_v[0] == 6) { +#ifdef USE_INET6 + nat2 = ipf_nat6_add(&fi, ipn, &ftp->ftp_pendnat, flags, + direction); +#endif + } else { + nat2 = ipf_nat_add(&fi, ipn, &ftp->ftp_pendnat, flags, + direction); + } + MUTEX_EXIT(&softn->ipf_nat_new); + + if (nat2 == NULL) { + KFREES(ipn, ipn->in_size); + return APR_ERR(1); + } + + (void) ipf_nat_proto(&fi, nat2, IPN_TCP); + MUTEX_ENTER(&nat2->nat_lock); + ipf_nat_update(&fi, nat2); + MUTEX_EXIT(&nat2->nat_lock); + fi.fin_ifp = NULL; + if (nat2->nat_dir == NAT_INBOUND) + fi.fin_dst6 = nat->nat_osrc6; + if (ipf_state_add(softc, &fi, (ipstate_t **)&ftp->ftp_pendstate, + SI_W_SPORT) != 0) + ipf_nat_setpending(softc, nat2); + return APR_INC(inc); } -int ippr_ftp_client(fin, ip, nat, ftp, dlen) -fr_info_t *fin; -nat_t *nat; -ftpinfo_t *ftp; -ip_t *ip; -int dlen; +int +ipf_p_ftp_client(softf, fin, ip, nat, ftp, dlen) + ipf_ftp_softc_t *softf; + fr_info_t *fin; + nat_t *nat; + ftpinfo_t *ftp; + ip_t *ip; + int dlen; { char *rptr, *wptr, cmd[6], c; ftpside_t *f; @@ -408,6 +642,7 @@ int dlen; cmd[i] = '\0'; ftp->ftp_incok = 0; + DT2(ftp_client_command, char [], cmd, int, ftp->ftp_passok); if (!strncmp(cmd, "USER ", 5) || !strncmp(cmd, "XAUT ", 5)) { if (ftp->ftp_passok == FTPXY_ADOK_1 || ftp->ftp_passok == FTPXY_AUOK_1) { @@ -437,14 +672,24 @@ int dlen; !strncmp(cmd, "ACCT ", 5)) { ftp->ftp_passok = FTPXY_ACCT_1; ftp->ftp_incok = 1; - } else if ((ftp->ftp_passok == FTPXY_GO) && !ippr_ftp_pasvonly && + } else if ((ftp->ftp_passok == FTPXY_GO) && + !softf->ipf_p_ftp_pasvonly && !strncmp(cmd, "PORT ", 5)) { - inc = ippr_ftp_port(fin, ip, nat, f, dlen); - } else if (ippr_ftp_insecure && !ippr_ftp_pasvonly && + inc = ipf_p_ftp_port(softf, fin, ip, nat, ftp, dlen); + } else if ((ftp->ftp_passok == FTPXY_GO) && + !softf->ipf_p_ftp_pasvonly && + !strncmp(cmd, "EPRT ", 5)) { + inc = ipf_p_ftp_eprt(softf, fin, ip, nat, ftp, dlen); + } else if (softf->ipf_p_ftp_insecure && + !softf->ipf_p_ftp_pasvonly && !strncmp(cmd, "PORT ", 5)) { - inc = ippr_ftp_port(fin, ip, nat, f, dlen); + inc = ipf_p_ftp_port(softf, fin, ip, nat, ftp, dlen); } + if (softf->ipf_p_ftp_debug & DEBUG_PARSE) + printf("ipf_p_ftp_client: cmd[%s] passok %d incok %d inc %d\n", + cmd, ftp->ftp_passok, ftp->ftp_incok, inc); + DT2(ftp_client_passok, char *, cmd, int, ftp->ftp_passok); while ((*rptr++ != '\n') && (rptr < wptr)) ; f->ftps_rptr = rptr; @@ -452,12 +697,14 @@ int dlen; } -int ippr_ftp_pasv(fin, ip, nat, ftp, dlen) -fr_info_t *fin; -ip_t *ip; -nat_t *nat; -ftpinfo_t *ftp; -int dlen; +int +ipf_p_ftp_pasv(softf, fin, ip, nat, ftp, dlen) + ipf_ftp_softc_t *softf; + fr_info_t *fin; + ip_t *ip; + nat_t *nat; + ftpinfo_t *ftp; + int dlen; { u_int a1, a2, a3, a4, data_ip; char newbuf[IPF_FTPBUFSZ]; @@ -466,11 +713,12 @@ int dlen; ftpside_t *f; char *s; - if (ippr_ftp_forcepasv != 0 && - ftp->ftp_side[0].ftps_cmds != FTPXY_C_PASV) { - if (ippr_ftp_debug > 0) - printf("ippr_ftp_pasv:ftps_cmds(%d) != FTPXY_C_PASV\n", - ftp->ftp_side[0].ftps_cmds); + if ((softf->ipf_p_ftp_forcepasv != 0) && + (ftp->ftp_side[0].ftps_cmd != FTPXY_C_PASV)) { + DT2(ftp_PASV_error_state, nat_t *, nat, ftpinfo_t *, ftp); + if (softf->ipf_p_ftp_debug & DEBUG_ERROR) + printf("ipf_p_ftp_pasv:ftps_cmd(%d) != FTPXY_C_PASV\n", + ftp->ftp_side[0].ftps_cmd); return 0; } @@ -481,14 +729,17 @@ int dlen; * Check for PASV reply message. */ if (dlen < IPF_MIN227LEN) { - if (ippr_ftp_debug > 1) - printf("ippr_ftp_pasv:dlen(%d) < IPF_MIN227LEN\n", + DT3(ftp_PASV_error_short, nat_t *, nat, ftpinfo_t *, ftp, + int, dlen); + if (softf->ipf_p_ftp_debug & DEBUG_ERROR) + printf("ipf_p_ftp_pasv:dlen(%d) < IPF_MIN227LEN\n", dlen); return 0; } else if (strncmp(f->ftps_rptr, "227 Entering Passive Mod", PASV_REPLEN)) { - if (ippr_ftp_debug > 0) - printf("ippr_ftp_pasv:%d reply wrong\n", 227); + DT2(ftp_PASV_error_string, nat_t *, nat, ftpinfo_t *, ftp); + if (softf->ipf_p_ftp_debug & DEBUG_PARSE_ERR) + printf("ipf_p_ftp_pasv:%d reply wrong\n", 227); return 0; } @@ -509,16 +760,18 @@ int dlen; /* * Pick out the address components, two at a time. */ - a1 = ippr_ftp_atoi(&s); + a1 = ipf_p_ftp_atoi(&s); if (s == NULL) { - if (ippr_ftp_debug > 1) - printf("ippr_ftp_pasv:ippr_ftp_atoi(%d) failed\n", 1); + DT2(ftp_PASV_error_atoi_1, nat_t *, nat, ftpside_t *, f); + if (softf->ipf_p_ftp_debug & DEBUG_PARSE_ERR) + printf("ipf_p_ftp_pasv:ipf_p_ftp_atoi(%d) failed\n", 1); return 0; } - a2 = ippr_ftp_atoi(&s); + a2 = ipf_p_ftp_atoi(&s); if (s == NULL) { - if (ippr_ftp_debug > 1) - printf("ippr_ftp_pasv:ippr_ftp_atoi(%d) failed\n", 2); + DT2(ftp_PASV_error_atoi_2, nat_t *, nat, ftpside_t *, f); + if (softf->ipf_p_ftp_debug & DEBUG_PARSE_ERR) + printf("ipf_p_ftp_pasv:ipf_p_ftp_atoi(%d) failed\n", 2); return 0; } @@ -530,18 +783,21 @@ int dlen; a1 |= a2; if (((nat->nat_dir == NAT_INBOUND) && - (a1 != ntohl(nat->nat_inip.s_addr))) || + (a1 != ntohl(nat->nat_ndstaddr))) || ((nat->nat_dir == NAT_OUTBOUND) && - (a1 != ntohl(nat->nat_oip.s_addr)))) { - if (ippr_ftp_debug > 0) - printf("ippr_ftp_pasv:%s != nat->nat_oip\n", "a1"); + (a1 != ntohl(nat->nat_odstaddr)))) { + DT3(ftp_PASV_error_address, nat_t *, nat, ftpside_t *, f, + u_int, a1); + if (softf->ipf_p_ftp_debug & DEBUG_ERROR) + printf("ipf_p_ftp_pasv:%s != nat->nat_oip\n", "a1"); return 0; } - a5 = ippr_ftp_atoi(&s); + a5 = ipf_p_ftp_atoi(&s); if (s == NULL) { - if (ippr_ftp_debug > 1) - printf("ippr_ftp_pasv:ippr_ftp_atoi(%d) failed\n", 3); + DT2(ftp_PASV_error_atoi_3, nat_t *, nat, ftpside_t *, f); + if (softf->ipf_p_ftp_debug & DEBUG_PARSE_ERR) + printf("ipf_p_ftp_pasv:ipf_p_ftp_atoi(%d) failed\n", 3); return 0; } @@ -554,13 +810,13 @@ int dlen; /* * check for CR-LF at the end. */ - if ((*s == '\r') && (*(s + 1) == '\n')) { - s += 2; - } else { - if (ippr_ftp_debug > 1) - printf("ippr_ftp_pasv:missing %s", "cr-lf\n"); + if ((*s != '\r') || (*(s + 1) != '\n')) { + DT(pasv_missing_crlf); + if (softf->ipf_p_ftp_debug & DEBUG_PARSE_ERR) + printf("ipf_p_ftp_pasv:missing %s", "cr-lf\n"); return 0; } + s += 2; a6 = a5 & 0xff; a5 >>= 8; @@ -568,7 +824,7 @@ int dlen; * Calculate new address parts for 227 reply */ if (nat->nat_dir == NAT_INBOUND) { - data_ip = nat->nat_outip.s_addr; + data_ip = nat->nat_odstaddr; a1 = ntohl(data_ip); } else data_ip = htonl(a1); @@ -587,156 +843,165 @@ int dlen; "227 Entering Passive Mode", brackets[0], a1, a2, a3, a4, a5, a6, brackets[1]); #endif - return ippr_ftp_pasvreply(fin, ip, nat, f, (a5 << 8 | a6), - newbuf, s, data_ip); + return ipf_p_ftp_pasvreply(softf, fin, ip, nat, ftp, (a5 << 8 | a6), + newbuf, s); } -int ippr_ftp_pasvreply(fin, ip, nat, f, port, newmsg, s, data_ip) -fr_info_t *fin; -ip_t *ip; -nat_t *nat; -ftpside_t *f; -u_int port; -char *newmsg; -char *s; -u_int data_ip; +int +ipf_p_ftp_pasvreply(softf, fin, ip, nat, ftp, port, newmsg, s) + ipf_ftp_softc_t *softf; + fr_info_t *fin; + ip_t *ip; + nat_t *nat; + ftpinfo_t *ftp; + u_int port; + char *newmsg; + char *s; { - int inc, off, nflags, sflags; + int inc, off, nflags; tcphdr_t *tcp, tcph, *tcp2; - struct in_addr swip, swip2; - struct in_addr data_addr; + ipf_main_softc_t *softc; + ipf_nat_softc_t *softn; size_t nlen, olen; +#ifdef USE_INET6 + ip6_t *ip6; +#endif + ipnat_t *ipn; fr_info_t fi; + ftpside_t *f; nat_t *nat2; mb_t *m; + softc = fin->fin_main_soft; + softn = softc->ipf_nat_soft; + + if ((ftp->ftp_pendnat != NULL) || (ftp->ftp_pendstate != NULL)) + ipf_p_ftp_setpending(softc, ftp); + m = fin->fin_m; tcp = (tcphdr_t *)fin->fin_dp; off = (char *)tcp - (char *)ip + (TCP_OFF(tcp) << 2) + fin->fin_ipoff; - data_addr.s_addr = data_ip; tcp2 = &tcph; inc = 0; - + f = &ftp->ftp_side[1]; olen = s - f->ftps_rptr; nlen = strlen(newmsg); inc = nlen - olen; - if ((inc + ip->ip_len) > 65535) { - if (ippr_ftp_debug > 0) - printf("ippr_ftp_pasv:inc(%d) + ip->ip_len > 65535\n", + if ((inc + fin->fin_plen) > 65535) { + DT3(ftp_PASV_error_inc, nat_t *, nat, ftpside_t *, f, + int, inc); + if (softf->ipf_p_ftp_debug & DEBUG_ERROR) + printf("ipf_p_ftp_pasv:inc(%d) + ip->ip_len > 65535\n", inc); return 0; } + ipn = ipf_proxy_rule_fwd(nat); + if (ipn == NULL) + return APR_ERR(1); + ipn->in_use = 0; + + /* + * Add skeleton NAT entry for connection which will come back the + * other way. + */ + bzero((char *)tcp2, sizeof(*tcp2)); + bcopy((char *)fin, (char *)&fi, sizeof(fi)); + fi.fin_flx |= FI_IGNORE; + fi.fin_data[0] = 0; + fi.fin_data[1] = port; + nflags = IPN_TCP|SI_W_SPORT; + + fi.fin_fr = &ftppxyfr; + fi.fin_dp = (char *)tcp2; + fi.fin_out = 1 - fin->fin_out; + fi.fin_dlen = sizeof(*tcp2); + fi.fin_src6 = nat->nat_osrc6; + fi.fin_dst6 = nat->nat_odst6; + fi.fin_plen = fi.fin_hlen + sizeof(*tcp); + fi.fin_flx &= FI_LOWTTL|FI_FRAG|FI_TCPUDP|FI_OPTIONS|FI_IGNORE; + + TCP_OFF_A(tcp2, 5); + tcp2->th_flags = TH_SYN; + tcp2->th_win = htons(8192); + tcp2->th_dport = htons(port); + + MUTEX_ENTER(&softn->ipf_nat_new); +#ifdef USE_INET6 + if (nat->nat_v[0] == 6) + nat2 = ipf_nat6_add(&fi, ipn, &ftp->ftp_pendnat, + nflags, nat->nat_dir); + else +#endif + nat2 = ipf_nat_add(&fi, ipn, &ftp->ftp_pendnat, + nflags, nat->nat_dir); + MUTEX_EXIT(&softn->ipf_nat_new); + + if (nat2 == NULL) { + KFREES(ipn, ipn->in_size); + return APR_ERR(1); + } + + (void) ipf_nat_proto(&fi, nat2, IPN_TCP); + MUTEX_ENTER(&nat2->nat_lock); + ipf_nat_update(&fi, nat2); + MUTEX_EXIT(&nat2->nat_lock); + fi.fin_ifp = NULL; + if (nat->nat_dir == NAT_INBOUND) { + if (nat->nat_v[0] == 6) { +#ifdef USE_INET6 + fi.fin_dst6 = nat->nat_ndst6; +#endif + } else { + fi.fin_daddr = nat->nat_ndstaddr; + } + } + if (ipf_state_add(softc, &fi, (ipstate_t **)&ftp->ftp_pendstate, + SI_W_SPORT) != 0) + ipf_nat_setpending(softc, nat2); + #if !defined(_KERNEL) - bcopy(newmsg, MTOD(m, char *) + off, nlen); + M_ADJ(m, inc); #else -# if defined(MENTAT) - if (inc < 0) - (void)adjmsg(m, inc); -# else /* defined(MENTAT) */ /* * m_adj takes care of pkthdr.len, if required and treats inc<0 to * mean remove -len bytes from the end of the packet. * The mbuf chain will be extended if necessary by m_copyback(). */ if (inc < 0) - m_adj(m, inc); -# endif /* defined(MENTAT) */ + M_ADJ(m, inc); #endif /* !defined(_KERNEL) */ COPYBACK(m, off, nlen, newmsg); + fin->fin_flx |= FI_DOCKSUM; if (inc != 0) { - ip->ip_len += inc; - fin->fin_dlen += inc; fin->fin_plen += inc; + fin->fin_dlen += inc; + if (nat->nat_v[0] == 6) { +#ifdef USE_INET6 + ip6 = (ip6_t *)fin->fin_ip; + u_short len = ntohs(ip6->ip6_plen) + inc; + ip6->ip6_plen = htons(len); +#endif + } else { + ip->ip_len = htons(fin->fin_plen); + } } - /* - * Add skeleton NAT entry for connection which will come back the - * other way. - */ - bcopy((char *)fin, (char *)&fi, sizeof(fi)); - fi.fin_state = NULL; - fi.fin_nat = NULL; - fi.fin_flx |= FI_IGNORE; - fi.fin_data[0] = 0; - fi.fin_data[1] = port; - nflags = IPN_TCP|SI_W_SPORT; - if (ippr_ftp_pasvrdr && f->ftps_ifp) - nflags |= SI_W_DPORT; - if (nat->nat_dir == NAT_OUTBOUND) - nat2 = nat_outlookup(&fi, nflags|NAT_SEARCH, - nat->nat_p, nat->nat_inip, nat->nat_oip); - else - nat2 = nat_inlookup(&fi, nflags|NAT_SEARCH, - nat->nat_p, nat->nat_inip, nat->nat_oip); - if (nat2 == NULL) { - int slen; - - slen = ip->ip_len; - ip->ip_len = fin->fin_hlen + sizeof(*tcp2); - bzero((char *)tcp2, sizeof(*tcp2)); - tcp2->th_win = htons(8192); - tcp2->th_sport = 0; /* XXX - fake it for nat_new */ - TCP_OFF_A(tcp2, 5); - tcp2->th_flags = TH_SYN; - fi.fin_data[1] = port; - fi.fin_dlen = sizeof(*tcp2); - tcp2->th_dport = htons(port); - fi.fin_data[0] = 0; - fi.fin_dp = (char *)tcp2; - fi.fin_plen = fi.fin_hlen + sizeof(*tcp); - fi.fin_fr = &ftppxyfr; - fi.fin_out = nat->nat_dir; - fi.fin_flx &= FI_LOWTTL|FI_FRAG|FI_TCPUDP|FI_OPTIONS|FI_IGNORE; - swip = ip->ip_src; - swip2 = ip->ip_dst; - if (nat->nat_dir == NAT_OUTBOUND) { - fi.fin_fi.fi_daddr = data_addr.s_addr; - fi.fin_fi.fi_saddr = nat->nat_inip.s_addr; - ip->ip_dst = data_addr; - ip->ip_src = nat->nat_inip; - } else if (nat->nat_dir == NAT_INBOUND) { - fi.fin_fi.fi_saddr = nat->nat_oip.s_addr; - fi.fin_fi.fi_daddr = nat->nat_outip.s_addr; - ip->ip_src = nat->nat_oip; - ip->ip_dst = nat->nat_outip; - } - - sflags = nflags; - nflags |= NAT_SLAVE; - if (nat->nat_dir == NAT_INBOUND) - nflags |= NAT_NOTRULEPORT; - nat2 = nat_new(&fi, nat->nat_ptr, NULL, nflags, nat->nat_dir); - if (nat2 != NULL) { - (void) nat_proto(&fi, nat2, IPN_TCP); - nat_update(&fi, nat2, nat->nat_ptr); - fi.fin_ifp = NULL; - if (nat->nat_dir == NAT_INBOUND) { - fi.fin_fi.fi_daddr = nat->nat_inip.s_addr; - ip->ip_dst = nat->nat_inip; - } - (void) fr_addstate(&fi, NULL, sflags); - if (fi.fin_state != NULL) - fr_statederef((ipstate_t **)&fi.fin_state); - } - - ip->ip_len = slen; - ip->ip_src = swip; - ip->ip_dst = swip2; - } - return inc; + return APR_INC(inc); } -int ippr_ftp_server(fin, ip, nat, ftp, dlen) -fr_info_t *fin; -ip_t *ip; -nat_t *nat; -ftpinfo_t *ftp; -int dlen; +int +ipf_p_ftp_server(softf, fin, ip, nat, ftp, dlen) + ipf_ftp_softc_t *softf; + fr_info_t *fin; + ip_t *ip; + nat_t *nat; + ftpinfo_t *ftp; + int dlen; { char *rptr, *wptr; ftpside_t *f; @@ -747,19 +1012,29 @@ int dlen; rptr = f->ftps_rptr; wptr = f->ftps_wptr; + DT2(ftp_server_response, char *, rptr, int, ftp->ftp_passok); if (*rptr == ' ') goto server_cmd_ok; if (!ISDIGIT(*rptr) || !ISDIGIT(*(rptr + 1)) || !ISDIGIT(*(rptr + 2))) return 0; + if (softf->ipf_p_ftp_debug & DEBUG_PARSE) + printf("ipf_p_ftp_server_1: cmd[%4.4s] passok %d\n", + rptr, ftp->ftp_passok); if (ftp->ftp_passok == FTPXY_GO) { if (!strncmp(rptr, "227 ", 4)) - inc = ippr_ftp_pasv(fin, ip, nat, ftp, dlen); + inc = ipf_p_ftp_pasv(softf, fin, ip, nat, ftp, dlen); else if (!strncmp(rptr, "229 ", 4)) - inc = ippr_ftp_epsv(fin, ip, nat, f, dlen); - } else if (ippr_ftp_insecure && !strncmp(rptr, "227 ", 4)) { - inc = ippr_ftp_pasv(fin, ip, nat, ftp, dlen); - } else if (ippr_ftp_insecure && !strncmp(rptr, "229 ", 4)) { - inc = ippr_ftp_epsv(fin, ip, nat, f, dlen); + inc = ipf_p_ftp_epsv(softf, fin, ip, nat, ftp, dlen); + else if (strncmp(rptr, "200", 3)) { + /* + * 200 is returned for a successful command. + */ + ; + } + } else if (softf->ipf_p_ftp_insecure && !strncmp(rptr, "227 ", 4)) { + inc = ipf_p_ftp_pasv(softf, fin, ip, nat, ftp, dlen); + } else if (softf->ipf_p_ftp_insecure && !strncmp(rptr, "229 ", 4)) { + inc = ipf_p_ftp_epsv(softf, fin, ip, nat, ftp, dlen); } else if (*rptr == '5' || *rptr == '4') ftp->ftp_passok = FTPXY_INIT; else if (ftp->ftp_incok) { @@ -784,8 +1059,13 @@ int dlen; } } } -server_cmd_ok: ftp->ftp_incok = 0; +server_cmd_ok: + if (softf->ipf_p_ftp_debug & DEBUG_PARSE) + printf("ipf_p_ftp_server_2: cmd[%4.4s] passok %d\n", + rptr, ftp->ftp_passok); + DT3(ftp_server_passok, char *,rptr, int, ftp->ftp_incok, + int, ftp->ftp_passok); while ((*rptr++ != '\n') && (rptr < wptr)) ; @@ -795,13 +1075,20 @@ int dlen; /* + * 0 FTPXY_JUNK_OK + * 1 FTPXY_JUNK_BAD + * 2 FTPXY_JUNK_EOL + * 3 FTPXY_JUNK_CONT + * * Look to see if the buffer starts with something which we recognise as * being the correct syntax for the FTP protocol. */ -int ippr_ftp_client_valid(ftps, buf, len) -ftpside_t *ftps; -char *buf; -size_t len; +int +ipf_p_ftp_client_valid(softf, ftps, buf, len) + ipf_ftp_softc_t *softf; + ftpside_t *ftps; + char *buf; + size_t len; { register char *s, c, pc; register size_t i = len; @@ -809,12 +1096,13 @@ size_t len; s = buf; - if (ftps->ftps_junk == 1) - return 1; + if (ftps->ftps_junk == FTPXY_JUNK_BAD) + return FTPXY_JUNK_BAD; if (i < 5) { - if (ippr_ftp_debug > 3) - printf("ippr_ftp_client_valid:i(%d) < 5\n", (int)i); + DT1(client_valid, int, i); + if (softf->ipf_p_ftp_debug & DEBUG_ERROR) + printf("ipf_p_ftp_client_valid:i(%d) < 5\n", (int)i); return 2; } @@ -847,12 +1135,13 @@ size_t len; goto bad_client_command; } else { bad_client_command: - if (ippr_ftp_debug > 3) + DT4(client_junk, int, len, int, i, int, c, char *, buf); + if (softf->ipf_p_ftp_debug & DEBUG_PARSE_ERR) printf("%s:bad:junk %d len %d/%d c 0x%x buf [%*.*s]\n", - "ippr_ftp_client_valid", + "ipf_p_ftp_client_valid", ftps->ftps_junk, (int)len, (int)i, c, (int)len, (int)len, buf); - return 1; + return FTPXY_JUNK_BAD; } for (; i; i--) { @@ -860,25 +1149,30 @@ size_t len; c = *s++; if ((pc == '\r') && (c == '\n')) { cmd[4] = '\0'; - if (!strcmp(cmd, "PASV")) - ftps->ftps_cmds = FTPXY_C_PASV; - else - ftps->ftps_cmds = 0; + if (!strcmp(cmd, "PASV")) { + ftps->ftps_cmd = FTPXY_C_PASV; + } else if (!strcmp(cmd, "EPSV")) { + ftps->ftps_cmd = FTPXY_C_EPSV; + } else { + ftps->ftps_cmd = 0; + } return 0; } } #if !defined(_KERNEL) - printf("ippr_ftp_client_valid:junk after cmd[%*.*s]\n", + printf("ipf_p_ftp_client_valid:junk after cmd[%*.*s]\n", (int)len, (int)len, buf); #endif - return 2; + return FTPXY_JUNK_EOL; } -int ippr_ftp_server_valid(ftps, buf, len) -ftpside_t *ftps; -char *buf; -size_t len; +int +ipf_p_ftp_server_valid(softf, ftps, buf, len) + ipf_ftp_softc_t *softf; + ftpside_t *ftps; + char *buf; + size_t len; { register char *s, c, pc; register size_t i = len; @@ -887,19 +1181,22 @@ size_t len; s = buf; cmd = 0; - if (ftps->ftps_junk == 1) - return 1; + if (ftps->ftps_junk == FTPXY_JUNK_BAD) + return FTPXY_JUNK_BAD; if (i < 5) { - if (ippr_ftp_debug > 3) - printf("ippr_ftp_servert_valid:i(%d) < 5\n", (int)i); + DT1(server_valid, int, i); + if (softf->ipf_p_ftp_debug & DEBUG_PARSE_ERR) + printf("ipf_p_ftp_servert_valid:i(%d) < 5\n", (int)i); return 2; } c = *s++; i--; - if (c == ' ') + if (c == ' ') { + cmd = -1; goto search_eol; + } if (ISDIGIT(c)) { cmd = (c - '0') * 100; @@ -915,40 +1212,54 @@ size_t len; i--; if ((c != '-') && (c != ' ')) goto bad_server_command; + if (c == '-') + return FTPXY_JUNK_CONT; } else goto bad_server_command; } else goto bad_server_command; } else { bad_server_command: - if (ippr_ftp_debug > 3) + DT4(server_junk, int len, buf, int, i, int, c, char *, buf); + if (softf->ipf_p_ftp_debug & DEBUG_PARSE_INFO) printf("%s:bad:junk %d len %d/%d c 0x%x buf [%*.*s]\n", - "ippr_ftp_server_valid", + "ipf_p_ftp_server_valid", ftps->ftps_junk, (int)len, (int)i, c, (int)len, (int)len, buf); - return 1; + if (ftps->ftps_junk == FTPXY_JUNK_CONT) + return FTPXY_JUNK_CONT; + return FTPXY_JUNK_BAD; } search_eol: for (; i; i--) { pc = c; c = *s++; if ((pc == '\r') && (c == '\n')) { - ftps->ftps_cmds = cmd; - return 0; + if (cmd == -1) { + if (ftps->ftps_junk == FTPXY_JUNK_CONT) + return FTPXY_JUNK_CONT; + } else { + ftps->ftps_cmd = cmd; + } + return FTPXY_JUNK_OK; } } - if (ippr_ftp_debug > 3) - printf("ippr_ftp_server_valid:junk after cmd[%*.*s]\n", + + DT2(junk_eol, int, len, char *, buf); + if (softf->ipf_p_ftp_debug & DEBUG_PARSE_INFO) + printf("ipf_p_ftp_server_valid:junk after cmd[%*.*s]\n", (int)len, (int)len, buf); - return 2; + return FTPXY_JUNK_EOL; } -int ippr_ftp_valid(ftp, side, buf, len) -ftpinfo_t *ftp; -int side; -char *buf; -size_t len; +int +ipf_p_ftp_valid(softf, ftp, side, buf, len) + ipf_ftp_softc_t *softf; + ftpinfo_t *ftp; + int side; + char *buf; + size_t len; { ftpside_t *ftps; int ret; @@ -956,9 +1267,9 @@ size_t len; ftps = &ftp->ftp_side[side]; if (side == 0) - ret = ippr_ftp_client_valid(ftps, buf, len); + ret = ipf_p_ftp_client_valid(softf, ftps, buf, len); else - ret = ippr_ftp_server_valid(ftps, buf, len); + ret = ipf_p_ftp_server_valid(softf, ftps, buf, len); return ret; } @@ -971,13 +1282,15 @@ size_t len; * rv == 0 for inbound processing, * rv == 1 for outbound processing. */ -int ippr_ftp_process(fin, nat, ftp, rv) -fr_info_t *fin; -nat_t *nat; -ftpinfo_t *ftp; -int rv; +int +ipf_p_ftp_process(softf, fin, nat, ftp, rv) + ipf_ftp_softc_t *softf; + fr_info_t *fin; + nat_t *nat; + ftpinfo_t *ftp; + int rv; { - int mlen, len, off, inc, i, sel, sel2, ok, ackoff, seqoff; + int mlen, len, off, inc, i, sel, sel2, ok, ackoff, seqoff, retry; char *rptr, *wptr, *s; u_32_t thseq, thack; ap_session_t *aps; @@ -995,14 +1308,17 @@ int rv; t = &ftp->ftp_side[1 - rv]; thseq = ntohl(tcp->th_seq); thack = ntohl(tcp->th_ack); - #ifdef __sgi mlen = fin->fin_plen - off; #else mlen = MSGDSIZE(m) - off; #endif - if (ippr_ftp_debug > 4) - printf("ippr_ftp_process: mlen %d\n", mlen); + + DT3(process_debug, tcphdr_t *, tcp, int, off, int, mlen); + if (softf->ipf_p_ftp_debug & DEBUG_INFO) + printf("ipf_p_ftp_process: %d:%d,%d, mlen %d flags %x\n", + fin->fin_out, fin->fin_sport, fin->fin_dport, + mlen, tcp->th_flags); if ((mlen == 0) && ((tcp->th_flags & TH_OPENING) == TH_OPENING)) { f->ftps_seq[0] = thseq + 1; @@ -1016,7 +1332,7 @@ int rv; sel = aps->aps_sel[1 - rv]; sel2 = aps->aps_sel[rv]; - if (rv == 0) { + if (rv == 1) { seqoff = aps->aps_seqoff[sel]; if (aps->aps_seqmin[sel] > seqoff + thseq) seqoff = aps->aps_seqoff[!sel]; @@ -1025,14 +1341,14 @@ int rv; ackoff = aps->aps_ackoff[!sel2]; } else { seqoff = aps->aps_ackoff[sel]; - if (ippr_ftp_debug > 2) + if (softf->ipf_p_ftp_debug & DEBUG_INFO) printf("seqoff %d thseq %x ackmin %x\n", seqoff, thseq, aps->aps_ackmin[sel]); if (aps->aps_ackmin[sel] > seqoff + thseq) seqoff = aps->aps_ackoff[!sel]; ackoff = aps->aps_seqoff[sel2]; - if (ippr_ftp_debug > 2) + if (softf->ipf_p_ftp_debug & DEBUG_INFO) printf("ackoff %d thack %x seqmin %x\n", ackoff, thack, aps->aps_seqmin[sel2]); if (ackoff > 0) { @@ -1043,7 +1359,7 @@ int rv; ackoff = aps->aps_seqoff[!sel2]; } } - if (ippr_ftp_debug > 2) { + if (softf->ipf_p_ftp_debug & DEBUG_INFO) { printf("%s: %x seq %x/%d ack %x/%d len %d/%d off %d\n", rv ? "IN" : "OUT", tcp->th_flags, thseq, seqoff, thack, ackoff, mlen, fin->fin_plen, off); @@ -1060,7 +1376,7 @@ int rv; * that it is out of order (and there is no real danger in doing so * apart from causing packets to go through here ordered). */ - if (ippr_ftp_debug > 2) { + if (softf->ipf_p_ftp_debug & DEBUG_INFO) { printf("rv %d t:seq[0] %x seq[1] %x %d/%d\n", rv, t->ftps_seq[0], t->ftps_seq[1], seqoff, ackoff); } @@ -1078,37 +1394,44 @@ int rv; ok = 1; } } else { - if (t->ftps_seq[0] + ackoff == thack) + if (t->ftps_seq[0] + ackoff == thack) { + t->ftps_seq[0] = thack; ok = 1; - else if (t->ftps_seq[0] == thack + ackoff) + } else if (t->ftps_seq[0] == thack + ackoff) { + t->ftps_seq[0] = thack + ackoff; ok = 1; - else if (t->ftps_seq[1] + ackoff == thack) { - t->ftps_seq[0] = thack - ackoff; + } else if (t->ftps_seq[1] + ackoff == thack) { + t->ftps_seq[0] = thack; ok = 1; } else if (t->ftps_seq[1] == thack + ackoff) { - t->ftps_seq[0] = thack - ackoff; + t->ftps_seq[0] = thack + ackoff; ok = 1; } } } - if (ippr_ftp_debug > 2) { + if (softf->ipf_p_ftp_debug & DEBUG_INFO) { if (!ok) printf("%s ok\n", "not"); } if (!mlen) { - if (t->ftps_seq[0] + ackoff != thack) { - if (ippr_ftp_debug > 1) { - printf("%s:seq[0](%x) + (%x) != (%x)\n", - "ippr_ftp_process", t->ftps_seq[0], + if (t->ftps_seq[0] + ackoff != thack && + t->ftps_seq[1] + ackoff != thack) { + DT3(thack, ftpside_t *t, t, int, ackoff, u_32_t, thack); + if (softf->ipf_p_ftp_debug & DEBUG_ERROR) { + printf("%s:seq[0](%u) + (%d) != (%u)\n", + "ipf_p_ftp_process", t->ftps_seq[0], + ackoff, thack); + printf("%s:seq[0](%u) + (%d) != (%u)\n", + "ipf_p_ftp_process", t->ftps_seq[1], ackoff, thack); } return APR_ERR(1); } - if (ippr_ftp_debug > 2) { - printf("ippr_ftp_process:f:seq[0] %x seq[1] %x\n", + if (softf->ipf_p_ftp_debug & DEBUG_PARSE) { + printf("ipf_p_ftp_process:f:seq[0] %x seq[1] %x\n", f->ftps_seq[0], f->ftps_seq[1]); } @@ -1117,9 +1440,10 @@ int rv; f->ftps_seq[0] = f->ftps_seq[1] - seqoff; f->ftps_seq[1] = thseq + 1 - seqoff; } else { - if (ippr_ftp_debug > 1) { - printf("FIN: thseq %x seqoff %d ftps_seq %x %x\n", - thseq, seqoff, f->ftps_seq[0], f->ftps_seq[1]); + DT2(thseq, ftpside_t *t, t, u_32_t, thseq); + if (softf->ipf_p_ftp_debug & DEBUG_ERROR) { + printf("FIN: thseq %x seqoff %d ftps_seq %x\n", + thseq, seqoff, f->ftps_seq[0]); } return APR_ERR(1); } @@ -1140,8 +1464,9 @@ int rv; } if (ok == 0) { + DT3(ok_0, ftpside_t *, f, u_32_t, thseq, int, mlen); inc = thseq - f->ftps_seq[0]; - if (ippr_ftp_debug > 1) { + if (softf->ipf_p_ftp_debug & DEBUG_ERROR) { printf("inc %d sel %d rv %d\n", inc, sel, rv); printf("th_seq %x ftps_seq %x/%x\n", thseq, f->ftps_seq[0], f->ftps_seq[1]); @@ -1163,68 +1488,69 @@ int rv; while (mlen > 0) { len = MIN(mlen, sizeof(f->ftps_buf) - (wptr - rptr)); + if (len == 0) + break; COPYDATA(m, off, len, wptr); mlen -= len; off += len; wptr += len; - if (ippr_ftp_debug > 3) +whilemore: + if (softf->ipf_p_ftp_debug & DEBUG_PARSE) printf("%s:len %d/%d off %d wptr %lx junk %d [%*.*s]\n", - "ippr_ftp_process", + "ipf_p_ftp_process", len, mlen, off, (u_long)wptr, f->ftps_junk, len, len, rptr); f->ftps_wptr = wptr; - if (f->ftps_junk != 0) { + if (f->ftps_junk != FTPXY_JUNK_OK) { i = f->ftps_junk; - f->ftps_junk = ippr_ftp_valid(ftp, rv, rptr, + f->ftps_junk = ipf_p_ftp_valid(softf, ftp, rv, rptr, wptr - rptr); + DT2(junk_transit, int, i, int, f->ftps_junk); - if (ippr_ftp_debug > 5) + if (softf->ipf_p_ftp_debug & DEBUG_PARSE) printf("%s:junk %d -> %d\n", - "ippr_ftp_process", i, f->ftps_junk); + "ipf_p_ftp_process", i, f->ftps_junk); - if (f->ftps_junk != 0) { + if (f->ftps_junk == FTPXY_JUNK_BAD) { + DT(buffer_full); if (wptr - rptr == sizeof(f->ftps_buf)) { - if (ippr_ftp_debug > 4) + if (softf->ipf_p_ftp_debug & + DEBUG_PARSE_INFO) printf("%s:full buffer\n", - "ippr_ftp_process"); + "ipf_p_ftp_process"); f->ftps_rptr = f->ftps_buf; f->ftps_wptr = f->ftps_buf; rptr = f->ftps_rptr; wptr = f->ftps_wptr; - /* - * Because we throw away data here that - * we would otherwise parse, set the - * junk flag to indicate just ignore - * any data upto the next CRLF. - */ - f->ftps_junk = 1; continue; } } } - while ((f->ftps_junk == 0) && (wptr > rptr)) { + while ((f->ftps_junk == FTPXY_JUNK_OK) && (wptr > rptr)) { len = wptr - rptr; - f->ftps_junk = ippr_ftp_valid(ftp, rv, rptr, len); + f->ftps_junk = ipf_p_ftp_valid(softf, ftp, rv, + rptr, len); - if (ippr_ftp_debug > 3) { + if (softf->ipf_p_ftp_debug & DEBUG_PARSE) { printf("%s=%d len %d rv %d ptr %lx/%lx ", - "ippr_ftp_valid", + "ipf_p_ftp_valid", f->ftps_junk, len, rv, (u_long)rptr, (u_long)wptr); printf("buf [%*.*s]\n", len, len, rptr); } - if (f->ftps_junk == 0) { + if (f->ftps_junk == FTPXY_JUNK_OK) { + f->ftps_cmds++; f->ftps_rptr = rptr; if (rv) - inc += ippr_ftp_server(fin, ip, nat, - ftp, len); + inc += ipf_p_ftp_server(softf, fin, ip, + nat, ftp, len); else - inc += ippr_ftp_client(fin, ip, nat, - ftp, len); + inc += ipf_p_ftp_client(softf, fin, ip, + nat, ftp, len); rptr = f->ftps_rptr; wptr = f->ftps_wptr; } @@ -1234,21 +1560,25 @@ int rv; * Off to a bad start so lets just forget about using the * ftp proxy for this connection. */ - if ((f->ftps_cmds == 0) && (f->ftps_junk == 1)) { + if ((f->ftps_cmds == 0) && (f->ftps_junk == FTPXY_JUNK_BAD)) { /* f->ftps_seq[1] += inc; */ - if (ippr_ftp_debug > 1) + DT(ftp_junk_cmd); + if (softf->ipf_p_ftp_debug & DEBUG_ERROR) printf("%s:cmds == 0 junk == 1\n", - "ippr_ftp_process"); + "ipf_p_ftp_process"); return APR_ERR(2); } - if ((f->ftps_junk != 0) && (rptr < wptr)) { + retry = 0; + if ((f->ftps_junk != FTPXY_JUNK_OK) && (rptr < wptr)) { for (s = rptr; s < wptr; s++) { if ((*s == '\r') && (s + 1 < wptr) && (*(s + 1) == '\n')) { rptr = s + 2; - f->ftps_junk = 0; + retry = 1; + if (f->ftps_junk != FTPXY_JUNK_CONT) + f->ftps_junk = FTPXY_JUNK_OK; break; } } @@ -1264,19 +1594,21 @@ int rv; * current state. */ if (rptr > f->ftps_buf) { - bcopy(rptr, f->ftps_buf, len); + bcopy(rptr, f->ftps_buf, wptr - rptr); wptr -= rptr - f->ftps_buf; rptr = f->ftps_buf; } } f->ftps_rptr = rptr; f->ftps_wptr = wptr; + if (retry) + goto whilemore; } /* f->ftps_seq[1] += inc; */ if (tcp->th_flags & TH_FIN) f->ftps_seq[1]++; - if (ippr_ftp_debug > 3) { + if (softf->ipf_p_ftp_debug & DEBUG_PARSE_INFO) { #ifdef __sgi mlen = fin->fin_plen; #else @@ -1293,11 +1625,14 @@ int rv; } -int ippr_ftp_out(fin, aps, nat) -fr_info_t *fin; -ap_session_t *aps; -nat_t *nat; +int +ipf_p_ftp_out(arg, fin, aps, nat) + void *arg; + fr_info_t *fin; + ap_session_t *aps; + nat_t *nat; { + ipf_ftp_softc_t *softf = arg; ftpinfo_t *ftp; int rev; @@ -1309,15 +1644,18 @@ nat_t *nat; if (ftp->ftp_side[1 - rev].ftps_ifp == NULL) ftp->ftp_side[1 - rev].ftps_ifp = fin->fin_ifp; - return ippr_ftp_process(fin, nat, ftp, rev); + return ipf_p_ftp_process(softf, fin, nat, ftp, rev); } -int ippr_ftp_in(fin, aps, nat) -fr_info_t *fin; -ap_session_t *aps; -nat_t *nat; +int +ipf_p_ftp_in(arg, fin, aps, nat) + void *arg; + fr_info_t *fin; + ap_session_t *aps; + nat_t *nat; { + ipf_ftp_softc_t *softf = arg; ftpinfo_t *ftp; int rev; @@ -1329,18 +1667,19 @@ nat_t *nat; if (ftp->ftp_side[rev].ftps_ifp == NULL) ftp->ftp_side[rev].ftps_ifp = fin->fin_ifp; - return ippr_ftp_process(fin, nat, ftp, 1 - rev); + return ipf_p_ftp_process(softf, fin, nat, ftp, 1 - rev); } /* - * ippr_ftp_atoi - implement a version of atoi which processes numbers in + * ipf_p_ftp_atoi - implement a version of atoi which processes numbers in * pairs separated by commas (which are expected to be in the range 0 - 255), * returning a 16 bit number combining either side of the , as the MSB and * LSB. */ -u_short ippr_ftp_atoi(ptr) -char **ptr; +u_short +ipf_p_ftp_atoi(ptr) + char **ptr; { register char *s = *ptr, c; register u_char i = 0, j = 0; @@ -1364,26 +1703,237 @@ char **ptr; } -int ippr_ftp_epsv(fin, ip, nat, f, dlen) -fr_info_t *fin; -ip_t *ip; -nat_t *nat; -ftpside_t *f; -int dlen; +int +ipf_p_ftp_eprt(softf, fin, ip, nat, ftp, dlen) + ipf_ftp_softc_t *softf; + fr_info_t *fin; + ip_t *ip; + nat_t *nat; + ftpinfo_t *ftp; + int dlen; +{ + ftpside_t *f; + + /* + * Check for client sending out EPRT message. + */ + if (dlen < IPF_MINEPRTLEN) { + DT1(epert_dlen, int, dlen); + if (softf->ipf_p_ftp_debug & DEBUG_PARSE_ERR) + printf("ipf_p_ftp_eprt:dlen(%d) < IPF_MINEPRTLEN\n", + dlen); + return 0; + } + + /* + * Parse the EPRT command. Format is: + * "EPRT |1|1.2.3.4|2000|" for IPv4 and + * "EPRT |2|ef00::1:2|2000|" for IPv6 + */ + f = &ftp->ftp_side[0]; + if (f->ftps_rptr[5] != '|') + return 0; + if (f->ftps_rptr[5] == f->ftps_rptr[7]) { + if (f->ftps_rptr[6] == '1' && nat->nat_v[0] == 4) + return ipf_p_ftp_eprt4(softf, fin, ip, nat, ftp, dlen); +#ifdef USE_INET6 + if (f->ftps_rptr[6] == '2' && nat->nat_v[0] == 6) + return ipf_p_ftp_eprt6(softf, fin, ip, nat, ftp, dlen); +#endif + } + return 0; +} + + +int +ipf_p_ftp_eprt4(softf, fin, ip, nat, ftp, dlen) + ipf_ftp_softc_t *softf; + fr_info_t *fin; + ip_t *ip; + nat_t *nat; + ftpinfo_t *ftp; + int dlen; +{ + int a1, a2, a3, a4, port, olen, nlen, inc, off; + char newbuf[IPF_FTPBUFSZ]; + char *s, c, delim; + u_32_t addr, i; + tcphdr_t *tcp; + ftpside_t *f; + mb_t *m; + + m = fin->fin_m; + tcp = (tcphdr_t *)fin->fin_dp; + off = (char *)tcp - (char *)ip + (TCP_OFF(tcp) << 2) + fin->fin_ipoff; + f = &ftp->ftp_side[0]; + delim = f->ftps_rptr[5]; + s = f->ftps_rptr + 8; + + /* + * get the IP address. + */ + i = 0; + while (((c = *s++) != '\0') && ISDIGIT(c)) { + i *= 10; + i += c - '0'; + } + if (i > 255) + return 0; + if (c != '.') + return 0; + addr = (i << 24); + + i = 0; + while (((c = *s++) != '\0') && ISDIGIT(c)) { + i *= 10; + i += c - '0'; + } + if (i > 255) + return 0; + if (c != '.') + return 0; + addr |= (addr << 16); + + i = 0; + while (((c = *s++) != '\0') && ISDIGIT(c)) { + i *= 10; + i += c - '0'; + } + if (i > 255) + return 0; + if (c != '.') + return 0; + addr |= (addr << 8); + + i = 0; + while (((c = *s++) != '\0') && ISDIGIT(c)) { + i *= 10; + i += c - '0'; + } + if (i > 255) + return 0; + if (c != delim) + return 0; + addr |= addr; + + /* + * Get the port number + */ + i = 0; + while (((c = *s++) != '\0') && ISDIGIT(c)) { + i *= 10; + i += c - '0'; + } + if (i > 65535) + return 0; + if (c != delim) + return 0; + port = i; + + /* + * Check for CR-LF at the end of the command string. + */ + if ((*s != '\r') || (*(s + 1) != '\n')) { + DT(eprt4_no_crlf); + if (softf->ipf_p_ftp_debug & DEBUG_PARSE_ERR) + printf("ipf_p_ftp_eprt4:missing %s\n", "cr-lf"); + return 0; + } + s += 2; + + /* + * Calculate new address parts for PORT command + */ + if (nat->nat_dir == NAT_INBOUND) + a1 = ntohl(nat->nat_odstaddr); + else + a1 = ntohl(ip->ip_src.s_addr); + a2 = (a1 >> 16) & 0xff; + a3 = (a1 >> 8) & 0xff; + a4 = a1 & 0xff; + a1 >>= 24; + olen = s - f->ftps_rptr; + /* DO NOT change this to snprintf! */ + /* + * While we could force the use of | as a delimiter here, it makes + * sense to preserve whatever character is being used by the systems + * involved in the communication. + */ +#if defined(SNPRINTF) && defined(_KERNEL) + SNPRINTF(newbuf, sizeof(newbuf), "%s %c1%c%u.%u.%u.%u%c%u%c\r\n", + "EPRT", delim, delim, a1, a2, a3, a4, delim, port, delim); +#else + (void) sprintf(newbuf, "%s %c1%c%u.%u.%u.%u%c%u%c\r\n", + "EPRT", delim, delim, a1, a2, a3, a4, delim, port, + delim); +#endif + + nlen = strlen(newbuf); + inc = nlen - olen; + if ((inc + fin->fin_plen) > 65535) { + DT2(eprt4_len, int, inc, int, fin->fin_plen); + if (softf->ipf_p_ftp_debug & DEBUG_ERROR) + printf("ipf_p_ftp_eprt4:inc(%d) + ip->ip_len > 65535\n", + inc); + return 0; + } + + off = (char *)tcp - (char *)ip + (TCP_OFF(tcp) << 2) + fin->fin_ipoff; +#if !defined(_KERNEL) + M_ADJ(m, inc); +#else + if (inc < 0) + M_ADJ(m, inc); +#endif + /* the mbuf chain will be extended if necessary by m_copyback() */ + COPYBACK(m, off, nlen, newbuf); + fin->fin_flx |= FI_DOCKSUM; + + if (inc != 0) { + fin->fin_plen += inc; + ip->ip_len = htons(fin->fin_plen); + fin->fin_dlen += inc; + } + + f->ftps_cmd = FTPXY_C_EPRT; + return ipf_p_ftp_addport(softf, fin, ip, nat, ftp, dlen, port, inc); +} + + +int +ipf_p_ftp_epsv(softf, fin, ip, nat, ftp, dlen) + ipf_ftp_softc_t *softf; + fr_info_t *fin; + ip_t *ip; + nat_t *nat; + ftpinfo_t *ftp; + int dlen; { char newbuf[IPF_FTPBUFSZ]; - char *s; u_short ap = 0; + ftpside_t *f; + char *s; + + if ((softf->ipf_p_ftp_forcepasv != 0) && + (ftp->ftp_side[0].ftps_cmd != FTPXY_C_EPSV)) { + DT1(epsv_cmd, int, ftp->ftp_side[0].ftps_cmd); + if (softf->ipf_p_ftp_debug & DEBUG_PARSE_ERR) + printf("ipf_p_ftp_epsv:ftps_cmd(%d) != FTPXY_C_EPSV\n", + ftp->ftp_side[0].ftps_cmd); + return 0; + } + f = &ftp->ftp_side[1]; #define EPSV_REPLEN 33 /* * Check for EPSV reply message. */ - if (dlen < IPF_MIN229LEN) + if (dlen < IPF_MIN229LEN) { return (0); - else if (strncmp(f->ftps_rptr, - "229 Entering Extended Passive Mode", EPSV_REPLEN)) + } else if (strncmp(f->ftps_rptr, + "229 Entering Extended Passive Mode", EPSV_REPLEN)) { return (0); +} /* * Skip the EPSV command + space @@ -1401,8 +1951,9 @@ int dlen; ap += *s++ - '0'; } - if (!*s) + if (!s) { return 0; +} if (*s == '|') s++; @@ -1413,10 +1964,10 @@ int dlen; /* * check for CR-LF at the end. */ - if ((*s == '\r') && (*(s + 1) == '\n')) { - s += 2; - } else + if ((*s != '\r') || (*(s + 1) != '\n')) { return 0; + } + s += 2; #if defined(SNPRINTF) && defined(_KERNEL) SNPRINTF(newbuf, sizeof(newbuf), "%s (|||%u|)\r\n", @@ -1426,6 +1977,218 @@ int dlen; "229 Entering Extended Passive Mode", ap); #endif - return ippr_ftp_pasvreply(fin, ip, nat, f, (u_int)ap, newbuf, s, - ip->ip_src.s_addr); + return ipf_p_ftp_pasvreply(softf, fin, ip, nat, ftp, (u_int)ap, + newbuf, s); } + +#ifdef USE_INET6 +int +ipf_p_ftp_eprt6(softf, fin, ip, nat, ftp, dlen) + ipf_ftp_softc_t *softf; + fr_info_t *fin; + ip_t *ip; + nat_t *nat; + ftpinfo_t *ftp; + int dlen; +{ + int port, olen, nlen, inc, off, left, i; + char newbuf[IPF_FTPBUFSZ]; + char *s, c; + i6addr_t addr, *a6; + tcphdr_t *tcp; + ip6_t *ip6; + char delim; + u_short whole; + u_short part; + ftpside_t *f; + u_short *t; + int fwd; + mb_t *m; + u_32_t a; + + m = fin->fin_m; + ip6 = (ip6_t *)ip; + f = &ftp->ftp_side[0]; + s = f->ftps_rptr + 8; + f = &ftp->ftp_side[0]; + delim = f->ftps_rptr[5]; + tcp = (tcphdr_t *)fin->fin_dp; + off = (char *)tcp - (char *)ip + (TCP_OFF(tcp) << 2) + fin->fin_ipoff; + + addr.i6[0] = 0; + addr.i6[1] = 0; + addr.i6[2] = 0; + addr.i6[3] = 0; + /* + * Parse an IPv6 address. + * Go forward until either :: or | is found. If :: is found, + * reverse direction. Direction change is performed to ease + * parsing an unknown number of 0s in the middle. + */ + whole = 0; + t = (u_short *)&addr; + fwd = 1; + for (part = 0; (c = *s) != '\0'; ) { + if (c == delim) { + *t = htons((u_short)whole); + break; + } + if (c == ':') { + *t = part; + if (fwd) { + *t = htons((u_short)whole); + t++; + } else { + *t = htons((u_short)(whole >> 16)); + t--; + } + whole = 0; + if (fwd == 1 && s[1] == ':') { + while (*s && *s != '|') + s++; + if ((c = *s) != delim) + break; + t = (u_short *)&addr.i6[3]; + t++; + fwd = 0; + } else if (fwd == 0 && s[-1] == ':') { + break; + } + } else { + if (c >= '0' && c <= '9') { + c -= '0'; + } else if (c >= 'a' && c <= 'f') { + c -= 'a' + 10; + } else if (c >= 'A' && c <= 'F') { + c -= 'A' + 10; + } + if (fwd) { + whole <<= 8; + whole |= c; + } else { + whole >>= 8; + whole |= ((u_32_t)c) << 24; + } + } + if (fwd) + s++; + else + s--; + } + if (c != ':' && c != delim) + return 0; + + while (*s != '|') + s++; + s++; + + /* + * Get the port number + */ + i = 0; + while (((c = *s++) != '\0') && ISDIGIT(c)) { + i *= 10; + i += c - '0'; + } + if (i > 65535) + return 0; + if (c != delim) + return 0; + port = (u_short)(i & 0xffff); + + /* + * Check for CR-LF at the end of the command string. + */ + if ((*s != '\r') || (*(s + 1) != '\n')) { + DT(eprt6_no_crlf); + if (softf->ipf_p_ftp_debug & DEBUG_PARSE_ERR) + printf("ipf_p_ftp_eprt6:missing %s\n", "cr-lf"); + return 0; + } + s += 2; + + /* + * Calculate new address parts for PORT command + */ + a6 = (i6addr_t *)&ip6->ip6_src; + olen = s - f->ftps_rptr; + /* DO NOT change this to snprintf! */ + /* + * While we could force the use of | as a delimiter here, it makes + * sense to preserve whatever character is being used by the systems + * involved in the communication. + */ + s = newbuf; + left = sizeof(newbuf); +#if defined(SNPRINTF) && defined(_KERNEL) + SNPRINTF(newbuf, left, "EPRT %c2%c", delim, delim); + left -= strlen(s) + 1; + s += strlen(s); + a = ntohl(a6->i6[0]); + SNPRINTF(s, left, "%x:%x:", a >> 16, a & 0xffff); + left -= strlen(s); + s += strlen(s); + a = ntohl(a6->i6[1]); + SNPRINTF(s, left, "%x:%x:", a >> 16, a & 0xffff); + left -= strlen(s); + s += strlen(s); + a = ntohl(a6->i6[2]); + SNPRINTF(s, left, "%x:%x:", a >> 16, a & 0xffff); + left -= strlen(s); + s += strlen(s); + a = ntohl(a6->i6[3]); + SNPRINTF(s, left, "%x:%x", a >> 16, a & 0xffff); + left -= strlen(s); + s += strlen(s); + sprintf(s, "|%d|\r\n", port); +#else + (void) sprintf(s, "EPRT %c2%c", delim, delim); + s += strlen(s); + a = ntohl(a6->i6[0]); + sprintf(s, "%x:%x:", a >> 16, a & 0xffff); + s += strlen(s); + a = ntohl(a6->i6[1]); + sprintf(s, "%x:%x:", a >> 16, a & 0xffff); + left -= strlen(s); + s += strlen(s); + a = ntohl(a6->i6[2]); + sprintf(s, "%x:%x:", a >> 16, a & 0xffff); + left -= strlen(s); + s += strlen(s); + a = ntohl(a6->i6[3]); + sprintf(s, "%x:%x", a >> 16, a & 0xffff); + left -= strlen(s); + s += strlen(s); + sprintf(s, "|%d|\r\n", port); +#endif + nlen = strlen(newbuf); + inc = nlen - olen; + if ((inc + fin->fin_plen) > 65535) { + DT2(eprt6_len, int, inc, int, fin->fin_plen); + if (softf->ipf_p_ftp_debug & DEBUG_ERROR) + printf("ipf_p_ftp_eprt6:inc(%d) + ip->ip_len > 65535\n", + inc); + return 0; + } + + off = (char *)tcp - (char *)ip + (TCP_OFF(tcp) << 2) + fin->fin_ipoff; +#if !defined(_KERNEL) + M_ADJ(m, inc); +#else + if (inc < 0) + M_ADJ(m, inc); +#endif + /* the mbuf chain will be extended if necessary by m_copyback() */ + COPYBACK(m, off, nlen, newbuf); + fin->fin_flx |= FI_DOCKSUM; + + if (inc != 0) { + fin->fin_plen += inc; + ip6->ip6_plen = htons(fin->fin_plen - fin->fin_hlen); + fin->fin_dlen += inc; + } + + f->ftps_cmd = FTPXY_C_EPRT; + return ipf_p_ftp_addport(softf, fin, ip, nat, ftp, dlen, port, inc); +} +#endif diff --git a/sys/contrib/ipfilter/netinet/ip_htable.c b/sys/contrib/ipfilter/netinet/ip_htable.c index fc521d851a32..62707f40edd2 100644 --- a/sys/contrib/ipfilter/netinet/ip_htable.c +++ b/sys/contrib/ipfilter/netinet/ip_htable.c @@ -1,7 +1,7 @@ /* $FreeBSD$ */ /* - * Copyright (C) 1993-2001, 2003 by Darren Reed. + * Copyright (C) 2012 by Darren Reed. * * See the IPFILTER.LICENCE file for details on licencing. */ @@ -41,7 +41,7 @@ struct file; #if defined(_KERNEL) # include #else -# include +# include "ipf.h" #endif #include #include @@ -53,82 +53,277 @@ struct file; /* END OF INCLUDES */ #if !defined(lint) -static const char rcsid[] = "@(#)$Id: ip_htable.c,v 2.34.2.11 2007/09/20 12:51:51 darrenr Exp $"; +static const char rcsid[] = "@(#)$Id$"; #endif -#ifdef IPFILTER_LOOKUP -static iphtent_t *fr_iphmfind __P((iphtable_t *, struct in_addr *)); -static u_long ipht_nomem[IPL_LOGSIZE] = { 0, 0, 0, 0, 0, 0, 0, 0 }; -static u_long ipf_nhtables[IPL_LOGSIZE] = { 0, 0, 0, 0, 0, 0, 0, 0 }; -static u_long ipf_nhtnodes[IPL_LOGSIZE] = { 0, 0, 0, 0, 0, 0, 0, 0 }; - -iphtable_t *ipf_htables[IPL_LOGSIZE] = { NULL, NULL, NULL, NULL, - NULL, NULL, NULL, NULL }; +# ifdef USE_INET6 +static iphtent_t *ipf_iphmfind6 __P((iphtable_t *, i6addr_t *)); +# endif +static iphtent_t *ipf_iphmfind __P((iphtable_t *, struct in_addr *)); +static int ipf_iphmfindip __P((ipf_main_softc_t *, void *, int, void *, u_int)); +static int ipf_htable_clear __P((ipf_main_softc_t *, void *, iphtable_t *)); +static int ipf_htable_create __P((ipf_main_softc_t *, void *, iplookupop_t *)); +static int ipf_htable_deref __P((ipf_main_softc_t *, void *, void *)); +static int ipf_htable_destroy __P((ipf_main_softc_t *, void *, int, char *)); +static void *ipf_htable_exists __P((void *, int, char *)); +static size_t ipf_htable_flush __P((ipf_main_softc_t *, void *, + iplookupflush_t *)); +static void ipf_htable_free __P((void *, iphtable_t *)); +static int ipf_htable_iter_deref __P((ipf_main_softc_t *, void *, int, + int, void *)); +static int ipf_htable_iter_next __P((ipf_main_softc_t *, void *, ipftoken_t *, + ipflookupiter_t *)); +static int ipf_htable_node_add __P((ipf_main_softc_t *, void *, + iplookupop_t *, int)); +static int ipf_htable_node_del __P((ipf_main_softc_t *, void *, + iplookupop_t *, int)); +static int ipf_htable_remove __P((ipf_main_softc_t *, void *, iphtable_t *)); +static void *ipf_htable_soft_create __P((ipf_main_softc_t *)); +static void ipf_htable_soft_destroy __P((ipf_main_softc_t *, void *)); +static int ipf_htable_soft_init __P((ipf_main_softc_t *, void *)); +static void ipf_htable_soft_fini __P((ipf_main_softc_t *, void *)); +static int ipf_htable_stats_get __P((ipf_main_softc_t *, void *, + iplookupop_t *)); +static int ipf_htable_table_add __P((ipf_main_softc_t *, void *, + iplookupop_t *)); +static int ipf_htable_table_del __P((ipf_main_softc_t *, void *, + iplookupop_t *)); +static int ipf_htent_deref __P((void *, iphtent_t *)); +static iphtent_t *ipf_htent_find __P((iphtable_t *, iphtent_t *)); +static int ipf_htent_insert __P((ipf_main_softc_t *, void *, iphtable_t *, + iphtent_t *)); +static int ipf_htent_remove __P((ipf_main_softc_t *, void *, iphtable_t *, + iphtent_t *)); +static void *ipf_htable_select_add_ref __P((void *, int, char *)); +static void ipf_htable_expire __P((ipf_main_softc_t *, void *)); -void fr_htable_unload() +typedef struct ipf_htable_softc_s { + u_long ipht_nomem[LOOKUP_POOL_SZ]; + u_long ipf_nhtables[LOOKUP_POOL_SZ]; + u_long ipf_nhtnodes[LOOKUP_POOL_SZ]; + iphtable_t *ipf_htables[LOOKUP_POOL_SZ]; + iphtent_t *ipf_node_explist; +} ipf_htable_softc_t; + +ipf_lookup_t ipf_htable_backend = { + IPLT_HASH, + ipf_htable_soft_create, + ipf_htable_soft_destroy, + ipf_htable_soft_init, + ipf_htable_soft_fini, + ipf_iphmfindip, + ipf_htable_flush, + ipf_htable_iter_deref, + ipf_htable_iter_next, + ipf_htable_node_add, + ipf_htable_node_del, + ipf_htable_stats_get, + ipf_htable_table_add, + ipf_htable_table_del, + ipf_htable_deref, + ipf_htable_exists, + ipf_htable_select_add_ref, + NULL, + ipf_htable_expire, + NULL +}; + + +/* ------------------------------------------------------------------------ */ +/* Function: ipf_htable_soft_create */ +/* Returns: void * - NULL = failure, else pointer to local context */ +/* Parameters: softc(I) - pointer to soft context main structure */ +/* */ +/* Initialise the routing table data structures where required. */ +/* ------------------------------------------------------------------------ */ +static void * +ipf_htable_soft_create(softc) + ipf_main_softc_t *softc; +{ + ipf_htable_softc_t *softh; + + KMALLOC(softh, ipf_htable_softc_t *); + if (softh == NULL) { + IPFERROR(30026); + return NULL; + } + + bzero((char *)softh, sizeof(*softh)); + + return softh; +} + + +/* ------------------------------------------------------------------------ */ +/* Function: ipf_htable_soft_destroy */ +/* Returns: Nil */ +/* Parameters: softc(I) - pointer to soft context main structure */ +/* arg(I) - pointer to local context to use */ +/* */ +/* Clean up the pool by free'ing the radix tree associated with it and free */ +/* up the pool context too. */ +/* ------------------------------------------------------------------------ */ +static void +ipf_htable_soft_destroy(softc, arg) + ipf_main_softc_t *softc; + void *arg; +{ + ipf_htable_softc_t *softh = arg; + + KFREE(softh); +} + + +/* ------------------------------------------------------------------------ */ +/* Function: ipf_htable_soft_init */ +/* Returns: int - 0 = success, else error */ +/* Parameters: softc(I) - pointer to soft context main structure */ +/* arg(I) - pointer to local context to use */ +/* */ +/* Initialise the hash table ready for use. */ +/* ------------------------------------------------------------------------ */ +static int +ipf_htable_soft_init(softc, arg) + ipf_main_softc_t *softc; + void *arg; +{ + ipf_htable_softc_t *softh = arg; + + bzero((char *)softh, sizeof(*softh)); + + return 0; +} + + +/* ------------------------------------------------------------------------ */ +/* Function: ipf_htable_soft_fini */ +/* Returns: Nil */ +/* Parameters: softc(I) - pointer to soft context main structure */ +/* arg(I) - pointer to local context to use */ +/* Locks: WRITE(ipf_global) */ +/* */ +/* Clean up all the pool data structures allocated and call the cleanup */ +/* function for the radix tree that supports the pools. ipf_pool_destroy is */ +/* used to delete the pools one by one to ensure they're properly freed up. */ +/* ------------------------------------------------------------------------ */ +static void +ipf_htable_soft_fini(softc, arg) + ipf_main_softc_t *softc; + void *arg; { iplookupflush_t fop; + fop.iplf_type = IPLT_HASH; fop.iplf_unit = IPL_LOGALL; - (void)fr_flushhtable(&fop); + fop.iplf_arg = 0; + fop.iplf_count = 0; + *fop.iplf_name = '\0'; + ipf_htable_flush(softc, arg, &fop); } -int fr_gethtablestat(op) -iplookupop_t *op; +/* ------------------------------------------------------------------------ */ +/* Function: ipf_htable_stats_get */ +/* Returns: int - 0 = success, else error */ +/* Parameters: softc(I) - pointer to soft context main structure */ +/* arg(I) - pointer to local context to use */ +/* op(I) - pointer to lookup operation data */ +/* */ +/* Copy the relevant statistics out of internal structures and into the */ +/* structure used to export statistics. */ +/* ------------------------------------------------------------------------ */ +static int +ipf_htable_stats_get(softc, arg, op) + ipf_main_softc_t *softc; + void *arg; + iplookupop_t *op; { + ipf_htable_softc_t *softh = arg; iphtstat_t stats; + int err; - if (op->iplo_size != sizeof(stats)) + if (op->iplo_size != sizeof(stats)) { + IPFERROR(30001); return EINVAL; + } - stats.iphs_tables = ipf_htables[op->iplo_unit]; - stats.iphs_numtables = ipf_nhtables[op->iplo_unit]; - stats.iphs_numnodes = ipf_nhtnodes[op->iplo_unit]; - stats.iphs_nomem = ipht_nomem[op->iplo_unit]; + stats.iphs_tables = softh->ipf_htables[op->iplo_unit + 1]; + stats.iphs_numtables = softh->ipf_nhtables[op->iplo_unit + 1]; + stats.iphs_numnodes = softh->ipf_nhtnodes[op->iplo_unit + 1]; + stats.iphs_nomem = softh->ipht_nomem[op->iplo_unit + 1]; - return COPYOUT(&stats, op->iplo_struct, sizeof(stats)); + err = COPYOUT(&stats, op->iplo_struct, sizeof(stats)); + if (err != 0) { + IPFERROR(30013); + return EFAULT; + } + return 0; } -/* - * Create a new hash table using the template passed. - */ -int fr_newhtable(op) -iplookupop_t *op; +/* ------------------------------------------------------------------------ */ +/* Function: ipf_htable_create */ +/* Returns: int - 0 = success, else error */ +/* Parameters: softc(I) - pointer to soft context main structure */ +/* arg(I) - pointer to local context to use */ +/* op(I) - pointer to lookup operation data */ +/* */ +/* Create a new hash table using the template passed. */ +/* ------------------------------------------------------------------------ */ +static int +ipf_htable_create(softc, arg, op) + ipf_main_softc_t *softc; + void *arg; + iplookupop_t *op; { - iphtable_t *iph, *oiph; + ipf_htable_softc_t *softh = arg; + iphtable_t htab, *iph, *oiph; char name[FR_GROUPLEN]; int err, i, unit; + if (op->iplo_size != sizeof(htab)) { + IPFERROR(30024); + return EINVAL; + } + err = COPYIN(op->iplo_struct, &htab, sizeof(htab)); + if (err != 0) { + IPFERROR(30003); + return EFAULT; + } + unit = op->iplo_unit; + if (htab.iph_unit != unit) { + IPFERROR(30005); + return EINVAL; + } + if (htab.iph_size < 1) { + IPFERROR(30025); + return EINVAL; + } + + if ((op->iplo_arg & IPHASH_ANON) == 0) { - iph = fr_existshtable(unit, op->iplo_name); + iph = ipf_htable_exists(softh, unit, op->iplo_name); if (iph != NULL) { - if ((iph->iph_flags & IPHASH_DELETE) == 0) + if ((iph->iph_flags & IPHASH_DELETE) == 0) { + IPFERROR(30004); return EEXIST; + } iph->iph_flags &= ~IPHASH_DELETE; + iph->iph_ref++; return 0; } } KMALLOC(iph, iphtable_t *); if (iph == NULL) { - ipht_nomem[op->iplo_unit]++; + softh->ipht_nomem[op->iplo_unit + 1]++; + IPFERROR(30002); return ENOMEM; } - err = COPYIN(op->iplo_struct, iph, sizeof(*iph)); - if (err != 0) { - KFREE(iph); - return EFAULT; - } - - if (iph->iph_unit != unit) { - KFREE(iph); - return EINVAL; - } + *iph = htab; if ((op->iplo_arg & IPHASH_ANON) != 0) { i = IPHASH_ANON; @@ -139,7 +334,7 @@ iplookupop_t *op; #else (void)sprintf(name, "%u", i); #endif - for (oiph = ipf_htables[unit]; oiph != NULL; + for (oiph = softh->ipf_htables[unit + 1]; oiph != NULL; oiph = oiph->iph_next) if (strncmp(oiph->iph_name, name, sizeof(oiph->iph_name)) == 0) @@ -149,113 +344,316 @@ iplookupop_t *op; (void)strncpy(iph->iph_name, name, sizeof(iph->iph_name)); (void)strncpy(op->iplo_name, name, sizeof(op->iplo_name)); iph->iph_type |= IPHASH_ANON; + } else { + (void)strncpy(iph->iph_name, op->iplo_name, + sizeof(iph->iph_name)); + iph->iph_name[sizeof(iph->iph_name) - 1] = '\0'; } KMALLOCS(iph->iph_table, iphtent_t **, iph->iph_size * sizeof(*iph->iph_table)); if (iph->iph_table == NULL) { KFREE(iph); - ipht_nomem[unit]++; + softh->ipht_nomem[unit + 1]++; + IPFERROR(30006); return ENOMEM; } bzero((char *)iph->iph_table, iph->iph_size * sizeof(*iph->iph_table)); - iph->iph_masks = 0; - iph->iph_list = NULL; + iph->iph_maskset[0] = 0; + iph->iph_maskset[1] = 0; + iph->iph_maskset[2] = 0; + iph->iph_maskset[3] = 0; iph->iph_ref = 1; - iph->iph_next = ipf_htables[unit]; - iph->iph_pnext = &ipf_htables[unit]; - if (ipf_htables[unit] != NULL) - ipf_htables[unit]->iph_pnext = &iph->iph_next; - ipf_htables[unit] = iph; - ipf_nhtables[unit]++; + iph->iph_list = NULL; + iph->iph_tail = &iph->iph_list; + iph->iph_next = softh->ipf_htables[unit + 1]; + iph->iph_pnext = &softh->ipf_htables[unit + 1]; + if (softh->ipf_htables[unit + 1] != NULL) + softh->ipf_htables[unit + 1]->iph_pnext = &iph->iph_next; + softh->ipf_htables[unit + 1] = iph; + + softh->ipf_nhtables[unit + 1]++; return 0; } -/* - */ -int fr_removehtable(unit, name) -int unit; -char *name; +/* ------------------------------------------------------------------------ */ +/* Function: ipf_htable_table_del */ +/* Returns: int - 0 = success, else error */ +/* Parameters: softc(I) - pointer to soft context main structure */ +/* arg(I) - pointer to local context to use */ +/* op(I) - pointer to lookup operation data */ +/* */ +/* ------------------------------------------------------------------------ */ +static int +ipf_htable_table_del(softc, arg, op) + ipf_main_softc_t *softc; + void *arg; + iplookupop_t *op; +{ + return ipf_htable_destroy(softc, arg, op->iplo_unit, op->iplo_name); +} + + +/* ------------------------------------------------------------------------ */ +/* Function: ipf_htable_destroy */ +/* Returns: int - 0 = success, else error */ +/* Parameters: softc(I) - pointer to soft context main structure */ +/* arg(I) - pointer to local context to use */ +/* op(I) - pointer to lookup operation data */ +/* */ +/* Find the hash table that belongs to the relevant part of ipfilter with a */ +/* matching name and attempt to destroy it. If it is in use, empty it out */ +/* and mark it for deletion so that when all the references disappear, it */ +/* can be removed. */ +/* ------------------------------------------------------------------------ */ +static int +ipf_htable_destroy(softc, arg, unit, name) + ipf_main_softc_t *softc; + void *arg; + int unit; + char *name; { iphtable_t *iph; - iph = fr_findhtable(unit, name); - if (iph == NULL) + iph = ipf_htable_find(arg, unit, name); + if (iph == NULL) { + IPFERROR(30007); return ESRCH; + } if (iph->iph_unit != unit) { + IPFERROR(30008); return EINVAL; } if (iph->iph_ref != 0) { - (void) fr_clearhtable(iph); + ipf_htable_clear(softc, arg, iph); iph->iph_flags |= IPHASH_DELETE; return 0; } - fr_delhtable(iph); + ipf_htable_remove(softc, arg, iph); return 0; } -int fr_clearhtable(iph) -iphtable_t *iph; +/* ------------------------------------------------------------------------ */ +/* Function: ipf_htable_clear */ +/* Returns: int - 0 = success, else error */ +/* Parameters: softc(I) - pointer to soft context main structure */ +/* arg(I) - pointer to local context to use */ +/* iph(I) - pointer to hash table to destroy */ +/* */ +/* Clean out the hash table by walking the list of entries and removing */ +/* each one, one by one. */ +/* ------------------------------------------------------------------------ */ +static int +ipf_htable_clear(softc, arg, iph) + ipf_main_softc_t *softc; + void *arg; + iphtable_t *iph; { iphtent_t *ipe; while ((ipe = iph->iph_list) != NULL) - if (fr_delhtent(iph, ipe) != 0) + if (ipf_htent_remove(softc, arg, iph, ipe) != 0) return 1; return 0; } -int fr_delhtable(iph) -iphtable_t *iph; +/* ------------------------------------------------------------------------ */ +/* Function: ipf_htable_free */ +/* Returns: Nil */ +/* Parameters: arg(I) - pointer to local context to use */ +/* iph(I) - pointer to hash table to destroy */ +/* */ +/* ------------------------------------------------------------------------ */ +static void +ipf_htable_free(arg, iph) + void *arg; + iphtable_t *iph; +{ + ipf_htable_softc_t *softh = arg; + + if (iph->iph_next != NULL) + iph->iph_next->iph_pnext = iph->iph_pnext; + if (iph->iph_pnext != NULL) + *iph->iph_pnext = iph->iph_next; + iph->iph_pnext = NULL; + iph->iph_next = NULL; + + softh->ipf_nhtables[iph->iph_unit + 1]--; + + KFREES(iph->iph_table, iph->iph_size * sizeof(*iph->iph_table)); + KFREE(iph); +} + + +/* ------------------------------------------------------------------------ */ +/* Function: ipf_htable_remove */ +/* Returns: int - 0 = success, else error */ +/* Parameters: softc(I) - pointer to soft context main structure */ +/* arg(I) - pointer to local context to use */ +/* iph(I) - pointer to hash table to destroy */ +/* */ +/* It is necessary to unlink here as well as free (called by deref) so that */ +/* the while loop in ipf_htable_flush() functions properly. */ +/* ------------------------------------------------------------------------ */ +static int +ipf_htable_remove(softc, arg, iph) + ipf_main_softc_t *softc; + void *arg; + iphtable_t *iph; { - if (fr_clearhtable(iph) != 0) + if (ipf_htable_clear(softc, arg, iph) != 0) return 1; if (iph->iph_pnext != NULL) *iph->iph_pnext = iph->iph_next; if (iph->iph_next != NULL) iph->iph_next->iph_pnext = iph->iph_pnext; + iph->iph_pnext = NULL; + iph->iph_next = NULL; - ipf_nhtables[iph->iph_unit]--; - - return fr_derefhtable(iph); + return ipf_htable_deref(softc, arg, iph); } -/* - * Delete an entry from a hash table. - */ -int fr_delhtent(iph, ipe) -iphtable_t *iph; -iphtent_t *ipe; +/* ------------------------------------------------------------------------ */ +/* Function: ipf_htable_node_del */ +/* Returns: int - 0 = success, else error */ +/* Parameters: softc(I) - pointer to soft context main structure */ +/* arg(I) - pointer to local context to use */ +/* op(I) - pointer to lookup operation data */ +/* uid(I) - real uid of process doing operation */ +/* */ +/* ------------------------------------------------------------------------ */ +static int +ipf_htable_node_del(softc, arg, op, uid) + ipf_main_softc_t *softc; + void *arg; + iplookupop_t *op; + int uid; +{ + iphtable_t *iph; + iphtent_t hte, *ent; + int err; + + if (op->iplo_size != sizeof(hte)) { + IPFERROR(30014); + return EINVAL; + } + + err = COPYIN(op->iplo_struct, &hte, sizeof(hte)); + if (err != 0) { + IPFERROR(30015); + return EFAULT; + } + + iph = ipf_htable_find(arg, op->iplo_unit, op->iplo_name); + if (iph == NULL) { + IPFERROR(30016); + return ESRCH; + } + + ent = ipf_htent_find(iph, &hte); + if (ent == NULL) { + IPFERROR(30022); + return ESRCH; + } + + if ((uid != 0) && (ent->ipe_uid != uid)) { + IPFERROR(30023); + return EACCES; + } + + err = ipf_htent_remove(softc, arg, iph, ent); + + return err; +} + + +/* ------------------------------------------------------------------------ */ +/* Function: ipf_htable_node_del */ +/* Returns: int - 0 = success, else error */ +/* Parameters: softc(I) - pointer to soft context main structure */ +/* arg(I) - pointer to local context to use */ +/* op(I) - pointer to lookup operation data */ +/* */ +/* ------------------------------------------------------------------------ */ +static int +ipf_htable_table_add(softc, arg, op) + ipf_main_softc_t *softc; + void *arg; + iplookupop_t *op; +{ + int err; + + if (ipf_htable_find(arg, op->iplo_unit, op->iplo_name) != NULL) { + IPFERROR(30017); + err = EEXIST; + } else { + err = ipf_htable_create(softc, arg, op); + } + + return err; +} + + +/* ------------------------------------------------------------------------ */ +/* Function: ipf_htent_remove */ +/* Returns: int - 0 = success, else error */ +/* Parameters: softc(I) - pointer to soft context main structure */ +/* arg(I) - pointer to local context to use */ +/* iph(I) - pointer to hash table */ +/* ipe(I) - pointer to hash table entry to remove */ +/* */ +/* Delete an entry from a hash table. */ +/* ------------------------------------------------------------------------ */ +static int +ipf_htent_remove(softc, arg, iph, ipe) + ipf_main_softc_t *softc; + void *arg; + iphtable_t *iph; + iphtent_t *ipe; { - if (ipe->ipe_phnext != NULL) - *ipe->ipe_phnext = ipe->ipe_hnext; + if (iph->iph_tail == &ipe->ipe_next) + iph->iph_tail = ipe->ipe_pnext; + if (ipe->ipe_hnext != NULL) ipe->ipe_hnext->ipe_phnext = ipe->ipe_phnext; + if (ipe->ipe_phnext != NULL) + *ipe->ipe_phnext = ipe->ipe_hnext; + ipe->ipe_phnext = NULL; + ipe->ipe_hnext = NULL; + + if (ipe->ipe_dnext != NULL) + ipe->ipe_dnext->ipe_pdnext = ipe->ipe_pdnext; + if (ipe->ipe_pdnext != NULL) + *ipe->ipe_pdnext = ipe->ipe_dnext; + ipe->ipe_pdnext = NULL; + ipe->ipe_dnext = NULL; - if (ipe->ipe_pnext != NULL) - *ipe->ipe_pnext = ipe->ipe_next; if (ipe->ipe_next != NULL) ipe->ipe_next->ipe_pnext = ipe->ipe_pnext; + if (ipe->ipe_pnext != NULL) + *ipe->ipe_pnext = ipe->ipe_next; + ipe->ipe_pnext = NULL; + ipe->ipe_next = NULL; switch (iph->iph_type & ~IPHASH_ANON) { case IPHASH_GROUPMAP : if (ipe->ipe_group != NULL) - fr_delgroup(ipe->ipe_group, IPL_LOGIPF, fr_active); + ipf_group_del(softc, ipe->ipe_ptr, NULL); break; default : @@ -264,35 +662,54 @@ iphtent_t *ipe; break; } - return fr_derefhtent(ipe); + return ipf_htent_deref(arg, ipe); } -int fr_derefhtable(iph) -iphtable_t *iph; +/* ------------------------------------------------------------------------ */ +/* Function: ipf_htable_deref */ +/* Returns: int - 0 = success, else error */ +/* Parameters: softc(I) - pointer to soft context main structure */ +/* arg(I) - pointer to local context to use */ +/* object(I) - pointer to hash table */ +/* */ +/* ------------------------------------------------------------------------ */ +static int +ipf_htable_deref(softc, arg, object) + ipf_main_softc_t *softc; + void *arg, *object; { + ipf_htable_softc_t *softh = arg; + iphtable_t *iph = object; int refs; iph->iph_ref--; refs = iph->iph_ref; if (iph->iph_ref == 0) { - KFREES(iph->iph_table, iph->iph_size * sizeof(*iph->iph_table)); - KFREE(iph); + ipf_htable_free(softh, iph); } return refs; } -int fr_derefhtent(ipe) -iphtent_t *ipe; +/* ------------------------------------------------------------------------ */ +/* Function: ipf_htent_deref */ +/* Parameters: arg(I) - pointer to local context to use */ +/* ipe(I) - */ +/* */ +/* ------------------------------------------------------------------------ */ +static int +ipf_htent_deref(arg, ipe) + void *arg; + iphtent_t *ipe; { + ipf_htable_softc_t *softh = arg; ipe->ipe_ref--; if (ipe->ipe_ref == 0) { - ipf_nhtnodes[ipe->ipe_unit]--; - + softh->ipf_nhtnodes[ipe->ipe_unit + 1]--; KFREE(ipe); return 0; @@ -302,26 +719,87 @@ iphtent_t *ipe; } -iphtable_t *fr_existshtable(unit, name) -int unit; -char *name; +/* ------------------------------------------------------------------------ */ +/* Function: ipf_htable_exists */ +/* Parameters: arg(I) - pointer to local context to use */ +/* */ +/* ------------------------------------------------------------------------ */ +static void * +ipf_htable_exists(arg, unit, name) + void *arg; + int unit; + char *name; { + ipf_htable_softc_t *softh = arg; iphtable_t *iph; - for (iph = ipf_htables[unit]; iph != NULL; iph = iph->iph_next) - if (strncmp(iph->iph_name, name, sizeof(iph->iph_name)) == 0) - break; + if (unit == IPL_LOGALL) { + int i; + + for (i = 0; i <= LOOKUP_POOL_MAX; i++) { + for (iph = softh->ipf_htables[i]; iph != NULL; + iph = iph->iph_next) { + if (strncmp(iph->iph_name, name, + sizeof(iph->iph_name)) == 0) + break; + } + if (iph != NULL) + break; + } + } else { + for (iph = softh->ipf_htables[unit + 1]; iph != NULL; + iph = iph->iph_next) { + if (strncmp(iph->iph_name, name, + sizeof(iph->iph_name)) == 0) + break; + } + } return iph; } -iphtable_t *fr_findhtable(unit, name) -int unit; -char *name; +/* ------------------------------------------------------------------------ */ +/* Function: ipf_htable_select_add_ref */ +/* Returns: void * - NULL = failure, else pointer to the hash table */ +/* Parameters: arg(I) - pointer to local context to use */ +/* unit(I) - ipfilter device to which we are working on */ +/* name(I) - name of the hash table */ +/* */ +/* ------------------------------------------------------------------------ */ +static void * +ipf_htable_select_add_ref(arg, unit, name) + void *arg; + int unit; + char *name; { iphtable_t *iph; - iph = fr_existshtable(unit, name); + iph = ipf_htable_exists(arg, unit, name); + if (iph != NULL) { + ATOMIC_INC32(iph->iph_ref); + } + return iph; +} + + +/* ------------------------------------------------------------------------ */ +/* Function: ipf_htable_find */ +/* Returns: void * - NULL = failure, else pointer to the hash table */ +/* Parameters: arg(I) - pointer to local context to use */ +/* unit(I) - ipfilter device to which we are working on */ +/* name(I) - name of the hash table */ +/* */ +/* This function is exposed becaues it is used in the group-map feature. */ +/* ------------------------------------------------------------------------ */ +iphtable_t * +ipf_htable_find(arg, unit, name) + void *arg; + int unit; + char *name; +{ + iphtable_t *iph; + + iph = ipf_htable_exists(arg, unit, name); if ((iph != NULL) && (iph->iph_flags & IPHASH_DELETE) == 0) return iph; @@ -329,19 +807,31 @@ char *name; } -size_t fr_flushhtable(op) -iplookupflush_t *op; +/* ------------------------------------------------------------------------ */ +/* Function: ipf_htable_flush */ +/* Returns: size_t - number of entries flushed */ +/* Parameters: softc(I) - pointer to soft context main structure */ +/* arg(I) - pointer to local context to use */ +/* op(I) - pointer to lookup operation data */ +/* */ +/* ------------------------------------------------------------------------ */ +static size_t +ipf_htable_flush(softc, arg, op) + ipf_main_softc_t *softc; + void *arg; + iplookupflush_t *op; { + ipf_htable_softc_t *softh = arg; iphtable_t *iph; size_t freed; int i; freed = 0; - for (i = 0; i <= IPL_LOGMAX; i++) { + for (i = -1; i <= IPL_LOGMAX; i++) { if (op->iplf_unit == i || op->iplf_unit == IPL_LOGALL) { - while ((iph = ipf_htables[i]) != NULL) { - if (fr_delhtable(iph) == 0) { + while ((iph = softh->ipf_htables[i + 1]) != NULL) { + if (ipf_htable_remove(softc, arg, iph) == 0) { freed++; } else { iph->iph_flags |= IPHASH_DELETE; @@ -354,13 +844,73 @@ iplookupflush_t *op; } -/* - * Add an entry to a hash table. - */ -int fr_addhtent(iph, ipeo) -iphtable_t *iph; -iphtent_t *ipeo; +/* ------------------------------------------------------------------------ */ +/* Function: ipf_htable_node_add */ +/* Returns: int - 0 = success, else error */ +/* Parameters: softc(I) - pointer to soft context main structure */ +/* arg(I) - pointer to local context to use */ +/* op(I) - pointer to lookup operation data */ +/* uid(I) - real uid of process doing operation */ +/* */ +/* ------------------------------------------------------------------------ */ +static int +ipf_htable_node_add(softc, arg, op, uid) + ipf_main_softc_t *softc; + void *arg; + iplookupop_t *op; + int uid; { + iphtable_t *iph; + iphtent_t hte; + int err; + + if (op->iplo_size != sizeof(hte)) { + IPFERROR(30018); + return EINVAL; + } + + err = COPYIN(op->iplo_struct, &hte, sizeof(hte)); + if (err != 0) { + IPFERROR(30019); + return EFAULT; + } + hte.ipe_uid = uid; + + iph = ipf_htable_find(arg, op->iplo_unit, op->iplo_name); + if (iph == NULL) { + IPFERROR(30020); + return ESRCH; + } + + if (ipf_htent_find(iph, &hte) != NULL) { + IPFERROR(30021); + return EEXIST; + } + + err = ipf_htent_insert(softc, arg, iph, &hte); + + return err; +} + + +/* ------------------------------------------------------------------------ */ +/* Function: ipf_htent_insert */ +/* Returns: int - 0 = success, -1 = error */ +/* Parameters: softc(I) - pointer to soft context main structure */ +/* arg(I) - pointer to local context to use */ +/* op(I) - pointer to lookup operation data */ +/* ipeo(I) - */ +/* */ +/* Add an entry to a hash table. */ +/* ------------------------------------------------------------------------ */ +static int +ipf_htent_insert(softc, arg, iph, ipeo) + ipf_main_softc_t *softc; + void *arg; + iphtable_t *iph; + iphtent_t *ipeo; +{ + ipf_htable_softc_t *softh = arg; iphtent_t *ipe; u_int hv; int bits; @@ -370,13 +920,35 @@ iphtent_t *ipeo; return -1; bcopy((char *)ipeo, (char *)ipe, sizeof(*ipe)); - ipe->ipe_addr.in4_addr &= ipe->ipe_mask.in4_addr; - ipe->ipe_addr.in4_addr = ntohl(ipe->ipe_addr.in4_addr); - bits = count4bits(ipe->ipe_mask.in4_addr); - ipe->ipe_mask.in4_addr = ntohl(ipe->ipe_mask.in4_addr); + ipe->ipe_addr.i6[0] &= ipe->ipe_mask.i6[0]; + if (ipe->ipe_family == AF_INET) { + bits = count4bits(ipe->ipe_mask.in4_addr); + ipe->ipe_addr.i6[1] = 0; + ipe->ipe_addr.i6[2] = 0; + ipe->ipe_addr.i6[3] = 0; + ipe->ipe_mask.i6[1] = 0; + ipe->ipe_mask.i6[2] = 0; + ipe->ipe_mask.i6[3] = 0; + hv = IPE_V4_HASH_FN(ipe->ipe_addr.in4_addr, + ipe->ipe_mask.in4_addr, iph->iph_size); + } else +#ifdef USE_INET6 + if (ipe->ipe_family == AF_INET6) { + ipe->ipe_addr.i6[1] &= ipe->ipe_mask.i6[1]; + ipe->ipe_addr.i6[2] &= ipe->ipe_mask.i6[2]; + ipe->ipe_addr.i6[3] &= ipe->ipe_mask.i6[3]; - hv = IPE_HASH_FN(ipe->ipe_addr.in4_addr, ipe->ipe_mask.in4_addr, - iph->iph_size); + bits = count6bits(ipe->ipe_mask.i6); + hv = IPE_V6_HASH_FN(ipe->ipe_addr.i6, + ipe->ipe_mask.i6, iph->iph_size); + } else +#endif + { + KFREE(ipe); + return -1; + } + + ipe->ipe_owner = iph; ipe->ipe_ref = 1; ipe->ipe_hnext = iph->iph_table[hv]; ipe->ipe_phnext = iph->iph_table + hv; @@ -385,21 +957,63 @@ iphtent_t *ipeo; iph->iph_table[hv]->ipe_phnext = &ipe->ipe_hnext; iph->iph_table[hv] = ipe; - ipe->ipe_next = iph->iph_list; - ipe->ipe_pnext = &iph->iph_list; - if (ipe->ipe_next != NULL) - ipe->ipe_next->ipe_pnext = &ipe->ipe_next; - iph->iph_list = ipe; + ipe->ipe_pnext = iph->iph_tail; + *iph->iph_tail = ipe; + iph->iph_tail = &ipe->ipe_next; + ipe->ipe_next = NULL; - if ((bits >= 0) && (bits != 32)) - iph->iph_masks |= 1 << bits; + if (ipe->ipe_die != 0) { + /* + * If the new node has a given expiration time, insert it + * into the list of expiring nodes with the ones to be + * removed first added to the front of the list. The + * insertion is O(n) but it is kept sorted for quick scans + * at expiration interval checks. + */ + iphtent_t *n; + + ipe->ipe_die = softc->ipf_ticks + IPF_TTLVAL(ipe->ipe_die); + for (n = softh->ipf_node_explist; n != NULL; n = n->ipe_dnext) { + if (ipe->ipe_die < n->ipe_die) + break; + if (n->ipe_dnext == NULL) { + /* + * We've got to the last node and everything + * wanted to be expired before this new node, + * so we have to tack it on the end... + */ + n->ipe_dnext = ipe; + ipe->ipe_pdnext = &n->ipe_dnext; + n = NULL; + break; + } + } + + if (softh->ipf_node_explist == NULL) { + softh->ipf_node_explist = ipe; + ipe->ipe_pdnext = &softh->ipf_node_explist; + } else if (n != NULL) { + ipe->ipe_dnext = n; + ipe->ipe_pdnext = n->ipe_pdnext; + n->ipe_pdnext = &ipe->ipe_dnext; + } + } + + if (ipe->ipe_family == AF_INET) { + ipf_inet_mask_add(bits, &iph->iph_v4_masks); + } +#ifdef USE_INET6 + else if (ipe->ipe_family == AF_INET6) { + ipf_inet6_mask_add(bits, &ipe->ipe_mask, &iph->iph_v6_masks); + } +#endif switch (iph->iph_type & ~IPHASH_ANON) { case IPHASH_GROUPMAP : - ipe->ipe_ptr = fr_addgroup(ipe->ipe_group, NULL, + ipe->ipe_ptr = ipf_group_add(softc, ipe->ipe_group, NULL, iph->iph_flags, IPL_LOGIPF, - fr_active); + softc->ipf_active); break; default : @@ -409,116 +1023,218 @@ iphtent_t *ipeo; } ipe->ipe_unit = iph->iph_unit; - ipf_nhtnodes[ipe->ipe_unit]++; + softh->ipf_nhtnodes[ipe->ipe_unit + 1]++; return 0; } -void *fr_iphmfindgroup(tptr, aptr) -void *tptr, *aptr; +/* ------------------------------------------------------------------------ */ +/* Function: ipf_htent_find */ +/* Returns: int - 0 = success, else error */ +/* Parameters: iph(I) - pointer to table to search */ +/* ipeo(I) - pointer to entry to find */ +/* */ +/* While it isn't absolutely necessary to for the address and mask to be */ +/* passed in through an iphtent_t structure, one is always present when it */ +/* is time to call this function, so it is just more convenient. */ +/* ------------------------------------------------------------------------ */ +static iphtent_t * +ipf_htent_find(iph, ipeo) + iphtable_t *iph; + iphtent_t *ipeo; +{ + iphtent_t ipe, *ent; + u_int hv; + int bits; + + bcopy((char *)ipeo, (char *)&ipe, sizeof(ipe)); + ipe.ipe_addr.i6[0] &= ipe.ipe_mask.i6[0]; + ipe.ipe_addr.i6[1] &= ipe.ipe_mask.i6[1]; + ipe.ipe_addr.i6[2] &= ipe.ipe_mask.i6[2]; + ipe.ipe_addr.i6[3] &= ipe.ipe_mask.i6[3]; + if (ipe.ipe_family == AF_INET) { + bits = count4bits(ipe.ipe_mask.in4_addr); + ipe.ipe_addr.i6[1] = 0; + ipe.ipe_addr.i6[2] = 0; + ipe.ipe_addr.i6[3] = 0; + ipe.ipe_mask.i6[1] = 0; + ipe.ipe_mask.i6[2] = 0; + ipe.ipe_mask.i6[3] = 0; + hv = IPE_V4_HASH_FN(ipe.ipe_addr.in4_addr, + ipe.ipe_mask.in4_addr, iph->iph_size); + } else +#ifdef USE_INET6 + if (ipe.ipe_family == AF_INET6) { + bits = count6bits(ipe.ipe_mask.i6); + hv = IPE_V6_HASH_FN(ipe.ipe_addr.i6, + ipe.ipe_mask.i6, iph->iph_size); + } else +#endif + return NULL; + + for (ent = iph->iph_table[hv]; ent != NULL; ent = ent->ipe_hnext) { + if (ent->ipe_family != ipe.ipe_family) + continue; + if (IP6_NEQ(&ipe.ipe_addr, &ent->ipe_addr)) + continue; + if (IP6_NEQ(&ipe.ipe_mask, &ent->ipe_mask)) + continue; + break; + } + + return ent; +} + + +/* ------------------------------------------------------------------------ */ +/* Function: ipf_iphmfindgroup */ +/* Returns: int - 0 = success, else error */ +/* Parameters: softc(I) - pointer to soft context main structure */ +/* tptr(I) - */ +/* aptr(I) - */ +/* */ +/* Search a hash table for a matching entry and return the pointer stored */ +/* in it for use as the next group of rules to search. */ +/* */ +/* This function is exposed becaues it is used in the group-map feature. */ +/* ------------------------------------------------------------------------ */ +void * +ipf_iphmfindgroup(softc, tptr, aptr) + ipf_main_softc_t *softc; + void *tptr, *aptr; { struct in_addr *addr; iphtable_t *iph; iphtent_t *ipe; void *rval; - READ_ENTER(&ip_poolrw); + READ_ENTER(&softc->ipf_poolrw); iph = tptr; addr = aptr; - ipe = fr_iphmfind(iph, addr); + ipe = ipf_iphmfind(iph, addr); if (ipe != NULL) rval = ipe->ipe_ptr; else rval = NULL; - RWLOCK_EXIT(&ip_poolrw); + RWLOCK_EXIT(&softc->ipf_poolrw); return rval; } /* ------------------------------------------------------------------------ */ -/* Function: fr_iphmfindip */ +/* Function: ipf_iphmfindip */ /* Returns: int - 0 == +ve match, -1 == error, 1 == -ve/no match */ -/* Parameters: tptr(I) - pointer to the pool to search */ +/* Parameters: softc(I) - pointer to soft context main structure */ +/* tptr(I) - pointer to the pool to search */ /* ipversion(I) - IP protocol version (4 or 6) */ /* aptr(I) - pointer to address information */ +/* bytes(I) - packet length */ /* */ /* Search the hash table for a given address and return a search result. */ /* ------------------------------------------------------------------------ */ -int fr_iphmfindip(tptr, ipversion, aptr) -void *tptr, *aptr; -int ipversion; +static int +ipf_iphmfindip(softc, tptr, ipversion, aptr, bytes) + ipf_main_softc_t *softc; + void *tptr, *aptr; + int ipversion; + u_int bytes; { struct in_addr *addr; iphtable_t *iph; iphtent_t *ipe; int rval; - if (ipversion != 4) - return -1; - if (tptr == NULL || aptr == NULL) return -1; iph = tptr; addr = aptr; - READ_ENTER(&ip_poolrw); - ipe = fr_iphmfind(iph, addr); - if (ipe != NULL) + READ_ENTER(&softc->ipf_poolrw); + if (ipversion == 4) { + ipe = ipf_iphmfind(iph, addr); +#ifdef USE_INET6 + } else if (ipversion == 6) { + ipe = ipf_iphmfind6(iph, (i6addr_t *)addr); +#endif + } else { + ipe = NULL; + } + + if (ipe != NULL) { rval = 0; - else + ipe->ipe_hits++; + ipe->ipe_bytes += bytes; + } else { rval = 1; - RWLOCK_EXIT(&ip_poolrw); + } + RWLOCK_EXIT(&softc->ipf_poolrw); return rval; } -/* Locks: ip_poolrw */ -static iphtent_t *fr_iphmfind(iph, addr) -iphtable_t *iph; -struct in_addr *addr; +/* ------------------------------------------------------------------------ */ +/* Function: ipf_iphmfindip */ +/* Parameters: iph(I) - pointer to hash table */ +/* addr(I) - pointer to IPv4 address */ +/* Locks: ipf_poolrw */ +/* */ +/* ------------------------------------------------------------------------ */ +static iphtent_t * +ipf_iphmfind(iph, addr) + iphtable_t *iph; + struct in_addr *addr; { - u_32_t hmsk, msk, ips; + u_32_t msk, ips; iphtent_t *ipe; u_int hv; + int i; - hmsk = iph->iph_masks; - msk = 0xffffffff; + i = 0; maskloop: - ips = ntohl(addr->s_addr) & msk; - hv = IPE_HASH_FN(ips, msk, iph->iph_size); + msk = iph->iph_v4_masks.imt4_active[i]; + ips = addr->s_addr & msk; + hv = IPE_V4_HASH_FN(ips, msk, iph->iph_size); for (ipe = iph->iph_table[hv]; (ipe != NULL); ipe = ipe->ipe_hnext) { - if (ipe->ipe_mask.in4_addr != msk || - ipe->ipe_addr.in4_addr != ips) { + if ((ipe->ipe_family != AF_INET) || + (ipe->ipe_mask.in4_addr != msk) || + (ipe->ipe_addr.in4_addr != ips)) { continue; } break; } - if ((ipe == NULL) && (hmsk != 0)) { - while (hmsk != 0) { - msk <<= 1; - if (hmsk & 0x80000000) - break; - hmsk <<= 1; - } - if (hmsk != 0) { - hmsk <<= 1; + if (ipe == NULL) { + i++; + if (i < iph->iph_v4_masks.imt4_max) goto maskloop; - } } return ipe; } -int fr_htable_getnext(token, ilp) -ipftoken_t *token; -ipflookupiter_t *ilp; +/* ------------------------------------------------------------------------ */ +/* Function: ipf_htable_iter_next */ +/* Returns: int - 0 = success, else error */ +/* Parameters: softc(I) - pointer to soft context main structure */ +/* arg(I) - pointer to local context to use */ +/* token(I) - */ +/* ilp(I) - */ +/* */ +/* ------------------------------------------------------------------------ */ +static int +ipf_htable_iter_next(softc, arg, token, ilp) + ipf_main_softc_t *softc; + void *arg; + ipftoken_t *token; + ipflookupiter_t *ilp; { + ipf_htable_softc_t *softh = arg; iphtent_t *node, zn, *nextnode; iphtable_t *iph, zp, *nextiph; + void *hnext; int err; err = 0; @@ -527,14 +1243,14 @@ ipflookupiter_t *ilp; nextiph = NULL; nextnode = NULL; - READ_ENTER(&ip_poolrw); + READ_ENTER(&softc->ipf_poolrw); switch (ilp->ili_otype) { case IPFLOOKUPITER_LIST : iph = token->ipt_data; if (iph == NULL) { - nextiph = ipf_htables[(int)ilp->ili_unit]; + nextiph = softh->ipf_htables[(int)ilp->ili_unit + 1]; } else { nextiph = iph->iph_next; } @@ -547,15 +1263,18 @@ ipflookupiter_t *ilp; nextiph = &zp; token->ipt_data = NULL; } + hnext = nextiph->iph_next; break; case IPFLOOKUPITER_NODE : node = token->ipt_data; if (node == NULL) { - iph = fr_findhtable(ilp->ili_unit, ilp->ili_name); - if (iph == NULL) + iph = ipf_htable_find(arg, ilp->ili_unit, + ilp->ili_name); + if (iph == NULL) { + IPFERROR(30009); err = ESRCH; - else { + } else { nextnode = iph->iph_list; } } else { @@ -570,73 +1289,179 @@ ipflookupiter_t *ilp; nextnode = &zn; token->ipt_data = NULL; } + hnext = nextnode->ipe_next; break; + default : + IPFERROR(30010); err = EINVAL; + hnext = NULL; break; } - RWLOCK_EXIT(&ip_poolrw); + RWLOCK_EXIT(&softc->ipf_poolrw); if (err != 0) return err; switch (ilp->ili_otype) { case IPFLOOKUPITER_LIST : - if (iph != NULL) { - WRITE_ENTER(&ip_poolrw); - fr_derefhtable(iph); - RWLOCK_EXIT(&ip_poolrw); - } err = COPYOUT(nextiph, ilp->ili_data, sizeof(*nextiph)); - if (err != 0) + if (err != 0) { + IPFERROR(30011); err = EFAULT; + } + if (iph != NULL) { + WRITE_ENTER(&softc->ipf_poolrw); + ipf_htable_deref(softc, softh, iph); + RWLOCK_EXIT(&softc->ipf_poolrw); + } break; case IPFLOOKUPITER_NODE : - if (node != NULL) { - WRITE_ENTER(&ip_poolrw); - fr_derefhtent(node); - RWLOCK_EXIT(&ip_poolrw); - } err = COPYOUT(nextnode, ilp->ili_data, sizeof(*nextnode)); - if (err != 0) + if (err != 0) { + IPFERROR(30012); err = EFAULT; + } + if (node != NULL) { + WRITE_ENTER(&softc->ipf_poolrw); + ipf_htent_deref(softc, node); + RWLOCK_EXIT(&softc->ipf_poolrw); + } break; } + if (hnext == NULL) + ipf_token_mark_complete(token); + return err; } -void fr_htable_iterderef(otype, unit, data) -u_int otype; -int unit; -void *data; +/* ------------------------------------------------------------------------ */ +/* Function: ipf_htable_iter_deref */ +/* Returns: int - 0 = success, else error */ +/* Parameters: softc(I) - pointer to soft context main structure */ +/* arg(I) - pointer to local context to use */ +/* otype(I) - which data structure type is being walked */ +/* unit(I) - ipfilter device to which we are working on */ +/* data(I) - pointer to old data structure */ +/* */ +/* ------------------------------------------------------------------------ */ +static int +ipf_htable_iter_deref(softc, arg, otype, unit, data) + ipf_main_softc_t *softc; + void *arg; + int otype; + int unit; + void *data; { if (data == NULL) - return; + return EFAULT; - if (unit < 0 || unit > IPL_LOGMAX) - return; + if (unit < -1 || unit > IPL_LOGMAX) + return EINVAL; switch (otype) { case IPFLOOKUPITER_LIST : - WRITE_ENTER(&ip_poolrw); - fr_derefhtable((iphtable_t *)data); - RWLOCK_EXIT(&ip_poolrw); + ipf_htable_deref(softc, arg, (iphtable_t *)data); break; case IPFLOOKUPITER_NODE : - WRITE_ENTER(&ip_poolrw); - fr_derefhtent((iphtent_t *)data); - RWLOCK_EXIT(&ip_poolrw); + ipf_htent_deref(arg, (iphtent_t *)data); break; default : break; } + + return 0; } -#endif /* IPFILTER_LOOKUP */ + +#ifdef USE_INET6 +/* ------------------------------------------------------------------------ */ +/* Function: ipf_iphmfind6 */ +/* Parameters: iph(I) - pointer to hash table */ +/* addr(I) - pointer to IPv6 address */ +/* Locks: ipf_poolrw */ +/* */ +/* ------------------------------------------------------------------------ */ +static iphtent_t * +ipf_iphmfind6(iph, addr) + iphtable_t *iph; + i6addr_t *addr; +{ + i6addr_t *msk, ips; + iphtent_t *ipe; + u_int hv; + int i; + + i = 0; +maskloop: + msk = iph->iph_v6_masks.imt6_active + i; + ips.i6[0] = addr->i6[0] & msk->i6[0]; + ips.i6[1] = addr->i6[1] & msk->i6[1]; + ips.i6[2] = addr->i6[2] & msk->i6[2]; + ips.i6[3] = addr->i6[3] & msk->i6[3]; + hv = IPE_V6_HASH_FN(ips.i6, msk->i6, iph->iph_size); + for (ipe = iph->iph_table[hv]; (ipe != NULL); ipe = ipe->ipe_next) { + if ((ipe->ipe_family != AF_INET6) || + IP6_NEQ(&ipe->ipe_mask, msk) || + IP6_NEQ(&ipe->ipe_addr, &ips)) { + continue; + } + break; + } + + if (ipe == NULL) { + i++; + if (i < iph->iph_v6_masks.imt6_max) + goto maskloop; + } + return ipe; +} +#endif + + +static void +ipf_htable_expire(softc, arg) + ipf_main_softc_t *softc; + void *arg; +{ + ipf_htable_softc_t *softh = arg; + iphtent_t *n; + + while ((n = softh->ipf_node_explist) != NULL) { + if (n->ipe_die > softc->ipf_ticks) + break; + + ipf_htent_remove(softc, softh, n->ipe_owner, n); + } +} + + +#ifndef _KERNEL + +/* ------------------------------------------------------------------------ */ +/* */ +/* ------------------------------------------------------------------------ */ +void +ipf_htable_dump(softc, arg) + ipf_main_softc_t *softc; + void *arg; +{ + ipf_htable_softc_t *softh = arg; + iphtable_t *iph; + int i; + + printf("List of configured hash tables\n"); + for (i = 0; i < IPL_LOGSIZE; i++) + for (iph = softh->ipf_htables[i]; iph != NULL; + iph = iph->iph_next) + printhash(iph, bcopywrap, NULL, opts, NULL); + +} +#endif diff --git a/sys/contrib/ipfilter/netinet/ip_htable.h b/sys/contrib/ipfilter/netinet/ip_htable.h index 2c0881230117..8038bbcc1044 100644 --- a/sys/contrib/ipfilter/netinet/ip_htable.h +++ b/sys/contrib/ipfilter/netinet/ip_htable.h @@ -6,36 +6,52 @@ typedef struct iphtent_s { struct iphtent_s *ipe_next, **ipe_pnext; struct iphtent_s *ipe_hnext, **ipe_phnext; + struct iphtent_s *ipe_dnext, **ipe_pdnext; + struct iphtable_s *ipe_owner; void *ipe_ptr; i6addr_t ipe_addr; i6addr_t ipe_mask; + U_QUAD_T ipe_hits; + U_QUAD_T ipe_bytes; + u_long ipe_die; + int ipe_uid; int ipe_ref; int ipe_unit; + char ipe_family; + char ipe_xxx[3]; union { char ipeu_char[16]; u_long ipeu_long; u_int ipeu_int; - }ipe_un; + } ipe_un; } iphtent_t; #define ipe_value ipe_un.ipeu_int #define ipe_group ipe_un.ipeu_char -#define IPE_HASH_FN(a, m, s) (((a) * (m)) % (s)) - +#define IPE_V4_HASH_FN(a, m, s) ((((m) ^ (a)) - 1 - ((a) >> 8)) % (s)) +#define IPE_V6_HASH_FN(a, m, s) (((((m)[0] ^ (a)[0]) - ((a)[0] >> 8)) + \ + (((m)[1] & (a)[1]) - ((a)[1] >> 8)) + \ + (((m)[2] & (a)[2]) - ((a)[2] >> 8)) + \ + (((m)[3] & (a)[3]) - ((a)[3] >> 8))) % (s)) typedef struct iphtable_s { ipfrwlock_t iph_rwlock; struct iphtable_s *iph_next, **iph_pnext; struct iphtent_s **iph_table; struct iphtent_s *iph_list; + struct iphtent_s **iph_tail; +#ifdef USE_INET6 + ipf_v6_masktab_t iph_v6_masks; +#endif + ipf_v4_masktab_t iph_v4_masks; size_t iph_size; /* size of hash table */ u_long iph_seed; /* hashing seed */ u_32_t iph_flags; u_int iph_unit; /* IPL_LOG* */ u_int iph_ref; u_int iph_type; /* lookup or group map - IPHASH_* */ - u_int iph_masks; /* IPv4 netmasks in use */ + u_int iph_maskset[4]; /* netmasks in use */ char iph_name[FR_GROUPLEN]; /* hash table number */ } iphtable_t; @@ -55,24 +71,11 @@ typedef struct iphtstat_s { } iphtstat_t; -extern iphtable_t *ipf_htables[IPL_LOGSIZE]; - -extern iphtable_t *fr_existshtable __P((int, char *)); -extern int fr_clearhtable __P((iphtable_t *)); -extern void fr_htable_unload __P((void)); -extern int fr_newhtable __P((iplookupop_t *)); -extern iphtable_t *fr_findhtable __P((int, char *)); -extern int fr_removehtable __P((int, char *)); -extern size_t fr_flushhtable __P((iplookupflush_t *)); -extern int fr_addhtent __P((iphtable_t *, iphtent_t *)); -extern int fr_delhtent __P((iphtable_t *, iphtent_t *)); -extern int fr_derefhtable __P((iphtable_t *)); -extern int fr_derefhtent __P((iphtent_t *)); -extern int fr_delhtable __P((iphtable_t *)); -extern void *fr_iphmfindgroup __P((void *, void *)); -extern int fr_iphmfindip __P((void *, int, void *)); -extern int fr_gethtablestat __P((iplookupop_t *)); -extern int fr_htable_getnext __P((ipftoken_t *, ipflookupiter_t *)); -extern void fr_htable_iterderef __P((u_int, int, void *)); +extern void *ipf_iphmfindgroup __P((ipf_main_softc_t *, void *, void *)); +extern iphtable_t *ipf_htable_find __P((void *, int, char *)); +extern ipf_lookup_t ipf_htable_backend; +#ifndef _KERNEL +extern void ipf_htable_dump __P((ipf_main_softc_t *, void *)); +#endif #endif /* __IP_HTABLE_H__ */ diff --git a/sys/contrib/ipfilter/netinet/ip_ipsec_pxy.c b/sys/contrib/ipfilter/netinet/ip_ipsec_pxy.c index e88a6b98b514..980476ad8bf9 100644 --- a/sys/contrib/ipfilter/netinet/ip_ipsec_pxy.c +++ b/sys/contrib/ipfilter/netinet/ip_ipsec_pxy.c @@ -1,152 +1,228 @@ /* - * Copyright (C) 2001-2003 by Darren Reed + * Copyright (C) 2012 by Darren Reed. * * See the IPFILTER.LICENCE file for details on licencing. * * Simple ISAKMP transparent proxy for in-kernel use. For use with the NAT * code. * - * $Id: ip_ipsec_pxy.c,v 2.20.2.8 2006/07/14 06:12:14 darrenr Exp $ + * $Id$ * */ #define IPF_IPSEC_PROXY -int ippr_ipsec_init __P((void)); -void ippr_ipsec_fini __P((void)); -int ippr_ipsec_new __P((fr_info_t *, ap_session_t *, nat_t *)); -void ippr_ipsec_del __P((ap_session_t *)); -int ippr_ipsec_inout __P((fr_info_t *, ap_session_t *, nat_t *)); -int ippr_ipsec_match __P((fr_info_t *, ap_session_t *, nat_t *)); +/* + * IPSec proxy + */ +typedef struct ipf_ipsec_softc_s { + frentry_t ipsec_fr; + int ipsec_proxy_init; + int ipsec_proxy_ttl; + ipftq_t *ipsec_nat_tqe; + ipftq_t *ipsec_state_tqe; + char ipsec_buffer[1500]; +} ipf_ipsec_softc_t; -static frentry_t ipsecfr; -static ipftq_t *ipsecnattqe; -static ipftq_t *ipsecstatetqe; -static char ipsec_buffer[1500]; -int ipsec_proxy_init = 0; -int ipsec_proxy_ttl = 60; +void *ipf_p_ipsec_soft_create __P((ipf_main_softc_t *)); +void ipf_p_ipsec_soft_destroy __P((ipf_main_softc_t *, void *)); +int ipf_p_ipsec_soft_init __P((ipf_main_softc_t *, void *)); +void ipf_p_ipsec_soft_fini __P((ipf_main_softc_t *, void *)); +int ipf_p_ipsec_init __P((void)); +void ipf_p_ipsec_fini __P((void)); +int ipf_p_ipsec_new __P((void *, fr_info_t *, ap_session_t *, nat_t *)); +void ipf_p_ipsec_del __P((ipf_main_softc_t *, ap_session_t *)); +int ipf_p_ipsec_inout __P((void *, fr_info_t *, ap_session_t *, nat_t *)); +int ipf_p_ipsec_match __P((fr_info_t *, ap_session_t *, nat_t *)); + /* * IPSec application proxy initialization. */ -int ippr_ipsec_init() +void * +ipf_p_ipsec_soft_create(softc) + ipf_main_softc_t *softc; { - bzero((char *)&ipsecfr, sizeof(ipsecfr)); - ipsecfr.fr_ref = 1; - ipsecfr.fr_flags = FR_OUTQUE|FR_PASS|FR_QUICK|FR_KEEPSTATE; - MUTEX_INIT(&ipsecfr.fr_lock, "IPsec proxy rule lock"); - ipsec_proxy_init = 1; + ipf_ipsec_softc_t *softi; - ipsecnattqe = fr_addtimeoutqueue(&nat_utqe, ipsec_proxy_ttl); - if (ipsecnattqe == NULL) + KMALLOC(softi, ipf_ipsec_softc_t *); + if (softi == NULL) + return NULL; + + bzero((char *)softi, sizeof(*softi)); + softi->ipsec_fr.fr_ref = 1; + softi->ipsec_fr.fr_flags = FR_OUTQUE|FR_PASS|FR_QUICK|FR_KEEPSTATE; + MUTEX_INIT(&softi->ipsec_fr.fr_lock, "IPsec proxy rule lock"); + softi->ipsec_proxy_init = 1; + softi->ipsec_proxy_ttl = 60; + + return softi; +} + + +int +ipf_p_ipsec_soft_init(softc, arg) + ipf_main_softc_t *softc; + void *arg; +{ + ipf_ipsec_softc_t *softi = arg; + + softi->ipsec_nat_tqe = ipf_state_add_tq(softc, softi->ipsec_proxy_ttl); + if (softi->ipsec_nat_tqe == NULL) return -1; - ipsecstatetqe = fr_addtimeoutqueue(&ips_utqe, ipsec_proxy_ttl); - if (ipsecstatetqe == NULL) { - if (fr_deletetimeoutqueue(ipsecnattqe) == 0) - fr_freetimeoutqueue(ipsecnattqe); - ipsecnattqe = NULL; + softi->ipsec_state_tqe = ipf_nat_add_tq(softc, softi->ipsec_proxy_ttl); + if (softi->ipsec_state_tqe == NULL) { + if (ipf_deletetimeoutqueue(softi->ipsec_nat_tqe) == 0) + ipf_freetimeoutqueue(softc, softi->ipsec_nat_tqe); + softi->ipsec_nat_tqe = NULL; return -1; } - ipsecnattqe->ifq_flags |= IFQF_PROXY; - ipsecstatetqe->ifq_flags |= IFQF_PROXY; - - ipsecfr.fr_age[0] = ipsec_proxy_ttl; - ipsecfr.fr_age[1] = ipsec_proxy_ttl; + softi->ipsec_nat_tqe->ifq_flags |= IFQF_PROXY; + softi->ipsec_state_tqe->ifq_flags |= IFQF_PROXY; + softi->ipsec_fr.fr_age[0] = softi->ipsec_proxy_ttl; + softi->ipsec_fr.fr_age[1] = softi->ipsec_proxy_ttl; return 0; } -void ippr_ipsec_fini() +void +ipf_p_ipsec_soft_fini(softc, arg) + ipf_main_softc_t *softc; + void *arg; { - if (ipsecnattqe != NULL) { - if (fr_deletetimeoutqueue(ipsecnattqe) == 0) - fr_freetimeoutqueue(ipsecnattqe); - } - ipsecnattqe = NULL; - if (ipsecstatetqe != NULL) { - if (fr_deletetimeoutqueue(ipsecstatetqe) == 0) - fr_freetimeoutqueue(ipsecstatetqe); - } - ipsecstatetqe = NULL; + ipf_ipsec_softc_t *softi = arg; - if (ipsec_proxy_init == 1) { - MUTEX_DESTROY(&ipsecfr.fr_lock); - ipsec_proxy_init = 0; + if (arg == NULL) + return; + + if (softi->ipsec_nat_tqe != NULL) { + if (ipf_deletetimeoutqueue(softi->ipsec_nat_tqe) == 0) + ipf_freetimeoutqueue(softc, softi->ipsec_nat_tqe); } + softi->ipsec_nat_tqe = NULL; + if (softi->ipsec_state_tqe != NULL) { + if (ipf_deletetimeoutqueue(softi->ipsec_state_tqe) == 0) + ipf_freetimeoutqueue(softc, softi->ipsec_state_tqe); + } + softi->ipsec_state_tqe = NULL; +} + + +void +ipf_p_ipsec_soft_destroy(softc, arg) + ipf_main_softc_t *softc; + void *arg; +{ + ipf_ipsec_softc_t *softi = arg; + + if (softi->ipsec_proxy_init == 1) { + MUTEX_DESTROY(&softi->ipsec_fr.fr_lock); + softi->ipsec_proxy_init = 0; + } + + KFREE(softi); } /* * Setup for a new IPSEC proxy. */ -int ippr_ipsec_new(fin, aps, nat) -fr_info_t *fin; -ap_session_t *aps; -nat_t *nat; +int +ipf_p_ipsec_new(arg, fin, aps, nat) + void *arg; + fr_info_t *fin; + ap_session_t *aps; + nat_t *nat; { - ipsec_pxy_t *ipsec; - fr_info_t fi; - ipnat_t *ipn; - char *ptr; + ipf_ipsec_softc_t *softi = arg; + ipf_main_softc_t *softc = fin->fin_main_soft; +#ifdef USE_MUTEXES + ipf_nat_softc_t *softn = softc->ipf_nat_soft; +#endif int p, off, dlen, ttl; - mb_t *m; + ipsec_pxy_t *ipsec; + ipnat_t *ipn, *np; + fr_info_t fi; + char *ptr; + int size; ip_t *ip; + mb_t *m; + + if (fin->fin_v != 4) + return -1; off = fin->fin_plen - fin->fin_dlen + fin->fin_ipoff; - bzero(ipsec_buffer, sizeof(ipsec_buffer)); + bzero(softi->ipsec_buffer, sizeof(softi->ipsec_buffer)); ip = fin->fin_ip; m = fin->fin_m; dlen = M_LEN(m) - off; if (dlen < 16) return -1; - COPYDATA(m, off, MIN(sizeof(ipsec_buffer), dlen), ipsec_buffer); + COPYDATA(m, off, MIN(sizeof(softi->ipsec_buffer), dlen), + softi->ipsec_buffer); - if (nat_outlookup(fin, 0, IPPROTO_ESP, nat->nat_inip, + if (ipf_nat_outlookup(fin, 0, IPPROTO_ESP, nat->nat_nsrcip, ip->ip_dst) != NULL) return -1; - aps->aps_psiz = sizeof(*ipsec); - KMALLOCS(aps->aps_data, ipsec_pxy_t *, sizeof(*ipsec)); - if (aps->aps_data == NULL) + np = nat->nat_ptr; + size = np->in_size; + KMALLOC(ipsec, ipsec_pxy_t *); + if (ipsec == NULL) return -1; - ipsec = aps->aps_data; + KMALLOCS(ipn, ipnat_t *, size); + if (ipn == NULL) { + KFREE(ipsec); + return -1; + } + + aps->aps_data = ipsec; + aps->aps_psiz = sizeof(*ipsec); bzero((char *)ipsec, sizeof(*ipsec)); + bzero((char *)ipn, size); + ipsec->ipsc_rule = ipn; /* * Create NAT rule against which the tunnel/transport mapping is * created. This is required because the current NAT rule does not * describe ESP but UDP instead. */ - ipn = &ipsec->ipsc_rule; - ttl = IPF_TTLVAL(ipsecnattqe->ifq_ttl); - ipn->in_tqehead[0] = fr_addtimeoutqueue(&nat_utqe, ttl); - ipn->in_tqehead[1] = fr_addtimeoutqueue(&nat_utqe, ttl); + ipn->in_size = size; + ttl = IPF_TTLVAL(softi->ipsec_nat_tqe->ifq_ttl); + ipn->in_tqehead[0] = ipf_nat_add_tq(softc, ttl); + ipn->in_tqehead[1] = ipf_nat_add_tq(softc, ttl); ipn->in_ifps[0] = fin->fin_ifp; ipn->in_apr = NULL; ipn->in_use = 1; ipn->in_hits = 1; - ipn->in_nip = ntohl(nat->nat_outip.s_addr); + ipn->in_snip = ntohl(nat->nat_nsrcaddr); ipn->in_ippip = 1; - ipn->in_inip = nat->nat_inip.s_addr; - ipn->in_inmsk = 0xffffffff; - ipn->in_outip = fin->fin_saddr; - ipn->in_outmsk = nat->nat_outip.s_addr; - ipn->in_srcip = fin->fin_saddr; - ipn->in_srcmsk = 0xffffffff; + ipn->in_osrcip = nat->nat_osrcip; + ipn->in_osrcmsk = 0xffffffff; + ipn->in_nsrcip = nat->nat_nsrcip; + ipn->in_nsrcmsk = 0xffffffff; + ipn->in_odstip = nat->nat_odstip; + ipn->in_odstmsk = 0xffffffff; + ipn->in_ndstip = nat->nat_ndstip; + ipn->in_ndstmsk = 0xffffffff; ipn->in_redir = NAT_MAP; - bcopy(nat->nat_ptr->in_ifnames[0], ipn->in_ifnames[0], - sizeof(ipn->in_ifnames[0])); - ipn->in_p = IPPROTO_ESP; + ipn->in_pr[0] = IPPROTO_ESP; + ipn->in_pr[1] = IPPROTO_ESP; + ipn->in_flags = (np->in_flags | IPN_PROXYRULE); + MUTEX_INIT(&ipn->in_lock, "IPSec proxy NAT rule"); + + ipn->in_namelen = np->in_namelen; + bcopy(np->in_names, ipn->in_ifnames, ipn->in_namelen); + ipn->in_ifnames[0] = np->in_ifnames[0]; + ipn->in_ifnames[1] = np->in_ifnames[1]; bcopy((char *)fin, (char *)&fi, sizeof(fi)); - fi.fin_state = NULL; - fi.fin_nat = NULL; fi.fin_fi.fi_p = IPPROTO_ESP; - fi.fin_fr = &ipsecfr; + fi.fin_fr = &softi->ipsec_fr; fi.fin_data[0] = 0; fi.fin_data[1] = 0; p = ip->ip_p; @@ -154,7 +230,7 @@ nat_t *nat; fi.fin_flx &= ~(FI_TCPUDP|FI_STATE|FI_FRAG); fi.fin_flx |= FI_IGNORE; - ptr = ipsec_buffer; + ptr = softi->ipsec_buffer; bcopy(ptr, (char *)ipsec->ipsc_icookie, sizeof(ipsec_cookie_t)); ptr += sizeof(ipsec_cookie_t); bcopy(ptr, (char *)ipsec->ipsc_rcookie, sizeof(ipsec_cookie_t)); @@ -166,18 +242,19 @@ nat_t *nat; if ((ipsec->ipsc_rcookie[0]|ipsec->ipsc_rcookie[1]) != 0) ipsec->ipsc_rckset = 1; - ipsec->ipsc_nat = nat_new(&fi, ipn, &ipsec->ipsc_nat, - NAT_SLAVE|SI_WILDP, NAT_OUTBOUND); + MUTEX_ENTER(&softn->ipf_nat_new); + ipsec->ipsc_nat = ipf_nat_add(&fi, ipn, &ipsec->ipsc_nat, + NAT_SLAVE|SI_WILDP, NAT_OUTBOUND); + MUTEX_EXIT(&softn->ipf_nat_new); if (ipsec->ipsc_nat != NULL) { - (void) nat_proto(&fi, ipsec->ipsc_nat, 0); - nat_update(&fi, ipsec->ipsc_nat, ipn); + (void) ipf_nat_proto(&fi, ipsec->ipsc_nat, 0); + MUTEX_ENTER(&ipsec->ipsc_nat->nat_lock); + ipf_nat_update(&fi, ipsec->ipsc_nat); + MUTEX_EXIT(&ipsec->ipsc_nat->nat_lock); fi.fin_data[0] = 0; fi.fin_data[1] = 0; - ipsec->ipsc_state = fr_addstate(&fi, &ipsec->ipsc_state, - SI_WILDP); - if (fi.fin_state != NULL) - fr_statederef((ipstate_t **)&fi.fin_state); + (void) ipf_state_add(softc, &fi, &ipsec->ipsc_state, SI_WILDP); } ip->ip_p = p & 0xff; return 0; @@ -188,11 +265,15 @@ nat_t *nat; * For outgoing IKE packets. refresh timeouts for NAT & state entries, if * we can. If they have disappeared, recreate them. */ -int ippr_ipsec_inout(fin, aps, nat) -fr_info_t *fin; -ap_session_t *aps; -nat_t *nat; +int +ipf_p_ipsec_inout(arg, fin, aps, nat) + void *arg; + fr_info_t *fin; + ap_session_t *aps; + nat_t *nat; { + ipf_ipsec_softc_t *softi = arg; + ipf_main_softc_t *softc = fin->fin_main_soft; ipsec_pxy_t *ipsec; fr_info_t fi; ip_t *ip; @@ -212,10 +293,8 @@ nat_t *nat; if ((ipsec->ipsc_nat == NULL) || (ipsec->ipsc_state == NULL)) { bcopy((char *)fin, (char *)&fi, sizeof(fi)); - fi.fin_state = NULL; - fi.fin_nat = NULL; fi.fin_fi.fi_p = IPPROTO_ESP; - fi.fin_fr = &ipsecfr; + fi.fin_fr = &softi->ipsec_fr; fi.fin_data[0] = 0; fi.fin_data[1] = 0; ip->ip_p = IPPROTO_ESP; @@ -227,36 +306,42 @@ nat_t *nat; * Update NAT timeout/create NAT if missing. */ if (ipsec->ipsc_nat != NULL) - fr_queueback(&ipsec->ipsc_nat->nat_tqe); + ipf_queueback(softc->ipf_ticks, + &ipsec->ipsc_nat->nat_tqe); else { - ipsec->ipsc_nat = nat_new(&fi, &ipsec->ipsc_rule, - &ipsec->ipsc_nat, - NAT_SLAVE|SI_WILDP, - nat->nat_dir); +#ifdef USE_MUTEXES + ipf_nat_softc_t *softn = softc->ipf_nat_soft; +#endif + + MUTEX_ENTER(&softn->ipf_nat_new); + ipsec->ipsc_nat = ipf_nat_add(&fi, ipsec->ipsc_rule, + &ipsec->ipsc_nat, + NAT_SLAVE|SI_WILDP, + nat->nat_dir); + MUTEX_EXIT(&softn->ipf_nat_new); if (ipsec->ipsc_nat != NULL) { - (void) nat_proto(&fi, ipsec->ipsc_nat, 0); - nat_update(&fi, ipsec->ipsc_nat, - &ipsec->ipsc_rule); + (void) ipf_nat_proto(&fi, ipsec->ipsc_nat, 0); + MUTEX_ENTER(&ipsec->ipsc_nat->nat_lock); + ipf_nat_update(&fi, ipsec->ipsc_nat); + MUTEX_EXIT(&ipsec->ipsc_nat->nat_lock); } } /* * Update state timeout/create state if missing. */ - READ_ENTER(&ipf_state); + READ_ENTER(&softc->ipf_state); if (ipsec->ipsc_state != NULL) { - fr_queueback(&ipsec->ipsc_state->is_sti); + ipf_queueback(softc->ipf_ticks, + &ipsec->ipsc_state->is_sti); ipsec->ipsc_state->is_die = nat->nat_age; - RWLOCK_EXIT(&ipf_state); + RWLOCK_EXIT(&softc->ipf_state); } else { - RWLOCK_EXIT(&ipf_state); + RWLOCK_EXIT(&softc->ipf_state); fi.fin_data[0] = 0; fi.fin_data[1] = 0; - ipsec->ipsc_state = fr_addstate(&fi, - &ipsec->ipsc_state, - SI_WILDP); - if (fi.fin_state != NULL) - fr_statederef((ipstate_t **)&fi.fin_state); + (void) ipf_state_add(softc, &fi, &ipsec->ipsc_state, + SI_WILDP); } ip->ip_p = p; } @@ -270,10 +355,11 @@ nat_t *nat; * in the same order (not reversed depending on packet flow direction as with * UDP/TCP port numbers). */ -int ippr_ipsec_match(fin, aps, nat) -fr_info_t *fin; -ap_session_t *aps; -nat_t *nat; +int +ipf_p_ipsec_match(fin, aps, nat) + fr_info_t *fin; + ap_session_t *aps; + nat_t *nat; { ipsec_pxy_t *ipsec; u_32_t cookies[4]; @@ -314,8 +400,10 @@ nat_t *nat; /* * clean up after ourselves. */ -void ippr_ipsec_del(aps) -ap_session_t *aps; +void +ipf_p_ipsec_del(softc, aps) + ipf_main_softc_t *softc; + ap_session_t *aps; { ipsec_pxy_t *ipsec; @@ -327,15 +415,17 @@ ap_session_t *aps; * *_del() is on a callback from aps_free(), from nat_delete() */ - READ_ENTER(&ipf_state); + READ_ENTER(&softc->ipf_state); if (ipsec->ipsc_state != NULL) { - ipsec->ipsc_state->is_die = fr_ticks + 1; + ipsec->ipsc_state->is_die = softc->ipf_ticks + 1; ipsec->ipsc_state->is_me = NULL; - fr_queuefront(&ipsec->ipsc_state->is_sti); + ipf_queuefront(&ipsec->ipsc_state->is_sti); } - RWLOCK_EXIT(&ipf_state); + RWLOCK_EXIT(&softc->ipf_state); ipsec->ipsc_state = NULL; ipsec->ipsc_nat = NULL; + ipsec->ipsc_rule->in_flags |= IPN_DELETE; + ipf_nat_rule_deref(softc, &ipsec->ipsc_rule); } } diff --git a/sys/contrib/ipfilter/netinet/ip_irc_pxy.c b/sys/contrib/ipfilter/netinet/ip_irc_pxy.c index 5bb252a25dac..b9954b4c067a 100644 --- a/sys/contrib/ipfilter/netinet/ip_irc_pxy.c +++ b/sys/contrib/ipfilter/netinet/ip_irc_pxy.c @@ -1,9 +1,9 @@ /* - * Copyright (C) 2000-2003 Darren Reed + * Copyright (C) 2012 by Darren Reed. * * See the IPFILTER.LICENCE file for details on licencing. * - * $Id: ip_irc_pxy.c,v 2.39.2.6 2006/07/14 06:12:14 darrenr Exp $ + * $Id$ */ #define IPF_IRC_PROXY @@ -11,12 +11,12 @@ #define IPF_IRCBUFSZ 96 /* This *MUST* be >= 64! */ -int ippr_irc_init __P((void)); -void ippr_irc_fini __P((void)); -int ippr_irc_new __P((fr_info_t *, ap_session_t *, nat_t *)); -int ippr_irc_out __P((fr_info_t *, ap_session_t *, nat_t *)); -int ippr_irc_send __P((fr_info_t *, nat_t *)); -int ippr_irc_complete __P((ircinfo_t *, char *, size_t)); +void ipf_p_irc_main_load __P((void)); +void ipf_p_irc_main_unload __P((void)); +int ipf_p_irc_new __P((void *, fr_info_t *, ap_session_t *, nat_t *)); +int ipf_p_irc_out __P((void *, fr_info_t *, ap_session_t *, nat_t *)); +int ipf_p_irc_send __P((fr_info_t *, nat_t *)); +int ipf_p_irc_complete __P((ircinfo_t *, char *, size_t)); u_short ipf_irc_atoi __P((char **)); static frentry_t ircnatfr; @@ -27,19 +27,19 @@ int irc_proxy_init = 0; /* * Initialize local structures. */ -int ippr_irc_init() +void +ipf_p_irc_main_load() { bzero((char *)&ircnatfr, sizeof(ircnatfr)); ircnatfr.fr_ref = 1; ircnatfr.fr_flags = FR_INQUE|FR_PASS|FR_QUICK|FR_KEEPSTATE; MUTEX_INIT(&ircnatfr.fr_lock, "IRC proxy rule lock"); irc_proxy_init = 1; - - return 0; } -void ippr_irc_fini() +void +ipf_p_irc_main_unload() { if (irc_proxy_init == 1) { MUTEX_DESTROY(&ircnatfr.fr_lock); @@ -48,7 +48,7 @@ void ippr_irc_fini() } -const char *ippr_irc_dcctypes[] = { +const char *ipf_p_irc_dcctypes[] = { "CHAT ", /* CHAT chat ipnumber portnumber */ "SEND ", /* SEND filename ipnumber portnumber */ "MOVE ", @@ -64,10 +64,11 @@ const char *ippr_irc_dcctypes[] = { */ -int ippr_irc_complete(ircp, buf, len) -ircinfo_t *ircp; -char *buf; -size_t len; +int +ipf_p_irc_complete(ircp, buf, len) + ircinfo_t *ircp; + char *buf; + size_t len; { register char *s, c; register size_t i; @@ -145,12 +146,12 @@ size_t len; /* * Check for a recognised DCC command */ - for (j = 0, k = 0; ippr_irc_dcctypes[j]; j++) { - k = MIN(strlen(ippr_irc_dcctypes[j]), i); - if (!strncmp(ippr_irc_dcctypes[j], s, k)) + for (j = 0, k = 0; ipf_p_irc_dcctypes[j]; j++) { + k = MIN(strlen(ipf_p_irc_dcctypes[j]), i); + if (!strncmp(ipf_p_irc_dcctypes[j], s, k)) break; } - if (!ippr_irc_dcctypes[j]) + if (!ipf_p_irc_dcctypes[j]) return 0; ircp->irc_type = s; @@ -222,18 +223,22 @@ size_t len; } -int ippr_irc_new(fin, aps, nat) -fr_info_t *fin; -ap_session_t *aps; -nat_t *nat; +int +ipf_p_irc_new(arg, fin, aps, nat) + void *arg; + fr_info_t *fin; + ap_session_t *aps; + nat_t *nat; { ircinfo_t *irc; + if (fin->fin_v != 4) + return -1; + KMALLOC(irc, ircinfo_t *); if (irc == NULL) return -1; - fin = fin; /* LINT */ nat = nat; /* LINT */ aps->aps_data = irc; @@ -244,13 +249,15 @@ nat_t *nat; } -int ippr_irc_send(fin, nat) -fr_info_t *fin; -nat_t *nat; +int +ipf_p_irc_send(fin, nat) + fr_info_t *fin; + nat_t *nat; { char ctcpbuf[IPF_IRCBUFSZ], newbuf[IPF_IRCBUFSZ]; tcphdr_t *tcp, tcph, *tcp2 = &tcph; int off, inc = 0, i, dlen; + ipf_main_softc_t *softc; size_t nlen = 0, olen; struct in_addr swip; u_short a5, sp; @@ -263,6 +270,7 @@ nat_t *nat; #ifdef MENTAT mb_t *m1; #endif + softc = fin->fin_main_soft; m = fin->fin_m; ip = fin->fin_ip; @@ -285,14 +293,14 @@ nat_t *nat; *newbuf = '\0'; irc = nat->nat_aps->aps_data; - if (ippr_irc_complete(irc, ctcpbuf, dlen) == 0) + if (ipf_p_irc_complete(irc, ctcpbuf, dlen) == 0) return 0; /* - * check that IP address in the PORT/PASV reply is the same as the - * sender of the command - prevents using PORT for port scanning. + * check that IP address in the DCC reply is the same as the + * sender of the command - prevents use for port scanning. */ - if (irc->irc_ipnum != ntohl(nat->nat_inip.s_addr)) + if (irc->irc_ipnum != ntohl(nat->nat_osrcaddr)) return 0; a5 = irc->irc_port; @@ -315,7 +323,7 @@ nat_t *nat; nlen = strlen(newbuf); inc = nlen - olen; - if ((inc + ip->ip_len) > 65535) + if ((inc + fin->fin_plen) > 65535) return 0; #ifdef MENTAT @@ -326,14 +334,14 @@ nat_t *nat; /* alloc enough to keep same trailer space for lower driver */ nm = allocb(nlen, BPRI_MED); - PANIC((!nm),("ippr_irc_out: allocb failed")); + PANIC((!nm),("ipf_p_irc_out: allocb failed")); nm->b_band = m1->b_band; nm->b_wptr += nlen; m1->b_wptr -= olen; PANIC((m1->b_wptr < m1->b_rptr), - ("ippr_irc_out: cannot handle fragmented data block")); + ("ipf_p_irc_out: cannot handle fragmented data block")); linkb(m1, nm); } else { @@ -350,13 +358,14 @@ nat_t *nat; /* the mbuf chain will be extended if necessary by m_copyback() */ #endif COPYBACK(m, off, nlen, newbuf); + fin->fin_flx |= FI_DOCKSUM; if (inc != 0) { #if defined(MENTAT) || defined(__sgi) register u_32_t sum1, sum2; - sum1 = ip->ip_len; - sum2 = ip->ip_len + inc; + sum1 = fin->fin_plen; + sum2 = fin->fin_plen + inc; /* Because ~1 == -2, We really need ~1 == -1 */ if (sum1 > sum2) @@ -364,9 +373,11 @@ nat_t *nat; sum2 -= sum1; sum2 = (sum2 & 0xffff) + (sum2 >> 16); - fix_outcksum(fin, &ip->ip_sum, sum2); + ipf_fix_outcksum(0, &ip->ip_sum, sum2, 0); #endif - ip->ip_len += inc; + fin->fin_plen += inc; + ip->ip_len = htons(fin->fin_plen); + fin->fin_dlen += inc; } /* @@ -389,16 +400,18 @@ nat_t *nat; bcopy((caddr_t)fin, (caddr_t)&fi, sizeof(fi)); fi.fin_data[0] = sp; fi.fin_data[1] = fin->fin_data[1]; - nat2 = nat_outlookup(fin, IPN_TCP, nat->nat_p, nat->nat_inip, + nat2 = ipf_nat_outlookup(fin, IPN_TCP, nat->nat_pr[1], nat->nat_nsrcip, ip->ip_dst); if (nat2 == NULL) { +#ifdef USE_MUTEXES + ipf_nat_softc_t *softn = softc->ipf_nat_soft; +#endif + bcopy((caddr_t)fin, (caddr_t)&fi, sizeof(fi)); bzero((char *)tcp2, sizeof(*tcp2)); tcp2->th_win = htons(8192); tcp2->th_sport = sp; tcp2->th_dport = 0; /* XXX - don't specify remote port */ - fi.fin_state = NULL; - fi.fin_nat = NULL; fi.fin_data[0] = ntohs(sp); fi.fin_data[1] = 0; fi.fin_dp = (char *)tcp2; @@ -406,16 +419,18 @@ nat_t *nat; fi.fin_dlen = sizeof(*tcp2); fi.fin_plen = fi.fin_hlen + sizeof(*tcp2); swip = ip->ip_src; - ip->ip_src = nat->nat_inip; - nat2 = nat_new(&fi, nat->nat_ptr, NULL, + ip->ip_src = nat->nat_nsrcip; + MUTEX_ENTER(&softn->ipf_nat_new); + nat2 = ipf_nat_add(&fi, nat->nat_ptr, NULL, NAT_SLAVE|IPN_TCP|SI_W_DPORT, NAT_OUTBOUND); + MUTEX_EXIT(&softn->ipf_nat_new); if (nat2 != NULL) { - (void) nat_proto(&fi, nat2, 0); - nat_update(&fi, nat2, nat2->nat_ptr); + (void) ipf_nat_proto(&fi, nat2, 0); + MUTEX_ENTER(&nat2->nat_lock); + ipf_nat_update(&fi, nat2); + MUTEX_EXIT(&nat2->nat_lock); - (void) fr_addstate(&fi, NULL, SI_W_DPORT); - if (fi.fin_state != NULL) - fr_statederef((ipstate_t **)&fi.fin_state); + (void) ipf_state_add(softc, &fi, NULL, SI_W_DPORT); } ip->ip_src = swip; } @@ -423,11 +438,13 @@ nat_t *nat; } -int ippr_irc_out(fin, aps, nat) -fr_info_t *fin; -ap_session_t *aps; -nat_t *nat; +int +ipf_p_irc_out(arg, fin, aps, nat) + void *arg; + fr_info_t *fin; + ap_session_t *aps; + nat_t *nat; { aps = aps; /* LINT */ - return ippr_irc_send(fin, nat); + return ipf_p_irc_send(fin, nat); } diff --git a/sys/contrib/ipfilter/netinet/ip_log.c b/sys/contrib/ipfilter/netinet/ip_log.c index 863cc9c058e2..d41384d5a8f5 100644 --- a/sys/contrib/ipfilter/netinet/ip_log.c +++ b/sys/contrib/ipfilter/netinet/ip_log.c @@ -1,7 +1,7 @@ /* $FreeBSD$ */ /* - * Copyright (C) 1997-2003 by Darren Reed. + * Copyright (C) 2012 by Darren Reed. * * See the IPFILTER.LICENCE file for details on licencing. * @@ -15,22 +15,8 @@ # define KERNEL 1 # define _KERNEL 1 #endif -#if defined(__NetBSD__) && (NetBSD >= 199905) && !defined(IPFILTER_LKM) && \ - defined(_KERNEL) -# if (__NetBSD_Version__ < 399001400) -# include "opt_ipfilter_log.h" -# else -# include "opt_ipfilter.h" -# endif -#endif -#if defined(__FreeBSD__) && !defined(IPFILTER_LKM) -# if defined(_KERNEL) -# if defined(__FreeBSD_version) && (__FreeBSD_version >= 300000) -# include "opt_ipfilter.h" -# endif -# else -# include -# endif +#if defined(__FreeBSD__) && !defined(_KERNEL) +# include #endif #ifndef SOLARIS # define SOLARIS (defined(sun) && (defined(__svr4__) || defined(__SVR4))) @@ -104,7 +90,6 @@ struct file; #if __FreeBSD_version >= 300000 # include #endif -#include #include #ifdef __sgi # include @@ -148,100 +133,240 @@ struct file; # include # include # define READ_COLLISION 0x001 - -iplog_select_t iplog_ss[IPL_LOGMAX+1]; - extern int selwait; # endif /* IPL_SELECT */ -# if defined(linux) && defined(_KERNEL) -wait_queue_head_t iplh_linux[IPL_LOGSIZE]; -# endif +typedef struct ipf_log_softc_s { + ipfmutex_t ipl_mutex[IPL_LOGSIZE]; # if SOLARIS && defined(_KERNEL) -extern kcondvar_t iplwait; -extern struct pollhead iplpollhead[IPL_LOGSIZE]; + kcondvar_t ipl_wait[IPL_LOGSIZE]; # endif +# if defined(linux) && defined(_KERNEL) + wait_queue_head_t iplh_linux[IPL_LOGSIZE]; +# endif +# if defined(__hpux) && defined(_KERNEL) + iplog_select_t ipl_ss[IPL_LOGSIZE]; +# endif + iplog_t **iplh[IPL_LOGSIZE]; + iplog_t *iplt[IPL_LOGSIZE]; + iplog_t *ipll[IPL_LOGSIZE]; + u_long ipl_logfail[IPL_LOGSIZE]; + u_long ipl_logok[IPL_LOGSIZE]; + fr_info_t ipl_crc[IPL_LOGSIZE]; + u_32_t ipl_counter[IPL_LOGSIZE]; + int ipl_suppress; + int ipl_logall; + int ipl_log_init; + int ipl_logsize; + int ipl_used[IPL_LOGSIZE]; + int ipl_magic[IPL_LOGSIZE]; + ipftuneable_t *ipf_log_tune; + int ipl_readers[IPL_LOGSIZE]; +} ipf_log_softc_t; -iplog_t **iplh[IPL_LOGSIZE], *iplt[IPL_LOGSIZE], *ipll[IPL_LOGSIZE]; -int iplused[IPL_LOGSIZE]; -static fr_info_t iplcrc[IPL_LOGSIZE]; -int ipl_suppress = 1; -int ipl_logmax = IPL_LOGMAX; -int ipl_logall = 0; -int ipl_log_init = 0; -int ipl_logsize = IPFILTER_LOGSIZE; -int ipl_magic[IPL_LOGSIZE] = { IPL_MAGIC, IPL_MAGIC_NAT, IPL_MAGIC_STATE, - IPL_MAGIC, IPL_MAGIC, IPL_MAGIC, - IPL_MAGIC, IPL_MAGIC }; +static int magic[IPL_LOGSIZE] = { IPL_MAGIC, IPL_MAGIC_NAT, IPL_MAGIC_STATE, + IPL_MAGIC, IPL_MAGIC, IPL_MAGIC, + IPL_MAGIC, IPL_MAGIC }; +static ipftuneable_t ipf_log_tuneables[] = { + /* log */ + { { (void *)offsetof(ipf_log_softc_t, ipl_suppress) }, + "log_suppress", 0, 1, + stsizeof(ipf_log_softc_t, ipl_suppress), + 0, NULL, NULL }, + { { (void *)offsetof(ipf_log_softc_t, ipl_logall) }, + "log_all", 0, 1, + stsizeof(ipf_log_softc_t, ipl_logall), + 0, NULL, NULL }, + { { (void *)offsetof(ipf_log_softc_t, ipl_logsize) }, + "log_size", 0, 0x80000, + stsizeof(ipf_log_softc_t, ipl_logsize), + 0, NULL, NULL }, + { { NULL }, NULL, 0, 0, + 0, + 0, NULL, NULL } +}; + + +int +ipf_log_main_load() +{ + return 0; +} + + +int +ipf_log_main_unload() +{ + return 0; +} /* ------------------------------------------------------------------------ */ -/* Function: fr_loginit */ -/* Returns: int - 0 == success (always returned) */ -/* Parameters: Nil */ +/* Function: ipf_log_soft_create */ +/* Returns: void * - NULL = failure, else pointer to log context data */ +/* Parameters: softc(I) - pointer to soft context main structure */ /* */ /* Initialise log buffers & pointers. Also iniialised the CRC to a local */ /* secret for use in calculating the "last log checksum". */ /* ------------------------------------------------------------------------ */ -int fr_loginit() +void * +ipf_log_soft_create(softc) + ipf_main_softc_t *softc; { - int i; + ipf_log_softc_t *softl; - for (i = IPL_LOGMAX; i >= 0; i--) { - iplt[i] = NULL; - ipll[i] = NULL; - iplh[i] = &iplt[i]; - iplused[i] = 0; - bzero((char *)&iplcrc[i], sizeof(iplcrc[i])); -# ifdef IPL_SELECT - iplog_ss[i].read_waiter = 0; - iplog_ss[i].state = 0; -# endif -# if defined(linux) && defined(_KERNEL) - init_waitqueue_head(iplh_linux + i); -# endif + KMALLOC(softl, ipf_log_softc_t *); + if (softl == NULL) + return NULL; + + bzero((char *)softl, sizeof(*softl)); + bcopy((char *)magic, (char *)softl->ipl_magic, sizeof(magic)); + + softl->ipf_log_tune = ipf_tune_array_copy(softl, + sizeof(ipf_log_tuneables), + ipf_log_tuneables); + if (softl->ipf_log_tune == NULL) { + ipf_log_soft_destroy(softc, softl); + return NULL; + } + if (ipf_tune_array_link(softc, softl->ipf_log_tune) == -1) { + ipf_log_soft_destroy(softc, softl); + return NULL; } -# if SOLARIS && defined(_KERNEL) - cv_init(&iplwait, "ipl condvar", CV_DRIVER, NULL); -# endif - MUTEX_INIT(&ipl_mutex, "ipf log mutex"); + softl->ipl_suppress = 1; + softl->ipl_logall = 0; + softl->ipl_log_init = 0; + softl->ipl_logsize = IPFILTER_LOGSIZE; - ipl_log_init = 1; + return softl; +} + +/* ------------------------------------------------------------------------ */ +/* Function: ipf_log_soft_init */ +/* Returns: int - 0 == success (always returned) */ +/* Parameters: softc(I) - pointer to soft context main structure */ +/* */ +/* Initialise log buffers & pointers. Also iniialised the CRC to a local */ +/* secret for use in calculating the "last log checksum". */ +/* ------------------------------------------------------------------------ */ +int +ipf_log_soft_init(softc, arg) + ipf_main_softc_t *softc; + void *arg; +{ + ipf_log_softc_t *softl = arg; + int i; + + for (i = IPL_LOGMAX; i >= 0; i--) { + softl->iplt[i] = NULL; + softl->ipll[i] = NULL; + softl->iplh[i] = &softl->iplt[i]; + bzero((char *)&softl->ipl_crc[i], sizeof(softl->ipl_crc[i])); +# ifdef IPL_SELECT + softl->iplog_ss[i].read_waiter = 0; + softl->iplog_ss[i].state = 0; +# endif +# if defined(linux) && defined(_KERNEL) + init_waitqueue_head(softl->iplh_linux + i); +# endif +# if SOLARIS && defined(_KERNEL) + cv_init(&softl->ipl_wait[i], NULL, CV_DRIVER, NULL); +# endif + MUTEX_INIT(&softl->ipl_mutex[i], "ipf log mutex"); + } + + + softl->ipl_log_init = 1; return 0; } /* ------------------------------------------------------------------------ */ -/* Function: fr_logunload */ -/* Returns: Nil */ -/* Parameters: Nil */ +/* Function: ipf_log_soft_fini */ +/* Parameters: softc(I) - pointer to soft context main structure */ +/* arg(I) - pointer to log context structure */ /* */ /* Clean up any log data that has accumulated without being read. */ /* ------------------------------------------------------------------------ */ -void fr_logunload() +int +ipf_log_soft_fini(softc, arg) + ipf_main_softc_t *softc; + void *arg; { + ipf_log_softc_t *softl = arg; int i; - if (ipl_log_init == 0) - return; + if (softl->ipl_log_init == 0) + return 0; - for (i = IPL_LOGMAX; i >= 0; i--) - (void) ipflog_clear(i); + softl->ipl_log_init = 0; + for (i = IPL_LOGMAX; i >= 0; i--) { + (void) ipf_log_clear(softc, i); + + /* + * This is a busy-wait loop so as to avoid yet another lock + * to wait on. + */ + MUTEX_ENTER(&softl->ipl_mutex[i]); + while (softl->ipl_readers[i] > 0) { # if SOLARIS && defined(_KERNEL) - cv_destroy(&iplwait); + cv_broadcast(&softl->ipl_wait[i]); + MUTEX_EXIT(&softl->ipl_mutex[i]); + delay(100); + pollwakeup(&softc->ipf_poll_head[i], POLLRDNORM); +# else + MUTEX_EXIT(&softl->ipl_mutex[i]); + WAKEUP(softl->iplh, i); + POLLWAKEUP(i); # endif - MUTEX_DESTROY(&ipl_mutex); + MUTEX_ENTER(&softl->ipl_mutex[i]); + } + MUTEX_EXIT(&softl->ipl_mutex[i]); + } - ipl_log_init = 0; + return 0; } /* ------------------------------------------------------------------------ */ -/* Function: ipflog */ -/* Returns: int - 0 == success, -1 == failure */ +/* Function: ipf_log_soft_destroy */ +/* Parameters: softc(I) - pointer to soft context main structure */ +/* arg(I) - pointer to log context structure */ +/* */ +/* When this function is called, it is expected that there are no longer */ +/* any threads active in the reading code path or the logging code path. */ +/* ------------------------------------------------------------------------ */ +void +ipf_log_soft_destroy(softc, arg) + ipf_main_softc_t *softc; + void *arg; +{ + ipf_log_softc_t *softl = arg; + int i; + + for (i = IPL_LOGMAX; i >= 0; i--) { +# if SOLARIS && defined(_KERNEL) + cv_destroy(&softl->ipl_wait[i]); +# endif + MUTEX_DESTROY(&softl->ipl_mutex[i]); + } + + if (softl->ipf_log_tune != NULL) { + ipf_tune_array_unlink(softc, softl->ipf_log_tune); + KFREES(softl->ipf_log_tune, sizeof(ipf_log_tuneables)); + softl->ipf_log_tune = NULL; + } + + KFREE(softl); +} + + +/* ------------------------------------------------------------------------ */ +/* Function: ipf_log_pkt */ +/* Returns: int - 0 == success, -1 == failure */ /* Parameters: fin(I) - pointer to packet information */ /* flags(I) - flags from filter rules */ /* */ @@ -251,10 +376,13 @@ void fr_logunload() /* how much data to copy into the log, including part of the data body if */ /* requested. */ /* ------------------------------------------------------------------------ */ -int ipflog(fin, flags) -fr_info_t *fin; -u_int flags; +int +ipf_log_pkt(fin, flags) + fr_info_t *fin; + u_int flags; { + ipf_main_softc_t *softc = fin->fin_main_soft; + ipf_log_softc_t *softl = softc->ipf_log_soft; register size_t hlen; int types[2], mlen; size_t sizes[2]; @@ -262,8 +390,7 @@ u_int flags; ipflog_t ipfl; u_char p; mb_t *m; -# if (SOLARIS || defined(__hpux)) && defined(_KERNEL) && \ - !defined(_INET_IP_STACK_H) +# if (SOLARIS || defined(__hpux)) && defined(_KERNEL) && !defined(FW_HOOKS) qif_t *ifp; # else struct ifnet *ifp; @@ -275,10 +402,8 @@ u_int flags; ipfl.fl_nattag.ipt_num[0] = 0; ifp = fin->fin_ifp; - if (fin->fin_exthdr != NULL) - hlen = (char *)fin->fin_dp - (char *)fin->fin_ip; - else - hlen = fin->fin_hlen; + hlen = (char *)fin->fin_dp - (char *)fin->fin_ip; + /* * calculate header size. */ @@ -292,7 +417,7 @@ u_int flags; struct icmp *icmp; icmp = (struct icmp *)fin->fin_dp; - + /* * For ICMP, if the packet is an error packet, also * include the information about the packet which @@ -339,15 +464,14 @@ u_int flags; * Get the interface number and name to which this packet is * currently associated. */ -# if (SOLARIS || defined(__hpux)) && defined(_KERNEL) && \ - !defined(_INET_IP_STACK_H) +# if (SOLARIS || defined(__hpux)) && defined(_KERNEL) +# if !defined(FW_HOOKS) ipfl.fl_unit = (u_int)ifp->qf_ppa; +# endif COPYIFNAME(fin->fin_v, ifp, ipfl.fl_ifname); # else -# if (defined(NetBSD) && (NetBSD <= 1991011) && (NetBSD >= 199603)) || \ - (defined(OpenBSD) && (OpenBSD >= 199603)) || defined(linux) || \ - (defined(__FreeBSD__) && (__FreeBSD_version >= 501113)) || \ - (SOLARIS && defined(_INET_IP_STACK_H)) +# if (defined(NetBSD) && (NetBSD <= 1991011) && (NetBSD >= 199603)) || \ + OPENBSD_GE_REV(199603) || defined(linux) || FREEBSD_GE_REV(501113) COPYIFNAME(fin->fin_v, ifp, ipfl.fl_ifname); # else ipfl.fl_unit = (u_int)ifp->if_unit; @@ -357,13 +481,13 @@ u_int flags; if ((ipfl.fl_ifname[2] = ifp->if_name[2])) ipfl.fl_ifname[3] = ifp->if_name[3]; # else - COPYIFNAME(fin->fin_v, ifp, ipfl.fl_ifname); + (void) strncpy(ipfl.fl_ifname, IFNAME(ifp), sizeof(ipfl.fl_ifname)); ipfl.fl_ifname[sizeof(ipfl.fl_ifname) - 1] = '\0'; # endif # endif # endif /* __hpux || SOLARIS */ mlen = fin->fin_plen - hlen; - if (!ipl_logall) { + if (!softl->ipl_logall) { mlen = (flags & FR_LOGBODY) ? MIN(mlen, 128) : 0; } else if ((flags & FR_LOGBODY) == 0) { mlen = 0; @@ -385,8 +509,10 @@ u_int flags; bcopy(fin->fin_nattag, (void *)&ipfl.fl_nattag, sizeof(ipfl.fl_nattag)); ipfl.fl_flags = flags; + ipfl.fl_breason = (fin->fin_reason & 0xff); ipfl.fl_dir = fin->fin_out; ipfl.fl_lflags = fin->fin_flx; + ipfl.fl_family = fin->fin_family; ptrs[0] = (void *)&ipfl; sizes[0] = sizeof(ipfl); types[0] = 0; @@ -408,14 +534,15 @@ u_int flags; sizes[1] = hlen + mlen; types[1] = 1; # endif /* MENTAT */ - return ipllog(IPL_LOGIPF, fin, ptrs, sizes, types, 2); + return ipf_log_items(softc, IPL_LOGIPF, fin, ptrs, sizes, types, 2); } /* ------------------------------------------------------------------------ */ -/* Function: ipllog */ -/* Returns: int - 0 == success, -1 == failure */ -/* Parameters: dev(I) - device that owns this log record */ +/* Function: ipf_log_items */ +/* Returns: int - 0 == success, -1 == failure */ +/* Parameters: softc(I) - pointer to main soft context */ +/* unit(I) - device we are reading from */ /* fin(I) - pointer to packet information */ /* items(I) - array of pointers to log data */ /* itemsz(I) - array of size of valid memory pointed to */ @@ -426,72 +553,51 @@ u_int flags; /* miscellaneous packet information, as well as packet data, for reading */ /* from the log device. */ /* ------------------------------------------------------------------------ */ -int ipllog(dev, fin, items, itemsz, types, cnt) -int dev; -fr_info_t *fin; -void **items; -size_t *itemsz; -int *types, cnt; +int +ipf_log_items(softc, unit, fin, items, itemsz, types, cnt) + ipf_main_softc_t *softc; + int unit; + fr_info_t *fin; + void **items; + size_t *itemsz; + int *types, cnt; { - u_char *buf, *ptr; + ipf_log_softc_t *softl = softc->ipf_log_soft; + caddr_t buf, ptr; iplog_t *ipl; size_t len; int i; SPL_INT(s); - /* - * Check to see if this log record has a CRC which matches the last - * record logged. If it does, just up the count on the previous one - * rather than create a new one. - */ - if (ipl_suppress) { - MUTEX_ENTER(&ipl_mutex); - if ((fin != NULL) && (fin->fin_off == 0)) { - if ((ipll[dev] != NULL) && - bcmp((char *)fin, (char *)&iplcrc[dev], - FI_LCSIZE) == 0) { - ipll[dev]->ipl_count++; - MUTEX_EXIT(&ipl_mutex); - return 0; - } - bcopy((char *)fin, (char *)&iplcrc[dev], FI_LCSIZE); - } else - bzero((char *)&iplcrc[dev], FI_CSIZE); - MUTEX_EXIT(&ipl_mutex); - } - /* * Get the total amount of data to be logged. */ for (i = 0, len = sizeof(iplog_t); i < cnt; i++) len += itemsz[i]; + SPL_NET(s); + MUTEX_ENTER(&softl->ipl_mutex[unit]); + softl->ipl_counter[unit]++; /* * check that we have space to record this information and can * allocate that much. */ - KMALLOCS(buf, u_char *, len); - if (buf == NULL) - return -1; - SPL_NET(s); - MUTEX_ENTER(&ipl_mutex); - if ((iplused[dev] + len) > ipl_logsize) { - MUTEX_EXIT(&ipl_mutex); - SPL_X(s); - KFREES(buf, len); + if ((softl->ipl_used[unit] + len) > softl->ipl_logsize) { + softl->ipl_logfail[unit]++; + MUTEX_EXIT(&softl->ipl_mutex[unit]); return -1; } - iplused[dev] += len; - MUTEX_EXIT(&ipl_mutex); - SPL_X(s); - /* - * advance the log pointer to the next empty record and deduct the - * amount of space we're going to use. - */ + KMALLOCS(buf, caddr_t, len); + if (buf == NULL) { + softl->ipl_logfail[unit]++; + MUTEX_EXIT(&softl->ipl_mutex[unit]); + return -1; + } ipl = (iplog_t *)buf; - ipl->ipl_magic = ipl_magic[dev]; + ipl->ipl_magic = softl->ipl_magic[unit]; ipl->ipl_count = 1; + ipl->ipl_seqnum = softl->ipl_counter[unit]; ipl->ipl_next = NULL; ipl->ipl_dsize = len; #ifdef _KERNEL @@ -509,42 +615,71 @@ int *types, cnt; if (types[i] == 0) { bcopy(items[i], ptr, itemsz[i]); } else if (types[i] == 1) { - COPYDATA(items[i], 0, itemsz[i], (char *)ptr); + COPYDATA(items[i], 0, itemsz[i], ptr); } ptr += itemsz[i]; } - SPL_NET(s); - MUTEX_ENTER(&ipl_mutex); - ipll[dev] = ipl; - *iplh[dev] = ipl; - iplh[dev] = &ipl->ipl_next; + /* + * Check to see if this log record has a CRC which matches the last + * record logged. If it does, just up the count on the previous one + * rather than create a new one. + */ + if (softl->ipl_suppress) { + if ((fin != NULL) && (fin->fin_off == 0)) { + if ((softl->ipll[unit] != NULL) && + (fin->fin_crc == softl->ipl_crc[unit].fin_crc) && + bcmp((char *)fin, (char *)&softl->ipl_crc[unit], + FI_LCSIZE) == 0) { + softl->ipll[unit]->ipl_count++; + MUTEX_EXIT(&softl->ipl_mutex[unit]); + SPL_X(s); + KFREES(buf, len); + return 0; + } + bcopy((char *)fin, (char *)&softl->ipl_crc[unit], + FI_LCSIZE); + softl->ipl_crc[unit].fin_crc = fin->fin_crc; + } else + bzero((char *)&softl->ipl_crc[unit], FI_CSIZE); + } + + /* + * advance the log pointer to the next empty record and deduct the + * amount of space we're going to use. + */ + softl->ipl_logok[unit]++; + softl->ipll[unit] = ipl; + *softl->iplh[unit] = ipl; + softl->iplh[unit] = &ipl->ipl_next; + softl->ipl_used[unit] += len; /* * Now that the log record has been completed and added to the queue, * wake up any listeners who may want to read it. */ # if SOLARIS && defined(_KERNEL) - cv_signal(&iplwait); - MUTEX_EXIT(&ipl_mutex); - pollwakeup(&iplpollhead[dev], POLLRDNORM); + cv_signal(&softl->ipl_wait[unit]); + MUTEX_EXIT(&softl->ipl_mutex[unit]); + pollwakeup(&softc->ipf_poll_head[unit], POLLRDNORM); # else - MUTEX_EXIT(&ipl_mutex); - WAKEUP(iplh, dev); - POLLWAKEUP(dev); + MUTEX_EXIT(&softl->ipl_mutex[unit]); + WAKEUP(softl->iplh, unit); + POLLWAKEUP(unit); # endif SPL_X(s); # ifdef IPL_SELECT - iplog_input_ready(dev); + iplog_input_ready(unit); # endif return 0; } /* ------------------------------------------------------------------------ */ -/* Function: ipflog_read */ -/* Returns: int - 0 == success, else error value. */ -/* Parameters: unit(I) - device we are reading from */ -/* uio(O) - pointer to information about where to store data */ +/* Function: ipf_log_read */ +/* Returns: int - 0 == success, else error value. */ +/* Parameters: softc(I) - pointer to main soft context */ +/* unit(I) - device we are reading from */ +/* uio(O) - pointer to information about where to store data */ /* */ /* Called to handle a read on an IPFilter device. Returns only complete */ /* log messages - will not partially copy a log record out to userland. */ @@ -552,38 +687,58 @@ int *types, cnt; /* NOTE: This function will block and wait for a signal to return data if */ /* there is none present. Asynchronous I/O is not implemented. */ /* ------------------------------------------------------------------------ */ -int ipflog_read(unit, uio) -minor_t unit; -struct uio *uio; +int +ipf_log_read(softc, unit, uio) + ipf_main_softc_t *softc; + minor_t unit; + struct uio *uio; { + ipf_log_softc_t *softl = softc->ipf_log_soft; size_t dlen, copied; int error = 0; iplog_t *ipl; SPL_INT(s); + if (softl->ipl_log_init == 0) { + IPFERROR(40007); + return 0; + } + /* * Sanity checks. Make sure the minor # is valid and we're copying * a valid chunk of data. */ - if (IPL_LOGMAX < unit) + if (IPL_LOGMAX < unit) { + IPFERROR(40001); return ENXIO; + } if (uio->uio_resid == 0) return 0; - if ((uio->uio_resid < sizeof(iplog_t)) || - (uio->uio_resid > ipl_logsize)) + + if (uio->uio_resid < sizeof(iplog_t)) { + IPFERROR(40002); return EINVAL; + } + if (uio->uio_resid > softl->ipl_logsize) { + IPFERROR(40005); + return EINVAL; + } /* * Lock the log so we can snapshot the variables. Wait for a signal * if the log is empty. */ SPL_NET(s); - MUTEX_ENTER(&ipl_mutex); + MUTEX_ENTER(&softl->ipl_mutex[unit]); + softl->ipl_readers[unit]++; - while (iplt[unit] == NULL) { + while (softl->ipl_log_init == 1 && softl->iplt[unit] == NULL) { # if SOLARIS && defined(_KERNEL) - if (!cv_wait_sig(&iplwait, &ipl_mutex.ipf_lk)) { - MUTEX_EXIT(&ipl_mutex); + if (!cv_wait_sig(&softl->ipl_wait[unit], + &softl->ipl_mutex[unit].ipf_lk)) { + softl->ipl_readers[unit]--; + MUTEX_EXIT(&softl->ipl_mutex[unit]); + IPFERROR(40003); return EINTR; } # else @@ -593,114 +748,206 @@ struct uio *uio; # ifdef IPL_SELECT if (uio->uio_fpflags & (FNBLOCK|FNDELAY)) { /* this is no blocking system call */ - MUTEX_EXIT(&ipl_mutex); + softl->ipl_readers[unit]--; + MUTEX_EXIT(&softl->ipl_mutex[unit]); return 0; } # endif - MUTEX_EXIT(&ipl_mutex); - l = get_sleep_lock(&iplh[unit]); - error = sleep(&iplh[unit], PZERO+1); + MUTEX_EXIT(&softl->ipl_mutex[unit]); + l = get_sleep_lock(&softl->iplh[unit]); + error = sleep(&softl->iplh[unit], PZERO+1); spinunlock(l); # else # if defined(__osf__) && defined(_KERNEL) - error = mpsleep(&iplh[unit], PSUSP|PCATCH, "iplread", 0, - &ipl_mutex, MS_LOCK_SIMPLE); + error = mpsleep(&softl->iplh[unit], PSUSP|PCATCH, "ipfread", 0, + &softl->ipl_mutex, MS_LOCK_SIMPLE); # else - MUTEX_EXIT(&ipl_mutex); + MUTEX_EXIT(&softl->ipl_mutex[unit]); SPL_X(s); - error = SLEEP(unit + iplh, "ipl sleep"); + error = SLEEP(unit + softl->iplh, "ipl sleep"); # endif /* __osf__ */ # endif /* __hpux */ - if (error) - return error; SPL_NET(s); - MUTEX_ENTER(&ipl_mutex); + MUTEX_ENTER(&softl->ipl_mutex[unit]); + if (error) { + softl->ipl_readers[unit]--; + MUTEX_EXIT(&softl->ipl_mutex[unit]); + IPFERROR(40004); + return error; + } # endif /* SOLARIS */ } + if (softl->ipl_log_init != 1) { + softl->ipl_readers[unit]--; + MUTEX_EXIT(&softl->ipl_mutex[unit]); + IPFERROR(40008); + return EIO; + } -# if (BSD >= 199101) || defined(__FreeBSD__) || defined(__osf__) +# if (defined(BSD) && (BSD >= 199101)) || defined(__FreeBSD__) || \ + defined(__osf__) uio->uio_rw = UIO_READ; # endif - for (copied = 0; (ipl = iplt[unit]) != NULL; copied += dlen) { + for (copied = 0; (ipl = softl->iplt[unit]) != NULL; copied += dlen) { dlen = ipl->ipl_dsize; if (dlen > uio->uio_resid) break; /* * Don't hold the mutex over the uiomove call. */ - iplt[unit] = ipl->ipl_next; - iplused[unit] -= dlen; - MUTEX_EXIT(&ipl_mutex); + softl->iplt[unit] = ipl->ipl_next; + softl->ipl_used[unit] -= dlen; + MUTEX_EXIT(&softl->ipl_mutex[unit]); SPL_X(s); error = UIOMOVE(ipl, dlen, UIO_READ, uio); if (error) { SPL_NET(s); - MUTEX_ENTER(&ipl_mutex); - ipl->ipl_next = iplt[unit]; - iplt[unit] = ipl; - iplused[unit] += dlen; + MUTEX_ENTER(&softl->ipl_mutex[unit]); + IPFERROR(40006); + ipl->ipl_next = softl->iplt[unit]; + softl->iplt[unit] = ipl; + softl->ipl_used[unit] += dlen; break; } - MUTEX_ENTER(&ipl_mutex); - KFREES(ipl, dlen); + MUTEX_ENTER(&softl->ipl_mutex[unit]); + KFREES((caddr_t)ipl, dlen); SPL_NET(s); } - if (!iplt[unit]) { - iplused[unit] = 0; - iplh[unit] = &iplt[unit]; - ipll[unit] = NULL; + if (!softl->iplt[unit]) { + softl->ipl_used[unit] = 0; + softl->iplh[unit] = &softl->iplt[unit]; + softl->ipll[unit] = NULL; } - MUTEX_EXIT(&ipl_mutex); + softl->ipl_readers[unit]--; + MUTEX_EXIT(&softl->ipl_mutex[unit]); SPL_X(s); return error; } /* ------------------------------------------------------------------------ */ -/* Function: ipflog_clear */ -/* Returns: int - number of log bytes cleared. */ -/* Parameters: unit(I) - device we are reading from */ +/* Function: ipf_log_clear */ +/* Returns: int - number of log bytes cleared. */ +/* Parameters: softc(I) - pointer to main soft context */ +/* unit(I) - device we are reading from */ /* */ /* Deletes all queued up log records for a given output device. */ /* ------------------------------------------------------------------------ */ -int ipflog_clear(unit) -minor_t unit; +int +ipf_log_clear(softc, unit) + ipf_main_softc_t *softc; + minor_t unit; { + ipf_log_softc_t *softl = softc->ipf_log_soft; iplog_t *ipl; int used; SPL_INT(s); SPL_NET(s); - MUTEX_ENTER(&ipl_mutex); - while ((ipl = iplt[unit]) != NULL) { - iplt[unit] = ipl->ipl_next; - KFREES(ipl, ipl->ipl_dsize); + MUTEX_ENTER(&softl->ipl_mutex[unit]); + while ((ipl = softl->iplt[unit]) != NULL) { + softl->iplt[unit] = ipl->ipl_next; + KFREES((caddr_t)ipl, ipl->ipl_dsize); } - iplh[unit] = &iplt[unit]; - ipll[unit] = NULL; - used = iplused[unit]; - iplused[unit] = 0; - bzero((char *)&iplcrc[unit], FI_CSIZE); - MUTEX_EXIT(&ipl_mutex); + softl->iplh[unit] = &softl->iplt[unit]; + softl->ipll[unit] = NULL; + used = softl->ipl_used[unit]; + softl->ipl_used[unit] = 0; + bzero((char *)&softl->ipl_crc[unit], FI_CSIZE); + MUTEX_EXIT(&softl->ipl_mutex[unit]); SPL_X(s); return used; } /* ------------------------------------------------------------------------ */ -/* Function: ipflog_canread */ -/* Returns: int - 0 == no data to read, 1 = data present */ -/* Parameters: unit(I) - device we are reading from */ +/* Function: ipf_log_canread */ +/* Returns: int - 0 == no data to read, 1 = data present */ +/* Parameters: softc(I) - pointer to main soft context */ +/* unit(I) - device we are reading from */ /* */ /* Returns an indication of whether or not there is data present in the */ /* current buffer for the selected ipf device. */ /* ------------------------------------------------------------------------ */ -int ipflog_canread(unit) -int unit; +int +ipf_log_canread(softc, unit) + ipf_main_softc_t *softc; + int unit; { - return iplt[unit] != NULL; + ipf_log_softc_t *softl = softc->ipf_log_soft; + + return softl->iplt[unit] != NULL; +} + + +/* ------------------------------------------------------------------------ */ +/* Function: ipf_log_canread */ +/* Returns: int - 0 == no data to read, 1 = data present */ +/* Parameters: softc(I) - pointer to main soft context */ +/* unit(I) - device we are reading from */ +/* */ +/* Returns how many bytes are currently held in log buffers for the */ +/* selected ipf device. */ +/* ------------------------------------------------------------------------ */ +int +ipf_log_bytesused(softc, unit) + ipf_main_softc_t *softc; + int unit; +{ + ipf_log_softc_t *softl = softc->ipf_log_soft; + + if (softl == NULL) + return 0; + + return softl->ipl_used[unit]; +} + + +/* ------------------------------------------------------------------------ */ +/* Function: ipf_log_failures */ +/* Returns: U_QUAD_T - number of log failures */ +/* Parameters: softc(I) - pointer to main soft context */ +/* unit(I) - device we are reading from */ +/* */ +/* Returns how many times we've tried to log a packet but failed to do so */ +/* for the selected ipf device. */ +/* ------------------------------------------------------------------------ */ +u_long +ipf_log_failures(softc, unit) + ipf_main_softc_t *softc; + int unit; +{ + ipf_log_softc_t *softl = softc->ipf_log_soft; + + if (softl == NULL) + return 0; + + return softl->ipl_logfail[unit]; +} + + +/* ------------------------------------------------------------------------ */ +/* Function: ipf_log_logok */ +/* Returns: U_QUAD_T - number of packets logged */ +/* Parameters: softc(I) - pointer to main soft context */ +/* unit(I) - device we are reading from */ +/* */ +/* Returns how many times we've successfully logged a packet for the */ +/* selected ipf device. */ +/* ------------------------------------------------------------------------ */ +u_long +ipf_log_logok(softc, unit) + ipf_main_softc_t *softc; + int unit; +{ + ipf_log_softc_t *softl = softc->ipf_log_soft; + + if (softl == NULL) + return 0; + + return softl->ipl_logok[unit]; } #endif /* IPFILTER_LOG */ diff --git a/sys/contrib/ipfilter/netinet/ip_lookup.c b/sys/contrib/ipfilter/netinet/ip_lookup.c index e33a6fe5cbe0..45999e0447ff 100644 --- a/sys/contrib/ipfilter/netinet/ip_lookup.c +++ b/sys/contrib/ipfilter/netinet/ip_lookup.c @@ -1,5 +1,6 @@ +/* $FreeBSD$ */ /* - * Copyright (C) 2002-2003 by Darren Reed. + * Copyright (C) 2012 by Darren Reed. * * See the IPFILTER.LICENCE file for details on licencing. */ @@ -24,7 +25,9 @@ # include #endif #if !defined(_KERNEL) +# include # include +# include # define _KERNEL # ifdef __OpenBSD__ struct file; @@ -33,106 +36,223 @@ struct file; # undef _KERNEL #endif #include -#if (defined(__osf__) || defined(AIX) || defined(__hpux) || defined(__sgi)) && defined(_KERNEL) -# include "radix_ipf_local.h" -# define _RADIX_H_ -#endif #include #if defined(__FreeBSD__) -# include -# include +# include +# include #endif #if defined(_KERNEL) # include # if !defined(__SVR4) && !defined(__svr4__) # include # endif +#else +# include "ipf.h" #endif #include #include "netinet/ip_compat.h" #include "netinet/ip_fil.h" +#include "netinet/ip_lookup.h" #include "netinet/ip_pool.h" #include "netinet/ip_htable.h" -#include "netinet/ip_lookup.h" +#include "netinet/ip_dstlist.h" /* END OF INCLUDES */ #if !defined(lint) -static const char rcsid[] = "@(#)$Id: ip_lookup.c,v 2.35.2.19 2007/10/11 09:05:51 darrenr Exp $"; +static const char rcsid[] = "@(#)$Id$"; #endif -#ifdef IPFILTER_LOOKUP -int ip_lookup_inited = 0; +/* + * In this file, ip_pool.c, ip_htable.c and ip_dstlist.c, you will find the + * range for unit is [-1,IPL_LOGMAX]. The -1 is considered to be a valid number + * and represents a "wildcard" or "all" units (IPL_LOGALL). The reason for not + * starting the numbering at 0 is because the numbers [0,IPL_LOGMAX] correspond + * to the minor device number for their respective device. Thus where there is + * array indexing on the unit, +1 is used to map [-1.IPL_LOGMAX] to + * [0.POOL_LOOKUP_MAX]. + */ +static int ipf_lookup_addnode __P((ipf_main_softc_t *, caddr_t, int)); +static int ipf_lookup_delnode __P((ipf_main_softc_t *, caddr_t, int)); +static int ipf_lookup_addtable __P((ipf_main_softc_t *, caddr_t)); +static int ipf_lookup_deltable __P((ipf_main_softc_t *, caddr_t)); +static int ipf_lookup_stats __P((ipf_main_softc_t *, caddr_t)); +static int ipf_lookup_flush __P((ipf_main_softc_t *, caddr_t)); +static int ipf_lookup_iterate __P((ipf_main_softc_t *, void *, int, void *)); +static int ipf_lookup_deltok __P((ipf_main_softc_t *, void *, int, void *)); -static int iplookup_addnode __P((caddr_t)); -static int iplookup_delnode __P((caddr_t data)); -static int iplookup_addtable __P((caddr_t)); -static int iplookup_deltable __P((caddr_t)); -static int iplookup_stats __P((caddr_t)); -static int iplookup_flush __P((caddr_t)); -static int iplookup_iterate __P((void *, int, void *)); -static int iplookup_deltok __P((void *, int, void *)); +#define MAX_BACKENDS 3 +static ipf_lookup_t *backends[MAX_BACKENDS] = { + &ipf_pool_backend, + &ipf_htable_backend, + &ipf_dstlist_backend +}; + + +typedef struct ipf_lookup_softc_s { + void *ipf_back[MAX_BACKENDS]; +} ipf_lookup_softc_t; /* ------------------------------------------------------------------------ */ -/* Function: iplookup_init */ -/* Returns: int - 0 = success, else error */ -/* Parameters: Nil */ +/* Function: ipf_lookup_init */ +/* Returns: int - 0 = success, else error */ +/* Parameters: softc(I) - pointer to soft context main structure */ /* */ /* Initialise all of the subcomponents of the lookup infrstructure. */ /* ------------------------------------------------------------------------ */ -int ip_lookup_init() +void * +ipf_lookup_soft_create(softc) + ipf_main_softc_t *softc; { + ipf_lookup_softc_t *softl; + ipf_lookup_t **l; + int i; - if (ip_pool_init() == -1) - return -1; + KMALLOC(softl, ipf_lookup_softc_t *); + if (softl == NULL) + return NULL; - RWLOCK_INIT(&ip_poolrw, "ip pool rwlock"); + bzero((char *)softl, sizeof(*softl)); - ip_lookup_inited = 1; + for (i = 0, l = backends; i < MAX_BACKENDS; i++, l++) { + softl->ipf_back[i] = (*(*l)->ipfl_create)(softc); + if (softl->ipf_back[i] == NULL) { + ipf_lookup_soft_destroy(softc, softl); + return NULL; + } + } + + return softl; +} + + +/* ------------------------------------------------------------------------ */ +/* Function: ipf_lookup_soft_init */ +/* Returns: int - 0 = success, else error */ +/* Parameters: softc(I) - pointer to soft context main structure */ +/* arg(I) - pointer to local context to use */ +/* */ +/* Initialise all of the subcomponents of the lookup infrstructure. */ +/* ------------------------------------------------------------------------ */ +int +ipf_lookup_soft_init(softc, arg) + ipf_main_softc_t *softc; + void *arg; +{ + ipf_lookup_softc_t *softl = (ipf_lookup_softc_t *)arg; + int err = 0; + int i; + + for (i = 0; i < MAX_BACKENDS; i++) { + err = (*backends[i]->ipfl_init)(softc, softl->ipf_back[i]); + if (err != 0) + break; + } + + return err; +} + + +/* ------------------------------------------------------------------------ */ +/* Function: ipf_lookup_soft_fini */ +/* Returns: int - 0 = success, else error */ +/* Parameters: softc(I) - pointer to soft context main structure */ +/* arg(I) - pointer to local context to use */ +/* */ +/* Call the fini function in each backend to cleanup all allocated data. */ +/* ------------------------------------------------------------------------ */ +int +ipf_lookup_soft_fini(softc, arg) + ipf_main_softc_t *softc; + void *arg; +{ + ipf_lookup_softc_t *softl = (ipf_lookup_softc_t *)arg; + int i; + + for (i = 0; i < MAX_BACKENDS; i++) { + if (softl->ipf_back[i] != NULL) + (*backends[i]->ipfl_fini)(softc, + softl->ipf_back[i]); + } return 0; } /* ------------------------------------------------------------------------ */ -/* Function: iplookup_unload */ -/* Returns: int - 0 = success, else error */ -/* Parameters: Nil */ +/* Function: ipf_lookup_expire */ +/* Returns: Nil */ +/* Parameters: softc(I) - pointer to soft context main structure */ /* */ -/* Free up all pool related memory that has been allocated whilst IPFilter */ -/* has been running. Also, do any other deinitialisation required such */ -/* ip_lookup_init() can be called again, safely. */ +/* Step through each of the backends and call their expire functions, */ +/* allowing them to delete any lifetime limited data. */ /* ------------------------------------------------------------------------ */ -void ip_lookup_unload() +void +ipf_lookup_expire(softc) + ipf_main_softc_t *softc; { - ip_pool_fini(); - fr_htable_unload(); + ipf_lookup_softc_t *softl = softc->ipf_lookup_soft; + int i; - if (ip_lookup_inited == 1) { - RW_DESTROY(&ip_poolrw); - ip_lookup_inited = 0; - } + WRITE_ENTER(&softc->ipf_poolrw); + for (i = 0; i < MAX_BACKENDS; i++) + (*backends[i]->ipfl_expire)(softc, softl->ipf_back[i]); + RWLOCK_EXIT(&softc->ipf_poolrw); } /* ------------------------------------------------------------------------ */ -/* Function: iplookup_ioctl */ +/* Function: ipf_lookup_softc_destroy */ +/* Returns: int - 0 = success, else error */ +/* Parameters: softc(I) - pointer to soft context main structure */ +/* arg(I) - pointer to local context to use */ +/* */ +/* Free up all pool related memory that has been allocated whilst IPFilter */ +/* has been running. Also, do any other deinitialisation required such */ +/* ipf_lookup_init() can be called again, safely. */ +/* ------------------------------------------------------------------------ */ +void +ipf_lookup_soft_destroy(softc, arg) + ipf_main_softc_t *softc; + void *arg; +{ + ipf_lookup_softc_t *softl = (ipf_lookup_softc_t *)arg; + int i; + + for (i = 0; i < MAX_BACKENDS; i++) { + if (softl->ipf_back[i] != NULL) + (*backends[i]->ipfl_destroy)(softc, + softl->ipf_back[i]); + } + + KFREE(softl); +} + + +/* ------------------------------------------------------------------------ */ +/* Function: ipf_lookup_ioctl */ /* Returns: int - 0 = success, else error */ -/* Parameters: data(IO) - pointer to ioctl data to be copied to/from user */ +/* Parameters: softc(I) - pointer to soft context main structure */ +/* arg(I) - pointer to local context to use */ +/* data(IO) - pointer to ioctl data to be copied to/from user */ /* space. */ /* cmd(I) - ioctl command number */ /* mode(I) - file mode bits used with open */ +/* uid(I) - uid of process doing ioctl */ +/* ctx(I) - pointer that represents context for uid */ /* */ /* Handle ioctl commands sent to the ioctl device. For the most part, this */ /* involves just calling another function to handle the specifics of each */ /* command. */ /* ------------------------------------------------------------------------ */ -int ip_lookup_ioctl(data, cmd, mode, uid, ctx) -caddr_t data; -ioctlcmd_t cmd; -int mode, uid; -void *ctx; +int +ipf_lookup_ioctl(softc, data, cmd, mode, uid, ctx) + ipf_main_softc_t *softc; + caddr_t data; + ioctlcmd_t cmd; + int mode, uid; + void *ctx; { int err; SPL_INT(s); @@ -145,52 +265,53 @@ void *ctx; { case SIOCLOOKUPADDNODE : case SIOCLOOKUPADDNODEW : - WRITE_ENTER(&ip_poolrw); - err = iplookup_addnode(data); - RWLOCK_EXIT(&ip_poolrw); + WRITE_ENTER(&softc->ipf_poolrw); + err = ipf_lookup_addnode(softc, data, uid); + RWLOCK_EXIT(&softc->ipf_poolrw); break; case SIOCLOOKUPDELNODE : case SIOCLOOKUPDELNODEW : - WRITE_ENTER(&ip_poolrw); - err = iplookup_delnode(data); - RWLOCK_EXIT(&ip_poolrw); + WRITE_ENTER(&softc->ipf_poolrw); + err = ipf_lookup_delnode(softc, data, uid); + RWLOCK_EXIT(&softc->ipf_poolrw); break; case SIOCLOOKUPADDTABLE : - WRITE_ENTER(&ip_poolrw); - err = iplookup_addtable(data); - RWLOCK_EXIT(&ip_poolrw); + WRITE_ENTER(&softc->ipf_poolrw); + err = ipf_lookup_addtable(softc, data); + RWLOCK_EXIT(&softc->ipf_poolrw); break; case SIOCLOOKUPDELTABLE : - WRITE_ENTER(&ip_poolrw); - err = iplookup_deltable(data); - RWLOCK_EXIT(&ip_poolrw); + WRITE_ENTER(&softc->ipf_poolrw); + err = ipf_lookup_deltable(softc, data); + RWLOCK_EXIT(&softc->ipf_poolrw); break; case SIOCLOOKUPSTAT : case SIOCLOOKUPSTATW : - WRITE_ENTER(&ip_poolrw); - err = iplookup_stats(data); - RWLOCK_EXIT(&ip_poolrw); + WRITE_ENTER(&softc->ipf_poolrw); + err = ipf_lookup_stats(softc, data); + RWLOCK_EXIT(&softc->ipf_poolrw); break; case SIOCLOOKUPFLUSH : - WRITE_ENTER(&ip_poolrw); - err = iplookup_flush(data); - RWLOCK_EXIT(&ip_poolrw); + WRITE_ENTER(&softc->ipf_poolrw); + err = ipf_lookup_flush(softc, data); + RWLOCK_EXIT(&softc->ipf_poolrw); break; case SIOCLOOKUPITER : - err = iplookup_iterate(data, uid, ctx); + err = ipf_lookup_iterate(softc, data, uid, ctx); break; case SIOCIPFDELTOK : - err = iplookup_deltok(data, uid, ctx); + err = ipf_lookup_deltok(softc, data, uid, ctx); break; default : + IPFERROR(50001); err = EINVAL; break; } @@ -200,192 +321,155 @@ void *ctx; /* ------------------------------------------------------------------------ */ -/* Function: iplookup_addnode */ +/* Function: ipf_lookup_addnode */ /* Returns: int - 0 = success, else error */ -/* Parameters: data(I) - pointer to data from ioctl call */ +/* Parameters: softc(I) - pointer to soft context main structure */ +/* data(I) - pointer to data from ioctl call */ /* */ /* Add a new data node to a lookup structure. First, check to see if the */ /* parent structure refered to by name exists and if it does, then go on to */ /* add a node to it. */ /* ------------------------------------------------------------------------ */ -static int iplookup_addnode(data) -caddr_t data; +static int +ipf_lookup_addnode(softc, data, uid) + ipf_main_softc_t *softc; + caddr_t data; + int uid; { - ip_pool_node_t node, *m; + ipf_lookup_softc_t *softl = softc->ipf_lookup_soft; iplookupop_t op; - iphtable_t *iph; - iphtent_t hte; - ip_pool_t *p; + ipf_lookup_t **l; int err; + int i; err = BCOPYIN(data, &op, sizeof(op)); - if (err != 0) + if (err != 0) { + IPFERROR(50002); return EFAULT; + } - if (op.iplo_unit < 0 || op.iplo_unit > IPL_LOGMAX) + if ((op.iplo_unit < 0 || op.iplo_unit > IPL_LOGMAX) && + (op.iplo_unit != IPLT_ALL)) { + IPFERROR(50003); return EINVAL; + } op.iplo_name[sizeof(op.iplo_name) - 1] = '\0'; - switch (op.iplo_type) - { - case IPLT_POOL : - if (op.iplo_size != sizeof(node)) - return EINVAL; - - err = COPYIN(op.iplo_struct, &node, sizeof(node)); - if (err != 0) - return EFAULT; - - p = ip_pool_find(op.iplo_unit, op.iplo_name); - if (p == NULL) - return ESRCH; - - /* - * add an entry to a pool - return an error if it already - * exists remove an entry from a pool - if it exists - * - in both cases, the pool *must* exist! - */ - m = ip_pool_findeq(p, &node.ipn_addr, &node.ipn_mask); - if (m) - return EEXIST; - err = ip_pool_insert(p, &node.ipn_addr.adf_addr, - &node.ipn_mask.adf_addr, node.ipn_info); - break; - - case IPLT_HASH : - if (op.iplo_size != sizeof(hte)) - return EINVAL; - - err = COPYIN(op.iplo_struct, &hte, sizeof(hte)); - if (err != 0) - return EFAULT; - - iph = fr_findhtable(op.iplo_unit, op.iplo_name); - if (iph == NULL) - return ESRCH; - err = fr_addhtent(iph, &hte); - break; - - default : - err = EINVAL; - break; + for (i = 0, l = backends; i < MAX_BACKENDS; i++, l++) { + if (op.iplo_type == (*l)->ipfl_type) { + err = (*(*l)->ipfl_node_add)(softc, + softl->ipf_back[i], + &op, uid); + break; + } } + + if (i == MAX_BACKENDS) { + IPFERROR(50012); + err = EINVAL; + } + return err; } /* ------------------------------------------------------------------------ */ -/* Function: iplookup_delnode */ +/* Function: ipf_lookup_delnode */ /* Returns: int - 0 = success, else error */ -/* Parameters: data(I) - pointer to data from ioctl call */ +/* Parameters: softc(I) - pointer to soft context main structure */ +/* data(I) - pointer to data from ioctl call */ /* */ /* Delete a node from a lookup table by first looking for the table it is */ /* in and then deleting the entry that gets found. */ /* ------------------------------------------------------------------------ */ -static int iplookup_delnode(data) -caddr_t data; +static int +ipf_lookup_delnode(softc, data, uid) + ipf_main_softc_t *softc; + caddr_t data; + int uid; { - ip_pool_node_t node, *m; + ipf_lookup_softc_t *softl = softc->ipf_lookup_soft; iplookupop_t op; - iphtable_t *iph; - iphtent_t hte; - ip_pool_t *p; + ipf_lookup_t **l; int err; + int i; err = BCOPYIN(data, &op, sizeof(op)); - if (err != 0) + if (err != 0) { + IPFERROR(50042); return EFAULT; + } - if (op.iplo_unit < 0 || op.iplo_unit > IPL_LOGMAX) + if ((op.iplo_unit < 0 || op.iplo_unit > IPL_LOGMAX) && + (op.iplo_unit != IPLT_ALL)) { + IPFERROR(50013); return EINVAL; + } op.iplo_name[sizeof(op.iplo_name) - 1] = '\0'; - switch (op.iplo_type) - { - case IPLT_POOL : - if (op.iplo_size != sizeof(node)) - return EINVAL; + for (i = 0, l = backends; i < MAX_BACKENDS; i++, l++) { + if (op.iplo_type == (*l)->ipfl_type) { + err = (*(*l)->ipfl_node_del)(softc, softl->ipf_back[i], + &op, uid); + break; + } + } - err = COPYIN(op.iplo_struct, &node, sizeof(node)); - if (err != 0) - return EFAULT; - - p = ip_pool_find(op.iplo_unit, op.iplo_name); - if (!p) - return ESRCH; - - m = ip_pool_findeq(p, &node.ipn_addr, &node.ipn_mask); - if (m == NULL) - return ENOENT; - err = ip_pool_remove(p, m); - break; - - case IPLT_HASH : - if (op.iplo_size != sizeof(hte)) - return EINVAL; - - err = COPYIN(op.iplo_struct, &hte, sizeof(hte)); - if (err != 0) - return EFAULT; - - iph = fr_findhtable(op.iplo_unit, op.iplo_name); - if (iph == NULL) - return ESRCH; - err = fr_delhtent(iph, &hte); - break; - - default : + if (i == MAX_BACKENDS) { + IPFERROR(50021); err = EINVAL; - break; } return err; } /* ------------------------------------------------------------------------ */ -/* Function: iplookup_addtable */ +/* Function: ipf_lookup_addtable */ /* Returns: int - 0 = success, else error */ -/* Parameters: data(I) - pointer to data from ioctl call */ +/* Parameters: softc(I) - pointer to soft context main structure */ +/* data(I) - pointer to data from ioctl call */ /* */ /* Create a new lookup table, if one doesn't already exist using the name */ /* for this one. */ /* ------------------------------------------------------------------------ */ -static int iplookup_addtable(data) -caddr_t data; +static int +ipf_lookup_addtable(softc, data) + ipf_main_softc_t *softc; + caddr_t data; { + ipf_lookup_softc_t *softl = softc->ipf_lookup_soft; iplookupop_t op; - int err; + ipf_lookup_t **l; + int err, i; err = BCOPYIN(data, &op, sizeof(op)); - if (err != 0) + if (err != 0) { + IPFERROR(50022); return EFAULT; + } - if (op.iplo_unit < 0 || op.iplo_unit > IPL_LOGMAX) + if ((op.iplo_unit < 0 || op.iplo_unit > IPL_LOGMAX) && + (op.iplo_unit != IPLT_ALL)) { + IPFERROR(50023); return EINVAL; + } op.iplo_name[sizeof(op.iplo_name) - 1] = '\0'; - switch (op.iplo_type) - { - case IPLT_POOL : - if (ip_pool_find(op.iplo_unit, op.iplo_name) != NULL) - err = EEXIST; - else - err = ip_pool_create(&op); - break; + for (i = 0, l = backends; i < MAX_BACKENDS; i++, l++) { + if (op.iplo_type == (*l)->ipfl_type) { + err = (*(*l)->ipfl_table_add)(softc, + softl->ipf_back[i], + &op); + break; + } + } - case IPLT_HASH : - if (fr_findhtable(op.iplo_unit, op.iplo_name) != NULL) - err = EEXIST; - else - err = fr_newhtable(&op); - break; - - default : + if (i == MAX_BACKENDS) { + IPFERROR(50026); err = EINVAL; - break; } /* @@ -394,8 +478,10 @@ caddr_t data; */ if ((err == 0) && ((op.iplo_arg & LOOKUP_ANON) != 0)) { err = BCOPYOUT(&op, data, sizeof(op)); - if (err != 0) + if (err != 0) { + IPFERROR(50027); err = EFAULT; + } } return err; @@ -403,260 +489,317 @@ caddr_t data; /* ------------------------------------------------------------------------ */ -/* Function: iplookup_deltable */ +/* Function: ipf_lookup_deltable */ /* Returns: int - 0 = success, else error */ -/* Parameters: data(I) - pointer to data from ioctl call */ +/* Parameters: softc(I) - pointer to soft context main structure */ +/* data(I) - pointer to data from ioctl call */ /* */ /* Decodes ioctl request to remove a particular hash table or pool and */ /* calls the relevant function to do the cleanup. */ /* ------------------------------------------------------------------------ */ -static int iplookup_deltable(data) -caddr_t data; +static int +ipf_lookup_deltable(softc, data) + ipf_main_softc_t *softc; + caddr_t data; { + ipf_lookup_softc_t *softl = softc->ipf_lookup_soft; iplookupop_t op; - int err; + ipf_lookup_t **l; + int err, i; err = BCOPYIN(data, &op, sizeof(op)); - if (err != 0) + if (err != 0) { + IPFERROR(50028); return EFAULT; + } - if (op.iplo_unit < 0 || op.iplo_unit > IPL_LOGMAX) + if ((op.iplo_unit < 0 || op.iplo_unit > IPL_LOGMAX) && + (op.iplo_unit != IPLT_ALL)) { + IPFERROR(50029); return EINVAL; + } op.iplo_name[sizeof(op.iplo_name) - 1] = '\0'; - /* - * create a new pool - fail if one already exists with - * the same # - */ - switch (op.iplo_type) - { - case IPLT_POOL : - err = ip_pool_destroy(op.iplo_unit, op.iplo_name); - break; + for (i = 0, l = backends; i < MAX_BACKENDS; i++, l++) { + if (op.iplo_type == (*l)->ipfl_type) { + err = (*(*l)->ipfl_table_del)(softc, + softl->ipf_back[i], + &op); + break; + } + } - case IPLT_HASH : - err = fr_removehtable(op.iplo_unit, op.iplo_name); - break; - - default : + if (i == MAX_BACKENDS) { + IPFERROR(50030); err = EINVAL; - break; } return err; } /* ------------------------------------------------------------------------ */ -/* Function: iplookup_stats */ +/* Function: ipf_lookup_stats */ /* Returns: int - 0 = success, else error */ -/* Parameters: data(I) - pointer to data from ioctl call */ +/* Parameters: softc(I) - pointer to soft context main structure */ +/* data(I) - pointer to data from ioctl call */ /* */ /* Copy statistical information from inside the kernel back to user space. */ /* ------------------------------------------------------------------------ */ -static int iplookup_stats(data) -caddr_t data; +static int +ipf_lookup_stats(softc, data) + ipf_main_softc_t *softc; + caddr_t data; { + ipf_lookup_softc_t *softl = softc->ipf_lookup_soft; iplookupop_t op; + ipf_lookup_t **l; int err; + int i; err = BCOPYIN(data, &op, sizeof(op)); - if (err != 0) + if (err != 0) { + IPFERROR(50031); return EFAULT; - - if (op.iplo_unit < 0 || op.iplo_unit > IPL_LOGMAX) - return EINVAL; - - switch (op.iplo_type) - { - case IPLT_POOL : - err = ip_pool_statistics(&op); - break; - - case IPLT_HASH : - err = fr_gethtablestat(&op); - break; - - default : - err = EINVAL; - break; } + + if ((op.iplo_unit < 0 || op.iplo_unit > IPL_LOGMAX) && + (op.iplo_unit != IPLT_ALL)) { + IPFERROR(50032); + return EINVAL; + } + + for (i = 0, l = backends; i < MAX_BACKENDS; i++, l++) { + if (op.iplo_type == (*l)->ipfl_type) { + err = (*(*l)->ipfl_stats_get)(softc, + softl->ipf_back[i], + &op); + break; + } + } + + if (i == MAX_BACKENDS) { + IPFERROR(50033); + err = EINVAL; + } + return err; } /* ------------------------------------------------------------------------ */ -/* Function: iplookup_flush */ +/* Function: ipf_lookup_flush */ /* Returns: int - 0 = success, else error */ -/* Parameters: data(I) - pointer to data from ioctl call */ +/* Parameters: softc(I) - pointer to soft context main structure */ +/* data(I) - pointer to data from ioctl call */ /* */ /* A flush is called when we want to flush all the nodes from a particular */ /* entry in the hash table/pool or want to remove all groups from those. */ /* ------------------------------------------------------------------------ */ -static int iplookup_flush(data) -caddr_t data; +static int +ipf_lookup_flush(softc, data) + ipf_main_softc_t *softc; + caddr_t data; { - int err, unit, num, type; + ipf_lookup_softc_t *softl = softc->ipf_lookup_soft; + int err, unit, num, type, i; iplookupflush_t flush; + ipf_lookup_t **l; err = BCOPYIN(data, &flush, sizeof(flush)); - if (err != 0) + if (err != 0) { + IPFERROR(50034); return EFAULT; + } unit = flush.iplf_unit; - if ((unit < 0 || unit > IPL_LOGMAX) && (unit != IPLT_ALL)) + if ((unit < 0 || unit > IPL_LOGMAX) && (unit != IPLT_ALL)) { + IPFERROR(50035); return EINVAL; + } flush.iplf_name[sizeof(flush.iplf_name) - 1] = '\0'; type = flush.iplf_type; + IPFERROR(50036); err = EINVAL; num = 0; - if (type == IPLT_POOL || type == IPLT_ALL) { - err = 0; - num = ip_pool_flush(&flush); - } - - if (type == IPLT_HASH || type == IPLT_ALL) { - err = 0; - num += fr_flushhtable(&flush); + for (i = 0, l = backends; i < MAX_BACKENDS; i++, l++) { + if (type == (*l)->ipfl_type || type == IPLT_ALL) { + err = 0; + num += (*(*l)->ipfl_flush)(softc, + softl->ipf_back[i], + &flush); + } } if (err == 0) { flush.iplf_count = num; err = BCOPYOUT(&flush, data, sizeof(flush)); - if (err != 0) + if (err != 0) { + IPFERROR(50037); err = EFAULT; + } } return err; } /* ------------------------------------------------------------------------ */ -/* Function: ip_lookup_delref */ +/* Function: ipf_lookup_delref */ /* Returns: void */ -/* Parameters: type(I) - table type to operate on */ +/* Parameters: softc(I) - pointer to soft context main structure */ +/* type(I) - table type to operate on */ /* ptr(I) - pointer to object to remove reference for */ /* */ /* This function organises calling the correct deref function for a given */ /* type of object being passed into it. */ /* ------------------------------------------------------------------------ */ -void ip_lookup_deref(type, ptr) -int type; -void *ptr; +void +ipf_lookup_deref(softc, type, ptr) + ipf_main_softc_t *softc; + int type; + void *ptr; { + ipf_lookup_softc_t *softl = softc->ipf_lookup_soft; + int i; + if (ptr == NULL) return; - WRITE_ENTER(&ip_poolrw); - switch (type) - { - case IPLT_POOL : - ip_pool_deref(ptr); - break; - - case IPLT_HASH : - fr_derefhtable(ptr); - break; + for (i = 0; i < MAX_BACKENDS; i++) { + if (type == backends[i]->ipfl_type) { + WRITE_ENTER(&softc->ipf_poolrw); + (*backends[i]->ipfl_table_deref)(softc, + softl->ipf_back[i], + ptr); + RWLOCK_EXIT(&softc->ipf_poolrw); + break; + } } - RWLOCK_EXIT(&ip_poolrw); } /* ------------------------------------------------------------------------ */ -/* Function: iplookup_iterate */ +/* Function: ipf_lookup_iterate */ /* Returns: int - 0 = success, else error */ -/* Parameters: data(I) - pointer to data from ioctl call */ +/* Parameters: softc(I) - pointer to soft context main structure */ +/* data(I) - pointer to data from ioctl call */ /* uid(I) - uid of caller */ /* ctx(I) - pointer to give the uid context */ /* */ /* Decodes ioctl request to step through either hash tables or pools. */ /* ------------------------------------------------------------------------ */ -static int iplookup_iterate(data, uid, ctx) -void *data; -int uid; -void *ctx; +static int +ipf_lookup_iterate(softc, data, uid, ctx) + ipf_main_softc_t *softc; + void *data; + int uid; + void *ctx; { + ipf_lookup_softc_t *softl = softc->ipf_lookup_soft; ipflookupiter_t iter; ipftoken_t *token; - int err; + int err, i; SPL_INT(s); - err = fr_inobj(data, &iter, IPFOBJ_LOOKUPITER); + err = ipf_inobj(softc, data, NULL, &iter, IPFOBJ_LOOKUPITER); if (err != 0) return err; - if (iter.ili_unit > IPL_LOGMAX) + if (iter.ili_unit < IPL_LOGALL && iter.ili_unit > IPL_LOGMAX) { + IPFERROR(50038); return EINVAL; + } - if (iter.ili_ival != IPFGENITER_LOOKUP) + if (iter.ili_ival != IPFGENITER_LOOKUP) { + IPFERROR(50039); return EINVAL; + } SPL_SCHED(s); - token = ipf_findtoken(iter.ili_key, uid, ctx); + token = ipf_token_find(softc, iter.ili_key, uid, ctx); if (token == NULL) { - RWLOCK_EXIT(&ipf_tokens); SPL_X(s); + IPFERROR(50040); return ESRCH; } - switch (iter.ili_type) - { - case IPLT_POOL : - err = ip_pool_getnext(token, &iter); - break; - case IPLT_HASH : - err = fr_htable_getnext(token, &iter); - break; - default : - err = EINVAL; - break; + for (i = 0; i < MAX_BACKENDS; i++) { + if (iter.ili_type == backends[i]->ipfl_type) { + err = (*backends[i]->ipfl_iter_next)(softc, + softl->ipf_back[i], + token, &iter); + break; + } } - RWLOCK_EXIT(&ipf_tokens); SPL_X(s); + if (i == MAX_BACKENDS) { + IPFERROR(50041); + err = EINVAL; + } + + WRITE_ENTER(&softc->ipf_tokens); + ipf_token_deref(softc, token); + RWLOCK_EXIT(&softc->ipf_tokens); + return err; } /* ------------------------------------------------------------------------ */ -/* Function: iplookup_iterderef */ -/* Returns: int - 0 = success, else error */ -/* Parameters: data(I) - pointer to data from ioctl call */ +/* Function: ipf_lookup_iterderef */ +/* Returns: void */ +/* Parameters: softc(I) - pointer to soft context main structure */ +/* type(I) - backend type to iterate through */ +/* data(I) - pointer to data from ioctl call */ /* */ /* Decodes ioctl request to remove a particular hash table or pool and */ /* calls the relevant function to do the cleanup. */ +/* Because each of the backend types has a different data structure, */ +/* iteration is limited to one type at a time (i.e. it is not permitted to */ +/* go on from pool types to hash types as part of the "get next".) */ /* ------------------------------------------------------------------------ */ -void ip_lookup_iterderef(type, data) -u_32_t type; -void *data; +void +ipf_lookup_iterderef(softc, type, data) + ipf_main_softc_t *softc; + u_32_t type; + void *data; { - iplookupiterkey_t key; + ipf_lookup_softc_t *softl = softc->ipf_lookup_soft; + struct iplookupiterkey *lkey; + iplookupiterkey_t key; + int i; key.ilik_key = type; + lkey = &key.ilik_unstr; - if (key.ilik_unstr.ilik_ival != IPFGENITER_LOOKUP) + if (lkey->ilik_ival != IPFGENITER_LOOKUP) return; - switch (key.ilik_unstr.ilik_type) - { - case IPLT_HASH : - fr_htable_iterderef((u_int)key.ilik_unstr.ilik_otype, - (int)key.ilik_unstr.ilik_unit, data); - break; - case IPLT_POOL : - ip_pool_iterderef((u_int)key.ilik_unstr.ilik_otype, - (int)key.ilik_unstr.ilik_unit, data); - break; + WRITE_ENTER(&softc->ipf_poolrw); + + for (i = 0; i < MAX_BACKENDS; i++) { + if (lkey->ilik_type == backends[i]->ipfl_type) { + (*backends[i]->ipfl_iter_deref)(softc, + softl->ipf_back[i], + lkey->ilik_otype, + lkey->ilik_unit, + data); + break; + } } + RWLOCK_EXIT(&softc->ipf_poolrw); } /* ------------------------------------------------------------------------ */ -/* Function: iplookup_deltok */ +/* Function: ipf_lookup_deltok */ /* Returns: int - 0 = success, else error */ -/* Parameters: data(I) - pointer to data from ioctl call */ +/* Parameters: softc(I) - pointer to soft context main structure */ +/* data(I) - pointer to data from ioctl call */ /* uid(I) - uid of caller */ /* ctx(I) - pointer to give the uid context */ /* */ @@ -664,32 +807,198 @@ void *data; /* "key" is a combination of the table type, iterator type and the unit for */ /* which the token was being used. */ /* ------------------------------------------------------------------------ */ -static int iplookup_deltok(data, uid, ctx) -void *data; -int uid; -void *ctx; +int +ipf_lookup_deltok(softc, data, uid, ctx) + ipf_main_softc_t *softc; + void *data; + int uid; + void *ctx; { int error, key; SPL_INT(s); SPL_SCHED(s); - error = BCOPYIN(data, &key, sizeof(key)); + error = BCOPYIN(data, &key, sizeof(key)); if (error == 0) - error = ipf_deltoken(key, uid, ctx); + error = ipf_token_del(softc, key, uid, ctx); SPL_X(s); return error; } -#else /* IPFILTER_LOOKUP */ - -/*ARGSUSED*/ -int ip_lookup_ioctl(data, cmd, mode, uid, ctx) -caddr_t data; -ioctlcmd_t cmd; -int mode, uid; -void *ctx; +/* ------------------------------------------------------------------------ */ +/* Function: ipf_lookup_res_num */ +/* Returns: void * - NULL = failure, else success. */ +/* Parameters: softc(I) - pointer to soft context main structure */ +/* unit(I) - device for which this is for */ +/* type(I) - type of lookup these parameters are for. */ +/* number(I) - table number to use when searching */ +/* funcptr(IO) - pointer to pointer for storing IP address */ +/* searching function. */ +/* */ +/* Search for the "table" number passed in amongst those configured for */ +/* that particular type. If the type is recognised then the function to */ +/* call to do the IP address search will be change, regardless of whether */ +/* or not the "table" number exists. */ +/* ------------------------------------------------------------------------ */ +void * +ipf_lookup_res_num(softc, unit, type, number, funcptr) + ipf_main_softc_t *softc; + int unit; + u_int type; + u_int number; + lookupfunc_t *funcptr; { - return EIO; + char name[FR_GROUPLEN]; + +#if defined(SNPRINTF) && defined(_KERNEL) + SNPRINTF(name, sizeof(name), "%u", number); +#else + (void) sprintf(name, "%u", number); +#endif + + return ipf_lookup_res_name(softc, unit, type, name, funcptr); } -#endif /* IPFILTER_LOOKUP */ + + +/* ------------------------------------------------------------------------ */ +/* Function: ipf_lookup_res_name */ +/* Returns: void * - NULL = failure, else success. */ +/* Parameters: softc(I) - pointer to soft context main structure */ +/* unit(I) - device for which this is for */ +/* type(I) - type of lookup these parameters are for. */ +/* name(I) - table name to use when searching */ +/* funcptr(IO) - pointer to pointer for storing IP address */ +/* searching function. */ +/* */ +/* Search for the "table" number passed in amongst those configured for */ +/* that particular type. If the type is recognised then the function to */ +/* call to do the IP address search will be changed, regardless of whether */ +/* or not the "table" number exists. */ +/* ------------------------------------------------------------------------ */ +void * +ipf_lookup_res_name(softc, unit, type, name, funcptr) + ipf_main_softc_t *softc; + int unit; + u_int type; + char *name; + lookupfunc_t *funcptr; +{ + ipf_lookup_softc_t *softl = softc->ipf_lookup_soft; + ipf_lookup_t **l; + void *ptr = NULL; + int i; + + READ_ENTER(&softc->ipf_poolrw); + + for (i = 0, l = backends; i < MAX_BACKENDS; i++, l++) { + if (type == (*l)->ipfl_type) { + ptr = (*(*l)->ipfl_select_add_ref)(softl->ipf_back[i], + unit, name); + if (ptr != NULL && funcptr != NULL) { + *funcptr = (*l)->ipfl_addr_find; + } + break; + } + } + + if (i == MAX_BACKENDS) { + ptr = NULL; + if (funcptr != NULL) + *funcptr = NULL; + } + + RWLOCK_EXIT(&softc->ipf_poolrw); + + return ptr; +} + + +/* ------------------------------------------------------------------------ */ +/* Function: ipf_lookup_find_htable */ +/* Returns: void * - NULL = failure, else success. */ +/* Parameters: softc(I) - pointer to soft context main structure */ +/* unit(I) - device for which this is for */ +/* name(I) - table name to use when searching */ +/* */ +/* To support the group-map feature, where a hash table maps address */ +/* networks to rule group numbers, we need to expose a function that uses */ +/* only the hash table backend. */ +/* ------------------------------------------------------------------------ */ +void * +ipf_lookup_find_htable(softc, unit, name) + ipf_main_softc_t *softc; + int unit; + char *name; +{ + ipf_lookup_softc_t *softl = softc->ipf_lookup_soft; + ipf_lookup_t **l; + void *tab = NULL; + int i; + + READ_ENTER(&softc->ipf_poolrw); + + for (i = 0, l = backends; i < MAX_BACKENDS; i++, l++) + if (IPLT_HASH == (*l)->ipfl_type) { + tab = ipf_htable_find(softl->ipf_back[i], unit, name); + break; + } + + RWLOCK_EXIT(&softc->ipf_poolrw); + + return tab; +} + + +/* ------------------------------------------------------------------------ */ +/* Function: ipf_lookup_sync */ +/* Returns: void */ +/* Parameters: softc(I) - pointer to soft context main structure */ +/* */ +/* This function is the interface that the machine dependent sync functions */ +/* call when a network interface name change occurs. It then calls the sync */ +/* functions of the lookup implementations - if they have one. */ +/* ------------------------------------------------------------------------ */ +/*ARGSUSED*/ +void +ipf_lookup_sync(softc, ifp) + ipf_main_softc_t *softc; + void *ifp; +{ + ipf_lookup_softc_t *softl = softc->ipf_lookup_soft; + ipf_lookup_t **l; + int i; + + READ_ENTER(&softc->ipf_poolrw); + + for (i = 0, l = backends; i < MAX_BACKENDS; i++, l++) + if ((*l)->ipfl_sync != NULL) + (*(*l)->ipfl_sync)(softc, softl->ipf_back[i]); + + RWLOCK_EXIT(&softc->ipf_poolrw); +} + + +#ifndef _KERNEL +void +ipf_lookup_dump(softc, arg) + ipf_main_softc_t *softc; + void *arg; +{ + ipf_lookup_softc_t *softl = softc->ipf_lookup_soft; + ipf_lookup_t **l; + int i; + + for (i = 0, l = backends; i < MAX_BACKENDS; i++, l++) + if (IPLT_POOL == (*l)->ipfl_type) { + ipf_pool_dump(softc, softl->ipf_back[i]); + break; + } + + for (i = 0, l = backends; i < MAX_BACKENDS; i++, l++) + if (IPLT_HASH == (*l)->ipfl_type) { + ipf_htable_dump(softc, softl->ipf_back[i]); + break; + } +} +#endif diff --git a/sys/contrib/ipfilter/netinet/ip_lookup.h b/sys/contrib/ipfilter/netinet/ip_lookup.h index 3886df16303d..181e1bc5d176 100644 --- a/sys/contrib/ipfilter/netinet/ip_lookup.h +++ b/sys/contrib/ipfilter/netinet/ip_lookup.h @@ -1,4 +1,10 @@ - +/* + * Copyright (C) 2012 by Darren Reed. + * + * See the IPFILTER.LICENCE file for details on licencing. + * + * $Id$ + */ #ifndef __IP_LOOKUP_H__ #define __IP_LOOKUP_H__ @@ -24,6 +30,9 @@ # define SIOCLOOKUPDELNODEW _IOW(r, 68, struct iplookupop) #endif +#define LOOKUP_POOL_MAX (IPL_LOGSIZE) +#define LOOKUP_POOL_SZ (IPL_LOGSIZE + 1) + typedef struct iplookupop { int iplo_type; /* IPLT_* */ int iplo_unit; /* IPL_LOG* */ @@ -40,7 +49,7 @@ typedef struct iplookupflush { int iplf_type; /* IPLT_* */ int iplf_unit; /* IPL_LOG* */ u_int iplf_arg; - size_t iplf_count; + u_int iplf_count; char iplf_name[FR_GROUPLEN]; } iplookupflush_t; @@ -55,16 +64,18 @@ typedef struct iplookuplink { #define IPLT_NONE 0 #define IPLT_POOL 1 #define IPLT_HASH 2 +#define IPLT_DSTLIST 3 + #define IPLT_ANON 0x80000000 typedef union { struct iplookupiterkey { - char ilik_ival; + u_char ilik_ival; u_char ilik_type; /* IPLT_* */ u_char ilik_otype; - u_char ilik_unit; /* IPL_LOG* */ + signed char ilik_unit; /* IPL_LOG* */ } ilik_unstr; u_32_t ilik_key; } iplookupiterkey_t; @@ -86,10 +97,56 @@ typedef struct ipflookupiter { #define IPFLOOKUPITER_NODE 1 -extern int ip_lookup_init __P((void)); -extern int ip_lookup_ioctl __P((caddr_t, ioctlcmd_t, int, int, void *)); -extern void ip_lookup_unload __P((void)); -extern void ip_lookup_deref __P((int, void *)); -extern void ip_lookup_iterderef __P((u_32_t, void *)); +typedef struct ipf_lookup { + int ipfl_type; + void *(*ipfl_create) __P((ipf_main_softc_t *)); + void (*ipfl_destroy) __P((ipf_main_softc_t *, void *)); + int (*ipfl_init) __P((ipf_main_softc_t *, void *)); + void (*ipfl_fini) __P((ipf_main_softc_t *, void *)); + int (*ipfl_addr_find) __P((ipf_main_softc_t *, void *, + int, void *, u_int)); + size_t (*ipfl_flush) __P((ipf_main_softc_t *, void *, + iplookupflush_t *)); + int (*ipfl_iter_deref) __P((ipf_main_softc_t *, void *, + int, int, void *)); + int (*ipfl_iter_next) __P((ipf_main_softc_t *, void *, + ipftoken_t *, ipflookupiter_t *)); + int (*ipfl_node_add) __P((ipf_main_softc_t *, void *, + iplookupop_t *, int)); + int (*ipfl_node_del) __P((ipf_main_softc_t *, void *, + iplookupop_t *, int)); + int (*ipfl_stats_get) __P((ipf_main_softc_t *, void *, + iplookupop_t *)); + int (*ipfl_table_add) __P((ipf_main_softc_t *, void *, + iplookupop_t *)); + int (*ipfl_table_del) __P((ipf_main_softc_t *, void *, + iplookupop_t *)); + int (*ipfl_table_deref) __P((ipf_main_softc_t *, void *, void *)); + void *(*ipfl_table_find) __P((void *, int, char *)); + void *(*ipfl_select_add_ref) __P((void *, int, char *)); + int (*ipfl_select_node) __P((fr_info_t *, void *, u_32_t *, + frdest_t *)); + void (*ipfl_expire) __P((ipf_main_softc_t *, void *)); + void (*ipfl_sync) __P((ipf_main_softc_t *, void *)); +} ipf_lookup_t; +extern int ipf_lookup_init __P((void)); +extern int ipf_lookup_ioctl __P((ipf_main_softc_t *, caddr_t, ioctlcmd_t, int, int, void *)); +extern void ipf_lookup_main_unload __P((void)); +extern void ipf_lookup_deref __P((ipf_main_softc_t *, int, void *)); +extern void ipf_lookup_iterderef __P((ipf_main_softc_t *, u_32_t, void *)); +extern void *ipf_lookup_res_name __P((ipf_main_softc_t *, int, u_int, char *, + lookupfunc_t *)); +extern void *ipf_lookup_res_num __P((ipf_main_softc_t *, int, u_int, u_int, + lookupfunc_t *)); +extern void ipf_lookup_soft_destroy __P((ipf_main_softc_t *, void *)); +extern void *ipf_lookup_soft_create __P((ipf_main_softc_t *)); +extern int ipf_lookup_soft_init __P((ipf_main_softc_t *, void *)); +extern int ipf_lookup_soft_fini __P((ipf_main_softc_t *, void *)); +extern void *ipf_lookup_find_htable __P((ipf_main_softc_t *, int, char *)); +extern void ipf_lookup_expire __P((ipf_main_softc_t *)); +extern void ipf_lookup_sync __P((ipf_main_softc_t *, void *)); +#ifndef _KERNEL +extern void ipf_lookup_dump __P((ipf_main_softc_t *, void *)); +#endif #endif /* __IP_LOOKUP_H__ */ diff --git a/sys/contrib/ipfilter/netinet/ip_nat.c b/sys/contrib/ipfilter/netinet/ip_nat.c index f790c7d1ec3b..d6647085a7eb 100644 --- a/sys/contrib/ipfilter/netinet/ip_nat.c +++ b/sys/contrib/ipfilter/netinet/ip_nat.c @@ -1,7 +1,7 @@ /* $FreeBSD$ */ /* - * Copyright (C) 1995-2003 by Darren Reed. + * Copyright (C) 2012 by Darren Reed. * * See the IPFILTER.LICENCE file for details on licencing. */ @@ -16,30 +16,23 @@ #include #include #include -#if defined(_KERNEL) && defined(__NetBSD_Version__) && \ - (__NetBSD_Version__ >= 399002000) +#if defined(_KERNEL) && \ + (defined(__NetBSD_Version) && (__NetBSD_Version >= 399002000)) # include #endif -#if defined(__NetBSD__) && (NetBSD >= 199905) && !defined(IPFILTER_LKM) && \ - defined(_KERNEL) -#if defined(__NetBSD_Version__) && (__NetBSD_Version__ < 399001400) -# include "opt_ipfilter_log.h" -# else -# include "opt_ipfilter.h" -# endif -#endif #if !defined(_KERNEL) # include # include # include -# define _KERNEL -# ifdef __OpenBSD__ +# define KERNEL +# ifdef _OpenBSD__ struct file; # endif # include -# undef _KERNEL +# undef KERNEL #endif -#if defined(_KERNEL) && (__FreeBSD_version >= 220000) +#if defined(_KERNEL) && \ + defined(__FreeBSD_version) && (__FreeBSD_version >= 220000) # include # include #else @@ -61,7 +54,7 @@ struct file; #if defined(__SVR4) || defined(__svr4__) # include # include -# ifdef _KERNEL +# ifdef KERNEL # include # endif # include @@ -73,14 +66,10 @@ struct file; #include #if __FreeBSD_version >= 300000 # include -# if defined(_KERNEL) && !defined(IPFILTER_LKM) -# include "opt_ipfilter.h" -# endif #endif #ifdef sun # include #endif -#include #include #include #include @@ -99,17 +88,23 @@ extern struct ifnet vpnif; #include #include "netinet/ip_compat.h" #include +#include "netinet/ipl.h" #include "netinet/ip_fil.h" #include "netinet/ip_nat.h" #include "netinet/ip_frag.h" #include "netinet/ip_state.h" #include "netinet/ip_proxy.h" -#ifdef IPFILTER_SYNC +#include "netinet/ip_lookup.h" +#include "netinet/ip_dstlist.h" #include "netinet/ip_sync.h" -#endif -#if (__FreeBSD_version >= 300000) +#if FREEBSD_GE_REV(300000) # include #endif +#ifdef HAS_SYS_MD5_H +# include +#else +# include "md5.h" +#endif /* END OF INCLUDES */ #undef SOCKADDR_IN @@ -122,195 +117,396 @@ static const char rcsid[] = "@(#)$FreeBSD$"; #endif +#define NATFSUM(n,v,f) ((v) == 4 ? (n)->f.in4.s_addr : (n)->f.i6[0] + \ + (n)->f.i6[1] + (n)->f.i6[2] + (n)->f.i6[3]) +#define NBUMP(x) softn->(x)++ +#define NBUMPD(x, y) do { \ + softn->x.y++; \ + DT(y); \ + } while (0) +#define NBUMPSIDE(y,x) softn->ipf_nat_stats.ns_side[y].x++ +#define NBUMPSIDED(y,x) do { softn->ipf_nat_stats.ns_side[y].x++; \ + DT(x); } while (0) +#define NBUMPSIDEX(y,x,z) \ + do { softn->ipf_nat_stats.ns_side[y].x++; \ + DT(z); } while (0) +#define NBUMPSIDEDF(y,x)do { softn->ipf_nat_stats.ns_side[y].x++; \ + DT1(x, fr_info_t *, fin); } while (0) + +frentry_t ipfnatblock; + +static ipftuneable_t ipf_nat_tuneables[] = { + /* nat */ + { { (void *)offsetof(ipf_nat_softc_t, ipf_nat_lock) }, + "nat_lock", 0, 1, + stsizeof(ipf_nat_softc_t, ipf_nat_lock), + IPFT_RDONLY, NULL, NULL }, + { { (void *)offsetof(ipf_nat_softc_t, ipf_nat_table_sz) }, + "nat_table_size", 1, 0x7fffffff, + stsizeof(ipf_nat_softc_t, ipf_nat_table_sz), + 0, NULL, ipf_nat_rehash }, + { { (void *)offsetof(ipf_nat_softc_t, ipf_nat_table_max) }, + "nat_table_max", 1, 0x7fffffff, + stsizeof(ipf_nat_softc_t, ipf_nat_table_max), + 0, NULL, NULL }, + { { (void *)offsetof(ipf_nat_softc_t, ipf_nat_maprules_sz) }, + "nat_rules_size", 1, 0x7fffffff, + stsizeof(ipf_nat_softc_t, ipf_nat_maprules_sz), + 0, NULL, ipf_nat_rehash_rules }, + { { (void *)offsetof(ipf_nat_softc_t, ipf_nat_rdrrules_sz) }, + "rdr_rules_size", 1, 0x7fffffff, + stsizeof(ipf_nat_softc_t, ipf_nat_rdrrules_sz), + 0, NULL, ipf_nat_rehash_rules }, + { { (void *)offsetof(ipf_nat_softc_t, ipf_nat_hostmap_sz) }, + "hostmap_size", 1, 0x7fffffff, + stsizeof(ipf_nat_softc_t, ipf_nat_hostmap_sz), + 0, NULL, ipf_nat_hostmap_rehash }, + { { (void *)offsetof(ipf_nat_softc_t, ipf_nat_maxbucket) }, + "nat_maxbucket",1, 0x7fffffff, + stsizeof(ipf_nat_softc_t, ipf_nat_maxbucket), + 0, NULL, NULL }, + { { (void *)offsetof(ipf_nat_softc_t, ipf_nat_logging) }, + "nat_logging", 0, 1, + stsizeof(ipf_nat_softc_t, ipf_nat_logging), + 0, NULL, NULL }, + { { (void *)offsetof(ipf_nat_softc_t, ipf_nat_doflush) }, + "nat_doflush", 0, 1, + stsizeof(ipf_nat_softc_t, ipf_nat_doflush), + 0, NULL, NULL }, + { { (void *)offsetof(ipf_nat_softc_t, ipf_nat_table_wm_low) }, + "nat_table_wm_low", 1, 99, + stsizeof(ipf_nat_softc_t, ipf_nat_table_wm_low), + 0, NULL, NULL }, + { { (void *)offsetof(ipf_nat_softc_t, ipf_nat_table_wm_high) }, + "nat_table_wm_high", 2, 100, + stsizeof(ipf_nat_softc_t, ipf_nat_table_wm_high), + 0, NULL, NULL }, + { { 0 }, + NULL, 0, 0, + 0, + 0, NULL, NULL } +}; + /* ======================================================================== */ /* How the NAT is organised and works. */ /* */ /* Inside (interface y) NAT Outside (interface x) */ /* -------------------- -+- ------------------------------------- */ -/* Packet going | out, processsed by fr_checknatout() for x */ +/* Packet going | out, processsed by ipf_nat_checkout() for x */ /* ------------> | ------------> */ /* src=10.1.1.1 | src=192.1.1.1 */ /* | */ -/* | in, processed by fr_checknatin() for x */ +/* | in, processed by ipf_nat_checkin() for x */ /* <------------ | <------------ */ /* dst=10.1.1.1 | dst=192.1.1.1 */ /* -------------------- -+- ------------------------------------- */ -/* fr_checknatout() - changes ip_src and if required, sport */ +/* ipf_nat_checkout() - changes ip_src and if required, sport */ /* - creates a new mapping, if required. */ -/* fr_checknatin() - changes ip_dst and if required, dport */ +/* ipf_nat_checkin() - changes ip_dst and if required, dport */ /* */ /* In the NAT table, internal source is recorded as "in" and externally */ /* seen as "out". */ /* ======================================================================== */ -nat_t **nat_table[2] = { NULL, NULL }, - *nat_instances = NULL; -ipnat_t *nat_list = NULL; -u_int ipf_nattable_max = NAT_TABLE_MAX; -u_int ipf_nattable_sz = NAT_TABLE_SZ; -u_int ipf_natrules_sz = NAT_SIZE; -u_int ipf_rdrrules_sz = RDR_SIZE; -u_int ipf_hostmap_sz = HOSTMAP_SIZE; -u_int fr_nat_maxbucket = 0, - fr_nat_maxbucket_reset = 1; -u_32_t nat_masks = 0; -u_32_t rdr_masks = 0; -u_long nat_last_force_flush = 0; -ipnat_t **nat_rules = NULL; -ipnat_t **rdr_rules = NULL; -hostmap_t **ipf_hm_maptable = NULL; -hostmap_t *ipf_hm_maplist = NULL; -ipftq_t nat_tqb[IPF_TCP_NSTATES]; -ipftq_t nat_udptq; -ipftq_t nat_icmptq; -ipftq_t nat_iptq; -ipftq_t *nat_utqe = NULL; -int fr_nat_doflush = 0; -#ifdef IPFILTER_LOG -int nat_logging = 1; -#else -int nat_logging = 0; -#endif - -u_long fr_defnatage = DEF_NAT_AGE, - fr_defnatipage = 120, /* 60 seconds */ - fr_defnaticmpage = 6; /* 3 seconds */ -natstat_t nat_stats; -int fr_nat_lock = 0; -int fr_nat_init = 0; -#if SOLARIS && !defined(_INET_IP_STACK_H) +#if SOLARIS && !defined(INSTANCES) extern int pfil_delayed_copy; #endif -static int nat_flush_entry __P((void *)); -static int nat_flushtable __P((void)); -static int nat_clearlist __P((void)); -static void nat_addnat __P((struct ipnat *)); -static void nat_addrdr __P((struct ipnat *)); -static void nat_delrdr __P((struct ipnat *)); -static void nat_delnat __P((struct ipnat *)); -static int fr_natgetent __P((caddr_t, int)); -static int fr_natgetsz __P((caddr_t, int)); -static int fr_natputent __P((caddr_t, int)); -static int nat_extraflush __P((int)); -static int nat_gettable __P((char *)); -static void nat_tabmove __P((nat_t *)); -static int nat_match __P((fr_info_t *, ipnat_t *)); -static INLINE int nat_newmap __P((fr_info_t *, nat_t *, natinfo_t *)); -static INLINE int nat_newrdr __P((fr_info_t *, nat_t *, natinfo_t *)); -static hostmap_t *nat_hostmap __P((ipnat_t *, struct in_addr, - struct in_addr, struct in_addr, u_32_t)); -static int nat_icmpquerytype4 __P((int)); -static int nat_siocaddnat __P((ipnat_t *, ipnat_t **, int)); -static void nat_siocdelnat __P((ipnat_t *, ipnat_t **, int)); -static int nat_finalise __P((fr_info_t *, nat_t *, natinfo_t *, - tcphdr_t *, nat_t **, int)); -static int nat_resolverule __P((ipnat_t *)); -static nat_t *fr_natclone __P((fr_info_t *, nat_t *)); -static void nat_mssclamp __P((tcphdr_t *, u_32_t, fr_info_t *, u_short *)); -static int nat_wildok __P((nat_t *, int, int, int, int)); -static int nat_getnext __P((ipftoken_t *, ipfgeniter_t *)); -static int nat_iterator __P((ipftoken_t *, ipfgeniter_t *)); - +static int ipf_nat_flush_entry __P((ipf_main_softc_t *, void *)); +static int ipf_nat_getent __P((ipf_main_softc_t *, caddr_t, int)); +static int ipf_nat_getsz __P((ipf_main_softc_t *, caddr_t, int)); +static int ipf_nat_putent __P((ipf_main_softc_t *, caddr_t, int)); +static void ipf_nat_addmap __P((ipf_nat_softc_t *, ipnat_t *)); +static void ipf_nat_addrdr __P((ipf_nat_softc_t *, ipnat_t *)); +static int ipf_nat_builddivertmp __P((ipf_nat_softc_t *, ipnat_t *)); +static int ipf_nat_clearlist __P((ipf_main_softc_t *, ipf_nat_softc_t *)); +static int ipf_nat_cmp_rules __P((ipnat_t *, ipnat_t *)); +static int ipf_nat_decap __P((fr_info_t *, nat_t *)); +static void ipf_nat_delrule __P((ipf_main_softc_t *, ipf_nat_softc_t *, + ipnat_t *, int)); +static int ipf_nat_extraflush __P((ipf_main_softc_t *, ipf_nat_softc_t *, int)); +static int ipf_nat_finalise __P((fr_info_t *, nat_t *)); +static int ipf_nat_flushtable __P((ipf_main_softc_t *, ipf_nat_softc_t *)); +static int ipf_nat_getnext __P((ipf_main_softc_t *, ipftoken_t *, + ipfgeniter_t *, ipfobj_t *)); +static int ipf_nat_gettable __P((ipf_main_softc_t *, ipf_nat_softc_t *, + char *)); +static hostmap_t *ipf_nat_hostmap __P((ipf_nat_softc_t *, ipnat_t *, + struct in_addr, struct in_addr, + struct in_addr, u_32_t)); +static int ipf_nat_icmpquerytype __P((int)); +static int ipf_nat_iterator __P((ipf_main_softc_t *, ipftoken_t *, + ipfgeniter_t *, ipfobj_t *)); +static int ipf_nat_match __P((fr_info_t *, ipnat_t *)); +static int ipf_nat_matcharray __P((nat_t *, int *, u_long)); +static int ipf_nat_matchflush __P((ipf_main_softc_t *, ipf_nat_softc_t *, + caddr_t)); +static void ipf_nat_mssclamp __P((tcphdr_t *, u_32_t, fr_info_t *, + u_short *)); +static int ipf_nat_newmap __P((fr_info_t *, nat_t *, natinfo_t *)); +static int ipf_nat_newdivert __P((fr_info_t *, nat_t *, natinfo_t *)); +static int ipf_nat_newrdr __P((fr_info_t *, nat_t *, natinfo_t *)); +static int ipf_nat_newrewrite __P((fr_info_t *, nat_t *, natinfo_t *)); +static int ipf_nat_nextaddr __P((fr_info_t *, nat_addr_t *, u_32_t *, + u_32_t *)); +static int ipf_nat_nextaddrinit __P((ipf_main_softc_t *, char *, + nat_addr_t *, int, void *)); +static int ipf_nat_resolverule __P((ipf_main_softc_t *, ipnat_t *)); +static int ipf_nat_ruleaddrinit __P((ipf_main_softc_t *, + ipf_nat_softc_t *, ipnat_t *)); +static void ipf_nat_rule_fini __P((ipf_main_softc_t *, ipnat_t *)); +static int ipf_nat_rule_init __P((ipf_main_softc_t *, ipf_nat_softc_t *, + ipnat_t *)); +static int ipf_nat_siocaddnat __P((ipf_main_softc_t *, ipf_nat_softc_t *, + ipnat_t *, int)); +static void ipf_nat_siocdelnat __P((ipf_main_softc_t *, ipf_nat_softc_t *, + ipnat_t *, int)); +static void ipf_nat_tabmove __P((ipf_nat_softc_t *, nat_t *)); /* ------------------------------------------------------------------------ */ -/* Function: fr_natinit */ +/* Function: ipf_nat_main_load */ /* Returns: int - 0 == success, -1 == failure */ /* Parameters: Nil */ /* */ -/* Initialise all of the NAT locks, tables and other structures. */ +/* The only global NAT structure that needs to be initialised is the filter */ +/* rule that is used with blocking packets. */ /* ------------------------------------------------------------------------ */ -int fr_natinit() +int +ipf_nat_main_load() { - int i; + bzero((char *)&ipfnatblock, sizeof(ipfnatblock)); + ipfnatblock.fr_flags = FR_BLOCK|FR_QUICK; + ipfnatblock.fr_ref = 1; - KMALLOCS(nat_table[0], nat_t **, sizeof(nat_t *) * ipf_nattable_sz); - if (nat_table[0] != NULL) - bzero((char *)nat_table[0], ipf_nattable_sz * sizeof(nat_t *)); - else - return -1; + return 0; +} - KMALLOCS(nat_table[1], nat_t **, sizeof(nat_t *) * ipf_nattable_sz); - if (nat_table[1] != NULL) - bzero((char *)nat_table[1], ipf_nattable_sz * sizeof(nat_t *)); - else - return -2; - KMALLOCS(nat_rules, ipnat_t **, sizeof(ipnat_t *) * ipf_natrules_sz); - if (nat_rules != NULL) - bzero((char *)nat_rules, ipf_natrules_sz * sizeof(ipnat_t *)); - else - return -3; +/* ------------------------------------------------------------------------ */ +/* Function: ipf_nat_main_unload */ +/* Returns: int - 0 == success, -1 == failure */ +/* Parameters: Nil */ +/* */ +/* A null-op function that exists as a placeholder so that the flow in */ +/* other functions is obvious. */ +/* ------------------------------------------------------------------------ */ +int +ipf_nat_main_unload() +{ + return 0; +} - KMALLOCS(rdr_rules, ipnat_t **, sizeof(ipnat_t *) * ipf_rdrrules_sz); - if (rdr_rules != NULL) - bzero((char *)rdr_rules, ipf_rdrrules_sz * sizeof(ipnat_t *)); - else - return -4; - KMALLOCS(ipf_hm_maptable, hostmap_t **, \ - sizeof(hostmap_t *) * ipf_hostmap_sz); - if (ipf_hm_maptable != NULL) - bzero((char *)ipf_hm_maptable, - sizeof(hostmap_t *) * ipf_hostmap_sz); - else - return -5; - ipf_hm_maplist = NULL; +/* ------------------------------------------------------------------------ */ +/* Function: ipf_nat_soft_create */ +/* Returns: void * - NULL = failure, else pointer to NAT context */ +/* Parameters: softc(I) - pointer to soft context main structure */ +/* */ +/* Allocate the initial soft context structure for NAT and populate it with */ +/* some default values. Creating the tables is left until we call _init so */ +/* that sizes can be changed before we get under way. */ +/* ------------------------------------------------------------------------ */ +void * +ipf_nat_soft_create(softc) + ipf_main_softc_t *softc; +{ + ipf_nat_softc_t *softn; - KMALLOCS(nat_stats.ns_bucketlen[0], u_long *, - ipf_nattable_sz * sizeof(u_long)); - if (nat_stats.ns_bucketlen[0] == NULL) - return -6; - bzero((char *)nat_stats.ns_bucketlen[0], - ipf_nattable_sz * sizeof(u_long)); + KMALLOC(softn, ipf_nat_softc_t *); + if (softn == NULL) + return NULL; - KMALLOCS(nat_stats.ns_bucketlen[1], u_long *, - ipf_nattable_sz * sizeof(u_long)); - if (nat_stats.ns_bucketlen[1] == NULL) - return -7; + bzero((char *)softn, sizeof(*softn)); - bzero((char *)nat_stats.ns_bucketlen[1], - ipf_nattable_sz * sizeof(u_long)); - - if (fr_nat_maxbucket == 0) { - for (i = ipf_nattable_sz; i > 0; i >>= 1) - fr_nat_maxbucket++; - fr_nat_maxbucket *= 2; + softn->ipf_nat_tune = ipf_tune_array_copy(softn, + sizeof(ipf_nat_tuneables), + ipf_nat_tuneables); + if (softn->ipf_nat_tune == NULL) { + ipf_nat_soft_destroy(softc, softn); + return NULL; + } + if (ipf_tune_array_link(softc, softn->ipf_nat_tune) == -1) { + ipf_nat_soft_destroy(softc, softn); + return NULL; } - fr_sttab_init(nat_tqb); + softn->ipf_nat_list_tail = &softn->ipf_nat_list; + + softn->ipf_nat_table_max = NAT_TABLE_MAX; + softn->ipf_nat_table_sz = NAT_TABLE_SZ; + softn->ipf_nat_maprules_sz = NAT_SIZE; + softn->ipf_nat_rdrrules_sz = RDR_SIZE; + softn->ipf_nat_hostmap_sz = HOSTMAP_SIZE; + softn->ipf_nat_doflush = 0; +#ifdef IPFILTER_LOG + softn->ipf_nat_logging = 1; +#else + softn->ipf_nat_logging = 0; +#endif + + softn->ipf_nat_defage = DEF_NAT_AGE; + softn->ipf_nat_defipage = IPF_TTLVAL(60); + softn->ipf_nat_deficmpage = IPF_TTLVAL(3); + softn->ipf_nat_table_wm_high = 99; + softn->ipf_nat_table_wm_low = 90; + + return softn; +} + +/* ------------------------------------------------------------------------ */ +/* Function: ipf_nat_soft_destroy */ +/* Returns: Nil */ +/* Parameters: softc(I) - pointer to soft context main structure */ +/* */ +/* ------------------------------------------------------------------------ */ +void +ipf_nat_soft_destroy(softc, arg) + ipf_main_softc_t *softc; + void *arg; +{ + ipf_nat_softc_t *softn = arg; + + if (softn->ipf_nat_tune != NULL) { + ipf_tune_array_unlink(softc, softn->ipf_nat_tune); + KFREES(softn->ipf_nat_tune, sizeof(ipf_nat_tuneables)); + softn->ipf_nat_tune = NULL; + } + + KFREE(softn); +} + + +/* ------------------------------------------------------------------------ */ +/* Function: ipf_nat_init */ +/* Returns: int - 0 == success, -1 == failure */ +/* Parameters: softc(I) - pointer to soft context main structure */ +/* */ +/* Initialise all of the NAT locks, tables and other structures. */ +/* ------------------------------------------------------------------------ */ +int +ipf_nat_soft_init(softc, arg) + ipf_main_softc_t *softc; + void *arg; +{ + ipf_nat_softc_t *softn = arg; + ipftq_t *tq; + int i; + + KMALLOCS(softn->ipf_nat_table[0], nat_t **, \ + sizeof(nat_t *) * softn->ipf_nat_table_sz); + + if (softn->ipf_nat_table[0] != NULL) { + bzero((char *)softn->ipf_nat_table[0], + softn->ipf_nat_table_sz * sizeof(nat_t *)); + } else { + return -1; + } + + KMALLOCS(softn->ipf_nat_table[1], nat_t **, \ + sizeof(nat_t *) * softn->ipf_nat_table_sz); + + if (softn->ipf_nat_table[1] != NULL) { + bzero((char *)softn->ipf_nat_table[1], + softn->ipf_nat_table_sz * sizeof(nat_t *)); + } else { + return -2; + } + + KMALLOCS(softn->ipf_nat_map_rules, ipnat_t **, \ + sizeof(ipnat_t *) * softn->ipf_nat_maprules_sz); + + if (softn->ipf_nat_map_rules != NULL) { + bzero((char *)softn->ipf_nat_map_rules, + softn->ipf_nat_maprules_sz * sizeof(ipnat_t *)); + } else { + return -3; + } + + KMALLOCS(softn->ipf_nat_rdr_rules, ipnat_t **, \ + sizeof(ipnat_t *) * softn->ipf_nat_rdrrules_sz); + + if (softn->ipf_nat_rdr_rules != NULL) { + bzero((char *)softn->ipf_nat_rdr_rules, + softn->ipf_nat_rdrrules_sz * sizeof(ipnat_t *)); + } else { + return -4; + } + + KMALLOCS(softn->ipf_hm_maptable, hostmap_t **, \ + sizeof(hostmap_t *) * softn->ipf_nat_hostmap_sz); + + if (softn->ipf_hm_maptable != NULL) { + bzero((char *)softn->ipf_hm_maptable, + sizeof(hostmap_t *) * softn->ipf_nat_hostmap_sz); + } else { + return -5; + } + softn->ipf_hm_maplist = NULL; + + KMALLOCS(softn->ipf_nat_stats.ns_side[0].ns_bucketlen, u_int *, + softn->ipf_nat_table_sz * sizeof(u_int)); + + if (softn->ipf_nat_stats.ns_side[0].ns_bucketlen == NULL) { + return -6; + } + bzero((char *)softn->ipf_nat_stats.ns_side[0].ns_bucketlen, + softn->ipf_nat_table_sz * sizeof(u_int)); + + KMALLOCS(softn->ipf_nat_stats.ns_side[1].ns_bucketlen, u_int *, + softn->ipf_nat_table_sz * sizeof(u_int)); + + if (softn->ipf_nat_stats.ns_side[1].ns_bucketlen == NULL) { + return -7; + } + + bzero((char *)softn->ipf_nat_stats.ns_side[1].ns_bucketlen, + softn->ipf_nat_table_sz * sizeof(u_int)); + + if (softn->ipf_nat_maxbucket == 0) { + for (i = softn->ipf_nat_table_sz; i > 0; i >>= 1) + softn->ipf_nat_maxbucket++; + softn->ipf_nat_maxbucket *= 2; + } + + ipf_sttab_init(softc, softn->ipf_nat_tcptq); /* * Increase this because we may have "keep state" following this too * and packet storms can occur if this is removed too quickly. */ - nat_tqb[IPF_TCPS_CLOSED].ifq_ttl = fr_tcplastack; - nat_tqb[IPF_TCP_NSTATES - 1].ifq_next = &nat_udptq; - nat_udptq.ifq_ttl = fr_defnatage; - nat_udptq.ifq_ref = 1; - nat_udptq.ifq_head = NULL; - nat_udptq.ifq_tail = &nat_udptq.ifq_head; - MUTEX_INIT(&nat_udptq.ifq_lock, "nat ipftq udp tab"); - nat_udptq.ifq_next = &nat_icmptq; - nat_icmptq.ifq_ttl = fr_defnaticmpage; - nat_icmptq.ifq_ref = 1; - nat_icmptq.ifq_head = NULL; - nat_icmptq.ifq_tail = &nat_icmptq.ifq_head; - MUTEX_INIT(&nat_icmptq.ifq_lock, "nat icmp ipftq tab"); - nat_icmptq.ifq_next = &nat_iptq; - nat_iptq.ifq_ttl = fr_defnatipage; - nat_iptq.ifq_ref = 1; - nat_iptq.ifq_head = NULL; - nat_iptq.ifq_tail = &nat_iptq.ifq_head; - MUTEX_INIT(&nat_iptq.ifq_lock, "nat ip ipftq tab"); - nat_iptq.ifq_next = NULL; + softn->ipf_nat_tcptq[IPF_TCPS_CLOSED].ifq_ttl = softc->ipf_tcplastack; + softn->ipf_nat_tcptq[IPF_TCP_NSTATES - 1].ifq_next = + &softn->ipf_nat_udptq; - for (i = 0; i < IPF_TCP_NSTATES; i++) { - if (nat_tqb[i].ifq_ttl < fr_defnaticmpage) - nat_tqb[i].ifq_ttl = fr_defnaticmpage; + IPFTQ_INIT(&softn->ipf_nat_udptq, softn->ipf_nat_defage, + "nat ipftq udp tab"); + softn->ipf_nat_udptq.ifq_next = &softn->ipf_nat_udpacktq; + + IPFTQ_INIT(&softn->ipf_nat_udpacktq, softn->ipf_nat_defage, + "nat ipftq udpack tab"); + softn->ipf_nat_udpacktq.ifq_next = &softn->ipf_nat_icmptq; + + IPFTQ_INIT(&softn->ipf_nat_icmptq, softn->ipf_nat_deficmpage, + "nat icmp ipftq tab"); + softn->ipf_nat_icmptq.ifq_next = &softn->ipf_nat_icmpacktq; + + IPFTQ_INIT(&softn->ipf_nat_icmpacktq, softn->ipf_nat_defage, + "nat icmpack ipftq tab"); + softn->ipf_nat_icmpacktq.ifq_next = &softn->ipf_nat_iptq; + + IPFTQ_INIT(&softn->ipf_nat_iptq, softn->ipf_nat_defipage, + "nat ip ipftq tab"); + softn->ipf_nat_iptq.ifq_next = &softn->ipf_nat_pending; + + IPFTQ_INIT(&softn->ipf_nat_pending, 1, "nat pending ipftq tab"); + softn->ipf_nat_pending.ifq_next = NULL; + + for (i = 0, tq = softn->ipf_nat_tcptq; i < IPF_TCP_NSTATES; i++, tq++) { + if (tq->ifq_ttl < softn->ipf_nat_deficmpage) + tq->ifq_ttl = softn->ipf_nat_deficmpage; #ifdef LARGE_NAT - else if (nat_tqb[i].ifq_ttl > fr_defnatage) - nat_tqb[i].ifq_ttl = fr_defnatage; + else if (tq->ifq_ttl > softn->ipf_nat_defage) + tq->ifq_ttl = softn->ipf_nat_defage; #endif } @@ -319,21 +515,124 @@ int fr_natinit() * this too and packet storms can occur if this is removed * too quickly. */ - nat_tqb[IPF_TCPS_CLOSED].ifq_ttl = nat_tqb[IPF_TCPS_LAST_ACK].ifq_ttl; + softn->ipf_nat_tcptq[IPF_TCPS_CLOSED].ifq_ttl = softc->ipf_tcplastack; - RWLOCK_INIT(&ipf_nat, "ipf IP NAT rwlock"); - RWLOCK_INIT(&ipf_natfrag, "ipf IP NAT-Frag rwlock"); - MUTEX_INIT(&ipf_nat_new, "ipf nat new mutex"); - MUTEX_INIT(&ipf_natio, "ipf nat io mutex"); + MUTEX_INIT(&softn->ipf_nat_new, "ipf nat new mutex"); + MUTEX_INIT(&softn->ipf_nat_io, "ipf nat io mutex"); - fr_nat_init = 1; + softn->ipf_nat_inited = 1; return 0; } /* ------------------------------------------------------------------------ */ -/* Function: nat_addrdr */ +/* Function: ipf_nat_soft_fini */ +/* Returns: Nil */ +/* Parameters: softc(I) - pointer to soft context main structure */ +/* */ +/* Free all memory used by NAT structures allocated at runtime. */ +/* ------------------------------------------------------------------------ */ +int +ipf_nat_soft_fini(softc, arg) + ipf_main_softc_t *softc; + void *arg; +{ + ipf_nat_softc_t *softn = arg; + ipftq_t *ifq, *ifqnext; + + (void) ipf_nat_clearlist(softc, softn); + (void) ipf_nat_flushtable(softc, softn); + + /* + * Proxy timeout queues are not cleaned here because although they + * exist on the NAT list, ipf_proxy_unload is called after unload + * and the proxies actually are responsible for them being created. + * Should the proxy timeouts have their own list? There's no real + * justification as this is the only complication. + */ + for (ifq = softn->ipf_nat_utqe; ifq != NULL; ifq = ifqnext) { + ifqnext = ifq->ifq_next; + if (ipf_deletetimeoutqueue(ifq) == 0) + ipf_freetimeoutqueue(softc, ifq); + } + + if (softn->ipf_nat_table[0] != NULL) { + KFREES(softn->ipf_nat_table[0], + sizeof(nat_t *) * softn->ipf_nat_table_sz); + softn->ipf_nat_table[0] = NULL; + } + if (softn->ipf_nat_table[1] != NULL) { + KFREES(softn->ipf_nat_table[1], + sizeof(nat_t *) * softn->ipf_nat_table_sz); + softn->ipf_nat_table[1] = NULL; + } + if (softn->ipf_nat_map_rules != NULL) { + KFREES(softn->ipf_nat_map_rules, + sizeof(ipnat_t *) * softn->ipf_nat_maprules_sz); + softn->ipf_nat_map_rules = NULL; + } + if (softn->ipf_nat_rdr_rules != NULL) { + KFREES(softn->ipf_nat_rdr_rules, + sizeof(ipnat_t *) * softn->ipf_nat_rdrrules_sz); + softn->ipf_nat_rdr_rules = NULL; + } + if (softn->ipf_hm_maptable != NULL) { + KFREES(softn->ipf_hm_maptable, + sizeof(hostmap_t *) * softn->ipf_nat_hostmap_sz); + softn->ipf_hm_maptable = NULL; + } + if (softn->ipf_nat_stats.ns_side[0].ns_bucketlen != NULL) { + KFREES(softn->ipf_nat_stats.ns_side[0].ns_bucketlen, + sizeof(u_int) * softn->ipf_nat_table_sz); + softn->ipf_nat_stats.ns_side[0].ns_bucketlen = NULL; + } + if (softn->ipf_nat_stats.ns_side[1].ns_bucketlen != NULL) { + KFREES(softn->ipf_nat_stats.ns_side[1].ns_bucketlen, + sizeof(u_int) * softn->ipf_nat_table_sz); + softn->ipf_nat_stats.ns_side[1].ns_bucketlen = NULL; + } + + if (softn->ipf_nat_inited == 1) { + softn->ipf_nat_inited = 0; + ipf_sttab_destroy(softn->ipf_nat_tcptq); + + MUTEX_DESTROY(&softn->ipf_nat_new); + MUTEX_DESTROY(&softn->ipf_nat_io); + + MUTEX_DESTROY(&softn->ipf_nat_udptq.ifq_lock); + MUTEX_DESTROY(&softn->ipf_nat_udpacktq.ifq_lock); + MUTEX_DESTROY(&softn->ipf_nat_icmptq.ifq_lock); + MUTEX_DESTROY(&softn->ipf_nat_icmpacktq.ifq_lock); + MUTEX_DESTROY(&softn->ipf_nat_iptq.ifq_lock); + MUTEX_DESTROY(&softn->ipf_nat_pending.ifq_lock); + } + + return 0; +} + + +/* ------------------------------------------------------------------------ */ +/* Function: ipf_nat_setlock */ +/* Returns: Nil */ +/* Parameters: arg(I) - pointer to soft state information */ +/* tmp(I) - new lock value */ +/* */ +/* Set the "lock status" of NAT to the value in tmp. */ +/* ------------------------------------------------------------------------ */ +void +ipf_nat_setlock(arg, tmp) + void *arg; + int tmp; +{ + ipf_nat_softc_t *softn = arg; + + softn->ipf_nat_lock = tmp; +} + + +/* ------------------------------------------------------------------------ */ +/* Function: ipf_nat_addrdr */ /* Returns: Nil */ /* Parameters: n(I) - pointer to NAT rule to add */ /* */ @@ -341,31 +640,41 @@ int fr_natinit() /* loaded NAT rules. Updates the bitmask indicating which netmasks are in */ /* use by redirect rules. */ /* ------------------------------------------------------------------------ */ -static void nat_addrdr(n) -ipnat_t *n; +static void +ipf_nat_addrdr(softn, n) + ipf_nat_softc_t *softn; + ipnat_t *n; { ipnat_t **np; u_32_t j; u_int hv; + u_int rhv; int k; - k = count4bits(n->in_outmsk); - if ((k >= 0) && (k != 32)) - rdr_masks |= 1 << k; - j = (n->in_outip & n->in_outmsk); - hv = NAT_HASH_FN(j, 0, ipf_rdrrules_sz); - np = rdr_rules + hv; + if (n->in_odstatype == FRI_NORMAL) { + k = count4bits(n->in_odstmsk); + ipf_inet_mask_add(k, &softn->ipf_nat_rdr_mask); + j = (n->in_odstaddr & n->in_odstmsk); + rhv = NAT_HASH_FN(j, 0, 0xffffffff); + } else { + ipf_inet_mask_add(0, &softn->ipf_nat_rdr_mask); + j = 0; + rhv = 0; + } + hv = rhv % softn->ipf_nat_rdrrules_sz; + np = softn->ipf_nat_rdr_rules + hv; while (*np != NULL) np = &(*np)->in_rnext; n->in_rnext = NULL; n->in_prnext = np; - n->in_hv = hv; + n->in_hv[0] = hv; + n->in_use++; *np = n; } /* ------------------------------------------------------------------------ */ -/* Function: nat_addnat */ +/* Function: ipf_nat_addmap */ /* Returns: Nil */ /* Parameters: n(I) - pointer to NAT rule to add */ /* */ @@ -373,63 +682,91 @@ ipnat_t *n; /* NAT rules. Updates the bitmask indicating which netmasks are in use by */ /* redirect rules. */ /* ------------------------------------------------------------------------ */ -static void nat_addnat(n) -ipnat_t *n; +static void +ipf_nat_addmap(softn, n) + ipf_nat_softc_t *softn; + ipnat_t *n; { ipnat_t **np; u_32_t j; u_int hv; + u_int rhv; int k; - k = count4bits(n->in_inmsk); - if ((k >= 0) && (k != 32)) - nat_masks |= 1 << k; - j = (n->in_inip & n->in_inmsk); - hv = NAT_HASH_FN(j, 0, ipf_natrules_sz); - np = nat_rules + hv; + if (n->in_osrcatype == FRI_NORMAL) { + k = count4bits(n->in_osrcmsk); + ipf_inet_mask_add(k, &softn->ipf_nat_map_mask); + j = (n->in_osrcaddr & n->in_osrcmsk); + rhv = NAT_HASH_FN(j, 0, 0xffffffff); + } else { + ipf_inet_mask_add(0, &softn->ipf_nat_map_mask); + j = 0; + rhv = 0; + } + hv = rhv % softn->ipf_nat_maprules_sz; + np = softn->ipf_nat_map_rules + hv; while (*np != NULL) np = &(*np)->in_mnext; n->in_mnext = NULL; n->in_pmnext = np; - n->in_hv = hv; + n->in_hv[1] = rhv; + n->in_use++; *np = n; } /* ------------------------------------------------------------------------ */ -/* Function: nat_delrdr */ +/* Function: ipf_nat_delrdr */ /* Returns: Nil */ /* Parameters: n(I) - pointer to NAT rule to delete */ /* */ /* Removes a redirect rule from the hash table of redirect rules. */ /* ------------------------------------------------------------------------ */ -static void nat_delrdr(n) -ipnat_t *n; +void +ipf_nat_delrdr(softn, n) + ipf_nat_softc_t *softn; + ipnat_t *n; { + if (n->in_odstatype == FRI_NORMAL) { + int k = count4bits(n->in_odstmsk); + ipf_inet_mask_del(k, &softn->ipf_nat_rdr_mask); + } else { + ipf_inet_mask_del(0, &softn->ipf_nat_rdr_mask); + } if (n->in_rnext) n->in_rnext->in_prnext = n->in_prnext; *n->in_prnext = n->in_rnext; + n->in_use--; } /* ------------------------------------------------------------------------ */ -/* Function: nat_delnat */ +/* Function: ipf_nat_delmap */ /* Returns: Nil */ /* Parameters: n(I) - pointer to NAT rule to delete */ /* */ /* Removes a NAT map rule from the hash table of NAT map rules. */ /* ------------------------------------------------------------------------ */ -static void nat_delnat(n) -ipnat_t *n; +void +ipf_nat_delmap(softn, n) + ipf_nat_softc_t *softn; + ipnat_t *n; { + if (n->in_osrcatype == FRI_NORMAL) { + int k = count4bits(n->in_osrcmsk); + ipf_inet_mask_del(k, &softn->ipf_nat_map_mask); + } else { + ipf_inet_mask_del(0, &softn->ipf_nat_map_mask); + } if (n->in_mnext != NULL) n->in_mnext->in_pmnext = n->in_pmnext; *n->in_pmnext = n->in_mnext; + n->in_use--; } /* ------------------------------------------------------------------------ */ -/* Function: nat_hostmap */ +/* Function: ipf_nat_hostmap */ /* Returns: struct hostmap* - NULL if no hostmap could be created, */ /* else a pointer to the hostmapping to use */ /* Parameters: np(I) - pointer to NAT rule */ @@ -442,57 +779,70 @@ ipnat_t *n; /* that is not doing port based translation. If is not yet allocated, then */ /* create a new entry if a non-NULL NAT rule pointer has been supplied. */ /* ------------------------------------------------------------------------ */ -static struct hostmap *nat_hostmap(np, src, dst, map, port) -ipnat_t *np; -struct in_addr src; -struct in_addr dst; -struct in_addr map; -u_32_t port; +static struct hostmap * +ipf_nat_hostmap(softn, np, src, dst, map, port) + ipf_nat_softc_t *softn; + ipnat_t *np; + struct in_addr src; + struct in_addr dst; + struct in_addr map; + u_32_t port; { hostmap_t *hm; - u_int hv; + u_int hv, rhv; hv = (src.s_addr ^ dst.s_addr); hv += src.s_addr; hv += dst.s_addr; - hv %= HOSTMAP_SIZE; - for (hm = ipf_hm_maptable[hv]; hm; hm = hm->hm_next) - if ((hm->hm_srcip.s_addr == src.s_addr) && - (hm->hm_dstip.s_addr == dst.s_addr) && + rhv = hv; + hv %= softn->ipf_nat_hostmap_sz; + for (hm = softn->ipf_hm_maptable[hv]; hm; hm = hm->hm_hnext) + if ((hm->hm_osrcip.s_addr == src.s_addr) && + (hm->hm_odstip.s_addr == dst.s_addr) && ((np == NULL) || (np == hm->hm_ipnat)) && ((port == 0) || (port == hm->hm_port))) { + softn->ipf_nat_stats.ns_hm_addref++; hm->hm_ref++; return hm; } - if (np == NULL) + if (np == NULL) { + softn->ipf_nat_stats.ns_hm_nullnp++; return NULL; + } KMALLOC(hm, hostmap_t *); if (hm) { - hm->hm_next = ipf_hm_maplist; - hm->hm_pnext = &ipf_hm_maplist; - if (ipf_hm_maplist != NULL) - ipf_hm_maplist->hm_pnext = &hm->hm_next; - ipf_hm_maplist = hm; - hm->hm_hnext = ipf_hm_maptable[hv]; - hm->hm_phnext = ipf_hm_maptable + hv; - if (ipf_hm_maptable[hv] != NULL) - ipf_hm_maptable[hv]->hm_phnext = &hm->hm_hnext; - ipf_hm_maptable[hv] = hm; + hm->hm_next = softn->ipf_hm_maplist; + hm->hm_pnext = &softn->ipf_hm_maplist; + if (softn->ipf_hm_maplist != NULL) + softn->ipf_hm_maplist->hm_pnext = &hm->hm_next; + softn->ipf_hm_maplist = hm; + hm->hm_hnext = softn->ipf_hm_maptable[hv]; + hm->hm_phnext = softn->ipf_hm_maptable + hv; + if (softn->ipf_hm_maptable[hv] != NULL) + softn->ipf_hm_maptable[hv]->hm_phnext = &hm->hm_hnext; + softn->ipf_hm_maptable[hv] = hm; hm->hm_ipnat = np; - hm->hm_srcip = src; - hm->hm_dstip = dst; - hm->hm_mapip = map; + np->in_use++; + hm->hm_osrcip = src; + hm->hm_odstip = dst; + hm->hm_nsrcip = map; + hm->hm_ndstip.s_addr = 0; hm->hm_ref = 1; hm->hm_port = port; + hm->hm_hv = rhv; + hm->hm_v = 4; + softn->ipf_nat_stats.ns_hm_new++; + } else { + softn->ipf_nat_stats.ns_hm_newfail++; } return hm; } /* ------------------------------------------------------------------------ */ -/* Function: fr_hostmapdel */ +/* Function: ipf_nat_hostmapdel */ /* Returns: Nil */ /* Parameters: hmp(I) - pointer to hostmap structure pointer */ /* Write Locks: ipf_nat */ @@ -500,8 +850,10 @@ u_32_t port; /* Decrement the references to this hostmap structure by one. If this */ /* reaches zero then remove it and free it. */ /* ------------------------------------------------------------------------ */ -void fr_hostmapdel(hmp) -struct hostmap **hmp; +void +ipf_nat_hostmapdel(softc, hmp) + ipf_main_softc_t *softc; + struct hostmap **hmp; { struct hostmap *hm; @@ -510,6 +862,7 @@ struct hostmap **hmp; hm->hm_ref--; if (hm->hm_ref == 0) { + ipf_nat_rule_deref(softc, &hm->hm_ipnat); if (hm->hm_hnext) hm->hm_hnext->hm_phnext = hm->hm_phnext; *hm->hm_phnext = hm->hm_hnext; @@ -522,7 +875,7 @@ struct hostmap **hmp; /* ------------------------------------------------------------------------ */ -/* Function: fix_outcksum */ +/* Function: ipf_fix_outcksum */ /* Returns: Nil */ /* Parameters: fin(I) - pointer to packet information */ /* sp(I) - location of 16bit checksum to update */ @@ -530,10 +883,11 @@ struct hostmap **hmp; /* */ /* Adjusts the 16bit checksum by "n" for packets going out. */ /* ------------------------------------------------------------------------ */ -void fix_outcksum(fin, sp, n) -fr_info_t *fin; -u_short *sp; -u_32_t n; +void +ipf_fix_outcksum(cksum, sp, n, partial) + int cksum; + u_short *sp; + u_32_t n, partial; { u_short sumshort; u_32_t sum1; @@ -541,11 +895,14 @@ u_32_t n; if (n == 0) return; - if (n & NAT_HW_CKSUM) { - n &= 0xffff; - n += fin->fin_dlen; - n = (n & 0xffff) + (n >> 16); - *sp = n & 0xffff; + if (cksum == 4) { + *sp = 0; + return; + } + if (cksum == 2) { + sum1 = partial; + sum1 = (sum1 & 0xffff) + (sum1 >> 16); + *sp = htons(sum1); return; } sum1 = (~ntohs(*sp)) & 0xffff; @@ -559,7 +916,7 @@ u_32_t n; /* ------------------------------------------------------------------------ */ -/* Function: fix_incksum */ +/* Function: ipf_fix_incksum */ /* Returns: Nil */ /* Parameters: fin(I) - pointer to packet information */ /* sp(I) - location of 16bit checksum to update */ @@ -567,10 +924,11 @@ u_32_t n; /* */ /* Adjusts the 16bit checksum by "n" for packets going in. */ /* ------------------------------------------------------------------------ */ -void fix_incksum(fin, sp, n) -fr_info_t *fin; -u_short *sp; -u_32_t n; +void +ipf_fix_incksum(cksum, sp, n, partial) + int cksum; + u_short *sp; + u_32_t n, partial; { u_short sumshort; u_32_t sum1; @@ -578,13 +936,17 @@ u_32_t n; if (n == 0) return; - if (n & NAT_HW_CKSUM) { - n &= 0xffff; - n += fin->fin_dlen; - n = (n & 0xffff) + (n >> 16); - *sp = n & 0xffff; + if (cksum == 4) { + *sp = 0; return; } + if (cksum == 2) { + sum1 = partial; + sum1 = (sum1 & 0xffff) + (sum1 >> 16); + *sp = htons(sum1); + return; + } + sum1 = (~ntohs(*sp)) & 0xffff; sum1 += ~(n) & 0xffff; sum1 = (sum1 >> 16) + (sum1 & 0xffff); @@ -596,7 +958,7 @@ u_32_t n; /* ------------------------------------------------------------------------ */ -/* Function: fix_datacksum */ +/* Function: ipf_fix_datacksum */ /* Returns: Nil */ /* Parameters: sp(I) - location of 16bit checksum to update */ /* n((I) - amount to adjust checksum by */ @@ -613,9 +975,10 @@ u_32_t n; /* processing like hardware cksum or ntohs processing have been done by the */ /* kernel on the data section. */ /* ------------------------------------------------------------------------ */ -void fix_datacksum(sp, n) -u_short *sp; -u_32_t n; +void +ipf_fix_datacksum(sp, n) + u_short *sp; + u_32_t n; { u_short sumshort; u_32_t sum1; @@ -634,42 +997,48 @@ u_32_t n; /* ------------------------------------------------------------------------ */ -/* Function: fr_nat_ioctl */ +/* Function: ipf_nat_ioctl */ /* Returns: int - 0 == success, != 0 == failure */ -/* Parameters: data(I) - pointer to ioctl data */ -/* cmd(I) - ioctl command integer */ -/* mode(I) - file mode bits used with open */ +/* Parameters: softc(I) - pointer to soft context main structure */ +/* data(I) - pointer to ioctl data */ +/* cmd(I) - ioctl command integer */ +/* mode(I) - file mode bits used with open */ +/* uid(I) - uid of calling process */ +/* ctx(I) - pointer used as key for finding context */ /* */ /* Processes an ioctl call made to operate on the IP Filter NAT device. */ /* ------------------------------------------------------------------------ */ -int fr_nat_ioctl(data, cmd, mode, uid, ctx) -ioctlcmd_t cmd; -caddr_t data; -int mode, uid; -void *ctx; +int +ipf_nat_ioctl(softc, data, cmd, mode, uid, ctx) + ipf_main_softc_t *softc; + ioctlcmd_t cmd; + caddr_t data; + int mode, uid; + void *ctx; { - ipnat_t *nat, *nt, *n = NULL, **np = NULL; + ipf_nat_softc_t *softn = softc->ipf_nat_soft; int error = 0, ret, arg, getlock; + ipnat_t *nat, *nt, *n; ipnat_t natd; SPL_INT(s); -#if (BSD >= 199306) && defined(_KERNEL) -# if defined(__NetBSD_Version__) && (__NetBSD_Version__ >= 399002000) +#if BSD_GE_YEAR(199306) && defined(_KERNEL) +# if NETBSD_GE_REV(399002000) if ((mode & FWRITE) && kauth_authorize_network(curlwp->l_cred, KAUTH_NETWORK_FIREWALL, KAUTH_REQ_NETWORK_FIREWALL_FW, - NULL, NULL, NULL)) { - return EPERM; - } + NULL, NULL, NULL)) # else # if defined(__FreeBSD_version) && (__FreeBSD_version >= 500034) - if (securelevel_ge(curthread->td_ucred, 3) && (mode & FWRITE)) { + if (securelevel_ge(curthread->td_ucred, 3) && (mode & FWRITE)) # else - if ((securelevel >= 3) && (mode & FWRITE)) { + if ((securelevel >= 3) && (mode & FWRITE)) # endif +# endif + { + IPFERROR(60001); return EPERM; } -# endif #endif #if defined(__osf__) && defined(_KERNEL) @@ -678,48 +1047,69 @@ void *ctx; getlock = (mode & NAT_LOCKHELD) ? 0 : 1; #endif - nat = NULL; /* XXX gcc -Wuninitialized */ - if (cmd == (ioctlcmd_t)SIOCADNAT) { - KMALLOC(nt, ipnat_t *); - } else { - nt = NULL; - } + n = NULL; + nt = NULL; + nat = NULL; - if ((cmd == (ioctlcmd_t)SIOCADNAT) || (cmd == (ioctlcmd_t)SIOCRMNAT)) { + if ((cmd == (ioctlcmd_t)SIOCADNAT) || (cmd == (ioctlcmd_t)SIOCRMNAT) || + (cmd == (ioctlcmd_t)SIOCPURGENAT)) { if (mode & NAT_SYSSPACE) { bcopy(data, (char *)&natd, sizeof(natd)); + nat = &natd; error = 0; } else { - error = fr_inobj(data, &natd, IPFOBJ_IPNAT); + bzero(&natd, sizeof(natd)); + error = ipf_inobj(softc, data, NULL, &natd, + IPFOBJ_IPNAT); + if (error != 0) + goto done; + + if (natd.in_size < sizeof(ipnat_t)) { + error = EINVAL; + goto done; + } + KMALLOCS(nt, ipnat_t *, natd.in_size); + if (nt == NULL) { + IPFERROR(60070); + error = ENOMEM; + goto done; + } + bzero(nt, natd.in_size); + error = ipf_inobjsz(softc, data, nt, IPFOBJ_IPNAT, + natd.in_size); + if (error) + goto done; + nat = nt; } - } - if (error != 0) - goto done; - - /* - * For add/delete, look to see if the NAT entry is already present - */ - if ((cmd == (ioctlcmd_t)SIOCADNAT) || (cmd == (ioctlcmd_t)SIOCRMNAT)) { - nat = &natd; - if (nat->in_v == 0) /* For backward compat. */ - nat->in_v = 4; + /* + * For add/delete, look to see if the NAT entry is + * already present + */ nat->in_flags &= IPN_USERFLAGS; if ((nat->in_redir & NAT_MAPBLK) == 0) { - if ((nat->in_flags & IPN_SPLIT) == 0) - nat->in_inip &= nat->in_inmsk; - if ((nat->in_flags & IPN_IPRANGE) == 0) - nat->in_outip &= nat->in_outmsk; - } - MUTEX_ENTER(&ipf_natio); - for (np = &nat_list; ((n = *np) != NULL); np = &n->in_next) - if (bcmp((char *)&nat->in_flags, (char *)&n->in_flags, - IPN_CMPSIZ) == 0) { - if (nat->in_redir == NAT_REDIRECT && - nat->in_pnext != n->in_pnext) - continue; - break; + if (nat->in_osrcatype == FRI_NORMAL || + nat->in_osrcatype == FRI_NONE) + nat->in_osrcaddr &= nat->in_osrcmsk; + if (nat->in_odstatype == FRI_NORMAL || + nat->in_odstatype == FRI_NONE) + nat->in_odstaddr &= nat->in_odstmsk; + if ((nat->in_flags & (IPN_SPLIT|IPN_SIPRANGE)) == 0) { + if (nat->in_nsrcatype == FRI_NORMAL) + nat->in_nsrcaddr &= nat->in_nsrcmsk; + if (nat->in_ndstatype == FRI_NORMAL) + nat->in_ndstaddr &= nat->in_ndstmsk; } + } + + error = ipf_nat_rule_init(softc, softn, nat); + if (error != 0) + goto done; + + MUTEX_ENTER(&softn->ipf_nat_io); + for (n = softn->ipf_nat_list; n != NULL; n = n->in_next) + if (ipf_nat_cmp_rules(nat, n) == 0) + break; } switch (cmd) @@ -729,115 +1119,169 @@ void *ctx; { int tmp; - if (!(mode & FWRITE)) + if (!(mode & FWRITE)) { + IPFERROR(60002); error = EPERM; - else { - tmp = ipflog_clear(IPL_LOGNAT); - error = BCOPYOUT((char *)&tmp, (char *)data, - sizeof(tmp)); - if (error != 0) + } else { + tmp = ipf_log_clear(softc, IPL_LOGNAT); + error = BCOPYOUT(&tmp, data, sizeof(tmp)); + if (error != 0) { + IPFERROR(60057); error = EFAULT; + } } break; } case SIOCSETLG : - if (!(mode & FWRITE)) + if (!(mode & FWRITE)) { + IPFERROR(60003); error = EPERM; - else { - error = BCOPYIN((char *)data, (char *)&nat_logging, - sizeof(nat_logging)); + } else { + error = BCOPYIN(data, &softn->ipf_nat_logging, + sizeof(softn->ipf_nat_logging)); if (error != 0) error = EFAULT; } break; case SIOCGETLG : - error = BCOPYOUT((char *)&nat_logging, (char *)data, - sizeof(nat_logging)); - if (error != 0) + error = BCOPYOUT(&softn->ipf_nat_logging, data, + sizeof(softn->ipf_nat_logging)); + if (error != 0) { + IPFERROR(60004); error = EFAULT; + } break; case FIONREAD : - arg = iplused[IPL_LOGNAT]; + arg = ipf_log_bytesused(softc, IPL_LOGNAT); error = BCOPYOUT(&arg, data, sizeof(arg)); - if (error != 0) + if (error != 0) { + IPFERROR(60005); error = EFAULT; + } break; #endif case SIOCADNAT : if (!(mode & FWRITE)) { + IPFERROR(60006); error = EPERM; } else if (n != NULL) { + natd.in_flineno = n->in_flineno; + (void) ipf_outobj(softc, data, &natd, IPFOBJ_IPNAT); + IPFERROR(60007); error = EEXIST; } else if (nt == NULL) { + IPFERROR(60008); error = ENOMEM; } if (error != 0) { - MUTEX_EXIT(&ipf_natio); + MUTEX_EXIT(&softn->ipf_nat_io); break; } - bcopy((char *)nat, (char *)nt, sizeof(*n)); - error = nat_siocaddnat(nt, np, getlock); - MUTEX_EXIT(&ipf_natio); - if (error == 0) + if (nat != nt) + bcopy((char *)nat, (char *)nt, sizeof(*n)); + error = ipf_nat_siocaddnat(softc, softn, nt, getlock); + MUTEX_EXIT(&softn->ipf_nat_io); + if (error == 0) { + nat = NULL; nt = NULL; + } break; case SIOCRMNAT : + case SIOCPURGENAT : if (!(mode & FWRITE)) { + IPFERROR(60009); error = EPERM; n = NULL; } else if (n == NULL) { + IPFERROR(60010); error = ESRCH; } if (error != 0) { - MUTEX_EXIT(&ipf_natio); + MUTEX_EXIT(&softn->ipf_nat_io); break; } - nat_siocdelnat(n, np, getlock); + if (cmd == (ioctlcmd_t)SIOCPURGENAT) { + error = ipf_outobjsz(softc, data, n, IPFOBJ_IPNAT, + n->in_size); + if (error) { + MUTEX_EXIT(&softn->ipf_nat_io); + goto done; + } + n->in_flags |= IPN_PURGE; + } + ipf_nat_siocdelnat(softc, softn, n, getlock); - MUTEX_EXIT(&ipf_natio); + MUTEX_EXIT(&softn->ipf_nat_io); n = NULL; break; case SIOCGNATS : - nat_stats.ns_table[0] = nat_table[0]; - nat_stats.ns_table[1] = nat_table[1]; - nat_stats.ns_list = nat_list; - nat_stats.ns_maptable = ipf_hm_maptable; - nat_stats.ns_maplist = ipf_hm_maplist; - nat_stats.ns_nattab_sz = ipf_nattable_sz; - nat_stats.ns_nattab_max = ipf_nattable_max; - nat_stats.ns_rultab_sz = ipf_natrules_sz; - nat_stats.ns_rdrtab_sz = ipf_rdrrules_sz; - nat_stats.ns_hostmap_sz = ipf_hostmap_sz; - nat_stats.ns_instances = nat_instances; - nat_stats.ns_apslist = ap_sess_list; - nat_stats.ns_ticks = fr_ticks; - error = fr_outobj(data, &nat_stats, IPFOBJ_NATSTAT); + { + natstat_t *nsp = &softn->ipf_nat_stats; + + nsp->ns_side[0].ns_table = softn->ipf_nat_table[0]; + nsp->ns_side[1].ns_table = softn->ipf_nat_table[1]; + nsp->ns_list = softn->ipf_nat_list; + nsp->ns_maptable = softn->ipf_hm_maptable; + nsp->ns_maplist = softn->ipf_hm_maplist; + nsp->ns_nattab_sz = softn->ipf_nat_table_sz; + nsp->ns_nattab_max = softn->ipf_nat_table_max; + nsp->ns_rultab_sz = softn->ipf_nat_maprules_sz; + nsp->ns_rdrtab_sz = softn->ipf_nat_rdrrules_sz; + nsp->ns_hostmap_sz = softn->ipf_nat_hostmap_sz; + nsp->ns_instances = softn->ipf_nat_instances; + nsp->ns_ticks = softc->ipf_ticks; +#ifdef IPFILTER_LOGGING + nsp->ns_log_ok = ipf_log_logok(softc, IPF_LOGNAT); + nsp->ns_log_fail = ipf_log_failures(softc, IPF_LOGNAT); +#else + nsp->ns_log_ok = 0; + nsp->ns_log_fail = 0; +#endif + error = ipf_outobj(softc, data, nsp, IPFOBJ_NATSTAT); break; + } case SIOCGNATL : { natlookup_t nl; - error = fr_inobj(data, &nl, IPFOBJ_NATLOOKUP); + error = ipf_inobj(softc, data, NULL, &nl, IPFOBJ_NATLOOKUP); if (error == 0) { void *ptr; if (getlock) { - READ_ENTER(&ipf_nat); + READ_ENTER(&softc->ipf_nat); } - ptr = nat_lookupredir(&nl); + + switch (nl.nl_v) + { + case 4 : + ptr = ipf_nat_lookupredir(&nl); + break; +#ifdef USE_INET6 + case 6 : + ptr = ipf_nat6_lookupredir(&nl); + break; +#endif + default: + ptr = NULL; + break; + } + if (getlock) { - RWLOCK_EXIT(&ipf_nat); + RWLOCK_EXIT(&softc->ipf_nat); } if (ptr != NULL) { - error = fr_outobj(data, &nl, IPFOBJ_NATLOOKUP); + error = ipf_outobj(softc, data, &nl, + IPFOBJ_NATLOOKUP); } else { + IPFERROR(60011); error = ESRCH; } } @@ -846,246 +1290,257 @@ void *ctx; case SIOCIPFFL : /* old SIOCFLNAT & SIOCCNATL */ if (!(mode & FWRITE)) { + IPFERROR(60012); error = EPERM; break; } if (getlock) { - WRITE_ENTER(&ipf_nat); + WRITE_ENTER(&softc->ipf_nat); } error = BCOPYIN(data, &arg, sizeof(arg)); - if (error != 0) + if (error != 0) { + IPFERROR(60013); error = EFAULT; - else { + } else { if (arg == 0) - ret = nat_flushtable(); + ret = ipf_nat_flushtable(softc, softn); else if (arg == 1) - ret = nat_clearlist(); + ret = ipf_nat_clearlist(softc, softn); else - ret = nat_extraflush(arg); + ret = ipf_nat_extraflush(softc, softn, arg); + ipf_proxy_flush(softc->ipf_proxy_soft, arg); } if (getlock) { - RWLOCK_EXIT(&ipf_nat); + RWLOCK_EXIT(&softc->ipf_nat); } if (error == 0) { error = BCOPYOUT(&ret, data, sizeof(ret)); } break; + case SIOCMATCHFLUSH : + if (!(mode & FWRITE)) { + IPFERROR(60014); + error = EPERM; + break; + } + if (getlock) { + WRITE_ENTER(&softc->ipf_nat); + } + + error = ipf_nat_matchflush(softc, softn, data); + + if (getlock) { + RWLOCK_EXIT(&softc->ipf_nat); + } + break; + case SIOCPROXY : - error = appr_ioctl(data, cmd, mode, ctx); + error = ipf_proxy_ioctl(softc, data, cmd, mode, ctx); break; case SIOCSTLCK : if (!(mode & FWRITE)) { + IPFERROR(60015); error = EPERM; } else { - error = fr_lock(data, &fr_nat_lock); + error = ipf_lock(data, &softn->ipf_nat_lock); } break; case SIOCSTPUT : if ((mode & FWRITE) != 0) { - error = fr_natputent(data, getlock); + error = ipf_nat_putent(softc, data, getlock); } else { + IPFERROR(60016); error = EACCES; } break; case SIOCSTGSZ : - if (fr_nat_lock) { - error = fr_natgetsz(data, getlock); - } else + if (softn->ipf_nat_lock) { + error = ipf_nat_getsz(softc, data, getlock); + } else { + IPFERROR(60017); error = EACCES; + } break; case SIOCSTGET : - if (fr_nat_lock) { - error = fr_natgetent(data, getlock); - } else + if (softn->ipf_nat_lock) { + error = ipf_nat_getent(softc, data, getlock); + } else { + IPFERROR(60018); error = EACCES; + } break; case SIOCGENITER : { ipfgeniter_t iter; ipftoken_t *token; + ipfobj_t obj; + + error = ipf_inobj(softc, data, &obj, &iter, IPFOBJ_GENITER); + if (error != 0) + break; SPL_SCHED(s); - error = fr_inobj(data, &iter, IPFOBJ_GENITER); - if (error == 0) { - token = ipf_findtoken(iter.igi_type, uid, ctx); - if (token != NULL) { - error = nat_iterator(token, &iter); - } - RWLOCK_EXIT(&ipf_tokens); + token = ipf_token_find(softc, iter.igi_type, uid, ctx); + if (token != NULL) { + error = ipf_nat_iterator(softc, token, &iter, &obj); + WRITE_ENTER(&softc->ipf_tokens); + ipf_token_deref(softc, token); + RWLOCK_EXIT(&softc->ipf_tokens); } SPL_X(s); break; } case SIOCIPFDELTOK : - error = BCOPYIN((caddr_t)data, (caddr_t)&arg, sizeof(arg)); + error = BCOPYIN(data, &arg, sizeof(arg)); if (error == 0) { SPL_SCHED(s); - error = ipf_deltoken(arg, uid, ctx); + error = ipf_token_del(softc, arg, uid, ctx); SPL_X(s); } else { + IPFERROR(60019); error = EFAULT; } break; case SIOCGTQTAB : - error = fr_outobj(data, nat_tqb, IPFOBJ_STATETQTAB); + error = ipf_outobj(softc, data, softn->ipf_nat_tcptq, + IPFOBJ_STATETQTAB); break; case SIOCGTABL : - error = nat_gettable(data); + error = ipf_nat_gettable(softc, softn, data); break; default : + IPFERROR(60020); error = EINVAL; break; } done: + if (nat != NULL) + ipf_nat_rule_fini(softc, nat); if (nt != NULL) - KFREE(nt); + KFREES(nt, nt->in_size); return error; } /* ------------------------------------------------------------------------ */ -/* Function: nat_siocaddnat */ +/* Function: ipf_nat_siocaddnat */ /* Returns: int - 0 == success, != 0 == failure */ -/* Parameters: n(I) - pointer to new NAT rule */ +/* Parameters: softc(I) - pointer to soft context main structure */ +/* softn(I) - pointer to NAT context structure */ +/* n(I) - pointer to new NAT rule */ /* np(I) - pointer to where to insert new NAT rule */ -/* getlock(I) - flag indicating if lock on ipf_nat is held */ -/* Mutex Locks: ipf_natio */ +/* getlock(I) - flag indicating if lock on is held */ +/* Mutex Locks: ipf_nat_io */ /* */ /* Handle SIOCADNAT. Resolve and calculate details inside the NAT rule */ /* from information passed to the kernel, then add it to the appropriate */ /* NAT rule table(s). */ /* ------------------------------------------------------------------------ */ -static int nat_siocaddnat(n, np, getlock) -ipnat_t *n, **np; -int getlock; +static int +ipf_nat_siocaddnat(softc, softn, n, getlock) + ipf_main_softc_t *softc; + ipf_nat_softc_t *softn; + ipnat_t *n; + int getlock; { - int error = 0, i, j; + int error = 0; - if (nat_resolverule(n) != 0) + if (ipf_nat_resolverule(softc, n) != 0) { + IPFERROR(60022); return ENOENT; - - if ((n->in_age[0] == 0) && (n->in_age[1] != 0)) - return EINVAL; - - n->in_use = 0; - if (n->in_redir & NAT_MAPBLK) - n->in_space = USABLE_PORTS * ~ntohl(n->in_outmsk); - else if (n->in_flags & IPN_AUTOPORTMAP) - n->in_space = USABLE_PORTS * ~ntohl(n->in_inmsk); - else if (n->in_flags & IPN_IPRANGE) - n->in_space = ntohl(n->in_outmsk) - ntohl(n->in_outip); - else if (n->in_flags & IPN_SPLIT) - n->in_space = 2; - else if (n->in_outmsk != 0) - n->in_space = ~ntohl(n->in_outmsk); - else - n->in_space = 1; - - /* - * Calculate the number of valid IP addresses in the output - * mapping range. In all cases, the range is inclusive of - * the start and ending IP addresses. - * If to a CIDR address, lose 2: broadcast + network address - * (so subtract 1) - * If to a range, add one. - * If to a single IP address, set to 1. - */ - if (n->in_space) { - if ((n->in_flags & IPN_IPRANGE) != 0) - n->in_space += 1; - else - n->in_space -= 1; - } else - n->in_space = 1; - - if ((n->in_outmsk != 0xffffffff) && (n->in_outmsk != 0) && - ((n->in_flags & (IPN_IPRANGE|IPN_SPLIT)) == 0)) - n->in_nip = ntohl(n->in_outip) + 1; - else if ((n->in_flags & IPN_SPLIT) && - (n->in_redir & NAT_REDIRECT)) - n->in_nip = ntohl(n->in_inip); - else - n->in_nip = ntohl(n->in_outip); - if (n->in_redir & NAT_MAP) { - n->in_pnext = ntohs(n->in_pmin); - /* - * Multiply by the number of ports made available. - */ - if (ntohs(n->in_pmax) >= ntohs(n->in_pmin)) { - n->in_space *= (ntohs(n->in_pmax) - - ntohs(n->in_pmin) + 1); - /* - * Because two different sources can map to - * different destinations but use the same - * local IP#/port #. - * If the result is smaller than in_space, then - * we may have wrapped around 32bits. - */ - i = n->in_inmsk; - if ((i != 0) && (i != 0xffffffff)) { - j = n->in_space * (~ntohl(i) + 1); - if (j >= n->in_space) - n->in_space = j; - else - n->in_space = 0xffffffff; - } - } - /* - * If no protocol is specified, multiple by 256 to allow for - * at least one IP:IP mapping per protocol. - */ - if ((n->in_flags & IPN_TCPUDPICMP) == 0) { - j = n->in_space * 256; - if (j >= n->in_space) - n->in_space = j; - else - n->in_space = 0xffffffff; - } } - /* Otherwise, these fields are preset */ + if ((n->in_age[0] == 0) && (n->in_age[1] != 0)) { + IPFERROR(60023); + return EINVAL; + } + + if (n->in_redir == (NAT_DIVERTUDP|NAT_MAP)) { + /* + * Prerecord whether or not the destination of the divert + * is local or not to the interface the packet is going + * to be sent out. + */ + n->in_dlocal = ipf_deliverlocal(softc, n->in_v[1], + n->in_ifps[1], &n->in_ndstip6); + } if (getlock) { - WRITE_ENTER(&ipf_nat); + WRITE_ENTER(&softc->ipf_nat); } n->in_next = NULL; - *np = n; - - if (n->in_age[0] != 0) - n->in_tqehead[0] = fr_addtimeoutqueue(&nat_utqe, n->in_age[0]); - - if (n->in_age[1] != 0) - n->in_tqehead[1] = fr_addtimeoutqueue(&nat_utqe, n->in_age[1]); + n->in_pnext = softn->ipf_nat_list_tail; + *n->in_pnext = n; + softn->ipf_nat_list_tail = &n->in_next; + n->in_use++; if (n->in_redir & NAT_REDIRECT) { n->in_flags &= ~IPN_NOTDST; - nat_addrdr(n); + switch (n->in_v[0]) + { + case 4 : + ipf_nat_addrdr(softn, n); + break; +#ifdef USE_INET6 + case 6 : + ipf_nat6_addrdr(softn, n); + break; +#endif + default : + break; + } + ATOMIC_INC32(softn->ipf_nat_stats.ns_rules_rdr); } + if (n->in_redir & (NAT_MAP|NAT_MAPBLK)) { n->in_flags &= ~IPN_NOTSRC; - nat_addnat(n); + switch (n->in_v[0]) + { + case 4 : + ipf_nat_addmap(softn, n); + break; +#ifdef USE_INET6 + case 6 : + ipf_nat6_addmap(softn, n); + break; +#endif + default : + break; + } + ATOMIC_INC32(softn->ipf_nat_stats.ns_rules_map); } + + if (n->in_age[0] != 0) + n->in_tqehead[0] = ipf_addtimeoutqueue(softc, + &softn->ipf_nat_utqe, + n->in_age[0]); + + if (n->in_age[1] != 0) + n->in_tqehead[1] = ipf_addtimeoutqueue(softc, + &softn->ipf_nat_utqe, + n->in_age[1]); + MUTEX_INIT(&n->in_lock, "ipnat rule lock"); n = NULL; - nat_stats.ns_rules++; -#if SOLARIS && !defined(_INET_IP_STACK_H) + ATOMIC_INC32(softn->ipf_nat_stats.ns_rules); +#if SOLARIS && !defined(INSTANCES) pfil_delayed_copy = 0; #endif if (getlock) { - RWLOCK_EXIT(&ipf_nat); /* WRITE */ + RWLOCK_EXIT(&softc->ipf_nat); /* WRITE */ } return error; @@ -1093,30 +1548,113 @@ int getlock; /* ------------------------------------------------------------------------ */ -/* Function: nat_resolvrule */ +/* Function: ipf_nat_ruleaddrinit */ +/* Parameters: softc(I) - pointer to soft context main structure */ +/* softn(I) - pointer to NAT context structure */ +/* n(I) - pointer to NAT rule */ +/* */ +/* Initialise all of the NAT address structures in a NAT rule. */ +/* ------------------------------------------------------------------------ */ +static int +ipf_nat_ruleaddrinit(softc, softn, n) + ipf_main_softc_t *softc; + ipf_nat_softc_t *softn; + ipnat_t *n; +{ + int idx, error; + + if ((n->in_ndst.na_atype == FRI_LOOKUP) && + (n->in_ndst.na_type != IPLT_DSTLIST)) { + IPFERROR(60071); + return EINVAL; + } + if ((n->in_nsrc.na_atype == FRI_LOOKUP) && + (n->in_nsrc.na_type != IPLT_DSTLIST)) { + IPFERROR(60069); + return EINVAL; + } + + if (n->in_redir == NAT_BIMAP) { + n->in_ndstaddr = n->in_osrcaddr; + n->in_ndstmsk = n->in_osrcmsk; + n->in_odstaddr = n->in_nsrcaddr; + n->in_odstmsk = n->in_nsrcmsk; + + } + + if (n->in_redir & NAT_REDIRECT) + idx = 1; + else + idx = 0; + /* + * Initialise all of the address fields. + */ + error = ipf_nat_nextaddrinit(softc, n->in_names, &n->in_osrc, 1, + n->in_ifps[idx]); + if (error != 0) + return error; + + error = ipf_nat_nextaddrinit(softc, n->in_names, &n->in_odst, 1, + n->in_ifps[idx]); + if (error != 0) + return error; + + error = ipf_nat_nextaddrinit(softc, n->in_names, &n->in_nsrc, 1, + n->in_ifps[idx]); + if (error != 0) + return error; + + error = ipf_nat_nextaddrinit(softc, n->in_names, &n->in_ndst, 1, + n->in_ifps[idx]); + if (error != 0) + return error; + + if (n->in_redir & NAT_DIVERTUDP) + ipf_nat_builddivertmp(softn, n); + + return 0; +} + + +/* ------------------------------------------------------------------------ */ +/* Function: ipf_nat_resolvrule */ /* Returns: Nil */ -/* Parameters: n(I) - pointer to NAT rule */ +/* Parameters: softc(I) - pointer to soft context main structure */ +/* n(I) - pointer to NAT rule */ /* */ /* Handle SIOCADNAT. Resolve and calculate details inside the NAT rule */ /* from information passed to the kernel, then add it to the appropriate */ /* NAT rule table(s). */ /* ------------------------------------------------------------------------ */ -static int nat_resolverule(n) -ipnat_t *n; +static int +ipf_nat_resolverule(softc, n) + ipf_main_softc_t *softc; + ipnat_t *n; { - n->in_ifnames[0][LIFNAMSIZ - 1] = '\0'; - n->in_ifps[0] = fr_resolvenic(n->in_ifnames[0], 4); + char *base; - n->in_ifnames[1][LIFNAMSIZ - 1] = '\0'; - if (n->in_ifnames[1][0] == '\0') { - (void) strncpy(n->in_ifnames[1], n->in_ifnames[0], LIFNAMSIZ); + base = n->in_names; + + n->in_ifps[0] = ipf_resolvenic(softc, base + n->in_ifnames[0], + n->in_v[0]); + + if (n->in_ifnames[1] == -1) { + n->in_ifnames[1] = n->in_ifnames[0]; n->in_ifps[1] = n->in_ifps[0]; } else { - n->in_ifps[1] = fr_resolvenic(n->in_ifnames[1], 4); + n->in_ifps[1] = ipf_resolvenic(softc, base + n->in_ifnames[1], + n->in_v[1]); } - if (n->in_plabel[0] != '\0') { - n->in_apr = appr_lookup(n->in_p, n->in_plabel); + if (n->in_plabel != -1) { + if (n->in_redir & NAT_REDIRECT) + n->in_apr = ipf_proxy_lookup(softc->ipf_proxy_soft, + n->in_pr[0], + base + n->in_plabel); + else + n->in_apr = ipf_proxy_lookup(softc->ipf_proxy_soft, + n->in_pr[1], + base + n->in_plabel); if (n->in_apr == NULL) return -1; } @@ -1125,106 +1663,93 @@ ipnat_t *n; /* ------------------------------------------------------------------------ */ -/* Function: nat_siocdelnat */ +/* Function: ipf_nat_siocdelnat */ /* Returns: int - 0 == success, != 0 == failure */ -/* Parameters: n(I) - pointer to new NAT rule */ -/* np(I) - pointer to where to insert new NAT rule */ -/* getlock(I) - flag indicating if lock on ipf_nat is held */ -/* Mutex Locks: ipf_natio */ +/* Parameters: softc(I) - pointer to soft context main structure */ +/* softn(I) - pointer to NAT context structure */ +/* n(I) - pointer to new NAT rule */ +/* getlock(I) - flag indicating if lock on is held */ +/* Mutex Locks: ipf_nat_io */ /* */ /* Handle SIOCADNAT. Resolve and calculate details inside the NAT rule */ /* from information passed to the kernel, then add it to the appropriate */ /* NAT rule table(s). */ /* ------------------------------------------------------------------------ */ -static void nat_siocdelnat(n, np, getlock) -ipnat_t *n, **np; -int getlock; +static void +ipf_nat_siocdelnat(softc, softn, n, getlock) + ipf_main_softc_t *softc; + ipf_nat_softc_t *softn; + ipnat_t *n; + int getlock; { - if (getlock) { - WRITE_ENTER(&ipf_nat); - } - if (n->in_redir & NAT_REDIRECT) - nat_delrdr(n); - if (n->in_redir & (NAT_MAPBLK|NAT_MAP)) - nat_delnat(n); - if (nat_list == NULL) { - nat_masks = 0; - rdr_masks = 0; - } - - if (n->in_tqehead[0] != NULL) { - if (fr_deletetimeoutqueue(n->in_tqehead[0]) == 0) { - fr_freetimeoutqueue(n->in_tqehead[1]); - } - } - - if (n->in_tqehead[1] != NULL) { - if (fr_deletetimeoutqueue(n->in_tqehead[1]) == 0) { - fr_freetimeoutqueue(n->in_tqehead[1]); - } - } - - *np = n->in_next; - - if (n->in_use == 0) { - if (n->in_apr) - appr_free(n->in_apr); - MUTEX_DESTROY(&n->in_lock); - KFREE(n); - nat_stats.ns_rules--; -#if SOLARIS && !defined(_INET_IP_STACK_H) - if (nat_stats.ns_rules == 0) - pfil_delayed_copy = 1; +#ifdef IPF_NAT6 + int i; #endif - } else { - n->in_flags |= IPN_DELETE; - n->in_next = NULL; - } + if (getlock) { - RWLOCK_EXIT(&ipf_nat); /* READ/WRITE */ + WRITE_ENTER(&softc->ipf_nat); + } + + ipf_nat_delrule(softc, softn, n, 1); + + if (getlock) { + RWLOCK_EXIT(&softc->ipf_nat); /* READ/WRITE */ } } /* ------------------------------------------------------------------------ */ -/* Function: fr_natgetsz */ +/* Function: ipf_nat_getsz */ /* Returns: int - 0 == success, != 0 is the error value. */ -/* Parameters: data(I) - pointer to natget structure with kernel pointer */ -/* get the size of. */ +/* Parameters: softc(I) - pointer to soft context main structure */ +/* data(I) - pointer to natget structure with kernel */ +/* pointer get the size of. */ +/* getlock(I) - flag indicating whether or not the caller */ +/* holds a lock on ipf_nat */ /* */ /* Handle SIOCSTGSZ. */ /* Return the size of the nat list entry to be copied back to user space. */ /* The size of the entry is stored in the ng_sz field and the enture natget */ /* structure is copied back to the user. */ /* ------------------------------------------------------------------------ */ -static int fr_natgetsz(data, getlock) -caddr_t data; -int getlock; +static int +ipf_nat_getsz(softc, data, getlock) + ipf_main_softc_t *softc; + caddr_t data; + int getlock; { + ipf_nat_softc_t *softn = softc->ipf_nat_soft; ap_session_t *aps; nat_t *nat, *n; natget_t ng; + int error; - if (BCOPYIN(data, &ng, sizeof(ng)) != 0) + error = BCOPYIN(data, &ng, sizeof(ng)); + if (error != 0) { + IPFERROR(60024); return EFAULT; + } if (getlock) { - READ_ENTER(&ipf_nat); + READ_ENTER(&softc->ipf_nat); } nat = ng.ng_ptr; if (!nat) { - nat = nat_instances; + nat = softn->ipf_nat_instances; ng.ng_sz = 0; /* * Empty list so the size returned is 0. Simple. */ if (nat == NULL) { if (getlock) { - RWLOCK_EXIT(&ipf_nat); + RWLOCK_EXIT(&softc->ipf_nat); } - if (BCOPYOUT(&ng, data, sizeof(ng)) != 0) + error = BCOPYOUT(&ng, data, sizeof(ng)); + if (error != 0) { + IPFERROR(60025); return EFAULT; + } return 0; } } else { @@ -1233,13 +1758,14 @@ int getlock; * current list of entries. Security precaution to prevent * copying of random kernel data. */ - for (n = nat_instances; n; n = n->nat_next) + for (n = softn->ipf_nat_instances; n; n = n->nat_next) if (n == nat) break; if (n == NULL) { if (getlock) { - RWLOCK_EXIT(&ipf_nat); + RWLOCK_EXIT(&softc->ipf_nat); } + IPFERROR(60026); return ESRCH; } } @@ -1255,56 +1781,71 @@ int getlock; ng.ng_sz += aps->aps_psiz; } if (getlock) { - RWLOCK_EXIT(&ipf_nat); + RWLOCK_EXIT(&softc->ipf_nat); } - if (BCOPYOUT(&ng, data, sizeof(ng)) != 0) + error = BCOPYOUT(&ng, data, sizeof(ng)); + if (error != 0) { + IPFERROR(60027); return EFAULT; + } return 0; } /* ------------------------------------------------------------------------ */ -/* Function: fr_natgetent */ +/* Function: ipf_nat_getent */ /* Returns: int - 0 == success, != 0 is the error value. */ -/* Parameters: data(I) - pointer to natget structure with kernel pointer */ -/* to NAT structure to copy out. */ +/* Parameters: softc(I) - pointer to soft context main structure */ +/* data(I) - pointer to natget structure with kernel pointer*/ +/* to NAT structure to copy out. */ +/* getlock(I) - flag indicating whether or not the caller */ +/* holds a lock on ipf_nat */ /* */ /* Handle SIOCSTGET. */ /* Copies out NAT entry to user space. Any additional data held for a */ /* proxy is also copied, as to is the NAT rule which was responsible for it */ /* ------------------------------------------------------------------------ */ -static int fr_natgetent(data, getlock) -caddr_t data; -int getlock; +static int +ipf_nat_getent(softc, data, getlock) + ipf_main_softc_t *softc; + caddr_t data; + int getlock; { + ipf_nat_softc_t *softn = softc->ipf_nat_soft; int error, outsize; ap_session_t *aps; nat_save_t *ipn, ipns; nat_t *n, *nat; - error = fr_inobj(data, &ipns, IPFOBJ_NATSAVE); + error = ipf_inobj(softc, data, NULL, &ipns, IPFOBJ_NATSAVE); if (error != 0) return error; - if ((ipns.ipn_dsize < sizeof(ipns)) || (ipns.ipn_dsize > 81920)) + if ((ipns.ipn_dsize < sizeof(ipns)) || (ipns.ipn_dsize > 81920)) { + IPFERROR(60028); return EINVAL; + } KMALLOCS(ipn, nat_save_t *, ipns.ipn_dsize); - if (ipn == NULL) + if (ipn == NULL) { + IPFERROR(60029); return ENOMEM; + } if (getlock) { - READ_ENTER(&ipf_nat); + READ_ENTER(&softc->ipf_nat); } ipn->ipn_dsize = ipns.ipn_dsize; nat = ipns.ipn_next; if (nat == NULL) { - nat = nat_instances; + nat = softn->ipf_nat_instances; if (nat == NULL) { - if (nat_instances == NULL) + if (softn->ipf_nat_instances == NULL) { + IPFERROR(60030); error = ENOENT; + } goto finished; } } else { @@ -1313,10 +1854,11 @@ int getlock; * current list of entries. Security precaution to prevent * copying of random kernel data. */ - for (n = nat_instances; n; n = n->nat_next) + for (n = softn->ipf_nat_instances; n; n = n->nat_next) if (n == nat) break; if (n == NULL) { + IPFERROR(60031); error = ESRCH; goto finished; } @@ -1333,7 +1875,7 @@ int getlock; */ if (nat->nat_ptr != NULL) bcopy((char *)nat->nat_ptr, (char *)&ipn->ipn_ipnat, - sizeof(ipn->ipn_ipnat)); + ipn->ipn_ipnat.in_size); /* * If we also know the NAT entry has an associated filter rule, @@ -1354,6 +1896,7 @@ int getlock; char *s; if (outsize < sizeof(*aps)) { + IPFERROR(60032); error = ENOBUFS; goto finished; } @@ -1364,20 +1907,23 @@ int getlock; outsize -= sizeof(*aps); if ((aps->aps_data != NULL) && (outsize >= aps->aps_psiz)) bcopy(aps->aps_data, s, aps->aps_psiz); - else + else { + IPFERROR(60033); error = ENOBUFS; + } } if (error == 0) { if (getlock) { - RWLOCK_EXIT(&ipf_nat); + READ_ENTER(&softc->ipf_nat); getlock = 0; } - error = fr_outobjsz(data, ipn, IPFOBJ_NATSAVE, ipns.ipn_dsize); + error = ipf_outobjsz(softc, data, ipn, IPFOBJ_NATSAVE, + ipns.ipn_dsize); } finished: if (getlock) { - RWLOCK_EXIT(&ipf_nat); + READ_ENTER(&softc->ipf_nat); } if (ipn != NULL) { KFREES(ipn, ipns.ipn_dsize); @@ -1387,21 +1933,25 @@ int getlock; /* ------------------------------------------------------------------------ */ -/* Function: fr_natputent */ +/* Function: ipf_nat_putent */ /* Returns: int - 0 == success, != 0 is the error value. */ -/* Parameters: data(I) - pointer to natget structure with NAT */ -/* structure information to load into the kernel */ +/* Parameters: softc(I) - pointer to soft context main structure */ +/* data(I) - pointer to natget structure with NAT */ +/* structure information to load into the kernel */ /* getlock(I) - flag indicating whether or not a write lock */ -/* on ipf_nat is already held. */ +/* on is already held. */ /* */ /* Handle SIOCSTPUT. */ /* Loads a NAT table entry from user space, including a NAT rule, proxy and */ /* firewall rule data structures, if pointers to them indicate so. */ /* ------------------------------------------------------------------------ */ -static int fr_natputent(data, getlock) -caddr_t data; -int getlock; +static int +ipf_nat_putent(softc, data, getlock) + ipf_main_softc_t *softc; + caddr_t data; + int getlock; { + ipf_nat_softc_t *softn = softc->ipf_nat_soft; nat_save_t ipn, *ipnn; ap_session_t *aps; nat_t *n, *nat; @@ -1410,13 +1960,14 @@ int getlock; ipnat_t *in; int error; - error = fr_inobj(data, &ipn, IPFOBJ_NATSAVE); + error = ipf_inobj(softc, data, NULL, &ipn, IPFOBJ_NATSAVE); if (error != 0) return error; /* * Initialise early because of code at junkput label. */ + n = NULL; in = NULL; aps = NULL; nat = NULL; @@ -1429,17 +1980,21 @@ int getlock; */ if (ipn.ipn_dsize > sizeof(ipn)) { if (ipn.ipn_dsize > 81920) { + IPFERROR(60034); error = ENOMEM; goto junkput; } KMALLOCS(ipnn, nat_save_t *, ipn.ipn_dsize); - if (ipnn == NULL) + if (ipnn == NULL) { + IPFERROR(60035); return ENOMEM; + } - error = fr_inobjsz(data, ipnn, IPFOBJ_NATSAVE, ipn.ipn_dsize); + bzero(ipnn, ipn.ipn_dsize); + error = ipf_inobjsz(softc, data, ipnn, IPFOBJ_NATSAVE, + ipn.ipn_dsize); if (error != 0) { - error = EFAULT; goto junkput; } } else @@ -1447,13 +2002,29 @@ int getlock; KMALLOC(nat, nat_t *); if (nat == NULL) { + IPFERROR(60037); error = ENOMEM; goto junkput; } bcopy((char *)&ipnn->ipn_nat, (char *)nat, sizeof(*nat)); + + switch (nat->nat_v[0]) + { + case 4: +#ifdef USE_INET6 + case 6 : +#endif + break; + default : + IPFERROR(60061); + error = EPROTONOSUPPORT; + goto junkput; + /*NOTREACHED*/ + } + /* - * Initialize all these so that nat_delete() doesn't cause a crash. + * Initialize all these so that ipf_nat_delete() doesn't cause a crash. */ bzero((char *)nat, offsetof(struct nat, nat_tqe)); nat->nat_tqe.tqe_pnext = NULL; @@ -1466,20 +2037,22 @@ int getlock; */ in = ipnn->ipn_nat.nat_ptr; if (in != NULL) { - KMALLOC(in, ipnat_t *); + KMALLOCS(in, ipnat_t *, ipnn->ipn_ipnat.in_size); nat->nat_ptr = in; if (in == NULL) { + IPFERROR(60038); error = ENOMEM; goto junkput; } - bzero((char *)in, offsetof(struct ipnat, in_next6)); - bcopy((char *)&ipnn->ipn_ipnat, (char *)in, sizeof(*in)); + bcopy((char *)&ipnn->ipn_ipnat, (char *)in, + ipnn->ipn_ipnat.in_size); in->in_use = 1; in->in_flags |= IPN_DELETE; - ATOMIC_INC(nat_stats.ns_rules); + ATOMIC_INC32(softn->ipf_nat_stats.ns_rules); - if (nat_resolverule(in) != 0) { + if (ipf_nat_resolverule(softc, in) != 0) { + IPFERROR(60039); error = ESRCH; goto junkput; } @@ -1491,43 +2064,76 @@ int getlock; * For NAT_OUTBOUND, we're lookup for a duplicate MAP entry. To do * this, we check to see if the inbound combination of addresses and * ports is already known. Similar logic is applied for NAT_INBOUND. - * + * */ bzero((char *)&fin, sizeof(fin)); - fin.fin_p = nat->nat_p; - if (nat->nat_dir == NAT_OUTBOUND) { - fin.fin_ifp = nat->nat_ifps[0]; - fin.fin_data[0] = ntohs(nat->nat_oport); - fin.fin_data[1] = ntohs(nat->nat_outport); + fin.fin_v = nat->nat_v[0]; + fin.fin_p = nat->nat_pr[0]; + fin.fin_rev = nat->nat_rev; + fin.fin_ifp = nat->nat_ifps[0]; + fin.fin_data[0] = ntohs(nat->nat_ndport); + fin.fin_data[1] = ntohs(nat->nat_nsport); + + switch (nat->nat_dir) + { + case NAT_OUTBOUND : + case NAT_DIVERTOUT : if (getlock) { - READ_ENTER(&ipf_nat); + READ_ENTER(&softc->ipf_nat); } - n = nat_inlookup(&fin, nat->nat_flags, fin.fin_p, - nat->nat_oip, nat->nat_inip); + + fin.fin_v = nat->nat_v[1]; + if (nat->nat_v[1] == 4) { + n = ipf_nat_inlookup(&fin, nat->nat_flags, fin.fin_p, + nat->nat_ndstip, nat->nat_nsrcip); +#ifdef USE_INET6 + } else if (nat->nat_v[1] == 6) { + n = ipf_nat6_inlookup(&fin, nat->nat_flags, fin.fin_p, + &nat->nat_ndst6.in6, + &nat->nat_nsrc6.in6); +#endif + } + if (getlock) { - RWLOCK_EXIT(&ipf_nat); + RWLOCK_EXIT(&softc->ipf_nat); } if (n != NULL) { + IPFERROR(60040); error = EEXIST; goto junkput; } - } else if (nat->nat_dir == NAT_INBOUND) { - fin.fin_ifp = nat->nat_ifps[0]; - fin.fin_data[0] = ntohs(nat->nat_outport); - fin.fin_data[1] = ntohs(nat->nat_oport); + break; + + case NAT_INBOUND : + case NAT_DIVERTIN : if (getlock) { - READ_ENTER(&ipf_nat); + READ_ENTER(&softc->ipf_nat); } - n = nat_outlookup(&fin, nat->nat_flags, fin.fin_p, - nat->nat_outip, nat->nat_oip); + + if (fin.fin_v == 4) { + n = ipf_nat_outlookup(&fin, nat->nat_flags, fin.fin_p, + nat->nat_ndstip, + nat->nat_nsrcip); +#ifdef USE_INET6 + } else if (fin.fin_v == 6) { + n = ipf_nat6_outlookup(&fin, nat->nat_flags, fin.fin_p, + &nat->nat_ndst6.in6, + &nat->nat_nsrc6.in6); +#endif + } + if (getlock) { - RWLOCK_EXIT(&ipf_nat); + RWLOCK_EXIT(&softc->ipf_nat); } if (n != NULL) { + IPFERROR(60041); error = EEXIST; goto junkput; } - } else { + break; + + default : + IPFERROR(60042); error = EINVAL; goto junkput; } @@ -1541,6 +2147,7 @@ int getlock; KMALLOC(aps, ap_session_t *); nat->nat_aps = aps; if (aps == NULL) { + IPFERROR(60043); error = ENOMEM; goto junkput; } @@ -1551,11 +2158,13 @@ int getlock; aps->aps_apr = NULL; if (aps->aps_psiz != 0) { if (aps->aps_psiz > 81920) { + IPFERROR(60044); error = ENOMEM; goto junkput; } KMALLOCS(aps->aps_data, void *, aps->aps_psiz); if (aps->aps_data == NULL) { + IPFERROR(60045); error = ENOMEM; goto junkput; } @@ -1577,12 +2186,13 @@ int getlock; KMALLOC(fr, frentry_t *); nat->nat_fr = fr; if (fr == NULL) { + IPFERROR(60046); error = ENOMEM; goto junkput; } ipnn->ipn_nat.nat_fr = fr; fr->fr_ref = 1; - (void) fr_outobj(data, ipnn, IPFOBJ_NATSAVE); + (void) ipf_outobj(softc, data, ipnn, IPFOBJ_NATSAVE); bcopy((char *)&ipnn->ipn_fr, (char *)fr, sizeof(*fr)); fr->fr_ref = 1; @@ -1594,9 +2204,9 @@ int getlock; MUTEX_INIT(&fr->fr_lock, "nat-filter rule lock"); } else { if (getlock) { - READ_ENTER(&ipf_nat); + READ_ENTER(&softc->ipf_nat); } - for (n = nat_instances; n; n = n->nat_next) + for (n = softn->ipf_nat_instances; n; n = n->nat_next) if (n->nat_fr == fr) break; @@ -1606,10 +2216,11 @@ int getlock; MUTEX_EXIT(&fr->fr_lock); } if (getlock) { - RWLOCK_EXIT(&ipf_nat); + RWLOCK_EXIT(&softc->ipf_nat); } - if (!n) { + if (n == NULL) { + IPFERROR(60047); error = ESRCH; goto junkput; } @@ -1622,25 +2233,30 @@ int getlock; } if (getlock) { - WRITE_ENTER(&ipf_nat); - } - error = nat_insert(nat, nat->nat_rev); - if ((error == 0) && (aps != NULL)) { - aps->aps_next = ap_sess_list; - ap_sess_list = aps; + WRITE_ENTER(&softc->ipf_nat); } + + if (fin.fin_v == 4) + error = ipf_nat_finalise(&fin, nat); +#ifdef USE_INET6 + else + error = ipf_nat6_finalise(&fin, nat); +#endif + if (getlock) { - RWLOCK_EXIT(&ipf_nat); + RWLOCK_EXIT(&softc->ipf_nat); } if (error == 0) return 0; + IPFERROR(60048); error = ENOMEM; junkput: - if (fr != NULL) - (void) fr_derefrule(&fr); + if (fr != NULL) { + (void) ipf_derefrule(softc, &fr); + } if ((ipnn != NULL) && (ipnn != &ipn)) { KFREES(ipnn, ipn.ipn_dsize); @@ -1654,8 +2270,8 @@ int getlock; } if (in != NULL) { if (in->in_apr) - appr_free(in->in_apr); - KFREE(in); + ipf_proxy_deref(in->in_apr); + KFREES(in, in->in_size); } KFREE(nat); } @@ -1664,27 +2280,29 @@ int getlock; /* ------------------------------------------------------------------------ */ -/* Function: nat_delete */ +/* Function: ipf_nat_delete */ /* Returns: Nil */ -/* Parameters: natd(I) - pointer to NAT structure to delete */ +/* Parameters: softc(I) - pointer to soft context main structure */ +/* nat(I) - pointer to NAT structure to delete */ /* logtype(I) - type of LOG record to create before deleting */ /* Write Lock: ipf_nat */ /* */ /* Delete a nat entry from the various lists and table. If NAT logging is */ /* enabled then generate a NAT log record for this event. */ /* ------------------------------------------------------------------------ */ -void nat_delete(nat, logtype) -struct nat *nat; -int logtype; +void +ipf_nat_delete(softc, nat, logtype) + ipf_main_softc_t *softc; + struct nat *nat; + int logtype; { + ipf_nat_softc_t *softn = softc->ipf_nat_soft; + int madeorphan = 0, bkt, removed = 0; + nat_stat_side_t *nss; struct ipnat *ipn; - int removed = 0; - if (logtype != 0 && nat_logging != 0) - nat_log(nat, logtype); -#if defined(NEED_LOCAL_RAND) && defined(_KERNEL) - ipf_rand_push(nat, sizeof(*nat)); -#endif + if (logtype != 0 && softn->ipf_nat_logging != 0) + ipf_nat_log(softc, softn, nat, logtype); /* * Take it as a general indication that all the pointers are set if @@ -1693,8 +2311,19 @@ int logtype; if (nat->nat_pnext != NULL) { removed = 1; - nat_stats.ns_bucketlen[0][nat->nat_hv[0]]--; - nat_stats.ns_bucketlen[1][nat->nat_hv[1]]--; + bkt = nat->nat_hv[0] % softn->ipf_nat_table_sz; + nss = &softn->ipf_nat_stats.ns_side[0]; + nss->ns_bucketlen[bkt]--; + if (nss->ns_bucketlen[bkt] == 0) { + nss->ns_inuse--; + } + + bkt = nat->nat_hv[1] % softn->ipf_nat_table_sz; + nss = &softn->ipf_nat_stats.ns_side[1]; + nss->ns_bucketlen[bkt]--; + if (nss->ns_bucketlen[bkt] == 0) { + nss->ns_inuse--; + } *nat->nat_pnext = nat->nat_next; if (nat->nat_next != NULL) { @@ -1717,20 +2346,34 @@ int logtype; } nat->nat_phnext[1] = NULL; - if ((nat->nat_flags & SI_WILDP) != 0) - nat_stats.ns_wilds--; + if ((nat->nat_flags & SI_WILDP) != 0) { + ATOMIC_DEC32(softn->ipf_nat_stats.ns_wilds); + } + madeorphan = 1; } if (nat->nat_me != NULL) { *nat->nat_me = NULL; nat->nat_me = NULL; + nat->nat_ref--; + ASSERT(nat->nat_ref >= 0); } - if (nat->nat_tqe.tqe_ifq != NULL) - fr_deletequeueentry(&nat->nat_tqe); + if (nat->nat_tqe.tqe_ifq != NULL) { + /* + * No call to ipf_freetimeoutqueue() is made here, they are + * garbage collected in ipf_nat_expire(). + */ + (void) ipf_deletequeueentry(&nat->nat_tqe); + } + + if (nat->nat_sync) { + ipf_sync_del_nat(softc->ipf_sync_soft, nat->nat_sync); + nat->nat_sync = NULL; + } if (logtype == NL_EXPIRE) - nat_stats.ns_expire++; + softn->ipf_nat_stats.ns_expire++; MUTEX_ENTER(&nat->nat_lock); /* @@ -1743,35 +2386,36 @@ int logtype; nat->nat_ref -= 2; MUTEX_EXIT(&nat->nat_lock); if (removed) - nat_stats.ns_orphans++; + softn->ipf_nat_stats.ns_orphans++; return; } } else if (nat->nat_ref > 1) { nat->nat_ref--; MUTEX_EXIT(&nat->nat_lock); - if (removed) - nat_stats.ns_orphans++; + if (madeorphan == 1) + softn->ipf_nat_stats.ns_orphans++; return; } + ASSERT(nat->nat_ref >= 0); MUTEX_EXIT(&nat->nat_lock); - /* - * At this point, nat_ref is 1, doing "--" would make it 0.. - */ nat->nat_ref = 0; - if (!removed) - nat_stats.ns_orphans--; -#ifdef IPFILTER_SYNC - if (nat->nat_sync) - ipfsync_del(nat->nat_sync); -#endif + if (madeorphan == 0) + softn->ipf_nat_stats.ns_orphans--; - if (nat->nat_fr != NULL) - (void) fr_derefrule(&nat->nat_fr); + /* + * At this point, nat_ref can be either 0 or -1 + */ + softn->ipf_nat_stats.ns_proto[nat->nat_pr[0]]--; - if (nat->nat_hm != NULL) - fr_hostmapdel(&nat->nat_hm); + if (nat->nat_fr != NULL) { + (void) ipf_derefrule(softc, &nat->nat_fr); + } + + if (nat->nat_hm != NULL) { + ipf_nat_hostmapdel(softc, &nat->nat_hm); + } /* * If there is an active reference from the nat entry to its parent @@ -1779,38 +2423,51 @@ int logtype; * longer being used. */ ipn = nat->nat_ptr; + nat->nat_ptr = NULL; + if (ipn != NULL) { - fr_ipnatderef(&ipn); + ipn->in_space++; + ipf_nat_rule_deref(softc, &ipn); + } + + if (nat->nat_aps != NULL) { + ipf_proxy_free(softc, nat->nat_aps); + nat->nat_aps = NULL; } MUTEX_DESTROY(&nat->nat_lock); - aps_free(nat->nat_aps); - nat_stats.ns_inuse--; + softn->ipf_nat_stats.ns_active--; /* * If there's a fragment table entry too for this nat entry, then * dereference that as well. This is after nat_lock is released * because of Tru64. */ - fr_forgetnat((void *)nat); + ipf_frag_natforget(softc, (void *)nat); KFREE(nat); } /* ------------------------------------------------------------------------ */ -/* Function: nat_flushtable */ +/* Function: ipf_nat_flushtable */ /* Returns: int - number of NAT rules deleted */ -/* Parameters: Nil */ +/* Parameters: softc(I) - pointer to soft context main structure */ +/* softn(I) - pointer to NAT context structure */ +/* Write Lock: ipf_nat */ /* */ /* Deletes all currently active NAT sessions. In deleting each NAT entry a */ -/* log record should be emitted in nat_delete() if NAT logging is enabled. */ +/* log record should be emitted in ipf_nat_delete() if NAT logging is */ +/* enabled. */ /* ------------------------------------------------------------------------ */ /* * nat_flushtable - clear the NAT table of all mapping entries. */ -static int nat_flushtable() +static int +ipf_nat_flushtable(softc, softn) + ipf_main_softc_t *softc; + ipf_nat_softc_t *softn; { nat_t *nat; int j = 0; @@ -1819,67 +2476,141 @@ static int nat_flushtable() * ALL NAT mappings deleted, so lets just make the deletions * quicker. */ - if (nat_table[0] != NULL) - bzero((char *)nat_table[0], - sizeof(nat_table[0]) * ipf_nattable_sz); - if (nat_table[1] != NULL) - bzero((char *)nat_table[1], - sizeof(nat_table[1]) * ipf_nattable_sz); + if (softn->ipf_nat_table[0] != NULL) + bzero((char *)softn->ipf_nat_table[0], + sizeof(softn->ipf_nat_table[0]) * + softn->ipf_nat_table_sz); + if (softn->ipf_nat_table[1] != NULL) + bzero((char *)softn->ipf_nat_table[1], + sizeof(softn->ipf_nat_table[1]) * + softn->ipf_nat_table_sz); - while ((nat = nat_instances) != NULL) { - nat_delete(nat, NL_FLUSH); + while ((nat = softn->ipf_nat_instances) != NULL) { + ipf_nat_delete(softc, nat, NL_FLUSH); j++; } - nat_stats.ns_inuse = 0; return j; } /* ------------------------------------------------------------------------ */ -/* Function: nat_clearlist */ +/* Function: ipf_nat_clearlist */ /* Returns: int - number of NAT/RDR rules deleted */ -/* Parameters: Nil */ +/* Parameters: softc(I) - pointer to soft context main structure */ +/* softn(I) - pointer to NAT context structure */ /* */ /* Delete all rules in the current list of rules. There is nothing elegant */ /* about this cleanup: simply free all entries on the list of rules and */ /* clear out the tables used for hashed NAT rule lookups. */ /* ------------------------------------------------------------------------ */ -static int nat_clearlist() +static int +ipf_nat_clearlist(softc, softn) + ipf_main_softc_t *softc; + ipf_nat_softc_t *softn; { - ipnat_t *n, **np = &nat_list; + ipnat_t *n; int i = 0; - if (nat_rules != NULL) - bzero((char *)nat_rules, sizeof(*nat_rules) * ipf_natrules_sz); - if (rdr_rules != NULL) - bzero((char *)rdr_rules, sizeof(*rdr_rules) * ipf_rdrrules_sz); + if (softn->ipf_nat_map_rules != NULL) { + bzero((char *)softn->ipf_nat_map_rules, + sizeof(*softn->ipf_nat_map_rules) * + softn->ipf_nat_maprules_sz); + } + if (softn->ipf_nat_rdr_rules != NULL) { + bzero((char *)softn->ipf_nat_rdr_rules, + sizeof(*softn->ipf_nat_rdr_rules) * + softn->ipf_nat_rdrrules_sz); + } - while ((n = *np) != NULL) { - *np = n->in_next; - if (n->in_use == 0) { - if (n->in_apr != NULL) - appr_free(n->in_apr); - MUTEX_DESTROY(&n->in_lock); - KFREE(n); - nat_stats.ns_rules--; - } else { - n->in_flags |= IPN_DELETE; - n->in_next = NULL; - } + while ((n = softn->ipf_nat_list) != NULL) { + ipf_nat_delrule(softc, softn, n, 0); i++; } -#if SOLARIS && !defined(_INET_IP_STACK_H) +#if SOLARIS && !defined(INSTANCES) pfil_delayed_copy = 1; #endif - nat_masks = 0; - rdr_masks = 0; return i; } /* ------------------------------------------------------------------------ */ -/* Function: nat_newmap */ +/* Function: ipf_nat_delrule */ +/* Returns: Nil */ +/* Parameters: softc(I) - pointer to soft context main structure */ +/* softn(I) - pointer to NAT context structure */ +/* np(I) - pointer to NAT rule to delete */ +/* purge(I) - 1 == allow purge, 0 == prevent purge */ +/* Locks: WRITE(ipf_nat) */ +/* */ +/* Preventing "purge" from occuring is allowed because when all of the NAT */ +/* rules are being removed, allowing the "purge" to walk through the list */ +/* of NAT sessions, possibly multiple times, would be a large performance */ +/* hit, on the order of O(N^2). */ +/* ------------------------------------------------------------------------ */ +static void +ipf_nat_delrule(softc, softn, np, purge) + ipf_main_softc_t *softc; + ipf_nat_softc_t *softn; + ipnat_t *np; + int purge; +{ + + if (np->in_pnext != NULL) { + *np->in_pnext = np->in_next; + if (np->in_next != NULL) + np->in_next->in_pnext = np->in_pnext; + if (softn->ipf_nat_list_tail == &np->in_next) + softn->ipf_nat_list_tail = np->in_pnext; + } + + if ((purge == 1) && ((np->in_flags & IPN_PURGE) != 0)) { + nat_t *next; + nat_t *nat; + + for (next = softn->ipf_nat_instances; (nat = next) != NULL;) { + next = nat->nat_next; + if (nat->nat_ptr == np) + ipf_nat_delete(softc, nat, NL_PURGE); + } + } + + if ((np->in_flags & IPN_DELETE) == 0) { + if (np->in_redir & NAT_REDIRECT) { + switch (np->in_v[0]) + { + case 4 : + ipf_nat_delrdr(softn, np); + break; +#ifdef USE_INET6 + case 6 : + ipf_nat6_delrdr(softn, np); + break; +#endif + } + } + if (np->in_redir & (NAT_MAPBLK|NAT_MAP)) { + switch (np->in_v[0]) + { + case 4 : + ipf_nat_delmap(softn, np); + break; +#ifdef USE_INET6 + case 6 : + ipf_nat6_delmap(softn, np); + break; +#endif + } + } + } + + np->in_flags |= IPN_DELETE; + ipf_nat_rule_deref(softc, &np); +} + + +/* ------------------------------------------------------------------------ */ +/* Function: ipf_nat_newmap */ /* Returns: int - -1 == error, 0 == success */ /* Parameters: fin(I) - pointer to packet information */ /* nat(I) - pointer to NAT entry */ @@ -1891,11 +2622,14 @@ static int nat_clearlist() /* ni.nai_ip is passed in uninitialised and must be set, in host byte order,*/ /* to the new IP address for the translation. */ /* ------------------------------------------------------------------------ */ -static INLINE int nat_newmap(fin, nat, ni) -fr_info_t *fin; -nat_t *nat; -natinfo_t *ni; +static int +ipf_nat_newmap(fin, nat, ni) + fr_info_t *fin; + nat_t *nat; + natinfo_t *ni; { + ipf_main_softc_t *softc = fin->fin_main_soft; + ipf_nat_softc_t *softn = softc->ipf_nat_soft; u_short st_port, dport, sport, port, sp, dp; struct in_addr in, inb; hostmap_t *hm; @@ -1912,11 +2646,17 @@ natinfo_t *ni; l = 0; hm = NULL; np = ni->nai_np; - st_ip = np->in_nip; - st_port = np->in_pnext; - flags = ni->nai_flags; - sport = ni->nai_sport; - dport = ni->nai_dport; + st_ip = np->in_snip; + st_port = np->in_spnext; + flags = nat->nat_flags; + + if (flags & IPN_ICMPQUERY) { + sport = fin->fin_data[1]; + dport = 0; + } else { + sport = htons(fin->fin_data[0]); + dport = htons(fin->fin_data[1]); + } /* * Do a loop until we either run out of entries to try or we find @@ -1925,50 +2665,54 @@ natinfo_t *ni; */ do { port = 0; - in.s_addr = htonl(np->in_nip); + in.s_addr = htonl(np->in_snip); if (l == 0) { /* * Check to see if there is an existing NAT * setup for this IP address pair. */ - hm = nat_hostmap(np, fin->fin_src, fin->fin_dst, - in, 0); + hm = ipf_nat_hostmap(softn, np, fin->fin_src, + fin->fin_dst, in, 0); if (hm != NULL) - in.s_addr = hm->hm_mapip.s_addr; + in.s_addr = hm->hm_nsrcip.s_addr; } else if ((l == 1) && (hm != NULL)) { - fr_hostmapdel(&hm); + ipf_nat_hostmapdel(softc, &hm); } in.s_addr = ntohl(in.s_addr); nat->nat_hm = hm; - if ((np->in_outmsk == 0xffffffff) && (np->in_pnext == 0)) { - if (l > 0) + if ((np->in_nsrcmsk == 0xffffffff) && (np->in_spnext == 0)) { + if (l > 0) { + NBUMPSIDEX(1, ns_exhausted, ns_exhausted_1); return -1; + } } if (np->in_redir == NAT_BIMAP && - np->in_inmsk == np->in_outmsk) { + np->in_osrcmsk == np->in_nsrcmsk) { /* * map the address block in a 1:1 fashion */ - in.s_addr = np->in_outip; - in.s_addr |= fin->fin_saddr & ~np->in_inmsk; + in.s_addr = np->in_nsrcaddr; + in.s_addr |= fin->fin_saddr & ~np->in_osrcmsk; in.s_addr = ntohl(in.s_addr); } else if (np->in_redir & NAT_MAPBLK) { if ((l >= np->in_ppip) || ((l > 0) && - !(flags & IPN_TCPUDP))) + !(flags & IPN_TCPUDP))) { + NBUMPSIDEX(1, ns_exhausted, ns_exhausted_2); return -1; + } /* * map-block - Calculate destination address. */ in.s_addr = ntohl(fin->fin_saddr); - in.s_addr &= ntohl(~np->in_inmsk); + in.s_addr &= ntohl(~np->in_osrcmsk); inb.s_addr = in.s_addr; in.s_addr /= np->in_ippip; - in.s_addr &= ntohl(~np->in_outmsk); - in.s_addr += ntohl(np->in_outip); + in.s_addr &= ntohl(~np->in_nsrcmsk); + in.s_addr += ntohl(np->in_nsrcaddr); /* * Calculate destination port. */ @@ -1982,28 +2726,34 @@ natinfo_t *ni; port = htons(port); } - } else if ((np->in_outip == 0) && - (np->in_outmsk == 0xffffffff)) { + } else if ((np->in_nsrcaddr == 0) && + (np->in_nsrcmsk == 0xffffffff)) { + i6addr_t in6; + /* * 0/32 - use the interface's IP address. */ if ((l > 0) || - fr_ifpaddr(4, FRI_NORMAL, fin->fin_ifp, - &in, NULL) == -1) + ipf_ifpaddr(softc, 4, FRI_NORMAL, fin->fin_ifp, + &in6, NULL) == -1) { + NBUMPSIDEX(1, ns_new_ifpaddr, ns_new_ifpaddr_1); return -1; - in.s_addr = ntohl(in.s_addr); + } + in.s_addr = ntohl(in6.in4.s_addr); - } else if ((np->in_outip == 0) && (np->in_outmsk == 0)) { + } else if ((np->in_nsrcaddr == 0) && (np->in_nsrcmsk == 0)) { /* * 0/0 - use the original source address/port. */ - if (l > 0) + if (l > 0) { + NBUMPSIDEX(1, ns_exhausted, ns_exhausted_3); return -1; + } in.s_addr = ntohl(fin->fin_saddr); - } else if ((np->in_outmsk != 0xffffffff) && - (np->in_pnext == 0) && ((l > 0) || (hm == NULL))) - np->in_nip++; + } else if ((np->in_nsrcmsk != 0xffffffff) && + (np->in_spnext == 0) && ((l > 0) || (hm == NULL))) + np->in_snip++; natl = NULL; @@ -2014,11 +2764,9 @@ natinfo_t *ni; * "ports auto" (without map-block) */ if ((l > 0) && (l % np->in_ppip == 0)) { - if (l > np->in_space) { - return -1; - } else if ((l > np->in_ppip) && - np->in_outmsk != 0xffffffff) - np->in_nip++; + if ((l > np->in_ppip) && + np->in_nsrcmsk != 0xffffffff) + np->in_snip++; } if (np->in_ppip != 0) { port = ntohs(sport); @@ -2032,35 +2780,35 @@ natinfo_t *ni; } } else if (((np->in_redir & NAT_MAPBLK) == 0) && - (flags & IPN_TCPUDPICMP) && (np->in_pnext != 0)) { + (flags & IPN_TCPUDPICMP) && (np->in_spnext != 0)) { /* * Standard port translation. Select next port. */ if (np->in_flags & IPN_SEQUENTIAL) { - port = np->in_pnext; + port = np->in_spnext; } else { - port = ipf_random() % (ntohs(np->in_pmax) - - ntohs(np->in_pmin)); - port += ntohs(np->in_pmin); + port = ipf_random() % (np->in_spmax - + np->in_spmin + 1); + port += np->in_spmin; } port = htons(port); - np->in_pnext++; + np->in_spnext++; - if (np->in_pnext > ntohs(np->in_pmax)) { - np->in_pnext = ntohs(np->in_pmin); - if (np->in_outmsk != 0xffffffff) - np->in_nip++; + if (np->in_spnext > np->in_spmax) { + np->in_spnext = np->in_spmin; + if (np->in_nsrcmsk != 0xffffffff) + np->in_snip++; } } - if (np->in_flags & IPN_IPRANGE) { - if (np->in_nip > ntohl(np->in_outmsk)) - np->in_nip = ntohl(np->in_outip); + if (np->in_flags & IPN_SIPRANGE) { + if (np->in_snip > ntohl(np->in_nsrcmsk)) + np->in_snip = ntohl(np->in_nsrcaddr); } else { - if ((np->in_outmsk != 0xffffffff) && - ((np->in_nip + 1) & ntohl(np->in_outmsk)) > - ntohl(np->in_outip)) - np->in_nip = ntohl(np->in_outip) + 1; + if ((np->in_nsrcmsk != 0xffffffff) && + ((np->in_snip + 1) & ntohl(np->in_nsrcmsk)) > + ntohl(np->in_nsrcaddr)) + np->in_snip = ntohl(np->in_nsrcaddr) + 1; } if ((port == 0) && (flags & (IPN_TCPUDPICMP|IPN_ICMPQUERY))) @@ -2080,9 +2828,9 @@ natinfo_t *ni; sp = fin->fin_data[0]; dp = fin->fin_data[1]; fin->fin_data[0] = fin->fin_data[1]; - fin->fin_data[1] = htons(port); - natl = nat_inlookup(fin, flags & ~(SI_WILDP|NAT_SEARCH), - (u_int)fin->fin_p, fin->fin_dst, inb); + fin->fin_data[1] = ntohs(port); + natl = ipf_nat_inlookup(fin, flags & ~(SI_WILDP|NAT_SEARCH), + (u_int)fin->fin_p, fin->fin_dst, inb); fin->fin_data[0] = sp; fin->fin_data[1] = dp; @@ -2091,64 +2839,41 @@ natinfo_t *ni; * start ? */ if ((natl != NULL) && - (np->in_pnext != 0) && (st_port == np->in_pnext) && - (np->in_nip != 0) && (st_ip == np->in_nip)) + (np->in_spnext != 0) && (st_port == np->in_spnext) && + (np->in_snip != 0) && (st_ip == np->in_snip)) { + NBUMPSIDED(1, ns_wrap); return -1; + } l++; } while (natl != NULL); - if (np->in_space > 0) - np->in_space--; - /* Setup the NAT table */ - nat->nat_inip = fin->fin_src; - nat->nat_outip.s_addr = htonl(in.s_addr); - nat->nat_oip = fin->fin_dst; + nat->nat_osrcip = fin->fin_src; + nat->nat_nsrcaddr = htonl(in.s_addr); + nat->nat_odstip = fin->fin_dst; + nat->nat_ndstip = fin->fin_dst; if (nat->nat_hm == NULL) - nat->nat_hm = nat_hostmap(np, fin->fin_src, fin->fin_dst, - nat->nat_outip, 0); - - /* - * The ICMP checksum does not have a pseudo header containing - * the IP addresses - */ - ni->nai_sum1 = LONG_SUM(ntohl(fin->fin_saddr)); - ni->nai_sum2 = LONG_SUM(in.s_addr); - if ((flags & IPN_TCPUDP)) { - ni->nai_sum1 += ntohs(sport); - ni->nai_sum2 += ntohs(port); - } + nat->nat_hm = ipf_nat_hostmap(softn, np, fin->fin_src, + fin->fin_dst, nat->nat_nsrcip, + 0); if (flags & IPN_TCPUDP) { - nat->nat_inport = sport; - nat->nat_outport = port; /* sport */ - nat->nat_oport = dport; + nat->nat_osport = sport; + nat->nat_nsport = port; /* sport */ + nat->nat_odport = dport; + nat->nat_ndport = dport; ((tcphdr_t *)fin->fin_dp)->th_sport = port; } else if (flags & IPN_ICMPQUERY) { + nat->nat_oicmpid = fin->fin_data[1]; ((icmphdr_t *)fin->fin_dp)->icmp_id = port; - nat->nat_inport = port; - nat->nat_outport = port; - } else if (fin->fin_p == IPPROTO_GRE) { -#if 0 - nat->nat_gre.gs_flags = ((grehdr_t *)fin->fin_dp)->gr_flags; - if (GRE_REV(nat->nat_gre.gs_flags) == 1) { - nat->nat_oport = 0;/*fin->fin_data[1];*/ - nat->nat_inport = 0;/*fin->fin_data[0];*/ - nat->nat_outport = 0;/*fin->fin_data[0];*/ - nat->nat_call[0] = fin->fin_data[0]; - nat->nat_call[1] = fin->fin_data[0]; - } -#endif + nat->nat_nicmpid = port; } - ni->nai_ip.s_addr = in.s_addr; - ni->nai_port = port; - ni->nai_nport = dport; return 0; } /* ------------------------------------------------------------------------ */ -/* Function: nat_newrdr */ +/* Function: ipf_nat_newrdr */ /* Returns: int - -1 == error, 0 == success (no move), 1 == success and */ /* allow rule to be moved if IPN_ROUNDR is set. */ /* Parameters: fin(I) - pointer to packet information */ @@ -2159,11 +2884,14 @@ natinfo_t *ni; /* ni.nai_ip is passed in uninitialised and must be set, in host byte order,*/ /* to the new IP address for the translation. */ /* ------------------------------------------------------------------------ */ -static INLINE int nat_newrdr(fin, nat, ni) -fr_info_t *fin; -nat_t *nat; -natinfo_t *ni; +static int +ipf_nat_newrdr(fin, nat, ni) + fr_info_t *fin; + nat_t *nat; + natinfo_t *ni; { + ipf_main_softc_t *softc = fin->fin_main_soft; + ipf_nat_softc_t *softn = softc->ipf_nat_soft; u_short nport, dport, sport; struct in_addr in, inb; u_short sp, dp; @@ -2177,9 +2905,18 @@ natinfo_t *ni; hm = NULL; in.s_addr = 0; np = ni->nai_np; - flags = ni->nai_flags; - sport = ni->nai_sport; - dport = ni->nai_dport; + flags = nat->nat_flags; + + if (flags & IPN_ICMPQUERY) { + dport = fin->fin_data[1]; + sport = 0; + } else { + sport = htons(fin->fin_data[0]); + dport = htons(fin->fin_data[1]); + } + + /* TRACE sport, dport */ + /* * If the matching rule has IPN_STICKY set, then we want to have the @@ -2190,13 +2927,14 @@ natinfo_t *ni; */ if (((np->in_flags & (IPN_ROUNDR|IPN_SPLIT)) != 0) && ((np->in_flags & IPN_STICKY) != 0)) { - hm = nat_hostmap(NULL, fin->fin_src, fin->fin_dst, in, - (u_32_t)dport); + hm = ipf_nat_hostmap(softn, NULL, fin->fin_src, fin->fin_dst, + in, (u_32_t)dport); if (hm != NULL) { - in.s_addr = ntohl(hm->hm_mapip.s_addr); + in.s_addr = ntohl(hm->hm_ndstip.s_addr); np = hm->hm_ipnat; ni->nai_np = np; move = 0; + ipf_nat_hostmapdel(softc, &hm); } } @@ -2207,53 +2945,60 @@ natinfo_t *ni; * internal port. */ if (np->in_flags & IPN_SPLIT) { - in.s_addr = np->in_nip; + in.s_addr = np->in_dnip; if ((np->in_flags & (IPN_ROUNDR|IPN_STICKY)) == IPN_STICKY) { - hm = nat_hostmap(NULL, fin->fin_src, fin->fin_dst, - in, (u_32_t)dport); + hm = ipf_nat_hostmap(softn, NULL, fin->fin_src, + fin->fin_dst, in, (u_32_t)dport); if (hm != NULL) { - in.s_addr = hm->hm_mapip.s_addr; + in.s_addr = hm->hm_ndstip.s_addr; move = 0; } } if (hm == NULL || hm->hm_ref == 1) { - if (np->in_inip == htonl(in.s_addr)) { - np->in_nip = ntohl(np->in_inmsk); + if (np->in_ndstaddr == htonl(in.s_addr)) { + np->in_dnip = ntohl(np->in_ndstmsk); move = 0; } else { - np->in_nip = ntohl(np->in_inip); + np->in_dnip = ntohl(np->in_ndstaddr); } } + if (hm != NULL) + ipf_nat_hostmapdel(softc, &hm); + + } else if ((np->in_ndstaddr == 0) && (np->in_ndstmsk == 0xffffffff)) { + i6addr_t in6; - } else if ((np->in_inip == 0) && (np->in_inmsk == 0xffffffff)) { /* * 0/32 - use the interface's IP address. */ - if (fr_ifpaddr(4, FRI_NORMAL, fin->fin_ifp, &in, NULL) == -1) + if (ipf_ifpaddr(softc, 4, FRI_NORMAL, fin->fin_ifp, + &in6, NULL) == -1) { + NBUMPSIDEX(0, ns_new_ifpaddr, ns_new_ifpaddr_2); return -1; - in.s_addr = ntohl(in.s_addr); + } + in.s_addr = ntohl(in6.in4.s_addr); - } else if ((np->in_inip == 0) && (np->in_inmsk== 0)) { + } else if ((np->in_ndstaddr == 0) && (np->in_ndstmsk== 0)) { /* * 0/0 - use the original destination address/port. */ in.s_addr = ntohl(fin->fin_daddr); } else if (np->in_redir == NAT_BIMAP && - np->in_inmsk == np->in_outmsk) { + np->in_ndstmsk == np->in_odstmsk) { /* * map the address block in a 1:1 fashion */ - in.s_addr = np->in_inip; - in.s_addr |= fin->fin_daddr & ~np->in_inmsk; + in.s_addr = np->in_ndstaddr; + in.s_addr |= fin->fin_daddr & ~np->in_ndstmsk; in.s_addr = ntohl(in.s_addr); } else { - in.s_addr = ntohl(np->in_inip); + in.s_addr = ntohl(np->in_ndstaddr); } - if ((np->in_pnext == 0) || ((flags & NAT_NOTRULEPORT) != 0)) + if ((np->in_dpnext == 0) || ((flags & NAT_NOTRULEPORT) != 0)) nport = dport; else { /* @@ -2261,12 +3006,15 @@ natinfo_t *ni; * pmin == pmax, the gain is not significant. */ if (((np->in_flags & IPN_FIXEDDPORT) == 0) && - (np->in_pmin != np->in_pmax)) { - nport = ntohs(dport) - ntohs(np->in_pmin) + - ntohs(np->in_pnext); + (np->in_odport != np->in_dtop)) { + nport = ntohs(dport) - np->in_odport + np->in_dpmax; nport = htons(nport); - } else - nport = np->in_pnext; + } else { + nport = htons(np->in_dpnext); + np->in_dpnext++; + if (np->in_dpnext > np->in_dpmax) + np->in_dpnext = np->in_dpmin; + } } /* @@ -2275,8 +3023,10 @@ natinfo_t *ni; * setup any translation for this either. */ if (in.s_addr == 0) { - if (nport == dport) + if (nport == dport) { + NBUMPSIDED(0, ns_xlate_null); return -1; + } in.s_addr = ntohl(fin->fin_daddr); } @@ -2290,54 +3040,41 @@ natinfo_t *ni; dp = fin->fin_data[1]; fin->fin_data[1] = fin->fin_data[0]; fin->fin_data[0] = ntohs(nport); - natl = nat_outlookup(fin, flags & ~(SI_WILDP|NAT_SEARCH), + natl = ipf_nat_outlookup(fin, flags & ~(SI_WILDP|NAT_SEARCH), (u_int)fin->fin_p, inb, fin->fin_src); fin->fin_data[0] = sp; fin->fin_data[1] = dp; - if (natl != NULL) + if (natl != NULL) { + DT2(ns_new_xlate_exists, fr_info_t *, fin, nat_t *, natl); + NBUMPSIDE(0, ns_xlate_exists); return -1; + } - nat->nat_inip.s_addr = htonl(in.s_addr); - nat->nat_outip = fin->fin_dst; - nat->nat_oip = fin->fin_src; + nat->nat_ndstaddr = htonl(in.s_addr); + nat->nat_odstip = fin->fin_dst; + nat->nat_nsrcip = fin->fin_src; + nat->nat_osrcip = fin->fin_src; if ((nat->nat_hm == NULL) && ((np->in_flags & IPN_STICKY) != 0)) - nat->nat_hm = nat_hostmap(np, fin->fin_src, fin->fin_dst, in, - (u_32_t)dport); - - ni->nai_sum1 = LONG_SUM(ntohl(fin->fin_daddr)) + ntohs(dport); - ni->nai_sum2 = LONG_SUM(in.s_addr) + ntohs(nport); - - ni->nai_ip.s_addr = in.s_addr; - ni->nai_nport = nport; - ni->nai_port = sport; + nat->nat_hm = ipf_nat_hostmap(softn, np, fin->fin_src, + fin->fin_dst, in, (u_32_t)dport); if (flags & IPN_TCPUDP) { - nat->nat_inport = nport; - nat->nat_outport = dport; - nat->nat_oport = sport; + nat->nat_odport = dport; + nat->nat_ndport = nport; + nat->nat_osport = sport; + nat->nat_nsport = sport; ((tcphdr_t *)fin->fin_dp)->th_dport = nport; } else if (flags & IPN_ICMPQUERY) { + nat->nat_oicmpid = fin->fin_data[1]; ((icmphdr_t *)fin->fin_dp)->icmp_id = nport; - nat->nat_inport = nport; - nat->nat_outport = nport; - } else if (fin->fin_p == IPPROTO_GRE) { -#if 0 - nat->nat_gre.gs_flags = ((grehdr_t *)fin->fin_dp)->gr_flags; - if (GRE_REV(nat->nat_gre.gs_flags) == 1) { - nat->nat_call[0] = fin->fin_data[0]; - nat->nat_call[1] = fin->fin_data[1]; - nat->nat_oport = 0; /*fin->fin_data[0];*/ - nat->nat_inport = 0; /*fin->fin_data[1];*/ - nat->nat_outport = 0; /*fin->fin_data[1];*/ - } -#endif + nat->nat_nicmpid = nport; } return move; } /* ------------------------------------------------------------------------ */ -/* Function: nat_new */ +/* Function: ipf_nat_add */ /* Returns: nat_t* - NULL == failure to create new NAT structure, */ /* else pointer to new NAT structure */ /* Parameters: fin(I) - pointer to packet information */ @@ -2358,29 +3095,32 @@ natinfo_t *ni; /* NOTE: natsave should NOT be used top point back to an ipstate_t struct */ /* as it can result in memory being corrupted. */ /* ------------------------------------------------------------------------ */ -nat_t *nat_new(fin, np, natsave, flags, direction) -fr_info_t *fin; -ipnat_t *np; -nat_t **natsave; -u_int flags; -int direction; +nat_t * +ipf_nat_add(fin, np, natsave, flags, direction) + fr_info_t *fin; + ipnat_t *np; + nat_t **natsave; + u_int flags; + int direction; { - u_short port = 0, sport = 0, dport = 0, nport = 0; - tcphdr_t *tcp = NULL; + ipf_main_softc_t *softc = fin->fin_main_soft; + ipf_nat_softc_t *softn = softc->ipf_nat_soft; hostmap_t *hm = NULL; - struct in_addr in; nat_t *nat, *natl; + natstat_t *nsp; u_int nflags; natinfo_t ni; - u_32_t sumd; int move; -#if SOLARIS && defined(_KERNEL) && (SOLARIS2 >= 6) && defined(ICK_M_CTL_MAGIC) - qpktinfo_t *qpi = fin->fin_qpi; -#endif - if (nat_stats.ns_inuse >= ipf_nattable_max) { - nat_stats.ns_memfail++; - fr_nat_doflush = 1; + nsp = &softn->ipf_nat_stats; + + if ((nsp->ns_active * 100 / softn->ipf_nat_table_max) > + softn->ipf_nat_table_wm_high) { + softn->ipf_nat_doflush = 1; + } + + if (nsp->ns_active >= softn->ipf_nat_table_max) { + NBUMPSIDED(fin->fin_out, ns_table_max); return NULL; } @@ -2389,34 +3129,29 @@ int direction; nflags &= NAT_FROMRULE; ni.nai_np = np; - ni.nai_nflags = nflags; - ni.nai_flags = flags; ni.nai_dport = 0; ni.nai_sport = 0; /* Give me a new nat */ KMALLOC(nat, nat_t *); if (nat == NULL) { - nat_stats.ns_memfail++; + NBUMPSIDED(fin->fin_out, ns_memfail); /* * Try to automatically tune the max # of entries in the * table allowed to be less than what will cause kmem_alloc() * to fail and try to eliminate panics due to out of memory * conditions arising. */ - if (ipf_nattable_max > ipf_nattable_sz) { - ipf_nattable_max = nat_stats.ns_inuse - 100; - printf("ipf_nattable_max reduced to %d\n", - ipf_nattable_max); + if ((softn->ipf_nat_table_max > softn->ipf_nat_table_sz) && + (nsp->ns_active > 100)) { + softn->ipf_nat_table_max = nsp->ns_active - 100; + printf("table_max reduced to %d\n", + softn->ipf_nat_table_max); } return NULL; } - if (flags & IPN_TCPUDP) { - tcp = fin->fin_dp; - ni.nai_sport = htons(fin->fin_sport); - ni.nai_dport = htons(fin->fin_dport); - } else if (flags & IPN_ICMPQUERY) { + if (flags & IPN_ICMPQUERY) { /* * In the ICMP query NAT code, we translate the ICMP id fields * to make them unique. This is indepedent of the ICMP type @@ -2430,28 +3165,34 @@ int direction; * the concept of source port. We overlay sport, so we can * maximally reuse the existing code. */ - ni.nai_sport = ((icmphdr_t *)fin->fin_dp)->icmp_id; - ni.nai_dport = ni.nai_sport; + ni.nai_sport = fin->fin_data[1]; + ni.nai_dport = 0; } bzero((char *)nat, sizeof(*nat)); nat->nat_flags = flags; nat->nat_redir = np->in_redir; - - if ((flags & NAT_SLAVE) == 0) { - MUTEX_ENTER(&ipf_nat_new); - } + nat->nat_dir = direction; + nat->nat_pr[0] = fin->fin_p; + nat->nat_pr[1] = fin->fin_p; /* - * Search the current table for a match. + * Search the current table for a match and create a new mapping + * if there is none found. */ - if (direction == NAT_OUTBOUND) { + if (np->in_redir & NAT_DIVERTUDP) { + move = ipf_nat_newdivert(fin, nat, &ni); + + } else if (np->in_redir & NAT_REWRITE) { + move = ipf_nat_newrewrite(fin, nat, &ni); + + } else if (direction == NAT_OUTBOUND) { /* * We can now arrange to call this for the same connection * because ipf_nat_new doesn't protect the code path into * this function. */ - natl = nat_outlookup(fin, nflags, (u_int)fin->fin_p, + natl = ipf_nat_outlookup(fin, nflags, (u_int)fin->fin_p, fin->fin_src, fin->fin_dst); if (natl != NULL) { KFREE(nat); @@ -2459,166 +3200,184 @@ int direction; goto done; } - move = nat_newmap(fin, nat, &ni); - if (move == -1) - goto badnat; - - np = ni.nai_np; - in = ni.nai_ip; + move = ipf_nat_newmap(fin, nat, &ni); } else { /* - * NAT_INBOUND is used only for redirects rules + * NAT_INBOUND is used for redirects rules */ - natl = nat_inlookup(fin, nflags, (u_int)fin->fin_p, - fin->fin_src, fin->fin_dst); + natl = ipf_nat_inlookup(fin, nflags, (u_int)fin->fin_p, + fin->fin_src, fin->fin_dst); if (natl != NULL) { KFREE(nat); nat = natl; goto done; } - move = nat_newrdr(fin, nat, &ni); - if (move == -1) + move = ipf_nat_newrdr(fin, nat, &ni); + } + if (move == -1) + goto badnat; + + np = ni.nai_np; + + nat->nat_mssclamp = np->in_mssclamp; + nat->nat_me = natsave; + nat->nat_fr = fin->fin_fr; + nat->nat_rev = fin->fin_rev; + nat->nat_ptr = np; + nat->nat_dlocal = np->in_dlocal; + + if ((np->in_apr != NULL) && ((nat->nat_flags & NAT_SLAVE) == 0)) { + if (ipf_proxy_new(fin, nat) == -1) { + NBUMPSIDED(fin->fin_out, ns_appr_fail); goto badnat; - - np = ni.nai_np; - in = ni.nai_ip; - } - port = ni.nai_port; - nport = ni.nai_nport; - - if ((move == 1) && (np->in_flags & IPN_ROUNDR)) { - if (np->in_redir == NAT_REDIRECT) { - nat_delrdr(np); - nat_addrdr(np); - } else if (np->in_redir == NAT_MAP) { - nat_delnat(np); - nat_addnat(np); } } - if (flags & IPN_TCPUDP) { - sport = ni.nai_sport; - dport = ni.nai_dport; - } else if (flags & IPN_ICMPQUERY) { - sport = ni.nai_sport; - dport = 0; + nat->nat_ifps[0] = np->in_ifps[0]; + if (np->in_ifps[0] != NULL) { + COPYIFNAME(np->in_v[0], np->in_ifps[0], nat->nat_ifnames[0]); } - CALC_SUMD(ni.nai_sum1, ni.nai_sum2, sumd); - nat->nat_sumd[0] = (sumd & 0xffff) + (sumd >> 16); -#if SOLARIS && defined(_KERNEL) && (SOLARIS2 >= 6) && defined(ICK_M_CTL_MAGIC) - if ((flags & IPN_TCP) && dohwcksum && - (((ill_t *)qpi->qpi_ill)->ill_ick.ick_magic == ICK_M_CTL_MAGIC)) { - if (direction == NAT_OUTBOUND) - ni.nai_sum1 = LONG_SUM(in.s_addr); - else - ni.nai_sum1 = LONG_SUM(ntohl(fin->fin_saddr)); - ni.nai_sum1 += LONG_SUM(ntohl(fin->fin_daddr)); - ni.nai_sum1 += 30; - ni.nai_sum1 = (ni.nai_sum1 & 0xffff) + (ni.nai_sum1 >> 16); - nat->nat_sumd[1] = NAT_HW_CKSUM|(ni.nai_sum1 & 0xffff); - } else -#endif - nat->nat_sumd[1] = nat->nat_sumd[0]; - - if ((flags & IPN_TCPUDPICMP) && ((sport != port) || (dport != nport))) { - if (direction == NAT_OUTBOUND) - ni.nai_sum1 = LONG_SUM(ntohl(fin->fin_saddr)); - else - ni.nai_sum1 = LONG_SUM(ntohl(fin->fin_daddr)); - - ni.nai_sum2 = LONG_SUM(in.s_addr); - - CALC_SUMD(ni.nai_sum1, ni.nai_sum2, sumd); - nat->nat_ipsumd = (sumd & 0xffff) + (sumd >> 16); - } else { - nat->nat_ipsumd = nat->nat_sumd[0]; - if (!(flags & IPN_TCPUDPICMP)) { - nat->nat_sumd[0] = 0; - nat->nat_sumd[1] = 0; - } + nat->nat_ifps[1] = np->in_ifps[1]; + if (np->in_ifps[1] != NULL) { + COPYIFNAME(np->in_v[1], np->in_ifps[1], nat->nat_ifnames[1]); } - if (nat_finalise(fin, nat, &ni, tcp, natsave, direction) == -1) { - fr_nat_doflush = 1; + if (ipf_nat_finalise(fin, nat) == -1) { goto badnat; } + + np->in_use++; + + if ((move == 1) && (np->in_flags & IPN_ROUNDR)) { + if ((np->in_redir & (NAT_REDIRECT|NAT_MAP)) == NAT_REDIRECT) { + ipf_nat_delrdr(softn, np); + ipf_nat_addrdr(softn, np); + } else if ((np->in_redir & (NAT_REDIRECT|NAT_MAP)) == NAT_MAP) { + ipf_nat_delmap(softn, np); + ipf_nat_addmap(softn, np); + } + } + if (flags & SI_WILDP) - nat_stats.ns_wilds++; - fin->fin_flx |= FI_NEWNAT; + nsp->ns_wilds++; + nsp->ns_proto[nat->nat_pr[0]]++; + goto done; badnat: - nat_stats.ns_badnat++; + DT2(ns_badnatnew, fr_info_t *, fin, nat_t *, nat); + NBUMPSIDE(fin->fin_out, ns_badnatnew); if ((hm = nat->nat_hm) != NULL) - fr_hostmapdel(&hm); + ipf_nat_hostmapdel(softc, &hm); KFREE(nat); nat = NULL; done: - if ((flags & NAT_SLAVE) == 0) { - MUTEX_EXIT(&ipf_nat_new); - } + if (nat != NULL && np != NULL) + np->in_hits++; + if (natsave != NULL) + *natsave = nat; return nat; } /* ------------------------------------------------------------------------ */ -/* Function: nat_finalise */ +/* Function: ipf_nat_finalise */ /* Returns: int - 0 == sucess, -1 == failure */ /* Parameters: fin(I) - pointer to packet information */ /* nat(I) - pointer to NAT entry */ -/* ni(I) - pointer to structure with misc. information needed */ -/* to create new NAT entry. */ /* Write Lock: ipf_nat */ /* */ /* This is the tail end of constructing a new NAT entry and is the same */ /* for both IPv4 and IPv6. */ /* ------------------------------------------------------------------------ */ /*ARGSUSED*/ -static int nat_finalise(fin, nat, ni, tcp, natsave, direction) -fr_info_t *fin; -nat_t *nat; -natinfo_t *ni; -tcphdr_t *tcp; -nat_t **natsave; -int direction; +static int +ipf_nat_finalise(fin, nat) + fr_info_t *fin; + nat_t *nat; { + ipf_main_softc_t *softc = fin->fin_main_soft; + ipf_nat_softc_t *softn = softc->ipf_nat_soft; + u_32_t sum1, sum2, sumd; frentry_t *fr; - ipnat_t *np; - - np = ni->nai_np; - - if (np->in_ifps[0] != NULL) { - COPYIFNAME(4, np->in_ifps[0], nat->nat_ifnames[0]); - } - if (np->in_ifps[1] != NULL) { - COPYIFNAME(4, np->in_ifps[1], nat->nat_ifnames[1]); - } -#ifdef IPFILTER_SYNC - if ((nat->nat_flags & SI_CLONE) == 0) - nat->nat_sync = ipfsync_new(SMC_NAT, fin, nat); + u_32_t flags; +#if SOLARIS && defined(_KERNEL) && (SOLARIS2 >= 6) && defined(ICK_M_CTL_MAGIC) + qpktinfo_t *qpi = fin->fin_qpi; #endif - nat->nat_me = natsave; - nat->nat_dir = direction; - nat->nat_ifps[0] = np->in_ifps[0]; - nat->nat_ifps[1] = np->in_ifps[1]; - nat->nat_ptr = np; - nat->nat_p = fin->fin_p; - nat->nat_mssclamp = np->in_mssclamp; - if (nat->nat_p == IPPROTO_TCP) - nat->nat_seqnext[0] = ntohl(tcp->th_seq); + flags = nat->nat_flags; - if ((np->in_apr != NULL) && ((ni->nai_flags & NAT_SLAVE) == 0)) - if (appr_new(fin, nat) == -1) - return -1; + switch (nat->nat_pr[0]) + { + case IPPROTO_ICMP : + sum1 = LONG_SUM(ntohs(nat->nat_oicmpid)); + sum2 = LONG_SUM(ntohs(nat->nat_nicmpid)); + CALC_SUMD(sum1, sum2, sumd); + nat->nat_sumd[0] = (sumd & 0xffff) + (sumd >> 16); - if (nat_insert(nat, fin->fin_rev) == 0) { - if (nat_logging) - nat_log(nat, (u_int)np->in_redir); - np->in_use++; - fr = fin->fin_fr; - nat->nat_fr = fr; + break; + + default : + sum1 = LONG_SUM(ntohl(nat->nat_osrcaddr) + \ + ntohs(nat->nat_osport)); + sum2 = LONG_SUM(ntohl(nat->nat_nsrcaddr) + \ + ntohs(nat->nat_nsport)); + CALC_SUMD(sum1, sum2, sumd); + nat->nat_sumd[0] = (sumd & 0xffff) + (sumd >> 16); + + sum1 = LONG_SUM(ntohl(nat->nat_odstaddr) + \ + ntohs(nat->nat_odport)); + sum2 = LONG_SUM(ntohl(nat->nat_ndstaddr) + \ + ntohs(nat->nat_ndport)); + CALC_SUMD(sum1, sum2, sumd); + nat->nat_sumd[0] += (sumd & 0xffff) + (sumd >> 16); + break; + } + + /* + * Compute the partial checksum, just in case. + * This is only ever placed into outbound packets so care needs + * to be taken over which pair of addresses are used. + */ + if (nat->nat_dir == NAT_OUTBOUND) { + sum1 = LONG_SUM(ntohl(nat->nat_nsrcaddr)); + sum1 += LONG_SUM(ntohl(nat->nat_ndstaddr)); + } else { + sum1 = LONG_SUM(ntohl(nat->nat_osrcaddr)); + sum1 += LONG_SUM(ntohl(nat->nat_odstaddr)); + } + sum1 += nat->nat_pr[1]; + nat->nat_sumd[1] = (sum1 & 0xffff) + (sum1 >> 16); + + sum1 = LONG_SUM(ntohl(nat->nat_osrcaddr)); + sum2 = LONG_SUM(ntohl(nat->nat_nsrcaddr)); + CALC_SUMD(sum1, sum2, sumd); + nat->nat_ipsumd = (sumd & 0xffff) + (sumd >> 16); + + sum1 = LONG_SUM(ntohl(nat->nat_odstaddr)); + sum2 = LONG_SUM(ntohl(nat->nat_ndstaddr)); + CALC_SUMD(sum1, sum2, sumd); + nat->nat_ipsumd += (sumd & 0xffff) + (sumd >> 16); + + nat->nat_v[0] = 4; + nat->nat_v[1] = 4; + + if ((nat->nat_ifps[0] != NULL) && (nat->nat_ifps[0] != (void *)-1)) { + nat->nat_mtu[0] = GETIFMTU_4(nat->nat_ifps[0]); + } + + if ((nat->nat_ifps[1] != NULL) && (nat->nat_ifps[1] != (void *)-1)) { + nat->nat_mtu[1] = GETIFMTU_4(nat->nat_ifps[1]); + } + + if ((nat->nat_flags & SI_CLONE) == 0) + nat->nat_sync = ipf_sync_new(softc, SMC_NAT, fin, nat); + + if (ipf_nat_insert(softc, softn, nat) == 0) { + if (softn->ipf_nat_logging) + ipf_nat_log(softc, softn, nat, NL_NEW); + fr = nat->nat_fr; if (fr != NULL) { MUTEX_ENTER(&fr->fr_lock); fr->fr_ref++; @@ -2627,112 +3386,224 @@ int direction; return 0; } + NBUMPSIDED(fin->fin_out, ns_unfinalised); /* * nat_insert failed, so cleanup time... */ + if (nat->nat_sync != NULL) + ipf_sync_del_nat(softc->ipf_sync_soft, nat->nat_sync); return -1; } /* ------------------------------------------------------------------------ */ -/* Function: nat_insert */ -/* Returns: int - 0 == sucess, -1 == failure */ -/* Parameters: nat(I) - pointer to NAT structure */ -/* rev(I) - flag indicating forward/reverse direction of packet */ -/* Write Lock: ipf_nat */ +/* Function: ipf_nat_insert */ +/* Returns: int - 0 == sucess, -1 == failure */ +/* Parameters: softc(I) - pointer to soft context main structure */ +/* softn(I) - pointer to NAT context structure */ +/* nat(I) - pointer to NAT structure */ +/* Write Lock: ipf_nat */ /* */ /* Insert a NAT entry into the hash tables for searching and add it to the */ /* list of active NAT entries. Adjust global counters when complete. */ /* ------------------------------------------------------------------------ */ -int nat_insert(nat, rev) -nat_t *nat; -int rev; +int +ipf_nat_insert(softc, softn, nat) + ipf_main_softc_t *softc; + ipf_nat_softc_t *softn; + nat_t *nat; { - u_int hv1, hv2; - nat_t **natp; + u_int hv0, hv1; + u_int sp, dp; + ipnat_t *in; /* * Try and return an error as early as possible, so calculate the hash * entry numbers first and then proceed. */ if ((nat->nat_flags & (SI_W_SPORT|SI_W_DPORT)) == 0) { - hv1 = NAT_HASH_FN(nat->nat_inip.s_addr, nat->nat_inport, - 0xffffffff); - hv1 = NAT_HASH_FN(nat->nat_oip.s_addr, hv1 + nat->nat_oport, - ipf_nattable_sz); - hv2 = NAT_HASH_FN(nat->nat_outip.s_addr, nat->nat_outport, - 0xffffffff); - hv2 = NAT_HASH_FN(nat->nat_oip.s_addr, hv2 + nat->nat_oport, - ipf_nattable_sz); + if ((nat->nat_flags & IPN_TCPUDP) != 0) { + sp = nat->nat_osport; + dp = nat->nat_odport; + } else if ((nat->nat_flags & IPN_ICMPQUERY) != 0) { + sp = 0; + dp = nat->nat_oicmpid; + } else { + sp = 0; + dp = 0; + } + hv0 = NAT_HASH_FN(nat->nat_osrcaddr, sp, 0xffffffff); + hv0 = NAT_HASH_FN(nat->nat_odstaddr, hv0 + dp, 0xffffffff); + /* + * TRACE nat_osrcaddr, nat_osport, nat_odstaddr, + * nat_odport, hv0 + */ + + if ((nat->nat_flags & IPN_TCPUDP) != 0) { + sp = nat->nat_nsport; + dp = nat->nat_ndport; + } else if ((nat->nat_flags & IPN_ICMPQUERY) != 0) { + sp = 0; + dp = nat->nat_nicmpid; + } else { + sp = 0; + dp = 0; + } + hv1 = NAT_HASH_FN(nat->nat_nsrcaddr, sp, 0xffffffff); + hv1 = NAT_HASH_FN(nat->nat_ndstaddr, hv1 + dp, 0xffffffff); + /* + * TRACE nat_nsrcaddr, nat_nsport, nat_ndstaddr, + * nat_ndport, hv1 + */ } else { - hv1 = NAT_HASH_FN(nat->nat_inip.s_addr, 0, 0xffffffff); - hv1 = NAT_HASH_FN(nat->nat_oip.s_addr, hv1, ipf_nattable_sz); - hv2 = NAT_HASH_FN(nat->nat_outip.s_addr, 0, 0xffffffff); - hv2 = NAT_HASH_FN(nat->nat_oip.s_addr, hv2, ipf_nattable_sz); + hv0 = NAT_HASH_FN(nat->nat_osrcaddr, 0, 0xffffffff); + hv0 = NAT_HASH_FN(nat->nat_odstaddr, hv0, 0xffffffff); + /* TRACE nat_osrcaddr, nat_odstaddr, hv0 */ + + hv1 = NAT_HASH_FN(nat->nat_nsrcaddr, 0, 0xffffffff); + hv1 = NAT_HASH_FN(nat->nat_ndstaddr, hv1, 0xffffffff); + /* TRACE nat_nsrcaddr, nat_ndstaddr, hv1 */ } - if (nat_stats.ns_bucketlen[0][hv1] >= fr_nat_maxbucket || - nat_stats.ns_bucketlen[1][hv2] >= fr_nat_maxbucket) { - return -1; - } - - nat->nat_hv[0] = hv1; - nat->nat_hv[1] = hv2; + nat->nat_hv[0] = hv0; + nat->nat_hv[1] = hv1; MUTEX_INIT(&nat->nat_lock, "nat entry lock"); - nat->nat_rev = rev; - nat->nat_ref = 1; - nat->nat_bytes[0] = 0; - nat->nat_pkts[0] = 0; - nat->nat_bytes[1] = 0; - nat->nat_pkts[1] = 0; + in = nat->nat_ptr; + nat->nat_ref = nat->nat_me ? 2 : 1; nat->nat_ifnames[0][LIFNAMSIZ - 1] = '\0'; - nat->nat_ifps[0] = fr_resolvenic(nat->nat_ifnames[0], 4); + nat->nat_ifps[0] = ipf_resolvenic(softc, nat->nat_ifnames[0], 4); if (nat->nat_ifnames[1][0] != '\0') { nat->nat_ifnames[1][LIFNAMSIZ - 1] = '\0'; - nat->nat_ifps[1] = fr_resolvenic(nat->nat_ifnames[1], 4); - } else { - (void) strncpy(nat->nat_ifnames[1], nat->nat_ifnames[0], - LIFNAMSIZ); - nat->nat_ifnames[1][LIFNAMSIZ - 1] = '\0'; - nat->nat_ifps[1] = nat->nat_ifps[0]; + nat->nat_ifps[1] = ipf_resolvenic(softc, + nat->nat_ifnames[1], 4); + } else if (in->in_ifnames[1] != -1) { + char *name; + + name = in->in_names + in->in_ifnames[1]; + if (name[1] != '\0' && name[0] != '-' && name[0] != '*') { + (void) strncpy(nat->nat_ifnames[1], + nat->nat_ifnames[0], LIFNAMSIZ); + nat->nat_ifnames[1][LIFNAMSIZ - 1] = '\0'; + nat->nat_ifps[1] = nat->nat_ifps[0]; + } + } + if ((nat->nat_ifps[0] != NULL) && (nat->nat_ifps[0] != (void *)-1)) { + nat->nat_mtu[0] = GETIFMTU_4(nat->nat_ifps[0]); + } + if ((nat->nat_ifps[1] != NULL) && (nat->nat_ifps[1] != (void *)-1)) { + nat->nat_mtu[1] = GETIFMTU_4(nat->nat_ifps[1]); } - nat->nat_next = nat_instances; - nat->nat_pnext = &nat_instances; - if (nat_instances) - nat_instances->nat_pnext = &nat->nat_next; - nat_instances = nat; + return ipf_nat_hashtab_add(softc, softn, nat); +} - natp = &nat_table[0][hv1]; - if (*natp) - (*natp)->nat_phnext[0] = &nat->nat_hnext[0]; + +/* ------------------------------------------------------------------------ */ +/* Function: ipf_nat_hashtab_add */ +/* Parameters: softc(I) - pointer to soft context main structure */ +/* softn(I) - pointer to NAT context structure */ +/* nat(I) - pointer to NAT structure */ +/* */ +/* Handle the insertion of a NAT entry into the table/list. */ +/* ------------------------------------------------------------------------ */ +int +ipf_nat_hashtab_add(softc, softn, nat) + ipf_main_softc_t *softc; + ipf_nat_softc_t *softn; + nat_t *nat; +{ + nat_t **natp; + u_int hv0; + u_int hv1; + + hv0 = nat->nat_hv[0] % softn->ipf_nat_table_sz; + hv1 = nat->nat_hv[1] % softn->ipf_nat_table_sz; + + if (nat->nat_dir == NAT_INBOUND || nat->nat_dir == NAT_DIVERTIN) { + u_int swap; + + swap = hv0; + hv0 = hv1; + hv1 = swap; + } + + if (softn->ipf_nat_stats.ns_side[0].ns_bucketlen[hv0] >= + softn->ipf_nat_maxbucket) { + DT1(ns_bucket_max_0, int, + softn->ipf_nat_stats.ns_side[0].ns_bucketlen[hv0]); + NBUMPSIDE(0, ns_bucket_max); + return -1; + } + + if (softn->ipf_nat_stats.ns_side[1].ns_bucketlen[hv1] >= + softn->ipf_nat_maxbucket) { + DT1(ns_bucket_max_1, int, + softn->ipf_nat_stats.ns_side[1].ns_bucketlen[hv1]); + NBUMPSIDE(1, ns_bucket_max); + return -1; + } + + /* + * The ordering of operations in the list and hash table insertion + * is very important. The last operation for each task should be + * to update the top of the list, after all the "nexts" have been + * done so that walking the list while it is being done does not + * find strange pointers. + * + * Global list of NAT instances + */ + nat->nat_next = softn->ipf_nat_instances; + nat->nat_pnext = &softn->ipf_nat_instances; + if (softn->ipf_nat_instances) + softn->ipf_nat_instances->nat_pnext = &nat->nat_next; + softn->ipf_nat_instances = nat; + + /* + * Inbound hash table. + */ + natp = &softn->ipf_nat_table[0][hv0]; nat->nat_phnext[0] = natp; nat->nat_hnext[0] = *natp; + if (*natp) { + (*natp)->nat_phnext[0] = &nat->nat_hnext[0]; + } else { + NBUMPSIDE(0, ns_inuse); + } *natp = nat; - nat_stats.ns_bucketlen[0][hv1]++; + NBUMPSIDE(0, ns_bucketlen[hv0]); - natp = &nat_table[1][hv2]; - if (*natp) - (*natp)->nat_phnext[1] = &nat->nat_hnext[1]; + /* + * Outbound hash table. + */ + natp = &softn->ipf_nat_table[1][hv1]; nat->nat_phnext[1] = natp; nat->nat_hnext[1] = *natp; + if (*natp) + (*natp)->nat_phnext[1] = &nat->nat_hnext[1]; + else { + NBUMPSIDE(1, ns_inuse); + } *natp = nat; - nat_stats.ns_bucketlen[1][hv2]++; + NBUMPSIDE(1, ns_bucketlen[hv1]); - fr_setnatqueue(nat, rev); + ipf_nat_setqueue(softc, softn, nat); - nat_stats.ns_added++; - nat_stats.ns_inuse++; + if (nat->nat_dir & NAT_OUTBOUND) { + NBUMPSIDE(1, ns_added); + } else { + NBUMPSIDE(0, ns_added); + } + softn->ipf_nat_stats.ns_active++; return 0; } /* ------------------------------------------------------------------------ */ -/* Function: nat_icmperrorlookup */ +/* Function: ipf_nat_icmperrorlookup */ /* Returns: nat_t* - point to matching NAT structure */ /* Parameters: fin(I) - pointer to packet information */ /* dir(I) - direction of packet (in/out) */ @@ -2741,12 +3612,16 @@ int rev; /* ICMP query nat entry. It is assumed that the packet is already of the */ /* the required length. */ /* ------------------------------------------------------------------------ */ -nat_t *nat_icmperrorlookup(fin, dir) -fr_info_t *fin; -int dir; +nat_t * +ipf_nat_icmperrorlookup(fin, dir) + fr_info_t *fin; + int dir; { + ipf_main_softc_t *softc = fin->fin_main_soft; + ipf_nat_softc_t *softn = softc->ipf_nat_soft; int flags = 0, type, minlen; icmphdr_t *icmp, *orgicmp; + nat_stat_side_t *nside; tcphdr_t *tcp = NULL; u_short data[2]; nat_t *nat; @@ -2755,13 +3630,16 @@ int dir; icmp = fin->fin_dp; type = icmp->icmp_type; + nside = &softn->ipf_nat_stats.ns_side[fin->fin_out]; /* * Does it at least have the return (basic) IP header ? * Only a basic IP header (no options) should be with an ICMP error * header. Also, if it's not an error type, then return. */ - if ((fin->fin_hlen != sizeof(ip_t)) || !(fin->fin_flx & FI_ICMPERR)) + if ((fin->fin_hlen != sizeof(ip_t)) || !(fin->fin_flx & FI_ICMPERR)) { + ATOMIC_INCL(nside->ns_icmp_basic); return NULL; + } /* * Check packet size @@ -2769,35 +3647,45 @@ int dir; oip = (ip_t *)((char *)fin->fin_dp + 8); minlen = IP_HL(oip) << 2; if ((minlen < sizeof(ip_t)) || - (fin->fin_plen < ICMPERR_IPICMPHLEN + minlen)) + (fin->fin_plen < ICMPERR_IPICMPHLEN + minlen)) { + ATOMIC_INCL(nside->ns_icmp_size); return NULL; + } + /* * Is the buffer big enough for all of it ? It's the size of the IP * header claimed in the encapsulated part which is of concern. It * may be too big to be in this buffer but not so big that it's * outside the ICMP packet, leading to TCP deref's causing problems. * This is possible because we don't know how big oip_hl is when we - * do the pullup early in fr_check() and thus can't gaurantee it is + * do the pullup early in ipf_check() and thus can't gaurantee it is * all here now. */ -#ifdef _KERNEL +#ifdef ipf_nat_KERNEL { mb_t *m; m = fin->fin_m; # if defined(MENTAT) - if ((char *)oip + fin->fin_dlen - ICMPERR_ICMPHLEN > (char *)m->b_wptr) + if ((char *)oip + fin->fin_dlen - ICMPERR_ICMPHLEN > + (char *)m->b_wptr) { + ATOMIC_INCL(nside->ns_icmp_mbuf); return NULL; + } # else if ((char *)oip + fin->fin_dlen - ICMPERR_ICMPHLEN > - (char *)fin->fin_ip + M_LEN(m)) + (char *)fin->fin_ip + M_LEN(m)) { + ATOMIC_INCL(nside->ns_icmp_mbuf); return NULL; + } # endif } #endif - if (fin->fin_daddr != oip->ip_src.s_addr) + if (fin->fin_daddr != oip->ip_src.s_addr) { + ATOMIC_INCL(nside->ns_icmp_address); return NULL; + } p = oip->ip_p; if (p == IPPROTO_TCP) @@ -2808,7 +3696,7 @@ int dir; orgicmp = (icmphdr_t *)((char *)oip + (IP_HL(oip) << 2)); /* see if this is related to an ICMP query */ - if (nat_icmpquerytype4(orgicmp->icmp_type)) { + if (ipf_nat_icmpquerytype(orgicmp->icmp_type)) { data[0] = fin->fin_data[0]; data[1] = fin->fin_data[1]; fin->fin_data[0] = 0; @@ -2821,21 +3709,26 @@ int dir; * message flows in the opposite direction. */ if (dir == NAT_INBOUND) - nat = nat_inlookup(fin, flags, p, oip->ip_dst, - oip->ip_src); + nat = ipf_nat_inlookup(fin, flags, p, + oip->ip_dst, + oip->ip_src); else - nat = nat_outlookup(fin, flags, p, oip->ip_dst, - oip->ip_src); + nat = ipf_nat_outlookup(fin, flags, p, + oip->ip_dst, + oip->ip_src); fin->fin_data[0] = data[0]; fin->fin_data[1] = data[1]; return nat; } } - + if (flags & IPN_TCPUDP) { minlen += 8; /* + 64bits of data to get ports */ - if (fin->fin_plen < ICMPERR_IPICMPHLEN + minlen) + /* TRACE (fin,minlen) */ + if (fin->fin_plen < ICMPERR_IPICMPHLEN + minlen) { + ATOMIC_INCL(nside->ns_icmp_short); return NULL; + } data[0] = fin->fin_data[0]; data[1] = fin->fin_data[1]; @@ -2844,10 +3737,10 @@ int dir; fin->fin_data[1] = ntohs(tcp->th_sport); if (dir == NAT_INBOUND) { - nat = nat_inlookup(fin, flags, p, oip->ip_dst, - oip->ip_src); + nat = ipf_nat_inlookup(fin, flags, p, oip->ip_dst, + oip->ip_src); } else { - nat = nat_outlookup(fin, flags, p, oip->ip_dst, + nat = ipf_nat_outlookup(fin, flags, p, oip->ip_dst, oip->ip_src); } fin->fin_data[0] = data[0]; @@ -2855,14 +3748,16 @@ int dir; return nat; } if (dir == NAT_INBOUND) - return nat_inlookup(fin, 0, p, oip->ip_dst, oip->ip_src); + nat = ipf_nat_inlookup(fin, 0, p, oip->ip_dst, oip->ip_src); else - return nat_outlookup(fin, 0, p, oip->ip_dst, oip->ip_src); + nat = ipf_nat_outlookup(fin, 0, p, oip->ip_dst, oip->ip_src); + + return nat; } /* ------------------------------------------------------------------------ */ -/* Function: nat_icmperror */ +/* Function: ipf_nat_icmperror */ /* Returns: nat_t* - point to matching NAT structure */ /* Parameters: fin(I) - pointer to packet information */ /* nflags(I) - NAT flags for this packet */ @@ -2874,13 +3769,16 @@ int dir; /* This should *ONLY* be used for incoming ICMP error packets to make sure */ /* a NAT'd ICMP packet gets correctly recognised. */ /* ------------------------------------------------------------------------ */ -nat_t *nat_icmperror(fin, nflags, dir) -fr_info_t *fin; -u_int *nflags; -int dir; +nat_t * +ipf_nat_icmperror(fin, nflags, dir) + fr_info_t *fin; + u_int *nflags; + int dir; { + ipf_main_softc_t *softc = fin->fin_main_soft; + ipf_nat_softc_t *softn = softc->ipf_nat_soft; u_32_t sum1, sum2, sumd, sumd2; - struct in_addr a1, a2; + struct in_addr a1, a2, a3, a4; int flags, dlen, odst; icmphdr_t *icmp; u_short *csump; @@ -2889,13 +3787,18 @@ int dir; ip_t *oip; void *dp; - if ((fin->fin_flx & (FI_SHORT|FI_FRAGBODY))) + if ((fin->fin_flx & (FI_SHORT|FI_FRAGBODY))) { + NBUMPSIDED(fin->fin_out, ns_icmp_short); return NULL; + } + /* - * nat_icmperrorlookup() will return NULL for `defective' packets. + * ipf_nat_icmperrorlookup() will return NULL for `defective' packets. */ - if ((fin->fin_v != 4) || !(nat = nat_icmperrorlookup(fin, dir))) + if ((fin->fin_v != 4) || !(nat = ipf_nat_icmperrorlookup(fin, dir))) { + NBUMPSIDED(fin->fin_out, ns_icmp_notfound); return NULL; + } tcp = NULL; csump = NULL; @@ -2923,7 +3826,7 @@ int dir; /* * Need to adjust ICMP header to include the real IP#'s and * port #'s. Only apply a checksum change relative to the - * IP address change as it will be modified again in fr_checknatout + * IP address change as it will be modified again in ipf_nat_checkout * for both address and port. Two checksum changes are * necessary for the two header address changes. Be careful * to only modify the checksum once for the port # and twice @@ -2949,42 +3852,73 @@ int dir; * ------------ * MAP rule, SRC=a,DST=b -> SRC=c,DST=b * - response to outgoing packet (a,b)=>(c,b) (OIP_SRC=c,OIP_DST=b) - * - OIP_SRC(c)=nat_outip, OIP_DST(b)=nat_oip + * - OIP_SRC(c)=nat_newsrcip, OIP_DST(b)=nat_newdstip + *=> OIP_SRC(c)=nat_oldsrcip, OIP_DST(b)=nat_olddstip * * RDR rule, SRC=a,DST=b -> SRC=a,DST=c * - response to outgoing packet (c,a)=>(b,a) (OIP_SRC=b,OIP_DST=a) - * - OIP_SRC(b)=nat_outip, OIP_DST(a)=nat_oip + * - OIP_SRC(b)=nat_olddstip, OIP_DST(a)=nat_oldsrcip + *=> OIP_SRC(b)=nat_newdstip, OIP_DST(a)=nat_newsrcip + * + * REWRITE out rule, SRC=a,DST=b -> SRC=c,DST=d + * - response to outgoing packet (a,b)=>(c,d) (OIP_SRC=c,OIP_DST=d) + * - OIP_SRC(c)=nat_newsrcip, OIP_DST(d)=nat_newdstip + *=> OIP_SRC(c)=nat_oldsrcip, OIP_DST(d)=nat_olddstip + * + * REWRITE in rule, SRC=a,DST=b -> SRC=c,DST=d + * - response to outgoing packet (d,c)=>(b,a) (OIP_SRC=b,OIP_DST=a) + * - OIP_SRC(b)=nat_olddstip, OIP_DST(a)=nat_oldsrcip + *=> OIP_SRC(b)=nat_newdstip, OIP_DST(a)=nat_newsrcip * * Outbound ICMP * ------------- * MAP rule, SRC=a,DST=b -> SRC=c,DST=b * - response to incoming packet (b,c)=>(b,a) (OIP_SRC=b,OIP_DST=a) - * - OIP_SRC(a)=nat_oip, OIP_DST(c)=nat_inip + * - OIP_SRC(b)=nat_olddstip, OIP_DST(a)=nat_oldsrcip + *=> OIP_SRC(b)=nat_newdstip, OIP_DST(a)=nat_newsrcip * * RDR rule, SRC=a,DST=b -> SRC=a,DST=c * - response to incoming packet (a,b)=>(a,c) (OIP_SRC=a,OIP_DST=c) - * - OIP_SRC(a)=nat_oip, OIP_DST(c)=nat_inip + * - OIP_SRC(a)=nat_newsrcip, OIP_DST(c)=nat_newdstip + *=> OIP_SRC(a)=nat_oldsrcip, OIP_DST(c)=nat_olddstip * + * REWRITE out rule, SRC=a,DST=b -> SRC=c,DST=d + * - response to incoming packet (d,c)=>(b,a) (OIP_SRC=c,OIP_DST=d) + * - OIP_SRC(c)=nat_olddstip, OIP_DST(d)=nat_oldsrcip + *=> OIP_SRC(b)=nat_newdstip, OIP_DST(a)=nat_newsrcip + * + * REWRITE in rule, SRC=a,DST=b -> SRC=c,DST=d + * - response to incoming packet (a,b)=>(c,d) (OIP_SRC=b,OIP_DST=a) + * - OIP_SRC(b)=nat_newsrcip, OIP_DST(a)=nat_newdstip + *=> OIP_SRC(a)=nat_oldsrcip, OIP_DST(c)=nat_olddstip */ - odst = (oip->ip_dst.s_addr == nat->nat_oip.s_addr) ? 1 : 0; - if (odst == 1) { - a1.s_addr = ntohl(nat->nat_inip.s_addr); - a2.s_addr = ntohl(oip->ip_src.s_addr); - oip->ip_src.s_addr = htonl(a1.s_addr); - } else { - a1.s_addr = ntohl(nat->nat_outip.s_addr); + + if (((fin->fin_out == 0) && ((nat->nat_redir & NAT_MAP) != 0)) || + ((fin->fin_out == 1) && ((nat->nat_redir & NAT_REDIRECT) != 0))) { + a1.s_addr = ntohl(nat->nat_osrcaddr); + a4.s_addr = ntohl(oip->ip_src.s_addr); + a3.s_addr = ntohl(nat->nat_odstaddr); a2.s_addr = ntohl(oip->ip_dst.s_addr); - oip->ip_dst.s_addr = htonl(a1.s_addr); - } - - sumd = a2.s_addr - a1.s_addr; - if (sumd != 0) { - if (a1.s_addr > a2.s_addr) - sumd--; - sumd = ~sumd; - - fix_datacksum(&oip->ip_sum, sumd); + oip->ip_src.s_addr = htonl(a1.s_addr); + oip->ip_dst.s_addr = htonl(a3.s_addr); + odst = 1; + } else { + a1.s_addr = ntohl(nat->nat_ndstaddr); + a2.s_addr = ntohl(oip->ip_dst.s_addr); + a3.s_addr = ntohl(nat->nat_nsrcaddr); + a4.s_addr = ntohl(oip->ip_src.s_addr); + oip->ip_dst.s_addr = htonl(a3.s_addr); + oip->ip_src.s_addr = htonl(a1.s_addr); + odst = 0; } + sum1 = 0; + sum2 = 0; + sumd = 0; + CALC_SUMD(a2.s_addr, a3.s_addr, sum1); + CALC_SUMD(a4.s_addr, a1.s_addr, sum2); + sumd = sum2 + sum1; + if (sumd != 0) + ipf_fix_datacksum(&oip->ip_sum, sumd); sumd2 = sumd; sum1 = 0; @@ -2995,6 +3929,8 @@ int dir; * IP address change. */ if (((flags & IPN_TCPUDP) != 0) && (dlen >= 4)) { + u_32_t sum3, sum4, sumt; + /* * Step 2 : * For offending TCP/UDP IP packets, translate the ports as @@ -3003,24 +3939,33 @@ int dir; * * Since the port fields are part of the TCP/UDP checksum * of the offending IP packet, you need to adjust that checksum - * as well... except that the change in the port numbers should + * as well... except that the change in the port numbers should * be offset by the checksum change. However, the TCP/UDP * checksum will also need to change if there has been an * IP address change. */ if (odst == 1) { - sum1 = ntohs(nat->nat_inport); - sum2 = ntohs(tcp->th_sport); - - tcp->th_sport = htons(sum1); - } else { - sum1 = ntohs(nat->nat_outport); + sum1 = ntohs(nat->nat_osport); + sum4 = ntohs(tcp->th_sport); + sum3 = ntohs(nat->nat_odport); sum2 = ntohs(tcp->th_dport); - tcp->th_dport = htons(sum1); - } + tcp->th_sport = htons(sum1); + tcp->th_dport = htons(sum3); + } else { + sum1 = ntohs(nat->nat_ndport); + sum2 = ntohs(tcp->th_dport); + sum3 = ntohs(nat->nat_nsport); + sum4 = ntohs(tcp->th_sport); + + tcp->th_dport = htons(sum3); + tcp->th_sport = htons(sum1); + } + CALC_SUMD(sum4, sum1, sumt); + sumd += sumt; + CALC_SUMD(sum2, sum3, sumt); + sumd += sumt; - sumd += sum1 - sum2; if (sumd != 0 || sumd2 != 0) { /* * At this point, sumd is the delta to apply to the @@ -3038,39 +3983,26 @@ int dir; */ if (oip->ip_p == IPPROTO_UDP) { if ((dlen >= 8) && (*csump != 0)) { - fix_datacksum(csump, sumd); + ipf_fix_datacksum(csump, sumd); } else { - sumd2 = sum1 - sum2; - if (sum2 > sum1) - sumd2--; + CALC_SUMD(sum1, sum4, sumd2); + CALC_SUMD(sum3, sum2, sumt); + sumd2 += sumt; } } else if (oip->ip_p == IPPROTO_TCP) { if (dlen >= 18) { - fix_datacksum(csump, sumd); + ipf_fix_datacksum(csump, sumd); } else { - sumd2 = sum2 - sum1; - if (sum1 > sum2) - sumd2--; + CALC_SUMD(sum1, sum4, sumd2); + CALC_SUMD(sum3, sum2, sumt); + sumd2 += sumt; } } - if (sumd2 != 0) { - ipnat_t *np; - - np = nat->nat_ptr; sumd2 = (sumd2 & 0xffff) + (sumd2 >> 16); sumd2 = (sumd2 & 0xffff) + (sumd2 >> 16); sumd2 = (sumd2 & 0xffff) + (sumd2 >> 16); - - if ((odst == 0) && (dir == NAT_OUTBOUND) && - (fin->fin_rev == 0) && (np != NULL) && - (np->in_redir & NAT_REDIRECT)) { - fix_outcksum(fin, &icmp->icmp_cksum, - sumd2); - } else { - fix_incksum(fin, &icmp->icmp_cksum, - sumd2); - } + ipf_fix_incksum(0, &icmp->icmp_cksum, sumd2, 0); } } } else if (((flags & IPN_ICMPQUERY) != 0) && (dlen >= 8)) { @@ -3078,12 +4010,13 @@ int dir; /* * XXX - what if this is bogus hl and we go off the end ? - * In this case, nat_icmperrorlookup() will have returned NULL. + * In this case, ipf_nat_icmperrorlookup() will have + * returned NULL. */ orgicmp = (icmphdr_t *)dp; if (odst == 1) { - if (orgicmp->icmp_id != nat->nat_inport) { + if (orgicmp->icmp_id != nat->nat_osport) { /* * Fix ICMP checksum (of the offening ICMP @@ -3098,10 +4031,10 @@ int dir; * overall icmp->icmp_cksum */ sum1 = ntohs(orgicmp->icmp_id); - sum2 = ntohs(nat->nat_inport); + sum2 = ntohs(nat->nat_oicmpid); CALC_SUMD(sum1, sum2, sumd); - orgicmp->icmp_id = nat->nat_inport; - fix_datacksum(&orgicmp->icmp_cksum, sumd); + orgicmp->icmp_id = nat->nat_oicmpid; + ipf_fix_datacksum(&orgicmp->icmp_cksum, sumd); } } /* nat_dir == NAT_INBOUND is impossible for icmp queries */ } @@ -3109,13 +4042,20 @@ int dir; } +/* + * MAP-IN MAP-OUT RDR-IN RDR-OUT + * osrc X == src == src X + * odst X == dst == dst X + * nsrc == dst X X == dst + * ndst == src X X == src + * MAP = NAT_OUTBOUND, RDR = NAT_INBOUND + */ /* * NB: these lookups don't lock access to the list, it assumed that it has * already been done! */ - /* ------------------------------------------------------------------------ */ -/* Function: nat_inlookup */ +/* Function: ipf_nat_inlookup */ /* Returns: nat_t* - NULL == no match, */ /* else pointer to matching NAT entry */ /* Parameters: fin(I) - pointer to packet information */ @@ -3130,17 +4070,20 @@ int dir; /* */ /* NOTE: THE PACKET BEING CHECKED (IF FOUND) HAS A MAPPING ALREADY. */ /* */ -/* NOTE: IT IS ASSUMED THAT ipf_nat IS ONLY HELD WITH A READ LOCK WHEN */ +/* NOTE: IT IS ASSUMED THAT IS ONLY HELD WITH A READ LOCK WHEN */ /* THIS FUNCTION IS CALLED WITH NAT_SEARCH SET IN nflags. */ /* */ /* flags -> relevant are IPN_UDP/IPN_TCP/IPN_ICMPQUERY that indicate if */ /* the packet is of said protocol */ /* ------------------------------------------------------------------------ */ -nat_t *nat_inlookup(fin, flags, p, src, mapdst) -fr_info_t *fin; -u_int flags, p; -struct in_addr src , mapdst; +nat_t * +ipf_nat_inlookup(fin, flags, p, src, mapdst) + fr_info_t *fin; + u_int flags, p; + struct in_addr src , mapdst; { + ipf_main_softc_t *softc = fin->fin_main_soft; + ipf_nat_softc_t *softn = softc->ipf_nat_soft; u_short sport, dport; grehdr_t *gre; ipnat_t *ipn; @@ -3149,11 +4092,9 @@ struct in_addr src , mapdst; int nflags; u_32_t dst; void *ifp; - u_int hv; + u_int hv, rhv; ifp = fin->fin_ifp; - sport = 0; - dport = 0; gre = NULL; dst = mapdst.s_addr; sflags = flags & NAT_TCPUDPICMP; @@ -3166,12 +4107,17 @@ struct in_addr src , mapdst; dport = htons(fin->fin_data[1]); break; case IPPROTO_ICMP : - if (flags & IPN_ICMPERR) + if (flags & IPN_ICMPERR) { sport = fin->fin_data[1]; - else + dport = 0; + } else { dport = fin->fin_data[1]; + sport = 0; + } break; default : + sport = 0; + dport = 0; break; } @@ -3179,57 +4125,81 @@ struct in_addr src , mapdst; if ((flags & SI_WILDP) != 0) goto find_in_wild_ports; - hv = NAT_HASH_FN(dst, dport, 0xffffffff); - hv = NAT_HASH_FN(src.s_addr, hv + sport, ipf_nattable_sz); - nat = nat_table[1][hv]; + rhv = NAT_HASH_FN(dst, dport, 0xffffffff); + rhv = NAT_HASH_FN(src.s_addr, rhv + sport, 0xffffffff); + hv = rhv % softn->ipf_nat_table_sz; + nat = softn->ipf_nat_table[1][hv]; + /* TRACE dst, dport, src, sport, hv, nat */ + for (; nat; nat = nat->nat_hnext[1]) { if (nat->nat_ifps[0] != NULL) { if ((ifp != NULL) && (ifp != nat->nat_ifps[0])) continue; - } else if (ifp != NULL) - nat->nat_ifps[0] = ifp; + } - nflags = nat->nat_flags; + if (nat->nat_pr[0] != p) + continue; - if (nat->nat_oip.s_addr == src.s_addr && - nat->nat_outip.s_addr == dst && - (((p == 0) && - (sflags == (nat->nat_flags & IPN_TCPUDPICMP))) - || (p == nat->nat_p))) { - switch (p) - { -#if 0 - case IPPROTO_GRE : - if (nat->nat_call[1] != fin->fin_data[0]) + switch (nat->nat_dir) + { + case NAT_INBOUND : + case NAT_DIVERTIN : + if (nat->nat_v[0] != 4) + continue; + if (nat->nat_osrcaddr != src.s_addr || + nat->nat_odstaddr != dst) + continue; + if ((nat->nat_flags & IPN_TCPUDP) != 0) { + if (nat->nat_osport != sport) + continue; + if (nat->nat_odport != dport) + continue; + + } else if (p == IPPROTO_ICMP) { + if (nat->nat_osport != dport) { continue; - break; -#endif - case IPPROTO_ICMP : - if ((flags & IPN_ICMPERR) != 0) { - if (nat->nat_outport != sport) - continue; - } else { - if (nat->nat_outport != dport) - continue; } - break; - case IPPROTO_TCP : - case IPPROTO_UDP : - if (nat->nat_oport != sport) - continue; - if (nat->nat_outport != dport) - continue; - break; - default : - break; } + break; + case NAT_DIVERTOUT : + if (nat->nat_dlocal) + continue; + case NAT_OUTBOUND : + if (nat->nat_v[1] != 4) + continue; + if (nat->nat_dlocal) + continue; + if (nat->nat_dlocal) + continue; + if (nat->nat_ndstaddr != src.s_addr || + nat->nat_nsrcaddr != dst) + continue; + if ((nat->nat_flags & IPN_TCPUDP) != 0) { + if (nat->nat_ndport != sport) + continue; + if (nat->nat_nsport != dport) + continue; + } else if (p == IPPROTO_ICMP) { + if (nat->nat_osport != dport) { + continue; + } + } + break; + } + + + if ((nat->nat_flags & IPN_TCPUDP) != 0) { ipn = nat->nat_ptr; if ((ipn != NULL) && (nat->nat_aps != NULL)) - if (appr_match(fin, nat) != 0) + if (ipf_proxy_match(fin, nat) != 0) continue; - return nat; } + if ((nat->nat_ifps[0] == NULL) && (ifp != NULL)) { + nat->nat_ifps[0] = ifp; + nat->nat_mtu[0] = GETIFMTU_4(ifp); + } + return nat; } /* @@ -3240,126 +4210,191 @@ struct in_addr src , mapdst; * for "dummy" (FI_IGNORE) lookups. */ find_in_wild_ports: - if (!(flags & NAT_TCPUDP) || !(flags & NAT_SEARCH)) + if (!(flags & NAT_TCPUDP) || !(flags & NAT_SEARCH)) { + NBUMPSIDEX(0, ns_lookup_miss, ns_lookup_miss_0); return NULL; - if (nat_stats.ns_wilds == 0) + } + if (softn->ipf_nat_stats.ns_wilds == 0 || (fin->fin_flx & FI_NOWILD)) { + NBUMPSIDEX(0, ns_lookup_nowild, ns_lookup_nowild_0); return NULL; + } - RWLOCK_EXIT(&ipf_nat); + RWLOCK_EXIT(&softc->ipf_nat); hv = NAT_HASH_FN(dst, 0, 0xffffffff); - hv = NAT_HASH_FN(src.s_addr, hv, ipf_nattable_sz); + hv = NAT_HASH_FN(src.s_addr, hv, softn->ipf_nat_table_sz); + WRITE_ENTER(&softc->ipf_nat); - WRITE_ENTER(&ipf_nat); - - nat = nat_table[1][hv]; + nat = softn->ipf_nat_table[1][hv]; + /* TRACE dst, src, hv, nat */ for (; nat; nat = nat->nat_hnext[1]) { if (nat->nat_ifps[0] != NULL) { if ((ifp != NULL) && (ifp != nat->nat_ifps[0])) continue; - } else if (ifp != NULL) - nat->nat_ifps[0] = ifp; + } - if (nat->nat_p != fin->fin_p) - continue; - if (nat->nat_oip.s_addr != src.s_addr || - nat->nat_outip.s_addr != dst) + if (nat->nat_pr[0] != fin->fin_p) continue; + switch (nat->nat_dir & (NAT_INBOUND|NAT_OUTBOUND)) + { + case NAT_INBOUND : + if (nat->nat_v[0] != 4) + continue; + if (nat->nat_osrcaddr != src.s_addr || + nat->nat_odstaddr != dst) + continue; + break; + case NAT_OUTBOUND : + if (nat->nat_v[1] != 4) + continue; + if (nat->nat_ndstaddr != src.s_addr || + nat->nat_nsrcaddr != dst) + continue; + break; + } + nflags = nat->nat_flags; if (!(nflags & (NAT_TCPUDP|SI_WILDP))) continue; - if (nat_wildok(nat, (int)sport, (int)dport, nflags, - NAT_INBOUND) == 1) { + if (ipf_nat_wildok(nat, (int)sport, (int)dport, nflags, + NAT_INBOUND) == 1) { if ((fin->fin_flx & FI_IGNORE) != 0) break; if ((nflags & SI_CLONE) != 0) { - nat = fr_natclone(fin, nat); + nat = ipf_nat_clone(fin, nat); if (nat == NULL) break; } else { - MUTEX_ENTER(&ipf_nat_new); - nat_stats.ns_wilds--; - MUTEX_EXIT(&ipf_nat_new); + MUTEX_ENTER(&softn->ipf_nat_new); + softn->ipf_nat_stats.ns_wilds--; + MUTEX_EXIT(&softn->ipf_nat_new); + } + + if (nat->nat_dir == NAT_INBOUND) { + if (nat->nat_osport == 0) { + nat->nat_osport = sport; + nat->nat_nsport = sport; + } + if (nat->nat_odport == 0) { + nat->nat_odport = dport; + nat->nat_ndport = dport; + } + } else if (nat->nat_dir == NAT_OUTBOUND) { + if (nat->nat_osport == 0) { + nat->nat_osport = dport; + nat->nat_nsport = dport; + } + if (nat->nat_odport == 0) { + nat->nat_odport = sport; + nat->nat_ndport = sport; + } + } + if ((nat->nat_ifps[0] == NULL) && (ifp != NULL)) { + nat->nat_ifps[0] = ifp; + nat->nat_mtu[0] = GETIFMTU_4(ifp); } - nat->nat_oport = sport; - nat->nat_outport = dport; nat->nat_flags &= ~(SI_W_DPORT|SI_W_SPORT); - nat_tabmove(nat); + ipf_nat_tabmove(softn, nat); break; } } - MUTEX_DOWNGRADE(&ipf_nat); + MUTEX_DOWNGRADE(&softc->ipf_nat); + if (nat == NULL) { + NBUMPSIDE(0, ns_lookup_miss); + } return nat; } /* ------------------------------------------------------------------------ */ -/* Function: nat_tabmove */ +/* Function: ipf_nat_tabmove */ /* Returns: Nil */ -/* Parameters: nat(I) - pointer to NAT structure */ +/* Parameters: softn(I) - pointer to NAT context structure */ +/* nat(I) - pointer to NAT structure */ /* Write Lock: ipf_nat */ /* */ /* This function is only called for TCP/UDP NAT table entries where the */ /* original was placed in the table without hashing on the ports and we now */ /* want to include hashing on port numbers. */ /* ------------------------------------------------------------------------ */ -static void nat_tabmove(nat) -nat_t *nat; +static void +ipf_nat_tabmove(softn, nat) + ipf_nat_softc_t *softn; + nat_t *nat; { + u_int hv0, hv1, rhv0, rhv1; + natstat_t *nsp; nat_t **natp; - u_int hv; if (nat->nat_flags & SI_CLONE) return; + nsp = &softn->ipf_nat_stats; /* * Remove the NAT entry from the old location */ if (nat->nat_hnext[0]) nat->nat_hnext[0]->nat_phnext[0] = nat->nat_phnext[0]; *nat->nat_phnext[0] = nat->nat_hnext[0]; - nat_stats.ns_bucketlen[0][nat->nat_hv[0]]--; + nsp->ns_side[0].ns_bucketlen[nat->nat_hv[0] % + softn->ipf_nat_table_sz]--; if (nat->nat_hnext[1]) nat->nat_hnext[1]->nat_phnext[1] = nat->nat_phnext[1]; *nat->nat_phnext[1] = nat->nat_hnext[1]; - nat_stats.ns_bucketlen[1][nat->nat_hv[1]]--; + nsp->ns_side[1].ns_bucketlen[nat->nat_hv[1] % + softn->ipf_nat_table_sz]--; /* * Add into the NAT table in the new position */ - hv = NAT_HASH_FN(nat->nat_inip.s_addr, nat->nat_inport, 0xffffffff); - hv = NAT_HASH_FN(nat->nat_oip.s_addr, hv + nat->nat_oport, - ipf_nattable_sz); - nat->nat_hv[0] = hv; - natp = &nat_table[0][hv]; + rhv0 = NAT_HASH_FN(nat->nat_osrcaddr, nat->nat_osport, 0xffffffff); + rhv0 = NAT_HASH_FN(nat->nat_odstaddr, rhv0 + nat->nat_odport, + 0xffffffff); + rhv1 = NAT_HASH_FN(nat->nat_nsrcaddr, nat->nat_nsport, 0xffffffff); + rhv1 = NAT_HASH_FN(nat->nat_ndstaddr, rhv1 + nat->nat_ndport, + 0xffffffff); + + hv0 = rhv0 % softn->ipf_nat_table_sz; + hv1 = rhv1 % softn->ipf_nat_table_sz; + + if (nat->nat_dir == NAT_INBOUND || nat->nat_dir == NAT_DIVERTIN) { + u_int swap; + + swap = hv0; + hv0 = hv1; + hv1 = swap; + } + + /* TRACE nat_osrcaddr, nat_osport, nat_odstaddr, nat_odport, hv0 */ + /* TRACE nat_nsrcaddr, nat_nsport, nat_ndstaddr, nat_ndport, hv1 */ + + nat->nat_hv[0] = rhv0; + natp = &softn->ipf_nat_table[0][hv0]; if (*natp) (*natp)->nat_phnext[0] = &nat->nat_hnext[0]; nat->nat_phnext[0] = natp; nat->nat_hnext[0] = *natp; *natp = nat; - nat_stats.ns_bucketlen[0][hv]++; + nsp->ns_side[0].ns_bucketlen[hv0]++; - hv = NAT_HASH_FN(nat->nat_outip.s_addr, nat->nat_outport, 0xffffffff); - hv = NAT_HASH_FN(nat->nat_oip.s_addr, hv + nat->nat_oport, - ipf_nattable_sz); - nat->nat_hv[1] = hv; - natp = &nat_table[1][hv]; + nat->nat_hv[1] = rhv1; + natp = &softn->ipf_nat_table[1][hv1]; if (*natp) (*natp)->nat_phnext[1] = &nat->nat_hnext[1]; nat->nat_phnext[1] = natp; nat->nat_hnext[1] = *natp; *natp = nat; - nat_stats.ns_bucketlen[1][hv]++; + nsp->ns_side[1].ns_bucketlen[hv1]++; } /* ------------------------------------------------------------------------ */ -/* Function: nat_outlookup */ +/* Function: ipf_nat_outlookup */ /* Returns: nat_t* - NULL == no match, */ /* else pointer to matching NAT entry */ /* Parameters: fin(I) - pointer to packet information */ @@ -3367,7 +4402,7 @@ nat_t *nat; /* p(I) - protocol for this packet */ /* src(I) - source IP address */ /* dst(I) - destination IP address */ -/* rw(I) - 1 == write lock on ipf_nat held, 0 == read lock. */ +/* rw(I) - 1 == write lock on held, 0 == read lock. */ /* */ /* Lookup a nat entry based on the source 'real' ip address/port and */ /* destination address/port. We use this lookup when sending a packet out, */ @@ -3375,28 +4410,28 @@ nat_t *nat; /* */ /* NOTE: THE PACKET BEING CHECKED (IF FOUND) HAS A MAPPING ALREADY. */ /* */ -/* NOTE: IT IS ASSUMED THAT ipf_nat IS ONLY HELD WITH A READ LOCK WHEN */ +/* NOTE: IT IS ASSUMED THAT IS ONLY HELD WITH A READ LOCK WHEN */ /* THIS FUNCTION IS CALLED WITH NAT_SEARCH SET IN nflags. */ /* */ /* flags -> relevant are IPN_UDP/IPN_TCP/IPN_ICMPQUERY that indicate if */ /* the packet is of said protocol */ /* ------------------------------------------------------------------------ */ -nat_t *nat_outlookup(fin, flags, p, src, dst) -fr_info_t *fin; -u_int flags, p; -struct in_addr src , dst; +nat_t * +ipf_nat_outlookup(fin, flags, p, src, dst) + fr_info_t *fin; + u_int flags, p; + struct in_addr src , dst; { + ipf_main_softc_t *softc = fin->fin_main_soft; + ipf_nat_softc_t *softn = softc->ipf_nat_soft; u_short sport, dport; u_int sflags; ipnat_t *ipn; - u_32_t srcip; nat_t *nat; - int nflags; void *ifp; u_int hv; ifp = fin->fin_ifp; - srcip = src.s_addr; sflags = flags & IPN_TCPUDPICMP; sport = 0; dport = 0; @@ -3421,47 +4456,75 @@ struct in_addr src , dst; if ((flags & SI_WILDP) != 0) goto find_out_wild_ports; - hv = NAT_HASH_FN(srcip, sport, 0xffffffff); - hv = NAT_HASH_FN(dst.s_addr, hv + dport, ipf_nattable_sz); - nat = nat_table[0][hv]; + hv = NAT_HASH_FN(src.s_addr, sport, 0xffffffff); + hv = NAT_HASH_FN(dst.s_addr, hv + dport, softn->ipf_nat_table_sz); + nat = softn->ipf_nat_table[0][hv]; + + /* TRACE src, sport, dst, dport, hv, nat */ + for (; nat; nat = nat->nat_hnext[0]) { if (nat->nat_ifps[1] != NULL) { if ((ifp != NULL) && (ifp != nat->nat_ifps[1])) continue; - } else if (ifp != NULL) - nat->nat_ifps[1] = ifp; - - nflags = nat->nat_flags; - - if (nat->nat_inip.s_addr == srcip && - nat->nat_oip.s_addr == dst.s_addr && - (((p == 0) && (sflags == (nflags & NAT_TCPUDPICMP))) - || (p == nat->nat_p))) { - switch (p) - { -#if 0 - case IPPROTO_GRE : - if (nat->nat_call[1] != fin->fin_data[0]) - continue; - break; -#endif - case IPPROTO_TCP : - case IPPROTO_UDP : - if (nat->nat_oport != dport) - continue; - if (nat->nat_inport != sport) - continue; - break; - default : - break; - } - - ipn = nat->nat_ptr; - if ((ipn != NULL) && (nat->nat_aps != NULL)) - if (appr_match(fin, nat) != 0) - continue; - return nat; } + + if (nat->nat_pr[1] != p) + continue; + + switch (nat->nat_dir) + { + case NAT_INBOUND : + case NAT_DIVERTIN : + if (nat->nat_v[1] != 4) + continue; + if (nat->nat_ndstaddr != src.s_addr || + nat->nat_nsrcaddr != dst.s_addr) + continue; + + if ((nat->nat_flags & IPN_TCPUDP) != 0) { + if (nat->nat_ndport != sport) + continue; + if (nat->nat_nsport != dport) + continue; + + } else if (p == IPPROTO_ICMP) { + if (nat->nat_osport != dport) { + continue; + } + } + break; + case NAT_OUTBOUND : + case NAT_DIVERTOUT : + if (nat->nat_v[0] != 4) + continue; + if (nat->nat_osrcaddr != src.s_addr || + nat->nat_odstaddr != dst.s_addr) + continue; + + if ((nat->nat_flags & IPN_TCPUDP) != 0) { + if (nat->nat_odport != dport) + continue; + if (nat->nat_osport != sport) + continue; + + } else if (p == IPPROTO_ICMP) { + if (nat->nat_osport != dport) { + continue; + } + } + break; + } + + ipn = nat->nat_ptr; + if ((ipn != NULL) && (nat->nat_aps != NULL)) + if (ipf_proxy_match(fin, nat) != 0) + continue; + + if ((nat->nat_ifps[1] == NULL) && (ifp != NULL)) { + nat->nat_ifps[1] = ifp; + nat->nat_mtu[1] = GETIFMTU_4(ifp); + } + return nat; } /* @@ -3472,67 +4535,107 @@ struct in_addr src , dst; * for "dummy" (FI_IGNORE) lookups. */ find_out_wild_ports: - if (!(flags & NAT_TCPUDP) || !(flags & NAT_SEARCH)) + if (!(flags & NAT_TCPUDP) || !(flags & NAT_SEARCH)) { + NBUMPSIDEX(1, ns_lookup_miss, ns_lookup_miss_1); return NULL; - if (nat_stats.ns_wilds == 0) + } + if (softn->ipf_nat_stats.ns_wilds == 0 || (fin->fin_flx & FI_NOWILD)) { + NBUMPSIDEX(1, ns_lookup_nowild, ns_lookup_nowild_1); return NULL; + } - RWLOCK_EXIT(&ipf_nat); + RWLOCK_EXIT(&softc->ipf_nat); - hv = NAT_HASH_FN(srcip, 0, 0xffffffff); - hv = NAT_HASH_FN(dst.s_addr, hv, ipf_nattable_sz); + hv = NAT_HASH_FN(src.s_addr, 0, 0xffffffff); + hv = NAT_HASH_FN(dst.s_addr, hv, softn->ipf_nat_table_sz); - WRITE_ENTER(&ipf_nat); + WRITE_ENTER(&softc->ipf_nat); - nat = nat_table[0][hv]; + nat = softn->ipf_nat_table[0][hv]; for (; nat; nat = nat->nat_hnext[0]) { if (nat->nat_ifps[1] != NULL) { if ((ifp != NULL) && (ifp != nat->nat_ifps[1])) continue; - } else if (ifp != NULL) - nat->nat_ifps[1] = ifp; + } - if (nat->nat_p != fin->fin_p) - continue; - if ((nat->nat_inip.s_addr != srcip) || - (nat->nat_oip.s_addr != dst.s_addr)) + if (nat->nat_pr[1] != fin->fin_p) continue; - nflags = nat->nat_flags; - if (!(nflags & (NAT_TCPUDP|SI_WILDP))) + switch (nat->nat_dir & (NAT_INBOUND|NAT_OUTBOUND)) + { + case NAT_INBOUND : + if (nat->nat_v[1] != 4) + continue; + if (nat->nat_ndstaddr != src.s_addr || + nat->nat_nsrcaddr != dst.s_addr) + continue; + break; + case NAT_OUTBOUND : + if (nat->nat_v[0] != 4) + continue; + if (nat->nat_osrcaddr != src.s_addr || + nat->nat_odstaddr != dst.s_addr) + continue; + break; + } + + if (!(nat->nat_flags & (NAT_TCPUDP|SI_WILDP))) continue; - if (nat_wildok(nat, (int)sport, (int)dport, nflags, - NAT_OUTBOUND) == 1) { + if (ipf_nat_wildok(nat, (int)sport, (int)dport, nat->nat_flags, + NAT_OUTBOUND) == 1) { if ((fin->fin_flx & FI_IGNORE) != 0) break; - if ((nflags & SI_CLONE) != 0) { - nat = fr_natclone(fin, nat); + if ((nat->nat_flags & SI_CLONE) != 0) { + nat = ipf_nat_clone(fin, nat); if (nat == NULL) break; } else { - MUTEX_ENTER(&ipf_nat_new); - nat_stats.ns_wilds--; - MUTEX_EXIT(&ipf_nat_new); + MUTEX_ENTER(&softn->ipf_nat_new); + softn->ipf_nat_stats.ns_wilds--; + MUTEX_EXIT(&softn->ipf_nat_new); + } + + if (nat->nat_dir == NAT_OUTBOUND) { + if (nat->nat_osport == 0) { + nat->nat_osport = sport; + nat->nat_nsport = sport; + } + if (nat->nat_odport == 0) { + nat->nat_odport = dport; + nat->nat_ndport = dport; + } + } else if (nat->nat_dir == NAT_INBOUND) { + if (nat->nat_osport == 0) { + nat->nat_osport = dport; + nat->nat_nsport = dport; + } + if (nat->nat_odport == 0) { + nat->nat_odport = sport; + nat->nat_ndport = sport; + } + } + if ((nat->nat_ifps[1] == NULL) && (ifp != NULL)) { + nat->nat_ifps[1] = ifp; + nat->nat_mtu[1] = GETIFMTU_4(ifp); } - nat->nat_inport = sport; - nat->nat_oport = dport; - if (nat->nat_outport == 0) - nat->nat_outport = sport; nat->nat_flags &= ~(SI_W_DPORT|SI_W_SPORT); - nat_tabmove(nat); + ipf_nat_tabmove(softn, nat); break; } } - MUTEX_DOWNGRADE(&ipf_nat); + MUTEX_DOWNGRADE(&softc->ipf_nat); + if (nat == NULL) { + NBUMPSIDE(1, ns_lookup_miss); + } return nat; } /* ------------------------------------------------------------------------ */ -/* Function: nat_lookupredir */ +/* Function: ipf_nat_lookupredir */ /* Returns: nat_t* - NULL == no match, */ /* else pointer to matching NAT entry */ /* Parameters: np(I) - pointer to description of packet to find NAT table */ @@ -3550,8 +4653,9 @@ struct in_addr src , dst; /* nl_in* = source information (untranslated) */ /* nl_out* = destination information (translated) */ /* ------------------------------------------------------------------------ */ -nat_t *nat_lookupredir(np) -natlookup_t *np; +nat_t * +ipf_nat_lookupredir(np) + natlookup_t *np; { fr_info_t fi; nat_t *nat; @@ -3577,34 +4681,34 @@ natlookup_t *np; * - default: we have the `in' and `out' address, look for `real'. */ if (np->nl_flags & IPN_IN) { - if ((nat = nat_inlookup(&fi, np->nl_flags, fi.fin_p, - np->nl_realip, np->nl_outip))) { - np->nl_inip = nat->nat_inip; - np->nl_inport = nat->nat_inport; + if ((nat = ipf_nat_inlookup(&fi, np->nl_flags, fi.fin_p, + np->nl_realip, np->nl_outip))) { + np->nl_inip = nat->nat_odstip; + np->nl_inport = nat->nat_odport; } } else { /* * If nl_inip is non null, this is a lookup based on the real * ip address. Else, we use the fake. */ - if ((nat = nat_outlookup(&fi, np->nl_flags, fi.fin_p, + if ((nat = ipf_nat_outlookup(&fi, np->nl_flags, fi.fin_p, np->nl_inip, np->nl_outip))) { if ((np->nl_flags & IPN_FINDFORWARD) != 0) { fr_info_t fin; bzero((char *)&fin, sizeof(fin)); - fin.fin_p = nat->nat_p; - fin.fin_data[0] = ntohs(nat->nat_outport); - fin.fin_data[1] = ntohs(nat->nat_oport); - if (nat_inlookup(&fin, np->nl_flags, fin.fin_p, - nat->nat_outip, - nat->nat_oip) != NULL) { + fin.fin_p = nat->nat_pr[0]; + fin.fin_data[0] = ntohs(nat->nat_ndport); + fin.fin_data[1] = ntohs(nat->nat_nsport); + if (ipf_nat_inlookup(&fin, np->nl_flags, + fin.fin_p, nat->nat_ndstip, + nat->nat_nsrcip) != NULL) { np->nl_flags &= ~IPN_FINDFORWARD; } } - np->nl_realip = nat->nat_outip; - np->nl_realport = nat->nat_outport; + np->nl_realip = nat->nat_ndstip; + np->nl_realport = nat->nat_ndport; } } @@ -3613,45 +4717,53 @@ natlookup_t *np; /* ------------------------------------------------------------------------ */ -/* Function: nat_match */ +/* Function: ipf_nat_match */ /* Returns: int - 0 == no match, 1 == match */ /* Parameters: fin(I) - pointer to packet information */ /* np(I) - pointer to NAT rule */ /* */ /* Pull the matching of a packet against a NAT rule out of that complex */ -/* loop inside fr_checknatin() and lay it out properly in its own function. */ +/* loop inside ipf_nat_checkin() and lay it out properly in its own function. */ /* ------------------------------------------------------------------------ */ -static int nat_match(fin, np) -fr_info_t *fin; -ipnat_t *np; +static int +ipf_nat_match(fin, np) + fr_info_t *fin; + ipnat_t *np; { + ipf_main_softc_t *softc = fin->fin_main_soft; frtuc_t *ft; + int match; - if (fin->fin_v != 4) - return 0; - - if (np->in_p && fin->fin_p != np->in_p) - return 0; - - if (fin->fin_out) { - if (!(np->in_redir & (NAT_MAP|NAT_MAPBLK))) - return 0; - if (((fin->fin_fi.fi_saddr & np->in_inmsk) != np->in_inip) - ^ ((np->in_flags & IPN_NOTSRC) != 0)) - return 0; - if (((fin->fin_fi.fi_daddr & np->in_srcmsk) != np->in_srcip) - ^ ((np->in_flags & IPN_NOTDST) != 0)) - return 0; - } else { - if (!(np->in_redir & NAT_REDIRECT)) - return 0; - if (((fin->fin_fi.fi_saddr & np->in_srcmsk) != np->in_srcip) - ^ ((np->in_flags & IPN_NOTSRC) != 0)) - return 0; - if (((fin->fin_fi.fi_daddr & np->in_outmsk) != np->in_outip) - ^ ((np->in_flags & IPN_NOTDST) != 0)) - return 0; + match = 0; + switch (np->in_osrcatype) + { + case FRI_NORMAL : + match = ((fin->fin_saddr & np->in_osrcmsk) != np->in_osrcaddr); + break; + case FRI_LOOKUP : + match = (*np->in_osrcfunc)(softc, np->in_osrcptr, + 4, &fin->fin_saddr, fin->fin_plen); + break; } + match ^= ((np->in_flags & IPN_NOTSRC) != 0); + if (match) + return 0; + + match = 0; + switch (np->in_odstatype) + { + case FRI_NORMAL : + match = ((fin->fin_daddr & np->in_odstmsk) != np->in_odstaddr); + break; + case FRI_LOOKUP : + match = (*np->in_odstfunc)(softc, np->in_odstptr, + 4, &fin->fin_daddr, fin->fin_plen); + break; + } + + match ^= ((np->in_flags & IPN_NOTDST) != 0); + if (match) + return 0; ft = &np->in_tuc; if (!(fin->fin_flx & FI_TCPUDP) || @@ -3661,28 +4773,33 @@ ipnat_t *np; return 1; } - return fr_tcpudpchk(fin, ft); + return ipf_tcpudpchk(&fin->fin_fi, ft); } /* ------------------------------------------------------------------------ */ -/* Function: nat_update */ +/* Function: ipf_nat_update */ /* Returns: Nil */ -/* Parameters: nat(I) - pointer to NAT structure */ -/* np(I) - pointer to NAT rule */ +/* Parameters: fin(I) - pointer to packet information */ +/* nat(I) - pointer to NAT structure */ /* */ /* Updates the lifetime of a NAT table entry for non-TCP packets. Must be */ -/* called with fin_rev updated - i.e. after calling nat_proto(). */ +/* called with fin_rev updated - i.e. after calling ipf_nat_proto(). */ +/* */ +/* This *MUST* be called after ipf_nat_proto() as it expects fin_rev to */ +/* already be set. */ /* ------------------------------------------------------------------------ */ -void nat_update(fin, nat, np) -fr_info_t *fin; -nat_t *nat; -ipnat_t *np; +void +ipf_nat_update(fin, nat) + fr_info_t *fin; + nat_t *nat; { + ipf_main_softc_t *softc = fin->fin_main_soft; + ipf_nat_softc_t *softn = softc->ipf_nat_soft; ipftq_t *ifq, *ifq2; ipftqent_t *tqe; + ipnat_t *np = nat->nat_ptr; - MUTEX_ENTER(&nat->nat_lock); tqe = &nat->nat_tqe; ifq = tqe->tqe_ifq; @@ -3691,51 +4808,36 @@ ipnat_t *np; * TCP, however, if it is TCP and there is no rule timeout set, * then do not update the timeout here. */ - if (np != NULL) + if (np != NULL) { + np->in_bytes[fin->fin_rev] += fin->fin_plen; ifq2 = np->in_tqehead[fin->fin_rev]; - else + } else { ifq2 = NULL; + } - if (nat->nat_p == IPPROTO_TCP && ifq2 == NULL) { - u_32_t end, ack; - u_char tcpflags; - tcphdr_t *tcp; - int dsize; - - tcp = fin->fin_dp; - tcpflags = tcp->th_flags; - dsize = fin->fin_dlen - (TCP_OFF(tcp) << 2) + - ((tcpflags & TH_SYN) ? 1 : 0) + - ((tcpflags & TH_FIN) ? 1 : 0); - - ack = ntohl(tcp->th_ack); - end = ntohl(tcp->th_seq) + dsize; - - if (SEQ_GT(ack, nat->nat_seqnext[1 - fin->fin_rev])) - nat->nat_seqnext[1 - fin->fin_rev] = ack; - - if (nat->nat_seqnext[fin->fin_rev] == 0) - nat->nat_seqnext[fin->fin_rev] = end; - - (void) fr_tcp_age(&nat->nat_tqe, fin, nat_tqb, 0); + if (nat->nat_pr[0] == IPPROTO_TCP && ifq2 == NULL) { + (void) ipf_tcp_age(&nat->nat_tqe, fin, softn->ipf_nat_tcptq, + 0, 2); } else { if (ifq2 == NULL) { - if (nat->nat_p == IPPROTO_UDP) - ifq2 = &nat_udptq; - else if (nat->nat_p == IPPROTO_ICMP) - ifq2 = &nat_icmptq; + if (nat->nat_pr[0] == IPPROTO_UDP) + ifq2 = fin->fin_rev ? &softn->ipf_nat_udpacktq : + &softn->ipf_nat_udptq; + else if (nat->nat_pr[0] == IPPROTO_ICMP || + nat->nat_pr[0] == IPPROTO_ICMPV6) + ifq2 = fin->fin_rev ? &softn->ipf_nat_icmpacktq: + &softn->ipf_nat_icmptq; else - ifq2 = &nat_iptq; + ifq2 = &softn->ipf_nat_iptq; } - fr_movequeue(tqe, ifq, ifq2); + ipf_movequeue(softc->ipf_ticks, tqe, ifq, ifq2); } - MUTEX_EXIT(&nat->nat_lock); } /* ------------------------------------------------------------------------ */ -/* Function: fr_checknatout */ +/* Function: ipf_nat_checkout */ /* Returns: int - -1 == packet failed NAT checks so block it, */ /* 0 == no packet translation occurred, */ /* 1 == packet was successfully translated. */ @@ -3749,29 +4851,46 @@ ipnat_t *np; /* NAT entry if a we matched a NAT rule. Lastly, actually change the */ /* packet header(s) as required. */ /* ------------------------------------------------------------------------ */ -int fr_checknatout(fin, passp) -fr_info_t *fin; -u_32_t *passp; +int +ipf_nat_checkout(fin, passp) + fr_info_t *fin; + u_32_t *passp; { + ipnat_t *np = NULL, *npnext; struct ifnet *ifp, *sifp; + ipf_main_softc_t *softc; + ipf_nat_softc_t *softn; icmphdr_t *icmp = NULL; tcphdr_t *tcp = NULL; int rval, natfailed; - ipnat_t *np = NULL; u_int nflags = 0; u_32_t ipa, iph; int natadd = 1; frentry_t *fr; nat_t *nat; - if (nat_stats.ns_rules == 0 || fr_nat_lock != 0) + if (fin->fin_v == 6) { +#ifdef USE_INET6 + return ipf_nat6_checkout(fin, passp); +#else + return 0; +#endif + } + + softc = fin->fin_main_soft; + softn = softc->ipf_nat_soft; + + if (softn->ipf_nat_lock != 0) + return 0; + if (softn->ipf_nat_stats.ns_rules == 0 && + softn->ipf_nat_instances == NULL) return 0; natfailed = 0; fr = fin->fin_fr; sifp = fin->fin_ifp; if (fr != NULL) { - ifp = fr->fr_tifs[fin->fin_rev].fd_ifp; + ifp = fr->fr_tifs[fin->fin_rev].fd_ptr; if ((ifp != NULL) && (ifp != (void *)-1)) fin->fin_ifp = ifp; } @@ -3793,117 +4912,152 @@ u_32_t *passp; * This is an incoming packet, so the destination is * the icmp_id and the source port equals 0 */ - if (nat_icmpquerytype4(icmp->icmp_type)) + if ((fin->fin_flx & FI_ICMPQUERY) != 0) nflags = IPN_ICMPQUERY; break; default : break; } - + if ((nflags & IPN_TCPUDP)) tcp = fin->fin_dp; } ipa = fin->fin_saddr; - READ_ENTER(&ipf_nat); + READ_ENTER(&softc->ipf_nat); - if (((fin->fin_flx & FI_ICMPERR) != 0) && - (nat = nat_icmperror(fin, &nflags, NAT_OUTBOUND))) + if ((fin->fin_p == IPPROTO_ICMP) && !(nflags & IPN_ICMPQUERY) && + (nat = ipf_nat_icmperror(fin, &nflags, NAT_OUTBOUND))) /*EMPTY*/; - else if ((fin->fin_flx & FI_FRAG) && (nat = fr_nat_knownfrag(fin))) + else if ((fin->fin_flx & FI_FRAG) && (nat = ipf_frag_natknown(fin))) natadd = 0; - else if ((nat = nat_outlookup(fin, nflags|NAT_SEARCH, (u_int)fin->fin_p, - fin->fin_src, fin->fin_dst))) { + else if ((nat = ipf_nat_outlookup(fin, nflags|NAT_SEARCH, + (u_int)fin->fin_p, fin->fin_src, + fin->fin_dst))) { nflags = nat->nat_flags; - } else { - u_32_t hv, msk, nmsk; + } else if (fin->fin_off == 0) { + u_32_t hv, msk, nmsk = 0; /* * If there is no current entry in the nat table for this IP#, * create one for it (if there is a matching rule). */ - RWLOCK_EXIT(&ipf_nat); - msk = 0xffffffff; - nmsk = nat_masks; - WRITE_ENTER(&ipf_nat); maskloop: - iph = ipa & htonl(msk); - hv = NAT_HASH_FN(iph, 0, ipf_natrules_sz); - for (np = nat_rules[hv]; np; np = np->in_mnext) - { + msk = softn->ipf_nat_map_active_masks[nmsk]; + iph = ipa & msk; + hv = NAT_HASH_FN(iph, 0, softn->ipf_nat_maprules_sz); +retry_roundrobin: + for (np = softn->ipf_nat_map_rules[hv]; np; np = npnext) { + npnext = np->in_mnext; if ((np->in_ifps[1] && (np->in_ifps[1] != ifp))) continue; - if (np->in_v != fin->fin_v) + if (np->in_v[0] != 4) continue; - if (np->in_p && (np->in_p != fin->fin_p)) + if (np->in_pr[1] && (np->in_pr[1] != fin->fin_p)) continue; - if ((np->in_flags & IPN_RF) && !(np->in_flags & nflags)) + if ((np->in_flags & IPN_RF) && + !(np->in_flags & nflags)) continue; if (np->in_flags & IPN_FILTER) { - if (!nat_match(fin, np)) + switch (ipf_nat_match(fin, np)) + { + case 0 : continue; - } else if ((ipa & np->in_inmsk) != np->in_inip) + case -1 : + rval = -1; + goto outmatchfail; + case 1 : + default : + break; + } + } else if ((ipa & np->in_osrcmsk) != np->in_osrcaddr) continue; if ((fr != NULL) && - !fr_matchtag(&np->in_tag, &fr->fr_nattag)) + !ipf_matchtag(&np->in_tag, &fr->fr_nattag)) continue; - if (*np->in_plabel != '\0') { + if (np->in_plabel != -1) { if (((np->in_flags & IPN_FILTER) == 0) && - (np->in_dport != tcp->th_dport)) + (np->in_odport != fin->fin_data[1])) continue; - if (appr_ok(fin, tcp, np) == 0) + if (ipf_proxy_ok(fin, tcp, np) == 0) continue; } - if ((nat = nat_new(fin, np, NULL, nflags, - NAT_OUTBOUND))) { + if (np->in_flags & IPN_NO) { np->in_hits++; break; - } else - natfailed = -1; - } - if ((np == NULL) && (nmsk != 0)) { - while (nmsk) { - msk <<= 1; - if (nmsk & 0x80000000) - break; - nmsk <<= 1; } - if (nmsk != 0) { - nmsk <<= 1; - goto maskloop; + MUTEX_ENTER(&softn->ipf_nat_new); + /* + * If we've matched a round-robin rule but it has + * moved in the list since we got it, start over as + * this is now no longer correct. + */ + if (npnext != np->in_mnext) { + if ((np->in_flags & IPN_ROUNDR) != 0) { + MUTEX_EXIT(&softn->ipf_nat_new); + goto retry_roundrobin; + } + npnext = np->in_mnext; } + + nat = ipf_nat_add(fin, np, NULL, nflags, NAT_OUTBOUND); + MUTEX_EXIT(&softn->ipf_nat_new); + if (nat != NULL) { + natfailed = 0; + break; + } + natfailed = -1; + } + if ((np == NULL) && (nmsk < softn->ipf_nat_map_max)) { + nmsk++; + goto maskloop; } - MUTEX_DOWNGRADE(&ipf_nat); } if (nat != NULL) { - rval = fr_natout(fin, nat, natadd, nflags); + rval = ipf_nat_out(fin, nat, natadd, nflags); if (rval == 1) { MUTEX_ENTER(&nat->nat_lock); - nat->nat_ref++; + ipf_nat_update(fin, nat); + nat->nat_bytes[1] += fin->fin_plen; + nat->nat_pkts[1]++; + fin->fin_pktnum = nat->nat_pkts[1]; MUTEX_EXIT(&nat->nat_lock); - nat->nat_touched = fr_ticks; - fin->fin_nat = nat; } } else rval = natfailed; - RWLOCK_EXIT(&ipf_nat); +outmatchfail: + RWLOCK_EXIT(&softc->ipf_nat); - if (rval == -1) { - if (passp != NULL) + switch (rval) + { + case -1 : + if (passp != NULL) { + DT1(frb_natv4out, fr_info_t *, fin); + NBUMPSIDED(1, ns_drop); *passp = FR_BLOCK; + fin->fin_reason = FRB_NATV4; + } fin->fin_flx |= FI_BADNAT; + NBUMPSIDED(1, ns_badnat); + break; + case 0 : + NBUMPSIDE(1, ns_ignored); + break; + case 1 : + NBUMPSIDE(1, ns_translated); + break; } fin->fin_ifp = sifp; return rval; } /* ------------------------------------------------------------------------ */ -/* Function: fr_natout */ +/* Function: ipf_nat_out */ /* Returns: int - -1 == packet failed NAT checks so block it, */ /* 1 == packet was successfully translated. */ /* Parameters: fin(I) - pointer to packet information */ @@ -3913,30 +5067,27 @@ u_32_t *passp; /* */ /* Translate a packet coming "out" on an interface. */ /* ------------------------------------------------------------------------ */ -int fr_natout(fin, nat, natadd, nflags) -fr_info_t *fin; -nat_t *nat; -int natadd; -u_32_t nflags; +int +ipf_nat_out(fin, nat, natadd, nflags) + fr_info_t *fin; + nat_t *nat; + int natadd; + u_32_t nflags; { + ipf_main_softc_t *softc = fin->fin_main_soft; + ipf_nat_softc_t *softn = softc->ipf_nat_soft; icmphdr_t *icmp; - u_short *csump; tcphdr_t *tcp; ipnat_t *np; + int skip; int i; tcp = NULL; icmp = NULL; - csump = NULL; np = nat->nat_ptr; if ((natadd != 0) && (fin->fin_flx & FI_FRAG) && (np != NULL)) - (void) fr_nat_newfrag(fin, 0, nat); - - MUTEX_ENTER(&nat->nat_lock); - nat->nat_bytes[1] += fin->fin_plen; - nat->nat_pkts[1]++; - MUTEX_EXIT(&nat->nat_lock); + (void) ipf_frag_natnew(softc, fin, 0, nat); /* * Fix up checksums, not by recalculating them, but @@ -3946,90 +5097,240 @@ u_32_t nflags; * IPFilter is called before the checksum needs calculating so there * is no call to modify whatever is in the header now. */ - if (fin->fin_v == 4) { - if (nflags == IPN_ICMPERR) { - u_32_t s1, s2, sumd; + if (nflags == IPN_ICMPERR) { + u_32_t s1, s2, sumd, msumd; - s1 = LONG_SUM(ntohl(fin->fin_saddr)); - s2 = LONG_SUM(ntohl(nat->nat_outip.s_addr)); - CALC_SUMD(s1, s2, sumd); - fix_outcksum(fin, &fin->fin_ip->ip_sum, sumd); + s1 = LONG_SUM(ntohl(fin->fin_saddr)); + if (nat->nat_dir == NAT_OUTBOUND) { + s2 = LONG_SUM(ntohl(nat->nat_nsrcaddr)); + } else { + s2 = LONG_SUM(ntohl(nat->nat_odstaddr)); } + CALC_SUMD(s1, s2, sumd); + msumd = sumd; + + s1 = LONG_SUM(ntohl(fin->fin_daddr)); + if (nat->nat_dir == NAT_OUTBOUND) { + s2 = LONG_SUM(ntohl(nat->nat_ndstaddr)); + } else { + s2 = LONG_SUM(ntohl(nat->nat_osrcaddr)); + } + CALC_SUMD(s1, s2, sumd); + msumd += sumd; + + ipf_fix_outcksum(0, &fin->fin_ip->ip_sum, msumd, 0); + } #if !defined(_KERNEL) || defined(MENTAT) || defined(__sgi) || \ defined(linux) || defined(BRIDGE_IPF) - else { - /* - * Strictly speaking, this isn't necessary on BSD - * kernels because they do checksum calculation after - * this code has run BUT if ipfilter is being used - * to do NAT as a bridge, that code doesn't exist. - */ - if (nat->nat_dir == NAT_OUTBOUND) - fix_outcksum(fin, &fin->fin_ip->ip_sum, - nat->nat_ipsumd); - else - fix_incksum(fin, &fin->fin_ip->ip_sum, - nat->nat_ipsumd); + else { + /* + * Strictly speaking, this isn't necessary on BSD + * kernels because they do checksum calculation after + * this code has run BUT if ipfilter is being used + * to do NAT as a bridge, that code doesn't exist. + */ + switch (nat->nat_dir) + { + case NAT_OUTBOUND : + ipf_fix_outcksum(fin->fin_cksum & FI_CK_L4PART, + &fin->fin_ip->ip_sum, + nat->nat_ipsumd, 0); + break; + + case NAT_INBOUND : + ipf_fix_incksum(fin->fin_cksum & FI_CK_L4PART, + &fin->fin_ip->ip_sum, + nat->nat_ipsumd, 0); + break; + + default : + break; } + } #endif + + /* + * Address assignment is after the checksum modification because + * we are using the address in the packet for determining the + * correct checksum offset (the ICMP error could be coming from + * anyone...) + */ + switch (nat->nat_dir) + { + case NAT_OUTBOUND : + fin->fin_ip->ip_src = nat->nat_nsrcip; + fin->fin_saddr = nat->nat_nsrcaddr; + fin->fin_ip->ip_dst = nat->nat_ndstip; + fin->fin_daddr = nat->nat_ndstaddr; + break; + + case NAT_INBOUND : + fin->fin_ip->ip_src = nat->nat_odstip; + fin->fin_saddr = nat->nat_ndstaddr; + fin->fin_ip->ip_dst = nat->nat_osrcip; + fin->fin_daddr = nat->nat_nsrcaddr; + break; + + case NAT_DIVERTIN : + { + mb_t *m; + + skip = ipf_nat_decap(fin, nat); + if (skip <= 0) { + NBUMPSIDED(1, ns_decap_fail); + return -1; + } + + m = fin->fin_m; + +#if defined(MENTAT) && defined(_KERNEL) + m->b_rptr += skip; +#else + m->m_data += skip; + m->m_len -= skip; + +# ifdef M_PKTHDR + if (m->m_flags & M_PKTHDR) + m->m_pkthdr.len -= skip; +# endif +#endif + + MUTEX_ENTER(&nat->nat_lock); + ipf_nat_update(fin, nat); + MUTEX_EXIT(&nat->nat_lock); + fin->fin_flx |= FI_NATED; + if (np != NULL && np->in_tag.ipt_num[0] != 0) + fin->fin_nattag = &np->in_tag; + return 1; + /* NOTREACHED */ + } + + case NAT_DIVERTOUT : + { + u_32_t s1, s2, sumd; + udphdr_t *uh; + ip_t *ip; + mb_t *m; + + m = M_DUP(np->in_divmp); + if (m == NULL) { + NBUMPSIDED(1, ns_divert_dup); + return -1; + } + + ip = MTOD(m, ip_t *); + ip->ip_id = htons(ipf_nextipid(fin)); + s2 = ntohs(ip->ip_id); + + s1 = ip->ip_len; + ip->ip_len = ntohs(ip->ip_len); + ip->ip_len += fin->fin_plen; + ip->ip_len = htons(ip->ip_len); + s2 += ntohs(ip->ip_len); + CALC_SUMD(s1, s2, sumd); + + uh = (udphdr_t *)(ip + 1); + uh->uh_ulen += fin->fin_plen; + uh->uh_ulen = htons(uh->uh_ulen); +#if !defined(_KERNEL) || defined(MENTAT) || defined(__sgi) || \ + defined(linux) || defined(BRIDGE_IPF) + ipf_fix_outcksum(0, &ip->ip_sum, sumd, 0); +#endif + + PREP_MB_T(fin, m); + + fin->fin_src = ip->ip_src; + fin->fin_dst = ip->ip_dst; + fin->fin_ip = ip; + fin->fin_plen += sizeof(ip_t) + 8; /* UDP + IPv4 hdr */ + fin->fin_dlen += sizeof(ip_t) + 8; /* UDP + IPv4 hdr */ + + nflags &= ~IPN_TCPUDPICMP; + + break; + } + + default : + break; } if (!(fin->fin_flx & FI_SHORT) && (fin->fin_off == 0)) { - if ((nat->nat_outport != 0) && (nflags & IPN_TCPUDP)) { + u_short *csump; + + if ((nat->nat_nsport != 0) && (nflags & IPN_TCPUDP)) { tcp = fin->fin_dp; - tcp->th_sport = nat->nat_outport; - fin->fin_data[0] = ntohs(nat->nat_outport); + switch (nat->nat_dir) + { + case NAT_OUTBOUND : + tcp->th_sport = nat->nat_nsport; + fin->fin_data[0] = ntohs(nat->nat_nsport); + tcp->th_dport = nat->nat_ndport; + fin->fin_data[1] = ntohs(nat->nat_ndport); + break; + + case NAT_INBOUND : + tcp->th_sport = nat->nat_odport; + fin->fin_data[0] = ntohs(nat->nat_odport); + tcp->th_dport = nat->nat_osport; + fin->fin_data[1] = ntohs(nat->nat_osport); + break; + } } - if ((nat->nat_outport != 0) && (nflags & IPN_ICMPQUERY)) { + if ((nat->nat_nsport != 0) && (nflags & IPN_ICMPQUERY)) { icmp = fin->fin_dp; - icmp->icmp_id = nat->nat_outport; + icmp->icmp_id = nat->nat_nicmpid; } - csump = nat_proto(fin, nat, nflags); + csump = ipf_nat_proto(fin, nat, nflags); + + /* + * The above comments do not hold for layer 4 (or higher) + * checksums... + */ + if (csump != NULL) { + if (nat->nat_dir == NAT_OUTBOUND) + ipf_fix_outcksum(fin->fin_cksum, csump, + nat->nat_sumd[0], + nat->nat_sumd[1] + + fin->fin_dlen); + else + ipf_fix_incksum(fin->fin_cksum, csump, + nat->nat_sumd[0], + nat->nat_sumd[1] + + fin->fin_dlen); + } } - fin->fin_ip->ip_src = nat->nat_outip; - - nat_update(fin, nat, np); - - /* - * The above comments do not hold for layer 4 (or higher) checksums... - */ - if (csump != NULL) { - if (nat->nat_dir == NAT_OUTBOUND) - fix_outcksum(fin, csump, nat->nat_sumd[1]); - else - fix_incksum(fin, csump, nat->nat_sumd[1]); - } -#ifdef IPFILTER_SYNC - ipfsync_update(SMC_NAT, fin, nat->nat_sync); -#endif + ipf_sync_update(softc, SMC_NAT, fin, nat->nat_sync); /* ------------------------------------------------------------- */ - /* A few quick notes: */ - /* Following are test conditions prior to calling the */ - /* appr_check routine. */ - /* */ - /* A NULL tcp indicates a non TCP/UDP packet. When dealing */ - /* with a redirect rule, we attempt to match the packet's */ - /* source port against in_dport, otherwise we'd compare the */ - /* packet's destination. */ + /* A few quick notes: */ + /* Following are test conditions prior to calling the */ + /* ipf_proxy_check routine. */ + /* */ + /* A NULL tcp indicates a non TCP/UDP packet. When dealing */ + /* with a redirect rule, we attempt to match the packet's */ + /* source port against in_dport, otherwise we'd compare the */ + /* packet's destination. */ /* ------------------------------------------------------------- */ if ((np != NULL) && (np->in_apr != NULL)) { - i = appr_check(fin, nat); - if (i == 0) + i = ipf_proxy_check(fin, nat); + if (i == 0) { i = 1; - } else + } else if (i == -1) { + NBUMPSIDED(1, ns_ipf_proxy_fail); + } + } else { i = 1; - ATOMIC_INCL(nat_stats.ns_mapped[1]); + } fin->fin_flx |= FI_NATED; return i; } /* ------------------------------------------------------------------------ */ -/* Function: fr_checknatin */ +/* Function: ipf_nat_checkin */ /* Returns: int - -1 == packet failed NAT checks so block it, */ /* 0 == no packet translation occurred, */ /* 1 == packet was successfully translated. */ @@ -4043,22 +5344,31 @@ u_32_t nflags; /* NAT entry if a we matched a NAT rule. Lastly, actually change the */ /* packet header(s) as required. */ /* ------------------------------------------------------------------------ */ -int fr_checknatin(fin, passp) -fr_info_t *fin; -u_32_t *passp; +int +ipf_nat_checkin(fin, passp) + fr_info_t *fin; + u_32_t *passp; { + ipf_main_softc_t *softc; + ipf_nat_softc_t *softn; u_int nflags, natadd; + ipnat_t *np, *npnext; int rval, natfailed; struct ifnet *ifp; struct in_addr in; icmphdr_t *icmp; tcphdr_t *tcp; u_short dport; - ipnat_t *np; nat_t *nat; u_32_t iph; - if (nat_stats.ns_rules == 0 || fr_nat_lock != 0) + softc = fin->fin_main_soft; + softn = softc->ipf_nat_soft; + + if (softn->ipf_nat_lock != 0) + return 0; + if (softn->ipf_nat_stats.ns_rules == 0 && + softn->ipf_nat_instances == NULL) return 0; tcp = NULL; @@ -4085,182 +5395,213 @@ u_32_t *passp; * This is an incoming packet, so the destination is * the icmp_id and the source port equals 0 */ - if (nat_icmpquerytype4(icmp->icmp_type)) { + if ((fin->fin_flx & FI_ICMPQUERY) != 0) { nflags = IPN_ICMPQUERY; - dport = icmp->icmp_id; + dport = icmp->icmp_id; } break; default : break; } - + if ((nflags & IPN_TCPUDP)) { tcp = fin->fin_dp; - dport = tcp->th_dport; + dport = fin->fin_data[1]; } } in = fin->fin_dst; - READ_ENTER(&ipf_nat); + READ_ENTER(&softc->ipf_nat); - if (((fin->fin_flx & FI_ICMPERR) != 0) && - (nat = nat_icmperror(fin, &nflags, NAT_INBOUND))) + if ((fin->fin_p == IPPROTO_ICMP) && !(nflags & IPN_ICMPQUERY) && + (nat = ipf_nat_icmperror(fin, &nflags, NAT_INBOUND))) /*EMPTY*/; - else if ((fin->fin_flx & FI_FRAG) && (nat = fr_nat_knownfrag(fin))) + else if ((fin->fin_flx & FI_FRAG) && (nat = ipf_frag_natknown(fin))) natadd = 0; - else if ((nat = nat_inlookup(fin, nflags|NAT_SEARCH, (u_int)fin->fin_p, - fin->fin_src, in))) { + else if ((nat = ipf_nat_inlookup(fin, nflags|NAT_SEARCH, + (u_int)fin->fin_p, + fin->fin_src, in))) { nflags = nat->nat_flags; - } else { - u_32_t hv, msk, rmsk; + } else if (fin->fin_off == 0) { + u_32_t hv, msk, rmsk = 0; - RWLOCK_EXIT(&ipf_nat); - rmsk = rdr_masks; - msk = 0xffffffff; - WRITE_ENTER(&ipf_nat); /* * If there is no current entry in the nat table for this IP#, * create one for it (if there is a matching rule). */ maskloop: - iph = in.s_addr & htonl(msk); - hv = NAT_HASH_FN(iph, 0, ipf_rdrrules_sz); - for (np = rdr_rules[hv]; np; np = np->in_rnext) { + msk = softn->ipf_nat_rdr_active_masks[rmsk]; + iph = in.s_addr & msk; + hv = NAT_HASH_FN(iph, 0, softn->ipf_nat_rdrrules_sz); +retry_roundrobin: + /* TRACE (iph,msk,rmsk,hv,softn->ipf_nat_rdrrules_sz) */ + for (np = softn->ipf_nat_rdr_rules[hv]; np; np = npnext) { + npnext = np->in_rnext; if (np->in_ifps[0] && (np->in_ifps[0] != ifp)) continue; - if (np->in_v != fin->fin_v) + if (np->in_v[0] != 4) continue; - if (np->in_p && (np->in_p != fin->fin_p)) + if (np->in_pr[0] && (np->in_pr[0] != fin->fin_p)) continue; if ((np->in_flags & IPN_RF) && !(np->in_flags & nflags)) continue; if (np->in_flags & IPN_FILTER) { - if (!nat_match(fin, np)) + switch (ipf_nat_match(fin, np)) + { + case 0 : continue; + case -1 : + rval = -1; + goto inmatchfail; + case 1 : + default : + break; + } } else { - if ((in.s_addr & np->in_outmsk) != np->in_outip) + if ((in.s_addr & np->in_odstmsk) != + np->in_odstaddr) continue; - if (np->in_pmin && - ((ntohs(np->in_pmax) < ntohs(dport)) || - (ntohs(dport) < ntohs(np->in_pmin)))) + if (np->in_odport && + ((np->in_dtop < dport) || + (dport < np->in_odport))) continue; } - if (*np->in_plabel != '\0') { - if (!appr_ok(fin, tcp, np)) { + if (np->in_plabel != -1) { + if (!ipf_proxy_ok(fin, tcp, np)) { continue; } } - nat = nat_new(fin, np, NULL, nflags, NAT_INBOUND); - if (nat != NULL) { + if (np->in_flags & IPN_NO) { np->in_hits++; break; - } else - natfailed = -1; - } + } - if ((np == NULL) && (rmsk != 0)) { - while (rmsk) { - msk <<= 1; - if (rmsk & 0x80000000) - break; - rmsk <<= 1; + MUTEX_ENTER(&softn->ipf_nat_new); + /* + * If we've matched a round-robin rule but it has + * moved in the list since we got it, start over as + * this is now no longer correct. + */ + if (npnext != np->in_rnext) { + if ((np->in_flags & IPN_ROUNDR) != 0) { + MUTEX_EXIT(&softn->ipf_nat_new); + goto retry_roundrobin; + } + npnext = np->in_rnext; } - if (rmsk != 0) { - rmsk <<= 1; - goto maskloop; + + nat = ipf_nat_add(fin, np, NULL, nflags, NAT_INBOUND); + MUTEX_EXIT(&softn->ipf_nat_new); + if (nat != NULL) { + natfailed = 0; + break; } + natfailed = -1; + } + if ((np == NULL) && (rmsk < softn->ipf_nat_rdr_max)) { + rmsk++; + goto maskloop; } - MUTEX_DOWNGRADE(&ipf_nat); } + if (nat != NULL) { - rval = fr_natin(fin, nat, natadd, nflags); + rval = ipf_nat_in(fin, nat, natadd, nflags); if (rval == 1) { MUTEX_ENTER(&nat->nat_lock); - nat->nat_ref++; + ipf_nat_update(fin, nat); + nat->nat_bytes[0] += fin->fin_plen; + nat->nat_pkts[0]++; + fin->fin_pktnum = nat->nat_pkts[0]; MUTEX_EXIT(&nat->nat_lock); - nat->nat_touched = fr_ticks; - fin->fin_nat = nat; } } else rval = natfailed; - RWLOCK_EXIT(&ipf_nat); +inmatchfail: + RWLOCK_EXIT(&softc->ipf_nat); - if (rval == -1) { - if (passp != NULL) + switch (rval) + { + case -1 : + if (passp != NULL) { + DT1(frb_natv4in, fr_info_t *, fin); + NBUMPSIDED(0, ns_drop); *passp = FR_BLOCK; + fin->fin_reason = FRB_NATV4; + } fin->fin_flx |= FI_BADNAT; + NBUMPSIDED(0, ns_badnat); + break; + case 0 : + NBUMPSIDE(0, ns_ignored); + break; + case 1 : + NBUMPSIDE(0, ns_translated); + break; } return rval; } /* ------------------------------------------------------------------------ */ -/* Function: fr_natin */ +/* Function: ipf_nat_in */ /* Returns: int - -1 == packet failed NAT checks so block it, */ /* 1 == packet was successfully translated. */ /* Parameters: fin(I) - pointer to packet information */ /* nat(I) - pointer to NAT structure */ /* natadd(I) - flag indicating if it is safe to add frag cache */ /* nflags(I) - NAT flags set for this packet */ -/* Locks Held: ipf_nat (READ) */ +/* Locks Held: ipf_nat(READ) */ /* */ /* Translate a packet coming "in" on an interface. */ /* ------------------------------------------------------------------------ */ -int fr_natin(fin, nat, natadd, nflags) -fr_info_t *fin; -nat_t *nat; -int natadd; -u_32_t nflags; +int +ipf_nat_in(fin, nat, natadd, nflags) + fr_info_t *fin; + nat_t *nat; + int natadd; + u_32_t nflags; { + ipf_main_softc_t *softc = fin->fin_main_soft; + ipf_nat_softc_t *softn = softc->ipf_nat_soft; + u_32_t sumd, ipsumd, sum1, sum2; icmphdr_t *icmp; - u_short *csump; tcphdr_t *tcp; ipnat_t *np; + int skip; int i; tcp = NULL; - csump = NULL; np = nat->nat_ptr; fin->fin_fr = nat->nat_fr; if (np != NULL) { if ((natadd != 0) && (fin->fin_flx & FI_FRAG)) - (void) fr_nat_newfrag(fin, 0, nat); + (void) ipf_frag_natnew(softc, fin, 0, nat); /* ------------------------------------------------------------- */ - /* A few quick notes: */ - /* Following are test conditions prior to calling the */ - /* appr_check routine. */ - /* */ - /* A NULL tcp indicates a non TCP/UDP packet. When dealing */ - /* with a map rule, we attempt to match the packet's */ - /* source port against in_dport, otherwise we'd compare the */ - /* packet's destination. */ + /* A few quick notes: */ + /* Following are test conditions prior to calling the */ + /* ipf_proxy_check routine. */ + /* */ + /* A NULL tcp indicates a non TCP/UDP packet. When dealing */ + /* with a map rule, we attempt to match the packet's */ + /* source port against in_dport, otherwise we'd compare the */ + /* packet's destination. */ /* ------------------------------------------------------------- */ if (np->in_apr != NULL) { - i = appr_check(fin, nat); + i = ipf_proxy_check(fin, nat); if (i == -1) { + NBUMPSIDED(0, ns_ipf_proxy_fail); return -1; } } } -#ifdef IPFILTER_SYNC - ipfsync_update(SMC_NAT, fin, nat->nat_sync); -#endif - - MUTEX_ENTER(&nat->nat_lock); - nat->nat_bytes[0] += fin->fin_plen; - nat->nat_pkts[0]++; - MUTEX_EXIT(&nat->nat_lock); - - fin->fin_ip->ip_dst = nat->nat_inip; - fin->fin_fi.fi_daddr = nat->nat_inip.s_addr; - if (nflags & IPN_TCPUDP) - tcp = fin->fin_dp; + ipf_sync_update(softc, SMC_NAT, fin, nat->nat_sync); + ipsumd = nat->nat_ipsumd; /* * Fix up checksums, not by recalculating them, but * simply computing adjustments. @@ -4271,42 +5612,166 @@ u_32_t nflags; * fast forwarding (so that it doesn't need to be recomputed) but with * header checksum offloading, perhaps it is a moot point. */ + + switch (nat->nat_dir) + { + case NAT_INBOUND : + if ((fin->fin_flx & FI_ICMPERR) == 0) { + fin->fin_ip->ip_src = nat->nat_nsrcip; + fin->fin_saddr = nat->nat_nsrcaddr; + } else { + sum1 = nat->nat_osrcaddr; + sum2 = nat->nat_nsrcaddr; + CALC_SUMD(sum1, sum2, sumd); + ipsumd -= sumd; + } + fin->fin_ip->ip_dst = nat->nat_ndstip; + fin->fin_daddr = nat->nat_ndstaddr; #if !defined(_KERNEL) || defined(MENTAT) || defined(__sgi) || \ defined(__osf__) || defined(linux) - if (nat->nat_dir == NAT_OUTBOUND) - fix_incksum(fin, &fin->fin_ip->ip_sum, nat->nat_ipsumd); - else - fix_outcksum(fin, &fin->fin_ip->ip_sum, nat->nat_ipsumd); + ipf_fix_outcksum(0, &fin->fin_ip->ip_sum, ipsumd, 0); +#endif + break; + + case NAT_OUTBOUND : + if ((fin->fin_flx & FI_ICMPERR) == 0) { + fin->fin_ip->ip_src = nat->nat_odstip; + fin->fin_saddr = nat->nat_odstaddr; + } else { + sum1 = nat->nat_odstaddr; + sum2 = nat->nat_ndstaddr; + CALC_SUMD(sum1, sum2, sumd); + ipsumd -= sumd; + } + fin->fin_ip->ip_dst = nat->nat_osrcip; + fin->fin_daddr = nat->nat_osrcaddr; +#if !defined(_KERNEL) || defined(MENTAT) || defined(__sgi) || \ + defined(__osf__) || defined(linux) + ipf_fix_incksum(0, &fin->fin_ip->ip_sum, ipsumd, 0); +#endif + break; + + case NAT_DIVERTIN : + { + udphdr_t *uh; + ip_t *ip; + mb_t *m; + + m = M_DUP(np->in_divmp); + if (m == NULL) { + NBUMPSIDED(0, ns_divert_dup); + return -1; + } + + ip = MTOD(m, ip_t *); + ip->ip_id = htons(ipf_nextipid(fin)); + sum1 = ntohs(ip->ip_len); + ip->ip_len = ntohs(ip->ip_len); + ip->ip_len += fin->fin_plen; + ip->ip_len = htons(ip->ip_len); + + uh = (udphdr_t *)(ip + 1); + uh->uh_ulen += fin->fin_plen; + uh->uh_ulen = htons(uh->uh_ulen); + + sum2 = ntohs(ip->ip_id) + ntohs(ip->ip_len); + sum2 += ntohs(ip->ip_off) & IP_DF; + CALC_SUMD(sum1, sum2, sumd); + +#if !defined(_KERNEL) || defined(MENTAT) || defined(__sgi) || \ + defined(__osf__) || defined(linux) + ipf_fix_outcksum(0, &ip->ip_sum, sumd, 0); +#endif + PREP_MB_T(fin, m); + + fin->fin_ip = ip; + fin->fin_plen += sizeof(ip_t) + 8; /* UDP + new IPv4 hdr */ + fin->fin_dlen += sizeof(ip_t) + 8; /* UDP + old IPv4 hdr */ + + nflags &= ~IPN_TCPUDPICMP; + + break; + } + + case NAT_DIVERTOUT : + { + mb_t *m; + + skip = ipf_nat_decap(fin, nat); + if (skip <= 0) { + NBUMPSIDED(0, ns_decap_fail); + return -1; + } + + m = fin->fin_m; + +#if defined(MENTAT) && defined(_KERNEL) + m->b_rptr += skip; +#else + m->m_data += skip; + m->m_len -= skip; + +# ifdef M_PKTHDR + if (m->m_flags & M_PKTHDR) + m->m_pkthdr.len -= skip; +# endif #endif + ipf_nat_update(fin, nat); + nflags &= ~IPN_TCPUDPICMP; + fin->fin_flx |= FI_NATED; + if (np != NULL && np->in_tag.ipt_num[0] != 0) + fin->fin_nattag = &np->in_tag; + return 1; + /* NOTREACHED */ + } + } + if (nflags & IPN_TCPUDP) + tcp = fin->fin_dp; + if (!(fin->fin_flx & FI_SHORT) && (fin->fin_off == 0)) { - if ((nat->nat_inport != 0) && (nflags & IPN_TCPUDP)) { - tcp->th_dport = nat->nat_inport; - fin->fin_data[1] = ntohs(nat->nat_inport); + u_short *csump; + + if ((nat->nat_odport != 0) && (nflags & IPN_TCPUDP)) { + switch (nat->nat_dir) + { + case NAT_INBOUND : + tcp->th_sport = nat->nat_nsport; + fin->fin_data[0] = ntohs(nat->nat_nsport); + tcp->th_dport = nat->nat_ndport; + fin->fin_data[1] = ntohs(nat->nat_ndport); + break; + + case NAT_OUTBOUND : + tcp->th_sport = nat->nat_odport; + fin->fin_data[0] = ntohs(nat->nat_odport); + tcp->th_dport = nat->nat_osport; + fin->fin_data[1] = ntohs(nat->nat_osport); + break; + } } - if ((nat->nat_inport != 0) && (nflags & IPN_ICMPQUERY)) { + if ((nat->nat_odport != 0) && (nflags & IPN_ICMPQUERY)) { icmp = fin->fin_dp; - icmp->icmp_id = nat->nat_inport; + icmp->icmp_id = nat->nat_nicmpid; } - csump = nat_proto(fin, nat, nflags); + csump = ipf_nat_proto(fin, nat, nflags); + + /* + * The above comments do not hold for layer 4 (or higher) + * checksums... + */ + if (csump != NULL) { + if (nat->nat_dir == NAT_OUTBOUND) + ipf_fix_incksum(0, csump, nat->nat_sumd[0], 0); + else + ipf_fix_outcksum(0, csump, nat->nat_sumd[0], 0); + } } - nat_update(fin, nat, np); - - /* - * The above comments do not hold for layer 4 (or higher) checksums... - */ - if (csump != NULL) { - if (nat->nat_dir == NAT_OUTBOUND) - fix_incksum(fin, csump, nat->nat_sumd[0]); - else - fix_outcksum(fin, csump, nat->nat_sumd[0]); - } - ATOMIC_INCL(nat_stats.ns_mapped[0]); fin->fin_flx |= FI_NATED; if (np != NULL && np->in_tag.ipt_num[0] != 0) fin->fin_nattag = &np->in_tag; @@ -4315,7 +5780,7 @@ u_32_t nflags; /* ------------------------------------------------------------------------ */ -/* Function: nat_proto */ +/* Function: ipf_nat_proto */ /* Returns: u_short* - pointer to transport header checksum to update, */ /* NULL if the transport protocol is not recognised */ /* as needing a checksum update. */ @@ -4328,10 +5793,11 @@ u_32_t nflags; /* that is not strictly 'address' translation, such as clamping the MSS in */ /* TCP down to a specific value, then do it from here. */ /* ------------------------------------------------------------------------ */ -u_short *nat_proto(fin, nat, nflags) -fr_info_t *fin; -nat_t *nat; -u_int nflags; +u_short * +ipf_nat_proto(fin, nat, nflags) + fr_info_t *fin; + nat_t *nat; + u_int nflags; { icmphdr_t *icmp; u_short *csump; @@ -4340,9 +5806,9 @@ u_int nflags; csump = NULL; if (fin->fin_out == 0) { - fin->fin_rev = (nat->nat_dir == NAT_OUTBOUND); + fin->fin_rev = (nat->nat_dir & NAT_OUTBOUND); } else { - fin->fin_rev = (nat->nat_dir == NAT_INBOUND); + fin->fin_rev = ((nat->nat_dir & NAT_OUTBOUND) == 0); } switch (fin->fin_p) @@ -4350,22 +5816,25 @@ u_int nflags; case IPPROTO_TCP : tcp = fin->fin_dp; - csump = &tcp->th_sum; + if ((nflags & IPN_TCP) != 0) + csump = &tcp->th_sum; /* * Do a MSS CLAMPING on a SYN packet, * only deal IPv4 for now. */ if ((nat->nat_mssclamp != 0) && (tcp->th_flags & TH_SYN) != 0) - nat_mssclamp(tcp, nat->nat_mssclamp, fin, csump); + ipf_nat_mssclamp(tcp, nat->nat_mssclamp, fin, csump); break; case IPPROTO_UDP : udp = fin->fin_dp; - if (udp->uh_sum) - csump = &udp->uh_sum; + if ((nflags & IPN_UDP) != 0) { + if (udp->uh_sum != 0) + csump = &udp->uh_sum; + } break; case IPPROTO_ICMP : @@ -4376,165 +5845,108 @@ u_int nflags; csump = &icmp->icmp_cksum; } break; + +#ifdef USE_INET6 + case IPPROTO_ICMPV6 : + { + struct icmp6_hdr *icmp6 = (struct icmp6_hdr *)fin->fin_dp; + + icmp6 = fin->fin_dp; + + if ((nflags & IPN_ICMPQUERY) != 0) { + if (icmp6->icmp6_cksum != 0) + csump = &icmp6->icmp6_cksum; + } + break; + } +#endif } return csump; } /* ------------------------------------------------------------------------ */ -/* Function: fr_natunload */ +/* Function: ipf_nat_expire */ /* Returns: Nil */ -/* Parameters: Nil */ -/* */ -/* Free all memory used by NAT structures allocated at runtime. */ -/* ------------------------------------------------------------------------ */ -void fr_natunload() -{ - ipftq_t *ifq, *ifqnext; - - (void) nat_clearlist(); - (void) nat_flushtable(); - - /* - * Proxy timeout queues are not cleaned here because although they - * exist on the NAT list, appr_unload is called after fr_natunload - * and the proxies actually are responsible for them being created. - * Should the proxy timeouts have their own list? There's no real - * justification as this is the only complication. - */ - for (ifq = nat_utqe; ifq != NULL; ifq = ifqnext) { - ifqnext = ifq->ifq_next; - if (((ifq->ifq_flags & IFQF_PROXY) == 0) && - (fr_deletetimeoutqueue(ifq) == 0)) - fr_freetimeoutqueue(ifq); - } - - if (nat_table[0] != NULL) { - KFREES(nat_table[0], sizeof(nat_t *) * ipf_nattable_sz); - nat_table[0] = NULL; - } - if (nat_table[1] != NULL) { - KFREES(nat_table[1], sizeof(nat_t *) * ipf_nattable_sz); - nat_table[1] = NULL; - } - if (nat_rules != NULL) { - KFREES(nat_rules, sizeof(ipnat_t *) * ipf_natrules_sz); - nat_rules = NULL; - } - if (rdr_rules != NULL) { - KFREES(rdr_rules, sizeof(ipnat_t *) * ipf_rdrrules_sz); - rdr_rules = NULL; - } - if (ipf_hm_maptable != NULL) { - KFREES(ipf_hm_maptable, sizeof(hostmap_t *) * ipf_hostmap_sz); - ipf_hm_maptable = NULL; - } - if (nat_stats.ns_bucketlen[0] != NULL) { - KFREES(nat_stats.ns_bucketlen[0], - sizeof(u_long *) * ipf_nattable_sz); - nat_stats.ns_bucketlen[0] = NULL; - } - if (nat_stats.ns_bucketlen[1] != NULL) { - KFREES(nat_stats.ns_bucketlen[1], - sizeof(u_long *) * ipf_nattable_sz); - nat_stats.ns_bucketlen[1] = NULL; - } - - if (fr_nat_maxbucket_reset == 1) - fr_nat_maxbucket = 0; - - if (fr_nat_init == 1) { - fr_nat_init = 0; - fr_sttab_destroy(nat_tqb); - - RW_DESTROY(&ipf_natfrag); - RW_DESTROY(&ipf_nat); - - MUTEX_DESTROY(&ipf_nat_new); - MUTEX_DESTROY(&ipf_natio); - - MUTEX_DESTROY(&nat_udptq.ifq_lock); - MUTEX_DESTROY(&nat_icmptq.ifq_lock); - MUTEX_DESTROY(&nat_iptq.ifq_lock); - } -} - - -/* ------------------------------------------------------------------------ */ -/* Function: fr_natexpire */ -/* Returns: Nil */ -/* Parameters: Nil */ +/* Parameters: softc(I) - pointer to soft context main structure */ /* */ /* Check all of the timeout queues for entries at the top which need to be */ /* expired. */ /* ------------------------------------------------------------------------ */ -void fr_natexpire() +void +ipf_nat_expire(softc) + ipf_main_softc_t *softc; { + ipf_nat_softc_t *softn = softc->ipf_nat_soft; ipftq_t *ifq, *ifqnext; ipftqent_t *tqe, *tqn; int i; SPL_INT(s); SPL_NET(s); - WRITE_ENTER(&ipf_nat); - for (ifq = nat_tqb, i = 0; ifq != NULL; ifq = ifq->ifq_next) { + WRITE_ENTER(&softc->ipf_nat); + for (ifq = softn->ipf_nat_tcptq, i = 0; ifq != NULL; + ifq = ifq->ifq_next) { for (tqn = ifq->ifq_head; ((tqe = tqn) != NULL); i++) { - if (tqe->tqe_die > fr_ticks) + if (tqe->tqe_die > softc->ipf_ticks) break; tqn = tqe->tqe_next; - nat_delete(tqe->tqe_parent, NL_EXPIRE); + ipf_nat_delete(softc, tqe->tqe_parent, NL_EXPIRE); } } - for (ifq = nat_utqe; ifq != NULL; ifq = ifqnext) { - ifqnext = ifq->ifq_next; - + for (ifq = softn->ipf_nat_utqe; ifq != NULL; ifq = ifq->ifq_next) { for (tqn = ifq->ifq_head; ((tqe = tqn) != NULL); i++) { - if (tqe->tqe_die > fr_ticks) + if (tqe->tqe_die > softc->ipf_ticks) break; tqn = tqe->tqe_next; - nat_delete(tqe->tqe_parent, NL_EXPIRE); + ipf_nat_delete(softc, tqe->tqe_parent, NL_EXPIRE); } } - for (ifq = nat_utqe; ifq != NULL; ifq = ifqnext) { + for (ifq = softn->ipf_nat_utqe; ifq != NULL; ifq = ifqnext) { ifqnext = ifq->ifq_next; if (((ifq->ifq_flags & IFQF_DELETE) != 0) && (ifq->ifq_ref == 0)) { - fr_freetimeoutqueue(ifq); + ipf_freetimeoutqueue(softc, ifq); } } - if (fr_nat_doflush != 0) { - nat_extraflush(2); - fr_nat_doflush = 0; + if (softn->ipf_nat_doflush != 0) { + ipf_nat_extraflush(softc, softn, 2); + softn->ipf_nat_doflush = 0; } - RWLOCK_EXIT(&ipf_nat); + RWLOCK_EXIT(&softc->ipf_nat); SPL_X(s); } /* ------------------------------------------------------------------------ */ -/* Function: fr_natsync */ +/* Function: ipf_nat_sync */ /* Returns: Nil */ -/* Parameters: ifp(I) - pointer to network interface */ +/* Parameters: softc(I) - pointer to soft context main structure */ +/* ifp(I) - pointer to network interface */ /* */ /* Walk through all of the currently active NAT sessions, looking for those */ /* which need to have their translated address updated. */ /* ------------------------------------------------------------------------ */ -void fr_natsync(ifp) -void *ifp; +void +ipf_nat_sync(softc, ifp) + ipf_main_softc_t *softc; + void *ifp; { + ipf_nat_softc_t *softn = softc->ipf_nat_soft; u_32_t sum1, sum2, sumd; - struct in_addr in; + i6addr_t in; ipnat_t *n; nat_t *nat; void *ifp2; + int idx; SPL_INT(s); - if (fr_running <= 0) + if (softc->ipf_running <= 0) return; /* @@ -4544,28 +5956,63 @@ void *ifp; * where the rule specifies the address is taken from the interface. */ SPL_NET(s); - WRITE_ENTER(&ipf_nat); + WRITE_ENTER(&softc->ipf_nat); - if (fr_running <= 0) { - RWLOCK_EXIT(&ipf_nat); + if (softc->ipf_running <= 0) { + RWLOCK_EXIT(&softc->ipf_nat); return; } - for (nat = nat_instances; nat; nat = nat->nat_next) { + for (nat = softn->ipf_nat_instances; nat; nat = nat->nat_next) { if ((nat->nat_flags & IPN_TCP) != 0) continue; + n = nat->nat_ptr; - if ((n == NULL) || - (n->in_outip != 0) || (n->in_outmsk != 0xffffffff)) - continue; + if (n != NULL) { + if (n->in_v[1] == 4) { + if (n->in_redir & NAT_MAP) { + if ((n->in_nsrcaddr != 0) || + (n->in_nsrcmsk != 0xffffffff)) + continue; + } else if (n->in_redir & NAT_REDIRECT) { + if ((n->in_ndstaddr != 0) || + (n->in_ndstmsk != 0xffffffff)) + continue; + } + } +#ifdef USE_INET6 + if (n->in_v[1] == 4) { + if (n->in_redir & NAT_MAP) { + if (!IP6_ISZERO(&n->in_nsrcaddr) || + !IP6_ISONES(&n->in_nsrcmsk)) + continue; + } else if (n->in_redir & NAT_REDIRECT) { + if (!IP6_ISZERO(&n->in_ndstaddr) || + !IP6_ISONES(&n->in_ndstmsk)) + continue; + } + } +#endif + } + if (((ifp == NULL) || (ifp == nat->nat_ifps[0]) || (ifp == nat->nat_ifps[1]))) { - nat->nat_ifps[0] = GETIFP(nat->nat_ifnames[0], 4); + nat->nat_ifps[0] = GETIFP(nat->nat_ifnames[0], + nat->nat_v[0]); + if ((nat->nat_ifps[0] != NULL) && + (nat->nat_ifps[0] != (void *)-1)) { + nat->nat_mtu[0] = GETIFMTU_4(nat->nat_ifps[0]); + } if (nat->nat_ifnames[1][0] != '\0') { nat->nat_ifps[1] = GETIFP(nat->nat_ifnames[1], - 4); - } else + nat->nat_v[1]); + } else { nat->nat_ifps[1] = nat->nat_ifps[0]; + } + if ((nat->nat_ifps[1] != NULL) && + (nat->nat_ifps[1] != (void *)-1)) { + nat->nat_mtu[1] = GETIFMTU_4(nat->nat_ifps[1]); + } ifp2 = nat->nat_ifps[0]; if (ifp2 == NULL) continue; @@ -4574,10 +6021,13 @@ void *ifp; * Change the map-to address to be the same as the * new one. */ - sum1 = nat->nat_outip.s_addr; - if (fr_ifpaddr(4, FRI_NORMAL, ifp2, &in, NULL) != -1) - nat->nat_outip = in; - sum2 = nat->nat_outip.s_addr; + sum1 = NATFSUM(nat, nat->nat_v[1], nat_nsrc6); + if (ipf_ifpaddr(softc, nat->nat_v[0], FRI_NORMAL, ifp2, + &in, NULL) != -1) { + if (nat->nat_v[0] == 4) + nat->nat_nsrcip = in.in4; + } + sum2 = NATFSUM(nat, nat->nat_v[1], nat_nsrc6); if (sum1 == sum2) continue; @@ -4595,27 +6045,53 @@ void *ifp; } } - for (n = nat_list; (n != NULL); n = n->in_next) { + for (n = softn->ipf_nat_list; (n != NULL); n = n->in_next) { + char *base = n->in_names; + if ((ifp == NULL) || (n->in_ifps[0] == ifp)) - n->in_ifps[0] = fr_resolvenic(n->in_ifnames[0], 4); + n->in_ifps[0] = ipf_resolvenic(softc, + base + n->in_ifnames[0], + n->in_v[0]); if ((ifp == NULL) || (n->in_ifps[1] == ifp)) - n->in_ifps[1] = fr_resolvenic(n->in_ifnames[1], 4); + n->in_ifps[1] = ipf_resolvenic(softc, + base + n->in_ifnames[1], + n->in_v[1]); + + if (n->in_redir & NAT_REDIRECT) + idx = 1; + else + idx = 0; + + if (((ifp == NULL) || (n->in_ifps[idx] == ifp)) && + (n->in_ifps[idx] != NULL && + n->in_ifps[idx] != (void *)-1)) { + + ipf_nat_nextaddrinit(softc, n->in_names, &n->in_osrc, + 0, n->in_ifps[idx]); + ipf_nat_nextaddrinit(softc, n->in_names, &n->in_odst, + 0, n->in_ifps[idx]); + ipf_nat_nextaddrinit(softc, n->in_names, &n->in_nsrc, + 0, n->in_ifps[idx]); + ipf_nat_nextaddrinit(softc, n->in_names, &n->in_ndst, + 0, n->in_ifps[idx]); + } } - RWLOCK_EXIT(&ipf_nat); + RWLOCK_EXIT(&softc->ipf_nat); SPL_X(s); } /* ------------------------------------------------------------------------ */ -/* Function: nat_icmpquerytype4 */ +/* Function: ipf_nat_icmpquerytype */ /* Returns: int - 1 == success, 0 == failure */ /* Parameters: icmptype(I) - ICMP type number */ /* */ /* Tests to see if the ICMP type number passed is a query/response type or */ /* not. */ /* ------------------------------------------------------------------------ */ -static int nat_icmpquerytype4(icmptype) -int icmptype; +static int +ipf_nat_icmpquerytype(icmptype) + int icmptype; { /* @@ -4627,10 +6103,8 @@ int icmptype; * altough it seems silly to call a reply a query, this is exactly * as it is defined in the IPv4 specification */ - switch (icmptype) { - case ICMP_ECHOREPLY: case ICMP_ECHO: /* route aedvertisement/solliciation is currently unsupported: */ @@ -4651,14 +6125,19 @@ int icmptype; /* ------------------------------------------------------------------------ */ /* Function: nat_log */ /* Returns: Nil */ -/* Parameters: nat(I) - pointer to NAT structure */ -/* type(I) - type of log entry to create */ +/* Parameters: softc(I) - pointer to soft context main structure */ +/* softn(I) - pointer to NAT context structure */ +/* nat(I) - pointer to NAT structure */ +/* action(I) - action related to NAT structure being performed */ /* */ /* Creates a NAT log entry. */ /* ------------------------------------------------------------------------ */ -void nat_log(nat, type) -struct nat *nat; -u_int type; +void +ipf_nat_log(softc, softn, nat, action) + ipf_main_softc_t *softc; + ipf_nat_softc_t *softn; + struct nat *nat; + u_int action; { #ifdef IPFILTER_LOG # ifndef LARGE_NAT @@ -4670,22 +6149,40 @@ u_int type; size_t sizes[1]; int types[1]; - natl.nl_inip = nat->nat_inip; - natl.nl_outip = nat->nat_outip; - natl.nl_origip = nat->nat_oip; + bcopy((char *)&nat->nat_osrc6, (char *)&natl.nl_osrcip, + sizeof(natl.nl_osrcip)); + bcopy((char *)&nat->nat_nsrc6, (char *)&natl.nl_nsrcip, + sizeof(natl.nl_nsrcip)); + bcopy((char *)&nat->nat_odst6, (char *)&natl.nl_odstip, + sizeof(natl.nl_odstip)); + bcopy((char *)&nat->nat_ndst6, (char *)&natl.nl_ndstip, + sizeof(natl.nl_ndstip)); + natl.nl_bytes[0] = nat->nat_bytes[0]; natl.nl_bytes[1] = nat->nat_bytes[1]; natl.nl_pkts[0] = nat->nat_pkts[0]; natl.nl_pkts[1] = nat->nat_pkts[1]; - natl.nl_origport = nat->nat_oport; - natl.nl_inport = nat->nat_inport; - natl.nl_outport = nat->nat_outport; - natl.nl_p = nat->nat_p; - natl.nl_type = type; + natl.nl_odstport = nat->nat_odport; + natl.nl_osrcport = nat->nat_osport; + natl.nl_nsrcport = nat->nat_nsport; + natl.nl_ndstport = nat->nat_ndport; + natl.nl_p[0] = nat->nat_pr[0]; + natl.nl_p[1] = nat->nat_pr[1]; + natl.nl_v[0] = nat->nat_v[0]; + natl.nl_v[1] = nat->nat_v[1]; + natl.nl_type = nat->nat_redir; + natl.nl_action = action; natl.nl_rule = -1; + + bcopy(nat->nat_ifnames[0], natl.nl_ifnames[0], + sizeof(nat->nat_ifnames[0])); + bcopy(nat->nat_ifnames[1], natl.nl_ifnames[1], + sizeof(nat->nat_ifnames[1])); + # ifndef LARGE_NAT if (nat->nat_ptr != NULL) { - for (rulen = 0, np = nat_list; np; np = np->in_next, rulen++) + for (rulen = 0, np = softn->ipf_nat_list; np != NULL; + np = np->in_next, rulen++) if (np == nat->nat_ptr) { natl.nl_rule = rulen; break; @@ -4696,63 +6193,108 @@ u_int type; sizes[0] = sizeof(natl); types[0] = 0; - (void) ipllog(IPL_LOGNAT, NULL, items, sizes, types, 1); + (void) ipf_log_items(softc, IPL_LOGNAT, NULL, items, sizes, types, 1); #endif } #if defined(__OpenBSD__) /* ------------------------------------------------------------------------ */ -/* Function: nat_ifdetach */ +/* Function: ipf_nat_ifdetach */ /* Returns: Nil */ /* Parameters: ifp(I) - pointer to network interface */ /* */ /* Compatibility interface for OpenBSD to trigger the correct updating of */ /* interface references within IPFilter. */ /* ------------------------------------------------------------------------ */ -void nat_ifdetach(ifp) -void *ifp; +void +ipf_nat_ifdetach(ifp) + void *ifp; { - frsync(ifp); + ipf_main_softc_t *softc; + + softc = ipf_get_softc(0); + + ipf_sync(ifp); return; } #endif /* ------------------------------------------------------------------------ */ -/* Function: fr_ipnatderef */ +/* Function: ipf_nat_rule_deref */ /* Returns: Nil */ -/* Parameters: isp(I) - pointer to pointer to NAT rule */ +/* Parameters: softc(I) - pointer to soft context main structure */ +/* inp(I) - pointer to pointer to NAT rule */ /* Write Locks: ipf_nat */ /* */ +/* Dropping the refernce count for a rule means that whatever held the */ +/* pointer to this rule (*inp) is no longer interested in it and when the */ +/* reference count drops to zero, any resources allocated for the rule can */ +/* be released and the rule itself free'd. */ /* ------------------------------------------------------------------------ */ -void fr_ipnatderef(inp) -ipnat_t **inp; +void +ipf_nat_rule_deref(softc, inp) + ipf_main_softc_t *softc; + ipnat_t **inp; { - ipnat_t *in; + ipf_nat_softc_t *softn = softc->ipf_nat_soft; + ipnat_t *n; - in = *inp; + n = *inp; *inp = NULL; - in->in_space++; - in->in_use--; - if (in->in_use == 0 && (in->in_flags & IPN_DELETE)) { - if (in->in_apr) - appr_free(in->in_apr); - MUTEX_DESTROY(&in->in_lock); - KFREE(in); - nat_stats.ns_rules--; -#if SOLARIS && !defined(_INET_IP_STACK_H) - if (nat_stats.ns_rules == 0) - pfil_delayed_copy = 1; -#endif + n->in_use--; + if (n->in_use > 0) + return; + + if (n->in_apr != NULL) + ipf_proxy_deref(n->in_apr); + + ipf_nat_rule_fini(softc, n); + + if (n->in_redir & NAT_REDIRECT) { + if ((n->in_flags & IPN_PROXYRULE) == 0) { + ATOMIC_DEC32(softn->ipf_nat_stats.ns_rules_rdr); + } } + if (n->in_redir & (NAT_MAP|NAT_MAPBLK)) { + if ((n->in_flags & IPN_PROXYRULE) == 0) { + ATOMIC_DEC32(softn->ipf_nat_stats.ns_rules_map); + } + } + + if (n->in_tqehead[0] != NULL) { + if (ipf_deletetimeoutqueue(n->in_tqehead[0]) == 0) { + ipf_freetimeoutqueue(softc, n->in_tqehead[1]); + } + } + + if (n->in_tqehead[1] != NULL) { + if (ipf_deletetimeoutqueue(n->in_tqehead[1]) == 0) { + ipf_freetimeoutqueue(softc, n->in_tqehead[1]); + } + } + + if ((n->in_flags & IPN_PROXYRULE) == 0) { + ATOMIC_DEC32(softn->ipf_nat_stats.ns_rules); + } + + MUTEX_DESTROY(&n->in_lock); + + KFREES(n, n->in_size); + +#if SOLARIS && !defined(INSTANCES) + if (softn->ipf_nat_stats.ns_rules == 0) + pfil_delayed_copy = 1; +#endif } /* ------------------------------------------------------------------------ */ -/* Function: fr_natderef */ +/* Function: ipf_nat_deref */ /* Returns: Nil */ -/* Parameters: isp(I) - pointer to pointer to NAT table entry */ +/* Parameters: softc(I) - pointer to soft context main structure */ +/* natp(I) - pointer to pointer to NAT table entry */ /* */ /* Decrement the reference counter for this NAT table entry and free it if */ /* there are no more things using it. */ @@ -4765,8 +6307,10 @@ ipnat_t **inp; /* Holding the lock on nat_lock is required to serialise nat_delete() being */ /* called from a NAT flush ioctl with a deref happening because of a packet.*/ /* ------------------------------------------------------------------------ */ -void fr_natderef(natp) -nat_t **natp; +void +ipf_nat_deref(softc, natp) + ipf_main_softc_t *softc; + nat_t **natp; { nat_t *nat; @@ -4776,19 +6320,20 @@ nat_t **natp; MUTEX_ENTER(&nat->nat_lock); if (nat->nat_ref > 1) { nat->nat_ref--; + ASSERT(nat->nat_ref >= 0); MUTEX_EXIT(&nat->nat_lock); return; } MUTEX_EXIT(&nat->nat_lock); - WRITE_ENTER(&ipf_nat); - nat_delete(nat, NL_EXPIRE); - RWLOCK_EXIT(&ipf_nat); + WRITE_ENTER(&softc->ipf_nat); + ipf_nat_delete(softc, nat, NL_EXPIRE); + RWLOCK_EXIT(&softc->ipf_nat); } /* ------------------------------------------------------------------------ */ -/* Function: fr_natclone */ +/* Function: ipf_nat_clone */ /* Returns: ipstate_t* - NULL == cloning failed, */ /* else pointer to new state structure */ /* Parameters: fin(I) - pointer to packet information */ @@ -4797,24 +6342,30 @@ nat_t **natp; /* */ /* Create a "duplcate" state table entry from the master. */ /* ------------------------------------------------------------------------ */ -static nat_t *fr_natclone(fin, nat) -fr_info_t *fin; -nat_t *nat; +nat_t * +ipf_nat_clone(fin, nat) + fr_info_t *fin; + nat_t *nat; { + ipf_main_softc_t *softc = fin->fin_main_soft; + ipf_nat_softc_t *softn = softc->ipf_nat_soft; frentry_t *fr; nat_t *clone; ipnat_t *np; KMALLOC(clone, nat_t *); - if (clone == NULL) + if (clone == NULL) { + NBUMPSIDED(fin->fin_out, ns_clone_nomem); return NULL; + } bcopy((char *)nat, (char *)clone, sizeof(*clone)); MUTEX_NUKE(&clone->nat_lock); + clone->nat_rev = fin->fin_rev; clone->nat_aps = NULL; /* - * Initialize all these so that nat_delete() doesn't cause a crash. + * Initialize all these so that ipf_nat_delete() doesn't cause a crash. */ clone->nat_tqe.tqe_pnext = NULL; clone->nat_tqe.tqe_next = NULL; @@ -4827,14 +6378,16 @@ nat_t *nat; if (clone->nat_hm) clone->nat_hm->hm_ref++; - if (nat_insert(clone, fin->fin_rev) == -1) { + if (ipf_nat_insert(softc, softn, clone) == -1) { KFREE(clone); + NBUMPSIDED(fin->fin_out, ns_insert_fail); return NULL; } + np = clone->nat_ptr; if (np != NULL) { - if (nat_logging) - nat_log(clone, (u_int)np->in_redir); + if (softn->ipf_nat_logging) + ipf_nat_log(softc, softn, clone, NL_CLONE); np->in_use++; } fr = clone->nat_fr; @@ -4844,26 +6397,25 @@ nat_t *nat; MUTEX_EXIT(&fr->fr_lock); } + /* * Because the clone is created outside the normal loop of things and * TCP has special needs in terms of state, initialise the timeout * state of the new NAT from here. */ - if (clone->nat_p == IPPROTO_TCP) { - (void) fr_tcp_age(&clone->nat_tqe, fin, nat_tqb, - clone->nat_flags); + if (clone->nat_pr[0] == IPPROTO_TCP) { + (void) ipf_tcp_age(&clone->nat_tqe, fin, softn->ipf_nat_tcptq, + clone->nat_flags, 2); } -#ifdef IPFILTER_SYNC - clone->nat_sync = ipfsync_new(SMC_NAT, fin, clone); -#endif - if (nat_logging) - nat_log(clone, NL_CLONE); + clone->nat_sync = ipf_sync_new(softc, SMC_NAT, fin, clone); + if (softn->ipf_nat_logging) + ipf_nat_log(softc, softn, clone, NL_CLONE); return clone; } /* ------------------------------------------------------------------------ */ -/* Function: nat_wildok */ +/* Function: ipf_nat_wildok */ /* Returns: int - 1 == packet's ports match wildcards */ /* 0 == packet's ports don't match wildcards */ /* Parameters: nat(I) - NAT entry */ @@ -4875,12 +6427,10 @@ nat_t *nat; /* Use NAT entry and packet direction to determine which combination of */ /* wildcard flags should be used. */ /* ------------------------------------------------------------------------ */ -static int nat_wildok(nat, sport, dport, flags, dir) -nat_t *nat; -int sport; -int dport; -int flags; -int dir; +int +ipf_nat_wildok(nat, sport, dport, flags, dir) + nat_t *nat; + int sport, dport, flags, dir; { /* * When called by dir is set to @@ -4891,34 +6441,33 @@ int dir; * "intended" direction of that NAT entry in nat->nat_dir to decide * which combination of wildcard flags to allow. */ - - switch ((dir << 1) | nat->nat_dir) + switch ((dir << 1) | (nat->nat_dir & (NAT_INBOUND|NAT_OUTBOUND))) { case 3: /* outbound packet / outbound entry */ - if (((nat->nat_inport == sport) || + if (((nat->nat_osport == sport) || (flags & SI_W_SPORT)) && - ((nat->nat_oport == dport) || + ((nat->nat_odport == dport) || (flags & SI_W_DPORT))) return 1; break; case 2: /* outbound packet / inbound entry */ - if (((nat->nat_outport == sport) || - (flags & SI_W_DPORT)) && - ((nat->nat_oport == dport) || - (flags & SI_W_SPORT))) + if (((nat->nat_osport == dport) || + (flags & SI_W_SPORT)) && + ((nat->nat_odport == sport) || + (flags & SI_W_DPORT))) return 1; break; case 1: /* inbound packet / outbound entry */ - if (((nat->nat_oport == sport) || - (flags & SI_W_DPORT)) && - ((nat->nat_outport == dport) || - (flags & SI_W_SPORT))) + if (((nat->nat_osport == dport) || + (flags & SI_W_SPORT)) && + ((nat->nat_odport == sport) || + (flags & SI_W_DPORT))) return 1; break; case 0: /* inbound packet / inbound entry */ - if (((nat->nat_oport == sport) || + if (((nat->nat_osport == sport) || (flags & SI_W_SPORT)) && - ((nat->nat_outport == dport) || + ((nat->nat_odport == dport) || (flags & SI_W_DPORT))) return 1; break; @@ -4942,11 +6491,12 @@ int dir; /* then the TCP header checksum will be updated to reflect the change in */ /* the MSS. */ /* ------------------------------------------------------------------------ */ -static void nat_mssclamp(tcp, maxmss, fin, csump) -tcphdr_t *tcp; -u_32_t maxmss; -fr_info_t *fin; -u_short *csump; +static void +ipf_nat_mssclamp(tcp, maxmss, fin, csump) + tcphdr_t *tcp; + u_32_t maxmss; + fr_info_t *fin; + u_short *csump; { u_char *cp, *ep, opt; int hlen, advance; @@ -4981,7 +6531,7 @@ u_short *csump; cp[2] = maxmss / 256; cp[3] = maxmss & 0xff; CALC_SUMD(mss, maxmss, sumd); - fix_outcksum(fin, csump, sumd); + ipf_fix_outcksum(0, csump, sumd, 0); } break; default: @@ -4996,20 +6546,24 @@ u_short *csump; /* ------------------------------------------------------------------------ */ -/* Function: fr_setnatqueue */ +/* Function: ipf_nat_setqueue */ /* Returns: Nil */ -/* Parameters: nat(I)- pointer to NAT structure */ -/* rev(I) - forward(0) or reverse(1) direction */ +/* Parameters: softc(I) - pointer to soft context main structure */ +/* softn(I) - pointer to NAT context structure */ +/* nat(I)- pointer to NAT structure */ /* Locks: ipf_nat (read or write) */ /* */ /* Put the NAT entry on its default queue entry, using rev as a helped in */ /* determining which queue it should be placed on. */ /* ------------------------------------------------------------------------ */ -void fr_setnatqueue(nat, rev) -nat_t *nat; -int rev; +void +ipf_nat_setqueue(softc, softn, nat) + ipf_main_softc_t *softc; + ipf_nat_softc_t *softn; + nat_t *nat; { ipftq_t *oifq, *nifq; + int rev = nat->nat_rev; if (nat->nat_ptr != NULL) nifq = nat->nat_ptr->in_tqehead[rev]; @@ -5017,19 +6571,20 @@ int rev; nifq = NULL; if (nifq == NULL) { - switch (nat->nat_p) + switch (nat->nat_pr[0]) { case IPPROTO_UDP : - nifq = &nat_udptq; + nifq = &softn->ipf_nat_udptq; break; case IPPROTO_ICMP : - nifq = &nat_icmptq; + nifq = &softn->ipf_nat_icmptq; break; case IPPROTO_TCP : - nifq = nat_tqb + nat->nat_tqe.tqe_state[rev]; + nifq = softn->ipf_nat_tcptq + + nat->nat_tqe.tqe_state[rev]; break; default : - nifq = &nat_iptq; + nifq = &softn->ipf_nat_iptq; break; } } @@ -5040,9 +6595,9 @@ int rev; * another, else put it on the end of the newly determined queue. */ if (oifq != NULL) - fr_movequeue(&nat->nat_tqe, oifq, nifq); + ipf_movequeue(softc->ipf_ticks, &nat->nat_tqe, oifq, nifq); else - fr_queueappend(&nat->nat_tqe, nifq, nat); + ipf_queueappend(softc->ipf_ticks, &nat->nat_tqe, nifq, nat); return; } @@ -5050,244 +6605,141 @@ int rev; /* ------------------------------------------------------------------------ */ /* Function: nat_getnext */ /* Returns: int - 0 == ok, else error */ -/* Parameters: t(I) - pointer to ipftoken structure */ +/* Parameters: softc(I) - pointer to soft context main structure */ +/* t(I) - pointer to ipftoken structure */ /* itp(I) - pointer to ipfgeniter_t structure */ /* */ /* Fetch the next nat/ipnat structure pointer from the linked list and */ /* copy it out to the storage space pointed to by itp_data. The next item */ /* in the list to look at is put back in the ipftoken struture. */ -/* If we call ipf_freetoken, the accompanying pointer is set to NULL because*/ -/* ipf_freetoken will call a deref function for us and we dont want to call */ -/* that twice (second time would be in the second switch statement below. */ /* ------------------------------------------------------------------------ */ -static int nat_getnext(t, itp) -ipftoken_t *t; -ipfgeniter_t *itp; +static int +ipf_nat_getnext(softc, t, itp, objp) + ipf_main_softc_t *softc; + ipftoken_t *t; + ipfgeniter_t *itp; + ipfobj_t *objp; { + ipf_nat_softc_t *softn = softc->ipf_nat_soft; hostmap_t *hm, *nexthm = NULL, zerohm; ipnat_t *ipn, *nextipnat = NULL, zeroipn; nat_t *nat, *nextnat = NULL, zeronat; - int error = 0, count; - char *dst; + int error = 0; + void *nnext; - count = itp->igi_nitems; - if (count < 1) + if (itp->igi_nitems != 1) { + IPFERROR(60075); return ENOSPC; + } - READ_ENTER(&ipf_nat); + READ_ENTER(&softc->ipf_nat); switch (itp->igi_type) { case IPFGENITER_HOSTMAP : hm = t->ipt_data; if (hm == NULL) { - nexthm = ipf_hm_maplist; + nexthm = softn->ipf_hm_maplist; } else { nexthm = hm->hm_next; } + if (nexthm != NULL) { + ATOMIC_INC32(nexthm->hm_ref); + t->ipt_data = nexthm; + } else { + bzero(&zerohm, sizeof(zerohm)); + nexthm = &zerohm; + t->ipt_data = NULL; + } + nnext = nexthm->hm_next; break; case IPFGENITER_IPNAT : ipn = t->ipt_data; if (ipn == NULL) { - nextipnat = nat_list; + nextipnat = softn->ipf_nat_list; } else { nextipnat = ipn->in_next; } + if (nextipnat != NULL) { + ATOMIC_INC32(nextipnat->in_use); + t->ipt_data = nextipnat; + } else { + bzero(&zeroipn, sizeof(zeroipn)); + nextipnat = &zeroipn; + t->ipt_data = NULL; + } + nnext = nextipnat->in_next; break; case IPFGENITER_NAT : nat = t->ipt_data; if (nat == NULL) { - nextnat = nat_instances; + nextnat = softn->ipf_nat_instances; } else { nextnat = nat->nat_next; } + if (nextnat != NULL) { + MUTEX_ENTER(&nextnat->nat_lock); + nextnat->nat_ref++; + MUTEX_EXIT(&nextnat->nat_lock); + t->ipt_data = nextnat; + } else { + bzero(&zeronat, sizeof(zeronat)); + nextnat = &zeronat; + t->ipt_data = NULL; + } + nnext = nextnat->nat_next; break; + default : - RWLOCK_EXIT(&ipf_nat); + RWLOCK_EXIT(&softc->ipf_nat); + IPFERROR(60055); return EINVAL; } - dst = itp->igi_data; - for (;;) { - switch (itp->igi_type) - { - case IPFGENITER_HOSTMAP : - if (nexthm != NULL) { - if (count == 1) { - ATOMIC_INC32(nexthm->hm_ref); - t->ipt_data = nexthm; - } - } else { - bzero(&zerohm, sizeof(zerohm)); - nexthm = &zerohm; - count = 1; - t->ipt_data = NULL; - } - break; - - case IPFGENITER_IPNAT : - if (nextipnat != NULL) { - if (count == 1) { - MUTEX_ENTER(&nextipnat->in_lock); - nextipnat->in_use++; - MUTEX_EXIT(&nextipnat->in_lock); - t->ipt_data = nextipnat; - } - } else { - bzero(&zeroipn, sizeof(zeroipn)); - nextipnat = &zeroipn; - count = 1; - t->ipt_data = NULL; - } - break; - - case IPFGENITER_NAT : - if (nextnat != NULL) { - if (count == 1) { - MUTEX_ENTER(&nextnat->nat_lock); - nextnat->nat_ref++; - MUTEX_EXIT(&nextnat->nat_lock); - t->ipt_data = nextnat; - } - } else { - bzero(&zeronat, sizeof(zeronat)); - nextnat = &zeronat; - count = 1; - t->ipt_data = NULL; - } - break; - default : - break; - } - RWLOCK_EXIT(&ipf_nat); - - /* - * Copying out to user space needs to be done without the lock. - */ - switch (itp->igi_type) - { - case IPFGENITER_HOSTMAP : - error = COPYOUT(nexthm, dst, sizeof(*nexthm)); - if (error != 0) - error = EFAULT; - else - dst += sizeof(*nexthm); - break; - - case IPFGENITER_IPNAT : - error = COPYOUT(nextipnat, dst, sizeof(*nextipnat)); - if (error != 0) - error = EFAULT; - else - dst += sizeof(*nextipnat); - break; - - case IPFGENITER_NAT : - error = COPYOUT(nextnat, dst, sizeof(*nextnat)); - if (error != 0) - error = EFAULT; - else - dst += sizeof(*nextnat); - break; - } - - if ((count == 1) || (error != 0)) - break; - - count--; - - READ_ENTER(&ipf_nat); - - /* - * We need to have the lock again here to make sure that - * using _next is consistent. - */ - switch (itp->igi_type) - { - case IPFGENITER_HOSTMAP : - nexthm = nexthm->hm_next; - break; - case IPFGENITER_IPNAT : - nextipnat = nextipnat->in_next; - break; - case IPFGENITER_NAT : - nextnat = nextnat->nat_next; - break; - } - } + RWLOCK_EXIT(&softc->ipf_nat); + objp->ipfo_ptr = itp->igi_data; switch (itp->igi_type) { case IPFGENITER_HOSTMAP : + error = COPYOUT(nexthm, objp->ipfo_ptr, sizeof(*nexthm)); + if (error != 0) { + IPFERROR(60049); + error = EFAULT; + } if (hm != NULL) { - WRITE_ENTER(&ipf_nat); - fr_hostmapdel(&hm); - RWLOCK_EXIT(&ipf_nat); + WRITE_ENTER(&softc->ipf_nat); + ipf_nat_hostmapdel(softc, &hm); + RWLOCK_EXIT(&softc->ipf_nat); } break; + case IPFGENITER_IPNAT : + objp->ipfo_size = nextipnat->in_size; + objp->ipfo_type = IPFOBJ_IPNAT; + error = ipf_outobjk(softc, objp, nextipnat); if (ipn != NULL) { - fr_ipnatderef(&ipn); + WRITE_ENTER(&softc->ipf_nat); + ipf_nat_rule_deref(softc, &ipn); + RWLOCK_EXIT(&softc->ipf_nat); } break; + case IPFGENITER_NAT : - if (nat != NULL) { - fr_natderef(&nat); - } - break; - default : + objp->ipfo_size = sizeof(nat_t); + objp->ipfo_type = IPFOBJ_NAT; + error = ipf_outobjk(softc, objp, nextnat); + if (nat != NULL) + ipf_nat_deref(softc, &nat); + break; } - return error; -} - - -/* ------------------------------------------------------------------------ */ -/* Function: nat_iterator */ -/* Returns: int - 0 == ok, else error */ -/* Parameters: token(I) - pointer to ipftoken structure */ -/* itp(I) - pointer to ipfgeniter_t structure */ -/* */ -/* This function acts as a handler for the SIOCGENITER ioctls that use a */ -/* generic structure to iterate through a list. There are three different */ -/* linked lists of NAT related information to go through: NAT rules, active */ -/* NAT mappings and the NAT fragment cache. */ -/* ------------------------------------------------------------------------ */ -static int nat_iterator(token, itp) -ipftoken_t *token; -ipfgeniter_t *itp; -{ - int error; - - if (itp->igi_data == NULL) - return EFAULT; - - token->ipt_subtype = itp->igi_type; - - switch (itp->igi_type) - { - case IPFGENITER_HOSTMAP : - case IPFGENITER_IPNAT : - case IPFGENITER_NAT : - error = nat_getnext(token, itp); - break; - - case IPFGENITER_NATFRAG : -#ifdef USE_MUTEXES - error = fr_nextfrag(token, itp, &ipfr_natlist, - &ipfr_nattail, &ipf_natfrag); -#else - error = fr_nextfrag(token, itp, &ipfr_natlist, &ipfr_nattail); -#endif - break; - default : - error = EINVAL; - break; - } + if (nnext == NULL) + ipf_token_mark_complete(t); return error; } @@ -5296,7 +6748,9 @@ ipfgeniter_t *itp; /* ------------------------------------------------------------------------ */ /* Function: nat_extraflush */ /* Returns: int - 0 == success, -1 == failure */ -/* Parameters: which(I) - how to flush the active NAT table */ +/* Parameters: softc(I) - pointer to soft context main structure */ +/* softn(I) - pointer to NAT context structure */ +/* which(I) - how to flush the active NAT table */ /* Write Locks: ipf_nat */ /* */ /* Flush nat tables. Three actions currently defined: */ @@ -5310,45 +6764,51 @@ ipfgeniter_t *itp; /* If that too fails, then work backwards in 30 second intervals */ /* for the last 30 minutes to at worst 30 seconds idle. */ /* ------------------------------------------------------------------------ */ -static int nat_extraflush(which) -int which; +static int +ipf_nat_extraflush(softc, softn, which) + ipf_main_softc_t *softc; + ipf_nat_softc_t *softn; + int which; { - ipftq_t *ifq, *ifqnext; nat_t *nat, **natp; ipftqent_t *tqn; + ipftq_t *ifq; int removed; SPL_INT(s); removed = 0; SPL_NET(s); - switch (which) { case 0 : + softn->ipf_nat_stats.ns_flush_all++; /* * Style 0 flush removes everything... */ - for (natp = &nat_instances; ((nat = *natp) != NULL); ) { - nat_delete(nat, NL_FLUSH); + for (natp = &softn->ipf_nat_instances; + ((nat = *natp) != NULL); ) { + ipf_nat_delete(softc, nat, NL_FLUSH); removed++; } break; case 1 : + softn->ipf_nat_stats.ns_flush_closing++; /* * Since we're only interested in things that are closing, * we can start with the appropriate timeout queue. */ - for (ifq = nat_tqb + IPF_TCPS_CLOSE_WAIT; ifq != NULL; - ifq = ifq->ifq_next) { + for (ifq = softn->ipf_nat_tcptq + IPF_TCPS_CLOSE_WAIT; + ifq != NULL; ifq = ifq->ifq_next) { for (tqn = ifq->ifq_head; tqn != NULL; ) { nat = tqn->tqe_parent; tqn = tqn->tqe_next; - if (nat->nat_p != IPPROTO_TCP) + if (nat->nat_pr[0] != IPPROTO_TCP || + nat->nat_pr[1] != IPPROTO_TCP) break; - nat_delete(nat, NL_EXPIRE); + ipf_nat_delete(softc, nat, NL_EXPIRE); removed++; } } @@ -5356,19 +6816,20 @@ int which; /* * Also need to look through the user defined queues. */ - for (ifq = nat_utqe; ifq != NULL; ifq = ifqnext) { - ifqnext = ifq->ifq_next; + for (ifq = softn->ipf_nat_utqe; ifq != NULL; + ifq = ifq->ifq_next) { for (tqn = ifq->ifq_head; tqn != NULL; ) { nat = tqn->tqe_parent; tqn = tqn->tqe_next; - if (nat->nat_p != IPPROTO_TCP) + if (nat->nat_pr[0] != IPPROTO_TCP || + nat->nat_pr[1] != IPPROTO_TCP) continue; if ((nat->nat_tcpstate[0] > IPF_TCPS_ESTABLISHED) && (nat->nat_tcpstate[1] > IPF_TCPS_ESTABLISHED)) { - nat_delete(nat, NL_EXPIRE); + ipf_nat_delete(softc, nat, NL_EXPIRE); removed++; } } @@ -5386,28 +6847,31 @@ int which; case IPF_TCPS_FIN_WAIT_2 : case IPF_TCPS_TIME_WAIT : case IPF_TCPS_CLOSED : - tqn = nat_tqb[which].ifq_head; + softn->ipf_nat_stats.ns_flush_state++; + tqn = softn->ipf_nat_tcptq[which].ifq_head; while (tqn != NULL) { nat = tqn->tqe_parent; tqn = tqn->tqe_next; - nat_delete(nat, NL_FLUSH); + ipf_nat_delete(softc, nat, NL_FLUSH); removed++; } break; - + default : if (which < 30) break; - + + softn->ipf_nat_stats.ns_flush_timeout++; /* * Take a large arbitrary number to mean the number of seconds * for which which consider to be the maximum value we'll allow * the expiration to be. */ which = IPF_TTLVAL(which); - for (natp = &nat_instances; ((nat = *natp) != NULL); ) { - if (fr_ticks - nat->nat_touched > which) { - nat_delete(nat, NL_FLUSH); + for (natp = &softn->ipf_nat_instances; + ((nat = *natp) != NULL); ) { + if (softc->ipf_ticks - nat->nat_touched > which) { + ipf_nat_delete(softc, nat, NL_FLUSH); removed++; } else natp = &nat->nat_next; @@ -5420,12 +6884,25 @@ int which; return removed; } + softn->ipf_nat_stats.ns_flush_queue++; + /* - * Asked to remove inactive entries because the table is full. + * Asked to remove inactive entries because the table is full, try + * again, 3 times, if first attempt failed with a different criteria + * each time. The order tried in must be in decreasing age. + * Another alternative is to implement random drop and drop N entries + * at random until N have been freed up. */ - if (fr_ticks - nat_last_force_flush > IPF_TTLVAL(5)) { - nat_last_force_flush = fr_ticks; - removed = ipf_queueflush(nat_flush_entry, nat_tqb, nat_utqe); + if (softc->ipf_ticks - softn->ipf_nat_last_force_flush > + IPF_TTLVAL(5)) { + softn->ipf_nat_last_force_flush = softc->ipf_ticks; + + removed = ipf_queueflush(softc, ipf_nat_flush_entry, + softn->ipf_nat_tcptq, + softn->ipf_nat_utqe, + &softn->ipf_nat_stats.ns_active, + softn->ipf_nat_table_sz, + softn->ipf_nat_table_wm_low); } SPL_X(s); @@ -5434,9 +6911,10 @@ int which; /* ------------------------------------------------------------------------ */ -/* Function: nat_flush_entry */ +/* Function: ipf_nat_flush_entry */ /* Returns: 0 - always succeeds */ -/* Parameters: entry(I) - pointer to NAT entry */ +/* Parameters: softc(I) - pointer to soft context main structure */ +/* entry(I) - pointer to NAT entry */ /* Write Locks: ipf_nat */ /* */ /* This function is a stepping stone between ipf_queueflush() and */ @@ -5444,50 +6922,1673 @@ int which; /* ipf_queueflush() function. Since the nat_delete() function returns void */ /* we translate that to mean it always succeeds in deleting something. */ /* ------------------------------------------------------------------------ */ -static int nat_flush_entry(entry) -void *entry; +static int +ipf_nat_flush_entry(softc, entry) + ipf_main_softc_t *softc; + void *entry; { - nat_delete(entry, NL_FLUSH); + ipf_nat_delete(softc, entry, NL_FLUSH); return 0; } /* ------------------------------------------------------------------------ */ -/* Function: nat_gettable */ +/* Function: ipf_nat_iterator */ +/* Returns: int - 0 == ok, else error */ +/* Parameters: softc(I) - pointer to soft context main structure */ +/* token(I) - pointer to ipftoken structure */ +/* itp(I) - pointer to ipfgeniter_t structure */ +/* obj(I) - pointer to data description structure */ +/* */ +/* This function acts as a handler for the SIOCGENITER ioctls that use a */ +/* generic structure to iterate through a list. There are three different */ +/* linked lists of NAT related information to go through: NAT rules, active */ +/* NAT mappings and the NAT fragment cache. */ +/* ------------------------------------------------------------------------ */ +static int +ipf_nat_iterator(softc, token, itp, obj) + ipf_main_softc_t *softc; + ipftoken_t *token; + ipfgeniter_t *itp; + ipfobj_t *obj; +{ + int error; + + if (itp->igi_data == NULL) { + IPFERROR(60052); + return EFAULT; + } + + switch (itp->igi_type) + { + case IPFGENITER_HOSTMAP : + case IPFGENITER_IPNAT : + case IPFGENITER_NAT : + error = ipf_nat_getnext(softc, token, itp, obj); + break; + + case IPFGENITER_NATFRAG : + error = ipf_frag_nat_next(softc, token, itp); + break; + default : + IPFERROR(60053); + error = EINVAL; + break; + } + + return error; +} + + +/* ------------------------------------------------------------------------ */ +/* Function: ipf_nat_setpending */ +/* Returns: Nil */ +/* Parameters: softc(I) - pointer to soft context main structure */ +/* nat(I) - pointer to NAT structure */ +/* Locks: ipf_nat (read or write) */ +/* */ +/* Put the NAT entry on to the pending queue - this queue has a very short */ +/* lifetime where items are put that can't be deleted straight away because */ +/* of locking issues but we want to delete them ASAP, anyway. In calling */ +/* this function, it is assumed that the owner (if there is one, as shown */ +/* by nat_me) is no longer interested in it. */ +/* ------------------------------------------------------------------------ */ +void +ipf_nat_setpending(softc, nat) + ipf_main_softc_t *softc; + nat_t *nat; +{ + ipf_nat_softc_t *softn = softc->ipf_nat_soft; + ipftq_t *oifq; + + oifq = nat->nat_tqe.tqe_ifq; + if (oifq != NULL) + ipf_movequeue(softc->ipf_ticks, &nat->nat_tqe, oifq, + &softn->ipf_nat_pending); + else + ipf_queueappend(softc->ipf_ticks, &nat->nat_tqe, + &softn->ipf_nat_pending, nat); + + if (nat->nat_me != NULL) { + *nat->nat_me = NULL; + nat->nat_me = NULL; + nat->nat_ref--; + ASSERT(nat->nat_ref >= 0); + } +} + + +/* ------------------------------------------------------------------------ */ +/* Function: nat_newrewrite */ +/* Returns: int - -1 == error, 0 == success (no move), 1 == success and */ +/* allow rule to be moved if IPN_ROUNDR is set. */ +/* Parameters: fin(I) - pointer to packet information */ +/* nat(I) - pointer to NAT entry */ +/* ni(I) - pointer to structure with misc. information needed */ +/* to create new NAT entry. */ +/* Write Lock: ipf_nat */ +/* */ +/* This function is responsible for setting up an active NAT session where */ +/* we are changing both the source and destination parameters at the same */ +/* time. The loop in here works differently to elsewhere - each iteration */ +/* is responsible for changing a single parameter that can be incremented. */ +/* So one pass may increase the source IP#, next source port, next dest. IP#*/ +/* and the last destination port for a total of 4 iterations to try each. */ +/* This is done to try and exhaustively use the translation space available.*/ +/* ------------------------------------------------------------------------ */ +static int +ipf_nat_newrewrite(fin, nat, nai) + fr_info_t *fin; + nat_t *nat; + natinfo_t *nai; +{ + int src_search = 1; + int dst_search = 1; + fr_info_t frnat; + u_32_t flags; + u_short swap; + ipnat_t *np; + nat_t *natl; + int l = 0; + int changed; + + natl = NULL; + changed = -1; + np = nai->nai_np; + flags = nat->nat_flags; + bcopy((char *)fin, (char *)&frnat, sizeof(*fin)); + + nat->nat_hm = NULL; + + do { + changed = -1; + /* TRACE (l, src_search, dst_search, np) */ + + if ((src_search == 0) && (np->in_spnext == 0) && + (dst_search == 0) && (np->in_dpnext == 0)) { + if (l > 0) + return -1; + } + + /* + * Find a new source address + */ + if (ipf_nat_nextaddr(fin, &np->in_nsrc, &frnat.fin_saddr, + &frnat.fin_saddr) == -1) { + return -1; + } + + if ((np->in_nsrcaddr == 0) && (np->in_nsrcmsk == 0xffffffff)) { + src_search = 0; + if (np->in_stepnext == 0) + np->in_stepnext = 1; + + } else if ((np->in_nsrcaddr == 0) && (np->in_nsrcmsk == 0)) { + src_search = 0; + if (np->in_stepnext == 0) + np->in_stepnext = 1; + + } else if (np->in_nsrcmsk == 0xffffffff) { + src_search = 0; + if (np->in_stepnext == 0) + np->in_stepnext = 1; + + } else if (np->in_nsrcmsk != 0xffffffff) { + if (np->in_stepnext == 0 && changed == -1) { + np->in_snip++; + np->in_stepnext++; + changed = 0; + } + } + + if ((flags & IPN_TCPUDPICMP) != 0) { + if (np->in_spnext != 0) + frnat.fin_data[0] = np->in_spnext; + + /* + * Standard port translation. Select next port. + */ + if ((flags & IPN_FIXEDSPORT) != 0) { + np->in_stepnext = 2; + } else if ((np->in_stepnext == 1) && + (changed == -1) && (natl != NULL)) { + np->in_spnext++; + np->in_stepnext++; + changed = 1; + if (np->in_spnext > np->in_spmax) + np->in_spnext = np->in_spmin; + } + } else { + np->in_stepnext = 2; + } + np->in_stepnext &= 0x3; + + /* + * Find a new destination address + */ + /* TRACE (fin, np, l, frnat) */ + + if (ipf_nat_nextaddr(fin, &np->in_ndst, &frnat.fin_daddr, + &frnat.fin_daddr) == -1) + return -1; + if ((np->in_ndstaddr == 0) && (np->in_ndstmsk == 0xffffffff)) { + dst_search = 0; + if (np->in_stepnext == 2) + np->in_stepnext = 3; + + } else if ((np->in_ndstaddr == 0) && (np->in_ndstmsk == 0)) { + dst_search = 0; + if (np->in_stepnext == 2) + np->in_stepnext = 3; + + } else if (np->in_ndstmsk == 0xffffffff) { + dst_search = 0; + if (np->in_stepnext == 2) + np->in_stepnext = 3; + + } else if (np->in_ndstmsk != 0xffffffff) { + if ((np->in_stepnext == 2) && (changed == -1) && + (natl != NULL)) { + changed = 2; + np->in_stepnext++; + np->in_dnip++; + } + } + + if ((flags & IPN_TCPUDPICMP) != 0) { + if (np->in_dpnext != 0) + frnat.fin_data[1] = np->in_dpnext; + + /* + * Standard port translation. Select next port. + */ + if ((flags & IPN_FIXEDDPORT) != 0) { + np->in_stepnext = 0; + } else if (np->in_stepnext == 3 && changed == -1) { + np->in_dpnext++; + np->in_stepnext++; + changed = 3; + if (np->in_dpnext > np->in_dpmax) + np->in_dpnext = np->in_dpmin; + } + } else { + if (np->in_stepnext == 3) + np->in_stepnext = 0; + } + + /* TRACE (frnat) */ + + /* + * Here we do a lookup of the connection as seen from + * the outside. If an IP# pair already exists, try + * again. So if you have A->B becomes C->B, you can + * also have D->E become C->E but not D->B causing + * another C->B. Also take protocol and ports into + * account when determining whether a pre-existing + * NAT setup will cause an external conflict where + * this is appropriate. + * + * fin_data[] is swapped around because we are doing a + * lookup of the packet is if it were moving in the opposite + * direction of the one we are working with now. + */ + if (flags & IPN_TCPUDP) { + swap = frnat.fin_data[0]; + frnat.fin_data[0] = frnat.fin_data[1]; + frnat.fin_data[1] = swap; + } + if (fin->fin_out == 1) { + natl = ipf_nat_inlookup(&frnat, + flags & ~(SI_WILDP|NAT_SEARCH), + (u_int)frnat.fin_p, + frnat.fin_dst, frnat.fin_src); + + } else { + natl = ipf_nat_outlookup(&frnat, + flags & ~(SI_WILDP|NAT_SEARCH), + (u_int)frnat.fin_p, + frnat.fin_dst, frnat.fin_src); + } + if (flags & IPN_TCPUDP) { + swap = frnat.fin_data[0]; + frnat.fin_data[0] = frnat.fin_data[1]; + frnat.fin_data[1] = swap; + } + + /* TRACE natl, in_stepnext, l */ + + if ((natl != NULL) && (l > 8)) /* XXX 8 is arbitrary */ + return -1; + + np->in_stepnext &= 0x3; + + l++; + changed = -1; + } while (natl != NULL); + + nat->nat_osrcip = fin->fin_src; + nat->nat_odstip = fin->fin_dst; + nat->nat_nsrcip = frnat.fin_src; + nat->nat_ndstip = frnat.fin_dst; + + if ((flags & IPN_TCPUDP) != 0) { + nat->nat_osport = htons(fin->fin_data[0]); + nat->nat_odport = htons(fin->fin_data[1]); + nat->nat_nsport = htons(frnat.fin_data[0]); + nat->nat_ndport = htons(frnat.fin_data[1]); + } else if ((flags & IPN_ICMPQUERY) != 0) { + nat->nat_oicmpid = fin->fin_data[1]; + nat->nat_nicmpid = frnat.fin_data[1]; + } + + return 0; +} + + +/* ------------------------------------------------------------------------ */ +/* Function: nat_newdivert */ +/* Returns: int - -1 == error, 0 == success */ +/* Parameters: fin(I) - pointer to packet information */ +/* nat(I) - pointer to NAT entry */ +/* ni(I) - pointer to structure with misc. information needed */ +/* to create new NAT entry. */ +/* Write Lock: ipf_nat */ +/* */ +/* Create a new NAT divert session as defined by the NAT rule. This is */ +/* somewhat different to other NAT session creation routines because we */ +/* do not iterate through either port numbers or IP addresses, searching */ +/* for a unique mapping, however, a complimentary duplicate check is made. */ +/* ------------------------------------------------------------------------ */ +static int +ipf_nat_newdivert(fin, nat, nai) + fr_info_t *fin; + nat_t *nat; + natinfo_t *nai; +{ + ipf_main_softc_t *softc = fin->fin_main_soft; + ipf_nat_softc_t *softn = softc->ipf_nat_soft; + fr_info_t frnat; + ipnat_t *np; + nat_t *natl; + int p; + + np = nai->nai_np; + bcopy((char *)fin, (char *)&frnat, sizeof(*fin)); + + nat->nat_pr[0] = 0; + nat->nat_osrcaddr = fin->fin_saddr; + nat->nat_odstaddr = fin->fin_daddr; + frnat.fin_saddr = htonl(np->in_snip); + frnat.fin_daddr = htonl(np->in_dnip); + if ((nat->nat_flags & IPN_TCPUDP) != 0) { + nat->nat_osport = htons(fin->fin_data[0]); + nat->nat_odport = htons(fin->fin_data[1]); + } else if ((nat->nat_flags & IPN_ICMPQUERY) != 0) { + nat->nat_oicmpid = fin->fin_data[1]; + } + + if (np->in_redir & NAT_DIVERTUDP) { + frnat.fin_data[0] = np->in_spnext; + frnat.fin_data[1] = np->in_dpnext; + frnat.fin_flx |= FI_TCPUDP; + p = IPPROTO_UDP; + } else { + frnat.fin_flx &= ~FI_TCPUDP; + p = IPPROTO_IPIP; + } + + if (fin->fin_out == 1) { + natl = ipf_nat_inlookup(&frnat, 0, p, + frnat.fin_dst, frnat.fin_src); + + } else { + natl = ipf_nat_outlookup(&frnat, 0, p, + frnat.fin_dst, frnat.fin_src); + } + + if (natl != NULL) { + NBUMPSIDED(fin->fin_out, ns_divert_exist); + return -1; + } + + nat->nat_nsrcaddr = frnat.fin_saddr; + nat->nat_ndstaddr = frnat.fin_daddr; + if ((nat->nat_flags & IPN_TCPUDP) != 0) { + nat->nat_nsport = htons(frnat.fin_data[0]); + nat->nat_ndport = htons(frnat.fin_data[1]); + } else if ((nat->nat_flags & IPN_ICMPQUERY) != 0) { + nat->nat_nicmpid = frnat.fin_data[1]; + } + + nat->nat_pr[fin->fin_out] = fin->fin_p; + nat->nat_pr[1 - fin->fin_out] = p; + + if (np->in_redir & NAT_REDIRECT) + nat->nat_dir = NAT_DIVERTIN; + else + nat->nat_dir = NAT_DIVERTOUT; + + return 0; +} + + +/* ------------------------------------------------------------------------ */ +/* Function: nat_builddivertmp */ +/* Returns: int - -1 == error, 0 == success */ +/* Parameters: softn(I) - pointer to NAT context structure */ +/* np(I) - pointer to a NAT rule */ +/* */ +/* For divert rules, a skeleton packet representing what will be prepended */ +/* to the real packet is created. Even though we don't have the full */ +/* packet here, a checksum is calculated that we update later when we */ +/* fill in the final details. At present a 0 checksum for UDP is being set */ +/* here because it is expected that divert will be used for localhost. */ +/* ------------------------------------------------------------------------ */ +static int +ipf_nat_builddivertmp(softn, np) + ipf_nat_softc_t *softn; + ipnat_t *np; +{ + udphdr_t *uh; + size_t len; + ip_t *ip; + + if ((np->in_redir & NAT_DIVERTUDP) != 0) + len = sizeof(ip_t) + sizeof(udphdr_t); + else + len = sizeof(ip_t); + + ALLOC_MB_T(np->in_divmp, len); + if (np->in_divmp == NULL) { + NBUMPD(ipf_nat_stats, ns_divert_build); + return -1; + } + + /* + * First, the header to get the packet diverted to the new destination + */ + ip = MTOD(np->in_divmp, ip_t *); + IP_V_A(ip, 4); + IP_HL_A(ip, 5); + ip->ip_tos = 0; + if ((np->in_redir & NAT_DIVERTUDP) != 0) + ip->ip_p = IPPROTO_UDP; + else + ip->ip_p = IPPROTO_IPIP; + ip->ip_ttl = 255; + ip->ip_off = 0; + ip->ip_sum = 0; + ip->ip_len = htons(len); + ip->ip_id = 0; + ip->ip_src.s_addr = htonl(np->in_snip); + ip->ip_dst.s_addr = htonl(np->in_dnip); + ip->ip_sum = ipf_cksum((u_short *)ip, sizeof(*ip)); + + if (np->in_redir & NAT_DIVERTUDP) { + uh = (udphdr_t *)(ip + 1); + uh->uh_sum = 0; + uh->uh_ulen = 8; + uh->uh_sport = htons(np->in_spnext); + uh->uh_dport = htons(np->in_dpnext); + } + + return 0; +} + + +#define MINDECAP (sizeof(ip_t) + sizeof(udphdr_t) + sizeof(ip_t)) + +/* ------------------------------------------------------------------------ */ +/* Function: nat_decap */ +/* Returns: int - -1 == error, 0 == success */ +/* Parameters: fin(I) - pointer to packet information */ +/* nat(I) - pointer to current NAT session */ +/* */ +/* This function is responsible for undoing a packet's encapsulation in the */ +/* reverse of an encap/divert rule. After removing the outer encapsulation */ +/* it is necessary to call ipf_makefrip() again so that the contents of 'fin'*/ +/* match the "new" packet as it may still be used by IPFilter elsewhere. */ +/* We use "dir" here as the basis for some of the expectations about the */ +/* outer header. If we return an error, the goal is to leave the original */ +/* packet information undisturbed - this falls short at the end where we'd */ +/* need to back a backup copy of "fin" - expensive. */ +/* ------------------------------------------------------------------------ */ +static int +ipf_nat_decap(fin, nat) + fr_info_t *fin; + nat_t *nat; +{ + ipf_main_softc_t *softc = fin->fin_main_soft; + ipf_nat_softc_t *softn = softc->ipf_nat_soft; + char *hdr; + int hlen; + int skip; + mb_t *m; + + if ((fin->fin_flx & FI_ICMPERR) != 0) { + /* + * ICMP packets don't get decapsulated, instead what we need + * to do is change the ICMP reply from including (in the data + * portion for errors) the encapsulated packet that we sent + * out to something that resembles the original packet prior + * to encapsulation. This isn't done here - all we're doing + * here is changing the outer address to ensure that it gets + * targetted back to the correct system. + */ + + if (nat->nat_dir & NAT_OUTBOUND) { + u_32_t sum1, sum2, sumd; + + sum1 = ntohl(fin->fin_daddr); + sum2 = ntohl(nat->nat_osrcaddr); + CALC_SUMD(sum1, sum2, sumd); + fin->fin_ip->ip_dst = nat->nat_osrcip; + fin->fin_daddr = nat->nat_osrcaddr; +#if !defined(_KERNEL) || defined(MENTAT) || defined(__sgi) || \ + defined(__osf__) || defined(linux) + ipf_fix_outcksum(0, &fin->fin_ip->ip_sum, sumd, 0); +#endif + } + return 0; + } + + m = fin->fin_m; + skip = fin->fin_hlen; + + switch (nat->nat_dir) + { + case NAT_DIVERTIN : + case NAT_DIVERTOUT : + if (fin->fin_plen < MINDECAP) + return -1; + skip += sizeof(udphdr_t); + break; + + case NAT_ENCAPIN : + case NAT_ENCAPOUT : + if (fin->fin_plen < (skip + sizeof(ip_t))) + return -1; + break; + default : + return -1; + /* NOTREACHED */ + } + + /* + * The aim here is to keep the original packet details in "fin" for + * as long as possible so that returning with an error is for the + * original packet and there is little undoing work to do. + */ + if (M_LEN(m) < skip + sizeof(ip_t)) { + if (ipf_pr_pullup(fin, skip + sizeof(ip_t)) == -1) + return -1; + } + + hdr = MTOD(fin->fin_m, char *); + fin->fin_ip = (ip_t *)(hdr + skip); + hlen = IP_HL(fin->fin_ip) << 2; + + if (ipf_pr_pullup(fin, skip + hlen) == -1) { + NBUMPSIDED(fin->fin_out, ns_decap_pullup); + return -1; + } + + fin->fin_hlen = hlen; + fin->fin_dlen -= skip; + fin->fin_plen -= skip; + fin->fin_ipoff += skip; + + if (ipf_makefrip(hlen, (ip_t *)hdr, fin) == -1) { + NBUMPSIDED(fin->fin_out, ns_decap_bad); + return -1; + } + + return skip; +} + + +/* ------------------------------------------------------------------------ */ +/* Function: nat_nextaddr */ +/* Returns: int - -1 == bad input (no new address), */ +/* 0 == success and dst has new address */ +/* Parameters: fin(I) - pointer to packet information */ +/* na(I) - how to generate new address */ +/* old(I) - original address being replaced */ +/* dst(O) - where to put the new address */ +/* Write Lock: ipf_nat */ +/* */ +/* This function uses the contents of the "na" structure, in combination */ +/* with "old" to produce a new address to store in "dst". Not all of the */ +/* possible uses of "na" will result in a new address. */ +/* ------------------------------------------------------------------------ */ +static int +ipf_nat_nextaddr(fin, na, old, dst) + fr_info_t *fin; + nat_addr_t *na; + u_32_t *old, *dst; +{ + ipf_main_softc_t *softc = fin->fin_main_soft; + ipf_nat_softc_t *softn = softc->ipf_nat_soft; + u_32_t amin, amax, new; + i6addr_t newip; + int error; + + new = 0; + amin = na->na_addr[0].in4.s_addr; + + switch (na->na_atype) + { + case FRI_RANGE : + amax = na->na_addr[1].in4.s_addr; + break; + + case FRI_NETMASKED : + case FRI_DYNAMIC : + case FRI_NORMAL : + /* + * Compute the maximum address by adding the inverse of the + * netmask to the minimum address. + */ + amax = ~na->na_addr[1].in4.s_addr; + amax |= amin; + break; + + case FRI_LOOKUP : + break; + + case FRI_BROADCAST : + case FRI_PEERADDR : + case FRI_NETWORK : + default : + return -1; + } + + error = -1; + + if (na->na_atype == FRI_LOOKUP) { + if (na->na_type == IPLT_DSTLIST) { + error = ipf_dstlist_select_node(fin, na->na_ptr, dst, + NULL); + } else { + NBUMPSIDE(fin->fin_out, ns_badnextaddr); + } + + } else if (na->na_atype == IPLT_NONE) { + /* + * 0/0 as the new address means leave it alone. + */ + if (na->na_addr[0].in4.s_addr == 0 && + na->na_addr[1].in4.s_addr == 0) { + new = *old; + + /* + * 0/32 means get the interface's address + */ + } else if (na->na_addr[0].in4.s_addr == 0 && + na->na_addr[1].in4.s_addr == 0xffffffff) { + if (ipf_ifpaddr(softc, 4, na->na_atype, + fin->fin_ifp, &newip, NULL) == -1) { + NBUMPSIDED(fin->fin_out, ns_ifpaddrfail); + return -1; + } + new = newip.in4.s_addr; + } else { + new = htonl(na->na_nextip); + } + *dst = new; + error = 0; + + } else { + NBUMPSIDE(fin->fin_out, ns_badnextaddr); + } + + return error; +} + + +/* ------------------------------------------------------------------------ */ +/* Function: nat_nextaddrinit */ +/* Returns: int - 0 == success, else error number */ +/* Parameters: softc(I) - pointer to soft context main structure */ +/* na(I) - NAT address information for generating new addr*/ +/* initial(I) - flag indicating if it is the first call for */ +/* this "na" structure. */ +/* ifp(I) - network interface to derive address */ +/* information from. */ +/* */ +/* This function is expected to be called in two scenarious: when a new NAT */ +/* rule is loaded into the kernel and when the list of NAT rules is sync'd */ +/* up with the valid network interfaces (possibly due to them changing.) */ +/* To distinguish between these, the "initial" parameter is used. If it is */ +/* 1 then this indicates the rule has just been reloaded and 0 for when we */ +/* are updating information. This difference is important because in */ +/* instances where we are not updating address information associated with */ +/* a network interface, we don't want to disturb what the "next" address to */ +/* come out of ipf_nat_nextaddr() will be. */ +/* ------------------------------------------------------------------------ */ +static int +ipf_nat_nextaddrinit(softc, base, na, initial, ifp) + ipf_main_softc_t *softc; + char *base; + nat_addr_t *na; + int initial; + void *ifp; +{ + + switch (na->na_atype) + { + case FRI_LOOKUP : + if (na->na_subtype == 0) { + na->na_ptr = ipf_lookup_res_num(softc, IPL_LOGNAT, + na->na_type, + na->na_num, + &na->na_func); + } else if (na->na_subtype == 1) { + na->na_ptr = ipf_lookup_res_name(softc, IPL_LOGNAT, + na->na_type, + base + na->na_num, + &na->na_func); + } + if (na->na_func == NULL) { + IPFERROR(60060); + return ESRCH; + } + if (na->na_ptr == NULL) { + IPFERROR(60056); + return ESRCH; + } + break; + + case FRI_DYNAMIC : + case FRI_BROADCAST : + case FRI_NETWORK : + case FRI_NETMASKED : + case FRI_PEERADDR : + if (ifp != NULL) + (void )ipf_ifpaddr(softc, 4, na->na_atype, ifp, + &na->na_addr[0], &na->na_addr[1]); + break; + + case FRI_SPLIT : + case FRI_RANGE : + if (initial) + na->na_nextip = ntohl(na->na_addr[0].in4.s_addr); + break; + + case FRI_NONE : + na->na_addr[0].in4.s_addr &= na->na_addr[1].in4.s_addr; + return 0; + + case FRI_NORMAL : + na->na_addr[0].in4.s_addr &= na->na_addr[1].in4.s_addr; + break; + + default : + IPFERROR(60054); + return EINVAL; + } + + if (initial && (na->na_atype == FRI_NORMAL)) { + if (na->na_addr[0].in4.s_addr == 0) { + if ((na->na_addr[1].in4.s_addr == 0xffffffff) || + (na->na_addr[1].in4.s_addr == 0)) { + return 0; + } + } + + if (na->na_addr[1].in4.s_addr == 0xffffffff) { + na->na_nextip = ntohl(na->na_addr[0].in4.s_addr); + } else { + na->na_nextip = ntohl(na->na_addr[0].in4.s_addr) + 1; + } + } + + return 0; +} + + +/* ------------------------------------------------------------------------ */ +/* Function: ipf_nat_matchflush */ +/* Returns: int - -1 == error, 0 == success */ +/* Parameters: softc(I) - pointer to soft context main structure */ +/* softn(I) - pointer to NAT context structure */ +/* nat(I) - pointer to current NAT session */ +/* */ +/* ------------------------------------------------------------------------ */ +static int +ipf_nat_matchflush(softc, softn, data) + ipf_main_softc_t *softc; + ipf_nat_softc_t *softn; + caddr_t data; +{ + int *array, flushed, error; + nat_t *nat, *natnext; + ipfobj_t obj; + + error = ipf_matcharray_load(softc, data, &obj, &array); + if (error != 0) + return error; + + flushed = 0; + + for (nat = softn->ipf_nat_instances; nat != NULL; nat = natnext) { + natnext = nat->nat_next; + if (ipf_nat_matcharray(nat, array, softc->ipf_ticks) == 0) { + ipf_nat_delete(softc, nat, NL_FLUSH); + flushed++; + } + } + + obj.ipfo_retval = flushed; + error = BCOPYOUT(&obj, data, sizeof(obj)); + + KFREES(array, array[0] * sizeof(*array)); + + return error; +} + + +/* ------------------------------------------------------------------------ */ +/* Function: ipf_nat_matcharray */ +/* Returns: int - -1 == error, 0 == success */ +/* Parameters: fin(I) - pointer to packet information */ +/* nat(I) - pointer to current NAT session */ +/* */ +/* ------------------------------------------------------------------------ */ +static int +ipf_nat_matcharray(nat, array, ticks) + nat_t *nat; + int *array; + u_long ticks; +{ + int i, n, *x, e, p; + + e = 0; + n = array[0]; + x = array + 1; + + for (; n > 0; x += 3 + x[2]) { + if (x[0] == IPF_EXP_END) + break; + e = 0; + + n -= x[2] + 3; + if (n < 0) + break; + + p = x[0] >> 16; + if (p != 0 && p != nat->nat_pr[1]) + break; + + switch (x[0]) + { + case IPF_EXP_IP_PR : + for (i = 0; !e && i < x[2]; i++) { + e |= (nat->nat_pr[1] == x[i + 3]); + } + break; + + case IPF_EXP_IP_SRCADDR : + if (nat->nat_v[0] == 4) { + for (i = 0; !e && i < x[2]; i++) { + e |= ((nat->nat_osrcaddr & x[i + 4]) == + x[i + 3]); + } + } + if (nat->nat_v[1] == 4) { + for (i = 0; !e && i < x[2]; i++) { + e |= ((nat->nat_nsrcaddr & x[i + 4]) == + x[i + 3]); + } + } + break; + + case IPF_EXP_IP_DSTADDR : + if (nat->nat_v[0] == 4) { + for (i = 0; !e && i < x[2]; i++) { + e |= ((nat->nat_odstaddr & x[i + 4]) == + x[i + 3]); + } + } + if (nat->nat_v[1] == 4) { + for (i = 0; !e && i < x[2]; i++) { + e |= ((nat->nat_ndstaddr & x[i + 4]) == + x[i + 3]); + } + } + break; + + case IPF_EXP_IP_ADDR : + for (i = 0; !e && i < x[2]; i++) { + if (nat->nat_v[0] == 4) { + e |= ((nat->nat_osrcaddr & x[i + 4]) == + x[i + 3]); + } + if (nat->nat_v[1] == 4) { + e |= ((nat->nat_nsrcaddr & x[i + 4]) == + x[i + 3]); + } + if (nat->nat_v[0] == 4) { + e |= ((nat->nat_odstaddr & x[i + 4]) == + x[i + 3]); + } + if (nat->nat_v[1] == 4) { + e |= ((nat->nat_ndstaddr & x[i + 4]) == + x[i + 3]); + } + } + break; + +#ifdef USE_INET6 + case IPF_EXP_IP6_SRCADDR : + if (nat->nat_v[0] == 6) { + for (i = 0; !e && i < x[3]; i++) { + e |= IP6_MASKEQ(&nat->nat_osrc6, + x + i + 7, x + i + 3); + } + } + if (nat->nat_v[1] == 6) { + for (i = 0; !e && i < x[3]; i++) { + e |= IP6_MASKEQ(&nat->nat_nsrc6, + x + i + 7, x + i + 3); + } + } + break; + + case IPF_EXP_IP6_DSTADDR : + if (nat->nat_v[0] == 6) { + for (i = 0; !e && i < x[3]; i++) { + e |= IP6_MASKEQ(&nat->nat_odst6, + x + i + 7, + x + i + 3); + } + } + if (nat->nat_v[1] == 6) { + for (i = 0; !e && i < x[3]; i++) { + e |= IP6_MASKEQ(&nat->nat_ndst6, + x + i + 7, + x + i + 3); + } + } + break; + + case IPF_EXP_IP6_ADDR : + for (i = 0; !e && i < x[3]; i++) { + if (nat->nat_v[0] == 6) { + e |= IP6_MASKEQ(&nat->nat_osrc6, + x + i + 7, + x + i + 3); + } + if (nat->nat_v[0] == 6) { + e |= IP6_MASKEQ(&nat->nat_odst6, + x + i + 7, + x + i + 3); + } + if (nat->nat_v[1] == 6) { + e |= IP6_MASKEQ(&nat->nat_nsrc6, + x + i + 7, + x + i + 3); + } + if (nat->nat_v[1] == 6) { + e |= IP6_MASKEQ(&nat->nat_ndst6, + x + i + 7, + x + i + 3); + } + } + break; +#endif + + case IPF_EXP_UDP_PORT : + case IPF_EXP_TCP_PORT : + for (i = 0; !e && i < x[2]; i++) { + e |= (nat->nat_nsport == x[i + 3]) || + (nat->nat_ndport == x[i + 3]); + } + break; + + case IPF_EXP_UDP_SPORT : + case IPF_EXP_TCP_SPORT : + for (i = 0; !e && i < x[2]; i++) { + e |= (nat->nat_nsport == x[i + 3]); + } + break; + + case IPF_EXP_UDP_DPORT : + case IPF_EXP_TCP_DPORT : + for (i = 0; !e && i < x[2]; i++) { + e |= (nat->nat_ndport == x[i + 3]); + } + break; + + case IPF_EXP_TCP_STATE : + for (i = 0; !e && i < x[2]; i++) { + e |= (nat->nat_tcpstate[0] == x[i + 3]) || + (nat->nat_tcpstate[1] == x[i + 3]); + } + break; + + case IPF_EXP_IDLE_GT : + e |= (ticks - nat->nat_touched > x[3]); + break; + } + e ^= x[1]; + + if (!e) + break; + } + + return e; +} + + +/* ------------------------------------------------------------------------ */ +/* Function: ipf_nat_gettable */ /* Returns: int - 0 = success, else error */ -/* Parameters: data(I) - pointer to ioctl data */ +/* Parameters: softc(I) - pointer to soft context main structure */ +/* softn(I) - pointer to NAT context structure */ +/* data(I) - pointer to ioctl data */ /* */ /* This function handles ioctl requests for tables of nat information. */ /* At present the only table it deals with is the hash bucket statistics. */ /* ------------------------------------------------------------------------ */ -static int nat_gettable(data) -char *data; +static int +ipf_nat_gettable(softc, softn, data) + ipf_main_softc_t *softc; + ipf_nat_softc_t *softn; + char *data; { ipftable_t table; int error; - error = fr_inobj(data, &table, IPFOBJ_GTABLE); + error = ipf_inobj(softc, data, NULL, &table, IPFOBJ_GTABLE); if (error != 0) return error; switch (table.ita_type) { case IPFTABLE_BUCKETS_NATIN : - error = COPYOUT(nat_stats.ns_bucketlen[0], table.ita_table, - ipf_nattable_sz * sizeof(u_long)); + error = COPYOUT(softn->ipf_nat_stats.ns_side[0].ns_bucketlen, + table.ita_table, + softn->ipf_nat_table_sz * sizeof(u_int)); break; case IPFTABLE_BUCKETS_NATOUT : - error = COPYOUT(nat_stats.ns_bucketlen[1], table.ita_table, - ipf_nattable_sz * sizeof(u_long)); + error = COPYOUT(softn->ipf_nat_stats.ns_side[1].ns_bucketlen, + table.ita_table, + softn->ipf_nat_table_sz * sizeof(u_int)); break; default : + IPFERROR(60058); return EINVAL; } if (error != 0) { + IPFERROR(60059); error = EFAULT; } return error; } + + +/* ------------------------------------------------------------------------ */ +/* Function: ipf_nat_settimeout */ +/* Returns: int - 0 = success, else failure */ +/* Parameters: softc(I) - pointer to soft context main structure */ +/* t(I) - pointer to tunable */ +/* p(I) - pointer to new tuning data */ +/* */ +/* Apply the timeout change to the NAT timeout queues. */ +/* ------------------------------------------------------------------------ */ +int +ipf_nat_settimeout(softc, t, p) + struct ipf_main_softc_s *softc; + ipftuneable_t *t; + ipftuneval_t *p; +{ + ipf_nat_softc_t *softn = softc->ipf_nat_soft; + + if (!strncmp(t->ipft_name, "tcp_", 4)) + return ipf_settimeout_tcp(t, p, softn->ipf_nat_tcptq); + + if (!strcmp(t->ipft_name, "udp_timeout")) { + ipf_apply_timeout(&softn->ipf_nat_udptq, p->ipftu_int); + } else if (!strcmp(t->ipft_name, "udp_ack_timeout")) { + ipf_apply_timeout(&softn->ipf_nat_udpacktq, p->ipftu_int); + } else if (!strcmp(t->ipft_name, "icmp_timeout")) { + ipf_apply_timeout(&softn->ipf_nat_icmptq, p->ipftu_int); + } else if (!strcmp(t->ipft_name, "icmp_ack_timeout")) { + ipf_apply_timeout(&softn->ipf_nat_icmpacktq, p->ipftu_int); + } else if (!strcmp(t->ipft_name, "ip_timeout")) { + ipf_apply_timeout(&softn->ipf_nat_iptq, p->ipftu_int); + } else { + IPFERROR(60062); + return ESRCH; + } + return 0; +} + + +/* ------------------------------------------------------------------------ */ +/* Function: ipf_nat_rehash */ +/* Returns: int - 0 = success, else failure */ +/* Parameters: softc(I) - pointer to soft context main structure */ +/* t(I) - pointer to tunable */ +/* p(I) - pointer to new tuning data */ +/* */ +/* To change the size of the basic NAT table, we need to first allocate the */ +/* new tables (lest it fails and we've got nowhere to store all of the NAT */ +/* sessions currently active) and then walk through the entire list and */ +/* insert them into the table. There are two tables here: an inbound one */ +/* and an outbound one. Each NAT entry goes into each table once. */ +/* ------------------------------------------------------------------------ */ +int +ipf_nat_rehash(softc, t, p) + ipf_main_softc_t *softc; + ipftuneable_t *t; + ipftuneval_t *p; +{ + ipf_nat_softc_t *softn = softc->ipf_nat_soft; + nat_t **newtab[2], *nat, **natp; + u_int *bucketlens[2]; + u_int maxbucket; + u_int newsize; + int error; + u_int hv; + int i; + + newsize = p->ipftu_int; + /* + * In case there is nothing to do... + */ + if (newsize == softn->ipf_nat_table_sz) + return 0; + + newtab[0] = NULL; + newtab[1] = NULL; + bucketlens[0] = NULL; + bucketlens[1] = NULL; + /* + * 4 tables depend on the NAT table size: the inbound looking table, + * the outbound lookup table and the hash chain length for each. + */ + KMALLOCS(newtab[0], nat_t **, newsize * sizeof(nat_t *)); + if (newtab == NULL) { + error = 60063; + goto badrehash; + } + + KMALLOCS(newtab[1], nat_t **, newsize * sizeof(nat_t *)); + if (newtab == NULL) { + error = 60064; + goto badrehash; + } + + KMALLOCS(bucketlens[0], u_int *, newsize * sizeof(u_int)); + if (bucketlens[0] == NULL) { + error = 60065; + goto badrehash; + } + + KMALLOCS(bucketlens[1], u_int *, newsize * sizeof(u_int)); + if (bucketlens[1] == NULL) { + error = 60066; + goto badrehash; + } + + /* + * Recalculate the maximum length based on the new size. + */ + for (maxbucket = 0, i = newsize; i > 0; i >>= 1) + maxbucket++; + maxbucket *= 2; + + bzero((char *)newtab[0], newsize * sizeof(nat_t *)); + bzero((char *)newtab[1], newsize * sizeof(nat_t *)); + bzero((char *)bucketlens[0], newsize * sizeof(u_int)); + bzero((char *)bucketlens[1], newsize * sizeof(u_int)); + + WRITE_ENTER(&softc->ipf_nat); + + if (softn->ipf_nat_table[0] != NULL) { + KFREES(softn->ipf_nat_table[0], + softn->ipf_nat_table_sz * + sizeof(*softn->ipf_nat_table[0])); + } + softn->ipf_nat_table[0] = newtab[0]; + + if (softn->ipf_nat_table[1] != NULL) { + KFREES(softn->ipf_nat_table[1], + softn->ipf_nat_table_sz * + sizeof(*softn->ipf_nat_table[1])); + } + softn->ipf_nat_table[1] = newtab[1]; + + if (softn->ipf_nat_stats.ns_side[0].ns_bucketlen != NULL) { + KFREES(softn->ipf_nat_stats.ns_side[0].ns_bucketlen, + softn->ipf_nat_table_sz * sizeof(u_int)); + } + softn->ipf_nat_stats.ns_side[0].ns_bucketlen = bucketlens[0]; + + if (softn->ipf_nat_stats.ns_side[1].ns_bucketlen != NULL) { + KFREES(softn->ipf_nat_stats.ns_side[1].ns_bucketlen, + softn->ipf_nat_table_sz * sizeof(u_int)); + } + softn->ipf_nat_stats.ns_side[1].ns_bucketlen = bucketlens[1]; + +#ifdef USE_INET6 + if (softn->ipf_nat_stats.ns_side6[0].ns_bucketlen != NULL) { + KFREES(softn->ipf_nat_stats.ns_side6[0].ns_bucketlen, + softn->ipf_nat_table_sz * sizeof(u_int)); + } + softn->ipf_nat_stats.ns_side6[0].ns_bucketlen = bucketlens[0]; + + if (softn->ipf_nat_stats.ns_side6[1].ns_bucketlen != NULL) { + KFREES(softn->ipf_nat_stats.ns_side6[1].ns_bucketlen, + softn->ipf_nat_table_sz * sizeof(u_int)); + } + softn->ipf_nat_stats.ns_side6[1].ns_bucketlen = bucketlens[1]; +#endif + + softn->ipf_nat_maxbucket = maxbucket; + softn->ipf_nat_table_sz = newsize; + /* + * Walk through the entire list of NAT table entries and put them + * in the new NAT table, somewhere. Because we have a new table, + * we need to restart the counter of how many chains are in use. + */ + softn->ipf_nat_stats.ns_side[0].ns_inuse = 0; + softn->ipf_nat_stats.ns_side[1].ns_inuse = 0; +#ifdef USE_INET6 + softn->ipf_nat_stats.ns_side6[0].ns_inuse = 0; + softn->ipf_nat_stats.ns_side6[1].ns_inuse = 0; +#endif + + for (nat = softn->ipf_nat_instances; nat != NULL; nat = nat->nat_next) { + nat->nat_hnext[0] = NULL; + nat->nat_phnext[0] = NULL; + hv = nat->nat_hv[0] % softn->ipf_nat_table_sz; + + natp = &softn->ipf_nat_table[0][hv]; + if (*natp) { + (*natp)->nat_phnext[0] = &nat->nat_hnext[0]; + } else { + NBUMPSIDE(0, ns_inuse); + } + nat->nat_phnext[0] = natp; + nat->nat_hnext[0] = *natp; + *natp = nat; + NBUMPSIDE(0, ns_bucketlen[hv]); + + nat->nat_hnext[1] = NULL; + nat->nat_phnext[1] = NULL; + hv = nat->nat_hv[1] % softn->ipf_nat_table_sz; + + natp = &softn->ipf_nat_table[1][hv]; + if (*natp) { + (*natp)->nat_phnext[1] = &nat->nat_hnext[1]; + } else { + NBUMPSIDE(1, ns_inuse); + } + nat->nat_phnext[1] = natp; + nat->nat_hnext[1] = *natp; + *natp = nat; + NBUMPSIDE(1, ns_bucketlen[hv]); + } + RWLOCK_EXIT(&softc->ipf_nat); + + return 0; + +badrehash: + if (bucketlens[1] != NULL) { + KFREES(bucketlens[0], newsize * sizeof(u_int)); + } + if (bucketlens[0] != NULL) { + KFREES(bucketlens[0], newsize * sizeof(u_int)); + } + if (newtab[0] != NULL) { + KFREES(newtab[0], newsize * sizeof(nat_t *)); + } + if (newtab[1] != NULL) { + KFREES(newtab[1], newsize * sizeof(nat_t *)); + } + IPFERROR(error); + return ENOMEM; +} + + +/* ------------------------------------------------------------------------ */ +/* Function: ipf_nat_rehash_rules */ +/* Returns: int - 0 = success, else failure */ +/* Parameters: softc(I) - pointer to soft context main structure */ +/* t(I) - pointer to tunable */ +/* p(I) - pointer to new tuning data */ +/* */ +/* All of the NAT rules hang off of a hash table that is searched with a */ +/* hash on address after the netmask is applied. There is a different table*/ +/* for both inbound rules (rdr) and outbound (map.) The resizing will only */ +/* affect one of these two tables. */ +/* ------------------------------------------------------------------------ */ +int +ipf_nat_rehash_rules(softc, t, p) + ipf_main_softc_t *softc; + ipftuneable_t *t; + ipftuneval_t *p; +{ + ipf_nat_softc_t *softn = softc->ipf_nat_soft; + ipnat_t **newtab, *np, ***old, **npp; + u_int newsize; + u_int mask; + u_int hv; + + newsize = p->ipftu_int; + /* + * In case there is nothing to do... + */ + if (newsize == *t->ipft_pint) + return 0; + + /* + * All inbound rules have the NAT_REDIRECT bit set in in_redir and + * all outbound rules have either NAT_MAP or MAT_MAPBLK set. + * This if statement allows for some more generic code to be below, + * rather than two huge gobs of code that almost do the same thing. + */ + if (t->ipft_pint == &softn->ipf_nat_rdrrules_sz) { + old = &softn->ipf_nat_rdr_rules; + mask = NAT_REDIRECT; + } else { + old = &softn->ipf_nat_map_rules; + mask = NAT_MAP|NAT_MAPBLK; + } + + KMALLOCS(newtab, ipnat_t **, newsize * sizeof(ipnat_t *)); + if (newtab == NULL) { + IPFERROR(60067); + return ENOMEM; + } + + bzero((char *)newtab, newsize * sizeof(ipnat_t *)); + + WRITE_ENTER(&softc->ipf_nat); + + if (*old != NULL) { + KFREES(*old, *t->ipft_pint * sizeof(ipnat_t **)); + } + *old = newtab; + *t->ipft_pint = newsize; + + for (np = softn->ipf_nat_list; np != NULL; np = np->in_next) { + if ((np->in_redir & mask) == 0) + continue; + + if (np->in_redir & NAT_REDIRECT) { + np->in_rnext = NULL; + hv = np->in_hv[0] % newsize; + for (npp = newtab + hv; *npp != NULL; ) + npp = &(*npp)->in_rnext; + np->in_prnext = npp; + *npp = np; + } + if (np->in_redir & NAT_MAP) { + np->in_mnext = NULL; + hv = np->in_hv[1] % newsize; + for (npp = newtab + hv; *npp != NULL; ) + npp = &(*npp)->in_mnext; + np->in_pmnext = npp; + *npp = np; + } + + } + RWLOCK_EXIT(&softc->ipf_nat); + + return 0; +} + + +/* ------------------------------------------------------------------------ */ +/* Function: ipf_nat_hostmap_rehash */ +/* Returns: int - 0 = success, else failure */ +/* Parameters: softc(I) - pointer to soft context main structure */ +/* t(I) - pointer to tunable */ +/* p(I) - pointer to new tuning data */ +/* */ +/* Allocate and populate a new hash table that will contain a reference to */ +/* all of the active IP# translations currently in place. */ +/* ------------------------------------------------------------------------ */ +int +ipf_nat_hostmap_rehash(softc, t, p) + ipf_main_softc_t *softc; + ipftuneable_t *t; + ipftuneval_t *p; +{ + ipf_nat_softc_t *softn = softc->ipf_nat_soft; + hostmap_t *hm, **newtab; + u_int newsize; + u_int hv; + + newsize = p->ipftu_int; + /* + * In case there is nothing to do... + */ + if (newsize == *t->ipft_pint) + return 0; + + KMALLOCS(newtab, hostmap_t **, newsize * sizeof(hostmap_t *)); + if (newtab == NULL) { + IPFERROR(60068); + return ENOMEM; + } + + bzero((char *)newtab, newsize * sizeof(hostmap_t *)); + + WRITE_ENTER(&softc->ipf_nat); + if (softn->ipf_hm_maptable != NULL) { + KFREES(softn->ipf_hm_maptable, + softn->ipf_nat_hostmap_sz * sizeof(hostmap_t *)); + } + softn->ipf_hm_maptable = newtab; + softn->ipf_nat_hostmap_sz = newsize; + + for (hm = softn->ipf_hm_maplist; hm != NULL; hm = hm->hm_next) { + hv = hm->hm_hv % softn->ipf_nat_hostmap_sz; + hm->hm_hnext = softn->ipf_hm_maptable[hv]; + hm->hm_phnext = softn->ipf_hm_maptable + hv; + if (softn->ipf_hm_maptable[hv] != NULL) + softn->ipf_hm_maptable[hv]->hm_phnext = &hm->hm_hnext; + softn->ipf_hm_maptable[hv] = hm; + } + RWLOCK_EXIT(&softc->ipf_nat); + + return 0; +} + + +/* ------------------------------------------------------------------------ */ +/* Function: ipf_nat_add_tq */ +/* Parameters: softc(I) - pointer to soft context main structure */ +/* */ +/* ------------------------------------------------------------------------ */ +ipftq_t * +ipf_nat_add_tq(softc, ttl) + ipf_main_softc_t *softc; + int ttl; +{ + ipf_nat_softc_t *softs = softc->ipf_nat_soft; + + return ipf_addtimeoutqueue(softc, &softs->ipf_nat_utqe, ttl); +} + +/* ------------------------------------------------------------------------ */ +/* Function: ipf_nat_uncreate */ +/* Returns: Nil */ +/* Parameters: fin(I) - pointer to packet information */ +/* */ +/* This function is used to remove a NAT entry from the NAT table when we */ +/* decide that the create was actually in error. It is thus assumed that */ +/* fin_flx will have both FI_NATED and FI_NATNEW set. Because we're dealing */ +/* with the translated packet (not the original), we have to reverse the */ +/* lookup. Although doing the lookup is expensive (relatively speaking), it */ +/* is not anticipated that this will be a frequent occurance for normal */ +/* traffic patterns. */ +/* ------------------------------------------------------------------------ */ +void +ipf_nat_uncreate(fin) + fr_info_t *fin; +{ + ipf_main_softc_t *softc = fin->fin_main_soft; + ipf_nat_softc_t *softn = softc->ipf_nat_soft; + int nflags; + nat_t *nat; + + switch (fin->fin_p) + { + case IPPROTO_TCP : + nflags = IPN_TCP; + break; + case IPPROTO_UDP : + nflags = IPN_UDP; + break; + default : + nflags = 0; + break; + } + + WRITE_ENTER(&softc->ipf_nat); + + if (fin->fin_out == 0) { + nat = ipf_nat_outlookup(fin, nflags, (u_int)fin->fin_p, + fin->fin_dst, fin->fin_src); + } else { + nat = ipf_nat_inlookup(fin, nflags, (u_int)fin->fin_p, + fin->fin_src, fin->fin_dst); + } + + if (nat != NULL) { + NBUMPSIDE(fin->fin_out, ns_uncreate[0]); + ipf_nat_delete(softc, nat, NL_DESTROY); + } else { + NBUMPSIDE(fin->fin_out, ns_uncreate[1]); + } + + RWLOCK_EXIT(&softc->ipf_nat); +} + + +/* ------------------------------------------------------------------------ */ +/* Function: ipf_nat_cmp_rules */ +/* Returns: int - 0 == success, else rules do not match. */ +/* Parameters: n1(I) - first rule to compare */ +/* n2(I) - first rule to compare */ +/* */ +/* Compare two rules using pointers to each rule. A straight bcmp will not */ +/* work as some fields (such as in_dst, in_pkts) actually do change once */ +/* the rule has been loaded into the kernel. Whilst this function returns */ +/* various non-zero returns, they're strictly to aid in debugging. Use of */ +/* this function should simply care if the result is zero or not. */ +/* ------------------------------------------------------------------------ */ +static int +ipf_nat_cmp_rules(n1, n2) + ipnat_t *n1, *n2; +{ + if (n1->in_size != n2->in_size) + return 1; + + if (bcmp((char *)&n1->in_v, (char *)&n2->in_v, + offsetof(ipnat_t, in_ndst) - offsetof(ipnat_t, in_v)) != 0) + return 2; + + if (bcmp((char *)&n1->in_tuc, (char *)&n2->in_tuc, + n1->in_size - offsetof(ipnat_t, in_tuc)) != 0) + return 3; + if (n1->in_ndst.na_atype != n2->in_ndst.na_atype) + return 5; + if (n1->in_ndst.na_function != n2->in_ndst.na_function) + return 6; + if (bcmp((char *)&n1->in_ndst.na_addr, (char *)&n2->in_ndst.na_addr, + sizeof(n1->in_ndst.na_addr))) + return 7; + if (n1->in_nsrc.na_atype != n2->in_nsrc.na_atype) + return 8; + if (n1->in_nsrc.na_function != n2->in_nsrc.na_function) + return 9; + if (bcmp((char *)&n1->in_nsrc.na_addr, (char *)&n2->in_nsrc.na_addr, + sizeof(n1->in_nsrc.na_addr))) + return 10; + if (n1->in_odst.na_atype != n2->in_odst.na_atype) + return 11; + if (n1->in_odst.na_function != n2->in_odst.na_function) + return 12; + if (bcmp((char *)&n1->in_odst.na_addr, (char *)&n2->in_odst.na_addr, + sizeof(n1->in_odst.na_addr))) + return 13; + if (n1->in_osrc.na_atype != n2->in_osrc.na_atype) + return 14; + if (n1->in_osrc.na_function != n2->in_osrc.na_function) + return 15; + if (bcmp((char *)&n1->in_osrc.na_addr, (char *)&n2->in_osrc.na_addr, + sizeof(n1->in_osrc.na_addr))) + return 16; + return 0; +} + + +/* ------------------------------------------------------------------------ */ +/* Function: ipf_nat_rule_init */ +/* Returns: int - 0 == success, else rules do not match. */ +/* Parameters: softc(I) - pointer to soft context main structure */ +/* softn(I) - pointer to NAT context structure */ +/* n(I) - first rule to compare */ +/* */ +/* ------------------------------------------------------------------------ */ +static int +ipf_nat_rule_init(softc, softn, n) + ipf_main_softc_t *softc; + ipf_nat_softc_t *softn; + ipnat_t *n; +{ + int error = 0; + + if ((n->in_flags & IPN_SIPRANGE) != 0) + n->in_nsrcatype = FRI_RANGE; + + if ((n->in_flags & IPN_DIPRANGE) != 0) + n->in_ndstatype = FRI_RANGE; + + if ((n->in_flags & IPN_SPLIT) != 0) + n->in_ndstatype = FRI_SPLIT; + + if ((n->in_redir & (NAT_MAP|NAT_REWRITE|NAT_DIVERTUDP)) != 0) + n->in_spnext = n->in_spmin; + + if ((n->in_redir & (NAT_REWRITE|NAT_DIVERTUDP)) != 0) { + n->in_dpnext = n->in_dpmin; + } else if (n->in_redir == NAT_REDIRECT) { + n->in_dpnext = n->in_dpmin; + } + + n->in_stepnext = 0; + + switch (n->in_v[0]) + { + case 4 : + error = ipf_nat_ruleaddrinit(softc, softn, n); + if (error != 0) + return error; + break; +#ifdef USE_INET6 + case 6 : + error = ipf_nat6_ruleaddrinit(softc, softn, n); + if (error != 0) + return error; + break; +#endif + default : + break; + } + + if (n->in_redir == (NAT_DIVERTUDP|NAT_MAP)) { + /* + * Prerecord whether or not the destination of the divert + * is local or not to the interface the packet is going + * to be sent out. + */ + n->in_dlocal = ipf_deliverlocal(softc, n->in_v[1], + n->in_ifps[1], &n->in_ndstip6); + } + + return error; +} + + +/* ------------------------------------------------------------------------ */ +/* Function: ipf_nat_rule_fini */ +/* Returns: int - 0 == success, else rules do not match. */ +/* Parameters: softc(I) - pointer to soft context main structure */ +/* n(I) - rule to work on */ +/* */ +/* This function is used to release any objects that were referenced during */ +/* the rule initialisation. This is useful both when free'ing the rule and */ +/* when handling ioctls that need to initialise these fields but not */ +/* actually use them after the ioctl processing has finished. */ +/* ------------------------------------------------------------------------ */ +static void +ipf_nat_rule_fini(softc, n) + ipf_main_softc_t *softc; + ipnat_t *n; +{ + if (n->in_odst.na_atype == FRI_LOOKUP && n->in_odst.na_ptr != NULL) + ipf_lookup_deref(softc, n->in_odst.na_type, n->in_odst.na_ptr); + + if (n->in_osrc.na_atype == FRI_LOOKUP && n->in_osrc.na_ptr != NULL) + ipf_lookup_deref(softc, n->in_osrc.na_type, n->in_osrc.na_ptr); + + if (n->in_ndst.na_atype == FRI_LOOKUP && n->in_ndst.na_ptr != NULL) + ipf_lookup_deref(softc, n->in_ndst.na_type, n->in_ndst.na_ptr); + + if (n->in_nsrc.na_atype == FRI_LOOKUP && n->in_nsrc.na_ptr != NULL) + ipf_lookup_deref(softc, n->in_nsrc.na_type, n->in_nsrc.na_ptr); + + if (n->in_divmp != NULL) + FREE_MB_T(n->in_divmp); +} diff --git a/sys/contrib/ipfilter/netinet/ip_nat.h b/sys/contrib/ipfilter/netinet/ip_nat.h index c8581ef3d7cb..a57bf0ce3ce4 100644 --- a/sys/contrib/ipfilter/netinet/ip_nat.h +++ b/sys/contrib/ipfilter/netinet/ip_nat.h @@ -1,7 +1,7 @@ /* $FreeBSD$ */ /* - * Copyright (C) 1995-2001, 2003 by Darren Reed. + * Copyright (C) 2012 by Darren Reed. * * See the IPFILTER.LICENCE file for details on licencing. * @@ -22,11 +22,13 @@ #define SIOCRMNAT _IOW('r', 61, struct ipfobj) #define SIOCGNATS _IOWR('r', 62, struct ipfobj) #define SIOCGNATL _IOWR('r', 63, struct ipfobj) +#define SIOCPURGENAT _IOWR('r', 100, struct ipfobj) #else #define SIOCADNAT _IOW(r, 60, struct ipfobj) #define SIOCRMNAT _IOW(r, 61, struct ipfobj) #define SIOCGNATS _IOWR(r, 62, struct ipfobj) #define SIOCGNATL _IOWR(r, 63, struct ipfobj) +#define SIOCPURGENAT _IOWR(r, 100, struct ipfobj) #endif #undef LARGE_NAT /* define this if you're setting up a system to NAT @@ -78,13 +80,18 @@ #ifndef APR_LABELLEN #define APR_LABELLEN 16 #endif -#define NAT_HW_CKSUM 0x80000000 +#define NAT_HW_CKSUM 0x80000000 +#define NAT_HW_CKSUM_PART 0x40000000 #define DEF_NAT_AGE 1200 /* 10 minutes (600 seconds) */ struct ipstate; struct ap_session; +/* + * This structure is used in the active NAT table and represents an + * active NAT session. + */ typedef struct nat { ipfmutex_t nat_lock; struct nat *nat_next; @@ -101,13 +108,15 @@ typedef struct nat { void *nat_ifps[2]; void *nat_sync; ipftqent_t nat_tqe; + int nat_mtu[2]; u_32_t nat_flags; u_32_t nat_sumd[2]; /* ip checksum delta for data segment*/ u_32_t nat_ipsumd; /* ip checksum delta for ip header */ u_32_t nat_mssclamp; /* if != zero clamp MSS to this */ - i6addr_t nat_inip6; - i6addr_t nat_outip6; - i6addr_t nat_oip6; /* other ip */ + i6addr_t nat_odst6; + i6addr_t nat_osrc6; + i6addr_t nat_ndst6; + i6addr_t nat_nsrc6; U_QUAD_T nat_pkts[2]; U_QUAD_T nat_bytes[2]; union { @@ -115,28 +124,37 @@ typedef struct nat { tcpinfo_t nat_unt; icmpinfo_t nat_uni; greinfo_t nat_ugre; - } nat_un; - u_short nat_oport; /* other port */ - u_short nat_use; - u_char nat_p; /* protocol for NAT */ + } nat_unold, nat_unnew; + int nat_use; + int nat_pr[2]; /* protocol for NAT */ int nat_dir; int nat_ref; /* reference count */ - int nat_hv[2]; + u_int nat_hv[2]; char nat_ifnames[2][LIFNAMSIZ]; int nat_rev; /* 0 = forward, 1 = reverse */ - int nat_redir; /* copy of in_redir */ - u_32_t nat_seqnext[2]; + int nat_dlocal; + int nat_v[2]; /* 0 = old, 1 = new */ + u_int nat_redir; /* copy of in_redir */ } nat_t; -#define nat_inip nat_inip6.in4 -#define nat_outip nat_outip6.in4 -#define nat_oip nat_oip6.in4 +#define nat_osrcip nat_osrc6.in4 +#define nat_odstip nat_odst6.in4 +#define nat_nsrcip nat_nsrc6.in4 +#define nat_ndstip nat_ndst6.in4 +#define nat_osrcaddr nat_osrc6.in4.s_addr +#define nat_odstaddr nat_odst6.in4.s_addr +#define nat_nsrcaddr nat_nsrc6.in4.s_addr +#define nat_ndstaddr nat_ndst6.in4.s_addr #define nat_age nat_tqe.tqe_die -#define nat_inport nat_un.nat_unt.ts_sport -#define nat_outport nat_un.nat_unt.ts_dport -#define nat_type nat_un.nat_uni.ici_type -#define nat_seq nat_un.nat_uni.ici_seq -#define nat_id nat_un.nat_uni.ici_id +#define nat_osport nat_unold.nat_unt.ts_sport +#define nat_odport nat_unold.nat_unt.ts_dport +#define nat_nsport nat_unnew.nat_unt.ts_sport +#define nat_ndport nat_unnew.nat_unt.ts_dport +#define nat_oicmpid nat_unold.nat_uni.ici_id +#define nat_nicmpid nat_unnew.nat_uni.ici_id +#define nat_type nat_unold.nat_uni.ici_type +#define nat_oseq nat_unold.nat_uni.ici_seq +#define nat_nseq nat_unnew.nat_uni.ici_seq #define nat_tcpstate nat_tqe.tqe_state #define nat_die nat_tqe.tqe_die #define nat_touched nat_tqe.tqe_touched @@ -146,6 +164,10 @@ typedef struct nat { */ #define NAT_INBOUND 0 #define NAT_OUTBOUND 1 +#define NAT_ENCAPIN 2 +#define NAT_ENCAPOUT 3 +#define NAT_DIVERTIN 4 +#define NAT_DIVERTOUT 5 /* * Definitions for nat_flags @@ -174,9 +196,29 @@ typedef struct nat { #define NAT_DEBUG 0x800000 +typedef struct nat_addr_s { + i6addr_t na_addr[2]; + i6addr_t na_nextaddr; + int na_atype; + int na_function; +} nat_addr_t; + +#define na_nextip na_nextaddr.in4.s_addr +#define na_nextip6 na_nextaddr.in6 +#define na_num na_addr[0].iplookupnum +#define na_type na_addr[0].iplookuptype +#define na_subtype na_addr[0].iplookupsubtype +#define na_ptr na_addr[1].iplookupptr +#define na_func na_addr[1].iplookupfunc + + +/* + * This structure represents an actual NAT rule, loaded by ipnat. + */ typedef struct ipnat { ipfmutex_t in_lock; struct ipnat *in_next; /* NAT rule list next */ + struct ipnat **in_pnext; /* prior rdr next ptr */ struct ipnat *in_rnext; /* rdr rule hash next */ struct ipnat **in_prnext; /* prior rdr next ptr */ struct ipnat *in_mnext; /* map rule hash next */ @@ -185,49 +227,114 @@ typedef struct ipnat { void *in_ifps[2]; void *in_apr; char *in_comment; - i6addr_t in_next6; + mb_t *in_divmp; + void *in_pconf; + U_QUAD_T in_pkts[2]; + U_QUAD_T in_bytes[2]; u_long in_space; u_long in_hits; - u_int in_use; - u_int in_hv; + int in_size; + int in_use; + u_int in_hv[2]; int in_flineno; /* conf. file line number */ - u_short in_pnext; - u_char in_v; - u_char in_xxx; + int in_stepnext; + int in_dlocal; + u_short in_dpnext; + u_short in_spnext; /* From here to the end is covered by IPN_CMPSIZ */ + u_char in_v[2]; /* 0 = old, 1 = new */ u_32_t in_flags; u_32_t in_mssclamp; /* if != 0 clamp MSS to this */ u_int in_age[2]; int in_redir; /* see below for values */ - int in_p; /* protocol. */ - i6addr_t in_in[2]; - i6addr_t in_out[2]; - i6addr_t in_src[2]; + int in_pr[2]; /* protocol. */ + nat_addr_t in_ndst; + nat_addr_t in_nsrc; + nat_addr_t in_osrc; + nat_addr_t in_odst; frtuc_t in_tuc; - u_short in_port[2]; u_short in_ppip; /* ports per IP. */ u_short in_ippip; /* IP #'s per IP# */ - char in_ifnames[2][LIFNAMSIZ]; - char in_plabel[APR_LABELLEN]; /* proxy label. */ + u_short in_ndports[2]; + u_short in_nsports[2]; + int in_ifnames[2]; + int in_plabel; /* proxy label. */ + int in_pconfig; /* proxy label. */ ipftag_t in_tag; + int in_namelen; + char in_names[1]; } ipnat_t; -#define in_pmin in_port[0] /* Also holds static redir port */ -#define in_pmax in_port[1] -#define in_nextip in_next6.in4 -#define in_nip in_next6.in4.s_addr -#define in_inip in_in[0].in4.s_addr -#define in_inmsk in_in[1].in4.s_addr -#define in_outip in_out[0].in4.s_addr -#define in_outmsk in_out[1].in4.s_addr -#define in_srcip in_src[0].in4.s_addr -#define in_srcmsk in_src[1].in4.s_addr +/* + * MAP-IN MAP-OUT RDR-IN RDR-OUT + * osrc X == src == src X + * odst X == dst == dst X + * nsrc == dst X X == dst + * ndst == src X X == src + */ +#define in_dpmin in_ndports[0] /* Also holds static redir port */ +#define in_dpmax in_ndports[1] +#define in_spmin in_nsports[0] /* Also holds static redir port */ +#define in_spmax in_nsports[1] +#define in_ndport in_ndports[0] +#define in_nsport in_nsports[0] +#define in_dipnext in_ndst.na_nextaddr.in4 +#define in_dipnext6 in_ndst.na_nextaddr +#define in_dnip in_ndst.na_nextaddr.in4.s_addr +#define in_dnip6 in_ndst.na_nextaddr +#define in_sipnext in_nsrc.na_nextaddr.in4 +#define in_snip in_nsrc.na_nextaddr.in4.s_addr +#define in_snip6 in_nsrc.na_nextaddr +#define in_odstip in_odst.na_addr[0].in4 +#define in_odstip6 in_odst.na_addr[0] +#define in_odstaddr in_odst.na_addr[0].in4.s_addr +#define in_odstmsk in_odst.na_addr[1].in4.s_addr +#define in_odstmsk6 in_odst.na_addr[1] +#define in_odstatype in_odst.na_atype +#define in_osrcip in_osrc.na_addr[0].in4 +#define in_osrcip6 in_osrc.na_addr[0] +#define in_osrcaddr in_osrc.na_addr[0].in4.s_addr +#define in_osrcmsk in_osrc.na_addr[1].in4.s_addr +#define in_osrcmsk6 in_osrc.na_addr[1] +#define in_osrcatype in_osrc.na_atype +#define in_ndstip in_ndst.na_addr[0].in4 +#define in_ndstip6 in_ndst.na_addr[0] +#define in_ndstaddr in_ndst.na_addr[0].in4.s_addr +#define in_ndstmsk in_ndst.na_addr[1].in4.s_addr +#define in_ndstmsk6 in_ndst.na_addr[1] +#define in_ndstatype in_ndst.na_atype +#define in_ndstafunc in_ndst.na_function +#define in_nsrcip in_nsrc.na_addr[0].in4 +#define in_nsrcip6 in_nsrc.na_addr[0] +#define in_nsrcaddr in_nsrc.na_addr[0].in4.s_addr +#define in_nsrcmsk in_nsrc.na_addr[1].in4.s_addr +#define in_nsrcmsk6 in_nsrc.na_addr[1] +#define in_nsrcatype in_nsrc.na_atype +#define in_nsrcafunc in_nsrc.na_function #define in_scmp in_tuc.ftu_scmp #define in_dcmp in_tuc.ftu_dcmp #define in_stop in_tuc.ftu_stop #define in_dtop in_tuc.ftu_dtop -#define in_sport in_tuc.ftu_sport -#define in_dport in_tuc.ftu_dport +#define in_osport in_tuc.ftu_sport +#define in_odport in_tuc.ftu_dport +#define in_ndstnum in_ndst.na_addr[0].iplookupnum +#define in_ndsttype in_ndst.na_addr[0].iplookuptype +#define in_ndstptr in_ndst.na_addr[1].iplookupptr +#define in_ndstfunc in_ndst.na_addr[1].iplookupfunc +#define in_nsrcnum in_nsrc.na_addr[0].iplookupnum +#define in_nsrctype in_nsrc.na_addr[0].iplookuptype +#define in_nsrcptr in_nsrc.na_addr[1].iplookupptr +#define in_nsrcfunc in_nsrc.na_addr[1].iplookupfunc +#define in_odstnum in_odst.na_addr[0].iplookupnum +#define in_odsttype in_odst.na_addr[0].iplookuptype +#define in_odstptr in_odst.na_addr[1].iplookupptr +#define in_odstfunc in_odst.na_addr[1].iplookupfunc +#define in_osrcnum in_osrc.na_addr[0].iplookupnum +#define in_osrctype in_osrc.na_addr[0].iplookuptype +#define in_osrcptr in_osrc.na_addr[1].iplookupptr +#define in_osrcfunc in_osrc.na_addr[1].iplookupfunc +#define in_icmpidmin in_nsports[0] +#define in_icmpidmax in_nsports[1] /* * Bit definitions for in_flags @@ -242,25 +349,30 @@ typedef struct ipnat { #define IPN_TCPUDPICMPQ (IPN_TCP|IPN_UDP|IPN_ICMPQUERY) #define IPN_RF (IPN_TCPUDP|IPN_DELETE|IPN_ICMPERR) #define IPN_AUTOPORTMAP 0x00010 -#define IPN_IPRANGE 0x00020 -#define IPN_FILTER 0x00040 -#define IPN_SPLIT 0x00080 -#define IPN_ROUNDR 0x00100 -#define IPN_NOTSRC 0x04000 -#define IPN_NOTDST 0x08000 -#define IPN_DYNSRCIP 0x10000 /* dynamic src IP# */ -#define IPN_DYNDSTIP 0x20000 /* dynamic dst IP# */ -#define IPN_DELETE 0x40000 -#define IPN_STICKY 0x80000 -#define IPN_FRAG 0x100000 -#define IPN_FIXEDDPORT 0x200000 -#define IPN_FINDFORWARD 0x400000 -#define IPN_IN 0x800000 -#define IPN_SEQUENTIAL 0x1000000 -#define IPN_USERFLAGS (IPN_TCPUDP|IPN_AUTOPORTMAP|IPN_IPRANGE|IPN_SPLIT|\ - IPN_ROUNDR|IPN_FILTER|IPN_NOTSRC|IPN_NOTDST|\ +#define IPN_FILTER 0x00020 +#define IPN_SPLIT 0x00040 +#define IPN_ROUNDR 0x00080 +#define IPN_SIPRANGE 0x00100 +#define IPN_DIPRANGE 0x00200 +#define IPN_NOTSRC 0x00400 +#define IPN_NOTDST 0x00800 +#define IPN_NO 0x01000 +#define IPN_DYNSRCIP 0x02000 /* dynamic src IP# */ +#define IPN_DYNDSTIP 0x04000 /* dynamic dst IP# */ +#define IPN_DELETE 0x08000 +#define IPN_STICKY 0x10000 +#define IPN_FRAG 0x20000 +#define IPN_FIXEDSPORT 0x40000 +#define IPN_FIXEDDPORT 0x80000 +#define IPN_FINDFORWARD 0x100000 +#define IPN_IN 0x200000 +#define IPN_SEQUENTIAL 0x400000 +#define IPN_PURGE 0x800000 +#define IPN_PROXYRULE 0x1000000 +#define IPN_USERFLAGS (IPN_TCPUDP|IPN_AUTOPORTMAP|IPN_SIPRANGE|IPN_SPLIT|\ + IPN_ROUNDR|IPN_FILTER|IPN_NOTSRC|IPN_NOTDST|IPN_NO|\ IPN_FRAG|IPN_STICKY|IPN_FIXEDDPORT|IPN_ICMPQUERY|\ - IPN_SEQUENTIAL) + IPN_DIPRANGE|IPN_SEQUENTIAL|IPN_PURGE) /* * Values for in_redir @@ -269,22 +381,33 @@ typedef struct ipnat { #define NAT_REDIRECT 0x02 #define NAT_BIMAP (NAT_MAP|NAT_REDIRECT) #define NAT_MAPBLK 0x04 +#define NAT_REWRITE 0x08 +#define NAT_ENCAP 0x10 +#define NAT_DIVERTUDP 0x20 #define MAPBLK_MINPORT 1024 /* don't use reserved ports for src port */ #define USABLE_PORTS (65536 - MAPBLK_MINPORT) -#define IPN_CMPSIZ (sizeof(ipnat_t) - offsetof(ipnat_t, in_flags)) +#define IPN_CMPSIZ (sizeof(ipnat_t) - offsetof(ipnat_t, in_v)) typedef struct natlookup { - struct in_addr nl_inip; - struct in_addr nl_outip; - struct in_addr nl_realip; - int nl_flags; - u_short nl_inport; - u_short nl_outport; - u_short nl_realport; + i6addr_t nl_inipaddr; + i6addr_t nl_outipaddr; + i6addr_t nl_realipaddr; + int nl_v; + int nl_flags; + u_short nl_inport; + u_short nl_outport; + u_short nl_realport; } natlookup_t; +#define nl_inip nl_inipaddr.in4 +#define nl_outip nl_outipaddr.in4 +#define nl_realip nl_realipaddr.in4 +#define nl_inip6 nl_inipaddr.in6 +#define nl_outip6 nl_outipaddr.in6 +#define nl_realip6 nl_realipaddr.in6 + typedef struct nat_save { void *ipn_next; @@ -315,13 +438,25 @@ typedef struct hostmap { struct hostmap *hm_next; struct hostmap **hm_pnext; struct ipnat *hm_ipnat; - struct in_addr hm_srcip; - struct in_addr hm_dstip; - struct in_addr hm_mapip; + i6addr_t hm_osrcip6; + i6addr_t hm_odstip6; + i6addr_t hm_nsrcip6; + i6addr_t hm_ndstip6; u_32_t hm_port; int hm_ref; + int hm_hv; + int hm_v; } hostmap_t; +#define hm_osrcip hm_osrcip6.in4 +#define hm_odstip hm_odstip6.in4 +#define hm_nsrcip hm_nsrcip6.in4 +#define hm_ndstip hm_ndstip6.in4 +#define hm_osrc6 hm_osrcip6.in6 +#define hm_odst6 hm_odstip6.in6 +#define hm_nsrc6 hm_nsrcip6.in6 +#define hm_ndst6 hm_ndstip6.in6 + /* * Structure used to pass information in to nat_newmap and nat_newrdr. @@ -330,9 +465,7 @@ typedef struct natinfo { ipnat_t *nai_np; u_32_t nai_sum1; u_32_t nai_sum2; - u_32_t nai_nflags; - u_32_t nai_flags; - struct in_addr nai_ip; + struct in_addr nai_ip; /* In host byte order */ u_short nai_port; u_short nai_nport; u_short nai_sport; @@ -340,62 +473,134 @@ typedef struct natinfo { } natinfo_t; -typedef struct natstat { - u_long ns_mapped[2]; - u_long ns_rules; +typedef struct nat_stat_side { + u_int *ns_bucketlen; + nat_t **ns_table; u_long ns_added; - u_long ns_expire; - u_long ns_inuse; - u_long ns_logged; - u_long ns_logfail; - u_long ns_memfail; + u_long ns_appr_fail; u_long ns_badnat; - u_long ns_addtrpnt; - nat_t **ns_table[2]; - hostmap_t **ns_maptable; - ipnat_t *ns_list; - void *ns_apslist; - u_int ns_wilds; - u_int ns_nattab_sz; - u_int ns_nattab_max; - u_int ns_rultab_sz; - u_int ns_rdrtab_sz; - u_int ns_trpntab_sz; - u_int ns_hostmap_sz; - nat_t *ns_instances; - hostmap_t *ns_maplist; - u_long *ns_bucketlen[2]; - u_long ns_ticks; - u_int ns_orphans; + u_long ns_badnatnew; + u_long ns_badnextaddr; + u_long ns_bucket_max; + u_long ns_clone_nomem; + u_long ns_decap_bad; + u_long ns_decap_fail; + u_long ns_decap_pullup; + u_long ns_divert_dup; + u_long ns_divert_exist; + u_long ns_drop; + u_long ns_encap_dup; + u_long ns_encap_pullup; + u_long ns_exhausted; + u_long ns_icmp_address; + u_long ns_icmp_basic; + u_long ns_icmp_mbuf; + u_long ns_icmp_notfound; + u_long ns_icmp_rebuild; + u_long ns_icmp_short; + u_long ns_icmp_size; + u_long ns_ifpaddrfail; + u_long ns_ignored; + u_long ns_insert_fail; + u_long ns_inuse; + u_long ns_log; + u_long ns_lookup_miss; + u_long ns_lookup_nowild; + u_long ns_new_ifpaddr; + u_long ns_memfail; + u_long ns_table_max; + u_long ns_translated; + u_long ns_unfinalised; + u_long ns_wrap; + u_long ns_xlate_null; + u_long ns_xlate_exists; + u_long ns_ipf_proxy_fail; + u_long ns_uncreate[2]; +} nat_stat_side_t; + + +typedef struct natstat { + nat_t *ns_instances; + ipnat_t *ns_list; + hostmap_t *ns_maplist; + hostmap_t **ns_maptable; + u_int ns_active; + u_long ns_addtrpnt; + u_long ns_divert_build; + u_long ns_expire; + u_long ns_flush_all; + u_long ns_flush_closing; + u_long ns_flush_queue; + u_long ns_flush_state; + u_long ns_flush_timeout; + u_long ns_hm_new; + u_long ns_hm_newfail; + u_long ns_hm_addref; + u_long ns_hm_nullnp; + u_long ns_log_ok; + u_long ns_log_fail; + u_int ns_hostmap_sz; + u_int ns_nattab_sz; + u_int ns_nattab_max; + u_int ns_orphans; + u_int ns_rules; + u_int ns_rules_map; + u_int ns_rules_rdr; + u_int ns_rultab_sz; + u_int ns_rdrtab_sz; + u_32_t ns_ticks; + u_int ns_trpntab_sz; + u_int ns_wilds; + u_long ns_proto[256]; + nat_stat_side_t ns_side[2]; +#ifdef USE_INET6 + nat_stat_side_t ns_side6[2]; +#endif } natstat_t; typedef struct natlog { - struct in_addr nl_origip; - struct in_addr nl_outip; - struct in_addr nl_inip; - u_short nl_origport; - u_short nl_outport; - u_short nl_inport; - u_short nl_type; - int nl_rule; + i6addr_t nl_osrcip; + i6addr_t nl_odstip; + i6addr_t nl_nsrcip; + i6addr_t nl_ndstip; + u_short nl_osrcport; + u_short nl_odstport; + u_short nl_nsrcport; + u_short nl_ndstport; + int nl_action; + int nl_type; + int nl_rule; U_QUAD_T nl_pkts[2]; U_QUAD_T nl_bytes[2]; - u_char nl_p; + u_char nl_p[2]; + u_char nl_v[2]; + u_char nl_ifnames[2][LIFNAMSIZ]; } natlog_t; -#define NL_NEWMAP NAT_MAP -#define NL_NEWRDR NAT_REDIRECT -#define NL_NEWBIMAP NAT_BIMAP -#define NL_NEWBLOCK NAT_MAPBLK -#define NL_DESTROY 0xfffc -#define NL_CLONE 0xfffd +#define NL_NEW 0 +#define NL_CLONE 1 +#define NL_PURGE 0xfffc +#define NL_DESTROY 0xfffd #define NL_FLUSH 0xfffe #define NL_EXPIRE 0xffff -#define NAT_HASH_FN(k,l,m) (((k) + ((k) >> 12) + l) % (m)) +#define NAT_HASH_FN(_k,_l,_m) (((_k) + ((_k) >> 12) + _l) % (_m)) +#define NAT_HASH_FN6(_k,_l,_m) ((((u_32_t *)(_k))[3] \ + + (((u_32_t *)(_k))[3] >> 12) \ + + (((u_32_t *)(_k))[2]) \ + + (((u_32_t *)(_k))[2] >> 12) \ + + (((u_32_t *)(_k))[1]) \ + + (((u_32_t *)(_k))[1] >> 12) \ + + (((u_32_t *)(_k))[0]) \ + + (((u_32_t *)(_k))[0] >> 12) \ + + _l) % (_m)) -#define LONG_SUM(in) (((in) & 0xffff) + ((in) >> 16)) +#define LONG_SUM(_i) (((_i) & 0xffff) + ((_i) >> 16)) +#define LONG_SUM6(_i) (LONG_SUM(ntohl(((u_32_t *)(_i))[0])) + \ + LONG_SUM(ntohl(((u_32_t *)(_i))[1])) + \ + LONG_SUM(ntohl(((u_32_t *)(_i))[2])) + \ + LONG_SUM(ntohl(((u_32_t *)(_i))[3]))) #define CALC_SUMD(s1, s2, sd) { \ (s1) = ((s1) & 0xffff) + ((s1) >> 16); \ @@ -411,64 +616,159 @@ typedef struct natlog { #define NAT_SYSSPACE 0x80000000 #define NAT_LOCKHELD 0x40000000 +/* + * This is present in ip_nat.h because it needs to be shared between + * ip_nat.c and ip_nat6.c + */ +typedef struct ipf_nat_softc_s { + ipfmutex_t ipf_nat_new; + ipfmutex_t ipf_nat_io; + int ipf_nat_doflush; + int ipf_nat_logging; + int ipf_nat_lock; + int ipf_nat_inited; + int ipf_nat_table_wm_high; + int ipf_nat_table_wm_low; + u_int ipf_nat_table_max; + u_int ipf_nat_table_sz; + u_int ipf_nat_maprules_sz; + u_int ipf_nat_rdrrules_sz; + u_int ipf_nat_hostmap_sz; + u_int ipf_nat_maxbucket; + u_int ipf_nat_last_force_flush; + u_int ipf_nat_defage; + u_int ipf_nat_defipage; + u_int ipf_nat_deficmpage; + ipf_v4_masktab_t ipf_nat_map_mask; + ipf_v6_masktab_t ipf_nat6_map_mask; + ipf_v4_masktab_t ipf_nat_rdr_mask; + ipf_v6_masktab_t ipf_nat6_rdr_mask; + nat_t **ipf_nat_table[2]; + nat_t *ipf_nat_instances; + ipnat_t *ipf_nat_list; + ipnat_t **ipf_nat_list_tail; + ipnat_t **ipf_nat_map_rules; + ipnat_t **ipf_nat_rdr_rules; + ipftq_t *ipf_nat_utqe; + hostmap_t **ipf_hm_maptable ; + hostmap_t *ipf_hm_maplist ; + ipftuneable_t *ipf_nat_tune; + ipftq_t ipf_nat_udptq; + ipftq_t ipf_nat_udpacktq; + ipftq_t ipf_nat_icmptq; + ipftq_t ipf_nat_icmpacktq; + ipftq_t ipf_nat_iptq; + ipftq_t ipf_nat_pending; + ipftq_t ipf_nat_tcptq[IPF_TCP_NSTATES]; + natstat_t ipf_nat_stats; +} ipf_nat_softc_t ; -extern u_int ipf_nattable_sz; -extern u_int ipf_nattable_max; -extern u_int ipf_natrules_sz; -extern u_int ipf_rdrrules_sz; -extern u_int ipf_hostmap_sz; -extern u_int fr_nat_maxbucket; -extern u_int fr_nat_maxbucket_reset; -extern int fr_nat_lock; -extern int fr_nat_doflush; -extern void fr_natsync __P((void *)); -extern u_long fr_defnatage; -extern u_long fr_defnaticmpage; -extern u_long fr_defnatipage; - /* nat_table[0] -> hashed list sorted by inside (ip, port) */ - /* nat_table[1] -> hashed list sorted by outside (ip, port) */ -extern nat_t **nat_table[2]; -extern nat_t *nat_instances; -extern ipnat_t *nat_list; -extern ipnat_t **nat_rules; -extern ipnat_t **rdr_rules; -extern ipftq_t *nat_utqe; -extern natstat_t nat_stats; +#define ipf_nat_map_max ipf_nat_map_mask.imt4_max +#define ipf_nat_rdr_max ipf_nat_rdr_mask.imt4_max +#define ipf_nat6_map_max ipf_nat6_map_mask.imt6_max +#define ipf_nat6_rdr_max ipf_nat6_rdr_mask.imt6_max +#define ipf_nat_map_active_masks ipf_nat_map_mask.imt4_active +#define ipf_nat_rdr_active_masks ipf_nat_rdr_mask.imt4_active +#define ipf_nat6_map_active_masks ipf_nat6_map_mask.imt6_active +#define ipf_nat6_rdr_active_masks ipf_nat6_rdr_mask.imt6_active +extern frentry_t ipfnatblock; + +extern void ipf_fix_datacksum __P((u_short *, u_32_t)); +extern void ipf_fix_incksum __P((int, u_short *, u_32_t, u_32_t)); +extern void ipf_fix_outcksum __P((int, u_short *, u_32_t, u_32_t)); + +extern int ipf_nat_checkin __P((fr_info_t *, u_32_t *)); +extern int ipf_nat_checkout __P((fr_info_t *, u_32_t *)); +extern void ipf_nat_delete __P((ipf_main_softc_t *, struct nat *, int)); +extern void ipf_nat_deref __P((ipf_main_softc_t *, nat_t **)); +extern void ipf_nat_expire __P((ipf_main_softc_t *)); +extern int ipf_nat_hashtab_add __P((ipf_main_softc_t *, + ipf_nat_softc_t *, nat_t *)); +extern void ipf_nat_hostmapdel __P((ipf_main_softc_t *, hostmap_t **)); +extern int ipf_nat_hostmap_rehash __P((ipf_main_softc_t *, + ipftuneable_t *, ipftuneval_t *)); +extern nat_t *ipf_nat_icmperrorlookup __P((fr_info_t *, int)); +extern nat_t *ipf_nat_icmperror __P((fr_info_t *, u_int *, int)); #if defined(__OpenBSD__) -extern void nat_ifdetach __P((void *)); +extern void ipf_nat_ifdetach __P((void *)); #endif -extern int fr_nat_ioctl __P((caddr_t, ioctlcmd_t, int, int, void *)); -extern int fr_natinit __P((void)); -extern nat_t *nat_new __P((fr_info_t *, ipnat_t *, nat_t **, u_int, int)); -extern nat_t *nat_outlookup __P((fr_info_t *, u_int, u_int, struct in_addr, - struct in_addr)); -extern void fix_datacksum __P((u_short *, u_32_t)); -extern nat_t *nat_inlookup __P((fr_info_t *, u_int, u_int, struct in_addr, +extern int ipf_nat_init __P((void)); +extern nat_t *ipf_nat_inlookup __P((fr_info_t *, u_int, u_int, + struct in_addr, struct in_addr)); +extern int ipf_nat_in __P((fr_info_t *, nat_t *, int, u_32_t)); +extern int ipf_nat_insert __P((ipf_main_softc_t *, ipf_nat_softc_t *, + nat_t *)); +extern int ipf_nat_ioctl __P((ipf_main_softc_t *, caddr_t, ioctlcmd_t, + int, int, void *)); +extern void ipf_nat_log __P((ipf_main_softc_t *, ipf_nat_softc_t *, + struct nat *, u_int)); +extern nat_t *ipf_nat_lookupredir __P((natlookup_t *)); +extern nat_t *ipf_nat_maplookup __P((void *, u_int, struct in_addr, struct in_addr)); -extern nat_t *nat_tnlookup __P((fr_info_t *, int)); -extern nat_t *nat_maplookup __P((void *, u_int, struct in_addr, - struct in_addr)); -extern nat_t *nat_lookupredir __P((natlookup_t *)); -extern nat_t *nat_icmperrorlookup __P((fr_info_t *, int)); -extern nat_t *nat_icmperror __P((fr_info_t *, u_int *, int)); -extern void nat_delete __P((struct nat *, int)); -extern int nat_insert __P((nat_t *, int)); +extern nat_t *ipf_nat_add __P((fr_info_t *, ipnat_t *, nat_t **, + u_int, int)); +extern int ipf_nat_out __P((fr_info_t *, nat_t *, int, u_32_t)); +extern nat_t *ipf_nat_outlookup __P((fr_info_t *, u_int, u_int, + struct in_addr, struct in_addr)); +extern u_short *ipf_nat_proto __P((fr_info_t *, nat_t *, u_int)); +extern void ipf_nat_rule_deref __P((ipf_main_softc_t *, ipnat_t **)); +extern void ipf_nat_setqueue __P((ipf_main_softc_t *, ipf_nat_softc_t *, + nat_t *)); +extern void ipf_nat_setpending __P((ipf_main_softc_t *, nat_t *)); +extern nat_t *ipf_nat_tnlookup __P((fr_info_t *, int)); +extern void ipf_nat_update __P((fr_info_t *, nat_t *)); +extern int ipf_nat_rehash __P((ipf_main_softc_t *, ipftuneable_t *, + ipftuneval_t *)); +extern int ipf_nat_rehash_rules __P((ipf_main_softc_t *, ipftuneable_t *, + ipftuneval_t *)); +extern int ipf_nat_settimeout __P((struct ipf_main_softc_s *, + ipftuneable_t *, ipftuneval_t *)); +extern void ipf_nat_sync __P((ipf_main_softc_t *, void *)); + +extern nat_t *ipf_nat_clone __P((fr_info_t *, nat_t *)); +extern void ipf_nat_delmap __P((ipf_nat_softc_t *, ipnat_t *)); +extern void ipf_nat_delrdr __P((ipf_nat_softc_t *, ipnat_t *)); +extern int ipf_nat_wildok __P((nat_t *, int, int, int, int)); +extern void ipf_nat_setlock __P((void *, int)); +extern void ipf_nat_load __P((void)); +extern void *ipf_nat_soft_create __P((ipf_main_softc_t *)); +extern int ipf_nat_soft_init __P((ipf_main_softc_t *, void *)); +extern void ipf_nat_soft_destroy __P((ipf_main_softc_t *, void *)); +extern int ipf_nat_soft_fini __P((ipf_main_softc_t *, void *)); +extern int ipf_nat_main_load __P((void)); +extern int ipf_nat_main_unload __P((void)); +extern ipftq_t *ipf_nat_add_tq __P((ipf_main_softc_t *, int)); +extern void ipf_nat_uncreate __P((fr_info_t *)); + +#ifdef USE_INET6 +extern nat_t *ipf_nat6_add __P((fr_info_t *, ipnat_t *, nat_t **, + u_int, int)); +extern void ipf_nat6_addrdr __P((ipf_nat_softc_t *, ipnat_t *)); +extern void ipf_nat6_addmap __P((ipf_nat_softc_t *, ipnat_t *)); +extern void ipf_nat6_addencap __P((ipf_nat_softc_t *, ipnat_t *)); +extern int ipf_nat6_checkout __P((fr_info_t *, u_32_t *)); +extern int ipf_nat6_checkin __P((fr_info_t *, u_32_t *)); +extern void ipf_nat6_delmap __P((ipf_nat_softc_t *, ipnat_t *)); +extern void ipf_nat6_delrdr __P((ipf_nat_softc_t *, ipnat_t *)); +extern int ipf_nat6_finalise __P((fr_info_t *, nat_t *)); +extern nat_t *ipf_nat6_icmperror __P((fr_info_t *, u_int *, int)); +extern nat_t *ipf_nat6_icmperrorlookup __P((fr_info_t *, int)); +extern nat_t *ipf_nat6_inlookup __P((fr_info_t *, u_int, u_int, + struct in6_addr *, struct in6_addr *)); +extern u_32_t ipf_nat6_ip6subtract __P((i6addr_t *, i6addr_t *)); +extern frentry_t *ipf_nat6_ipfin __P((fr_info_t *, u_32_t *)); +extern frentry_t *ipf_nat6_ipfout __P((fr_info_t *, u_32_t *)); +extern nat_t *ipf_nat6_lookupredir __P((natlookup_t *)); +extern int ipf_nat6_newmap __P((fr_info_t *, nat_t *, natinfo_t *)); +extern int ipf_nat6_newrdr __P((fr_info_t *, nat_t *, natinfo_t *)); +extern nat_t *ipf_nat6_outlookup __P((fr_info_t *, u_int, u_int, + struct in6_addr *, struct in6_addr *)); +extern int ipf_nat6_newrewrite __P((fr_info_t *, nat_t *, natinfo_t *)); +extern int ipf_nat6_newdivert __P((fr_info_t *, nat_t *, natinfo_t *)); +extern int ipf_nat6_ruleaddrinit __P((ipf_main_softc_t *, ipf_nat_softc_t *, ipnat_t *)); + +#endif -extern int fr_checknatout __P((fr_info_t *, u_32_t *)); -extern int fr_natout __P((fr_info_t *, nat_t *, int, u_32_t)); -extern int fr_checknatin __P((fr_info_t *, u_32_t *)); -extern int fr_natin __P((fr_info_t *, nat_t *, int, u_32_t)); -extern void fr_natunload __P((void)); -extern void fr_natexpire __P((void)); -extern void nat_log __P((struct nat *, u_int)); -extern void fix_incksum __P((fr_info_t *, u_short *, u_32_t)); -extern void fix_outcksum __P((fr_info_t *, u_short *, u_32_t)); -extern void fr_ipnatderef __P((ipnat_t **)); -extern void fr_natderef __P((nat_t **)); -extern u_short *nat_proto __P((fr_info_t *, nat_t *, u_int)); -extern void nat_update __P((fr_info_t *, nat_t *, ipnat_t *)); -extern void fr_setnatqueue __P((nat_t *, int)); -extern void fr_hostmapdel __P((hostmap_t **)); #endif /* __IP_NAT_H__ */ diff --git a/sys/contrib/ipfilter/netinet/ip_nat6.c b/sys/contrib/ipfilter/netinet/ip_nat6.c new file mode 100644 index 000000000000..72931c9fca2d --- /dev/null +++ b/sys/contrib/ipfilter/netinet/ip_nat6.c @@ -0,0 +1,4098 @@ +/* + * Copyright (C) 2012 by Darren Reed. + * + * See the IPFILTER.LICENCE file for details on licencing. + */ +#if defined(KERNEL) || defined(_KERNEL) +# undef KERNEL +# undef _KERNEL +# define KERNEL 1 +# define _KERNEL 1 +#endif +#include +#include +#include +#include +#include +#if defined(_KERNEL) && defined(__NetBSD_Version__) && \ + (__NetBSD_Version__ >= 399002000) +# include +#endif +#if !defined(_KERNEL) +# include +# include +# include +# define _KERNEL +# ifdef ipf_nat6__OpenBSD__ +struct file; +# endif +# include +# undef _KERNEL +#endif +#if defined(_KERNEL) && (__FreeBSD_version >= 220000) +# include +# include +#else +# include +#endif +#if !defined(AIX) +# include +#endif +#if !defined(linux) +# include +#endif +#include +#if defined(_KERNEL) +# include +# if !defined(__SVR4) && !defined(__svr4__) +# include +# endif +#endif +#if defined(__SVR4) || defined(__svr4__) +# include +# include +# ifdef _KERNEL +# include +# endif +# include +# include +#endif +#if __FreeBSD_version >= 300000 +# include +#endif +#include +#if __FreeBSD_version >= 300000 +# include +#endif +#ifdef sun +# include +#endif +#include +#include +#include +#include + +#ifdef RFC1825 +# include +# include +extern struct ifnet vpnif; +#endif + +#if !defined(linux) +# include +#endif +#include +#include +#include +#include "netinet/ip_compat.h" +#include +#include "netinet/ip_fil.h" +#include "netinet/ip_nat.h" +#include "netinet/ip_frag.h" +#include "netinet/ip_state.h" +#include "netinet/ip_proxy.h" +#include "netinet/ip_lookup.h" +#include "netinet/ip_dstlist.h" +#include "netinet/ip_sync.h" +#if (__FreeBSD_version >= 300000) +# include +#endif +#ifdef HAS_SYS_MD5_H +# include +#else +# include "md5.h" +#endif +/* END OF INCLUDES */ + +#undef SOCKADDR_IN +#define SOCKADDR_IN struct sockaddr_in + +#if !defined(lint) +static const char rcsid[] = "@(#)$Id: ip_nat6.c,v 1.22.2.20 2012/07/22 08:04:23 darren_r Exp $"; +#endif + +#ifdef USE_INET6 +static struct hostmap *ipf_nat6_hostmap __P((ipf_nat_softc_t *, ipnat_t *, + i6addr_t *, i6addr_t *, + i6addr_t *, u_32_t)); +static int ipf_nat6_match __P((fr_info_t *, ipnat_t *)); +static void ipf_nat6_tabmove __P((ipf_nat_softc_t *, nat_t *)); +static int ipf_nat6_decap __P((fr_info_t *, nat_t *)); +static int ipf_nat6_nextaddr __P((fr_info_t *, nat_addr_t *, i6addr_t *, + i6addr_t *)); +static int ipf_nat6_icmpquerytype __P((int)); +static int ipf_nat6_out __P((fr_info_t *, nat_t *, int, u_32_t)); +static int ipf_nat6_in __P((fr_info_t *, nat_t *, int, u_32_t)); +static int ipf_nat6_builddivertmp __P((ipf_nat_softc_t *, ipnat_t *)); +static int ipf_nat6_nextaddrinit __P((ipf_main_softc_t *, char *, + nat_addr_t *, int, void *)); +static int ipf_nat6_insert __P((ipf_main_softc_t *, ipf_nat_softc_t *, + nat_t *)); + + +#define NINCLSIDE6(y,x) ATOMIC_INCL(softn->ipf_nat_stats.ns_side6[y].x) +#define NBUMPSIDE(y,x) softn->ipf_nat_stats.ns_side[y].x++ +#define NBUMPSIDE6(y,x) softn->ipf_nat_stats.ns_side6[y].x++ +#define NBUMPSIDE6D(y,x) \ + do { \ + softn->ipf_nat_stats.ns_side6[y].x++; \ + DT(x); \ + } while (0) +#define NBUMPSIDE6DX(y,x,z) \ + do { \ + softn->ipf_nat_stats.ns_side6[y].x++; \ + DT(z); \ + } while (0) + + +/* ------------------------------------------------------------------------ */ +/* Function: ipf_nat6_ruleaddrinit */ +/* Returns: int - 0 == success, else failure */ +/* Parameters: in(I) - NAT rule that requires address fields to be init'd */ +/* */ +/* For each of the source/destination address fields in a NAT rule, call */ +/* ipf_nat6_nextaddrinit() to prepare the structure for active duty. Other */ +/* IPv6 specific actions can also be taken care of here. */ +/* ------------------------------------------------------------------------ */ +int +ipf_nat6_ruleaddrinit(softc, softn, n) + ipf_main_softc_t *softc; + ipf_nat_softc_t *softn; + ipnat_t *n; +{ + int idx, error; + + if (n->in_redir == NAT_BIMAP) { + n->in_ndstip6 = n->in_osrcip6; + n->in_ndstmsk6 = n->in_osrcmsk6; + n->in_odstip6 = n->in_nsrcip6; + n->in_odstmsk6 = n->in_nsrcmsk6; + + } + + if (n->in_redir & NAT_REDIRECT) + idx = 1; + else + idx = 0; + /* + * Initialise all of the address fields. + */ + error = ipf_nat6_nextaddrinit(softc, n->in_names, &n->in_osrc, 1, + n->in_ifps[idx]); + if (error != 0) + return error; + + error = ipf_nat6_nextaddrinit(softc, n->in_names, &n->in_odst, 1, + n->in_ifps[idx]); + if (error != 0) + return error; + + error = ipf_nat6_nextaddrinit(softc, n->in_names, &n->in_nsrc, 1, + n->in_ifps[idx]); + if (error != 0) + return error; + + error = ipf_nat6_nextaddrinit(softc, n->in_names, &n->in_ndst, 1, + n->in_ifps[idx]); + if (error != 0) + return error; + + if (n->in_redir & NAT_DIVERTUDP) + ipf_nat6_builddivertmp(softn, n); + return 0; +} + + +/* ------------------------------------------------------------------------ */ +/* Function: ipf_nat6_addrdr */ +/* Returns: Nil */ +/* Parameters: n(I) - pointer to NAT rule to add */ +/* */ +/* Adds a redirect rule to the hash table of redirect rules and the list of */ +/* loaded NAT rules. Updates the bitmask indicating which netmasks are in */ +/* use by redirect rules. */ +/* ------------------------------------------------------------------------ */ +void +ipf_nat6_addrdr(softn, n) + ipf_nat_softc_t *softn; + ipnat_t *n; +{ + i6addr_t *mask; + ipnat_t **np; + i6addr_t j; + u_int hv; + int k; + + if ((n->in_redir & NAT_BIMAP) == NAT_BIMAP) { + k = count6bits(n->in_nsrcmsk6.i6); + mask = &n->in_nsrcmsk6; + IP6_AND(&n->in_odstip6, &n->in_odstmsk6, &j); + hv = NAT_HASH_FN6(&j, 0, softn->ipf_nat_rdrrules_sz); + + } else if (n->in_odstatype == FRI_NORMAL) { + k = count6bits(n->in_odstmsk6.i6); + mask = &n->in_odstmsk6; + IP6_AND(&n->in_odstip6, &n->in_odstmsk6, &j); + hv = NAT_HASH_FN6(&j, 0, softn->ipf_nat_rdrrules_sz); + } else { + k = 0; + hv = 0; + mask = NULL; + } + ipf_inet6_mask_add(k, mask, &softn->ipf_nat6_rdr_mask); + + np = softn->ipf_nat_rdr_rules + hv; + while (*np != NULL) + np = &(*np)->in_rnext; + n->in_rnext = NULL; + n->in_prnext = np; + n->in_hv[0] = hv; + n->in_use++; + *np = n; +} + + +/* ------------------------------------------------------------------------ */ +/* Function: ipf_nat6_addmap */ +/* Returns: Nil */ +/* Parameters: n(I) - pointer to NAT rule to add */ +/* */ +/* Adds a NAT map rule to the hash table of rules and the list of loaded */ +/* NAT rules. Updates the bitmask indicating which netmasks are in use by */ +/* redirect rules. */ +/* ------------------------------------------------------------------------ */ +void +ipf_nat6_addmap(softn, n) + ipf_nat_softc_t *softn; + ipnat_t *n; +{ + i6addr_t *mask; + ipnat_t **np; + i6addr_t j; + u_int hv; + int k; + + if (n->in_osrcatype == FRI_NORMAL) { + k = count6bits(n->in_osrcmsk6.i6); + mask = &n->in_osrcmsk6; + IP6_AND(&n->in_osrcip6, &n->in_osrcmsk6, &j); + hv = NAT_HASH_FN6(&j, 0, softn->ipf_nat_maprules_sz); + } else { + k = 0; + hv = 0; + mask = NULL; + } + ipf_inet6_mask_add(k, mask, &softn->ipf_nat6_map_mask); + + np = softn->ipf_nat_map_rules + hv; + while (*np != NULL) + np = &(*np)->in_mnext; + n->in_mnext = NULL; + n->in_pmnext = np; + n->in_hv[1] = hv; + n->in_use++; + *np = n; +} + + +/* ------------------------------------------------------------------------ */ +/* Function: ipf_nat6_del_rdr */ +/* Returns: Nil */ +/* Parameters: n(I) - pointer to NAT rule to delete */ +/* */ +/* Removes a NAT rdr rule from the hash table of NAT rdr rules. */ +/* ------------------------------------------------------------------------ */ +void +ipf_nat6_delrdr(softn, n) + ipf_nat_softc_t *softn; + ipnat_t *n; +{ + i6addr_t *mask; + int k; + + if ((n->in_redir & NAT_BIMAP) == NAT_BIMAP) { + k = count6bits(n->in_nsrcmsk6.i6); + mask = &n->in_nsrcmsk6; + } else if (n->in_odstatype == FRI_NORMAL) { + k = count6bits(n->in_odstmsk6.i6); + mask = &n->in_odstmsk6; + } else { + k = 0; + mask = NULL; + } + ipf_inet6_mask_del(k, mask, &softn->ipf_nat6_rdr_mask); + + if (n->in_rnext != NULL) + n->in_rnext->in_prnext = n->in_prnext; + *n->in_prnext = n->in_rnext; + n->in_use--; +} + + +/* ------------------------------------------------------------------------ */ +/* Function: ipf_nat6_delmap */ +/* Returns: Nil */ +/* Parameters: n(I) - pointer to NAT rule to delete */ +/* */ +/* Removes a NAT map rule from the hash table of NAT map rules. */ +/* ------------------------------------------------------------------------ */ +void +ipf_nat6_delmap(softn, n) + ipf_nat_softc_t *softn; + ipnat_t *n; +{ + i6addr_t *mask; + int k; + + if (n->in_osrcatype == FRI_NORMAL) { + k = count6bits(n->in_osrcmsk6.i6); + mask = &n->in_osrcmsk6; + } else { + k = 0; + mask = NULL; + } + ipf_inet6_mask_del(k, mask, &softn->ipf_nat6_map_mask); + + if (n->in_mnext != NULL) + n->in_mnext->in_pmnext = n->in_pmnext; + *n->in_pmnext = n->in_mnext; + n->in_use--; +} + + +/* ------------------------------------------------------------------------ */ +/* Function: ipf_nat6_hostmap */ +/* Returns: struct hostmap* - NULL if no hostmap could be created, */ +/* else a pointer to the hostmapping to use */ +/* Parameters: np(I) - pointer to NAT rule */ +/* real(I) - real IP address */ +/* map(I) - mapped IP address */ +/* port(I) - destination port number */ +/* Write Locks: ipf_nat */ +/* */ +/* Check if an ip address has already been allocated for a given mapping */ +/* that is not doing port based translation. If is not yet allocated, then */ +/* create a new entry if a non-NULL NAT rule pointer has been supplied. */ +/* ------------------------------------------------------------------------ */ +static struct hostmap * +ipf_nat6_hostmap(softn, np, src, dst, map, port) + ipf_nat_softc_t *softn; + ipnat_t *np; + i6addr_t *src, *dst, *map; + u_32_t port; +{ + hostmap_t *hm; + u_int hv; + + hv = (src->i6[3] ^ dst->i6[3]); + hv += (src->i6[2] ^ dst->i6[2]); + hv += (src->i6[1] ^ dst->i6[1]); + hv += (src->i6[0] ^ dst->i6[0]); + hv += src->i6[3]; + hv += src->i6[2]; + hv += src->i6[1]; + hv += src->i6[0]; + hv += dst->i6[3]; + hv += dst->i6[2]; + hv += dst->i6[1]; + hv += dst->i6[0]; + hv %= HOSTMAP_SIZE; + for (hm = softn->ipf_hm_maptable[hv]; hm; hm = hm->hm_next) + if (IP6_EQ(&hm->hm_osrc6, src) && + IP6_EQ(&hm->hm_odst6, dst) && + ((np == NULL) || (np == hm->hm_ipnat)) && + ((port == 0) || (port == hm->hm_port))) { + softn->ipf_nat_stats.ns_hm_addref++; + hm->hm_ref++; + return hm; + } + + if (np == NULL) { + softn->ipf_nat_stats.ns_hm_nullnp++; + return NULL; + } + + KMALLOC(hm, hostmap_t *); + if (hm) { + hm->hm_next = softn->ipf_hm_maplist; + hm->hm_pnext = &softn->ipf_hm_maplist; + if (softn->ipf_hm_maplist != NULL) + softn->ipf_hm_maplist->hm_pnext = &hm->hm_next; + softn->ipf_hm_maplist = hm; + hm->hm_hnext = softn->ipf_hm_maptable[hv]; + hm->hm_phnext = softn->ipf_hm_maptable + hv; + if (softn->ipf_hm_maptable[hv] != NULL) + softn->ipf_hm_maptable[hv]->hm_phnext = &hm->hm_hnext; + softn->ipf_hm_maptable[hv] = hm; + hm->hm_ipnat = np; + np->in_use++; + hm->hm_osrcip6 = *src; + hm->hm_odstip6 = *dst; + hm->hm_nsrcip6 = *map; + hm->hm_ndstip6.i6[0] = 0; + hm->hm_ndstip6.i6[1] = 0; + hm->hm_ndstip6.i6[2] = 0; + hm->hm_ndstip6.i6[3] = 0; + hm->hm_ref = 1; + hm->hm_port = port; + hm->hm_hv = hv; + hm->hm_v = 6; + softn->ipf_nat_stats.ns_hm_new++; + } else { + softn->ipf_nat_stats.ns_hm_newfail++; + } + return hm; +} + + +/* ------------------------------------------------------------------------ */ +/* Function: ipf_nat6_newmap */ +/* Returns: int - -1 == error, 0 == success */ +/* Parameters: fin(I) - pointer to packet information */ +/* nat(I) - pointer to NAT entry */ +/* ni(I) - pointer to structure with misc. information needed */ +/* to create new NAT entry. */ +/* */ +/* Given an empty NAT structure, populate it with new information about a */ +/* new NAT session, as defined by the matching NAT rule. */ +/* ni.nai_ip is passed in uninitialised and must be set, in host byte order,*/ +/* to the new IP address for the translation. */ +/* ------------------------------------------------------------------------ */ +int +ipf_nat6_newmap(fin, nat, ni) + fr_info_t *fin; + nat_t *nat; + natinfo_t *ni; +{ + ipf_main_softc_t *softc = fin->fin_main_soft; + ipf_nat_softc_t *softn = softc->ipf_nat_soft; + u_short st_port, dport, sport, port, sp, dp; + i6addr_t in, st_ip; + hostmap_t *hm; + u_32_t flags; + ipnat_t *np; + nat_t *natl; + int l; + + /* + * If it's an outbound packet which doesn't match any existing + * record, then create a new port + */ + l = 0; + hm = NULL; + np = ni->nai_np; + st_ip = np->in_snip6; + st_port = np->in_spnext; + flags = nat->nat_flags; + + if (flags & IPN_ICMPQUERY) { + sport = fin->fin_data[1]; + dport = 0; + } else { + sport = htons(fin->fin_data[0]); + dport = htons(fin->fin_data[1]); + } + + /* + * Do a loop until we either run out of entries to try or we find + * a NAT mapping that isn't currently being used. This is done + * because the change to the source is not (usually) being fixed. + */ + do { + port = 0; + in = np->in_nsrc.na_nextaddr; + if (l == 0) { + /* + * Check to see if there is an existing NAT + * setup for this IP address pair. + */ + hm = ipf_nat6_hostmap(softn, np, &fin->fin_src6, + &fin->fin_dst6, &in, 0); + if (hm != NULL) + in = hm->hm_nsrcip6; + } else if ((l == 1) && (hm != NULL)) { + ipf_nat_hostmapdel(softc, &hm); + } + + nat->nat_hm = hm; + + if (IP6_ISONES(&np->in_nsrcmsk6) && (np->in_spnext == 0)) { + if (l > 0) { + NBUMPSIDE6DX(1, ns_exhausted, ns_exhausted_1); + return -1; + } + } + + if ((np->in_redir == NAT_BIMAP) && + IP6_EQ(&np->in_osrcmsk6, &np->in_nsrcmsk6)) { + i6addr_t temp; + /* + * map the address block in a 1:1 fashion + */ + temp.i6[0] = fin->fin_src6.i6[0] & + ~np->in_osrcmsk6.i6[0]; + temp.i6[1] = fin->fin_src6.i6[1] & + ~np->in_osrcmsk6.i6[1]; + temp.i6[2] = fin->fin_src6.i6[2] & + ~np->in_osrcmsk6.i6[0]; + temp.i6[3] = fin->fin_src6.i6[3] & + ~np->in_osrcmsk6.i6[3]; + in = np->in_nsrcip6; + IP6_MERGE(&in, &temp, &np->in_osrc); + +#ifdef NEED_128BIT_MATH + } else if (np->in_redir & NAT_MAPBLK) { + if ((l >= np->in_ppip) || ((l > 0) && + !(flags & IPN_TCPUDP))) { + NBUMPSIDE6DX(1, ns_exhausted, ns_exhausted_2); + return -1; + } + /* + * map-block - Calculate destination address. + */ + IP6_MASK(&in, &fin->fin_src6, &np->in_osrcmsk6); + in = ntohl(in); + inb = in; + in.s_addr /= np->in_ippip; + in.s_addr &= ntohl(~np->in_nsrcmsk6); + in.s_addr += ntohl(np->in_nsrcaddr6); + /* + * Calculate destination port. + */ + if ((flags & IPN_TCPUDP) && + (np->in_ppip != 0)) { + port = ntohs(sport) + l; + port %= np->in_ppip; + port += np->in_ppip * + (inb.s_addr % np->in_ippip); + port += MAPBLK_MINPORT; + port = htons(port); + } +#endif + + } else if (IP6_ISZERO(&np->in_nsrcaddr) && + IP6_ISONES(&np->in_nsrcmsk)) { + /* + * 0/32 - use the interface's IP address. + */ + if ((l > 0) || + ipf_ifpaddr(softc, 6, FRI_NORMAL, fin->fin_ifp, + &in, NULL) == -1) { + NBUMPSIDE6DX(1, ns_new_ifpaddr, + ns_new_ifpaddr_1); + return -1; + } + + } else if (IP6_ISZERO(&np->in_nsrcip6) && + IP6_ISZERO(&np->in_nsrcmsk6)) { + /* + * 0/0 - use the original source address/port. + */ + if (l > 0) { + NBUMPSIDE6DX(1, ns_exhausted, ns_exhausted_3); + return -1; + } + in = fin->fin_src6; + + } else if (!IP6_ISONES(&np->in_nsrcmsk6) && + (np->in_spnext == 0) && ((l > 0) || (hm == NULL))) { + IP6_INC(&np->in_snip6); + } + + natl = NULL; + + if ((flags & IPN_TCPUDP) && + ((np->in_redir & NAT_MAPBLK) == 0) && + (np->in_flags & IPN_AUTOPORTMAP)) { +#ifdef NEED_128BIT_MATH + /* + * "ports auto" (without map-block) + */ + if ((l > 0) && (l % np->in_ppip == 0)) { + if ((l > np->in_ppip) && + !IP6_ISONES(&np->in_nsrcmsk)) { + IP6_INC(&np->in_snip6) + } + } + if (np->in_ppip != 0) { + port = ntohs(sport); + port += (l % np->in_ppip); + port %= np->in_ppip; + port += np->in_ppip * + (ntohl(fin->fin_src6) % + np->in_ippip); + port += MAPBLK_MINPORT; + port = htons(port); + } +#endif + + } else if (((np->in_redir & NAT_MAPBLK) == 0) && + (flags & IPN_TCPUDPICMP) && (np->in_spnext != 0)) { + /* + * Standard port translation. Select next port. + */ + if (np->in_flags & IPN_SEQUENTIAL) { + port = np->in_spnext; + } else { + port = ipf_random() % (np->in_spmax - + np->in_spmin + 1); + port += np->in_spmin; + } + port = htons(port); + np->in_spnext++; + + if (np->in_spnext > np->in_spmax) { + np->in_spnext = np->in_spmin; + if (!IP6_ISONES(&np->in_nsrcmsk6)) { + IP6_INC(&np->in_snip6); + } + } + } + + if (np->in_flags & IPN_SIPRANGE) { + if (IP6_GT(&np->in_snip, &np->in_nsrcmsk)) + np->in_snip6 = np->in_nsrcip6; + } else { + i6addr_t a1, a2; + + a1 = np->in_snip6; + IP6_INC(&a1); + IP6_AND(&a1, &np->in_nsrcmsk6, &a2); + + if (!IP6_ISONES(&np->in_nsrcmsk6) && + IP6_GT(&a2, &np->in_nsrcip6)) { + IP6_ADD(&np->in_nsrcip6, 1, &np->in_snip6); + } + } + + if ((port == 0) && (flags & (IPN_TCPUDPICMP|IPN_ICMPQUERY))) + port = sport; + + /* + * Here we do a lookup of the connection as seen from + * the outside. If an IP# pair already exists, try + * again. So if you have A->B becomes C->B, you can + * also have D->E become C->E but not D->B causing + * another C->B. Also take protocol and ports into + * account when determining whether a pre-existing + * NAT setup will cause an external conflict where + * this is appropriate. + */ + sp = fin->fin_data[0]; + dp = fin->fin_data[1]; + fin->fin_data[0] = fin->fin_data[1]; + fin->fin_data[1] = ntohs(port); + natl = ipf_nat6_inlookup(fin, flags & ~(SI_WILDP|NAT_SEARCH), + (u_int)fin->fin_p, &fin->fin_dst6.in6, + &in.in6); + fin->fin_data[0] = sp; + fin->fin_data[1] = dp; + + /* + * Has the search wrapped around and come back to the + * start ? + */ + if ((natl != NULL) && + (np->in_spnext != 0) && (st_port == np->in_spnext) && + (!IP6_ISZERO(&np->in_snip6) && + IP6_EQ(&st_ip, &np->in_snip6))) { + NBUMPSIDE6D(1, ns_wrap); + return -1; + } + l++; + } while (natl != NULL); + + /* Setup the NAT table */ + nat->nat_osrc6 = fin->fin_src6; + nat->nat_nsrc6 = in; + nat->nat_odst6 = fin->fin_dst6; + nat->nat_ndst6 = fin->fin_dst6; + if (nat->nat_hm == NULL) + nat->nat_hm = ipf_nat6_hostmap(softn, np, &fin->fin_src6, + &fin->fin_dst6, + &nat->nat_nsrc6, 0); + + if (flags & IPN_TCPUDP) { + nat->nat_osport = sport; + nat->nat_nsport = port; /* sport */ + nat->nat_odport = dport; + nat->nat_ndport = dport; + ((tcphdr_t *)fin->fin_dp)->th_sport = port; + } else if (flags & IPN_ICMPQUERY) { + nat->nat_oicmpid = fin->fin_data[1]; + ((struct icmp6_hdr *)fin->fin_dp)->icmp6_id = port; + nat->nat_nicmpid = port; + } + return 0; +} + + +/* ------------------------------------------------------------------------ */ +/* Function: ipf_nat6_newrdr */ +/* Returns: int - -1 == error, 0 == success (no move), 1 == success and */ +/* allow rule to be moved if IPN_ROUNDR is set. */ +/* Parameters: fin(I) - pointer to packet information */ +/* nat(I) - pointer to NAT entry */ +/* ni(I) - pointer to structure with misc. information needed */ +/* to create new NAT entry. */ +/* */ +/* ni.nai_ip is passed in uninitialised and must be set, in host byte order,*/ +/* to the new IP address for the translation. */ +/* ------------------------------------------------------------------------ */ +int +ipf_nat6_newrdr(fin, nat, ni) + fr_info_t *fin; + nat_t *nat; + natinfo_t *ni; +{ + ipf_main_softc_t *softc = fin->fin_main_soft; + ipf_nat_softc_t *softn = softc->ipf_nat_soft; + u_short nport, dport, sport; + u_short sp, dp; + hostmap_t *hm; + u_32_t flags; + i6addr_t in; + ipnat_t *np; + nat_t *natl; + int move; + + move = 1; + hm = NULL; + in.i6[0] = 0; + in.i6[1] = 0; + in.i6[2] = 0; + in.i6[3] = 0; + np = ni->nai_np; + flags = nat->nat_flags; + + if (flags & IPN_ICMPQUERY) { + dport = fin->fin_data[1]; + sport = 0; + } else { + sport = htons(fin->fin_data[0]); + dport = htons(fin->fin_data[1]); + } + + /* TRACE sport, dport */ + + + /* + * If the matching rule has IPN_STICKY set, then we want to have the + * same rule kick in as before. Why would this happen? If you have + * a collection of rdr rules with "round-robin sticky", the current + * packet might match a different one to the previous connection but + * we want the same destination to be used. + */ + if (((np->in_flags & (IPN_ROUNDR|IPN_SPLIT)) != 0) && + ((np->in_flags & IPN_STICKY) != 0)) { + hm = ipf_nat6_hostmap(softn, NULL, &fin->fin_src6, + &fin->fin_dst6, &in, (u_32_t)dport); + if (hm != NULL) { + in = hm->hm_ndstip6; + np = hm->hm_ipnat; + ni->nai_np = np; + move = 0; + } + } + + /* + * Otherwise, it's an inbound packet. Most likely, we don't + * want to rewrite source ports and source addresses. Instead, + * we want to rewrite to a fixed internal address and fixed + * internal port. + */ + if (np->in_flags & IPN_SPLIT) { + in = np->in_dnip6; + + if ((np->in_flags & (IPN_ROUNDR|IPN_STICKY)) == IPN_STICKY) { + hm = ipf_nat6_hostmap(softn, NULL, &fin->fin_src6, + &fin->fin_dst6, &in, + (u_32_t)dport); + if (hm != NULL) { + in = hm->hm_ndstip6; + move = 0; + } + } + + if (hm == NULL || hm->hm_ref == 1) { + if (IP6_EQ(&np->in_ndstip6, &in)) { + np->in_dnip6 = np->in_ndstmsk6; + move = 0; + } else { + np->in_dnip6 = np->in_ndstip6; + } + } + + } else if (IP6_ISZERO(&np->in_ndstaddr) && + IP6_ISONES(&np->in_ndstmsk)) { + /* + * 0/32 - use the interface's IP address. + */ + if (ipf_ifpaddr(softc, 6, FRI_NORMAL, fin->fin_ifp, + &in, NULL) == -1) { + NBUMPSIDE6DX(0, ns_new_ifpaddr, ns_new_ifpaddr_2); + return -1; + } + + } else if (IP6_ISZERO(&np->in_ndstip6) && + IP6_ISZERO(&np->in_ndstmsk6)) { + /* + * 0/0 - use the original destination address/port. + */ + in = fin->fin_dst6; + + } else if (np->in_redir == NAT_BIMAP && + IP6_EQ(&np->in_ndstmsk6, &np->in_odstmsk6)) { + i6addr_t temp; + /* + * map the address block in a 1:1 fashion + */ + temp.i6[0] = fin->fin_dst6.i6[0] & ~np->in_osrcmsk6.i6[0]; + temp.i6[1] = fin->fin_dst6.i6[1] & ~np->in_osrcmsk6.i6[1]; + temp.i6[2] = fin->fin_dst6.i6[2] & ~np->in_osrcmsk6.i6[0]; + temp.i6[3] = fin->fin_dst6.i6[3] & ~np->in_osrcmsk6.i6[3]; + in = np->in_ndstip6; + IP6_MERGE(&in, &temp, &np->in_ndstmsk6); + } else { + in = np->in_ndstip6; + } + + if ((np->in_dpnext == 0) || ((flags & NAT_NOTRULEPORT) != 0)) + nport = dport; + else { + /* + * Whilst not optimized for the case where + * pmin == pmax, the gain is not significant. + */ + if (((np->in_flags & IPN_FIXEDDPORT) == 0) && + (np->in_odport != np->in_dtop)) { + nport = ntohs(dport) - np->in_odport + np->in_dpmax; + nport = htons(nport); + } else { + nport = htons(np->in_dpnext); + np->in_dpnext++; + if (np->in_dpnext > np->in_dpmax) + np->in_dpnext = np->in_dpmin; + } + } + + /* + * When the redirect-to address is set to 0.0.0.0, just + * assume a blank `forwarding' of the packet. We don't + * setup any translation for this either. + */ + if (IP6_ISZERO(&in)) { + if (nport == dport) { + NBUMPSIDE6D(0, ns_xlate_null); + return -1; + } + in = fin->fin_dst6; + } + + /* + * Check to see if this redirect mapping already exists and if + * it does, return "failure" (allowing it to be created will just + * cause one or both of these "connections" to stop working.) + */ + sp = fin->fin_data[0]; + dp = fin->fin_data[1]; + fin->fin_data[1] = fin->fin_data[0]; + fin->fin_data[0] = ntohs(nport); + natl = ipf_nat6_outlookup(fin, flags & ~(SI_WILDP|NAT_SEARCH), + (u_int)fin->fin_p, &in.in6, + &fin->fin_src6.in6); + fin->fin_data[0] = sp; + fin->fin_data[1] = dp; + if (natl != NULL) { + NBUMPSIDE6D(0, ns_xlate_exists); + return -1; + } + + nat->nat_ndst6 = in; + nat->nat_odst6 = fin->fin_dst6; + nat->nat_nsrc6 = fin->fin_src6; + nat->nat_osrc6 = fin->fin_src6; + if ((nat->nat_hm == NULL) && ((np->in_flags & IPN_STICKY) != 0)) + nat->nat_hm = ipf_nat6_hostmap(softn, np, &fin->fin_src6, + &fin->fin_dst6, &in, + (u_32_t)dport); + + if (flags & IPN_TCPUDP) { + nat->nat_odport = dport; + nat->nat_ndport = nport; + nat->nat_osport = sport; + nat->nat_nsport = sport; + ((tcphdr_t *)fin->fin_dp)->th_dport = nport; + } else if (flags & IPN_ICMPQUERY) { + nat->nat_oicmpid = fin->fin_data[1]; + ((struct icmp6_hdr *)fin->fin_dp)->icmp6_id = nport; + nat->nat_nicmpid = nport; + } + + return move; +} + +/* ------------------------------------------------------------------------ */ +/* Function: ipf_nat6_add */ +/* Returns: nat6_t* - NULL == failure to create new NAT structure, */ +/* else pointer to new NAT structure */ +/* Parameters: fin(I) - pointer to packet information */ +/* np(I) - pointer to NAT rule */ +/* natsave(I) - pointer to where to store NAT struct pointer */ +/* flags(I) - flags describing the current packet */ +/* direction(I) - direction of packet (in/out) */ +/* Write Lock: ipf_nat */ +/* */ +/* Attempts to create a new NAT entry. Does not actually change the packet */ +/* in any way. */ +/* */ +/* This fucntion is in three main parts: (1) deal with creating a new NAT */ +/* structure for a "MAP" rule (outgoing NAT translation); (2) deal with */ +/* creating a new NAT structure for a "RDR" rule (incoming NAT translation) */ +/* and (3) building that structure and putting it into the NAT table(s). */ +/* */ +/* NOTE: natsave should NOT be used top point back to an ipstate_t struct */ +/* as it can result in memory being corrupted. */ +/* ------------------------------------------------------------------------ */ +nat_t * +ipf_nat6_add(fin, np, natsave, flags, direction) + fr_info_t *fin; + ipnat_t *np; + nat_t **natsave; + u_int flags; + int direction; +{ + ipf_main_softc_t *softc = fin->fin_main_soft; + ipf_nat_softc_t *softn = softc->ipf_nat_soft; + hostmap_t *hm = NULL; + nat_t *nat, *natl; + natstat_t *nsp; + u_int nflags; + natinfo_t ni; + int move; +#if SOLARIS && defined(_KERNEL) && (SOLARIS2 >= 6) && defined(ICK_M_CTL_MAGIC) + qpktinfo_t *qpi = fin->fin_qpi; +#endif + + nsp = &softn->ipf_nat_stats; + + if ((nsp->ns_active * 100 / softn->ipf_nat_table_max) > + softn->ipf_nat_table_wm_high) { + softn->ipf_nat_doflush = 1; + } + + if (nsp->ns_active >= softn->ipf_nat_table_max) { + NBUMPSIDE6(fin->fin_out, ns_table_max); + return NULL; + } + + move = 1; + nflags = np->in_flags & flags; + nflags &= NAT_FROMRULE; + + ni.nai_np = np; + ni.nai_dport = 0; + ni.nai_sport = 0; + + /* Give me a new nat */ + KMALLOC(nat, nat_t *); + if (nat == NULL) { + NBUMPSIDE6(fin->fin_out, ns_memfail); + /* + * Try to automatically tune the max # of entries in the + * table allowed to be less than what will cause kmem_alloc() + * to fail and try to eliminate panics due to out of memory + * conditions arising. + */ + if ((softn->ipf_nat_table_max > softn->ipf_nat_table_sz) && + (nsp->ns_active > 100)) { + softn->ipf_nat_table_max = nsp->ns_active - 100; + printf("table_max reduced to %d\n", + softn->ipf_nat_table_max); + } + return NULL; + } + + if (flags & IPN_ICMPQUERY) { + /* + * In the ICMP query NAT code, we translate the ICMP id fields + * to make them unique. This is indepedent of the ICMP type + * (e.g. in the unlikely event that a host sends an echo and + * an tstamp request with the same id, both packets will have + * their ip address/id field changed in the same way). + */ + /* The icmp6_id field is used by the sender to identify the + * process making the icmp request. (the receiver justs + * copies it back in its response). So, it closely matches + * the concept of source port. We overlay sport, so we can + * maximally reuse the existing code. + */ + ni.nai_sport = fin->fin_data[1]; + ni.nai_dport = 0; + } + + bzero((char *)nat, sizeof(*nat)); + nat->nat_flags = flags; + nat->nat_redir = np->in_redir; + nat->nat_dir = direction; + nat->nat_pr[0] = fin->fin_p; + nat->nat_pr[1] = fin->fin_p; + + /* + * Search the current table for a match and create a new mapping + * if there is none found. + */ + if (np->in_redir & NAT_DIVERTUDP) { + move = ipf_nat6_newdivert(fin, nat, &ni); + + } else if (np->in_redir & NAT_REWRITE) { + move = ipf_nat6_newrewrite(fin, nat, &ni); + + } else if (direction == NAT_OUTBOUND) { + /* + * We can now arrange to call this for the same connection + * because ipf_nat6_new doesn't protect the code path into + * this function. + */ + natl = ipf_nat6_outlookup(fin, nflags, (u_int)fin->fin_p, + &fin->fin_src6.in6, + &fin->fin_dst6.in6); + if (natl != NULL) { + KFREE(nat); + nat = natl; + goto done; + } + + move = ipf_nat6_newmap(fin, nat, &ni); + } else { + /* + * NAT_INBOUND is used for redirects rules + */ + natl = ipf_nat6_inlookup(fin, nflags, (u_int)fin->fin_p, + &fin->fin_src6.in6, + &fin->fin_dst6.in6); + if (natl != NULL) { + KFREE(nat); + nat = natl; + goto done; + } + + move = ipf_nat6_newrdr(fin, nat, &ni); + } + if (move == -1) + goto badnat; + + np = ni.nai_np; + + nat->nat_mssclamp = np->in_mssclamp; + nat->nat_me = natsave; + nat->nat_fr = fin->fin_fr; + nat->nat_rev = fin->fin_rev; + nat->nat_ptr = np; + nat->nat_dlocal = np->in_dlocal; + + if ((np->in_apr != NULL) && ((nat->nat_flags & NAT_SLAVE) == 0)) { + if (ipf_proxy_new(fin, nat) == -1) { + NBUMPSIDE6D(fin->fin_out, ns_appr_fail); + goto badnat; + } + } + + nat->nat_ifps[0] = np->in_ifps[0]; + if (np->in_ifps[0] != NULL) { + COPYIFNAME(np->in_v[0], np->in_ifps[0], nat->nat_ifnames[0]); + } + + nat->nat_ifps[1] = np->in_ifps[1]; + if (np->in_ifps[1] != NULL) { + COPYIFNAME(np->in_v[1], np->in_ifps[1], nat->nat_ifnames[1]); + } + + if (ipf_nat6_finalise(fin, nat) == -1) { + goto badnat; + } + + np->in_use++; + + if ((move == 1) && (np->in_flags & IPN_ROUNDR)) { + if ((np->in_redir & (NAT_REDIRECT|NAT_MAP)) == NAT_REDIRECT) { + ipf_nat6_delrdr(softn, np); + ipf_nat6_addrdr(softn, np); + } else if ((np->in_redir & (NAT_REDIRECT|NAT_MAP)) == NAT_MAP) { + ipf_nat6_delmap(softn, np); + ipf_nat6_addmap(softn, np); + } + } + + if (flags & SI_WILDP) + nsp->ns_wilds++; + softn->ipf_nat_stats.ns_proto[nat->nat_pr[0]]++; + + goto done; +badnat: + NBUMPSIDE6(fin->fin_out, ns_badnatnew); + if ((hm = nat->nat_hm) != NULL) + ipf_nat_hostmapdel(softc, &hm); + KFREE(nat); + nat = NULL; +done: + if (nat != NULL && np != NULL) + np->in_hits++; + if (natsave != NULL) + *natsave = nat; + return nat; +} + + +/* ------------------------------------------------------------------------ */ +/* Function: ipf_nat6_finalise */ +/* Returns: int - 0 == sucess, -1 == failure */ +/* Parameters: fin(I) - pointer to packet information */ +/* nat(I) - pointer to NAT entry */ +/* Write Lock: ipf_nat */ +/* */ +/* This is the tail end of constructing a new NAT entry and is the same */ +/* for both IPv4 and IPv6. */ +/* ------------------------------------------------------------------------ */ +/*ARGSUSED*/ +int +ipf_nat6_finalise(fin, nat) + fr_info_t *fin; + nat_t *nat; +{ + ipf_main_softc_t *softc = fin->fin_main_soft; + ipf_nat_softc_t *softn = softc->ipf_nat_soft; + u_32_t sum1, sum2, sumd; + frentry_t *fr; + u_32_t flags; + + flags = nat->nat_flags; + + switch (fin->fin_p) + { + case IPPROTO_ICMPV6 : + sum1 = LONG_SUM6(&nat->nat_osrc6); + sum1 += ntohs(nat->nat_oicmpid); + sum2 = LONG_SUM6(&nat->nat_nsrc6); + sum2 += ntohs(nat->nat_nicmpid); + CALC_SUMD(sum1, sum2, sumd); + nat->nat_sumd[0] = (sumd & 0xffff) + (sumd >> 16); + + sum1 = LONG_SUM6(&nat->nat_odst6); + sum2 = LONG_SUM6(&nat->nat_ndst6); + CALC_SUMD(sum1, sum2, sumd); + nat->nat_sumd[0] += (sumd & 0xffff) + (sumd >> 16); + break; + + case IPPROTO_TCP : + case IPPROTO_UDP : + sum1 = LONG_SUM6(&nat->nat_osrc6); + sum1 += ntohs(nat->nat_osport); + sum2 = LONG_SUM6(&nat->nat_nsrc6); + sum2 += ntohs(nat->nat_nsport); + CALC_SUMD(sum1, sum2, sumd); + nat->nat_sumd[0] = (sumd & 0xffff) + (sumd >> 16); + + sum1 = LONG_SUM6(&nat->nat_odst6); + sum1 += ntohs(nat->nat_odport); + sum2 = LONG_SUM6(&nat->nat_ndst6); + sum2 += ntohs(nat->nat_ndport); + CALC_SUMD(sum1, sum2, sumd); + nat->nat_sumd[0] += (sumd & 0xffff) + (sumd >> 16); + break; + + default : + sum1 = LONG_SUM6(&nat->nat_osrc6); + sum2 = LONG_SUM6(&nat->nat_nsrc6); + CALC_SUMD(sum1, sum2, sumd); + nat->nat_sumd[0] = (sumd & 0xffff) + (sumd >> 16); + + sum1 = LONG_SUM6(&nat->nat_odst6); + sum2 = LONG_SUM6(&nat->nat_ndst6); + CALC_SUMD(sum1, sum2, sumd); + nat->nat_sumd[0] += (sumd & 0xffff) + (sumd >> 16); + break; + } + + /* + * Compute the partial checksum, just in case. + * This is only ever placed into outbound packets so care needs + * to be taken over which pair of addresses are used. + */ + if (nat->nat_dir == NAT_OUTBOUND) { + sum1 = LONG_SUM6(&nat->nat_nsrc6); + sum1 += LONG_SUM6(&nat->nat_ndst6); + } else { + sum1 = LONG_SUM6(&nat->nat_osrc6); + sum1 += LONG_SUM6(&nat->nat_odst6); + } + sum1 += nat->nat_pr[1]; + nat->nat_sumd[1] = (sum1 & 0xffff) + (sum1 >> 16); + + if ((nat->nat_flags & SI_CLONE) == 0) + nat->nat_sync = ipf_sync_new(softc, SMC_NAT, fin, nat); + + if ((nat->nat_ifps[0] != NULL) && (nat->nat_ifps[0] != (void *)-1)) { + nat->nat_mtu[0] = GETIFMTU_6(nat->nat_ifps[0]); + } + + if ((nat->nat_ifps[1] != NULL) && (nat->nat_ifps[1] != (void *)-1)) { + nat->nat_mtu[1] = GETIFMTU_6(nat->nat_ifps[1]); + } + + nat->nat_v[0] = 6; + nat->nat_v[1] = 6; + + if (ipf_nat6_insert(softc, softn, nat) == 0) { + if (softn->ipf_nat_logging) + ipf_nat_log(softc, softn, nat, NL_NEW); + fr = nat->nat_fr; + if (fr != NULL) { + MUTEX_ENTER(&fr->fr_lock); + fr->fr_ref++; + MUTEX_EXIT(&fr->fr_lock); + } + return 0; + } + + NBUMPSIDE6D(fin->fin_out, ns_unfinalised); + /* + * nat6_insert failed, so cleanup time... + */ + if (nat->nat_sync != NULL) + ipf_sync_del_nat(softc->ipf_sync_soft, nat->nat_sync); + return -1; +} + + +/* ------------------------------------------------------------------------ */ +/* Function: ipf_nat6_insert */ +/* Returns: int - 0 == sucess, -1 == failure */ +/* Parameters: softc(I) - pointer to soft context main structure */ +/* softn(I) - pointer to NAT context structure */ +/* nat(I) - pointer to NAT structure */ +/* Write Lock: ipf_nat */ +/* */ +/* Insert a NAT entry into the hash tables for searching and add it to the */ +/* list of active NAT entries. Adjust global counters when complete. */ +/* ------------------------------------------------------------------------ */ +static int +ipf_nat6_insert(softc, softn, nat) + ipf_main_softc_t *softc; + ipf_nat_softc_t *softn; + nat_t *nat; +{ + u_int hv1, hv2; + u_32_t sp, dp; + ipnat_t *in; + + /* + * Try and return an error as early as possible, so calculate the hash + * entry numbers first and then proceed. + */ + if ((nat->nat_flags & (SI_W_SPORT|SI_W_DPORT)) == 0) { + if ((nat->nat_flags & IPN_TCPUDP) != 0) { + sp = nat->nat_osport; + dp = nat->nat_odport; + } else if ((nat->nat_flags & IPN_ICMPQUERY) != 0) { + sp = 0; + dp = nat->nat_oicmpid; + } else { + sp = 0; + dp = 0; + } + hv1 = NAT_HASH_FN6(&nat->nat_osrc6, sp, 0xffffffff); + hv1 = NAT_HASH_FN6(&nat->nat_odst6, hv1 + dp, + softn->ipf_nat_table_sz); + + /* + * TRACE nat6_osrc6, nat6_osport, nat6_odst6, + * nat6_odport, hv1 + */ + + if ((nat->nat_flags & IPN_TCPUDP) != 0) { + sp = nat->nat_nsport; + dp = nat->nat_ndport; + } else if ((nat->nat_flags & IPN_ICMPQUERY) != 0) { + sp = 0; + dp = nat->nat_nicmpid; + } else { + sp = 0; + dp = 0; + } + hv2 = NAT_HASH_FN6(&nat->nat_nsrc6, sp, 0xffffffff); + hv2 = NAT_HASH_FN6(&nat->nat_ndst6, hv2 + dp, + softn->ipf_nat_table_sz); + /* + * TRACE nat6_nsrcaddr, nat6_nsport, nat6_ndstaddr, + * nat6_ndport, hv1 + */ + } else { + hv1 = NAT_HASH_FN6(&nat->nat_osrc6, 0, 0xffffffff); + hv1 = NAT_HASH_FN6(&nat->nat_odst6, hv1, + softn->ipf_nat_table_sz); + /* TRACE nat6_osrcip6, nat6_odstip6, hv1 */ + + hv2 = NAT_HASH_FN6(&nat->nat_nsrc6, 0, 0xffffffff); + hv2 = NAT_HASH_FN6(&nat->nat_ndst6, hv2, + softn->ipf_nat_table_sz); + /* TRACE nat6_nsrcip6, nat6_ndstip6, hv2 */ + } + + nat->nat_hv[0] = hv1; + nat->nat_hv[1] = hv2; + + MUTEX_INIT(&nat->nat_lock, "nat entry lock"); + + in = nat->nat_ptr; + nat->nat_ref = nat->nat_me ? 2 : 1; + + nat->nat_ifnames[0][LIFNAMSIZ - 1] = '\0'; + nat->nat_ifps[0] = ipf_resolvenic(softc, nat->nat_ifnames[0], + nat->nat_v[0]); + + if (nat->nat_ifnames[1][0] != '\0') { + nat->nat_ifnames[1][LIFNAMSIZ - 1] = '\0'; + nat->nat_ifps[1] = ipf_resolvenic(softc, nat->nat_ifnames[1], + nat->nat_v[1]); + } else if (in->in_ifnames[1] != -1) { + char *name; + + name = in->in_names + in->in_ifnames[1]; + if (name[1] != '\0' && name[0] != '-' && name[0] != '*') { + (void) strncpy(nat->nat_ifnames[1], + nat->nat_ifnames[0], LIFNAMSIZ); + nat->nat_ifnames[1][LIFNAMSIZ - 1] = '\0'; + nat->nat_ifps[1] = nat->nat_ifps[0]; + } + } + if ((nat->nat_ifps[0] != NULL) && (nat->nat_ifps[0] != (void *)-1)) { + nat->nat_mtu[0] = GETIFMTU_6(nat->nat_ifps[0]); + } + if ((nat->nat_ifps[1] != NULL) && (nat->nat_ifps[1] != (void *)-1)) { + nat->nat_mtu[1] = GETIFMTU_6(nat->nat_ifps[1]); + } + + return ipf_nat_hashtab_add(softc, softn, nat); +} + + +/* ------------------------------------------------------------------------ */ +/* Function: ipf_nat6_icmperrorlookup */ +/* Returns: nat6_t* - point to matching NAT structure */ +/* Parameters: fin(I) - pointer to packet information */ +/* dir(I) - direction of packet (in/out) */ +/* */ +/* Check if the ICMP error message is related to an existing TCP, UDP or */ +/* ICMP query nat entry. It is assumed that the packet is already of the */ +/* the required length. */ +/* ------------------------------------------------------------------------ */ +nat_t * +ipf_nat6_icmperrorlookup(fin, dir) + fr_info_t *fin; + int dir; +{ + ipf_main_softc_t *softc = fin->fin_main_soft; + ipf_nat_softc_t *softn = softc->ipf_nat_soft; + struct icmp6_hdr *icmp6, *orgicmp; + int flags = 0, type, minlen; + nat_stat_side_t *nside; + tcphdr_t *tcp = NULL; + u_short data[2]; + ip6_t *oip6; + nat_t *nat; + u_int p; + + minlen = 40; + icmp6 = fin->fin_dp; + type = icmp6->icmp6_type; + nside = &softn->ipf_nat_stats.ns_side6[fin->fin_out]; + /* + * Does it at least have the return (basic) IP header ? + * Only a basic IP header (no options) should be with an ICMP error + * header. Also, if it's not an error type, then return. + */ + if (!(fin->fin_flx & FI_ICMPERR)) { + ATOMIC_INCL(nside->ns_icmp_basic); + return NULL; + } + + /* + * Check packet size + */ + if (fin->fin_plen < ICMP6ERR_IPICMPHLEN) { + ATOMIC_INCL(nside->ns_icmp_size); + return NULL; + } + oip6 = (ip6_t *)((char *)fin->fin_dp + 8); + + /* + * Is the buffer big enough for all of it ? It's the size of the IP + * header claimed in the encapsulated part which is of concern. It + * may be too big to be in this buffer but not so big that it's + * outside the ICMP packet, leading to TCP deref's causing problems. + * This is possible because we don't know how big oip_hl is when we + * do the pullup early in ipf_check() and thus can't gaurantee it is + * all here now. + */ +#ifdef _KERNEL + { + mb_t *m; + + m = fin->fin_m; +# if defined(MENTAT) + if ((char *)oip6 + fin->fin_dlen - ICMPERR_ICMPHLEN > + (char *)m->b_wptr) { + ATOMIC_INCL(nside->ns_icmp_mbuf); + return NULL; + } +# else + if ((char *)oip6 + fin->fin_dlen - ICMPERR_ICMPHLEN > + (char *)fin->fin_ip + M_LEN(m)) { + ATOMIC_INCL(nside->ns_icmp_mbuf); + return NULL; + } +# endif + } +#endif + + if (IP6_NEQ(&fin->fin_dst6, &oip6->ip6_src)) { + ATOMIC_INCL(nside->ns_icmp_address); + return NULL; + } + + p = oip6->ip6_nxt; + if (p == IPPROTO_TCP) + flags = IPN_TCP; + else if (p == IPPROTO_UDP) + flags = IPN_UDP; + else if (p == IPPROTO_ICMPV6) { + orgicmp = (struct icmp6_hdr *)(oip6 + 1); + + /* see if this is related to an ICMP query */ + if (ipf_nat6_icmpquerytype(orgicmp->icmp6_type)) { + data[0] = fin->fin_data[0]; + data[1] = fin->fin_data[1]; + fin->fin_data[0] = 0; + fin->fin_data[1] = orgicmp->icmp6_id; + + flags = IPN_ICMPERR|IPN_ICMPQUERY; + /* + * NOTE : dir refers to the direction of the original + * ip packet. By definition the icmp error + * message flows in the opposite direction. + */ + if (dir == NAT_INBOUND) + nat = ipf_nat6_inlookup(fin, flags, p, + &oip6->ip6_dst, + &oip6->ip6_src); + else + nat = ipf_nat6_outlookup(fin, flags, p, + &oip6->ip6_dst, + &oip6->ip6_src); + fin->fin_data[0] = data[0]; + fin->fin_data[1] = data[1]; + return nat; + } + } + + if (flags & IPN_TCPUDP) { + minlen += 8; /* + 64bits of data to get ports */ + /* TRACE (fin,minlen) */ + if (fin->fin_plen < ICMPERR_IPICMPHLEN + minlen) { + ATOMIC_INCL(nside->ns_icmp_short); + return NULL; + } + + data[0] = fin->fin_data[0]; + data[1] = fin->fin_data[1]; + tcp = (tcphdr_t *)(oip6 + 1); + fin->fin_data[0] = ntohs(tcp->th_dport); + fin->fin_data[1] = ntohs(tcp->th_sport); + + if (dir == NAT_INBOUND) { + nat = ipf_nat6_inlookup(fin, flags, p, &oip6->ip6_dst, + &oip6->ip6_src); + } else { + nat = ipf_nat6_outlookup(fin, flags, p, &oip6->ip6_dst, + &oip6->ip6_src); + } + fin->fin_data[0] = data[0]; + fin->fin_data[1] = data[1]; + return nat; + } + if (dir == NAT_INBOUND) + nat = ipf_nat6_inlookup(fin, 0, p, &oip6->ip6_dst, + &oip6->ip6_src); + else + nat = ipf_nat6_outlookup(fin, 0, p, &oip6->ip6_dst, + &oip6->ip6_src); + + return nat; +} + + +/* result = ip1 - ip2 */ +u_32_t +ipf_nat6_ip6subtract(ip1, ip2) + i6addr_t *ip1, *ip2; +{ + i6addr_t l1, l2, d; + u_short *s1, *s2, *ds; + u_32_t r; + int i, neg; + + neg = 0; + l1 = *ip1; + l2 = *ip2; + s1 = (u_short *)&l1; + s2 = (u_short *)&l2; + ds = (u_short *)&d; + + for (i = 7; i > 0; i--) { + if (s1[i] > s2[i]) { + ds[i] = s2[i] + 0x10000 - s1[i]; + s2[i - 1] += 0x10000; + } else { + ds[i] = s2[i] - s1[i]; + } + } + if (s2[0] > s1[0]) { + ds[0] = s2[0] + 0x10000 - s1[0]; + neg = 1; + } else { + ds[0] = s2[0] - s1[0]; + } + + for (i = 0, r = 0; i < 8; i++) { + r += ds[i]; + } + + return r; +} + + +/* ------------------------------------------------------------------------ */ +/* Function: ipf_nat6_icmperror */ +/* Returns: nat6_t* - point to matching NAT structure */ +/* Parameters: fin(I) - pointer to packet information */ +/* nflags(I) - NAT flags for this packet */ +/* dir(I) - direction of packet (in/out) */ +/* */ +/* Fix up an ICMP packet which is an error message for an existing NAT */ +/* session. This will correct both packet header data and checksums. */ +/* */ +/* This should *ONLY* be used for incoming ICMP error packets to make sure */ +/* a NAT'd ICMP packet gets correctly recognised. */ +/* ------------------------------------------------------------------------ */ +nat_t * +ipf_nat6_icmperror(fin, nflags, dir) + fr_info_t *fin; + u_int *nflags; + int dir; +{ + ipf_main_softc_t *softc = fin->fin_main_soft; + ipf_nat_softc_t *softn = softc->ipf_nat_soft; + u_32_t sum1, sum2, sumd, sumd2; + i6addr_t a1, a2, a3, a4; + struct icmp6_hdr *icmp6; + int flags, dlen, odst; + u_short *csump; + tcphdr_t *tcp; + ip6_t *oip6; + nat_t *nat; + void *dp; + + if ((fin->fin_flx & (FI_SHORT|FI_FRAGBODY))) { + NBUMPSIDE6D(fin->fin_out, ns_icmp_short); + return NULL; + } + + /* + * ipf_nat6_icmperrorlookup() will return NULL for `defective' packets. + */ + if ((fin->fin_v != 6) || !(nat = ipf_nat6_icmperrorlookup(fin, dir))) { + NBUMPSIDE6D(fin->fin_out, ns_icmp_notfound); + return NULL; + } + + tcp = NULL; + csump = NULL; + flags = 0; + sumd2 = 0; + *nflags = IPN_ICMPERR; + icmp6 = fin->fin_dp; + oip6 = (ip6_t *)((u_char *)icmp6 + sizeof(*icmp6)); + dp = (u_char *)oip6 + sizeof(*oip6); + if (oip6->ip6_nxt == IPPROTO_TCP) { + tcp = (tcphdr_t *)dp; + csump = (u_short *)&tcp->th_sum; + flags = IPN_TCP; + } else if (oip6->ip6_nxt == IPPROTO_UDP) { + udphdr_t *udp; + + udp = (udphdr_t *)dp; + tcp = (tcphdr_t *)dp; + csump = (u_short *)&udp->uh_sum; + flags = IPN_UDP; + } else if (oip6->ip6_nxt == IPPROTO_ICMPV6) + flags = IPN_ICMPQUERY; + dlen = fin->fin_plen - ((char *)dp - (char *)fin->fin_ip); + + /* + * Need to adjust ICMP header to include the real IP#'s and + * port #'s. Only apply a checksum change relative to the + * IP address change as it will be modified again in ipf_nat6_checkout + * for both address and port. Two checksum changes are + * necessary for the two header address changes. Be careful + * to only modify the checksum once for the port # and twice + * for the IP#. + */ + + /* + * Step 1 + * Fix the IP addresses in the offending IP packet. You also need + * to adjust the IP header checksum of that offending IP packet. + * + * Normally, you would expect that the ICMP checksum of the + * ICMP error message needs to be adjusted as well for the + * IP address change in oip. + * However, this is a NOP, because the ICMP checksum is + * calculated over the complete ICMP packet, which includes the + * changed oip IP addresses and oip6->ip6_sum. However, these + * two changes cancel each other out (if the delta for + * the IP address is x, then the delta for ip_sum is minus x), + * so no change in the icmp_cksum is necessary. + * + * Inbound ICMP + * ------------ + * MAP rule, SRC=a,DST=b -> SRC=c,DST=b + * - response to outgoing packet (a,b)=>(c,b) (OIP_SRC=c,OIP_DST=b) + * - OIP_SRC(c)=nat6_newsrcip, OIP_DST(b)=nat6_newdstip + *=> OIP_SRC(c)=nat6_oldsrcip, OIP_DST(b)=nat6_olddstip + * + * RDR rule, SRC=a,DST=b -> SRC=a,DST=c + * - response to outgoing packet (c,a)=>(b,a) (OIP_SRC=b,OIP_DST=a) + * - OIP_SRC(b)=nat6_olddstip, OIP_DST(a)=nat6_oldsrcip + *=> OIP_SRC(b)=nat6_newdstip, OIP_DST(a)=nat6_newsrcip + * + * REWRITE out rule, SRC=a,DST=b -> SRC=c,DST=d + * - response to outgoing packet (a,b)=>(c,d) (OIP_SRC=c,OIP_DST=d) + * - OIP_SRC(c)=nat6_newsrcip, OIP_DST(d)=nat6_newdstip + *=> OIP_SRC(c)=nat6_oldsrcip, OIP_DST(d)=nat6_olddstip + * + * REWRITE in rule, SRC=a,DST=b -> SRC=c,DST=d + * - response to outgoing packet (d,c)=>(b,a) (OIP_SRC=b,OIP_DST=a) + * - OIP_SRC(b)=nat6_olddstip, OIP_DST(a)=nat6_oldsrcip + *=> OIP_SRC(b)=nat6_newdstip, OIP_DST(a)=nat6_newsrcip + * + * Outbound ICMP + * ------------- + * MAP rule, SRC=a,DST=b -> SRC=c,DST=b + * - response to incoming packet (b,c)=>(b,a) (OIP_SRC=b,OIP_DST=a) + * - OIP_SRC(b)=nat6_olddstip, OIP_DST(a)=nat6_oldsrcip + *=> OIP_SRC(b)=nat6_newdstip, OIP_DST(a)=nat6_newsrcip + * + * RDR rule, SRC=a,DST=b -> SRC=a,DST=c + * - response to incoming packet (a,b)=>(a,c) (OIP_SRC=a,OIP_DST=c) + * - OIP_SRC(a)=nat6_newsrcip, OIP_DST(c)=nat6_newdstip + *=> OIP_SRC(a)=nat6_oldsrcip, OIP_DST(c)=nat6_olddstip + * + * REWRITE out rule, SRC=a,DST=b -> SRC=c,DST=d + * - response to incoming packet (d,c)=>(b,a) (OIP_SRC=c,OIP_DST=d) + * - OIP_SRC(c)=nat6_olddstip, OIP_DST(d)=nat6_oldsrcip + *=> OIP_SRC(b)=nat6_newdstip, OIP_DST(a)=nat6_newsrcip + * + * REWRITE in rule, SRC=a,DST=b -> SRC=c,DST=d + * - response to incoming packet (a,b)=>(c,d) (OIP_SRC=b,OIP_DST=a) + * - OIP_SRC(b)=nat6_newsrcip, OIP_DST(a)=nat6_newdstip + *=> OIP_SRC(a)=nat6_oldsrcip, OIP_DST(c)=nat6_olddstip + */ + + if (((fin->fin_out == 0) && ((nat->nat_redir & NAT_MAP) != 0)) || + ((fin->fin_out == 1) && ((nat->nat_redir & NAT_REDIRECT) != 0))) { + a1 = nat->nat_osrc6; + a4.in6 = oip6->ip6_src; + a3 = nat->nat_odst6; + a2.in6 = oip6->ip6_dst; + oip6->ip6_src = a1.in6; + oip6->ip6_dst = a3.in6; + odst = 1; + } else { + a1 = nat->nat_ndst6; + a2.in6 = oip6->ip6_dst; + a3 = nat->nat_nsrc6; + a4.in6 = oip6->ip6_src; + oip6->ip6_dst = a3.in6; + oip6->ip6_src = a1.in6; + odst = 0; + } + + sumd = 0; + if (IP6_NEQ(&a3, &a2) || IP6_NEQ(&a1, &a4)) { + if (IP6_GT(&a3, &a2)) { + sumd = ipf_nat6_ip6subtract(&a2, &a3); + sumd--; + } else { + sumd = ipf_nat6_ip6subtract(&a2, &a3); + } + if (IP6_GT(&a1, &a4)) { + sumd += ipf_nat6_ip6subtract(&a4, &a1); + sumd--; + } else { + sumd += ipf_nat6_ip6subtract(&a4, &a1); + } + sumd = ~sumd; + } + + sumd2 = sumd; + sum1 = 0; + sum2 = 0; + + /* + * Fix UDP pseudo header checksum to compensate for the + * IP address change. + */ + if (((flags & IPN_TCPUDP) != 0) && (dlen >= 4)) { + u_32_t sum3, sum4; + /* + * Step 2 : + * For offending TCP/UDP IP packets, translate the ports as + * well, based on the NAT specification. Of course such + * a change may be reflected in the ICMP checksum as well. + * + * Since the port fields are part of the TCP/UDP checksum + * of the offending IP packet, you need to adjust that checksum + * as well... except that the change in the port numbers should + * be offset by the checksum change. However, the TCP/UDP + * checksum will also need to change if there has been an + * IP address change. + */ + if (odst == 1) { + sum1 = ntohs(nat->nat_osport); + sum4 = ntohs(tcp->th_sport); + sum3 = ntohs(nat->nat_odport); + sum2 = ntohs(tcp->th_dport); + + tcp->th_sport = htons(sum1); + tcp->th_dport = htons(sum3); + } else { + sum1 = ntohs(nat->nat_ndport); + sum2 = ntohs(tcp->th_dport); + sum3 = ntohs(nat->nat_nsport); + sum4 = ntohs(tcp->th_sport); + + tcp->th_dport = htons(sum3); + tcp->th_sport = htons(sum1); + } + sumd += sum1 - sum4; + sumd += sum3 - sum2; + + if (sumd != 0 || sumd2 != 0) { + /* + * At this point, sumd is the delta to apply to the + * TCP/UDP header, given the changes in both the IP + * address and the ports and sumd2 is the delta to + * apply to the ICMP header, given the IP address + * change delta that may need to be applied to the + * TCP/UDP checksum instead. + * + * If we will both the IP and TCP/UDP checksums + * then the ICMP checksum changes by the address + * delta applied to the TCP/UDP checksum. If we + * do not change the TCP/UDP checksum them we + * apply the delta in ports to the ICMP checksum. + */ + if (oip6->ip6_nxt == IPPROTO_UDP) { + if ((dlen >= 8) && (*csump != 0)) { + ipf_fix_datacksum(csump, sumd); + } else { + sumd2 = sum4 - sum1; + if (sum1 > sum4) + sumd2--; + sumd2 += sum2 - sum3; + if (sum3 > sum2) + sumd2--; + } + } else if (oip6->ip6_nxt == IPPROTO_TCP) { + if (dlen >= 18) { + ipf_fix_datacksum(csump, sumd); + } else { + sumd2 = sum4 - sum1; + if (sum1 > sum4) + sumd2--; + sumd2 += sum2 - sum3; + if (sum3 > sum2) + sumd2--; + } + } + if (sumd2 != 0) { + sumd2 = (sumd2 & 0xffff) + (sumd2 >> 16); + sumd2 = (sumd2 & 0xffff) + (sumd2 >> 16); + sumd2 = (sumd2 & 0xffff) + (sumd2 >> 16); + ipf_fix_incksum(0, &icmp6->icmp6_cksum, + sumd2, 0); + } + } + } else if (((flags & IPN_ICMPQUERY) != 0) && (dlen >= 8)) { + struct icmp6_hdr *orgicmp; + + /* + * XXX - what if this is bogus hl and we go off the end ? + * In this case, ipf_nat6_icmperrorlookup() will have + * returned NULL. + */ + orgicmp = (struct icmp6_hdr *)dp; + + if (odst == 1) { + if (orgicmp->icmp6_id != nat->nat_osport) { + + /* + * Fix ICMP checksum (of the offening ICMP + * query packet) to compensate the change + * in the ICMP id of the offending ICMP + * packet. + * + * Since you modify orgicmp->icmp6_id with + * a delta (say x) and you compensate that + * in origicmp->icmp6_cksum with a delta + * minus x, you don't have to adjust the + * overall icmp->icmp6_cksum + */ + sum1 = ntohs(orgicmp->icmp6_id); + sum2 = ntohs(nat->nat_osport); + CALC_SUMD(sum1, sum2, sumd); + orgicmp->icmp6_id = nat->nat_oicmpid; + ipf_fix_datacksum(&orgicmp->icmp6_cksum, sumd); + } + } /* nat6_dir == NAT_INBOUND is impossible for icmp queries */ + } + return nat; +} + + +/* + * MAP-IN MAP-OUT RDR-IN RDR-OUT + * osrc X == src == src X + * odst X == dst == dst X + * nsrc == dst X X == dst + * ndst == src X X == src + * MAP = NAT_OUTBOUND, RDR = NAT_INBOUND + */ +/* + * NB: these lookups don't lock access to the list, it assumed that it has + * already been done! + */ +/* ------------------------------------------------------------------------ */ +/* Function: ipf_nat6_inlookup */ +/* Returns: nat6_t* - NULL == no match, */ +/* else pointer to matching NAT entry */ +/* Parameters: fin(I) - pointer to packet information */ +/* flags(I) - NAT flags for this packet */ +/* p(I) - protocol for this packet */ +/* src(I) - source IP address */ +/* mapdst(I) - destination IP address */ +/* */ +/* Lookup a nat entry based on the mapped destination ip address/port and */ +/* real source address/port. We use this lookup when receiving a packet, */ +/* we're looking for a table entry, based on the destination address. */ +/* */ +/* NOTE: THE PACKET BEING CHECKED (IF FOUND) HAS A MAPPING ALREADY. */ +/* */ +/* NOTE: IT IS ASSUMED THAT IS ONLY HELD WITH A READ LOCK WHEN */ +/* THIS FUNCTION IS CALLED WITH NAT_SEARCH SET IN nflags. */ +/* */ +/* flags -> relevant are IPN_UDP/IPN_TCP/IPN_ICMPQUERY that indicate if */ +/* the packet is of said protocol */ +/* ------------------------------------------------------------------------ */ +nat_t * +ipf_nat6_inlookup(fin, flags, p, src, mapdst) + fr_info_t *fin; + u_int flags, p; + struct in6_addr *src , *mapdst; +{ + ipf_main_softc_t *softc = fin->fin_main_soft; + ipf_nat_softc_t *softn = softc->ipf_nat_soft; + u_short sport, dport; + grehdr_t *gre; + ipnat_t *ipn; + u_int sflags; + nat_t *nat; + int nflags; + i6addr_t dst; + void *ifp; + u_int hv; + + ifp = fin->fin_ifp; + sport = 0; + dport = 0; + gre = NULL; + dst.in6 = *mapdst; + sflags = flags & NAT_TCPUDPICMP; + + switch (p) + { + case IPPROTO_TCP : + case IPPROTO_UDP : + sport = htons(fin->fin_data[0]); + dport = htons(fin->fin_data[1]); + break; + case IPPROTO_ICMPV6 : + if (flags & IPN_ICMPERR) + sport = fin->fin_data[1]; + else + dport = fin->fin_data[1]; + break; + default : + break; + } + + + if ((flags & SI_WILDP) != 0) + goto find_in_wild_ports; + + hv = NAT_HASH_FN6(&dst, dport, 0xffffffff); + hv = NAT_HASH_FN6(src, hv + sport, softn->ipf_nat_table_sz); + nat = softn->ipf_nat_table[1][hv]; + /* TRACE dst, dport, src, sport, hv, nat */ + + for (; nat; nat = nat->nat_hnext[1]) { + if (nat->nat_ifps[0] != NULL) { + if ((ifp != NULL) && (ifp != nat->nat_ifps[0])) + continue; + } + + if (nat->nat_pr[0] != p) + continue; + + switch (nat->nat_dir) + { + case NAT_INBOUND : + if (nat->nat_v[0] != 6) + continue; + if (IP6_NEQ(&nat->nat_osrc6, src) || + IP6_NEQ(&nat->nat_odst6, &dst)) + continue; + if ((nat->nat_flags & IPN_TCPUDP) != 0) { + if (nat->nat_osport != sport) + continue; + if (nat->nat_odport != dport) + continue; + + } else if (p == IPPROTO_ICMPV6) { + if (nat->nat_osport != dport) { + continue; + } + } + break; + case NAT_OUTBOUND : + if (nat->nat_v[1] != 6) + continue; + if (IP6_NEQ(&nat->nat_ndst6, src) || + IP6_NEQ(&nat->nat_nsrc6, &dst)) + continue; + if ((nat->nat_flags & IPN_TCPUDP) != 0) { + if (nat->nat_ndport != sport) + continue; + if (nat->nat_nsport != dport) + continue; + + } else if (p == IPPROTO_ICMPV6) { + if (nat->nat_osport != dport) { + continue; + } + } + break; + } + + + if ((nat->nat_flags & IPN_TCPUDP) != 0) { + ipn = nat->nat_ptr; +#ifdef IPF_V6_PROXIES + if ((ipn != NULL) && (nat->nat_aps != NULL)) + if (appr_match(fin, nat) != 0) + continue; +#endif + } + if ((nat->nat_ifps[0] == NULL) && (ifp != NULL)) { + nat->nat_ifps[0] = ifp; + nat->nat_mtu[0] = GETIFMTU_6(ifp); + } + return nat; + } + + /* + * So if we didn't find it but there are wildcard members in the hash + * table, go back and look for them. We do this search and update here + * because it is modifying the NAT table and we want to do this only + * for the first packet that matches. The exception, of course, is + * for "dummy" (FI_IGNORE) lookups. + */ +find_in_wild_ports: + if (!(flags & NAT_TCPUDP) || !(flags & NAT_SEARCH)) { + NBUMPSIDE6DX(0, ns_lookup_miss, ns_lookup_miss_1); + return NULL; + } + if (softn->ipf_nat_stats.ns_wilds == 0 || (fin->fin_flx & FI_NOWILD)) { + NBUMPSIDE6D(0, ns_lookup_nowild); + return NULL; + } + + RWLOCK_EXIT(&softc->ipf_nat); + + hv = NAT_HASH_FN6(&dst, 0, 0xffffffff); + hv = NAT_HASH_FN6(src, hv, softn->ipf_nat_table_sz); + WRITE_ENTER(&softc->ipf_nat); + + nat = softn->ipf_nat_table[1][hv]; + /* TRACE dst, src, hv, nat */ + for (; nat; nat = nat->nat_hnext[1]) { + if (nat->nat_ifps[0] != NULL) { + if ((ifp != NULL) && (ifp != nat->nat_ifps[0])) + continue; + } + + if (nat->nat_pr[0] != fin->fin_p) + continue; + + switch (nat->nat_dir) + { + case NAT_INBOUND : + if (nat->nat_v[0] != 6) + continue; + if (IP6_NEQ(&nat->nat_osrc6, src) || + IP6_NEQ(&nat->nat_odst6, &dst)) + continue; + break; + case NAT_OUTBOUND : + if (nat->nat_v[1] != 6) + continue; + if (IP6_NEQ(&nat->nat_ndst6, src) || + IP6_NEQ(&nat->nat_nsrc6, &dst)) + continue; + break; + } + + nflags = nat->nat_flags; + if (!(nflags & (NAT_TCPUDP|SI_WILDP))) + continue; + + if (ipf_nat_wildok(nat, (int)sport, (int)dport, nflags, + NAT_INBOUND) == 1) { + if ((fin->fin_flx & FI_IGNORE) != 0) + break; + if ((nflags & SI_CLONE) != 0) { + nat = ipf_nat_clone(fin, nat); + if (nat == NULL) + break; + } else { + MUTEX_ENTER(&softn->ipf_nat_new); + softn->ipf_nat_stats.ns_wilds--; + MUTEX_EXIT(&softn->ipf_nat_new); + } + + if (nat->nat_dir == NAT_INBOUND) { + if (nat->nat_osport == 0) { + nat->nat_osport = sport; + nat->nat_nsport = sport; + } + if (nat->nat_odport == 0) { + nat->nat_odport = dport; + nat->nat_ndport = dport; + } + } else { + if (nat->nat_osport == 0) { + nat->nat_osport = dport; + nat->nat_nsport = dport; + } + if (nat->nat_odport == 0) { + nat->nat_odport = sport; + nat->nat_ndport = sport; + } + } + if ((nat->nat_ifps[0] == NULL) && (ifp != NULL)) { + nat->nat_ifps[0] = ifp; + nat->nat_mtu[0] = GETIFMTU_6(ifp); + } + nat->nat_flags &= ~(SI_W_DPORT|SI_W_SPORT); + ipf_nat6_tabmove(softn, nat); + break; + } + } + + MUTEX_DOWNGRADE(&softc->ipf_nat); + + if (nat == NULL) { + NBUMPSIDE6DX(0, ns_lookup_miss, ns_lookup_miss_2); + } + return nat; +} + + +/* ------------------------------------------------------------------------ */ +/* Function: ipf_nat6_tabmove */ +/* Returns: Nil */ +/* Parameters: nat(I) - pointer to NAT structure */ +/* Write Lock: ipf_nat */ +/* */ +/* This function is only called for TCP/UDP NAT table entries where the */ +/* original was placed in the table without hashing on the ports and we now */ +/* want to include hashing on port numbers. */ +/* ------------------------------------------------------------------------ */ +static void +ipf_nat6_tabmove(softn, nat) + ipf_nat_softc_t *softn; + nat_t *nat; +{ + nat_t **natp; + u_int hv0, hv1; + + if (nat->nat_flags & SI_CLONE) + return; + + /* + * Remove the NAT entry from the old location + */ + if (nat->nat_hnext[0]) + nat->nat_hnext[0]->nat_phnext[0] = nat->nat_phnext[0]; + *nat->nat_phnext[0] = nat->nat_hnext[0]; + softn->ipf_nat_stats.ns_side[0].ns_bucketlen[nat->nat_hv[0]]--; + + if (nat->nat_hnext[1]) + nat->nat_hnext[1]->nat_phnext[1] = nat->nat_phnext[1]; + *nat->nat_phnext[1] = nat->nat_hnext[1]; + softn->ipf_nat_stats.ns_side[1].ns_bucketlen[nat->nat_hv[1]]--; + + /* + * Add into the NAT table in the new position + */ + hv0 = NAT_HASH_FN6(&nat->nat_osrc6, nat->nat_osport, 0xffffffff); + hv0 = NAT_HASH_FN6(&nat->nat_odst6, hv0 + nat->nat_odport, + softn->ipf_nat_table_sz); + hv1 = NAT_HASH_FN6(&nat->nat_nsrc6, nat->nat_nsport, 0xffffffff); + hv1 = NAT_HASH_FN6(&nat->nat_ndst6, hv1 + nat->nat_ndport, + softn->ipf_nat_table_sz); + + if (nat->nat_dir == NAT_INBOUND || nat->nat_dir == NAT_DIVERTIN) { + u_int swap; + + swap = hv0; + hv0 = hv1; + hv1 = swap; + } + + /* TRACE nat_osrc6, nat_osport, nat_odst6, nat_odport, hv0 */ + /* TRACE nat_nsrc6, nat_nsport, nat_ndst6, nat_ndport, hv1 */ + + nat->nat_hv[0] = hv0; + natp = &softn->ipf_nat_table[0][hv0]; + if (*natp) + (*natp)->nat_phnext[0] = &nat->nat_hnext[0]; + nat->nat_phnext[0] = natp; + nat->nat_hnext[0] = *natp; + *natp = nat; + softn->ipf_nat_stats.ns_side[0].ns_bucketlen[hv0]++; + + nat->nat_hv[1] = hv1; + natp = &softn->ipf_nat_table[1][hv1]; + if (*natp) + (*natp)->nat_phnext[1] = &nat->nat_hnext[1]; + nat->nat_phnext[1] = natp; + nat->nat_hnext[1] = *natp; + *natp = nat; + softn->ipf_nat_stats.ns_side[1].ns_bucketlen[hv1]++; +} + + +/* ------------------------------------------------------------------------ */ +/* Function: ipf_nat6_outlookup */ +/* Returns: nat6_t* - NULL == no match, */ +/* else pointer to matching NAT entry */ +/* Parameters: fin(I) - pointer to packet information */ +/* flags(I) - NAT flags for this packet */ +/* p(I) - protocol for this packet */ +/* src(I) - source IP address */ +/* dst(I) - destination IP address */ +/* rw(I) - 1 == write lock on held, 0 == read lock. */ +/* */ +/* Lookup a nat entry based on the source 'real' ip address/port and */ +/* destination address/port. We use this lookup when sending a packet out, */ +/* we're looking for a table entry, based on the source address. */ +/* */ +/* NOTE: THE PACKET BEING CHECKED (IF FOUND) HAS A MAPPING ALREADY. */ +/* */ +/* NOTE: IT IS ASSUMED THAT IS ONLY HELD WITH A READ LOCK WHEN */ +/* THIS FUNCTION IS CALLED WITH NAT_SEARCH SET IN nflags. */ +/* */ +/* flags -> relevant are IPN_UDP/IPN_TCP/IPN_ICMPQUERY that indicate if */ +/* the packet is of said protocol */ +/* ------------------------------------------------------------------------ */ +nat_t * +ipf_nat6_outlookup(fin, flags, p, src, dst) + fr_info_t *fin; + u_int flags, p; + struct in6_addr *src , *dst; +{ + ipf_main_softc_t *softc = fin->fin_main_soft; + ipf_nat_softc_t *softn = softc->ipf_nat_soft; + u_short sport, dport; + u_int sflags; + ipnat_t *ipn; + nat_t *nat; + void *ifp; + u_int hv; + + ifp = fin->fin_ifp; + sflags = flags & IPN_TCPUDPICMP; + sport = 0; + dport = 0; + + switch (p) + { + case IPPROTO_TCP : + case IPPROTO_UDP : + sport = htons(fin->fin_data[0]); + dport = htons(fin->fin_data[1]); + break; + case IPPROTO_ICMPV6 : + if (flags & IPN_ICMPERR) + sport = fin->fin_data[1]; + else + dport = fin->fin_data[1]; + break; + default : + break; + } + + if ((flags & SI_WILDP) != 0) + goto find_out_wild_ports; + + hv = NAT_HASH_FN6(src, sport, 0xffffffff); + hv = NAT_HASH_FN6(dst, hv + dport, softn->ipf_nat_table_sz); + nat = softn->ipf_nat_table[0][hv]; + + /* TRACE src, sport, dst, dport, hv, nat */ + + for (; nat; nat = nat->nat_hnext[0]) { + if (nat->nat_ifps[1] != NULL) { + if ((ifp != NULL) && (ifp != nat->nat_ifps[1])) + continue; + } + + if (nat->nat_pr[1] != p) + continue; + + switch (nat->nat_dir) + { + case NAT_INBOUND : + if (nat->nat_v[1] != 6) + continue; + if (IP6_NEQ(&nat->nat_ndst6, src) || + IP6_NEQ(&nat->nat_nsrc6, dst)) + continue; + + if ((nat->nat_flags & IPN_TCPUDP) != 0) { + if (nat->nat_ndport != sport) + continue; + if (nat->nat_nsport != dport) + continue; + + } else if (p == IPPROTO_ICMPV6) { + if (nat->nat_osport != dport) { + continue; + } + } + break; + case NAT_OUTBOUND : + if (nat->nat_v[0] != 6) + continue; + if (IP6_NEQ(&nat->nat_osrc6, src) || + IP6_NEQ(&nat->nat_odst6, dst)) + continue; + + if ((nat->nat_flags & IPN_TCPUDP) != 0) { + if (nat->nat_odport != dport) + continue; + if (nat->nat_osport != sport) + continue; + + } else if (p == IPPROTO_ICMPV6) { + if (nat->nat_osport != dport) { + continue; + } + } + break; + } + + ipn = nat->nat_ptr; +#ifdef IPF_V6_PROXIES + if ((ipn != NULL) && (nat->nat_aps != NULL)) + if (appr_match(fin, nat) != 0) + continue; +#endif + + if ((nat->nat_ifps[1] == NULL) && (ifp != NULL)) { + nat->nat_ifps[1] = ifp; + nat->nat_mtu[1] = GETIFMTU_6(ifp); + } + return nat; + } + + /* + * So if we didn't find it but there are wildcard members in the hash + * table, go back and look for them. We do this search and update here + * because it is modifying the NAT table and we want to do this only + * for the first packet that matches. The exception, of course, is + * for "dummy" (FI_IGNORE) lookups. + */ +find_out_wild_ports: + if (!(flags & NAT_TCPUDP) || !(flags & NAT_SEARCH)) { + NBUMPSIDE6DX(1, ns_lookup_miss, ns_lookup_miss_3); + return NULL; + } + if (softn->ipf_nat_stats.ns_wilds == 0 || (fin->fin_flx & FI_NOWILD)) { + NBUMPSIDE6D(1, ns_lookup_nowild); + return NULL; + } + + RWLOCK_EXIT(&softc->ipf_nat); + + hv = NAT_HASH_FN6(src, 0, 0xffffffff); + hv = NAT_HASH_FN6(dst, hv, softn->ipf_nat_table_sz); + + WRITE_ENTER(&softc->ipf_nat); + + nat = softn->ipf_nat_table[0][hv]; + for (; nat; nat = nat->nat_hnext[0]) { + if (nat->nat_ifps[1] != NULL) { + if ((ifp != NULL) && (ifp != nat->nat_ifps[1])) + continue; + } + + if (nat->nat_pr[1] != fin->fin_p) + continue; + + switch (nat->nat_dir) + { + case NAT_INBOUND : + if (nat->nat_v[1] != 6) + continue; + if (IP6_NEQ(&nat->nat_ndst6, src) || + IP6_NEQ(&nat->nat_nsrc6, dst)) + continue; + break; + case NAT_OUTBOUND : + if (nat->nat_v[0] != 6) + continue; + if (IP6_NEQ(&nat->nat_osrc6, src) || + IP6_NEQ(&nat->nat_odst6, dst)) + continue; + break; + } + + if (!(nat->nat_flags & (NAT_TCPUDP|SI_WILDP))) + continue; + + if (ipf_nat_wildok(nat, (int)sport, (int)dport, nat->nat_flags, + NAT_OUTBOUND) == 1) { + if ((fin->fin_flx & FI_IGNORE) != 0) + break; + if ((nat->nat_flags & SI_CLONE) != 0) { + nat = ipf_nat_clone(fin, nat); + if (nat == NULL) + break; + } else { + MUTEX_ENTER(&softn->ipf_nat_new); + softn->ipf_nat_stats.ns_wilds--; + MUTEX_EXIT(&softn->ipf_nat_new); + } + + if (nat->nat_dir == NAT_OUTBOUND) { + if (nat->nat_osport == 0) { + nat->nat_osport = sport; + nat->nat_nsport = sport; + } + if (nat->nat_odport == 0) { + nat->nat_odport = dport; + nat->nat_ndport = dport; + } + } else { + if (nat->nat_osport == 0) { + nat->nat_osport = dport; + nat->nat_nsport = dport; + } + if (nat->nat_odport == 0) { + nat->nat_odport = sport; + nat->nat_ndport = sport; + } + } + if ((nat->nat_ifps[1] == NULL) && (ifp != NULL)) { + nat->nat_ifps[1] = ifp; + nat->nat_mtu[1] = GETIFMTU_6(ifp); + } + nat->nat_flags &= ~(SI_W_DPORT|SI_W_SPORT); + ipf_nat6_tabmove(softn, nat); + break; + } + } + + MUTEX_DOWNGRADE(&softc->ipf_nat); + + if (nat == NULL) { + NBUMPSIDE6DX(1, ns_lookup_miss, ns_lookup_miss_4); + } + return nat; +} + + +/* ------------------------------------------------------------------------ */ +/* Function: ipf_nat6_lookupredir */ +/* Returns: nat6_t* - NULL == no match, */ +/* else pointer to matching NAT entry */ +/* Parameters: np(I) - pointer to description of packet to find NAT table */ +/* entry for. */ +/* */ +/* Lookup the NAT tables to search for a matching redirect */ +/* The contents of natlookup_t should imitate those found in a packet that */ +/* would be translated - ie a packet coming in for RDR or going out for MAP.*/ +/* We can do the lookup in one of two ways, imitating an inbound or */ +/* outbound packet. By default we assume outbound, unless IPN_IN is set. */ +/* For IN, the fields are set as follows: */ +/* nl_real* = source information */ +/* nl_out* = destination information (translated) */ +/* For an out packet, the fields are set like this: */ +/* nl_in* = source information (untranslated) */ +/* nl_out* = destination information (translated) */ +/* ------------------------------------------------------------------------ */ +nat_t * +ipf_nat6_lookupredir(np) + natlookup_t *np; +{ + fr_info_t fi; + nat_t *nat; + + bzero((char *)&fi, sizeof(fi)); + if (np->nl_flags & IPN_IN) { + fi.fin_data[0] = ntohs(np->nl_realport); + fi.fin_data[1] = ntohs(np->nl_outport); + } else { + fi.fin_data[0] = ntohs(np->nl_inport); + fi.fin_data[1] = ntohs(np->nl_outport); + } + if (np->nl_flags & IPN_TCP) + fi.fin_p = IPPROTO_TCP; + else if (np->nl_flags & IPN_UDP) + fi.fin_p = IPPROTO_UDP; + else if (np->nl_flags & (IPN_ICMPERR|IPN_ICMPQUERY)) + fi.fin_p = IPPROTO_ICMPV6; + + /* + * We can do two sorts of lookups: + * - IPN_IN: we have the `real' and `out' address, look for `in'. + * - default: we have the `in' and `out' address, look for `real'. + */ + if (np->nl_flags & IPN_IN) { + if ((nat = ipf_nat6_inlookup(&fi, np->nl_flags, fi.fin_p, + &np->nl_realip6, + &np->nl_outip6))) { + np->nl_inip6 = nat->nat_odst6.in6; + np->nl_inport = nat->nat_odport; + } + } else { + /* + * If nl_inip is non null, this is a lookup based on the real + * ip address. Else, we use the fake. + */ + if ((nat = ipf_nat6_outlookup(&fi, np->nl_flags, fi.fin_p, + &np->nl_inip6, &np->nl_outip6))) { + + if ((np->nl_flags & IPN_FINDFORWARD) != 0) { + fr_info_t fin; + bzero((char *)&fin, sizeof(fin)); + fin.fin_p = nat->nat_pr[0]; + fin.fin_data[0] = ntohs(nat->nat_ndport); + fin.fin_data[1] = ntohs(nat->nat_nsport); + if (ipf_nat6_inlookup(&fin, np->nl_flags, + fin.fin_p, + &nat->nat_ndst6.in6, + &nat->nat_nsrc6.in6) != + NULL) { + np->nl_flags &= ~IPN_FINDFORWARD; + } + } + + np->nl_realip6 = nat->nat_ndst6.in6; + np->nl_realport = nat->nat_ndport; + } + } + + return nat; +} + + +/* ------------------------------------------------------------------------ */ +/* Function: ipf_nat6_match */ +/* Returns: int - 0 == no match, 1 == match */ +/* Parameters: fin(I) - pointer to packet information */ +/* np(I) - pointer to NAT rule */ +/* */ +/* Pull the matching of a packet against a NAT rule out of that complex */ +/* loop inside ipf_nat6_checkin() and lay it out properly in its own */ +/* function. */ +/* ------------------------------------------------------------------------ */ +static int +ipf_nat6_match(fin, np) + fr_info_t *fin; + ipnat_t *np; +{ + frtuc_t *ft; + int match; + + match = 0; + switch (np->in_osrcatype) + { + case FRI_NORMAL : + match = IP6_MASKNEQ(&fin->fin_src6, &np->in_osrcmsk6, + &np->in_osrcip6); + break; + case FRI_LOOKUP : + match = (*np->in_osrcfunc)(fin->fin_main_soft, np->in_osrcptr, + 6, &fin->fin_src6, fin->fin_plen); + break; + } + match ^= ((np->in_flags & IPN_NOTSRC) != 0); + if (match) + return 0; + + match = 0; + switch (np->in_odstatype) + { + case FRI_NORMAL : + match = IP6_MASKNEQ(&fin->fin_dst6, &np->in_odstmsk6, + &np->in_odstip6); + break; + case FRI_LOOKUP : + match = (*np->in_odstfunc)(fin->fin_main_soft, np->in_odstptr, + 6, &fin->fin_dst6, fin->fin_plen); + break; + } + + match ^= ((np->in_flags & IPN_NOTDST) != 0); + if (match) + return 0; + + ft = &np->in_tuc; + if (!(fin->fin_flx & FI_TCPUDP) || + (fin->fin_flx & (FI_SHORT|FI_FRAGBODY))) { + if (ft->ftu_scmp || ft->ftu_dcmp) + return 0; + return 1; + } + + return ipf_tcpudpchk(&fin->fin_fi, ft); +} + + +/* ------------------------------------------------------------------------ */ +/* Function: ipf_nat6_checkout */ +/* Returns: int - -1 == packet failed NAT checks so block it, */ +/* 0 == no packet translation occurred, */ +/* 1 == packet was successfully translated. */ +/* Parameters: fin(I) - pointer to packet information */ +/* passp(I) - pointer to filtering result flags */ +/* */ +/* Check to see if an outcoming packet should be changed. ICMP packets are */ +/* first checked to see if they match an existing entry (if an error), */ +/* otherwise a search of the current NAT table is made. If neither results */ +/* in a match then a search for a matching NAT rule is made. Create a new */ +/* NAT entry if a we matched a NAT rule. Lastly, actually change the */ +/* packet header(s) as required. */ +/* ------------------------------------------------------------------------ */ +int +ipf_nat6_checkout(fin, passp) + fr_info_t *fin; + u_32_t *passp; +{ + ipf_main_softc_t *softc = fin->fin_main_soft; + ipf_nat_softc_t *softn = softc->ipf_nat_soft; + struct icmp6_hdr *icmp6 = NULL; + struct ifnet *ifp, *sifp; + tcphdr_t *tcp = NULL; + int rval, natfailed; + ipnat_t *np = NULL; + u_int nflags = 0; + i6addr_t ipa, iph; + int natadd = 1; + frentry_t *fr; + nat_t *nat; + + if (softn->ipf_nat_stats.ns_rules == 0 || softn->ipf_nat_lock != 0) + return 0; + + icmp6 = NULL; + natfailed = 0; + fr = fin->fin_fr; + sifp = fin->fin_ifp; + if (fr != NULL) { + ifp = fr->fr_tifs[fin->fin_rev].fd_ptr; + if ((ifp != NULL) && (ifp != (void *)-1)) + fin->fin_ifp = ifp; + } + ifp = fin->fin_ifp; + + if (!(fin->fin_flx & FI_SHORT) && (fin->fin_off == 0)) { + switch (fin->fin_p) + { + case IPPROTO_TCP : + nflags = IPN_TCP; + break; + case IPPROTO_UDP : + nflags = IPN_UDP; + break; + case IPPROTO_ICMPV6 : + icmp6 = fin->fin_dp; + + /* + * Apart from ECHO request and reply, all other + * informational messages should not be translated + * so as to keep IPv6 working. + */ + if (icmp6->icmp6_type > ICMP6_ECHO_REPLY) + return 0; + + /* + * This is an incoming packet, so the destination is + * the icmp6_id and the source port equals 0 + */ + if ((fin->fin_flx & FI_ICMPQUERY) != 0) + nflags = IPN_ICMPQUERY; + break; + default : + break; + } + + if ((nflags & IPN_TCPUDP)) + tcp = fin->fin_dp; + } + + ipa = fin->fin_src6; + + READ_ENTER(&softc->ipf_nat); + + if ((fin->fin_p == IPPROTO_ICMPV6) && !(nflags & IPN_ICMPQUERY) && + (nat = ipf_nat6_icmperror(fin, &nflags, NAT_OUTBOUND))) + /*EMPTY*/; + else if ((fin->fin_flx & FI_FRAG) && (nat = ipf_frag_natknown(fin))) + natadd = 0; + else if ((nat = ipf_nat6_outlookup(fin, nflags|NAT_SEARCH, + (u_int)fin->fin_p, + &fin->fin_src6.in6, + &fin->fin_dst6.in6))) { + nflags = nat->nat_flags; + } else if (fin->fin_off == 0) { + u_32_t hv, nmsk = 0; + i6addr_t *msk; + + /* + * If there is no current entry in the nat table for this IP#, + * create one for it (if there is a matching rule). + */ +maskloop: + msk = &softn->ipf_nat6_map_active_masks[nmsk]; + IP6_AND(&ipa, msk, &iph); + hv = NAT_HASH_FN6(&iph, 0, softn->ipf_nat_maprules_sz); + for (np = softn->ipf_nat_map_rules[hv]; np; np = np->in_mnext) { + if ((np->in_ifps[1] && (np->in_ifps[1] != ifp))) + continue; + if (np->in_v[0] != 6) + continue; + if (np->in_pr[1] && (np->in_pr[1] != fin->fin_p)) + continue; + if ((np->in_flags & IPN_RF) && + !(np->in_flags & nflags)) + continue; + if (np->in_flags & IPN_FILTER) { + switch (ipf_nat6_match(fin, np)) + { + case 0 : + continue; + case -1 : + rval = -1; + goto outmatchfail; + case 1 : + default : + break; + } + } else if (!IP6_MASKEQ(&ipa, &np->in_osrcmsk, + &np->in_osrcip6)) + continue; + + if ((fr != NULL) && + !ipf_matchtag(&np->in_tag, &fr->fr_nattag)) + continue; + +#ifdef IPF_V6_PROXIES + if (np->in_plabel != -1) { + if (((np->in_flags & IPN_FILTER) == 0) && + (np->in_odport != fin->fin_data[1])) + continue; + if (appr_ok(fin, tcp, np) == 0) + continue; + } +#endif + + if (np->in_flags & IPN_NO) { + np->in_hits++; + break; + } + + MUTEX_ENTER(&softn->ipf_nat_new); + nat = ipf_nat6_add(fin, np, NULL, nflags, NAT_OUTBOUND); + MUTEX_EXIT(&softn->ipf_nat_new); + if (nat != NULL) { + np->in_hits++; + break; + } + natfailed = -1; + } + if ((np == NULL) && (nmsk < softn->ipf_nat6_map_max)) { + nmsk++; + goto maskloop; + } + } + + if (nat != NULL) { + rval = ipf_nat6_out(fin, nat, natadd, nflags); + if (rval == 1) { + MUTEX_ENTER(&nat->nat_lock); + ipf_nat_update(fin, nat); + nat->nat_bytes[1] += fin->fin_plen; + nat->nat_pkts[1]++; + MUTEX_EXIT(&nat->nat_lock); + } + } else + rval = natfailed; +outmatchfail: + RWLOCK_EXIT(&softc->ipf_nat); + + switch (rval) + { + case -1 : + if (passp != NULL) { + NBUMPSIDE6D(1, ns_drop); + *passp = FR_BLOCK; + fin->fin_reason = FRB_NATV6; + } + fin->fin_flx |= FI_BADNAT; + NBUMPSIDE6D(1, ns_badnat); + break; + case 0 : + NBUMPSIDE6D(1, ns_ignored); + break; + case 1 : + NBUMPSIDE6D(1, ns_translated); + break; + } + fin->fin_ifp = sifp; + return rval; +} + +/* ------------------------------------------------------------------------ */ +/* Function: ipf_nat6_out */ +/* Returns: int - -1 == packet failed NAT checks so block it, */ +/* 1 == packet was successfully translated. */ +/* Parameters: fin(I) - pointer to packet information */ +/* nat(I) - pointer to NAT structure */ +/* natadd(I) - flag indicating if it is safe to add frag cache */ +/* nflags(I) - NAT flags set for this packet */ +/* */ +/* Translate a packet coming "out" on an interface. */ +/* ------------------------------------------------------------------------ */ +static int +ipf_nat6_out(fin, nat, natadd, nflags) + fr_info_t *fin; + nat_t *nat; + int natadd; + u_32_t nflags; +{ + ipf_main_softc_t *softc = fin->fin_main_soft; + ipf_nat_softc_t *softn = softc->ipf_nat_soft; + struct icmp6_hdr *icmp6; + tcphdr_t *tcp; + ipnat_t *np; + int skip; + int i; + + tcp = NULL; + icmp6 = NULL; + np = nat->nat_ptr; + + if ((natadd != 0) && (fin->fin_flx & FI_FRAG) && (np != NULL)) + (void) ipf_frag_natnew(softc, fin, 0, nat); + + /* + * Address assignment is after the checksum modification because + * we are using the address in the packet for determining the + * correct checksum offset (the ICMP error could be coming from + * anyone...) + */ + switch (nat->nat_dir) + { + case NAT_OUTBOUND : + fin->fin_ip6->ip6_src = nat->nat_nsrc6.in6; + fin->fin_src6 = nat->nat_nsrc6; + fin->fin_ip6->ip6_dst = nat->nat_ndst6.in6; + fin->fin_dst6 = nat->nat_ndst6; + break; + + case NAT_INBOUND : + fin->fin_ip6->ip6_src = nat->nat_odst6.in6; + fin->fin_src6 = nat->nat_ndst6; + fin->fin_ip6->ip6_dst = nat->nat_osrc6.in6; + fin->fin_dst6 = nat->nat_nsrc6; + break; + + case NAT_DIVERTIN : + { + mb_t *m; + + skip = ipf_nat6_decap(fin, nat); + if (skip <= 0) { + NBUMPSIDE6D(1, ns_decap_fail); + return -1; + } + + m = fin->fin_m; + +#if defined(MENTAT) && defined(_KERNEL) + m->b_rptr += skip; +#else + m->m_data += skip; + m->m_len -= skip; + +# ifdef M_PKTHDR + if (m->m_flags & M_PKTHDR) + m->m_pkthdr.len -= skip; +# endif +#endif + + MUTEX_ENTER(&nat->nat_lock); + ipf_nat_update(fin, nat); + MUTEX_EXIT(&nat->nat_lock); + fin->fin_flx |= FI_NATED; + if (np != NULL && np->in_tag.ipt_num[0] != 0) + fin->fin_nattag = &np->in_tag; + return 1; + /* NOTREACHED */ + } + + case NAT_DIVERTOUT : + { + udphdr_t *uh; + ip6_t *ip6; + mb_t *m; + + m = M_DUP(np->in_divmp); + if (m == NULL) { + NBUMPSIDE6D(1, ns_divert_dup); + return -1; + } + + ip6 = MTOD(m, ip6_t *); + + ip6->ip6_plen = htons(fin->fin_plen + 8); + + uh = (udphdr_t *)(ip6 + 1); + uh->uh_ulen = htons(fin->fin_plen); + + PREP_MB_T(fin, m); + + fin->fin_ip6 = ip6; + fin->fin_plen += sizeof(ip6_t) + 8; /* UDP + new IPv4 hdr */ + fin->fin_dlen += sizeof(ip6_t) + 8; /* UDP + old IPv4 hdr */ + + nflags &= ~IPN_TCPUDPICMP; + + break; + } + + default : + break; + } + + if (!(fin->fin_flx & FI_SHORT) && (fin->fin_off == 0)) { + u_short *csump; + + if ((nat->nat_nsport != 0) && (nflags & IPN_TCPUDP)) { + tcp = fin->fin_dp; + + switch (nat->nat_dir) + { + case NAT_OUTBOUND : + tcp->th_sport = nat->nat_nsport; + fin->fin_data[0] = ntohs(nat->nat_nsport); + tcp->th_dport = nat->nat_ndport; + fin->fin_data[1] = ntohs(nat->nat_ndport); + break; + + case NAT_INBOUND : + tcp->th_sport = nat->nat_odport; + fin->fin_data[0] = ntohs(nat->nat_odport); + tcp->th_dport = nat->nat_osport; + fin->fin_data[1] = ntohs(nat->nat_osport); + break; + } + } + + if ((nat->nat_nsport != 0) && (nflags & IPN_ICMPQUERY)) { + icmp6 = fin->fin_dp; + icmp6->icmp6_id = nat->nat_nicmpid; + } + + csump = ipf_nat_proto(fin, nat, nflags); + + /* + * The above comments do not hold for layer 4 (or higher) + * checksums... + */ + if (csump != NULL) { + if (nat->nat_dir == NAT_OUTBOUND) + ipf_fix_outcksum(fin->fin_cksum, csump, + nat->nat_sumd[0], + nat->nat_sumd[1] + + fin->fin_dlen); + else + ipf_fix_incksum(fin->fin_cksum, csump, + nat->nat_sumd[0], + nat->nat_sumd[1] + + fin->fin_dlen); + } + } + + ipf_sync_update(softc, SMC_NAT, fin, nat->nat_sync); + /* ------------------------------------------------------------- */ + /* A few quick notes: */ + /* Following are test conditions prior to calling the */ + /* ipf_proxy_check routine. */ + /* */ + /* A NULL tcp indicates a non TCP/UDP packet. When dealing */ + /* with a redirect rule, we attempt to match the packet's */ + /* source port against in_dport, otherwise we'd compare the */ + /* packet's destination. */ + /* ------------------------------------------------------------- */ + if ((np != NULL) && (np->in_apr != NULL)) { + i = ipf_proxy_check(fin, nat); + if (i == 0) { + i = 1; + } else if (i == -1) { + NBUMPSIDE6D(1, ns_ipf_proxy_fail); + } + } else { + i = 1; + } + fin->fin_flx |= FI_NATED; + return i; +} + + +/* ------------------------------------------------------------------------ */ +/* Function: ipf_nat6_checkin */ +/* Returns: int - -1 == packet failed NAT checks so block it, */ +/* 0 == no packet translation occurred, */ +/* 1 == packet was successfully translated. */ +/* Parameters: fin(I) - pointer to packet information */ +/* passp(I) - pointer to filtering result flags */ +/* */ +/* Check to see if an incoming packet should be changed. ICMP packets are */ +/* first checked to see if they match an existing entry (if an error), */ +/* otherwise a search of the current NAT table is made. If neither results */ +/* in a match then a search for a matching NAT rule is made. Create a new */ +/* NAT entry if a we matched a NAT rule. Lastly, actually change the */ +/* packet header(s) as required. */ +/* ------------------------------------------------------------------------ */ +int +ipf_nat6_checkin(fin, passp) + fr_info_t *fin; + u_32_t *passp; +{ + ipf_main_softc_t *softc = fin->fin_main_soft; + ipf_nat_softc_t *softn = softc->ipf_nat_soft; + struct icmp6_hdr *icmp6; + u_int nflags, natadd; + int rval, natfailed; + struct ifnet *ifp; + i6addr_t ipa, iph; + tcphdr_t *tcp; + u_short dport; + ipnat_t *np; + nat_t *nat; + + if (softn->ipf_nat_stats.ns_rules == 0 || softn->ipf_nat_lock != 0) + return 0; + + tcp = NULL; + icmp6 = NULL; + dport = 0; + natadd = 1; + nflags = 0; + natfailed = 0; + ifp = fin->fin_ifp; + + if (!(fin->fin_flx & FI_SHORT) && (fin->fin_off == 0)) { + switch (fin->fin_p) + { + case IPPROTO_TCP : + nflags = IPN_TCP; + break; + case IPPROTO_UDP : + nflags = IPN_UDP; + break; + case IPPROTO_ICMPV6 : + icmp6 = fin->fin_dp; + + /* + * Apart from ECHO request and reply, all other + * informational messages should not be translated + * so as to keep IPv6 working. + */ + if (icmp6->icmp6_type > ICMP6_ECHO_REPLY) + return 0; + + /* + * This is an incoming packet, so the destination is + * the icmp6_id and the source port equals 0 + */ + if ((fin->fin_flx & FI_ICMPQUERY) != 0) { + nflags = IPN_ICMPQUERY; + dport = icmp6->icmp6_id; + } break; + default : + break; + } + + if ((nflags & IPN_TCPUDP)) { + tcp = fin->fin_dp; + dport = fin->fin_data[1]; + } + } + + ipa = fin->fin_dst6; + + READ_ENTER(&softc->ipf_nat); + + if ((fin->fin_p == IPPROTO_ICMPV6) && !(nflags & IPN_ICMPQUERY) && + (nat = ipf_nat6_icmperror(fin, &nflags, NAT_INBOUND))) + /*EMPTY*/; + else if ((fin->fin_flx & FI_FRAG) && (nat = ipf_frag_natknown(fin))) + natadd = 0; + else if ((nat = ipf_nat6_inlookup(fin, nflags|NAT_SEARCH, + (u_int)fin->fin_p, + &fin->fin_src6.in6, &ipa.in6))) { + nflags = nat->nat_flags; + } else if (fin->fin_off == 0) { + u_32_t hv, rmsk = 0; + i6addr_t *msk; + + /* + * If there is no current entry in the nat table for this IP#, + * create one for it (if there is a matching rule). + */ +maskloop: + msk = &softn->ipf_nat6_rdr_active_masks[rmsk]; + IP6_AND(&ipa, msk, &iph); + hv = NAT_HASH_FN6(&iph, 0, softn->ipf_nat_rdrrules_sz); + for (np = softn->ipf_nat_rdr_rules[hv]; np; np = np->in_rnext) { + if (np->in_ifps[0] && (np->in_ifps[0] != ifp)) + continue; + if (np->in_v[0] != 6) + continue; + if (np->in_pr[0] && (np->in_pr[0] != fin->fin_p)) + continue; + if ((np->in_flags & IPN_RF) && !(np->in_flags & nflags)) + continue; + if (np->in_flags & IPN_FILTER) { + switch (ipf_nat6_match(fin, np)) + { + case 0 : + continue; + case -1 : + rval = -1; + goto inmatchfail; + case 1 : + default : + break; + } + } else { + if (!IP6_MASKEQ(&ipa, &np->in_odstmsk6, + &np->in_odstip6)) { + continue; + } + if (np->in_odport && + ((np->in_dtop < dport) || + (dport < np->in_odport))) + continue; + } + +#ifdef IPF_V6_PROXIES + if (np->in_plabel != -1) { + if (!appr_ok(fin, tcp, np)) { + continue; + } + } +#endif + + if (np->in_flags & IPN_NO) { + np->in_hits++; + break; + } + + MUTEX_ENTER(&softn->ipf_nat_new); + nat = ipf_nat6_add(fin, np, NULL, nflags, NAT_INBOUND); + MUTEX_EXIT(&softn->ipf_nat_new); + if (nat != NULL) { + np->in_hits++; + break; + } + natfailed = -1; + } + + if ((np == NULL) && (rmsk < softn->ipf_nat6_rdr_max)) { + rmsk++; + goto maskloop; + } + } + if (nat != NULL) { + rval = ipf_nat6_in(fin, nat, natadd, nflags); + if (rval == 1) { + MUTEX_ENTER(&nat->nat_lock); + ipf_nat_update(fin, nat); + nat->nat_bytes[0] += fin->fin_plen; + nat->nat_pkts[0]++; + MUTEX_EXIT(&nat->nat_lock); + } + } else + rval = natfailed; +inmatchfail: + RWLOCK_EXIT(&softc->ipf_nat); + + switch (rval) + { + case -1 : + if (passp != NULL) { + NBUMPSIDE6D(0, ns_drop); + *passp = FR_BLOCK; + fin->fin_reason = FRB_NATV6; + } + fin->fin_flx |= FI_BADNAT; + NBUMPSIDE6D(0, ns_badnat); + break; + case 0 : + NBUMPSIDE6D(0, ns_ignored); + break; + case 1 : + NBUMPSIDE6D(0, ns_translated); + break; + } + return rval; +} + + +/* ------------------------------------------------------------------------ */ +/* Function: ipf_nat6_in */ +/* Returns: int - -1 == packet failed NAT checks so block it, */ +/* 1 == packet was successfully translated. */ +/* Parameters: fin(I) - pointer to packet information */ +/* nat(I) - pointer to NAT structure */ +/* natadd(I) - flag indicating if it is safe to add frag cache */ +/* nflags(I) - NAT flags set for this packet */ +/* Locks Held: (READ) */ +/* */ +/* Translate a packet coming "in" on an interface. */ +/* ------------------------------------------------------------------------ */ +static int +ipf_nat6_in(fin, nat, natadd, nflags) + fr_info_t *fin; + nat_t *nat; + int natadd; + u_32_t nflags; +{ + ipf_main_softc_t *softc = fin->fin_main_soft; + ipf_nat_softc_t *softn = softc->ipf_nat_soft; + struct icmp6_hdr *icmp6; + u_short *csump; + tcphdr_t *tcp; + ipnat_t *np; + int skip; + int i; + + tcp = NULL; + csump = NULL; + np = nat->nat_ptr; + fin->fin_fr = nat->nat_fr; + + if (np != NULL) { + if ((natadd != 0) && (fin->fin_flx & FI_FRAG)) + (void) ipf_frag_natnew(softc, fin, 0, nat); + + /* ------------------------------------------------------------- */ + /* A few quick notes: */ + /* Following are test conditions prior to calling the */ + /* ipf_proxy_check routine. */ + /* */ + /* A NULL tcp indicates a non TCP/UDP packet. When dealing */ + /* with a map rule, we attempt to match the packet's */ + /* source port against in_dport, otherwise we'd compare the */ + /* packet's destination. */ + /* ------------------------------------------------------------- */ + if (np->in_apr != NULL) { + i = ipf_proxy_check(fin, nat); + if (i == -1) { + NBUMPSIDE6D(0, ns_ipf_proxy_fail); + return -1; + } + } + } + + ipf_sync_update(softc, SMC_NAT, fin, nat->nat_sync); + + /* + * Fix up checksums, not by recalculating them, but + * simply computing adjustments. + * Why only do this for some platforms on inbound packets ? + * Because for those that it is done, IP processing is yet to happen + * and so the IPv4 header checksum has not yet been evaluated. + * Perhaps it should always be done for the benefit of things like + * fast forwarding (so that it doesn't need to be recomputed) but with + * header checksum offloading, perhaps it is a moot point. + */ + + switch (nat->nat_dir) + { + case NAT_INBOUND : + if ((fin->fin_flx & FI_ICMPERR) == 0) { + fin->fin_ip6->ip6_src = nat->nat_nsrc6.in6; + fin->fin_src6 = nat->nat_nsrc6; + } + fin->fin_ip6->ip6_dst = nat->nat_ndst6.in6; + fin->fin_dst6 = nat->nat_ndst6; + break; + + case NAT_OUTBOUND : + if ((fin->fin_flx & FI_ICMPERR) == 0) { + fin->fin_ip6->ip6_src = nat->nat_odst6.in6; + fin->fin_src6 = nat->nat_odst6; + } + fin->fin_ip6->ip6_dst = nat->nat_osrc6.in6; + fin->fin_dst6 = nat->nat_osrc6; + break; + + case NAT_DIVERTIN : + { + udphdr_t *uh; + ip6_t *ip6; + mb_t *m; + + m = M_DUP(np->in_divmp); + if (m == NULL) { + NBUMPSIDE6D(0, ns_divert_dup); + return -1; + } + + ip6 = MTOD(m, ip6_t *); + ip6->ip6_plen = htons(fin->fin_plen + sizeof(udphdr_t)); + + uh = (udphdr_t *)(ip6 + 1); + uh->uh_ulen = ntohs(fin->fin_plen); + + PREP_MB_T(fin, m); + + fin->fin_ip6 = ip6; + fin->fin_plen += sizeof(ip6_t) + 8; /* UDP + new IPv6 hdr */ + fin->fin_dlen += sizeof(ip6_t) + 8; /* UDP + old IPv6 hdr */ + + nflags &= ~IPN_TCPUDPICMP; + + break; + } + + case NAT_DIVERTOUT : + { + mb_t *m; + + skip = ipf_nat6_decap(fin, nat); + if (skip <= 0) { + NBUMPSIDE6D(0, ns_decap_fail); + return -1; + } + + m = fin->fin_m; + +#if defined(MENTAT) && defined(_KERNEL) + m->b_rptr += skip; +#else + m->m_data += skip; + m->m_len -= skip; + +# ifdef M_PKTHDR + if (m->m_flags & M_PKTHDR) + m->m_pkthdr.len -= skip; +# endif +#endif + + ipf_nat_update(fin, nat); + fin->fin_flx |= FI_NATED; + if (np != NULL && np->in_tag.ipt_num[0] != 0) + fin->fin_nattag = &np->in_tag; + return 1; + /* NOTREACHED */ + } + } + if (nflags & IPN_TCPUDP) + tcp = fin->fin_dp; + + if (!(fin->fin_flx & FI_SHORT) && (fin->fin_off == 0)) { + if ((nat->nat_odport != 0) && (nflags & IPN_TCPUDP)) { + switch (nat->nat_dir) + { + case NAT_INBOUND : + tcp->th_sport = nat->nat_nsport; + fin->fin_data[0] = ntohs(nat->nat_nsport); + tcp->th_dport = nat->nat_ndport; + fin->fin_data[1] = ntohs(nat->nat_ndport); + break; + + case NAT_OUTBOUND : + tcp->th_sport = nat->nat_odport; + fin->fin_data[0] = ntohs(nat->nat_odport); + tcp->th_dport = nat->nat_osport; + fin->fin_data[1] = ntohs(nat->nat_osport); + break; + } + } + + + if ((nat->nat_odport != 0) && (nflags & IPN_ICMPQUERY)) { + icmp6 = fin->fin_dp; + + icmp6->icmp6_id = nat->nat_nicmpid; + } + + csump = ipf_nat_proto(fin, nat, nflags); + } + + /* + * The above comments do not hold for layer 4 (or higher) checksums... + */ + if (csump != NULL) { + if (nat->nat_dir == NAT_OUTBOUND) + ipf_fix_incksum(0, csump, nat->nat_sumd[0], 0); + else + ipf_fix_outcksum(0, csump, nat->nat_sumd[0], 0); + } + fin->fin_flx |= FI_NATED; + if (np != NULL && np->in_tag.ipt_num[0] != 0) + fin->fin_nattag = &np->in_tag; + return 1; +} + + +/* ------------------------------------------------------------------------ */ +/* Function: ipf_nat6_newrewrite */ +/* Returns: int - -1 == error, 0 == success (no move), 1 == success and */ +/* allow rule to be moved if IPN_ROUNDR is set. */ +/* Parameters: fin(I) - pointer to packet information */ +/* nat(I) - pointer to NAT entry */ +/* ni(I) - pointer to structure with misc. information needed */ +/* to create new NAT entry. */ +/* Write Lock: ipf_nat */ +/* */ +/* This function is responsible for setting up an active NAT session where */ +/* we are changing both the source and destination parameters at the same */ +/* time. The loop in here works differently to elsewhere - each iteration */ +/* is responsible for changing a single parameter that can be incremented. */ +/* So one pass may increase the source IP#, next source port, next dest. IP#*/ +/* and the last destination port for a total of 4 iterations to try each. */ +/* This is done to try and exhaustively use the translation space available.*/ +/* ------------------------------------------------------------------------ */ +int +ipf_nat6_newrewrite(fin, nat, nai) + fr_info_t *fin; + nat_t *nat; + natinfo_t *nai; +{ + int src_search = 1; + int dst_search = 1; + fr_info_t frnat; + u_32_t flags; + u_short swap; + ipnat_t *np; + nat_t *natl; + int l = 0; + int changed; + + natl = NULL; + changed = -1; + np = nai->nai_np; + flags = nat->nat_flags; + bcopy((char *)fin, (char *)&frnat, sizeof(*fin)); + + nat->nat_hm = NULL; + + do { + changed = -1; + /* TRACE (l, src_search, dst_search, np) */ + + if ((src_search == 0) && (np->in_spnext == 0) && + (dst_search == 0) && (np->in_dpnext == 0)) { + if (l > 0) + return -1; + } + + /* + * Find a new source address + */ + if (ipf_nat6_nextaddr(fin, &np->in_nsrc, &frnat.fin_src6, + &frnat.fin_src6) == -1) { + return -1; + } + + if (IP6_ISZERO(&np->in_nsrcip6) && + IP6_ISONES(&np->in_nsrcmsk6)) { + src_search = 0; + if (np->in_stepnext == 0) + np->in_stepnext = 1; + + } else if (IP6_ISZERO(&np->in_nsrcip6) && + IP6_ISZERO(&np->in_nsrcmsk6)) { + src_search = 0; + if (np->in_stepnext == 0) + np->in_stepnext = 1; + + } else if (IP6_ISONES(&np->in_nsrcmsk)) { + src_search = 0; + if (np->in_stepnext == 0) + np->in_stepnext = 1; + + } else if (!IP6_ISONES(&np->in_nsrcmsk6)) { + if (np->in_stepnext == 0 && changed == -1) { + IP6_INC(&np->in_snip); + np->in_stepnext++; + changed = 0; + } + } + + if ((flags & IPN_TCPUDPICMP) != 0) { + if (np->in_spnext != 0) + frnat.fin_data[0] = np->in_spnext; + + /* + * Standard port translation. Select next port. + */ + if ((flags & IPN_FIXEDSPORT) != 0) { + np->in_stepnext = 2; + } else if ((np->in_stepnext == 1) && + (changed == -1) && (natl != NULL)) { + np->in_spnext++; + np->in_stepnext++; + changed = 1; + if (np->in_spnext > np->in_spmax) + np->in_spnext = np->in_spmin; + } + } else { + np->in_stepnext = 2; + } + np->in_stepnext &= 0x3; + + /* + * Find a new destination address + */ + /* TRACE (fin, np, l, frnat) */ + + if (ipf_nat6_nextaddr(fin, &np->in_ndst, &frnat.fin_dst6, + &frnat.fin_dst6) == -1) + return -1; + + if (IP6_ISZERO(&np->in_ndstip6) && + IP6_ISONES(&np->in_ndstmsk6)) { + dst_search = 0; + if (np->in_stepnext == 2) + np->in_stepnext = 3; + + } else if (IP6_ISZERO(&np->in_ndstip6) && + IP6_ISZERO(&np->in_ndstmsk6)) { + dst_search = 0; + if (np->in_stepnext == 2) + np->in_stepnext = 3; + + } else if (IP6_ISONES(&np->in_ndstmsk6)) { + dst_search = 0; + if (np->in_stepnext == 2) + np->in_stepnext = 3; + + } else if (!IP6_ISONES(&np->in_ndstmsk6)) { + if ((np->in_stepnext == 2) && (changed == -1) && + (natl != NULL)) { + changed = 2; + np->in_stepnext++; + IP6_INC(&np->in_dnip6); + } + } + + if ((flags & IPN_TCPUDPICMP) != 0) { + if (np->in_dpnext != 0) + frnat.fin_data[1] = np->in_dpnext; + + /* + * Standard port translation. Select next port. + */ + if ((flags & IPN_FIXEDDPORT) != 0) { + np->in_stepnext = 0; + } else if (np->in_stepnext == 3 && changed == -1) { + np->in_dpnext++; + np->in_stepnext++; + changed = 3; + if (np->in_dpnext > np->in_dpmax) + np->in_dpnext = np->in_dpmin; + } + } else { + if (np->in_stepnext == 3) + np->in_stepnext = 0; + } + + /* TRACE (frnat) */ + + /* + * Here we do a lookup of the connection as seen from + * the outside. If an IP# pair already exists, try + * again. So if you have A->B becomes C->B, you can + * also have D->E become C->E but not D->B causing + * another C->B. Also take protocol and ports into + * account when determining whether a pre-existing + * NAT setup will cause an external conflict where + * this is appropriate. + * + * fin_data[] is swapped around because we are doing a + * lookup of the packet is if it were moving in the opposite + * direction of the one we are working with now. + */ + if (flags & IPN_TCPUDP) { + swap = frnat.fin_data[0]; + frnat.fin_data[0] = frnat.fin_data[1]; + frnat.fin_data[1] = swap; + } + if (fin->fin_out == 1) { + natl = ipf_nat6_inlookup(&frnat, + flags & ~(SI_WILDP|NAT_SEARCH), + (u_int)frnat.fin_p, + &frnat.fin_dst6.in6, + &frnat.fin_src6.in6); + + } else { + natl = ipf_nat6_outlookup(&frnat, + flags & ~(SI_WILDP|NAT_SEARCH), + (u_int)frnat.fin_p, + &frnat.fin_dst6.in6, + &frnat.fin_src6.in6); + } + if (flags & IPN_TCPUDP) { + swap = frnat.fin_data[0]; + frnat.fin_data[0] = frnat.fin_data[1]; + frnat.fin_data[1] = swap; + } + + /* TRACE natl, in_stepnext, l */ + + if ((natl != NULL) && (l > 8)) /* XXX 8 is arbitrary */ + return -1; + + np->in_stepnext &= 0x3; + + l++; + changed = -1; + } while (natl != NULL); + nat->nat_osrc6 = fin->fin_src6; + nat->nat_odst6 = fin->fin_dst6; + nat->nat_nsrc6 = frnat.fin_src6; + nat->nat_ndst6 = frnat.fin_dst6; + + if ((flags & IPN_TCPUDP) != 0) { + nat->nat_osport = htons(fin->fin_data[0]); + nat->nat_odport = htons(fin->fin_data[1]); + nat->nat_nsport = htons(frnat.fin_data[0]); + nat->nat_ndport = htons(frnat.fin_data[1]); + } else if ((flags & IPN_ICMPQUERY) != 0) { + nat->nat_oicmpid = fin->fin_data[1]; + nat->nat_nicmpid = frnat.fin_data[1]; + } + + return 0; +} + + +/* ------------------------------------------------------------------------ */ +/* Function: ipf_nat6_newdivert */ +/* Returns: int - -1 == error, 0 == success */ +/* Parameters: fin(I) - pointer to packet information */ +/* nat(I) - pointer to NAT entry */ +/* ni(I) - pointer to structure with misc. information needed */ +/* to create new NAT entry. */ +/* Write Lock: ipf_nat */ +/* */ +/* Create a new NAT divert session as defined by the NAT rule. This is */ +/* somewhat different to other NAT session creation routines because we */ +/* do not iterate through either port numbers or IP addresses, searching */ +/* for a unique mapping, however, a complimentary duplicate check is made. */ +/* ------------------------------------------------------------------------ */ +int +ipf_nat6_newdivert(fin, nat, nai) + fr_info_t *fin; + nat_t *nat; + natinfo_t *nai; +{ + ipf_main_softc_t *softc = fin->fin_main_soft; + ipf_nat_softc_t *softn = softc->ipf_nat_soft; + fr_info_t frnat; + ipnat_t *np; + nat_t *natl; + int p; + + np = nai->nai_np; + bcopy((char *)fin, (char *)&frnat, sizeof(*fin)); + + nat->nat_pr[0] = 0; + nat->nat_osrc6 = fin->fin_src6; + nat->nat_odst6 = fin->fin_dst6; + nat->nat_osport = htons(fin->fin_data[0]); + nat->nat_odport = htons(fin->fin_data[1]); + frnat.fin_src6 = np->in_snip6; + frnat.fin_dst6 = np->in_dnip6; + + if (np->in_redir & NAT_DIVERTUDP) { + frnat.fin_data[0] = np->in_spnext; + frnat.fin_data[1] = np->in_dpnext; + frnat.fin_flx |= FI_TCPUDP; + p = IPPROTO_UDP; + } else { + frnat.fin_flx &= ~FI_TCPUDP; + p = IPPROTO_IPIP; + } + + if (fin->fin_out == 1) { + natl = ipf_nat6_inlookup(&frnat, 0, p, &frnat.fin_dst6.in6, + &frnat.fin_src6.in6); + + } else { + natl = ipf_nat6_outlookup(&frnat, 0, p, &frnat.fin_dst6.in6, + &frnat.fin_src6.in6); + } + + if (natl != NULL) { + NBUMPSIDE6D(fin->fin_out, ns_divert_exist); + return -1; + } + + nat->nat_nsrc6 = frnat.fin_src6; + nat->nat_ndst6 = frnat.fin_dst6; + if (np->in_redir & NAT_DIVERTUDP) { + nat->nat_nsport = htons(frnat.fin_data[0]); + nat->nat_ndport = htons(frnat.fin_data[1]); + } + nat->nat_pr[fin->fin_out] = fin->fin_p; + nat->nat_pr[1 - fin->fin_out] = p; + + if (np->in_redir & NAT_REDIRECT) + nat->nat_dir = NAT_DIVERTIN; + else + nat->nat_dir = NAT_DIVERTOUT; + + return 0; +} + + +/* ------------------------------------------------------------------------ */ +/* Function: nat6_builddivertmp */ +/* Returns: int - -1 == error, 0 == success */ +/* Parameters: np(I) - pointer to a NAT rule */ +/* */ +/* For divert rules, a skeleton packet representing what will be prepended */ +/* to the real packet is created. Even though we don't have the full */ +/* packet here, a checksum is calculated that we update later when we */ +/* fill in the final details. At present a 0 checksum for UDP is being set */ +/* here because it is expected that divert will be used for localhost. */ +/* ------------------------------------------------------------------------ */ +static int +ipf_nat6_builddivertmp(softn, np) + ipf_nat_softc_t *softn; + ipnat_t *np; +{ + udphdr_t *uh; + size_t len; + ip6_t *ip6; + + if ((np->in_redir & NAT_DIVERTUDP) != 0) + len = sizeof(ip6_t) + sizeof(udphdr_t); + else + len = sizeof(ip6_t); + + ALLOC_MB_T(np->in_divmp, len); + if (np->in_divmp == NULL) { + ATOMIC_INCL(softn->ipf_nat_stats.ns_divert_build); + return -1; + } + + /* + * First, the header to get the packet diverted to the new destination + */ + ip6 = MTOD(np->in_divmp, ip6_t *); + ip6->ip6_vfc = 0x60; + if ((np->in_redir & NAT_DIVERTUDP) != 0) + ip6->ip6_nxt = IPPROTO_UDP; + else + ip6->ip6_nxt = IPPROTO_IPIP; + ip6->ip6_hlim = 255; + ip6->ip6_plen = 0; + ip6->ip6_src = np->in_snip6.in6; + ip6->ip6_dst = np->in_dnip6.in6; + + if (np->in_redir & NAT_DIVERTUDP) { + uh = (udphdr_t *)((u_char *)ip6 + sizeof(*ip6)); + uh->uh_sum = 0; + uh->uh_ulen = 8; + uh->uh_sport = htons(np->in_spnext); + uh->uh_dport = htons(np->in_dpnext); + } + + return 0; +} + + +#define MINDECAP (sizeof(ip6_t) + sizeof(udphdr_t) + sizeof(ip6_t)) + +/* ------------------------------------------------------------------------ */ +/* Function: nat6_decap */ +/* Returns: int - -1 == error, 0 == success */ +/* Parameters: fin(I) - pointer to packet information */ +/* nat(I) - pointer to current NAT session */ +/* */ +/* This function is responsible for undoing a packet's encapsulation in the */ +/* reverse of an encap/divert rule. After removing the outer encapsulation */ +/* it is necessary to call ipf_makefrip() again so that the contents of 'fin'*/ +/* match the "new" packet as it may still be used by IPFilter elsewhere. */ +/* We use "dir" here as the basis for some of the expectations about the */ +/* outer header. If we return an error, the goal is to leave the original */ +/* packet information undisturbed - this falls short at the end where we'd */ +/* need to back a backup copy of "fin" - expensive. */ +/* ------------------------------------------------------------------------ */ +static int +ipf_nat6_decap(fin, nat) + fr_info_t *fin; + nat_t *nat; +{ + ipf_main_softc_t *softc = fin->fin_main_soft; + ipf_nat_softc_t *softn = softc->ipf_nat_soft; + char *hdr; + int skip; + mb_t *m; + + if ((fin->fin_flx & FI_ICMPERR) != 0) { + return 0; + } + + m = fin->fin_m; + skip = fin->fin_hlen; + + switch (nat->nat_dir) + { + case NAT_DIVERTIN : + case NAT_DIVERTOUT : + if (fin->fin_plen < MINDECAP) + return -1; + skip += sizeof(udphdr_t); + break; + + case NAT_ENCAPIN : + case NAT_ENCAPOUT : + if (fin->fin_plen < (skip + sizeof(ip6_t))) + return -1; + break; + default : + return -1; + /* NOTREACHED */ + } + + /* + * The aim here is to keep the original packet details in "fin" for + * as long as possible so that returning with an error is for the + * original packet and there is little undoing work to do. + */ + if (M_LEN(m) < skip + sizeof(ip6_t)) { + if (ipf_pr_pullup(fin, skip + sizeof(ip6_t)) == -1) + return -1; + } + + hdr = MTOD(fin->fin_m, char *); + fin->fin_ip6 = (ip6_t *)(hdr + skip); + + if (ipf_pr_pullup(fin, skip + sizeof(ip6_t)) == -1) { + NBUMPSIDE6D(fin->fin_out, ns_decap_pullup); + return -1; + } + + fin->fin_hlen = sizeof(ip6_t); + fin->fin_dlen -= skip; + fin->fin_plen -= skip; + fin->fin_ipoff += skip; + + if (ipf_makefrip(sizeof(ip6_t), (ip_t *)hdr, fin) == -1) { + NBUMPSIDE6D(fin->fin_out, ns_decap_bad); + return -1; + } + + return skip; +} + + +/* ------------------------------------------------------------------------ */ +/* Function: nat6_nextaddr */ +/* Returns: int - -1 == bad input (no new address), */ +/* 0 == success and dst has new address */ +/* Parameters: fin(I) - pointer to packet information */ +/* na(I) - how to generate new address */ +/* old(I) - original address being replaced */ +/* dst(O) - where to put the new address */ +/* Write Lock: ipf_nat */ +/* */ +/* This function uses the contents of the "na" structure, in combination */ +/* with "old" to produce a new address to store in "dst". Not all of the */ +/* possible uses of "na" will result in a new address. */ +/* ------------------------------------------------------------------------ */ +static int +ipf_nat6_nextaddr(fin, na, old, dst) + fr_info_t *fin; + nat_addr_t *na; + i6addr_t *old, *dst; +{ + ipf_main_softc_t *softc = fin->fin_main_soft; + ipf_nat_softc_t *softn = softc->ipf_nat_soft; + i6addr_t newip, new; + u_32_t amin, amax; + int error; + + new.i6[0] = 0; + new.i6[1] = 0; + new.i6[2] = 0; + new.i6[3] = 0; + amin = na->na_addr[0].in4.s_addr; + + switch (na->na_atype) + { + case FRI_RANGE : + amax = na->na_addr[1].in4.s_addr; + break; + + case FRI_NETMASKED : + case FRI_DYNAMIC : + case FRI_NORMAL : + /* + * Compute the maximum address by adding the inverse of the + * netmask to the minimum address. + */ + amax = ~na->na_addr[1].in4.s_addr; + amax |= amin; + break; + + case FRI_LOOKUP : + break; + + case FRI_BROADCAST : + case FRI_PEERADDR : + case FRI_NETWORK : + default : + return -1; + } + + error = -1; + switch (na->na_function) + { + case IPLT_DSTLIST : + error = ipf_dstlist_select_node(fin, na->na_ptr, dst->i6, + NULL); + break; + + case IPLT_NONE : + /* + * 0/0 as the new address means leave it alone. + */ + if (na->na_addr[0].in4.s_addr == 0 && + na->na_addr[1].in4.s_addr == 0) { + new = *old; + + /* + * 0/32 means get the interface's address + */ + } else if (IP6_ISZERO(&na->na_addr[0].in6) && + IP6_ISONES(&na->na_addr[1].in6)) { + if (ipf_ifpaddr(softc, 6, na->na_atype, + fin->fin_ifp, &newip, NULL) == -1) { + NBUMPSIDE6(fin->fin_out, ns_ifpaddrfail); + return -1; + } + new = newip; + } else { + new.in6 = na->na_nextip6; + } + *dst = new; + error = 0; + break; + + default : + NBUMPSIDE6(fin->fin_out, ns_badnextaddr); + break; + } + + return error; +} + + +/* ------------------------------------------------------------------------ */ +/* Function: ipf_nat6_nextaddrinit */ +/* Returns: int - 0 == success, else error number */ +/* Parameters: na(I) - NAT address information for generating new addr*/ +/* base(I) - start of where to find strings */ +/* initial(I) - flag indicating if it is the first call for */ +/* this "na" structure. */ +/* ifp(I) - network interface to derive address */ +/* information from. */ +/* */ +/* This function is expected to be called in two scenarious: when a new NAT */ +/* rule is loaded into the kernel and when the list of NAT rules is sync'd */ +/* up with the valid network interfaces (possibly due to them changing.) */ +/* To distinguish between these, the "initial" parameter is used. If it is */ +/* 1 then this indicates the rule has just been reloaded and 0 for when we */ +/* are updating information. This difference is important because in */ +/* instances where we are not updating address information associated with */ +/* a network interface, we don't want to disturb what the "next" address to */ +/* come out of ipf_nat6_nextaddr() will be. */ +/* ------------------------------------------------------------------------ */ +static int +ipf_nat6_nextaddrinit(softc, base, na, initial, ifp) + ipf_main_softc_t *softc; + char *base; + nat_addr_t *na; + int initial; + void *ifp; +{ + switch (na->na_atype) + { + case FRI_LOOKUP : + if (na->na_subtype == 0) { + na->na_ptr = ipf_lookup_res_num(softc, IPL_LOGNAT, + na->na_type, + na->na_num, + &na->na_func); + } else if (na->na_subtype == 1) { + na->na_ptr = ipf_lookup_res_name(softc, IPL_LOGNAT, + na->na_type, + base + na->na_num, + &na->na_func); + } + if (na->na_func == NULL) { + IPFERROR(60072); + return ESRCH; + } + if (na->na_ptr == NULL) { + IPFERROR(60073); + return ESRCH; + } + break; + case FRI_DYNAMIC : + case FRI_BROADCAST : + case FRI_NETWORK : + case FRI_NETMASKED : + case FRI_PEERADDR : + if (ifp != NULL) + (void )ipf_ifpaddr(softc, 6, na->na_atype, ifp, + &na->na_addr[0], + &na->na_addr[1]); + break; + + case FRI_SPLIT : + case FRI_RANGE : + if (initial) + na->na_nextip6 = na->na_addr[0].in6; + break; + + case FRI_NONE : + IP6_ANDASSIGN(&na->na_addr[0].in6, &na->na_addr[1].in6); + return 0; + + case FRI_NORMAL : + IP6_ANDASSIGN(&na->na_addr[0].in6, &na->na_addr[1].in6); + break; + + default : + IPFERROR(60074); + return EINVAL; + } + + if (initial && (na->na_atype == FRI_NORMAL)) { + if (IP6_ISZERO(&na->na_addr[0].in6)) { + if (IP6_ISONES(&na->na_addr[1].in6) || + IP6_ISZERO(&na->na_addr[1].in6)) { + return 0; + } + } + + na->na_nextip6 = na->na_addr[0].in6; + if (!IP6_ISONES(&na->na_addr[1].in6)) { + IP6_INC(&na->na_nextip6); + } + } + + return 0; +} + + +/* ------------------------------------------------------------------------ */ +/* Function: ipf_nat6_icmpquerytype */ +/* Returns: int - 1 == success, 0 == failure */ +/* Parameters: icmptype(I) - ICMP type number */ +/* */ +/* Tests to see if the ICMP type number passed is a query/response type or */ +/* not. */ +/* ------------------------------------------------------------------------ */ +static int +ipf_nat6_icmpquerytype(icmptype) + int icmptype; +{ + + /* + * For the ICMP query NAT code, it is essential that both the query + * and the reply match on the NAT rule. Because the NAT structure + * does not keep track of the icmptype, and a single NAT structure + * is used for all icmp types with the same src, dest and id, we + * simply define the replies as queries as well. The funny thing is, + * altough it seems silly to call a reply a query, this is exactly + * as it is defined in the IPv4 specification + */ + + switch (icmptype) + { + + case ICMP6_ECHO_REPLY: + case ICMP6_ECHO_REQUEST: + /* route aedvertisement/solliciation is currently unsupported: */ + /* it would require rewriting the ICMP data section */ + case ICMP6_MEMBERSHIP_QUERY: + case ICMP6_MEMBERSHIP_REPORT: + case ICMP6_MEMBERSHIP_REDUCTION: + case ICMP6_WRUREQUEST: + case ICMP6_WRUREPLY: + case MLD6_MTRACE_RESP: + case MLD6_MTRACE: + return 1; + default: + return 0; + } +} +#endif /* USE_INET6 */ diff --git a/sys/contrib/ipfilter/netinet/ip_netbios_pxy.c b/sys/contrib/ipfilter/netinet/ip_netbios_pxy.c index 1a0b2a2e49ed..4e8bdc66a2f2 100644 --- a/sys/contrib/ipfilter/netinet/ip_netbios_pxy.c +++ b/sys/contrib/ipfilter/netinet/ip_netbios_pxy.c @@ -1,7 +1,7 @@ /* * Simple netbios-dgm transparent proxy for in-kernel use. * For use with the NAT code. - * $Id: ip_netbios_pxy.c,v 2.8.2.1 2005/08/20 13:48:23 darrenr Exp $ + * $Id$ */ /*- @@ -29,14 +29,14 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: ip_netbios_pxy.c,v 2.8.2.1 2005/08/20 13:48:23 darrenr Exp $ + * $Id$ */ #define IPF_NETBIOS_PROXY -int ippr_netbios_init __P((void)); -void ippr_netbios_fini __P((void)); -int ippr_netbios_out __P((fr_info_t *, ap_session_t *, nat_t *)); +void ipf_p_netbios_main_load __P((void)); +void ipf_p_netbios_main_unload __P((void)); +int ipf_p_netbios_out __P((void *, fr_info_t *, ap_session_t *, nat_t *)); static frentry_t netbiosfr; @@ -45,19 +45,19 @@ int netbios_proxy_init = 0; /* * Initialize local structures. */ -int ippr_netbios_init() +void +ipf_p_netbios_main_load() { bzero((char *)&netbiosfr, sizeof(netbiosfr)); netbiosfr.fr_ref = 1; netbiosfr.fr_flags = FR_INQUE|FR_PASS|FR_QUICK|FR_KEEPSTATE; MUTEX_INIT(&netbiosfr.fr_lock, "NETBIOS proxy rule lock"); netbios_proxy_init = 1; - - return 0; } -void ippr_netbios_fini() +void +ipf_p_netbios_main_unload() { if (netbios_proxy_init == 1) { MUTEX_DESTROY(&netbiosfr.fr_lock); @@ -66,10 +66,12 @@ void ippr_netbios_fini() } -int ippr_netbios_out(fin, aps, nat) -fr_info_t *fin; -ap_session_t *aps; -nat_t *nat; +int +ipf_p_netbios_out(arg, fin, aps, nat) + void *arg; + fr_info_t *fin; + ap_session_t *aps; + nat_t *nat; { char dgmbuf[6]; int off, dlen; diff --git a/sys/contrib/ipfilter/netinet/ip_pool.c b/sys/contrib/ipfilter/netinet/ip_pool.c index eab33108a567..2a43cdb00bfa 100644 --- a/sys/contrib/ipfilter/netinet/ip_pool.c +++ b/sys/contrib/ipfilter/netinet/ip_pool.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 1993-2001, 2003 by Darren Reed. + * Copyright (C) 2012 by Darren Reed. * * See the IPFILTER.LICENCE file for details on licencing. */ @@ -33,15 +33,10 @@ struct file; # endif #endif #include -#if !defined(linux) -# include -#endif -#include -#if defined(_KERNEL) && (!defined(__SVR4) && !defined(__svr4__)) +#if defined(_KERNEL) && !defined(SOLARIS2) # include #endif #if defined(__SVR4) || defined(__svr4__) -# include # include # ifdef _KERNEL # include @@ -53,69 +48,91 @@ struct file; # include #endif -#if defined(SOLARIS2) && !defined(_KERNEL) -# include "radix_ipf.h" -#endif -#if defined(_KERNEL) && (defined(__osf__) || defined(AIX) || \ - defined(__hpux) || defined(__sgi)) -# include "radix_ipf_local.h" -# define _RADIX_H_ -#endif +#include #include #include +#if !defined(_KERNEL) +# include "ipf.h" +#endif #include "netinet/ip_compat.h" #include "netinet/ip_fil.h" #include "netinet/ip_pool.h" - -#if defined(IPFILTER_LOOKUP) && defined(_KERNEL) && \ - ((BSD >= 198911) && !defined(__osf__) && \ - !defined(__hpux) && !defined(__sgi)) -static int rn_freenode __P((struct radix_node *, void *)); -#endif +#include "netinet/radix_ipf.h" /* END OF INCLUDES */ #if !defined(lint) static const char sccsid[] = "@(#)ip_fil.c 2.41 6/5/96 (C) 1993-2000 Darren Reed"; -static const char rcsid[] = "@(#)$Id: ip_pool.c,v 2.55.2.24 2007/10/10 09:45:37 darrenr Exp $"; +static const char rcsid[] = "@(#)$Id$"; #endif -#ifdef IPFILTER_LOOKUP +typedef struct ipf_pool_softc_s { + void *ipf_radix; + ip_pool_t *ipf_pool_list[LOOKUP_POOL_SZ]; + ipf_pool_stat_t ipf_pool_stats; + ip_pool_node_t *ipf_node_explist; +} ipf_pool_softc_t; -# if !defined(RADIX_NODE_HEAD_LOCK) || !defined(RADIX_NODE_HEAD_UNLOCK) || \ - !defined(_KERNEL) -# undef RADIX_NODE_HEAD_LOCK -# undef RADIX_NODE_HEAD_UNLOCK -# define RADIX_NODE_HEAD_LOCK(x) ; -# define RADIX_NODE_HEAD_UNLOCK(x) ; -# endif -static void ip_pool_clearnodes __P((ip_pool_t *)); -static void *ip_pool_exists __P((int, char *)); +static void ipf_pool_clearnodes __P((ipf_main_softc_t *, ipf_pool_softc_t *, + ip_pool_t *)); +static int ipf_pool_create __P((ipf_main_softc_t *, ipf_pool_softc_t *, iplookupop_t *)); +static int ipf_pool_deref __P((ipf_main_softc_t *, void *, void *)); +static int ipf_pool_destroy __P((ipf_main_softc_t *, ipf_pool_softc_t *, int, char *)); +static void *ipf_pool_exists __P((ipf_pool_softc_t *, int, char *)); +static void *ipf_pool_find __P((void *, int, char *)); +static ip_pool_node_t *ipf_pool_findeq __P((ipf_pool_softc_t *, ip_pool_t *, + addrfamily_t *, addrfamily_t *)); +static void ipf_pool_free __P((ipf_main_softc_t *, ipf_pool_softc_t *, + ip_pool_t *)); +static int ipf_pool_insert_node __P((ipf_main_softc_t *, ipf_pool_softc_t *, + ip_pool_t *, struct ip_pool_node *)); +static int ipf_pool_iter_deref __P((ipf_main_softc_t *, void *, int, int, void *)); +static int ipf_pool_iter_next __P((ipf_main_softc_t *, void *, ipftoken_t *, + ipflookupiter_t *)); +static size_t ipf_pool_flush __P((ipf_main_softc_t *, void *, iplookupflush_t *)); +static int ipf_pool_node_add __P((ipf_main_softc_t *, void *, iplookupop_t *, + int)); +static int ipf_pool_node_del __P((ipf_main_softc_t *, void *, iplookupop_t *, + int)); +static void ipf_pool_node_deref __P((ipf_pool_softc_t *, ip_pool_node_t *)); +static int ipf_pool_remove_node __P((ipf_main_softc_t *, ipf_pool_softc_t *, + ip_pool_t *, ip_pool_node_t *)); +static int ipf_pool_search __P((ipf_main_softc_t *, void *, int, + void *, u_int)); +static void *ipf_pool_soft_create __P((ipf_main_softc_t *)); +static void ipf_pool_soft_destroy __P((ipf_main_softc_t *, void *)); +static void ipf_pool_soft_fini __P((ipf_main_softc_t *, void *)); +static int ipf_pool_soft_init __P((ipf_main_softc_t *, void *)); +static int ipf_pool_stats_get __P((ipf_main_softc_t *, void *, iplookupop_t *)); +static int ipf_pool_table_add __P((ipf_main_softc_t *, void *, iplookupop_t *)); +static int ipf_pool_table_del __P((ipf_main_softc_t *, void *, iplookupop_t *)); +static void *ipf_pool_select_add_ref __P((void *, int, char *)); +static void ipf_pool_expire __P((ipf_main_softc_t *, void *)); -ip_pool_stat_t ipoolstat; -ipfrwlock_t ip_poolrw; - -/* - * Binary tree routines from Sedgewick and enhanced to do ranges of addresses. - * NOTE: Insertion *MUST* be from greatest range to least for it to work! - * These should be replaced, eventually, by something else - most notably a - * interval searching method. The important feature is to be able to find - * the best match. - * - * So why not use a radix tree for this? As the first line implies, it - * has been written to work with a _range_ of addresses. A range is not - * necessarily a match with any given netmask so what we end up dealing - * with is an interval tree. Implementations of these are hard to find - * and the one herein is far from bug free. - * - * Sigh, in the end I became convinced that the bugs the code contained did - * not make it worthwhile not using radix trees. For now the radix tree from - * 4.4 BSD is used, but this is not viewed as a long term solution. - */ -ip_pool_t *ip_pool_list[IPL_LOGSIZE] = { NULL, NULL, NULL, NULL, - NULL, NULL, NULL, NULL }; +ipf_lookup_t ipf_pool_backend = { + IPLT_POOL, + ipf_pool_soft_create, + ipf_pool_soft_destroy, + ipf_pool_soft_init, + ipf_pool_soft_fini, + ipf_pool_search, + ipf_pool_flush, + ipf_pool_iter_deref, + ipf_pool_iter_next, + ipf_pool_node_add, + ipf_pool_node_del, + ipf_pool_stats_get, + ipf_pool_table_add, + ipf_pool_table_del, + ipf_pool_deref, + ipf_pool_find, + ipf_pool_select_add_ref, + NULL, + ipf_pool_expire, + NULL +}; #ifdef TEST_POOL @@ -126,96 +143,98 @@ main(argc, argv) int argc; char *argv[]; { + ip_pool_node_t node; addrfamily_t a, b; iplookupop_t op; ip_pool_t *ipo; i6addr_t ip; - RWLOCK_INIT(&ip_poolrw, "poolrw"); - ip_pool_init(); + RWLOCK_INIT(softc->ipf_poolrw, "poolrw"); + ipf_pool_init(); - bzero((char *)&a, sizeof(a)); - bzero((char *)&b, sizeof(b)); bzero((char *)&ip, sizeof(ip)); bzero((char *)&op, sizeof(op)); + bzero((char *)&node, sizeof(node)); strcpy(op.iplo_name, "0"); - if (ip_pool_create(&op) == 0) - ipo = ip_pool_exists(0, "0"); + if (ipf_pool_create(&op) == 0) + ipo = ipf_pool_exists(0, "0"); - a.adf_addr.in4.s_addr = 0x0a010203; - b.adf_addr.in4.s_addr = 0xffffffff; - ip_pool_insert(ipo, &a.adf_addr, &b.adf_addr, 1); - ip_pool_insert(ipo, &a.adf_addr, &b.adf_addr, 1); + node.ipn_addr.adf_family = AF_INET; - a.adf_addr.in4.s_addr = 0x0a000000; - b.adf_addr.in4.s_addr = 0xff000000; - ip_pool_insert(ipo, &a.adf_addr, &b.adf_addr, 0); - ip_pool_insert(ipo, &a.adf_addr, &b.adf_addr, 0); + node.ipn_addr.adf_addr.in4.s_addr = 0x0a010203; + node.ipn_mask.adf_addr.in4.s_addr = 0xffffffff; + node.ipn_info = 1; + ipf_pool_insert_node(ipo, &node); - a.adf_addr.in4.s_addr = 0x0a010100; - b.adf_addr.in4.s_addr = 0xffffff00; - ip_pool_insert(ipo, &a.adf_addr, &b.adf_addr, 1); - ip_pool_insert(ipo, &a.adf_addr, &b.adf_addr, 1); + node.ipn_addr.adf_addr.in4.s_addr = 0x0a000000; + node.ipn_mask.adf_addr.in4.s_addr = 0xff000000; + node.ipn_info = 0; + ipf_pool_insert_node(ipo, &node); - a.adf_addr.in4.s_addr = 0x0a010200; - b.adf_addr.in4.s_addr = 0xffffff00; - ip_pool_insert(ipo, &a.adf_addr, &b.adf_addr, 0); - ip_pool_insert(ipo, &a.adf_addr, &b.adf_addr, 0); + node.ipn_addr.adf_addr.in4.s_addr = 0x0a010100; + node.ipn_mask.adf_addr.in4.s_addr = 0xffffff00; + node.ipn_info = 1; + ipf_pool_insert_node(ipo, &node); - a.adf_addr.in4.s_addr = 0x0a010000; - b.adf_addr.in4.s_addr = 0xffff0000; - ip_pool_insert(ipo, &a.adf_addr, &b.adf_addr, 1); - ip_pool_insert(ipo, &a.adf_addr, &b.adf_addr, 1); + node.ipn_addr.adf_addr.in4.s_addr = 0x0a010200; + node.ipn_mask.adf_addr.in4.s_addr = 0xffffff00; + node.ipn_info = 0; + ipf_pool_insert_node(ipo, &node); - a.adf_addr.in4.s_addr = 0x0a01020f; - b.adf_addr.in4.s_addr = 0xffffffff; - ip_pool_insert(ipo, &a.adf_addr, &b.adf_addr, 1); - ip_pool_insert(ipo, &a.adf_addr, &b.adf_addr, 1); + node.ipn_addr.adf_addr.in4.s_addr = 0x0a010000; + node.ipn_mask.adf_addr.in4.s_addr = 0xffff0000; + node.ipn_info = 1; + ipf_pool_insert_node(ipo, &node); + + node.ipn_addr.adf_addr.in4.s_addr = 0x0a01020f; + node.ipn_mask.adf_addr.in4.s_addr = 0xffffffff; + node.ipn_info = 1; + ipf_pool_insert_node(ipo, &node); #ifdef DEBUG_POOL -treeprint(ipo); + treeprint(ipo); #endif ip.in4.s_addr = 0x0a00aabb; printf("search(%#x) = %d (0)\n", ip.in4.s_addr, - ip_pool_search(ipo, 4, &ip)); + ipf_pool_search(ipo, 4, &ip, 1)); ip.in4.s_addr = 0x0a000001; printf("search(%#x) = %d (0)\n", ip.in4.s_addr, - ip_pool_search(ipo, 4, &ip)); + ipf_pool_search(ipo, 4, &ip, 1)); ip.in4.s_addr = 0x0a000101; printf("search(%#x) = %d (0)\n", ip.in4.s_addr, - ip_pool_search(ipo, 4, &ip)); + ipf_pool_search(ipo, 4, &ip, 1)); ip.in4.s_addr = 0x0a010001; printf("search(%#x) = %d (1)\n", ip.in4.s_addr, - ip_pool_search(ipo, 4, &ip)); + ipf_pool_search(ipo, 4, &ip, 1)); ip.in4.s_addr = 0x0a010101; printf("search(%#x) = %d (1)\n", ip.in4.s_addr, - ip_pool_search(ipo, 4, &ip)); + ipf_pool_search(ipo, 4, &ip, 1)); ip.in4.s_addr = 0x0a010201; printf("search(%#x) = %d (0)\n", ip.in4.s_addr, - ip_pool_search(ipo, 4, &ip)); + ipf_pool_search(ipo, 4, &ip, 1)); ip.in4.s_addr = 0x0a010203; printf("search(%#x) = %d (1)\n", ip.in4.s_addr, - ip_pool_search(ipo, 4, &ip)); + ipf_pool_search(ipo, 4, &ip, 1)); ip.in4.s_addr = 0x0a01020f; printf("search(%#x) = %d (1)\n", ip.in4.s_addr, - ip_pool_search(ipo, 4, &ip)); + ipf_pool_search(ipo, 4, &ip, 1)); ip.in4.s_addr = 0x0b00aabb; printf("search(%#x) = %d (-1)\n", ip.in4.s_addr, - ip_pool_search(ipo, 4, &ip)); + ipf_pool_search(ipo, 4, &ip, 1)); #ifdef DEBUG_POOL -treeprint(ipo); + treeprint(ipo); #endif - ip_pool_fini(); + ipf_pool_fini(); return 0; } @@ -223,7 +242,7 @@ treeprint(ipo); void treeprint(ipo) -ip_pool_t *ipo; + ip_pool_t *ipo; { ip_pool_node_t *c; @@ -237,123 +256,445 @@ ip_pool_t *ipo; /* ------------------------------------------------------------------------ */ -/* Function: ip_pool_init */ -/* Returns: int - 0 = success, else error */ +/* Function: ipf_pool_soft_create */ +/* Returns: void * - NULL = failure, else pointer to local context */ +/* Parameters: softc(I) - pointer to soft context main structure */ /* */ /* Initialise the routing table data structures where required. */ /* ------------------------------------------------------------------------ */ -int ip_pool_init() +static void * +ipf_pool_soft_create(softc) + ipf_main_softc_t *softc; { + ipf_pool_softc_t *softp; - bzero((char *)&ipoolstat, sizeof(ipoolstat)); + KMALLOC(softp, ipf_pool_softc_t *); + if (softp == NULL) { + IPFERROR(70032); + return NULL; + } + + bzero((char *)softp, sizeof(*softp)); + + softp->ipf_radix = ipf_rx_create(); + if (softp->ipf_radix == NULL) { + IPFERROR(70033); + KFREE(softp); + return NULL; + } + + return softp; +} + + +/* ------------------------------------------------------------------------ */ +/* Function: ipf_pool_soft_init */ +/* Returns: int - 0 = success, else error */ +/* Parameters: softc(I) - pointer to soft context main structure */ +/* arg(I) - pointer to local context to use */ +/* */ +/* Initialise the routing table data structures where required. */ +/* ------------------------------------------------------------------------ */ +static int +ipf_pool_soft_init(softc, arg) + ipf_main_softc_t *softc; + void *arg; +{ + ipf_pool_softc_t *softp = arg; + + ipf_rx_init(softp->ipf_radix); -#if (!defined(_KERNEL) || (BSD < 199306)) - rn_init(); -#endif return 0; } /* ------------------------------------------------------------------------ */ -/* Function: ip_pool_fini */ -/* Returns: int - 0 = success, else error */ +/* Function: ipf_pool_soft_fini */ +/* Returns: Nil */ +/* Parameters: softc(I) - pointer to soft context main structure */ +/* arg(I) - pointer to local context to use */ /* Locks: WRITE(ipf_global) */ /* */ /* Clean up all the pool data structures allocated and call the cleanup */ -/* function for the radix tree that supports the pools. ip_pool_destroy() is*/ +/* function for the radix tree that supports the pools. ipf_pool_destroy is */ /* used to delete the pools one by one to ensure they're properly freed up. */ /* ------------------------------------------------------------------------ */ -void ip_pool_fini() +static void +ipf_pool_soft_fini(softc, arg) + ipf_main_softc_t *softc; + void *arg; { + ipf_pool_softc_t *softp = arg; ip_pool_t *p, *q; int i; - for (i = 0; i <= IPL_LOGMAX; i++) { - for (q = ip_pool_list[i]; (p = q) != NULL; ) { + softc = arg; + + for (i = -1; i <= IPL_LOGMAX; i++) { + for (q = softp->ipf_pool_list[i + 1]; (p = q) != NULL; ) { q = p->ipo_next; - (void) ip_pool_destroy(i, p->ipo_name); + (void) ipf_pool_destroy(softc, arg, i, p->ipo_name); } } - -#if (!defined(_KERNEL) || (BSD < 199306)) - rn_fini(); -#endif } /* ------------------------------------------------------------------------ */ -/* Function: ip_pool_statistics */ -/* Returns: int - 0 = success, else error */ -/* Parameters: op(I) - pointer to lookup operation arguments */ +/* Function: ipf_pool_soft_destroy */ +/* Returns: Nil */ +/* Parameters: softc(I) - pointer to soft context main structure */ +/* arg(I) - pointer to local context to use */ /* */ -/* Copy the current statistics out into user space, collecting pool list */ -/* pointers as appropriate for later use. */ +/* Clean up the pool by free'ing the radix tree associated with it and free */ +/* up the pool context too. */ /* ------------------------------------------------------------------------ */ -int ip_pool_statistics(op) -iplookupop_t *op; +static void +ipf_pool_soft_destroy(softc, arg) + ipf_main_softc_t *softc; + void *arg; { - ip_pool_stat_t stats; - int unit, i, err = 0; + ipf_pool_softc_t *softp = arg; - if (op->iplo_size != sizeof(ipoolstat)) + ipf_rx_destroy(softp->ipf_radix); + + KFREE(softp); +} + + +/* ------------------------------------------------------------------------ */ +/* Function: ipf_pool_node_add */ +/* Returns: int - 0 = success, else error */ +/* Parameters: softc(I) - pointer to soft context main structure */ +/* arg(I) - pointer to local context to use */ +/* op(I) - pointer to lookup operatin data */ +/* */ +/* When adding a new node, a check is made to ensure that the address/mask */ +/* pair supplied has been appropriately prepared by applying the mask to */ +/* the address prior to calling for the pair to be added. */ +/* ------------------------------------------------------------------------ */ +static int +ipf_pool_node_add(softc, arg, op, uid) + ipf_main_softc_t *softc; + void *arg; + iplookupop_t *op; + int uid; +{ + ip_pool_node_t node, *m; + ip_pool_t *p; + int err; + + if (op->iplo_size != sizeof(node)) { + IPFERROR(70014); return EINVAL; + } + + err = COPYIN(op->iplo_struct, &node, sizeof(node)); + if (err != 0) { + IPFERROR(70015); + return EFAULT; + } + + p = ipf_pool_find(arg, op->iplo_unit, op->iplo_name); + if (p == NULL) { + IPFERROR(70017); + return ESRCH; + } + + if (node.ipn_addr.adf_family == AF_INET) { + if (node.ipn_addr.adf_len != offsetof(addrfamily_t, adf_addr) + + sizeof(struct in_addr)) { + IPFERROR(70028); + return EINVAL; + } + } +#ifdef USE_INET6 + else if (node.ipn_addr.adf_family == AF_INET6) { + if (node.ipn_addr.adf_len != offsetof(addrfamily_t, adf_addr) + + sizeof(struct in6_addr)) { + IPFERROR(70034); + return EINVAL; + } + } +#endif + if (node.ipn_mask.adf_len != node.ipn_addr.adf_len) { + IPFERROR(70029); + return EINVAL; + } + + /* + * Check that the address/mask pair works. + */ + if (node.ipn_addr.adf_family == AF_INET) { + if ((node.ipn_addr.adf_addr.in4.s_addr & + node.ipn_mask.adf_addr.in4.s_addr) != + node.ipn_addr.adf_addr.in4.s_addr) { + IPFERROR(70035); + return EINVAL; + } + } +#ifdef USE_INET6 + else if (node.ipn_addr.adf_family == AF_INET6) { + if (IP6_MASKNEQ(&node.ipn_addr.adf_addr.in6, + &node.ipn_mask.adf_addr.in6, + &node.ipn_addr.adf_addr.in6)) { + IPFERROR(70036); + return EINVAL; + } + } +#endif + + /* + * add an entry to a pool - return an error if it already + * exists remove an entry from a pool - if it exists + * - in both cases, the pool *must* exist! + */ + m = ipf_pool_findeq(arg, p, &node.ipn_addr, &node.ipn_mask); + if (m != NULL) { + IPFERROR(70018); + return EEXIST; + } + err = ipf_pool_insert_node(softc, arg, p, &node); - bcopy((char *)&ipoolstat, (char *)&stats, sizeof(stats)); - unit = op->iplo_unit; - if (unit == IPL_LOGALL) { - for (i = 0; i < IPL_LOGSIZE; i++) - stats.ipls_list[i] = ip_pool_list[i]; - } else if (unit >= 0 && unit < IPL_LOGSIZE) { - if (op->iplo_name[0] != '\0') - stats.ipls_list[unit] = ip_pool_exists(unit, - op->iplo_name); - else - stats.ipls_list[unit] = ip_pool_list[unit]; - } else - err = EINVAL; - if (err == 0) - err = COPYOUT(&stats, op->iplo_struct, sizeof(stats)); return err; } /* ------------------------------------------------------------------------ */ -/* Function: ip_pool_exists */ -/* Returns: int - 0 = success, else error */ -/* Parameters: ipo(I) - pointer to the pool getting the new node. */ +/* Function: ipf_pool_node_del */ +/* Returns: int - 0 = success, else error */ +/* Parameters: softc(I) - pointer to soft context main structure */ +/* arg(I) - pointer to local context to use */ +/* op(I) - pointer to lookup operatin data */ +/* */ +/* ------------------------------------------------------------------------ */ +static int +ipf_pool_node_del(softc, arg, op, uid) + ipf_main_softc_t *softc; + void *arg; + iplookupop_t *op; + int uid; +{ + ip_pool_node_t node, *m; + ip_pool_t *p; + int err; + + + if (op->iplo_size != sizeof(node)) { + IPFERROR(70019); + return EINVAL; + } + node.ipn_uid = uid; + + err = COPYIN(op->iplo_struct, &node, sizeof(node)); + if (err != 0) { + IPFERROR(70020); + return EFAULT; + } + + if (node.ipn_addr.adf_family == AF_INET) { + if (node.ipn_addr.adf_len != offsetof(addrfamily_t, adf_addr) + + sizeof(struct in_addr)) { + IPFERROR(70030); + return EINVAL; + } + } +#ifdef USE_INET6 + else if (node.ipn_addr.adf_family == AF_INET6) { + if (node.ipn_addr.adf_len != offsetof(addrfamily_t, adf_addr) + + sizeof(struct in6_addr)) { + IPFERROR(70037); + return EINVAL; + } + } +#endif + if (node.ipn_mask.adf_len != node.ipn_addr.adf_len) { + IPFERROR(70031); + return EINVAL; + } + + p = ipf_pool_find(arg, op->iplo_unit, op->iplo_name); + if (p == NULL) { + IPFERROR(70021); + return ESRCH; + } + + m = ipf_pool_findeq(arg, p, &node.ipn_addr, &node.ipn_mask); + if (m == NULL) { + IPFERROR(70022); + return ENOENT; + } + + if ((uid != 0) && (uid != m->ipn_uid)) { + IPFERROR(70024); + return EACCES; + } + + err = ipf_pool_remove_node(softc, arg, p, m); + + return err; +} + + +/* ------------------------------------------------------------------------ */ +/* Function: ipf_pool_table_add */ +/* Returns: int - 0 = success, else error */ +/* Parameters: softc(I) - pointer to soft context main structure */ +/* arg(I) - pointer to local context to use */ +/* op(I) - pointer to lookup operatin data */ +/* */ +/* ------------------------------------------------------------------------ */ +static int +ipf_pool_table_add(softc, arg, op) + ipf_main_softc_t *softc; + void *arg; + iplookupop_t *op; +{ + int err; + + if (((op->iplo_arg & LOOKUP_ANON) == 0) && + (ipf_pool_find(arg, op->iplo_unit, op->iplo_name) != NULL)) { + IPFERROR(70023); + err = EEXIST; + } else { + err = ipf_pool_create(softc, arg, op); + } + + return err; +} + + +/* ------------------------------------------------------------------------ */ +/* Function: ipf_pool_table_del */ +/* Returns: int - 0 = success, else error */ +/* Parameters: softc(I) - pointer to soft context main structure */ +/* arg(I) - pointer to local context to use */ +/* op(I) - pointer to lookup operatin data */ +/* */ +/* ------------------------------------------------------------------------ */ +static int +ipf_pool_table_del(softc, arg, op) + ipf_main_softc_t *softc; + void *arg; + iplookupop_t *op; +{ + return ipf_pool_destroy(softc, arg, op->iplo_unit, op->iplo_name); +} + + +/* ------------------------------------------------------------------------ */ +/* Function: ipf_pool_statistics */ +/* Returns: int - 0 = success, else error */ +/* Parameters: softc(I) - pointer to soft context main structure */ +/* arg(I) - pointer to local context to use */ +/* op(I) - pointer to lookup operatin data */ +/* */ +/* Copy the current statistics out into user space, collecting pool list */ +/* pointers as appropriate for later use. */ +/* ------------------------------------------------------------------------ */ +static int +ipf_pool_stats_get(softc, arg, op) + ipf_main_softc_t *softc; + void *arg; + iplookupop_t *op; +{ + ipf_pool_softc_t *softp = arg; + ipf_pool_stat_t stats; + int unit, i, err = 0; + + if (op->iplo_size != sizeof(ipf_pool_stat_t)) { + IPFERROR(70001); + return EINVAL; + } + + bcopy((char *)&softp->ipf_pool_stats, (char *)&stats, sizeof(stats)); + unit = op->iplo_unit; + if (unit == IPL_LOGALL) { + for (i = 0; i <= LOOKUP_POOL_MAX; i++) + stats.ipls_list[i] = softp->ipf_pool_list[i]; + } else if (unit >= 0 && unit <= IPL_LOGMAX) { + unit++; /* -1 => 0 */ + if (op->iplo_name[0] != '\0') + stats.ipls_list[unit] = ipf_pool_exists(softp, unit - 1, + op->iplo_name); + else + stats.ipls_list[unit] = softp->ipf_pool_list[unit]; + } else { + IPFERROR(70025); + err = EINVAL; + } + if (err == 0) { + err = COPYOUT(&stats, op->iplo_struct, sizeof(stats)); + if (err != 0) { + IPFERROR(70026); + return EFAULT; + } + } + return 0; +} + + +/* ------------------------------------------------------------------------ */ +/* Function: ipf_pool_exists */ +/* Returns: int - 0 = success, else error */ +/* Parameters: softp(I) - pointer to soft context pool information */ +/* unit(I) - ipfilter device to which we are working on */ +/* name(I) - name of the pool */ /* */ /* Find a matching pool inside the collection of pools for a particular */ /* device, indicated by the unit number. */ /* ------------------------------------------------------------------------ */ -static void *ip_pool_exists(unit, name) -int unit; -char *name; +static void * +ipf_pool_exists(softp, unit, name) + ipf_pool_softc_t *softp; + int unit; + char *name; { ip_pool_t *p; + int i; - for (p = ip_pool_list[unit]; p != NULL; p = p->ipo_next) - if (strncmp(p->ipo_name, name, sizeof(p->ipo_name)) == 0) - break; + if (unit == IPL_LOGALL) { + for (i = 0; i <= LOOKUP_POOL_MAX; i++) { + for (p = softp->ipf_pool_list[i]; p != NULL; + p = p->ipo_next) { + if (strncmp(p->ipo_name, name, + sizeof(p->ipo_name)) == 0) + break; + } + if (p != NULL) + break; + } + } else { + for (p = softp->ipf_pool_list[unit + 1]; p != NULL; + p = p->ipo_next) + if (strncmp(p->ipo_name, name, + sizeof(p->ipo_name)) == 0) + break; + } return p; } /* ------------------------------------------------------------------------ */ -/* Function: ip_pool_find */ -/* Returns: int - 0 = success, else error */ -/* Parameters: ipo(I) - pointer to the pool getting the new node. */ +/* Function: ipf_pool_find */ +/* Returns: int - 0 = success, else error */ +/* Parameters: arg(I) - pointer to local context to use */ +/* unit(I) - ipfilter device to which we are working on */ +/* name(I) - name of the pool */ /* */ /* Find a matching pool inside the collection of pools for a particular */ /* device, indicated by the unit number. If it is marked for deletion then */ /* pretend it does not exist. */ /* ------------------------------------------------------------------------ */ -void *ip_pool_find(unit, name) -int unit; -char *name; +static void * +ipf_pool_find(arg, unit, name) + void *arg; + int unit; + char *name; { + ipf_pool_softc_t *softp = arg; ip_pool_t *p; - p = ip_pool_exists(unit, name); + p = ipf_pool_exists(softp, unit, name); if ((p != NULL) && (p->ipo_flags & IPOOL_DELETE)) return NULL; @@ -362,45 +703,75 @@ char *name; /* ------------------------------------------------------------------------ */ -/* Function: ip_pool_findeq */ +/* Function: ipf_pool_select_add_ref */ +/* Returns: int - 0 = success, else error */ +/* Parameters: arg(I) - pointer to local context to use */ +/* unit(I) - ipfilter device to which we are working on */ +/* name(I) - name of the pool */ +/* */ +/* ------------------------------------------------------------------------ */ +static void * +ipf_pool_select_add_ref(arg, unit, name) + void *arg; + int unit; + char *name; +{ + ip_pool_t *p; + + p = ipf_pool_find(arg, -1, name); + if (p == NULL) + p = ipf_pool_find(arg, unit, name); + if (p != NULL) { + ATOMIC_INC32(p->ipo_ref); + } + return p; +} + + +/* ------------------------------------------------------------------------ */ +/* Function: ipf_pool_findeq */ /* Returns: int - 0 = success, else error */ -/* Parameters: ipo(I) - pointer to the pool getting the new node. */ -/* addr(I) - pointer to address information to delete */ -/* mask(I) - */ +/* Parameters: softp(I) - pointer to soft context pool information */ +/* ipo(I) - pointer to the pool getting the new node. */ +/* addr(I) - pointer to address information to match on */ +/* mask(I) - pointer to the address mask to match */ /* */ /* Searches for an exact match of an entry in the pool. */ /* ------------------------------------------------------------------------ */ -ip_pool_node_t *ip_pool_findeq(ipo, addr, mask) -ip_pool_t *ipo; -addrfamily_t *addr, *mask; +extern void printhostmask __P((int, u_32_t *, u_32_t *)); +static ip_pool_node_t * +ipf_pool_findeq(softp, ipo, addr, mask) + ipf_pool_softc_t *softp; + ip_pool_t *ipo; + addrfamily_t *addr, *mask; { - struct radix_node *n; - SPL_INT(s); + ipf_rdx_node_t *n; - SPL_NET(s); - RADIX_NODE_HEAD_LOCK(ipo->ipo_head); - n = ipo->ipo_head->rnh_lookup(addr, mask, ipo->ipo_head); - RADIX_NODE_HEAD_UNLOCK(ipo->ipo_head); - SPL_X(s); + n = ipo->ipo_head->lookup(ipo->ipo_head, addr, mask); return (ip_pool_node_t *)n; } /* ------------------------------------------------------------------------ */ -/* Function: ip_pool_search */ +/* Function: ipf_pool_search */ /* Returns: int - 0 == +ve match, -1 == error, 1 == -ve/no match */ -/* Parameters: tptr(I) - pointer to the pool to search */ +/* Parameters: softc(I) - pointer to soft context main structure */ +/* tptr(I) - pointer to the pool to search */ /* version(I) - IP protocol version (4 or 6) */ /* dptr(I) - pointer to address information */ +/* bytes(I) - length of packet */ /* */ /* Search the pool for a given address and return a search result. */ /* ------------------------------------------------------------------------ */ -int ip_pool_search(tptr, ipversion, dptr) -void *tptr; -int ipversion; -void *dptr; +static int +ipf_pool_search(softc, tptr, ipversion, dptr, bytes) + ipf_main_softc_t *softc; + void *tptr; + int ipversion; + void *dptr; + u_int bytes; { - struct radix_node *rn; + ipf_rdx_node_t *rn; ip_pool_node_t *m; i6addr_t *addr; addrfamily_t v; @@ -415,102 +786,154 @@ void *dptr; m = NULL; addr = (i6addr_t *)dptr; bzero(&v, sizeof(v)); - v.adf_len = offsetof(addrfamily_t, adf_addr); if (ipversion == 4) { - v.adf_len += sizeof(addr->in4); + v.adf_family = AF_INET; + v.adf_len = offsetof(addrfamily_t, adf_addr) + + sizeof(struct in_addr); v.adf_addr.in4 = addr->in4; #ifdef USE_INET6 } else if (ipversion == 6) { - v.adf_len += sizeof(addr->in6); + v.adf_family = AF_INET6; + v.adf_len = offsetof(addrfamily_t, adf_addr) + + sizeof(struct in6_addr); v.adf_addr.in6 = addr->in6; #endif } else return -1; - READ_ENTER(&ip_poolrw); + READ_ENTER(&softc->ipf_poolrw); - RADIX_NODE_HEAD_LOCK(ipo->ipo_head); - rn = ipo->ipo_head->rnh_matchaddr(&v, ipo->ipo_head); - RADIX_NODE_HEAD_UNLOCK(ipo->ipo_head); + rn = ipo->ipo_head->matchaddr(ipo->ipo_head, &v); - if ((rn != NULL) && ((rn->rn_flags & RNF_ROOT) == 0)) { + if ((rn != NULL) && (rn->root == 0)) { m = (ip_pool_node_t *)rn; ipo->ipo_hits++; + m->ipn_bytes += bytes; m->ipn_hits++; rv = m->ipn_info; } - RWLOCK_EXIT(&ip_poolrw); + RWLOCK_EXIT(&softc->ipf_poolrw); return rv; } /* ------------------------------------------------------------------------ */ -/* Function: ip_pool_insert */ -/* Returns: int - 0 = success, else error */ -/* Parameters: ipo(I) - pointer to the pool getting the new node. */ -/* addr(I) - address being added as a node */ -/* mask(I) - netmask to with the node being added */ -/* info(I) - extra information to store in this node. */ -/* Locks: WRITE(ip_poolrw) */ +/* Function: ipf_pool_insert_node */ +/* Returns: int - 0 = success, else error */ +/* Parameters: softc(I) - pointer to soft context main structure */ +/* softp(I) - pointer to soft context pool information */ +/* ipo(I) - pointer to the pool getting the new node. */ +/* node(I) - structure with address/mask to add */ +/* Locks: WRITE(ipf_poolrw) */ /* */ /* Add another node to the pool given by ipo. The three parameters passed */ /* in (addr, mask, info) shold all be stored in the node. */ /* ------------------------------------------------------------------------ */ -int ip_pool_insert(ipo, addr, mask, info) -ip_pool_t *ipo; -i6addr_t *addr, *mask; -int info; +static int +ipf_pool_insert_node(softc, softp, ipo, node) + ipf_main_softc_t *softc; + ipf_pool_softc_t *softp; + ip_pool_t *ipo; + struct ip_pool_node *node; { - struct radix_node *rn; + ipf_rdx_node_t *rn; ip_pool_node_t *x; + if ((node->ipn_addr.adf_len > sizeof(*rn)) || + (node->ipn_addr.adf_len < 4)) { + IPFERROR(70003); + return EINVAL; + } + + if ((node->ipn_mask.adf_len > sizeof(*rn)) || + (node->ipn_mask.adf_len < 4)) { + IPFERROR(70004); + return EINVAL; + } + KMALLOC(x, ip_pool_node_t *); if (x == NULL) { + IPFERROR(70002); return ENOMEM; } - bzero(x, sizeof(*x)); + *x = *node; + bzero((char *)x->ipn_nodes, sizeof(x->ipn_nodes)); + x->ipn_owner = ipo; + x->ipn_hits = 0; + x->ipn_next = NULL; + x->ipn_pnext = NULL; + x->ipn_dnext = NULL; + x->ipn_pdnext = NULL; - x->ipn_info = info; - (void)strncpy(x->ipn_name, ipo->ipo_name, sizeof(x->ipn_name)); + if (x->ipn_die != 0) { + /* + * If the new node has a given expiration time, insert it + * into the list of expiring nodes with the ones to be + * removed first added to the front of the list. The + * insertion is O(n) but it is kept sorted for quick scans + * at expiration interval checks. + */ + ip_pool_node_t *n; - bcopy(addr, &x->ipn_addr.adf_addr, sizeof(*addr)); - x->ipn_addr.adf_len = sizeof(x->ipn_addr); - bcopy(mask, &x->ipn_mask.adf_addr, sizeof(*mask)); - x->ipn_mask.adf_len = sizeof(x->ipn_mask); + x->ipn_die = softc->ipf_ticks + IPF_TTLVAL(x->ipn_die); + for (n = softp->ipf_node_explist; n != NULL; n = n->ipn_dnext) { + if (x->ipn_die < n->ipn_die) + break; + if (n->ipn_dnext == NULL) { + /* + * We've got to the last node and everything + * wanted to be expired before this new node, + * so we have to tack it on the end... + */ + n->ipn_dnext = x; + x->ipn_pdnext = &n->ipn_dnext; + n = NULL; + break; + } + } - RADIX_NODE_HEAD_LOCK(ipo->ipo_head); - rn = ipo->ipo_head->rnh_addaddr(&x->ipn_addr, &x->ipn_mask, - ipo->ipo_head, x->ipn_nodes); - RADIX_NODE_HEAD_UNLOCK(ipo->ipo_head); + if (softp->ipf_node_explist == NULL) { + softp->ipf_node_explist = x; + x->ipn_pdnext = &softp->ipf_node_explist; + } else if (n != NULL) { + x->ipn_dnext = n; + x->ipn_pdnext = n->ipn_pdnext; + n->ipn_pdnext = &x->ipn_dnext; + } + } + + rn = ipo->ipo_head->addaddr(ipo->ipo_head, &x->ipn_addr, &x->ipn_mask, + x->ipn_nodes); #ifdef DEBUG_POOL printf("Added %p at %p\n", x, rn); #endif if (rn == NULL) { KFREE(x); + IPFERROR(70005); return ENOMEM; } x->ipn_ref = 1; - x->ipn_next = ipo->ipo_list; - x->ipn_pnext = &ipo->ipo_list; - if (ipo->ipo_list != NULL) - ipo->ipo_list->ipn_pnext = &x->ipn_next; - ipo->ipo_list = x; + x->ipn_pnext = ipo->ipo_tail; + *ipo->ipo_tail = x; + ipo->ipo_tail = &x->ipn_next; - ipoolstat.ipls_nodes++; + softp->ipf_pool_stats.ipls_nodes++; return 0; } /* ------------------------------------------------------------------------ */ -/* Function: ip_pool_create */ -/* Returns: int - 0 = success, else error */ -/* Parameters: op(I) - pointer to iplookup struct with call details */ -/* Locks: WRITE(ip_poolrw) */ +/* Function: ipf_pool_create */ +/* Returns: int - 0 = success, else error */ +/* Parameters: softc(I) - pointer to soft context main structure */ +/* softp(I) - pointer to soft context pool information */ +/* op(I) - pointer to iplookup struct with call details */ +/* Locks: WRITE(ipf_poolrw) */ /* */ /* Creates a new group according to the paramters passed in via the */ /* iplookupop structure. Does not check to see if the group already exists */ @@ -522,8 +945,11 @@ int info; /* as this likely means we've tried to free a pool that is in use (flush) */ /* and now want to repopulate it with "new" data. */ /* ------------------------------------------------------------------------ */ -int ip_pool_create(op) -iplookupop_t *op; +static int +ipf_pool_create(softc, softp, op) + ipf_main_softc_t *softc; + ipf_pool_softc_t *softp; + iplookupop_t *op; { char name[FR_GROUPLEN]; int poolnum, unit; @@ -532,23 +958,27 @@ iplookupop_t *op; unit = op->iplo_unit; if ((op->iplo_arg & LOOKUP_ANON) == 0) { - h = ip_pool_exists(unit, op->iplo_name); + h = ipf_pool_exists(softp, unit, op->iplo_name); if (h != NULL) { - if ((h->ipo_flags & IPOOL_DELETE) == 0) + if ((h->ipo_flags & IPOOL_DELETE) == 0) { + IPFERROR(70006); return EEXIST; + } h->ipo_flags &= ~IPOOL_DELETE; return 0; } } KMALLOC(h, ip_pool_t *); - if (h == NULL) + if (h == NULL) { + IPFERROR(70007); return ENOMEM; + } bzero(h, sizeof(*h)); - if (rn_inithead((void **)&h->ipo_head, - offsetof(addrfamily_t, adf_addr) << 3) == 0) { + if (ipf_rx_inithead(softp->ipf_radix, &h->ipo_head) != 0) { KFREE(h); + IPFERROR(70008); return ENOMEM; } @@ -564,7 +994,7 @@ iplookupop_t *op; (void)sprintf(name, "%x", poolnum); #endif - for (p = ip_pool_list[unit]; p != NULL; ) { + for (p = softp->ipf_pool_list[unit + 1]; p != NULL; ) { if (strncmp(name, p->ipo_name, sizeof(p->ipo_name)) == 0) { poolnum++; @@ -573,7 +1003,7 @@ iplookupop_t *op; #else (void)sprintf(name, "%x", poolnum); #endif - p = ip_pool_list[unit]; + p = softp->ipf_pool_list[unit + 1]; } else p = p->ipo_next; } @@ -584,121 +1014,144 @@ iplookupop_t *op; (void)strncpy(h->ipo_name, op->iplo_name, sizeof(h->ipo_name)); } + h->ipo_radix = softp->ipf_radix; h->ipo_ref = 1; h->ipo_list = NULL; + h->ipo_tail = &h->ipo_list; h->ipo_unit = unit; - h->ipo_next = ip_pool_list[unit]; - if (ip_pool_list[unit] != NULL) - ip_pool_list[unit]->ipo_pnext = &h->ipo_next; - h->ipo_pnext = &ip_pool_list[unit]; - ip_pool_list[unit] = h; + h->ipo_next = softp->ipf_pool_list[unit + 1]; + if (softp->ipf_pool_list[unit + 1] != NULL) + softp->ipf_pool_list[unit + 1]->ipo_pnext = &h->ipo_next; + h->ipo_pnext = &softp->ipf_pool_list[unit + 1]; + softp->ipf_pool_list[unit + 1] = h; - ipoolstat.ipls_pools++; + softp->ipf_pool_stats.ipls_pools++; return 0; } /* ------------------------------------------------------------------------ */ -/* Function: ip_pool_remove */ -/* Returns: int - 0 = success, else error */ -/* Parameters: ipo(I) - pointer to the pool to remove the node from. */ -/* ipe(I) - address being deleted as a node */ -/* Locks: WRITE(ip_poolrw) */ +/* Function: ipf_pool_remove_node */ +/* Returns: int - 0 = success, else error */ +/* Parameters: softc(I) - pointer to soft context main structure */ +/* ipo(I) - pointer to the pool to remove the node from. */ +/* ipe(I) - address being deleted as a node */ +/* Locks: WRITE(ipf_poolrw) */ /* */ /* Remove a node from the pool given by ipo. */ /* ------------------------------------------------------------------------ */ -int ip_pool_remove(ipo, ipe) -ip_pool_t *ipo; -ip_pool_node_t *ipe; +static int +ipf_pool_remove_node(softc, softp, ipo, ipe) + ipf_main_softc_t *softc; + ipf_pool_softc_t *softp; + ip_pool_t *ipo; + ip_pool_node_t *ipe; { + void *ptr; + + if (ipo->ipo_tail == &ipe->ipn_next) + ipo->ipo_tail = ipe->ipn_pnext; if (ipe->ipn_pnext != NULL) *ipe->ipn_pnext = ipe->ipn_next; if (ipe->ipn_next != NULL) ipe->ipn_next->ipn_pnext = ipe->ipn_pnext; - RADIX_NODE_HEAD_LOCK(ipo->ipo_head); - ipo->ipo_head->rnh_deladdr(&ipe->ipn_addr, &ipe->ipn_mask, - ipo->ipo_head); - RADIX_NODE_HEAD_UNLOCK(ipo->ipo_head); + if (ipe->ipn_pdnext != NULL) + *ipe->ipn_pdnext = ipe->ipn_dnext; + if (ipe->ipn_dnext != NULL) + ipe->ipn_dnext->ipn_pdnext = ipe->ipn_pdnext; - ip_pool_node_deref(ipe); + ptr = ipo->ipo_head->deladdr(ipo->ipo_head, &ipe->ipn_addr, + &ipe->ipn_mask); - return 0; + if (ptr != NULL) { + ipf_pool_node_deref(softp, ipe); + return 0; + } + IPFERROR(70027); + return ESRCH; } /* ------------------------------------------------------------------------ */ -/* Function: ip_pool_destroy */ +/* Function: ipf_pool_destroy */ /* Returns: int - 0 = success, else error */ -/* Parameters: op(I) - information about the pool to remove */ -/* Locks: WRITE(ip_poolrw) or WRITE(ipf_global) */ +/* Parameters: softc(I) - pointer to soft context main structure */ +/* softp(I) - pointer to soft context pool information */ +/* unit(I) - ipfilter device to which we are working on */ +/* name(I) - name of the pool */ +/* Locks: WRITE(ipf_poolrw) or WRITE(ipf_global) */ /* */ /* Search for a pool using paramters passed in and if it's not otherwise */ /* busy, free it. If it is busy, clear all of its nodes, mark it for being */ /* deleted and return an error saying it is busy. */ /* */ -/* NOTE: Because this function is called out of ipfdetach() where ip_poolrw */ +/* NOTE: Because this function is called out of ipfdetach() where ipf_poolrw*/ /* may not be initialised, we can't use an ASSERT to enforce the locking */ -/* assertion that one of the two (ip_poolrw,ipf_global) is held. */ +/* assertion that one of the two (ipf_poolrw,ipf_global) is held. */ /* ------------------------------------------------------------------------ */ -int ip_pool_destroy(unit, name) -int unit; -char *name; +static int +ipf_pool_destroy(softc, softp, unit, name) + ipf_main_softc_t *softc; + ipf_pool_softc_t *softp; + int unit; + char *name; { ip_pool_t *ipo; - ipo = ip_pool_exists(unit, name); - if (ipo == NULL) + ipo = ipf_pool_exists(softp, unit, name); + if (ipo == NULL) { + IPFERROR(70009); return ESRCH; + } if (ipo->ipo_ref != 1) { - ip_pool_clearnodes(ipo); + ipf_pool_clearnodes(softc, softp, ipo); ipo->ipo_flags |= IPOOL_DELETE; return 0; } - ip_pool_free(ipo); + ipf_pool_free(softc, softp, ipo); return 0; } /* ------------------------------------------------------------------------ */ -/* Function: ip_pool_flush */ +/* Function: ipf_pool_flush */ /* Returns: int - number of pools deleted */ -/* Parameters: fp(I) - which pool(s) to flush */ -/* Locks: WRITE(ip_poolrw) or WRITE(ipf_global) */ +/* Parameters: softc(I) - pointer to soft context main structure */ +/* arg(I) - pointer to local context to use */ +/* fp(I) - which pool(s) to flush */ +/* Locks: WRITE(ipf_poolrw) or WRITE(ipf_global) */ /* */ /* Free all pools associated with the device that matches the unit number */ /* passed in with operation. */ /* */ -/* NOTE: Because this function is called out of ipfdetach() where ip_poolrw */ +/* NOTE: Because this function is called out of ipfdetach() where ipf_poolrw*/ /* may not be initialised, we can't use an ASSERT to enforce the locking */ -/* assertion that one of the two (ip_poolrw,ipf_global) is held. */ +/* assertion that one of the two (ipf_poolrw,ipf_global) is held. */ /* ------------------------------------------------------------------------ */ -int ip_pool_flush(fp) -iplookupflush_t *fp; +static size_t +ipf_pool_flush(softc, arg, fp) + ipf_main_softc_t *softc; + void *arg; + iplookupflush_t *fp; { + ipf_pool_softc_t *softp = arg; int i, num = 0, unit, err; ip_pool_t *p, *q; - iplookupop_t op; unit = fp->iplf_unit; - - for (i = 0; i <= IPL_LOGMAX; i++) { + for (i = -1; i <= IPL_LOGMAX; i++) { if (unit != IPLT_ALL && i != unit) continue; - for (q = ip_pool_list[i]; (p = q) != NULL; ) { - op.iplo_unit = i; - (void)strncpy(op.iplo_name, p->ipo_name, - sizeof(op.iplo_name)); + for (q = softp->ipf_pool_list[i + 1]; (p = q) != NULL; ) { q = p->ipo_next; - err = ip_pool_destroy(op.iplo_unit, op.iplo_name); + err = ipf_pool_destroy(softc, softp, i, p->ipo_name); if (err == 0) num++; - else - break; } } return num; @@ -706,125 +1159,140 @@ iplookupflush_t *fp; /* ------------------------------------------------------------------------ */ -/* Function: ip_pool_free */ +/* Function: ipf_pool_free */ /* Returns: void */ -/* Parameters: ipo(I) - pointer to pool structure */ -/* Locks: WRITE(ip_poolrw) or WRITE(ipf_global) */ +/* Parameters: softc(I) - pointer to soft context main structure */ +/* softp(I) - pointer to soft context pool information */ +/* ipo(I) - pointer to pool structure */ +/* Locks: WRITE(ipf_poolrw) or WRITE(ipf_global) */ /* */ /* Deletes the pool strucutre passed in from the list of pools and deletes */ /* all of the address information stored in it, including any tree data */ /* structures also allocated. */ /* */ -/* NOTE: Because this function is called out of ipfdetach() where ip_poolrw */ +/* NOTE: Because this function is called out of ipfdetach() where ipf_poolrw*/ /* may not be initialised, we can't use an ASSERT to enforce the locking */ -/* assertion that one of the two (ip_poolrw,ipf_global) is held. */ +/* assertion that one of the two (ipf_poolrw,ipf_global) is held. */ /* ------------------------------------------------------------------------ */ -void ip_pool_free(ipo) -ip_pool_t *ipo; +static void +ipf_pool_free(softc, softp, ipo) + ipf_main_softc_t *softc; + ipf_pool_softc_t *softp; + ip_pool_t *ipo; { - ip_pool_clearnodes(ipo); + ipf_pool_clearnodes(softc, softp, ipo); if (ipo->ipo_next != NULL) ipo->ipo_next->ipo_pnext = ipo->ipo_pnext; *ipo->ipo_pnext = ipo->ipo_next; - rn_freehead(ipo->ipo_head); + ipf_rx_freehead(ipo->ipo_head); KFREE(ipo); - ipoolstat.ipls_pools--; + softp->ipf_pool_stats.ipls_pools--; } /* ------------------------------------------------------------------------ */ -/* Function: ip_pool_clearnodes */ +/* Function: ipf_pool_clearnodes */ /* Returns: void */ -/* Parameters: ipo(I) - pointer to pool structure */ -/* Locks: WRITE(ip_poolrw) or WRITE(ipf_global) */ +/* Parameters: softc(I) - pointer to soft context main structure */ +/* softp(I) - pointer to soft context pool information */ +/* ipo(I) - pointer to pool structure */ +/* Locks: WRITE(ipf_poolrw) or WRITE(ipf_global) */ /* */ /* Deletes all nodes stored in a pool structure. */ /* ------------------------------------------------------------------------ */ -static void ip_pool_clearnodes(ipo) -ip_pool_t *ipo; +static void +ipf_pool_clearnodes(softc, softp, ipo) + ipf_main_softc_t *softc; + ipf_pool_softc_t *softp; + ip_pool_t *ipo; { - ip_pool_node_t *n; + ip_pool_node_t *n, **next; - RADIX_NODE_HEAD_LOCK(ipo->ipo_head); - while ((n = ipo->ipo_list) != NULL) { - ipo->ipo_head->rnh_deladdr(&n->ipn_addr, &n->ipn_mask, - ipo->ipo_head); - - *n->ipn_pnext = n->ipn_next; - if (n->ipn_next) - n->ipn_next->ipn_pnext = n->ipn_pnext; - - KFREE(n); - - ipoolstat.ipls_nodes--; - } - RADIX_NODE_HEAD_UNLOCK(ipo->ipo_head); + for (next = &ipo->ipo_list; (n = *next) != NULL; ) + ipf_pool_remove_node(softc, softp, ipo, n); ipo->ipo_list = NULL; } /* ------------------------------------------------------------------------ */ -/* Function: ip_pool_deref */ +/* Function: ipf_pool_deref */ /* Returns: void */ -/* Parameters: ipo(I) - pointer to pool structure */ -/* Locks: WRITE(ip_poolrw) */ +/* Parameters: softc(I) - pointer to soft context main structure */ +/* arg(I) - pointer to local context to use */ +/* pool(I) - pointer to pool structure */ +/* Locks: WRITE(ipf_poolrw) */ /* */ /* Drop the number of known references to this pool structure by one and if */ /* we arrive at zero known references, free it. */ /* ------------------------------------------------------------------------ */ -void ip_pool_deref(ipo) -ip_pool_t *ipo; +static int +ipf_pool_deref(softc, arg, pool) + ipf_main_softc_t *softc; + void *arg, *pool; { + ip_pool_t *ipo = pool; ipo->ipo_ref--; if (ipo->ipo_ref == 0) - ip_pool_free(ipo); + ipf_pool_free(softc, arg, ipo); else if ((ipo->ipo_ref == 1) && (ipo->ipo_flags & IPOOL_DELETE)) - ip_pool_destroy(ipo->ipo_unit, ipo->ipo_name); + ipf_pool_destroy(softc, arg, ipo->ipo_unit, ipo->ipo_name); + + return 0; } /* ------------------------------------------------------------------------ */ -/* Function: ip_pool_node_deref */ +/* Function: ipf_pool_node_deref */ /* Returns: void */ -/* Parameters: ipn(I) - pointer to pool structure */ -/* Locks: WRITE(ip_poolrw) */ +/* Parameters: softp(I) - pointer to soft context pool information */ +/* ipn(I) - pointer to pool structure */ +/* Locks: WRITE(ipf_poolrw) */ /* */ /* Drop a reference to the pool node passed in and if we're the last, free */ /* it all up and adjust the stats accordingly. */ /* ------------------------------------------------------------------------ */ -void ip_pool_node_deref(ipn) -ip_pool_node_t *ipn; +static void +ipf_pool_node_deref(softp, ipn) + ipf_pool_softc_t *softp; + ip_pool_node_t *ipn; { ipn->ipn_ref--; if (ipn->ipn_ref == 0) { KFREE(ipn); - ipoolstat.ipls_nodes--; + softp->ipf_pool_stats.ipls_nodes--; } } /* ------------------------------------------------------------------------ */ -/* Function: ip_pool_getnext */ +/* Function: ipf_pool_iter_next */ /* Returns: void */ -/* Parameters: token(I) - pointer to pool structure */ -/* Parameters: ilp(IO) - pointer to pool iterating structure */ +/* Parameters: softc(I) - pointer to soft context main structure */ +/* arg(I) - pointer to local context to use */ +/* token(I) - pointer to pool structure */ +/* ilp(IO) - pointer to pool iterating structure */ /* */ /* ------------------------------------------------------------------------ */ -int ip_pool_getnext(token, ilp) -ipftoken_t *token; -ipflookupiter_t *ilp; +static int +ipf_pool_iter_next(softc, arg, token, ilp) + ipf_main_softc_t *softc; + void *arg; + ipftoken_t *token; + ipflookupiter_t *ilp; { + ipf_pool_softc_t *softp = arg; ip_pool_node_t *node, zn, *nextnode; ip_pool_t *ipo, zp, *nextipo; + void *pnext; int err; err = 0; @@ -833,35 +1301,38 @@ ipflookupiter_t *ilp; ipo = NULL; nextipo = NULL; - READ_ENTER(&ip_poolrw); + READ_ENTER(&softc->ipf_poolrw); switch (ilp->ili_otype) { case IPFLOOKUPITER_LIST : ipo = token->ipt_data; if (ipo == NULL) { - nextipo = ip_pool_list[(int)ilp->ili_unit]; + nextipo = softp->ipf_pool_list[(int)ilp->ili_unit + 1]; } else { nextipo = ipo->ipo_next; } if (nextipo != NULL) { - ATOMIC_INC(nextipo->ipo_ref); + ATOMIC_INC32(nextipo->ipo_ref); token->ipt_data = nextipo; } else { bzero((char *)&zp, sizeof(zp)); nextipo = &zp; token->ipt_data = NULL; } + pnext = nextipo->ipo_next; break; case IPFLOOKUPITER_NODE : node = token->ipt_data; if (node == NULL) { - ipo = ip_pool_exists(ilp->ili_unit, ilp->ili_name); - if (ipo == NULL) + ipo = ipf_pool_exists(arg, ilp->ili_unit, + ilp->ili_name); + if (ipo == NULL) { + IPFERROR(70010); err = ESRCH; - else { + } else { nextnode = ipo->ipo_list; ipo = NULL; } @@ -870,123 +1341,149 @@ ipflookupiter_t *ilp; } if (nextnode != NULL) { - ATOMIC_INC(nextnode->ipn_ref); + ATOMIC_INC32(nextnode->ipn_ref); token->ipt_data = nextnode; } else { bzero((char *)&zn, sizeof(zn)); nextnode = &zn; token->ipt_data = NULL; } + pnext = nextnode->ipn_next; break; + default : + IPFERROR(70011); + pnext = NULL; err = EINVAL; break; } - RWLOCK_EXIT(&ip_poolrw); - + RWLOCK_EXIT(&softc->ipf_poolrw); if (err != 0) return err; switch (ilp->ili_otype) { case IPFLOOKUPITER_LIST : - if (ipo != NULL) { - WRITE_ENTER(&ip_poolrw); - ip_pool_deref(ipo); - RWLOCK_EXIT(&ip_poolrw); - } err = COPYOUT(nextipo, ilp->ili_data, sizeof(*nextipo)); - if (err != 0) + if (err != 0) { + IPFERROR(70012); err = EFAULT; + } + if (ipo != NULL) { + WRITE_ENTER(&softc->ipf_poolrw); + ipf_pool_deref(softc, softp, ipo); + RWLOCK_EXIT(&softc->ipf_poolrw); + } break; case IPFLOOKUPITER_NODE : - if (node != NULL) { - WRITE_ENTER(&ip_poolrw); - ip_pool_node_deref(node); - RWLOCK_EXIT(&ip_poolrw); - } err = COPYOUT(nextnode, ilp->ili_data, sizeof(*nextnode)); - if (err != 0) + if (err != 0) { + IPFERROR(70013); err = EFAULT; + } + if (node != NULL) { + WRITE_ENTER(&softc->ipf_poolrw); + ipf_pool_node_deref(softp, node); + RWLOCK_EXIT(&softc->ipf_poolrw); + } break; } + if (pnext == NULL) + ipf_token_mark_complete(token); return err; } /* ------------------------------------------------------------------------ */ -/* Function: ip_pool_iterderef */ +/* Function: ipf_pool_iterderef */ /* Returns: void */ -/* Parameters: ipn(I) - pointer to pool structure */ -/* Locks: WRITE(ip_poolrw) */ +/* Parameters: softc(I) - pointer to soft context main structure */ +/* arg(I) - pointer to local context to use */ +/* unit(I) - ipfilter device to which we are working on */ +/* Locks: WRITE(ipf_poolrw) */ /* */ /* ------------------------------------------------------------------------ */ -void ip_pool_iterderef(otype, unit, data) -u_int otype; -int unit; -void *data; +static int +ipf_pool_iter_deref(softc, arg, otype, unit, data) + ipf_main_softc_t *softc; + void *arg; + int otype; + int unit; + void *data; { + ipf_pool_softc_t *softp = arg; if (data == NULL) - return; + return EINVAL; if (unit < 0 || unit > IPL_LOGMAX) - return; + return EINVAL; switch (otype) { case IPFLOOKUPITER_LIST : - WRITE_ENTER(&ip_poolrw); - ip_pool_deref((ip_pool_t *)data); - RWLOCK_EXIT(&ip_poolrw); + ipf_pool_deref(softc, softp, (ip_pool_t *)data); break; case IPFLOOKUPITER_NODE : - WRITE_ENTER(&ip_poolrw); - ip_pool_node_deref((ip_pool_node_t *)data); - RWLOCK_EXIT(&ip_poolrw); + ipf_pool_node_deref(softp, (ip_pool_node_t *)data); break; default : break; } -} - -# if defined(_KERNEL) && ((BSD >= 198911) && !defined(__osf__) && \ - !defined(__hpux) && !defined(__sgi)) -static int -rn_freenode(struct radix_node *n, void *p) -{ - struct radix_node_head *rnh = p; - struct radix_node *d; - - d = rnh->rnh_deladdr(n->rn_key, NULL, rnh); - if (d != NULL) { - FreeS(d, max_keylen + 2 * sizeof (*d)); - } return 0; } -void -rn_freehead(rnh) - struct radix_node_head *rnh; +/* ------------------------------------------------------------------------ */ +/* Function: ipf_pool_expire */ +/* Returns: Nil */ +/* Parameters: softc(I) - pointer to soft context main structure */ +/* arg(I) - pointer to local context to use */ +/* */ +/* At present this function exists just to support temporary addition of */ +/* nodes to the address pool. */ +/* ------------------------------------------------------------------------ */ +static void +ipf_pool_expire(softc, arg) + ipf_main_softc_t *softc; + void *arg; { + ipf_pool_softc_t *softp = arg; + ip_pool_node_t *n; - RADIX_NODE_HEAD_LOCK(rnh); - (*rnh->rnh_walktree)(rnh, rn_freenode, rnh); - - rnh->rnh_addaddr = NULL; - rnh->rnh_deladdr = NULL; - rnh->rnh_matchaddr = NULL; - rnh->rnh_lookup = NULL; - rnh->rnh_walktree = NULL; - RADIX_NODE_HEAD_UNLOCK(rnh); - - Free(rnh); + while ((n = softp->ipf_node_explist) != NULL) { + /* + * Because the list is kept sorted on insertion, the fist + * one that dies in the future means no more work to do. + */ + if (n->ipn_die > softc->ipf_ticks) + break; + ipf_pool_remove_node(softc, softp, n->ipn_owner, n); + } } -# endif -#endif /* IPFILTER_LOOKUP */ + + + + +#ifndef _KERNEL +void +ipf_pool_dump(softc, arg) + ipf_main_softc_t *softc; + void *arg; +{ + ipf_pool_softc_t *softp = arg; + ip_pool_t *ipl; + int i; + + printf("List of configured pools\n"); + for (i = 0; i <= LOOKUP_POOL_MAX; i++) + for (ipl = softp->ipf_pool_list[i]; ipl != NULL; + ipl = ipl->ipo_next) + printpool(ipl, bcopywrap, NULL, opts, NULL); +} +#endif diff --git a/sys/contrib/ipfilter/netinet/ip_pool.h b/sys/contrib/ipfilter/netinet/ip_pool.h index 9968ef012f5b..8524e607949c 100644 --- a/sys/contrib/ipfilter/netinet/ip_pool.h +++ b/sys/contrib/ipfilter/netinet/ip_pool.h @@ -1,90 +1,67 @@ /* - * Copyright (C) 1993-2001, 2003 by Darren Reed. + * Copyright (C) 2012 by Darren Reed. * * See the IPFILTER.LICENCE file for details on licencing. * - * $Id: ip_pool.h,v 2.26.2.6 2007/10/10 09:51:43 darrenr Exp $ + * $Id$ */ #ifndef __IP_POOL_H__ #define __IP_POOL_H__ -#if defined(_KERNEL) && !defined(__osf__) && !defined(__hpux) && \ - !defined(linux) && !defined(sun) && !defined(AIX) -# include -extern void rn_freehead __P((struct radix_node_head *)); -# define FreeS(p, z) KFREES(p, z) -extern int max_keylen; -#else -# if defined(__osf__) || defined(__hpux) || defined(sun) -# include "radix_ipf_local.h" -# define radix_mask ipf_radix_mask -# define radix_node ipf_radix_node -# define radix_node_head ipf_radix_node_head -# else -# include "radix_ipf.h" -# endif -#endif #include "netinet/ip_lookup.h" +#include "radix_ipf.h" #define IP_POOL_NOMATCH 0 #define IP_POOL_POSITIVE 1 typedef struct ip_pool_node { - struct radix_node ipn_nodes[2]; + ipf_rdx_node_t ipn_nodes[2]; addrfamily_t ipn_addr; addrfamily_t ipn_mask; + int ipn_uid; int ipn_info; int ipn_ref; -char ipn_name[FR_GROUPLEN]; -u_long ipn_hits; + char ipn_name[FR_GROUPLEN]; + U_QUAD_T ipn_hits; + U_QUAD_T ipn_bytes; + u_long ipn_die; struct ip_pool_node *ipn_next, **ipn_pnext; + struct ip_pool_node *ipn_dnext, **ipn_pdnext; + struct ip_pool_s *ipn_owner; } ip_pool_node_t; typedef struct ip_pool_s { struct ip_pool_s *ipo_next; struct ip_pool_s **ipo_pnext; - struct radix_node_head *ipo_head; - ip_pool_node_t *ipo_list; - u_long ipo_hits; - int ipo_unit; - int ipo_flags; - int ipo_ref; - char ipo_name[FR_GROUPLEN]; + ipf_rdx_head_t *ipo_head; + ip_pool_node_t *ipo_list; + ip_pool_node_t **ipo_tail; + ip_pool_node_t *ipo_nextaddr; + void *ipo_radix; + u_long ipo_hits; + int ipo_unit; + int ipo_flags; + int ipo_ref; + char ipo_name[FR_GROUPLEN]; } ip_pool_t; #define IPOOL_DELETE 0x01 #define IPOOL_ANON 0x02 -typedef struct ip_pool_stat { - u_long ipls_pools; - u_long ipls_tables; - u_long ipls_nodes; - ip_pool_t *ipls_list[IPL_LOGSIZE]; -} ip_pool_stat_t; +typedef struct ipf_pool_stat { + u_long ipls_pools; + u_long ipls_tables; + u_long ipls_nodes; + ip_pool_t *ipls_list[LOOKUP_POOL_SZ]; +} ipf_pool_stat_t; +extern ipf_lookup_t ipf_pool_backend; -extern ip_pool_stat_t ipoolstat; -extern ip_pool_t *ip_pool_list[IPL_LOGSIZE]; - -extern int ip_pool_search __P((void *, int, void *)); -extern int ip_pool_init __P((void)); -extern void ip_pool_fini __P((void)); -extern int ip_pool_create __P((iplookupop_t *)); -extern int ip_pool_insert __P((ip_pool_t *, i6addr_t *, i6addr_t *, int)); -extern int ip_pool_remove __P((ip_pool_t *, ip_pool_node_t *)); -extern int ip_pool_destroy __P((int, char *)); -extern void ip_pool_free __P((ip_pool_t *)); -extern void ip_pool_deref __P((ip_pool_t *)); -extern void ip_pool_node_deref __P((ip_pool_node_t *)); -extern void *ip_pool_find __P((int, char *)); -extern ip_pool_node_t *ip_pool_findeq __P((ip_pool_t *, - addrfamily_t *, addrfamily_t *)); -extern int ip_pool_flush __P((iplookupflush_t *)); -extern int ip_pool_statistics __P((iplookupop_t *)); -extern int ip_pool_getnext __P((ipftoken_t *, ipflookupiter_t *)); -extern void ip_pool_iterderef __P((u_int, int, void *)); +#ifndef _KERNEL +extern void ipf_pool_dump __P((ipf_main_softc_t *, void *)); +#endif #endif /* __IP_POOL_H__ */ diff --git a/sys/contrib/ipfilter/netinet/ip_pptp_pxy.c b/sys/contrib/ipfilter/netinet/ip_pptp_pxy.c index 3924d4b829ed..959b107cd6af 100644 --- a/sys/contrib/ipfilter/netinet/ip_pptp_pxy.c +++ b/sys/contrib/ipfilter/netinet/ip_pptp_pxy.c @@ -1,18 +1,42 @@ /* - * Copyright (C) 2002-2003 by Darren Reed + * Copyright (C) 2012 by Darren Reed. * * Simple PPTP transparent proxy for in-kernel use. For use with the NAT * code. * - * $Id: ip_pptp_pxy.c,v 2.10.2.15 2006/10/31 12:11:23 darrenr Exp $ + * $Id$ * */ #define IPF_PPTP_PROXY + + +/* + * PPTP proxy + */ +typedef struct pptp_side { + u_32_t pptps_nexthdr; + u_32_t pptps_next; + int pptps_state; + int pptps_gothdr; + int pptps_len; + int pptps_bytes; + char *pptps_wptr; + char pptps_buffer[512]; +} pptp_side_t; + +typedef struct pptp_pxy { + nat_t *pptp_nat; + struct ipstate *pptp_state; + u_short pptp_call[2]; + pptp_side_t pptp_side[2]; + ipnat_t *pptp_rule; +} pptp_pxy_t; + typedef struct pptp_hdr { - u_short pptph_len; - u_short pptph_type; - u_32_t pptph_cookie; + u_short pptph_len; + u_short pptph_type; + u_32_t pptph_cookie; } pptp_hdr_t; #define PPTP_MSGTYPE_CTL 1 @@ -33,41 +57,41 @@ typedef struct pptp_hdr { #define PPTP_MTCTL_LINKINFO 15 -int ippr_pptp_init __P((void)); -void ippr_pptp_fini __P((void)); -int ippr_pptp_new __P((fr_info_t *, ap_session_t *, nat_t *)); -void ippr_pptp_del __P((ap_session_t *)); -int ippr_pptp_inout __P((fr_info_t *, ap_session_t *, nat_t *)); -void ippr_pptp_donatstate __P((fr_info_t *, nat_t *, pptp_pxy_t *)); -int ippr_pptp_message __P((fr_info_t *, nat_t *, pptp_pxy_t *, pptp_side_t *)); -int ippr_pptp_nextmessage __P((fr_info_t *, nat_t *, pptp_pxy_t *, int)); -int ippr_pptp_mctl __P((fr_info_t *, nat_t *, pptp_pxy_t *, pptp_side_t *)); +void ipf_p_pptp_main_load __P((void)); +void ipf_p_pptp_main_unload __P((void)); +int ipf_p_pptp_new __P((void *, fr_info_t *, ap_session_t *, nat_t *)); +void ipf_p_pptp_del __P((ipf_main_softc_t *, ap_session_t *)); +int ipf_p_pptp_inout __P((void *, fr_info_t *, ap_session_t *, nat_t *)); +void ipf_p_pptp_donatstate __P((fr_info_t *, nat_t *, pptp_pxy_t *)); +int ipf_p_pptp_message __P((fr_info_t *, nat_t *, pptp_pxy_t *, pptp_side_t *)); +int ipf_p_pptp_nextmessage __P((fr_info_t *, nat_t *, pptp_pxy_t *, int)); +int ipf_p_pptp_mctl __P((fr_info_t *, nat_t *, pptp_pxy_t *, pptp_side_t *)); static frentry_t pptpfr; -int pptp_proxy_init = 0; -int ippr_pptp_debug = 0; -int ippr_pptp_gretimeout = IPF_TTLVAL(120); /* 2 minutes */ +static int pptp_proxy_init = 0; +static int ipf_p_pptp_debug = 0; +static int ipf_p_pptp_gretimeout = IPF_TTLVAL(120); /* 2 minutes */ /* * PPTP application proxy initialization. */ -int ippr_pptp_init() +void +ipf_p_pptp_main_load() { bzero((char *)&pptpfr, sizeof(pptpfr)); pptpfr.fr_ref = 1; - pptpfr.fr_age[0] = ippr_pptp_gretimeout; - pptpfr.fr_age[1] = ippr_pptp_gretimeout; + pptpfr.fr_age[0] = ipf_p_pptp_gretimeout; + pptpfr.fr_age[1] = ipf_p_pptp_gretimeout; pptpfr.fr_flags = FR_OUTQUE|FR_PASS|FR_QUICK|FR_KEEPSTATE; MUTEX_INIT(&pptpfr.fr_lock, "PPTP proxy rule lock"); pptp_proxy_init = 1; - - return 0; } -void ippr_pptp_fini() +void +ipf_p_pptp_main_unload() { if (pptp_proxy_init == 1) { MUTEX_DESTROY(&pptpfr.fr_lock); @@ -82,64 +106,83 @@ void ippr_pptp_fini() * NOTE: The printf's are broken up with %s in them to prevent them being * optimised into puts statements on FreeBSD (this doesn't exist in the kernel) */ -int ippr_pptp_new(fin, aps, nat) -fr_info_t *fin; -ap_session_t *aps; -nat_t *nat; +int +ipf_p_pptp_new(arg, fin, aps, nat) + void *arg; + fr_info_t *fin; + ap_session_t *aps; + nat_t *nat; { pptp_pxy_t *pptp; ipnat_t *ipn; + ipnat_t *np; + int size; ip_t *ip; + if (fin->fin_v != 4) + return -1; + ip = fin->fin_ip; + np = nat->nat_ptr; + size = np->in_size; - if (nat_outlookup(fin, 0, IPPROTO_GRE, nat->nat_inip, + if (ipf_nat_outlookup(fin, 0, IPPROTO_GRE, nat->nat_osrcip, ip->ip_dst) != NULL) { - if (ippr_pptp_debug > 0) - printf("ippr_pptp_new: GRE session %s\n", - "already exists"); + if (ipf_p_pptp_debug > 0) + printf("ipf_p_pptp_new: GRE session already exists\n"); return -1; } - aps->aps_psiz = sizeof(*pptp); - KMALLOCS(aps->aps_data, pptp_pxy_t *, sizeof(*pptp)); - if (aps->aps_data == NULL) { - if (ippr_pptp_debug > 0) - printf("ippr_pptp_new: malloc for aps_data %s\n", - "failed"); + KMALLOC(pptp, pptp_pxy_t *); + if (pptp == NULL) { + if (ipf_p_pptp_debug > 0) + printf("ipf_p_pptp_new: malloc for aps_data failed\n"); return -1; } + KMALLOCS(ipn, ipnat_t *, size); + if (ipn == NULL) { + KFREE(pptp); + return -1; + } + + aps->aps_data = pptp; + aps->aps_psiz = sizeof(*pptp); + bzero((char *)pptp, sizeof(*pptp)); + bzero((char *)ipn, size); + pptp->pptp_rule = ipn; /* * Create NAT rule against which the tunnel/transport mapping is * created. This is required because the current NAT rule does not * describe GRE but TCP instead. */ - pptp = aps->aps_data; - bzero((char *)pptp, sizeof(*pptp)); - ipn = &pptp->pptp_rule; + ipn->in_size = size; ipn->in_ifps[0] = fin->fin_ifp; ipn->in_apr = NULL; ipn->in_use = 1; ipn->in_hits = 1; ipn->in_ippip = 1; - if (nat->nat_dir == NAT_OUTBOUND) { - ipn->in_nip = ntohl(nat->nat_outip.s_addr); - ipn->in_outip = fin->fin_saddr; - ipn->in_redir = NAT_MAP; - } else if (nat->nat_dir == NAT_INBOUND) { - ipn->in_nip = 0; - ipn->in_outip = nat->nat_outip.s_addr; - ipn->in_redir = NAT_REDIRECT; - } - ipn->in_inip = nat->nat_inip.s_addr; - ipn->in_inmsk = 0xffffffff; - ipn->in_outmsk = 0xffffffff; - ipn->in_srcip = fin->fin_saddr; - ipn->in_srcmsk = 0xffffffff; - bcopy(nat->nat_ptr->in_ifnames[0], ipn->in_ifnames[0], - sizeof(ipn->in_ifnames[0])); - ipn->in_p = IPPROTO_GRE; + ipn->in_snip = ntohl(nat->nat_nsrcaddr); + ipn->in_nsrcaddr = fin->fin_saddr; + ipn->in_dnip = ntohl(nat->nat_ndstaddr); + ipn->in_ndstaddr = nat->nat_ndstaddr; + ipn->in_redir = np->in_redir; + ipn->in_osrcaddr = nat->nat_osrcaddr; + ipn->in_odstaddr = nat->nat_odstaddr; + ipn->in_osrcmsk = 0xffffffff; + ipn->in_nsrcmsk = 0xffffffff; + ipn->in_odstmsk = 0xffffffff; + ipn->in_ndstmsk = 0xffffffff; + ipn->in_flags = (np->in_flags | IPN_PROXYRULE); + MUTEX_INIT(&ipn->in_lock, "pptp proxy NAT rule"); + + ipn->in_namelen = np->in_namelen; + bcopy(np->in_names, ipn->in_ifnames, ipn->in_namelen); + ipn->in_ifnames[0] = np->in_ifnames[0]; + ipn->in_ifnames[1] = np->in_ifnames[1]; + + ipn->in_pr[0] = IPPROTO_GRE; + ipn->in_pr[1] = IPPROTO_GRE; pptp->pptp_side[0].pptps_wptr = pptp->pptp_side[0].pptps_buffer; pptp->pptp_side[1].pptps_wptr = pptp->pptp_side[1].pptps_buffer; @@ -147,11 +190,13 @@ nat_t *nat; } -void ippr_pptp_donatstate(fin, nat, pptp) -fr_info_t *fin; -nat_t *nat; -pptp_pxy_t *pptp; +void +ipf_p_pptp_donatstate(fin, nat, pptp) + fr_info_t *fin; + nat_t *nat; + pptp_pxy_t *pptp; { + ipf_main_softc_t *softc = fin->fin_main_soft; fr_info_t fi; grehdr_t gre; nat_t *nat2; @@ -165,8 +210,6 @@ pptp_pxy_t *pptp; if ((nat2 == NULL) || (pptp->pptp_state == NULL)) { bcopy((char *)fin, (char *)&fi, sizeof(fi)); bzero((char *)&gre, sizeof(gre)); - fi.fin_state = NULL; - fi.fin_nat = NULL; fi.fin_fi.fi_p = IPPROTO_GRE; fi.fin_fr = &pptpfr; if ((nat->nat_dir == NAT_OUTBOUND && fin->fin_out) || @@ -183,47 +226,47 @@ pptp_pxy_t *pptp; fi.fin_flx |= FI_IGNORE; fi.fin_dp = &gre; gre.gr_flags = htons(1 << 13); - if (fin->fin_out && nat->nat_dir == NAT_INBOUND) { - fi.fin_fi.fi_saddr = fin->fin_fi.fi_daddr; - fi.fin_fi.fi_daddr = nat->nat_outip.s_addr; - } else if (!fin->fin_out && nat->nat_dir == NAT_OUTBOUND) { - fi.fin_fi.fi_saddr = nat->nat_inip.s_addr; - fi.fin_fi.fi_daddr = fin->fin_fi.fi_saddr; - } + + fi.fin_fi.fi_saddr = nat->nat_osrcaddr; + fi.fin_fi.fi_daddr = nat->nat_odstaddr; } /* * Update NAT timeout/create NAT if missing. */ if (nat2 != NULL) - fr_queueback(&nat2->nat_tqe); + ipf_queueback(softc->ipf_ticks, &nat2->nat_tqe); else { - nat2 = nat_new(&fi, &pptp->pptp_rule, &pptp->pptp_nat, - NAT_SLAVE, nat->nat_dir); - pptp->pptp_nat = nat2; +#ifdef USE_MUTEXES + ipf_nat_softc_t *softn = softc->ipf_nat_soft; +#endif + + MUTEX_ENTER(&softn->ipf_nat_new); + nat2 = ipf_nat_add(&fi, pptp->pptp_rule, &pptp->pptp_nat, + NAT_SLAVE, nat->nat_dir); + MUTEX_EXIT(&softn->ipf_nat_new); if (nat2 != NULL) { - (void) nat_proto(&fi, nat2, 0); - nat_update(&fi, nat2, nat2->nat_ptr); + (void) ipf_nat_proto(&fi, nat2, 0); + MUTEX_ENTER(&nat2->nat_lock); + ipf_nat_update(&fi, nat2); + MUTEX_EXIT(&nat2->nat_lock); } } - READ_ENTER(&ipf_state); + READ_ENTER(&softc->ipf_state); if (pptp->pptp_state != NULL) { - fr_queueback(&pptp->pptp_state->is_sti); - RWLOCK_EXIT(&ipf_state); + ipf_queueback(softc->ipf_ticks, &pptp->pptp_state->is_sti); + RWLOCK_EXIT(&softc->ipf_state); } else { - RWLOCK_EXIT(&ipf_state); + RWLOCK_EXIT(&softc->ipf_state); if (nat2 != NULL) { if (nat->nat_dir == NAT_INBOUND) - fi.fin_fi.fi_daddr = nat2->nat_inip.s_addr; + fi.fin_fi.fi_daddr = nat2->nat_ndstaddr; else - fi.fin_fi.fi_saddr = nat2->nat_inip.s_addr; + fi.fin_fi.fi_saddr = nat2->nat_osrcaddr; } fi.fin_ifp = NULL; - pptp->pptp_state = fr_addstate(&fi, &pptp->pptp_state, - 0); - if (fi.fin_state != NULL) - fr_statederef((ipstate_t **)&fi.fin_state); + (void) ipf_state_add(softc, &fi, &pptp->pptp_state, 0); } ip->ip_p = p; return; @@ -235,13 +278,14 @@ pptp_pxy_t *pptp; * build it up completely (fits in our buffer) then pass it off to the message * parsing function. */ -int ippr_pptp_nextmessage(fin, nat, pptp, rev) -fr_info_t *fin; -nat_t *nat; -pptp_pxy_t *pptp; -int rev; +int +ipf_p_pptp_nextmessage(fin, nat, pptp, rev) + fr_info_t *fin; + nat_t *nat; + pptp_pxy_t *pptp; + int rev; { - static const char *funcname = "ippr_pptp_nextmessage"; + static const char *funcname = "ipf_p_pptp_nextmessage"; pptp_side_t *pptps; u_32_t start, end; pptp_hdr_t *hdr; @@ -271,7 +315,7 @@ int rev; return 0; if (pptps->pptps_next != start) { - if (ippr_pptp_debug > 5) + if (ipf_p_pptp_debug > 5) printf("%s: next (%x) != start (%x)\n", funcname, pptps->pptps_next, start); return -1; @@ -296,7 +340,7 @@ int rev; if (pptps->pptps_bytes == 8) { pptps->pptps_next += 8; if (ntohl(hdr->pptph_cookie) != 0x1a2b3c4d) { - if (ippr_pptp_debug > 1) + if (ipf_p_pptp_debug > 1) printf("%s: bad cookie (%x)\n", funcname, hdr->pptph_cookie); @@ -320,7 +364,7 @@ int rev; * bad data packet, anyway. */ if (len > sizeof(pptps->pptps_buffer)) { - if (ippr_pptp_debug > 3) + if (ipf_p_pptp_debug > 3) printf("%s: message too big (%d)\n", funcname, len); pptps->pptps_next = pptps->pptps_nexthdr; @@ -341,7 +385,7 @@ int rev; if (pptps->pptps_len > pptps->pptps_bytes) break; - ippr_pptp_message(fin, nat, pptp, pptps); + ipf_p_pptp_message(fin, nat, pptp, pptps); pptps->pptps_wptr = pptps->pptps_buffer; pptps->pptps_gothdr = 0; pptps->pptps_bytes = 0; @@ -359,18 +403,19 @@ int rev; /* * handle a complete PPTP message */ -int ippr_pptp_message(fin, nat, pptp, pptps) -fr_info_t *fin; -nat_t *nat; -pptp_pxy_t *pptp; -pptp_side_t *pptps; +int +ipf_p_pptp_message(fin, nat, pptp, pptps) + fr_info_t *fin; + nat_t *nat; + pptp_pxy_t *pptp; + pptp_side_t *pptps; { pptp_hdr_t *hdr = (pptp_hdr_t *)pptps->pptps_buffer; switch (ntohs(hdr->pptph_type)) { case PPTP_MSGTYPE_CTL : - ippr_pptp_mctl(fin, nat, pptp, pptps); + ipf_p_pptp_mctl(fin, nat, pptp, pptps); break; default : @@ -383,11 +428,12 @@ pptp_side_t *pptps; /* * handle a complete PPTP control message */ -int ippr_pptp_mctl(fin, nat, pptp, pptps) -fr_info_t *fin; -nat_t *nat; -pptp_pxy_t *pptp; -pptp_side_t *pptps; +int +ipf_p_pptp_mctl(fin, nat, pptp, pptps) + fr_info_t *fin; + nat_t *nat; + pptp_pxy_t *pptp; + pptp_side_t *pptps; { u_short *buffer = (u_short *)(pptps->pptps_buffer); pptp_side_t *pptpo; @@ -432,7 +478,7 @@ pptp_side_t *pptps; pptps->pptps_state = PPTP_MTCTL_OUTREP; pptp->pptp_call[0] = buffer[7]; pptp->pptp_call[1] = buffer[6]; - ippr_pptp_donatstate(fin, nat, pptp); + ipf_p_pptp_donatstate(fin, nat, pptp); } break; case PPTP_MTCTL_INREQ : @@ -443,7 +489,7 @@ pptp_side_t *pptps; pptps->pptps_state = PPTP_MTCTL_INREP; pptp->pptp_call[0] = buffer[7]; pptp->pptp_call[1] = buffer[6]; - ippr_pptp_donatstate(fin, nat, pptp); + ipf_p_pptp_donatstate(fin, nat, pptp); } break; case PPTP_MTCTL_INCONNECT : @@ -471,10 +517,12 @@ pptp_side_t *pptps; * For outgoing PPTP packets. refresh timeouts for NAT & state entries, if * we can. If they have disappeared, recreate them. */ -int ippr_pptp_inout(fin, aps, nat) -fr_info_t *fin; -ap_session_t *aps; -nat_t *nat; +int +ipf_p_pptp_inout(arg, fin, aps, nat) + void *arg; + fr_info_t *fin; + ap_session_t *aps; + nat_t *nat; { pptp_pxy_t *pptp; tcphdr_t *tcp; @@ -495,7 +543,7 @@ nat_t *nat; pptp->pptp_side[rev].pptps_next = ntohl(tcp->th_seq) + 1; pptp->pptp_side[rev].pptps_nexthdr = ntohl(tcp->th_seq) + 1; } - return ippr_pptp_nextmessage(fin, nat, (pptp_pxy_t *)aps->aps_data, + return ipf_p_pptp_nextmessage(fin, nat, (pptp_pxy_t *)aps->aps_data, rev); } @@ -503,8 +551,10 @@ nat_t *nat; /* * clean up after ourselves. */ -void ippr_pptp_del(aps) -ap_session_t *aps; +void +ipf_p_pptp_del(softc, aps) + ipf_main_softc_t *softc; + ap_session_t *aps; { pptp_pxy_t *pptp; @@ -516,15 +566,15 @@ ap_session_t *aps; * *_del() is on a callback from aps_free(), from nat_delete() */ - READ_ENTER(&ipf_state); + READ_ENTER(&softc->ipf_state); if (pptp->pptp_state != NULL) { - pptp->pptp_state->is_die = fr_ticks + 1; - pptp->pptp_state->is_me = NULL; - fr_queuefront(&pptp->pptp_state->is_sti); + ipf_state_setpending(softc, pptp->pptp_state); } - RWLOCK_EXIT(&ipf_state); + RWLOCK_EXIT(&softc->ipf_state); - pptp->pptp_state = NULL; - pptp->pptp_nat = NULL; + if (pptp->pptp_nat != NULL) + ipf_nat_setpending(softc, pptp->pptp_nat); + pptp->pptp_rule->in_flags |= IPN_DELETE; + ipf_nat_rule_deref(softc, &pptp->pptp_rule); } } diff --git a/sys/contrib/ipfilter/netinet/ip_proxy.c b/sys/contrib/ipfilter/netinet/ip_proxy.c index e492a33e5743..39addb0f6b28 100644 --- a/sys/contrib/ipfilter/netinet/ip_proxy.c +++ b/sys/contrib/ipfilter/netinet/ip_proxy.c @@ -1,7 +1,7 @@ /* $FreeBSD$ */ /* - * Copyright (C) 1997-2003 by Darren Reed. + * Copyright (C) 2012 by Darren Reed. * * See the IPFILTER.LICENCE file for details on licencing. */ @@ -49,9 +49,6 @@ struct file; #if defined(_KERNEL) && (__FreeBSD_version >= 220000) # include # include -# if (__FreeBSD_version >= 300000) && !defined(IPFILTER_LKM) -# include "opt_ipfilter.h" -# endif #else # include #endif @@ -70,7 +67,6 @@ struct file; #ifdef sun # include #endif -#include #include #include #include @@ -90,9 +86,12 @@ struct file; # include #endif +/* END OF INCLUDES */ + #include "netinet/ip_ftp_pxy.c" +#include "netinet/ip_tftp_pxy.c" #include "netinet/ip_rcmd_pxy.c" -# include "netinet/ip_pptp_pxy.c" +#include "netinet/ip_pptp_pxy.c" #if defined(_KERNEL) # include "netinet/ip_irc_pxy.c" # include "netinet/ip_raudio_pxy.c" @@ -101,93 +100,474 @@ struct file; #include "netinet/ip_ipsec_pxy.c" #include "netinet/ip_rpcb_pxy.c" -/* END OF INCLUDES */ - #if !defined(lint) -static const char rcsid[] = "@(#)$Id: ip_proxy.c,v 2.62.2.21 2007/06/02 21:22:28 darrenr Exp $"; +static const char rcsid[] = "@(#)$Id$"; #endif -static int appr_fixseqack __P((fr_info_t *, ip_t *, ap_session_t *, int )); - #define AP_SESS_SIZE 53 -#if defined(_KERNEL) -int ipf_proxy_debug = 0; -#else -int ipf_proxy_debug = 2; -#endif -ap_session_t *ap_sess_tab[AP_SESS_SIZE]; -ap_session_t *ap_sess_list = NULL; -aproxy_t *ap_proxylist = NULL; -aproxy_t ap_proxies[] = { -#ifdef IPF_FTP_PROXY - { NULL, "ftp", (char)IPPROTO_TCP, 0, 0, ippr_ftp_init, ippr_ftp_fini, - ippr_ftp_new, NULL, ippr_ftp_in, ippr_ftp_out, NULL, NULL }, -#endif -#ifdef IPF_IRC_PROXY - { NULL, "irc", (char)IPPROTO_TCP, 0, 0, ippr_irc_init, ippr_irc_fini, - ippr_irc_new, NULL, NULL, ippr_irc_out, NULL, NULL }, -#endif -#ifdef IPF_RCMD_PROXY - { NULL, "rcmd", (char)IPPROTO_TCP, 0, 0, ippr_rcmd_init, ippr_rcmd_fini, - ippr_rcmd_new, NULL, ippr_rcmd_in, ippr_rcmd_out, NULL, NULL }, -#endif -#ifdef IPF_RAUDIO_PROXY - { NULL, "raudio", (char)IPPROTO_TCP, 0, 0, ippr_raudio_init, ippr_raudio_fini, - ippr_raudio_new, NULL, ippr_raudio_in, ippr_raudio_out, NULL, NULL }, -#endif -#ifdef IPF_MSNRPC_PROXY - { NULL, "msnrpc", (char)IPPROTO_TCP, 0, 0, ippr_msnrpc_init, ippr_msnrpc_fini, - ippr_msnrpc_new, NULL, ippr_msnrpc_in, ippr_msnrpc_out, NULL, NULL }, -#endif -#ifdef IPF_NETBIOS_PROXY - { NULL, "netbios", (char)IPPROTO_UDP, 0, 0, ippr_netbios_init, ippr_netbios_fini, - NULL, NULL, NULL, ippr_netbios_out, NULL, NULL }, -#endif -#ifdef IPF_IPSEC_PROXY - { NULL, "ipsec", (char)IPPROTO_UDP, 0, 0, - ippr_ipsec_init, ippr_ipsec_fini, ippr_ipsec_new, ippr_ipsec_del, - ippr_ipsec_inout, ippr_ipsec_inout, ippr_ipsec_match, NULL }, -#endif -#ifdef IPF_PPTP_PROXY - { NULL, "pptp", (char)IPPROTO_TCP, 0, 0, - ippr_pptp_init, ippr_pptp_fini, ippr_pptp_new, ippr_pptp_del, - ippr_pptp_inout, ippr_pptp_inout, NULL, NULL }, -#endif -#ifdef IPF_H323_PROXY - { NULL, "h323", (char)IPPROTO_TCP, 0, 0, ippr_h323_init, ippr_h323_fini, - ippr_h323_new, ippr_h323_del, ippr_h323_in, NULL, NULL, NULL }, - { NULL, "h245", (char)IPPROTO_TCP, 0, 0, NULL, NULL, - ippr_h245_new, NULL, NULL, ippr_h245_out, NULL, NULL }, -#endif -#ifdef IPF_RPCB_PROXY -# if 0 - { NULL, "rpcbt", (char)IPPROTO_TCP, 0, 0, - ippr_rpcb_init, ippr_rpcb_fini, ippr_rpcb_new, ippr_rpcb_del, - ippr_rpcb_in, ippr_rpcb_out, NULL, NULL }, -# endif - { NULL, "rpcbu", (char)IPPROTO_UDP, 0, 0, - ippr_rpcb_init, ippr_rpcb_fini, ippr_rpcb_new, ippr_rpcb_del, - ippr_rpcb_in, ippr_rpcb_out, NULL, NULL }, -#endif - { NULL, "", '\0', 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL } +static int ipf_proxy_fixseqack __P((fr_info_t *, ip_t *, ap_session_t *, int )); +static aproxy_t *ipf_proxy_create_clone __P((ipf_main_softc_t *, aproxy_t *)); + +typedef struct ipf_proxy_softc_s { + int ips_proxy_debug; + int ips_proxy_session_size; + ap_session_t **ips_sess_tab; + ap_session_t *ips_sess_list; + aproxy_t *ips_proxies; + int ips_init_run; + ipftuneable_t *ipf_proxy_tune; +} ipf_proxy_softc_t; + +static ipftuneable_t ipf_proxy_tuneables[] = { + { { (void *)offsetof(ipf_proxy_softc_t, ips_proxy_debug) }, + "proxy_debug", 0, 0x1f, + stsizeof(ipf_proxy_softc_t, ips_proxy_debug), + 0, NULL, NULL }, + { { NULL }, NULL, 0, 0, + 0, + 0, NULL, NULL} }; -/* - * Dynamically add a new kernel proxy. Ensure that it is unique in the - * collection compiled in and dynamically added. - */ -int appr_add(ap) -aproxy_t *ap; +static aproxy_t *ap_proxylist = NULL; +static aproxy_t ips_proxies[] = { +#ifdef IPF_FTP_PROXY + { NULL, NULL, "ftp", (char)IPPROTO_TCP, 0, 0, 0, + ipf_p_ftp_main_load, ipf_p_ftp_main_unload, + ipf_p_ftp_soft_create, ipf_p_ftp_soft_destroy, + NULL, NULL, + ipf_p_ftp_new, ipf_p_ftp_del, ipf_p_ftp_in, ipf_p_ftp_out, NULL, + NULL, NULL, NULL, NULL }, +#endif +#ifdef IPF_TFTP_PROXY + { NULL, NULL, "tftp", (char)IPPROTO_UDP, 0, 0, 0, + ipf_p_tftp_main_load, ipf_p_tftp_main_unload, + ipf_p_tftp_soft_create, ipf_p_tftp_soft_destroy, + NULL, NULL, + ipf_p_tftp_new, ipf_p_tftp_del, + ipf_p_tftp_in, ipf_p_tftp_out, NULL, + NULL, NULL, NULL, NULL }, +#endif +#ifdef IPF_IRC_PROXY + { NULL, NULL, "irc", (char)IPPROTO_TCP, 0, 0, 0, + ipf_p_irc_main_load, ipf_p_irc_main_unload, + NULL, NULL, + NULL, NULL, + ipf_p_irc_new, NULL, NULL, ipf_p_irc_out, NULL, + NULL, NULL, NULL, NULL }, +#endif +#ifdef IPF_RCMD_PROXY + { NULL, NULL, "rcmd", (char)IPPROTO_TCP, 0, 0, 0, + ipf_p_rcmd_main_load, ipf_p_rcmd_main_unload, + NULL, NULL, + NULL, NULL, + ipf_p_rcmd_new, ipf_p_rcmd_del, + ipf_p_rcmd_in, ipf_p_rcmd_out, NULL, + NULL, NULL, NULL, NULL }, +#endif +#ifdef IPF_RAUDIO_PROXY + { NULL, NULL, "raudio", (char)IPPROTO_TCP, 0, 0, 0, + ipf_p_raudio_main_load, ipf_p_raudio_main_unload, + NULL, NULL, + NULL, NULL, + ipf_p_raudio_new, NULL, ipf_p_raudio_in, ipf_p_raudio_out, NULL, + NULL, NULL, NULL, NULL }, +#endif +#ifdef IPF_MSNRPC_PROXY + { NULL, NULL, "msnrpc", (char)IPPROTO_TCP, 0, 0, 0, + ipf_p_msnrpc_init, ipf_p_msnrpc_fini, + NULL, NULL, + NULL, NULL, + ipf_p_msnrpc_new, NULL, ipf_p_msnrpc_in, ipf_p_msnrpc_out, NULL, + NULL, NULL, NULL, NULL }, +#endif +#ifdef IPF_NETBIOS_PROXY + { NULL, NULL, "netbios", (char)IPPROTO_UDP, 0, 0, 0, + ipf_p_netbios_main_load, ipf_p_netbios_main_unload, + NULL, NULL, + NULL, NULL, + NULL, NULL, NULL, ipf_p_netbios_out, NULL, + NULL, NULL, NULL, NULL }, +#endif +#ifdef IPF_IPSEC_PROXY + { NULL, NULL, "ipsec", (char)IPPROTO_UDP, 0, 0, 0, + NULL, NULL, + ipf_p_ipsec_soft_create, ipf_p_ipsec_soft_destroy, + ipf_p_ipsec_soft_init, ipf_p_ipsec_soft_fini, + ipf_p_ipsec_new, ipf_p_ipsec_del, + ipf_p_ipsec_inout, ipf_p_ipsec_inout, ipf_p_ipsec_match, + NULL, NULL, NULL, NULL }, +#endif +#ifdef IPF_DNS_PROXY + { NULL, NULL, "dns", (char)IPPROTO_UDP, 0, 0, 0, + NULL, NULL, + ipf_p_dns_soft_create, ipf_p_dns_soft_destroy, + NULL, NULL, + ipf_p_dns_new, ipf_p_ipsec_del, + ipf_p_dns_inout, ipf_p_dns_inout, ipf_p_dns_match, + ipf_p_dns_ctl, NULL, NULL, NULL }, +#endif +#ifdef IPF_PPTP_PROXY + { NULL, NULL, "pptp", (char)IPPROTO_TCP, 0, 0, 0, + ipf_p_pptp_main_load, ipf_p_pptp_main_unload, + NULL, NULL, + NULL, NULL, + ipf_p_pptp_new, ipf_p_pptp_del, + ipf_p_pptp_inout, ipf_p_pptp_inout, NULL, + NULL, NULL, NULL, NULL }, +#endif +#ifdef IPF_RPCB_PROXY +# ifndef _KERNEL + { NULL, NULL, "rpcbt", (char)IPPROTO_TCP, 0, 0, 0, + NULL, NULL, + NULL, NULL, + NULL, NULL, + ipf_p_rpcb_new, ipf_p_rpcb_del, + ipf_p_rpcb_in, ipf_p_rpcb_out, NULL, + NULL, NULL, NULL, NULL }, +# endif + { NULL, NULL, "rpcbu", (char)IPPROTO_UDP, 0, 0, 0, + ipf_p_rpcb_main_load, ipf_p_rpcb_main_unload, + NULL, NULL, + NULL, NULL, + ipf_p_rpcb_new, ipf_p_rpcb_del, + ipf_p_rpcb_in, ipf_p_rpcb_out, NULL, + NULL, NULL, NULL, NULL }, +#endif + { NULL, NULL, "", '\0', 0, 0, 0, + NULL, NULL, + NULL, NULL, + NULL, NULL, + NULL, NULL, + NULL, NULL, NULL, + NULL, NULL, NULL, NULL } +}; + + +/* ------------------------------------------------------------------------ */ +/* Function: ipf_proxy_main_load */ +/* Returns: int - 0 == success, else failure. */ +/* Parameters: Nil */ +/* */ +/* Initialise hook for kernel application proxies. */ +/* Call the initialise routine for all the compiled in kernel proxies. */ +/* ------------------------------------------------------------------------ */ +int +ipf_proxy_main_load() { + aproxy_t *ap; + + for (ap = ips_proxies; ap->apr_p; ap++) { + if (ap->apr_load != NULL) + (*ap->apr_load)(); + } + return 0; +} + + +/* ------------------------------------------------------------------------ */ +/* Function: ipf_proxy_main_unload */ +/* Returns: int - 0 == success, else failure. */ +/* Parameters: Nil */ +/* */ +/* Unload hook for kernel application proxies. */ +/* Call the finialise routine for all the compiled in kernel proxies. */ +/* ------------------------------------------------------------------------ */ +int +ipf_proxy_main_unload() +{ + aproxy_t *ap; + + for (ap = ips_proxies; ap->apr_p; ap++) + if (ap->apr_unload != NULL) + (*ap->apr_unload)(); + for (ap = ap_proxylist; ap; ap = ap->apr_next) + if (ap->apr_unload != NULL) + (*ap->apr_unload)(); + + return 0; +} + + +/* ------------------------------------------------------------------------ */ +/* Function: ipf_proxy_soft_create */ +/* Returns: void * - */ +/* Parameters: softc(I) - pointer to soft context main structure */ +/* */ +/* Build the structure to hold all of the run time data to support proxies. */ +/* ------------------------------------------------------------------------ */ +void * +ipf_proxy_soft_create(softc) + ipf_main_softc_t *softc; +{ + ipf_proxy_softc_t *softp; + aproxy_t *last; + aproxy_t *apn; + aproxy_t *ap; + + KMALLOC(softp, ipf_proxy_softc_t *); + if (softp == NULL) + return softp; + + bzero((char *)softp, sizeof(*softp)); + +#if defined(_KERNEL) + softp->ips_proxy_debug = 0; +#else + softp->ips_proxy_debug = 2; +#endif + softp->ips_proxy_session_size = AP_SESS_SIZE; + + softp->ipf_proxy_tune = ipf_tune_array_copy(softp, + sizeof(ipf_proxy_tuneables), + ipf_proxy_tuneables); + if (softp->ipf_proxy_tune == NULL) { + ipf_proxy_soft_destroy(softc, softp); + return NULL; + } + if (ipf_tune_array_link(softc, softp->ipf_proxy_tune) == -1) { + ipf_proxy_soft_destroy(softc, softp); + return NULL; + } + + last = NULL; + for (ap = ips_proxies; ap->apr_p; ap++) { + apn = ipf_proxy_create_clone(softc, ap); + if (apn == NULL) + goto failed; + if (last != NULL) + last->apr_next = apn; + else + softp->ips_proxies = apn; + last = apn; + } + for (ap = ips_proxies; ap != NULL; ap = ap->apr_next) { + apn = ipf_proxy_create_clone(softc, ap); + if (apn == NULL) + goto failed; + if (last != NULL) + last->apr_next = apn; + else + softp->ips_proxies = apn; + last = apn; + } + + return softp; +failed: + ipf_proxy_soft_destroy(softc, softp); + return NULL; +} + + +/* ------------------------------------------------------------------------ */ +/* Function: ipf_proxy_soft_create */ +/* Returns: void * - */ +/* Parameters: softc(I) - pointer to soft context main structure */ +/* orig(I) - pointer to proxy definition to copy */ +/* */ +/* This function clones a proxy definition given by orig and returns a */ +/* a pointer to that copy. */ +/* ------------------------------------------------------------------------ */ +static aproxy_t * +ipf_proxy_create_clone(softc, orig) + ipf_main_softc_t *softc; + aproxy_t *orig; +{ + aproxy_t *apn; + + KMALLOC(apn, aproxy_t *); + if (apn == NULL) + return NULL; + + bcopy((char *)orig, (char *)apn, sizeof(*apn)); + apn->apr_next = NULL; + apn->apr_soft = NULL; + + if (apn->apr_create != NULL) { + apn->apr_soft = (*apn->apr_create)(softc); + if (apn->apr_soft == NULL) { + KFREE(apn); + return NULL; + } + } + + apn->apr_parent = orig; + orig->apr_clones++; + + return apn; +} + + +/* ------------------------------------------------------------------------ */ +/* Function: ipf_proxy_soft_create */ +/* Returns: int - 0 == success, else failure. */ +/* Parameters: softc(I) - pointer to soft context main structure */ +/* arg(I) - pointer to proxy contect data */ +/* */ +/* Initialise the proxy context and walk through each of the proxies and */ +/* call its initialisation function. This allows for proxies to do any */ +/* local setup prior to actual use. */ +/* ------------------------------------------------------------------------ */ +int +ipf_proxy_soft_init(softc, arg) + ipf_main_softc_t *softc; + void *arg; +{ + ipf_proxy_softc_t *softp; + aproxy_t *ap; + u_int size; + int err; + + softp = arg; + size = softp->ips_proxy_session_size * sizeof(ap_session_t *); + + KMALLOCS(softp->ips_sess_tab, ap_session_t **, size); + + if (softp->ips_sess_tab == NULL) + return -1; + + bzero(softp->ips_sess_tab, size); + + for (ap = softp->ips_proxies; ap != NULL; ap = ap->apr_next) { + if (ap->apr_init != NULL) { + err = (*ap->apr_init)(softc, ap->apr_soft); + if (err != 0) + return -2; + } + } + softp->ips_init_run = 1; + + return 0; +} + + +/* ------------------------------------------------------------------------ */ +/* Function: ipf_proxy_soft_create */ +/* Returns: int - 0 == success, else failure. */ +/* Parameters: softc(I) - pointer to soft context main structure */ +/* arg(I) - pointer to proxy contect data */ +/* */ +/* This function should always succeed. It is responsible for ensuring that */ +/* the proxy context can be safely called when ipf_proxy_soft_destroy is */ +/* called and suring all of the proxies have similarly been instructed. */ +/* ------------------------------------------------------------------------ */ +int +ipf_proxy_soft_fini(softc, arg) + ipf_main_softc_t *softc; + void *arg; +{ + ipf_proxy_softc_t *softp = arg; + aproxy_t *ap; + + for (ap = softp->ips_proxies; ap != NULL; ap = ap->apr_next) { + if (ap->apr_fini != NULL) { + (*ap->apr_fini)(softc, ap->apr_soft); + } + } + + if (softp->ips_sess_tab != NULL) { + KFREES(softp->ips_sess_tab, + softp->ips_proxy_session_size * sizeof(ap_session_t *)); + softp->ips_sess_tab = NULL; + } + softp->ips_init_run = 0; + + return 0; +} + + +/* ------------------------------------------------------------------------ */ +/* Function: ipf_proxy_soft_destroy */ +/* Returns: Nil */ +/* Parameters: softc(I) - pointer to soft context main structure */ +/* arg(I) - pointer to proxy contect data */ +/* */ +/* Free up all of the local data structures allocated during creation. */ +/* ------------------------------------------------------------------------ */ +void +ipf_proxy_soft_destroy(softc, arg) + ipf_main_softc_t *softc; + void *arg; +{ + ipf_proxy_softc_t *softp = arg; + aproxy_t *ap; + + while ((ap = softp->ips_proxies) != NULL) { + softp->ips_proxies = ap->apr_next; + if (ap->apr_destroy != NULL) + (*ap->apr_destroy)(softc, ap->apr_soft); + ap->apr_parent->apr_clones--; + KFREE(ap); + } + + if (softp->ipf_proxy_tune != NULL) { + ipf_tune_array_unlink(softc, softp->ipf_proxy_tune); + KFREES(softp->ipf_proxy_tune, sizeof(ipf_proxy_tuneables)); + softp->ipf_proxy_tune = NULL; + } + + KFREE(softp); +} + + +/* ------------------------------------------------------------------------ */ +/* Function: ipf_proxy_flush */ +/* Returns: Nil */ +/* Parameters: arg(I) - pointer to proxy contect data */ +/* how(I) - indicates the type of flush operation */ +/* */ +/* Walk through all of the proxies and pass on the flush command as either */ +/* a flush or a clear. */ +/* ------------------------------------------------------------------------ */ +void +ipf_proxy_flush(arg, how) + void *arg; + int how; +{ + ipf_proxy_softc_t *softp = arg; + aproxy_t *ap; + + switch (how) + { + case 0 : + for (ap = softp->ips_proxies; ap; ap = ap->apr_next) + if (ap->apr_flush != NULL) + (*ap->apr_flush)(ap, how); + break; + case 1 : + for (ap = softp->ips_proxies; ap; ap = ap->apr_next) + if (ap->apr_clear != NULL) + (*ap->apr_clear)(ap); + break; + default : + break; + } +} + + +/* ------------------------------------------------------------------------ */ +/* Function: ipf_proxy_add */ +/* Returns: int - 0 == success, else failure. */ +/* Parameters: ap(I) - pointer to proxy structure */ +/* */ +/* Dynamically add a new kernel proxy. Ensure that it is unique in the */ +/* collection compiled in and dynamically added. */ +/* ------------------------------------------------------------------------ */ +int +ipf_proxy_add(arg, ap) + void *arg; + aproxy_t *ap; +{ + ipf_proxy_softc_t *softp = arg; + aproxy_t *a; - for (a = ap_proxies; a->apr_p; a++) + for (a = ips_proxies; a->apr_p; a++) if ((a->apr_p == ap->apr_p) && !strncmp(a->apr_label, ap->apr_label, sizeof(ap->apr_label))) { - if (ipf_proxy_debug > 1) - printf("appr_add: %s/%d already present (B)\n", + if (softp->ips_proxy_debug & 0x01) + printf("ipf_proxy_add: %s/%d present (B)\n", a->apr_label, a->apr_p); return -1; } @@ -196,89 +576,113 @@ aproxy_t *ap; if ((a->apr_p == ap->apr_p) && !strncmp(a->apr_label, ap->apr_label, sizeof(ap->apr_label))) { - if (ipf_proxy_debug > 1) - printf("appr_add: %s/%d already present (D)\n", + if (softp->ips_proxy_debug & 0x01) + printf("ipf_proxy_add: %s/%d present (D)\n", a->apr_label, a->apr_p); return -1; } ap->apr_next = ap_proxylist; ap_proxylist = ap; - if (ap->apr_init != NULL) - return (*ap->apr_init)(); + if (ap->apr_load != NULL) + (*ap->apr_load)(); return 0; } -/* - * Check to see if the proxy this control request has come through for - * exists, and if it does and it has a control function then invoke that - * control function. - */ -int appr_ctl(ctl) -ap_ctl_t *ctl; +/* ------------------------------------------------------------------------ */ +/* Function: ipf_proxy_ctl */ +/* Returns: int - 0 == success, else error */ +/* Parameters: softc(I) - pointer to soft context main structure */ +/* arg(I) - pointer to proxy context */ +/* ctl(I) - pointer to proxy control structure */ +/* */ +/* Check to see if the proxy this control request has come through for */ +/* exists, and if it does and it has a control function then invoke that */ +/* control function. */ +/* ------------------------------------------------------------------------ */ +int +ipf_proxy_ctl(softc, arg, ctl) + ipf_main_softc_t *softc; + void *arg; + ap_ctl_t *ctl; { + ipf_proxy_softc_t *softp = arg; aproxy_t *a; int error; - a = appr_lookup(ctl->apc_p, ctl->apc_label); + a = ipf_proxy_lookup(arg, ctl->apc_p, ctl->apc_label); if (a == NULL) { - if (ipf_proxy_debug > 1) - printf("appr_ctl: can't find %s/%d\n", + if (softp->ips_proxy_debug & 0x01) + printf("ipf_proxy_ctl: can't find %s/%d\n", ctl->apc_label, ctl->apc_p); + IPFERROR(80001); error = ESRCH; } else if (a->apr_ctl == NULL) { - if (ipf_proxy_debug > 1) - printf("appr_ctl: no ctl function for %s/%d\n", + if (softp->ips_proxy_debug & 0x01) + printf("ipf_proxy_ctl: no ctl function for %s/%d\n", ctl->apc_label, ctl->apc_p); + IPFERROR(80002); error = ENXIO; } else { - error = (*a->apr_ctl)(a, ctl); - if ((error != 0) && (ipf_proxy_debug > 1)) - printf("appr_ctl: %s/%d ctl error %d\n", + error = (*a->apr_ctl)(softc, a->apr_soft, ctl); + if ((error != 0) && (softp->ips_proxy_debug & 0x02)) + printf("ipf_proxy_ctl: %s/%d ctl error %d\n", a->apr_label, a->apr_p, error); } return error; } -/* - * Delete a proxy that has been added dynamically from those available. - * If it is in use, return 1 (do not destroy NOW), not in use 0 or -1 - * if it cannot be matched. - */ -int appr_del(ap) -aproxy_t *ap; +/* ------------------------------------------------------------------------ */ +/* Function: ipf_proxy_del */ +/* Returns: int - 0 == success, else failure. */ +/* Parameters: ap(I) - pointer to proxy structure */ +/* */ +/* Delete a proxy that has been added dynamically from those available. */ +/* If it is in use, return 1 (do not destroy NOW), not in use 0 or -1 */ +/* if it cannot be matched. */ +/* ------------------------------------------------------------------------ */ +int +ipf_proxy_del(ap) + aproxy_t *ap; { aproxy_t *a, **app; - for (app = &ap_proxylist; ((a = *app) != NULL); app = &a->apr_next) + for (app = &ap_proxylist; ((a = *app) != NULL); app = &a->apr_next) { if (a == ap) { a->apr_flags |= APR_DELETE; - *app = a->apr_next; - if (ap->apr_ref != 0) { - if (ipf_proxy_debug > 2) - printf("appr_del: orphaning %s/%d\n", - ap->apr_label, ap->apr_p); - return 1; + if (ap->apr_ref == 0 && ap->apr_clones == 0) { + *app = a->apr_next; + return 0; } - return 0; + return 1; } - if (ipf_proxy_debug > 1) - printf("appr_del: proxy %lx not found\n", (u_long)ap); + } + return -1; } -/* - * Return 1 if the packet is a good match against a proxy, else 0. - */ -int appr_ok(fin, tcp, nat) -fr_info_t *fin; -tcphdr_t *tcp; -ipnat_t *nat; +/* ------------------------------------------------------------------------ */ +/* Function: ipf_proxy_ok */ +/* Returns: int - 1 == good match else not. */ +/* Parameters: fin(I) - pointer to packet information */ +/* tcp(I) - pointer to TCP/UDP header */ +/* nat(I) - pointer to current NAT session */ +/* */ +/* This function extends the NAT matching to ensure that a packet that has */ +/* arrived matches the proxy information attached to the NAT rule. Notably, */ +/* if the proxy is scheduled to be deleted then packets will not match the */ +/* rule even if the rule is still active. */ +/* ------------------------------------------------------------------------ */ +int +ipf_proxy_ok(fin, tcp, np) + fr_info_t *fin; + tcphdr_t *tcp; + ipnat_t *np; { - aproxy_t *apr = nat->in_apr; - u_short dport = nat->in_dport; + aproxy_t *apr = np->in_apr; + u_short dport = np->in_odport; if ((apr == NULL) || (apr->apr_flags & APR_DELETE) || (fin->fin_p != apr->apr_p)) @@ -289,14 +693,26 @@ ipnat_t *nat; } -int appr_ioctl(data, cmd, mode, ctx) -caddr_t data; -ioctlcmd_t cmd; -int mode; -void *ctx; +/* ------------------------------------------------------------------------ */ +/* Function: ipf_proxy_ioctl */ +/* Returns: int - 0 == success, else error */ +/* Parameters: softc(I) - pointer to soft context main structure */ +/* data(I) - pointer to ioctl data */ +/* cmd(I) - ioctl command */ +/* mode(I) - mode bits for device */ +/* ctx(I) - pointer to context information */ +/* */ +/* ------------------------------------------------------------------------ */ +int +ipf_proxy_ioctl(softc, data, cmd, mode, ctx) + ipf_main_softc_t *softc; + caddr_t data; + ioctlcmd_t cmd; + int mode; + void *ctx; { ap_ctl_t ctl; - u_char *ptr; + caddr_t ptr; int error; mode = mode; /* LINT */ @@ -304,17 +720,19 @@ void *ctx; switch (cmd) { case SIOCPROXY : - error = BCOPYIN(data, &ctl, sizeof(ctl)); - if (error != 0) - return EFAULT; + error = ipf_inobj(softc, data, NULL, &ctl, IPFOBJ_PROXYCTL); + if (error != 0) { + return error; + } ptr = NULL; if (ctl.apc_dsize > 0) { - KMALLOCS(ptr, u_char *, ctl.apc_dsize); - if (ptr == NULL) + KMALLOCS(ptr, caddr_t, ctl.apc_dsize); + if (ptr == NULL) { + IPFERROR(80003); error = ENOMEM; - else { - error = copyinptr(ctl.apc_data, ptr, + } else { + error = copyinptr(softc, ctl.apc_data, ptr, ctl.apc_dsize); if (error == 0) ctl.apc_data = ptr; @@ -325,49 +743,61 @@ void *ctx; } if (error == 0) - error = appr_ctl(&ctl); + error = ipf_proxy_ctl(softc, softc->ipf_proxy_soft, + &ctl); - if (ptr != NULL) { + if ((error != 0) && (ptr != NULL)) { KFREES(ptr, ctl.apc_dsize); } break; default : + IPFERROR(80004); error = EINVAL; } return error; } -/* - * If a proxy has a match function, call that to do extended packet - * matching. - */ -int appr_match(fin, nat) -fr_info_t *fin; -nat_t *nat; +/* ------------------------------------------------------------------------ */ +/* Function: ipf_proxy_match */ +/* Returns: int - 0 == success, else error */ +/* Parameters: fin(I) - pointer to packet information */ +/* nat(I) - pointer to current NAT session */ +/* */ +/* If a proxy has a match function, call that to do extended packet */ +/* matching. Whilst other parts of the NAT code are rather lenient when it */ +/* comes to the quality of the packet that it will transform, the proxy */ +/* matching is not because they need to work with data, not just headers. */ +/* ------------------------------------------------------------------------ */ +int +ipf_proxy_match(fin, nat) + fr_info_t *fin; + nat_t *nat; { + ipf_main_softc_t *softc = fin->fin_main_soft; + ipf_proxy_softc_t *softp = softc->ipf_proxy_soft; aproxy_t *apr; ipnat_t *ipn; int result; ipn = nat->nat_ptr; - if (ipf_proxy_debug > 8) - printf("appr_match(%lx,%lx) aps %lx ptr %lx\n", + if (softp->ips_proxy_debug & 0x04) + printf("ipf_proxy_match(%lx,%lx) aps %lx ptr %lx\n", (u_long)fin, (u_long)nat, (u_long)nat->nat_aps, (u_long)ipn); if ((fin->fin_flx & (FI_SHORT|FI_BAD)) != 0) { - if (ipf_proxy_debug > 0) - printf("appr_match: flx 0x%x (BAD|SHORT)\n", + if (softp->ips_proxy_debug & 0x08) + printf("ipf_proxy_match: flx 0x%x (BAD|SHORT)\n", fin->fin_flx); return -1; } apr = ipn->in_apr; if ((apr == NULL) || (apr->apr_flags & APR_DELETE)) { - if (ipf_proxy_debug > 0) - printf("appr_match:apr %lx apr_flags 0x%x\n", + if (softp->ips_proxy_debug & 0x08) + printf("ipf_proxy_match:apr %lx apr_flags 0x%x\n", (u_long)apr, apr ? apr->apr_flags : 0); return -1; } @@ -375,8 +805,8 @@ nat_t *nat; if (apr->apr_match != NULL) { result = (*apr->apr_match)(fin, nat->nat_aps, nat); if (result != 0) { - if (ipf_proxy_debug > 4) - printf("appr_match: result %d\n", result); + if (softp->ips_proxy_debug & 0x08) + printf("ipf_proxy_match: result %d\n", result); return -1; } } @@ -384,24 +814,32 @@ nat_t *nat; } -/* - * Allocate a new application proxy structure and fill it in with the - * relevant details. call the init function once complete, prior to - * returning. - */ -int appr_new(fin, nat) -fr_info_t *fin; -nat_t *nat; +/* ------------------------------------------------------------------------ */ +/* Function: ipf_proxy_new */ +/* Returns: int - 0 == success, else error */ +/* Parameters: fin(I) - pointer to packet information */ +/* nat(I) - pointer to current NAT session */ +/* */ +/* Allocate a new application proxy structure and fill it in with the */ +/* relevant details. call the init function once complete, prior to */ +/* returning. */ +/* ------------------------------------------------------------------------ */ +int +ipf_proxy_new(fin, nat) + fr_info_t *fin; + nat_t *nat; { + ipf_main_softc_t *softc = fin->fin_main_soft; + ipf_proxy_softc_t *softp = softc->ipf_proxy_soft; register ap_session_t *aps; aproxy_t *apr; - if (ipf_proxy_debug > 8) - printf("appr_new(%lx,%lx) \n", (u_long)fin, (u_long)nat); + if (softp->ips_proxy_debug & 0x04) + printf("ipf_proxy_new(%lx,%lx) \n", (u_long)fin, (u_long)nat); if ((nat->nat_ptr == NULL) || (nat->nat_aps != NULL)) { - if (ipf_proxy_debug > 0) - printf("appr_new: nat_ptr %lx nat_aps %lx\n", + if (softp->ips_proxy_debug & 0x08) + printf("ipf_proxy_new: nat_ptr %lx nat_aps %lx\n", (u_long)nat->nat_ptr, (u_long)nat->nat_aps); return -1; } @@ -410,65 +848,71 @@ nat_t *nat; if ((apr->apr_flags & APR_DELETE) || (fin->fin_p != apr->apr_p)) { - if (ipf_proxy_debug > 2) - printf("appr_new: apr_flags 0x%x p %d/%d\n", + if (softp->ips_proxy_debug & 0x08) + printf("ipf_proxy_new: apr_flags 0x%x p %d/%d\n", apr->apr_flags, fin->fin_p, apr->apr_p); return -1; } KMALLOC(aps, ap_session_t *); if (!aps) { - if (ipf_proxy_debug > 0) - printf("appr_new: malloc failed (%lu)\n", + if (softp->ips_proxy_debug & 0x08) + printf("ipf_proxy_new: malloc failed (%lu)\n", (u_long)sizeof(ap_session_t)); return -1; } bzero((char *)aps, sizeof(*aps)); - aps->aps_p = fin->fin_p; aps->aps_data = NULL; aps->aps_apr = apr; aps->aps_psiz = 0; if (apr->apr_new != NULL) - if ((*apr->apr_new)(fin, aps, nat) == -1) { + if ((*apr->apr_new)(apr->apr_soft, fin, aps, nat) == -1) { if ((aps->aps_data != NULL) && (aps->aps_psiz != 0)) { KFREES(aps->aps_data, aps->aps_psiz); } KFREE(aps); - if (ipf_proxy_debug > 2) - printf("appr_new: new(%lx) failed\n", + if (softp->ips_proxy_debug & 0x08) + printf("ipf_proxy_new: new(%lx) failed\n", (u_long)apr->apr_new); return -1; } aps->aps_nat = nat; - aps->aps_next = ap_sess_list; - ap_sess_list = aps; + aps->aps_next = softp->ips_sess_list; + softp->ips_sess_list = aps; nat->nat_aps = aps; return 0; } -/* - * Check to see if a packet should be passed through an active proxy routine - * if one has been setup for it. We don't need to check the checksum here if - * IPFILTER_CKSUM is defined because if it is, a failed check causes FI_BAD - * to be set. - */ -int appr_check(fin, nat) -fr_info_t *fin; -nat_t *nat; +/* ------------------------------------------------------------------------ */ +/* Function: ipf_proxy_check */ +/* Returns: int - -1 == error, 0 == success */ +/* Parameters: fin(I) - pointer to packet information */ +/* nat(I) - pointer to current NAT session */ +/* */ +/* Check to see if a packet should be passed through an active proxy */ +/* routine if one has been setup for it. We don't need to check the */ +/* checksum here if IPFILTER_CKSUM is defined because if it is, a failed */ +/* check causes FI_BAD to be set. */ +/* ------------------------------------------------------------------------ */ +int +ipf_proxy_check(fin, nat) + fr_info_t *fin; + nat_t *nat; { -#if SOLARIS && defined(_KERNEL) && (SOLARIS2 >= 6) -# if defined(ICK_VALID) + ipf_main_softc_t *softc = fin->fin_main_soft; + ipf_proxy_softc_t *softp = softc->ipf_proxy_soft; +#if SOLARIS && defined(_KERNEL) && defined(ICK_VALID) mb_t *m; -# endif - int dosum = 1; #endif tcphdr_t *tcp = NULL; udphdr_t *udp = NULL; ap_session_t *aps; aproxy_t *apr; + short adjlen; + int dosum; ip_t *ip; short rv; int err; @@ -477,55 +921,54 @@ nat_t *nat; #endif if (fin->fin_flx & FI_BAD) { - if (ipf_proxy_debug > 0) - printf("appr_check: flx 0x%x (BAD)\n", fin->fin_flx); + if (softp->ips_proxy_debug & 0x08) + printf("ipf_proxy_check: flx 0x%x (BAD)\n", + fin->fin_flx); return -1; } #ifndef IPFILTER_CKSUM - if ((fin->fin_out == 0) && (fr_checkl4sum(fin) == -1)) { - if (ipf_proxy_debug > 0) - printf("appr_check: l4 checksum failure %d\n", + if ((fin->fin_out == 0) && (ipf_checkl4sum(fin) == -1)) { + if (softp->ips_proxy_debug & 0x08) + printf("ipf_proxy_check: l4 checksum failure %d\n", fin->fin_p); if (fin->fin_p == IPPROTO_TCP) - frstats[fin->fin_out].fr_tcpbad++; + softc->ipf_stats[fin->fin_out].fr_tcpbad++; return -1; } #endif aps = nat->nat_aps; - if ((aps != NULL) && (aps->aps_p == fin->fin_p)) { + if (aps != NULL) { /* * If there is data in this packet to be proxied then try and * get it all into the one buffer, else drop it. */ #if defined(MENTAT) || defined(HAVE_M_PULLDOWN) if ((fin->fin_dlen > 0) && !(fin->fin_flx & FI_COALESCE)) - if (fr_coalesce(fin) == -1) { - if (ipf_proxy_debug > 0) - printf("appr_check: fr_coalesce failed %x\n", fin->fin_flx); + if (ipf_coalesce(fin) == -1) { + if (softp->ips_proxy_debug & 0x08) + printf("ipf_proxy_check: %s %x\n", + "coalesce failed", fin->fin_flx); return -1; } #endif ip = fin->fin_ip; + if (fin->fin_cksum > FI_CK_SUMOK) + dosum = 0; + else + dosum = 1; switch (fin->fin_p) { case IPPROTO_TCP : tcp = (tcphdr_t *)fin->fin_dp; - -#if SOLARIS && defined(_KERNEL) && (SOLARIS2 >= 6) && defined(ICK_VALID) +#if SOLARIS && defined(_KERNEL) && defined(ICK_VALID) m = fin->fin_qfm; if (dohwcksum && (m->b_ick_flag == ICK_VALID)) dosum = 0; #endif - /* - * Don't bother the proxy with these...or in fact, - * should we free up proxy stuff when seen? - */ - if ((fin->fin_tcpf & TH_RST) != 0) - break; - /*FALLTHROUGH*/ + break; case IPPROTO_UDP : udp = (udphdr_t *)fin->fin_dp; break; @@ -537,22 +980,24 @@ nat_t *nat; err = 0; if (fin->fin_out != 0) { if (apr->apr_outpkt != NULL) - err = (*apr->apr_outpkt)(fin, aps, nat); + err = (*apr->apr_outpkt)(apr->apr_soft, fin, + aps, nat); } else { if (apr->apr_inpkt != NULL) - err = (*apr->apr_inpkt)(fin, aps, nat); + err = (*apr->apr_inpkt)(apr->apr_soft, fin, + aps, nat); } rv = APR_EXIT(err); - if (((ipf_proxy_debug > 0) && (rv != 0)) || - (ipf_proxy_debug > 8)) - printf("appr_check: out %d err %x rv %d\n", + if (((softp->ips_proxy_debug & 0x08) && (rv != 0)) || + (softp->ips_proxy_debug & 0x04)) + printf("ipf_proxy_check: out %d err %x rv %d\n", fin->fin_out, err, rv); if (rv == 1) return -1; if (rv == 2) { - appr_free(apr); + ipf_proxy_deref(apr); nat->nat_aps = NULL; return -1; } @@ -562,16 +1007,17 @@ nat_t *nat; * so we need to recalculate the header checksums for the * packet. */ + adjlen = APR_INC(err); #if !defined(_KERNEL) || defined(MENTAT) || defined(__sgi) - if (err != 0) { - short adjlen = err & 0xffff; - - s1 = LONG_SUM(fin->fin_plen - adjlen); - s2 = LONG_SUM(fin->fin_plen); - CALC_SUMD(s1, s2, sd); - fix_outcksum(fin, &ip->ip_sum, sd); - } + s1 = LONG_SUM(fin->fin_plen - adjlen); + s2 = LONG_SUM(fin->fin_plen); + CALC_SUMD(s1, s2, sd); + if ((err != 0) && (fin->fin_cksum < FI_CK_L4PART) && + fin->fin_v == 4) + ipf_fix_outcksum(0, &ip->ip_sum, sd, 0); #endif + if (fin->fin_flx & FI_DOCKSUM) + dosum = 1; /* * For TCP packets, we may need to adjust the sequence and @@ -583,28 +1029,24 @@ nat_t *nat; * changed or not. */ if (tcp != NULL) { - err = appr_fixseqack(fin, ip, aps, APR_INC(err)); -#if SOLARIS && defined(_KERNEL) && (SOLARIS2 >= 6) - if (dosum) - tcp->th_sum = fr_cksum(fin->fin_qfm, ip, - IPPROTO_TCP, tcp, - fin->fin_plen); -#else - tcp->th_sum = fr_cksum(fin->fin_m, ip, - IPPROTO_TCP, tcp, - fin->fin_plen); -#endif + err = ipf_proxy_fixseqack(fin, ip, aps, adjlen); + if (fin->fin_cksum == FI_CK_L4PART) { + u_short sum = ntohs(tcp->th_sum); + sum += adjlen; + tcp->th_sum = htons(sum); + } else if (fin->fin_cksum < FI_CK_L4PART) { + tcp->th_sum = fr_cksum(fin, ip, + IPPROTO_TCP, tcp); + } } else if ((udp != NULL) && (udp->uh_sum != 0)) { -#if SOLARIS && defined(_KERNEL) && (SOLARIS2 >= 6) - if (dosum) - udp->uh_sum = fr_cksum(fin->fin_qfm, ip, - IPPROTO_UDP, udp, - fin->fin_plen); -#else - udp->uh_sum = fr_cksum(fin->fin_m, ip, - IPPROTO_UDP, udp, - fin->fin_plen); -#endif + if (fin->fin_cksum == FI_CK_L4PART) { + u_short sum = ntohs(udp->uh_sum); + sum += adjlen; + udp->uh_sum = htons(sum); + } else if (dosum) { + udp->uh_sum = fr_cksum(fin, ip, + IPPROTO_UDP, udp); + } } aps->aps_bytes += fin->fin_plen; aps->aps_pkts++; @@ -614,54 +1056,78 @@ nat_t *nat; } -/* - * Search for an proxy by the protocol it is being used with and its name. - */ -aproxy_t *appr_lookup(pr, name) -u_int pr; -char *name; +/* ------------------------------------------------------------------------ */ +/* Function: ipf_proxy_lookup */ +/* Returns: int - -1 == error, 0 == success */ +/* Parameters: arg(I) - pointer to proxy context information */ +/* pr(I) - protocol number for proxy */ +/* name(I) - proxy name */ +/* */ +/* Search for an proxy by the protocol it is being used with and its name. */ +/* ------------------------------------------------------------------------ */ +aproxy_t * +ipf_proxy_lookup(arg, pr, name) + void *arg; + u_int pr; + char *name; { + ipf_proxy_softc_t *softp = arg; aproxy_t *ap; - if (ipf_proxy_debug > 8) - printf("appr_lookup(%d,%s)\n", pr, name); + if (softp->ips_proxy_debug & 0x04) + printf("ipf_proxy_lookup(%d,%s)\n", pr, name); - for (ap = ap_proxies; ap->apr_p; ap++) + for (ap = softp->ips_proxies; ap != NULL; ap = ap->apr_next) if ((ap->apr_p == pr) && !strncmp(name, ap->apr_label, sizeof(ap->apr_label))) { ap->apr_ref++; return ap; } - for (ap = ap_proxylist; ap; ap = ap->apr_next) - if ((ap->apr_p == pr) && - !strncmp(name, ap->apr_label, sizeof(ap->apr_label))) { - ap->apr_ref++; - return ap; - } - if (ipf_proxy_debug > 2) - printf("appr_lookup: failed for %d/%s\n", pr, name); + if (softp->ips_proxy_debug & 0x08) + printf("ipf_proxy_lookup: failed for %d/%s\n", pr, name); return NULL; } -void appr_free(ap) -aproxy_t *ap; +/* ------------------------------------------------------------------------ */ +/* Function: ipf_proxy_deref */ +/* Returns: Nil */ +/* Parameters: ap(I) - pointer to proxy structure */ +/* */ +/* Drop the reference counter associated with the proxy. */ +/* ------------------------------------------------------------------------ */ +void +ipf_proxy_deref(ap) + aproxy_t *ap; { ap->apr_ref--; } -void aps_free(aps) -ap_session_t *aps; +/* ------------------------------------------------------------------------ */ +/* Function: ipf_proxy_free */ +/* Returns: Nil */ +/* Parameters: softc(I) - pointer to soft context main structure */ +/* aps(I) - pointer to current proxy session */ +/* Locks Held: ipf_nat_new, ipf_nat(W) */ +/* */ +/* Free up proxy session information allocated to be used with a NAT */ +/* session. */ +/* ------------------------------------------------------------------------ */ +void +ipf_proxy_free(softc, aps) + ipf_main_softc_t *softc; + ap_session_t *aps; { + ipf_proxy_softc_t *softp = softc->ipf_proxy_soft; ap_session_t *a, **ap; aproxy_t *apr; if (!aps) return; - for (ap = &ap_sess_list; ((a = *ap) != NULL); ap = &a->aps_next) + for (ap = &softp->ips_sess_list; ((a = *ap) != NULL); ap = &a->aps_next) if (a == aps) { *ap = a->aps_next; break; @@ -669,7 +1135,7 @@ ap_session_t *aps; apr = aps->aps_apr; if ((apr != NULL) && (apr->apr_del != NULL)) - (*apr->apr_del)(aps); + (*apr->apr_del)(softc, aps); if ((aps->aps_data != NULL) && (aps->aps_psiz != 0)) KFREES(aps->aps_data, aps->aps_psiz); @@ -677,15 +1143,28 @@ ap_session_t *aps; } -/* - * returns 2 if ack or seq number in TCP header is changed, returns 0 otherwise - */ -static int appr_fixseqack(fin, ip, aps, inc) -fr_info_t *fin; -ip_t *ip; -ap_session_t *aps; -int inc; +/* ------------------------------------------------------------------------ */ +/* Function: ipf_proxy_fixseqack */ +/* Returns: int - 2 if TCP ack/seq is changed, else 0 */ +/* Parameters: fin(I) - pointer to packet information */ +/* ip(I) - pointer to IP header */ +/* nat(I) - pointer to current NAT session */ +/* inc(I) - delta to apply to TCP sequence numbering */ +/* */ +/* Adjust the TCP sequence/acknowledge numbers in the TCP header based on */ +/* whether or not the new header is past the point at which an adjustment */ +/* occurred. This might happen because of (say) an FTP string being changed */ +/* and the new string being a different length to the old. */ +/* ------------------------------------------------------------------------ */ +static int +ipf_proxy_fixseqack(fin, ip, aps, inc) + fr_info_t *fin; + ip_t *ip; + ap_session_t *aps; + int inc; { + ipf_main_softc_t *softc = fin->fin_main_soft; + ipf_proxy_softc_t *softp = softc->ipf_proxy_soft; int sel, ch = 0, out, nlen; u_32_t seq1, seq2; tcphdr_t *tcp; @@ -694,10 +1173,10 @@ int inc; tcp = (tcphdr_t *)fin->fin_dp; out = fin->fin_out; /* - * fin->fin_plen has already been adjusted by 'inc'. + * ip_len has already been adjusted by 'inc'. */ - nlen = fin->fin_plen; - nlen -= (IP_HL(ip) << 2) + (TCP_OFF(tcp) << 2); + nlen = fin->fin_dlen; + nlen -= (TCP_OFF(tcp) << 2); inc2 = inc; inc = (int)inc2; @@ -709,7 +1188,7 @@ int inc; /* switch to other set ? */ if ((aps->aps_seqmin[!sel] > aps->aps_seqmin[sel]) && (seq1 > aps->aps_seqmin[!sel])) { - if (ipf_proxy_debug > 7) + if (softp->ips_proxy_debug & 0x10) printf("proxy out switch set seq %d -> %d %x > %x\n", sel, !sel, seq1, aps->aps_seqmin[!sel]); @@ -729,7 +1208,7 @@ int inc; if (inc && (seq1 > aps->aps_seqmin[!sel])) { aps->aps_seqmin[sel] = seq1 + nlen - 1; aps->aps_seqoff[sel] = aps->aps_seqoff[sel] + inc; - if (ipf_proxy_debug > 7) + if (softp->ips_proxy_debug & 0x10) printf("proxy seq set %d at %x to %d + %d\n", sel, aps->aps_seqmin[sel], aps->aps_seqoff[sel], inc); @@ -743,7 +1222,7 @@ int inc; /* switch to other set ? */ if ((aps->aps_ackmin[!sel] > aps->aps_ackmin[sel]) && (seq1 > aps->aps_ackmin[!sel])) { - if (ipf_proxy_debug > 7) + if (softp->ips_proxy_debug & 0x10) printf("proxy out switch set ack %d -> %d %x > %x\n", sel, !sel, seq1, aps->aps_ackmin[!sel]); @@ -762,7 +1241,7 @@ int inc; /* switch to other set ? */ if ((aps->aps_ackmin[!sel] > aps->aps_ackmin[sel]) && (seq1 > aps->aps_ackmin[!sel])) { - if (ipf_proxy_debug > 7) + if (softp->ips_proxy_debug & 0x10) printf("proxy in switch set ack %d -> %d %x > %x\n", sel, !sel, seq1, aps->aps_ackmin[!sel]); sel = aps->aps_sel[out] = !sel; @@ -782,7 +1261,7 @@ int inc; aps->aps_ackmin[!sel] = seq1 + nlen - 1; aps->aps_ackoff[!sel] = aps->aps_ackoff[sel] + inc; - if (ipf_proxy_debug > 7) + if (softp->ips_proxy_debug & 0x10) printf("proxy ack set %d at %x to %d + %d\n", !sel, aps->aps_seqmin[!sel], aps->aps_seqoff[sel], inc); @@ -796,14 +1275,14 @@ int inc; /* switch to other set ? */ if ((aps->aps_seqmin[!sel] > aps->aps_seqmin[sel]) && (seq1 > aps->aps_seqmin[!sel])) { - if (ipf_proxy_debug > 7) + if (softp->ips_proxy_debug & 0x10) printf("proxy in switch set seq %d -> %d %x > %x\n", sel, !sel, seq1, aps->aps_seqmin[!sel]); sel = aps->aps_sel[1 - out] = !sel; } if (aps->aps_seqoff[sel] != 0) { - if (ipf_proxy_debug > 7) + if (softp->ips_proxy_debug & 0x10) printf("sel %d seqoff %d seq1 %x seqmin %x\n", sel, aps->aps_seqoff[sel], seq1, aps->aps_seqmin[sel]); @@ -815,45 +1294,175 @@ int inc; } } - if (ipf_proxy_debug > 8) - printf("appr_fixseqack: seq %x ack %x\n", + if (softp->ips_proxy_debug & 0x10) + printf("ipf_proxy_fixseqack: seq %u ack %u\n", (u_32_t)ntohl(tcp->th_seq), (u_32_t)ntohl(tcp->th_ack)); return ch ? 2 : 0; } -/* - * Initialise hook for kernel application proxies. - * Call the initialise routine for all the compiled in kernel proxies. - */ -int appr_init() +/* ------------------------------------------------------------------------ */ +/* Function: ipf_proxy_rule_rev */ +/* Returns: ipnat_t * - NULL = failure, else pointer to new rule */ +/* Parameters: nat(I) - pointer to NAT session to create rule from */ +/* */ +/* This function creates a NAT rule that is based upon the reverse packet */ +/* flow associated with this NAT session. Thus if this NAT session was */ +/* created with a map rule then this function will create a rdr rule. */ +/* Only address fields and network interfaces are assigned in this function */ +/* and the address fields are formed such that an exact is required. If the */ +/* original rule had a netmask, that is not replicated here not is it */ +/* desired. The ultimate goal here is to create a NAT rule to support a NAT */ +/* session being created that does not have a user configured rule. The */ +/* classic example is supporting the FTP proxy, where a data channel needs */ +/* to be setup, based on the addresses used for the control connection. In */ +/* that case, this function is used to handle creating NAT rules to support */ +/* data connections with the PORT and EPRT commands. */ +/* ------------------------------------------------------------------------ */ +ipnat_t * +ipf_proxy_rule_rev(nat) + nat_t *nat; { - aproxy_t *ap; - int err = 0; + ipnat_t *old; + ipnat_t *ipn; + int size; - for (ap = ap_proxies; ap->apr_p; ap++) { - if (ap->apr_init != NULL) { - err = (*ap->apr_init)(); - if (err != 0) - break; + old = nat->nat_ptr; + size = old->in_size; + + KMALLOCS(ipn, ipnat_t *, size); + if (ipn == NULL) + return NULL; + + bzero((char *)ipn, size); + + ipn->in_use = 1; + ipn->in_hits = 1; + ipn->in_ippip = 1; + ipn->in_apr = NULL; + ipn->in_size = size; + ipn->in_pr[0] = old->in_pr[1]; + ipn->in_pr[1] = old->in_pr[0]; + ipn->in_v[0] = old->in_v[1]; + ipn->in_v[1] = old->in_v[0]; + ipn->in_ifps[0] = old->in_ifps[1]; + ipn->in_ifps[1] = old->in_ifps[0]; + ipn->in_flags = (old->in_flags | IPN_PROXYRULE); + + ipn->in_nsrcip6 = nat->nat_odst6; + ipn->in_osrcip6 = nat->nat_ndst6; + + if ((old->in_redir & NAT_REDIRECT) != 0) { + ipn->in_redir = NAT_MAP; + if (ipn->in_v[0] == 4) { + ipn->in_snip = ntohl(nat->nat_odstaddr); + ipn->in_dnip = ntohl(nat->nat_nsrcaddr); + } else { +#ifdef USE_INET6 + ipn->in_snip6 = nat->nat_odst6; + ipn->in_dnip6 = nat->nat_nsrc6; +#endif } + ipn->in_ndstip6 = nat->nat_nsrc6; + ipn->in_odstip6 = nat->nat_osrc6; + } else { + ipn->in_redir = NAT_REDIRECT; + if (ipn->in_v[0] == 4) { + ipn->in_snip = ntohl(nat->nat_odstaddr); + ipn->in_dnip = ntohl(nat->nat_osrcaddr); + } else { +#ifdef USE_INET6 + ipn->in_snip6 = nat->nat_odst6; + ipn->in_dnip6 = nat->nat_osrc6; +#endif + } + ipn->in_ndstip6 = nat->nat_osrc6; + ipn->in_odstip6 = nat->nat_nsrc6; } - return err; + + IP6_SETONES(&ipn->in_osrcmsk6); + IP6_SETONES(&ipn->in_nsrcmsk6); + IP6_SETONES(&ipn->in_odstmsk6); + IP6_SETONES(&ipn->in_ndstmsk6); + + ipn->in_namelen = old->in_namelen; + ipn->in_ifnames[0] = old->in_ifnames[1]; + ipn->in_ifnames[1] = old->in_ifnames[0]; + bcopy(old->in_names, ipn->in_names, ipn->in_namelen); + MUTEX_INIT(&ipn->in_lock, "ipnat rev rule lock"); + + return ipn; } -/* - * Unload hook for kernel application proxies. - * Call the finialise routine for all the compiled in kernel proxies. - */ -void appr_unload() +/* ------------------------------------------------------------------------ */ +/* Function: ipf_proxy_rule_fwd */ +/* Returns: ipnat_t * - NULL = failure, else pointer to new rule */ +/* Parameters: nat(I) - pointer to NAT session to create rule from */ +/* */ +/* The purpose and rationale of this function is much the same as the above */ +/* function, ipf_proxy_rule_rev, except that a rule is created that matches */ +/* the same direction as that of the existing NAT session. Thus if this NAT */ +/* session was created with a map rule then this function will also create */ +/* a data structure to represent a map rule. Whereas ipf_proxy_rule_rev is */ +/* used to support PORT/EPRT, this function supports PASV/EPSV. */ +/* ------------------------------------------------------------------------ */ +ipnat_t * +ipf_proxy_rule_fwd(nat) + nat_t *nat; { - aproxy_t *ap; + ipnat_t *old; + ipnat_t *ipn; + int size; - for (ap = ap_proxies; ap->apr_p; ap++) - if (ap->apr_fini != NULL) - (*ap->apr_fini)(); - for (ap = ap_proxylist; ap; ap = ap->apr_next) - if (ap->apr_fini != NULL) - (*ap->apr_fini)(); + old = nat->nat_ptr; + size = old->in_size; + + KMALLOCS(ipn, ipnat_t *, size); + if (ipn == NULL) + return NULL; + + bzero((char *)ipn, size); + + ipn->in_use = 1; + ipn->in_hits = 1; + ipn->in_ippip = 1; + ipn->in_apr = NULL; + ipn->in_size = size; + ipn->in_pr[0] = old->in_pr[0]; + ipn->in_pr[1] = old->in_pr[1]; + ipn->in_v[0] = old->in_v[0]; + ipn->in_v[1] = old->in_v[1]; + ipn->in_ifps[0] = nat->nat_ifps[0]; + ipn->in_ifps[1] = nat->nat_ifps[1]; + ipn->in_flags = (old->in_flags | IPN_PROXYRULE); + + ipn->in_nsrcip6 = nat->nat_nsrc6; + ipn->in_osrcip6 = nat->nat_osrc6; + ipn->in_ndstip6 = nat->nat_ndst6; + ipn->in_odstip6 = nat->nat_odst6; + ipn->in_redir = old->in_redir; + + if (ipn->in_v[0] == 4) { + ipn->in_snip = ntohl(nat->nat_nsrcaddr); + ipn->in_dnip = ntohl(nat->nat_ndstaddr); + } else { +#ifdef USE_INET6 + ipn->in_snip6 = nat->nat_nsrc6; + ipn->in_dnip6 = nat->nat_ndst6; +#endif + } + + IP6_SETONES(&ipn->in_osrcmsk6); + IP6_SETONES(&ipn->in_nsrcmsk6); + IP6_SETONES(&ipn->in_odstmsk6); + IP6_SETONES(&ipn->in_ndstmsk6); + + ipn->in_namelen = old->in_namelen; + ipn->in_ifnames[0] = old->in_ifnames[0]; + ipn->in_ifnames[1] = old->in_ifnames[1]; + bcopy(old->in_names, ipn->in_names, ipn->in_namelen); + MUTEX_INIT(&ipn->in_lock, "ipnat fwd rule lock"); + + return ipn; } diff --git a/sys/contrib/ipfilter/netinet/ip_proxy.h b/sys/contrib/ipfilter/netinet/ip_proxy.h index 1bcfc6069e3e..1a1fdfac36aa 100644 --- a/sys/contrib/ipfilter/netinet/ip_proxy.h +++ b/sys/contrib/ipfilter/netinet/ip_proxy.h @@ -1,7 +1,7 @@ /* $FreeBSD$ */ /* - * Copyright (C) 1997-2001 by Darren Reed. + * Copyright (C) 2012 by Darren Reed. * * See the IPFILTER.LICENCE file for details on licencing. * @@ -53,14 +53,11 @@ typedef struct ap_session { struct ap_tcp apu_tcp; struct ap_udp apu_udp; } aps_un; - u_int aps_flags; U_QUAD_T aps_bytes; /* bytes sent */ U_QUAD_T aps_pkts; /* packets sent */ void *aps_nat; /* pointer back to nat struct */ void *aps_data; /* private data */ - int aps_p; /* protocol */ int aps_psiz; /* size of private data */ - struct ap_session *aps_hnext; struct ap_session *aps_next; } ap_session_t; @@ -76,6 +73,7 @@ typedef struct ap_session { typedef struct ap_control { char apc_label[APR_LABELLEN]; + char apc_config[APR_LABELLEN]; u_char apc_p; /* * The following fields are upto the proxy's apr_ctl routine to deal @@ -93,21 +91,36 @@ typedef struct ap_control { size_t apc_dsize; } ap_ctl_t; +#define APC_CMD_ADD 0 +#define APC_CMD_DEL 1 + typedef struct aproxy { struct aproxy *apr_next; + struct aproxy *apr_parent; char apr_label[APR_LABELLEN]; /* Proxy label # */ - u_char apr_p; /* protocol */ - int apr_ref; /* +1 per rule referencing it */ + u_char apr_p; /* protocol */ int apr_flags; - int (* apr_init) __P((void)); - void (* apr_fini) __P((void)); - int (* apr_new) __P((fr_info_t *, ap_session_t *, struct nat *)); - void (* apr_del) __P((ap_session_t *)); - int (* apr_inpkt) __P((fr_info_t *, ap_session_t *, struct nat *)); - int (* apr_outpkt) __P((fr_info_t *, ap_session_t *, struct nat *)); + int apr_ref; + int apr_clones; + void (* apr_load) __P((void)); + void (* apr_unload) __P((void)); + void *(* apr_create) __P((ipf_main_softc_t *)); + void (* apr_destroy) __P((ipf_main_softc_t *, void *)); + int (* apr_init) __P((ipf_main_softc_t *, void *)); + void (* apr_fini) __P((ipf_main_softc_t *, void *)); + int (* apr_new) __P((void *, fr_info_t *, ap_session_t *, + struct nat *)); + void (* apr_del) __P((ipf_main_softc_t *, ap_session_t *)); + int (* apr_inpkt) __P((void *, fr_info_t *, ap_session_t *, + struct nat *)); + int (* apr_outpkt) __P((void *, fr_info_t *, ap_session_t *, + struct nat *)); int (* apr_match) __P((fr_info_t *, ap_session_t *, struct nat *)); - int (* apr_ctl) __P((struct aproxy *, struct ap_control *)); + int (* apr_ctl) __P((ipf_main_softc_t *, void *, ap_ctl_t *)); + int (* apr_clear) __P((struct aproxy *)); + int (* apr_flush) __P((struct aproxy *, int)); + void *apr_soft; } aproxy_t; #define APR_DELETE 1 @@ -116,42 +129,37 @@ typedef struct aproxy { #define APR_EXIT(x) (((x) >> 16) & 0xffff) #define APR_INC(x) ((x) & 0xffff) + +#ifdef _KERNEL /* * Generic #define's to cover missing things in the kernel */ -#ifndef isdigit -#define isdigit(x) ((x) >= '0' && (x) <= '9') -#endif -#ifndef isupper -#define isupper(x) (((unsigned)(x) >= 'A') && ((unsigned)(x) <= 'Z')) -#endif -#ifndef islower -#define islower(x) (((unsigned)(x) >= 'a') && ((unsigned)(x) <= 'z')) -#endif -#ifndef isalpha -#define isalpha(x) (isupper(x) || islower(x)) -#endif -#ifndef toupper -#define toupper(x) (isupper(x) ? (x) : (x) - 'a' + 'A') -#endif -#ifndef isspace -#define isspace(x) (((x) == ' ') || ((x) == '\r') || ((x) == '\n') || \ +# ifndef isdigit +# define isdigit(x) ((x) >= '0' && (x) <= '9') +# endif +# ifndef isupper +# define isupper(x) (((unsigned)(x) >= 'A') && ((unsigned)(x) <= 'Z')) +# endif +# ifndef islower +# define islower(x) (((unsigned)(x) >= 'a') && ((unsigned)(x) <= 'z')) +# endif +# ifndef isalpha +# define isalpha(x) (isupper(x) || islower(x)) +# endif +# ifndef toupper +# define toupper(x) (isupper(x) ? (x) : (x) - 'a' + 'A') +# endif +# ifndef isspace +# define isspace(x) (((x) == ' ') || ((x) == '\r') || ((x) == '\n') || \ ((x) == '\t') || ((x) == '\b')) -#endif +# endif +#endif /* _KERNEL */ /* - * This is the scratch buffer size used to hold strings from the TCP stream - * that we may want to parse. It's an arbitrary size, really, but it must - * be at least as large as IPF_FTPBUFSZ. - */ -#define FTP_BUFSZ 120 - -/* - * This buffer, however, doesn't need to be nearly so big. It just needs to - * be able to squeeze in the largest command it needs to rewrite, Which ones - * does it rewrite? EPRT, PORT, 227 replies. + * For the ftp proxy. */ -#define IPF_FTPBUFSZ 80 /* This *MUST* be >= 53! */ +#define FTP_BUFSZ 160 +#define IPF_FTPBUFSZ 160 typedef struct ftpside { char *ftps_rptr; @@ -159,18 +167,36 @@ typedef struct ftpside { void *ftps_ifp; u_32_t ftps_seq[2]; u_32_t ftps_len; - int ftps_junk; /* 2 = no cr/lf yet, 1 = cannot parse */ + int ftps_junk; int ftps_cmds; + int ftps_cmd; char ftps_buf[FTP_BUFSZ]; } ftpside_t; typedef struct ftpinfo { int ftp_passok; int ftp_incok; + void *ftp_pendstate; + nat_t *ftp_pendnat; ftpside_t ftp_side[2]; } ftpinfo_t; +/* + * IPsec proxy + */ +typedef u_32_t ipsec_cookie_t[2]; + +typedef struct ipsec_pxy { + ipsec_cookie_t ipsc_icookie; + ipsec_cookie_t ipsc_rcookie; + int ipsc_rckset; + nat_t *ipsc_nat; + struct ipstate *ipsc_state; + ipnat_t *ipsc_rule; +} ipsec_pxy_t; + + /* * For the irc proxy. */ @@ -186,6 +212,16 @@ typedef struct ircinfo { } ircinfo_t; +/* + * For the DNS "proxy" + */ +typedef struct dnsinfo { + ipfmutex_t dnsi_lock; + u_short dnsi_id; + char dnsi_buffer[512]; +} dnsinfo_t; + + /* * Real audio proxy structure and #defines */ @@ -230,43 +266,6 @@ typedef struct msnrpcinfo { } msnrpcinfo_t; -/* - * IPSec proxy - */ -typedef u_32_t ipsec_cookie_t[2]; - -typedef struct ipsec_pxy { - ipsec_cookie_t ipsc_icookie; - ipsec_cookie_t ipsc_rcookie; - int ipsc_rckset; - ipnat_t ipsc_rule; - nat_t *ipsc_nat; - struct ipstate *ipsc_state; -} ipsec_pxy_t; - -/* - * PPTP proxy - */ -typedef struct pptp_side { - u_32_t pptps_nexthdr; - u_32_t pptps_next; - int pptps_state; - int pptps_gothdr; - int pptps_len; - int pptps_bytes; - char *pptps_wptr; - char pptps_buffer[512]; -} pptp_side_t; - -typedef struct pptp_pxy { - ipnat_t pptp_rule; - nat_t *pptp_nat; - struct ipstate *pptp_state; - u_short pptp_call[2]; - pptp_side_t pptp_side[2]; -} pptp_pxy_t; - - /* * Sun RPCBIND proxy */ @@ -439,24 +438,26 @@ typedef struct rpcb_session { */ #define XDRALIGN(x) ((((x) % 4) != 0) ? ((((x) + 3) / 4) * 4) : (x)) -extern ap_session_t *ap_sess_tab[AP_SESS_SIZE]; -extern ap_session_t *ap_sess_list; -extern aproxy_t ap_proxies[]; -extern int ippr_ftp_pasvonly; -extern int ipf_proxy_debug; - -extern int appr_add __P((aproxy_t *)); -extern int appr_ctl __P((ap_ctl_t *)); -extern int appr_del __P((aproxy_t *)); -extern int appr_init __P((void)); -extern void appr_unload __P((void)); -extern int appr_ok __P((fr_info_t *, tcphdr_t *, struct ipnat *)); -extern int appr_match __P((fr_info_t *, struct nat *)); -extern void appr_free __P((aproxy_t *)); -extern void aps_free __P((ap_session_t *)); -extern int appr_check __P((fr_info_t *, struct nat *)); -extern aproxy_t *appr_lookup __P((u_int, char *)); -extern int appr_new __P((fr_info_t *, struct nat *)); -extern int appr_ioctl __P((caddr_t, ioctlcmd_t, int, void *)); +extern int ipf_proxy_add __P((void *, aproxy_t *)); +extern int ipf_proxy_check __P((fr_info_t *, struct nat *)); +extern int ipf_proxy_ctl __P((ipf_main_softc_t *, void *, ap_ctl_t *)); +extern int ipf_proxy_del __P((aproxy_t *)); +extern void ipf_proxy_deref __P((aproxy_t *)); +extern void ipf_proxy_flush __P((void *, int)); +extern int ipf_proxy_init __P((void)); +extern int ipf_proxy_ioctl __P((ipf_main_softc_t *, caddr_t, ioctlcmd_t, int, void *)); +extern aproxy_t *ipf_proxy_lookup __P((void *, u_int, char *)); +extern int ipf_proxy_match __P((fr_info_t *, struct nat *)); +extern int ipf_proxy_new __P((fr_info_t *, struct nat *)); +extern int ipf_proxy_ok __P((fr_info_t *, tcphdr_t *, struct ipnat *)); +extern void ipf_proxy_free __P((ipf_main_softc_t *, ap_session_t *)); +extern int ipf_proxy_main_load __P((void)); +extern int ipf_proxy_main_unload __P((void)); +extern ipnat_t *ipf_proxy_rule_fwd __P((nat_t *)); +extern ipnat_t *ipf_proxy_rule_rev __P((nat_t *)); +extern void *ipf_proxy_soft_create __P((ipf_main_softc_t *)); +extern void ipf_proxy_soft_destroy __P((ipf_main_softc_t *, void *)); +extern int ipf_proxy_soft_init __P((ipf_main_softc_t *, void *)); +extern int ipf_proxy_soft_fini __P((ipf_main_softc_t *, void *)); #endif /* __IP_PROXY_H__ */ diff --git a/sys/contrib/ipfilter/netinet/ip_raudio_pxy.c b/sys/contrib/ipfilter/netinet/ip_raudio_pxy.c index 2729dc6725b0..031363793cea 100644 --- a/sys/contrib/ipfilter/netinet/ip_raudio_pxy.c +++ b/sys/contrib/ipfilter/netinet/ip_raudio_pxy.c @@ -1,8 +1,7 @@ /* $FreeBSD$ */ /* - * $FreeBSD$ - * Copyright (C) 1998-2003 by Darren Reed + * Copyright (C) 2012 by Darren Reed. * * See the IPFILTER.LICENCE file for details on licencing. * @@ -12,11 +11,11 @@ #define IPF_RAUDIO_PROXY -int ippr_raudio_init __P((void)); -void ippr_raudio_fini __P((void)); -int ippr_raudio_new __P((fr_info_t *, ap_session_t *, nat_t *)); -int ippr_raudio_in __P((fr_info_t *, ap_session_t *, nat_t *)); -int ippr_raudio_out __P((fr_info_t *, ap_session_t *, nat_t *)); +void ipf_p_raudio_main_load __P((void)); +void ipf_p_raudio_main_unload __P((void)); +int ipf_p_raudio_new __P((void *, fr_info_t *, ap_session_t *, nat_t *)); +int ipf_p_raudio_in __P((void *, fr_info_t *, ap_session_t *, nat_t *)); +int ipf_p_raudio_out __P((void *, fr_info_t *, ap_session_t *, nat_t *)); static frentry_t raudiofr; @@ -26,19 +25,19 @@ int raudio_proxy_init = 0; /* * Real Audio application proxy initialization. */ -int ippr_raudio_init() +void +ipf_p_raudio_main_load() { bzero((char *)&raudiofr, sizeof(raudiofr)); raudiofr.fr_ref = 1; raudiofr.fr_flags = FR_INQUE|FR_PASS|FR_QUICK|FR_KEEPSTATE; MUTEX_INIT(&raudiofr.fr_lock, "Real Audio proxy rule lock"); raudio_proxy_init = 1; - - return 0; } -void ippr_raudio_fini() +void +ipf_p_raudio_main_unload() { if (raudio_proxy_init == 1) { MUTEX_DESTROY(&raudiofr.fr_lock); @@ -50,20 +49,24 @@ void ippr_raudio_fini() /* * Setup for a new proxy to handle Real Audio. */ -int ippr_raudio_new(fin, aps, nat) -fr_info_t *fin; -ap_session_t *aps; -nat_t *nat; +int +ipf_p_raudio_new(arg, fin, aps, nat) + void *arg; + fr_info_t *fin; + ap_session_t *aps; + nat_t *nat; { raudio_t *rap; + nat = nat; /* LINT */ + + if (fin->fin_v != 4) + return -1; + KMALLOCS(aps->aps_data, void *, sizeof(raudio_t)); if (aps->aps_data == NULL) return -1; - fin = fin; /* LINT */ - nat = nat; /* LINT */ - bzero(aps->aps_data, sizeof(raudio_t)); rap = aps->aps_data; aps->aps_psiz = sizeof(raudio_t); @@ -73,10 +76,12 @@ nat_t *nat; -int ippr_raudio_out(fin, aps, nat) -fr_info_t *fin; -ap_session_t *aps; -nat_t *nat; +int +ipf_p_raudio_out(arg, fin, aps, nat) + void *arg; + fr_info_t *fin; + ap_session_t *aps; + nat_t *nat; { raudio_t *rap = aps->aps_data; unsigned char membuf[512 + 1], *s; @@ -179,14 +184,18 @@ nat_t *nat; } -int ippr_raudio_in(fin, aps, nat) -fr_info_t *fin; -ap_session_t *aps; -nat_t *nat; +int +ipf_p_raudio_in(arg, fin, aps, nat) + void *arg; + fr_info_t *fin; + ap_session_t *aps; + nat_t *nat; { unsigned char membuf[IPF_MAXPORTLEN + 1], *s; tcphdr_t *tcp, tcph, *tcp2 = &tcph; raudio_t *rap = aps->aps_data; + ipf_main_softc_t *softc; + ipf_nat_softc_t *softn; struct in_addr swa, swb; int off, dlen, slen; int a1, a2, a3, a4; @@ -198,6 +207,8 @@ nat_t *nat; ip_t *ip; mb_t *m; + softc = fin->fin_main_soft; + softn = softc->ipf_nat_soft; /* * Wait until we've seen the end of the start messages and even then * only proceed further if we're using UDP. If they want to use TCP @@ -272,14 +283,12 @@ nat_t *nat; swb = ip->ip_dst; ip->ip_p = IPPROTO_UDP; - ip->ip_src = nat->nat_inip; - ip->ip_dst = nat->nat_oip; + ip->ip_src = nat->nat_ndstip; + ip->ip_dst = nat->nat_odstip; bcopy((char *)fin, (char *)&fi, sizeof(fi)); bzero((char *)tcp2, sizeof(*tcp2)); TCP_OFF_A(tcp2, 5); - fi.fin_state = NULL; - fi.fin_nat = NULL; fi.fin_flx |= FI_IGNORE; fi.fin_dp = (char *)tcp2; fi.fin_fr = &raudiofr; @@ -287,7 +296,7 @@ nat_t *nat; fi.fin_plen = fi.fin_hlen + sizeof(*tcp2); tcp2->th_win = htons(8192); slen = ip->ip_len; - ip->ip_len = fin->fin_hlen + sizeof(*tcp); + ip->ip_len = htons(fin->fin_hlen + sizeof(*tcp)); if (((rap->rap_mode & RAP_M_UDP_ROBUST) == RAP_M_UDP_ROBUST) && (rap->rap_srport != 0)) { @@ -298,16 +307,19 @@ nat_t *nat; fi.fin_data[0] = dp; fi.fin_data[1] = sp; fi.fin_out = 0; - nat2 = nat_new(&fi, nat->nat_ptr, NULL, + MUTEX_ENTER(&softn->ipf_nat_new); + nat2 = ipf_nat_add(&fi, nat->nat_ptr, NULL, NAT_SLAVE|IPN_UDP | (sp ? 0 : SI_W_SPORT), NAT_OUTBOUND); + MUTEX_EXIT(&softn->ipf_nat_new); if (nat2 != NULL) { - (void) nat_proto(&fi, nat2, IPN_UDP); - nat_update(&fi, nat2, nat2->nat_ptr); + (void) ipf_nat_proto(&fi, nat2, IPN_UDP); + MUTEX_ENTER(&nat2->nat_lock); + ipf_nat_update(&fi, nat2); + MUTEX_EXIT(&nat2->nat_lock); - (void) fr_addstate(&fi, NULL, (sp ? 0 : SI_W_SPORT)); - if (fi.fin_state != NULL) - fr_statederef((ipstate_t **)&fi.fin_state); + (void) ipf_state_add(softc, &fi, NULL, + (sp ? 0 : SI_W_SPORT)); } } @@ -318,16 +330,18 @@ nat_t *nat; fi.fin_data[0] = sp; fi.fin_data[1] = 0; fi.fin_out = 1; - nat2 = nat_new(&fi, nat->nat_ptr, NULL, + MUTEX_ENTER(&softn->ipf_nat_new); + nat2 = ipf_nat_add(&fi, nat->nat_ptr, NULL, NAT_SLAVE|IPN_UDP|SI_W_DPORT, NAT_OUTBOUND); + MUTEX_EXIT(&softn->ipf_nat_new); if (nat2 != NULL) { - (void) nat_proto(&fi, nat2, IPN_UDP); - nat_update(&fi, nat2, nat2->nat_ptr); + (void) ipf_nat_proto(&fi, nat2, IPN_UDP); + MUTEX_ENTER(&nat2->nat_lock); + ipf_nat_update(&fi, nat2); + MUTEX_EXIT(&nat2->nat_lock); - (void) fr_addstate(&fi, NULL, SI_W_DPORT); - if (fi.fin_state != NULL) - fr_statederef((ipstate_t **)&fi.fin_state); + (void) ipf_state_add(softc, &fi, NULL, SI_W_DPORT); } } diff --git a/sys/contrib/ipfilter/netinet/ip_rcmd_pxy.c b/sys/contrib/ipfilter/netinet/ip_rcmd_pxy.c index dc92bf546845..4b453c037d08 100644 --- a/sys/contrib/ipfilter/netinet/ip_rcmd_pxy.c +++ b/sys/contrib/ipfilter/netinet/ip_rcmd_pxy.c @@ -1,11 +1,11 @@ /* $FreeBSD$ */ /* - * Copyright (C) 1998-2003 by Darren Reed + * Copyright (C) 2012 by Darren Reed. * * See the IPFILTER.LICENCE file for details on licencing. * - * $Id: ip_rcmd_pxy.c,v 1.41.2.7 2006/07/14 06:12:18 darrenr Exp $ + * $Id$ * * Simple RCMD transparent proxy for in-kernel use. For use with the NAT * code. @@ -14,36 +14,45 @@ #define IPF_RCMD_PROXY +typedef struct rcmdinfo { + u_32_t rcmd_port; /* Port number seen */ + u_32_t rcmd_portseq; /* Sequence number where port is first seen */ + ipnat_t *rcmd_rule; /* Template rule for back connection */ +} rcmdinfo_t; -int ippr_rcmd_init __P((void)); -void ippr_rcmd_fini __P((void)); -int ippr_rcmd_new __P((fr_info_t *, ap_session_t *, nat_t *)); -int ippr_rcmd_out __P((fr_info_t *, ap_session_t *, nat_t *)); -int ippr_rcmd_in __P((fr_info_t *, ap_session_t *, nat_t *)); +void ipf_p_rcmd_main_load __P((void)); +void ipf_p_rcmd_main_unload __P((void)); + +int ipf_p_rcmd_init __P((void)); +void ipf_p_rcmd_fini __P((void)); +void ipf_p_rcmd_del __P((ipf_main_softc_t *, ap_session_t *)); +int ipf_p_rcmd_new __P((void *, fr_info_t *, ap_session_t *, nat_t *)); +int ipf_p_rcmd_out __P((void *, fr_info_t *, ap_session_t *, nat_t *)); +int ipf_p_rcmd_in __P((void *, fr_info_t *, ap_session_t *, nat_t *)); u_short ipf_rcmd_atoi __P((char *)); -int ippr_rcmd_portmsg __P((fr_info_t *, ap_session_t *, nat_t *)); +int ipf_p_rcmd_portmsg __P((fr_info_t *, ap_session_t *, nat_t *)); static frentry_t rcmdfr; -int rcmd_proxy_init = 0; +static int rcmd_proxy_init = 0; /* * RCMD application proxy initialization. */ -int ippr_rcmd_init() +void +ipf_p_rcmd_main_load() { bzero((char *)&rcmdfr, sizeof(rcmdfr)); rcmdfr.fr_ref = 1; rcmdfr.fr_flags = FR_INQUE|FR_PASS|FR_QUICK|FR_KEEPSTATE; MUTEX_INIT(&rcmdfr.fr_lock, "RCMD proxy rule lock"); rcmd_proxy_init = 1; - - return 0; } -void ippr_rcmd_fini() +void +ipf_p_rcmd_main_unload() { if (rcmd_proxy_init == 1) { MUTEX_DESTROY(&rcmdfr.fr_lock); @@ -55,36 +64,70 @@ void ippr_rcmd_fini() /* * Setup for a new RCMD proxy. */ -int ippr_rcmd_new(fin, aps, nat) -fr_info_t *fin; -ap_session_t *aps; -nat_t *nat; +int +ipf_p_rcmd_new(arg, fin, aps, nat) + void *arg; + fr_info_t *fin; + ap_session_t *aps; + nat_t *nat; { tcphdr_t *tcp = (tcphdr_t *)fin->fin_dp; + rcmdinfo_t *rc; + ipnat_t *ipn; + ipnat_t *np; + int size; fin = fin; /* LINT */ - nat = nat; /* LINT */ - aps->aps_psiz = sizeof(u_32_t); - KMALLOCS(aps->aps_data, u_32_t *, sizeof(u_32_t)); - if (aps->aps_data == NULL) { + np = nat->nat_ptr; + size = np->in_size; + KMALLOC(rc, rcmdinfo_t *); + if (rc == NULL) { #ifdef IP_RCMD_PROXY_DEBUG - printf("ippr_rcmd_new:KMALLOCS(%d) failed\n", sizeof(u_32_t)); + printf("ipf_p_rcmd_new:KMALLOCS(%d) failed\n", sizeof(*rc)); #endif return -1; } - *(u_32_t *)aps->aps_data = 0; aps->aps_sport = tcp->th_sport; aps->aps_dport = tcp->th_dport; + + ipn = ipf_proxy_rule_rev(nat); + if (ipn == NULL) { + KFREE(rc); + return -1; + } + + aps->aps_data = rc; + aps->aps_psiz = sizeof(*rc); + bzero((char *)rc, sizeof(*rc)); + + rc->rcmd_rule = ipn; + return 0; } +void +ipf_p_rcmd_del(softc, aps) + ipf_main_softc_t *softc; + ap_session_t *aps; +{ + rcmdinfo_t *rci; + + rci = aps->aps_data; + if (rci != NULL) { + rci->rcmd_rule->in_flags |= IPN_DELETE; + ipf_nat_rule_deref(softc, &rci->rcmd_rule); + } +} + + /* * ipf_rcmd_atoi - implement a simple version of atoi */ -u_short ipf_rcmd_atoi(ptr) -char *ptr; +u_short +ipf_rcmd_atoi(ptr) + char *ptr; { register char *s = ptr, c; register u_short i = 0; @@ -97,44 +140,50 @@ char *ptr; } -int ippr_rcmd_portmsg(fin, aps, nat) -fr_info_t *fin; -ap_session_t *aps; -nat_t *nat; +int +ipf_p_rcmd_portmsg(fin, aps, nat) + fr_info_t *fin; + ap_session_t *aps; + nat_t *nat; { tcphdr_t *tcp, tcph, *tcp2 = &tcph; - struct in_addr swip, swip2; - int off, dlen, nflags; + int off, dlen, nflags, direction; + ipf_main_softc_t *softc; + ipf_nat_softc_t *softn; char portbuf[8], *s; + rcmdinfo_t *rc; fr_info_t fi; u_short sp; nat_t *nat2; +#ifdef USE_INET6 + ip6_t *ip6; +#endif + int tcpsz; + int slen; ip_t *ip; mb_t *m; tcp = (tcphdr_t *)fin->fin_dp; - if (tcp->th_flags & TH_SYN) { - *(u_32_t *)aps->aps_data = htonl(ntohl(tcp->th_seq) + 1); - return 0; - } - - if ((*(u_32_t *)aps->aps_data != 0) && - (tcp->th_seq != *(u_32_t *)aps->aps_data)) - return 0; - m = fin->fin_m; ip = fin->fin_ip; - off = (char *)tcp - (char *)ip + (TCP_OFF(tcp) << 2) + fin->fin_ipoff; - -#ifdef __sgi - dlen = fin->fin_plen - off; -#else - dlen = MSGDSIZE(m) - off; + tcpsz = TCP_OFF(tcp) << 2; +#ifdef USE_INET6 + ip6 = (ip6_t *)fin->fin_ip; #endif + softc = fin->fin_main_soft; + softn = softc->ipf_nat_soft; + off = (char *)tcp - (char *)ip + tcpsz + fin->fin_ipoff; + + dlen = fin->fin_dlen - tcpsz; if (dlen <= 0) return 0; + rc = (rcmdinfo_t *)aps->aps_data; + if ((rc->rcmd_portseq != 0) && + (tcp->th_seq != rc->rcmd_portseq)) + return 0; + bzero(portbuf, sizeof(portbuf)); COPYDATA(m, off, MIN(sizeof(portbuf), dlen), portbuf); @@ -143,97 +192,161 @@ nat_t *nat; sp = ipf_rcmd_atoi(s); if (sp == 0) { #ifdef IP_RCMD_PROXY_DEBUG - printf("ippr_rcmd_portmsg:sp == 0 dlen %d [%s]\n", + printf("ipf_p_rcmd_portmsg:sp == 0 dlen %d [%s]\n", dlen, portbuf); #endif return 0; } + if (rc->rcmd_port != 0 && sp != rc->rcmd_port) { +#ifdef IP_RCMD_PROXY_DEBUG + printf("ipf_p_rcmd_portmsg:sp(%d) != rcmd_port(%d)\n", + sp, rc->rcmd_port); +#endif + return 0; + } + + rc->rcmd_port = sp; + rc->rcmd_portseq = tcp->th_seq; + /* - * Add skeleton NAT entry for connection which will come back the - * other way. + * Initialise the packet info structure so we can search the NAT + * table to see if there already is soemthing present that matches + * up with what we want to add. */ bcopy((char *)fin, (char *)&fi, sizeof(fi)); - fi.fin_state = NULL; - fi.fin_nat = NULL; fi.fin_flx |= FI_IGNORE; - fi.fin_data[0] = sp; - fi.fin_data[1] = 0; - if (nat->nat_dir == NAT_OUTBOUND) - nat2 = nat_outlookup(&fi, NAT_SEARCH|IPN_TCP, nat->nat_p, - nat->nat_inip, nat->nat_oip); - else - nat2 = nat_inlookup(&fi, NAT_SEARCH|IPN_TCP, nat->nat_p, - nat->nat_inip, nat->nat_oip); - if (nat2 == NULL) { - int slen; - - slen = ip->ip_len; - ip->ip_len = fin->fin_hlen + sizeof(*tcp); - bzero((char *)tcp2, sizeof(*tcp2)); - tcp2->th_win = htons(8192); - tcp2->th_sport = htons(sp); - tcp2->th_dport = 0; /* XXX - don't specify remote port */ - TCP_OFF_A(tcp2, 5); - tcp2->th_flags = TH_SYN; - fi.fin_dp = (char *)tcp2; - fi.fin_fr = &rcmdfr; - fi.fin_dlen = sizeof(*tcp2); - fi.fin_plen = fi.fin_hlen + sizeof(*tcp2); - fi.fin_flx &= FI_LOWTTL|FI_FRAG|FI_TCPUDP|FI_OPTIONS|FI_IGNORE; - nflags = NAT_SLAVE|IPN_TCP|SI_W_DPORT; - - swip = ip->ip_src; - swip2 = ip->ip_dst; + fi.fin_data[0] = 0; + fi.fin_data[1] = sp; + fi.fin_src6 = nat->nat_ndst6; + fi.fin_dst6 = nat->nat_nsrc6; + if (nat->nat_v[0] == 6) { +#ifdef USE_INET6 if (nat->nat_dir == NAT_OUTBOUND) { - fi.fin_fi.fi_saddr = nat->nat_inip.s_addr; - ip->ip_src = nat->nat_inip; + nat2 = ipf_nat6_outlookup(&fi, NAT_SEARCH|IPN_TCP, + nat->nat_pr[1], + &nat->nat_osrc6.in6, + &nat->nat_odst6.in6); } else { - fi.fin_fi.fi_saddr = nat->nat_oip.s_addr; - ip->ip_src = nat->nat_oip; - nflags |= NAT_NOTRULEPORT; + nat2 = ipf_nat6_inlookup(&fi, NAT_SEARCH|IPN_TCP, + nat->nat_pr[0], + &nat->nat_osrc6.in6, + &nat->nat_odst6.in6); } - - nat2 = nat_new(&fi, nat->nat_ptr, NULL, nflags, nat->nat_dir); - - if (nat2 != NULL) { - (void) nat_proto(&fi, nat2, IPN_TCP); - nat_update(&fi, nat2, nat2->nat_ptr); - fi.fin_ifp = NULL; - if (nat->nat_dir == NAT_INBOUND) { - fi.fin_fi.fi_daddr = nat->nat_inip.s_addr; - ip->ip_dst = nat->nat_inip; - } - (void) fr_addstate(&fi, NULL, SI_W_DPORT); - if (fi.fin_state != NULL) - fr_statederef((ipstate_t **)&fi.fin_state); +#else + nat2 = (void *)-1; +#endif + } else { + if (nat->nat_dir == NAT_OUTBOUND) { + nat2 = ipf_nat_outlookup(&fi, NAT_SEARCH|IPN_TCP, + nat->nat_pr[1], + nat->nat_osrcip, + nat->nat_odstip); + } else { + nat2 = ipf_nat_inlookup(&fi, NAT_SEARCH|IPN_TCP, + nat->nat_pr[0], + nat->nat_osrcip, + nat->nat_odstip); } - ip->ip_len = slen; - ip->ip_src = swip; - ip->ip_dst = swip2; } + if (nat2 != NULL) + return APR_ERR(1); + + /* + * Add skeleton NAT entry for connection which will come + * back the other way. + */ + + if (nat->nat_v[0] == 6) { +#ifdef USE_INET6 + slen = ip6->ip6_plen; + ip6->ip6_plen = htons(sizeof(*tcp)); +#endif + } else { + slen = ip->ip_len; + ip->ip_len = htons(fin->fin_hlen + sizeof(*tcp)); + } + + /* + * Fill out the fake TCP header with a few fields that ipfilter + * considers to be important. + */ + bzero((char *)tcp2, sizeof(*tcp2)); + tcp2->th_win = htons(8192); + TCP_OFF_A(tcp2, 5); + tcp2->th_flags = TH_SYN; + + fi.fin_dp = (char *)tcp2; + fi.fin_fr = &rcmdfr; + fi.fin_dlen = sizeof(*tcp2); + fi.fin_plen = fi.fin_hlen + sizeof(*tcp2); + fi.fin_flx &= FI_LOWTTL|FI_FRAG|FI_TCPUDP|FI_OPTIONS|FI_IGNORE; + + if (nat->nat_dir == NAT_OUTBOUND) { + fi.fin_out = 0; + direction = NAT_INBOUND; + } else { + fi.fin_out = 1; + direction = NAT_OUTBOUND; + } + nflags = SI_W_SPORT|NAT_SLAVE|IPN_TCP; + + MUTEX_ENTER(&softn->ipf_nat_new); + if (fin->fin_v == 4) + nat2 = ipf_nat_add(&fi, rc->rcmd_rule, NULL, nflags, + direction); +#ifdef USE_INET6 + else + nat2 = ipf_nat6_add(&fi, rc->rcmd_rule, NULL, nflags, + direction); +#endif + MUTEX_EXIT(&softn->ipf_nat_new); + + if (nat2 != NULL) { + (void) ipf_nat_proto(&fi, nat2, IPN_TCP); + MUTEX_ENTER(&nat2->nat_lock); + ipf_nat_update(&fi, nat2); + MUTEX_EXIT(&nat2->nat_lock); + fi.fin_ifp = NULL; + if (nat2->nat_dir == NAT_INBOUND) + fi.fin_dst6 = nat->nat_osrc6; + (void) ipf_state_add(softc, &fi, NULL, SI_W_SPORT); + } + if (nat->nat_v[0] == 6) { +#ifdef USE_INET6 + ip6->ip6_plen = slen; +#endif + } else { + ip->ip_len = slen; + } + if (nat2 == NULL) + return APR_ERR(1); return 0; } -int ippr_rcmd_out(fin, aps, nat) -fr_info_t *fin; -ap_session_t *aps; -nat_t *nat; +int +ipf_p_rcmd_out(arg, fin, aps, nat) + void *arg; + fr_info_t *fin; + ap_session_t *aps; + nat_t *nat; { if (nat->nat_dir == NAT_OUTBOUND) - return ippr_rcmd_portmsg(fin, aps, nat); + return ipf_p_rcmd_portmsg(fin, aps, nat); return 0; } -int ippr_rcmd_in(fin, aps, nat) -fr_info_t *fin; -ap_session_t *aps; -nat_t *nat; +int +ipf_p_rcmd_in(arg, fin, aps, nat) + void *arg; + fr_info_t *fin; + ap_session_t *aps; + nat_t *nat; { if (nat->nat_dir == NAT_INBOUND) - return ippr_rcmd_portmsg(fin, aps, nat); + return ipf_p_rcmd_portmsg(fin, aps, nat); return 0; } diff --git a/sys/contrib/ipfilter/netinet/ip_rpcb_pxy.c b/sys/contrib/ipfilter/netinet/ip_rpcb_pxy.c index da76fde4d155..9493d2bfae38 100644 --- a/sys/contrib/ipfilter/netinet/ip_rpcb_pxy.c +++ b/sys/contrib/ipfilter/netinet/ip_rpcb_pxy.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2003 by Ryan Beasley + * Copyright (C) 2002-2012 by Ryan Beasley * * See the IPFILTER.LICENCE file for details on licencing. */ @@ -37,44 +37,43 @@ * o The enclosed hack of STREAMS support is pretty sick and most likely * broken. * - * $Id: ip_rpcb_pxy.c,v 2.25.2.7 2007/06/04 09:16:31 darrenr Exp $ + * $Id$ */ - #define IPF_RPCB_PROXY /* * Function prototypes */ -int ippr_rpcb_init __P((void)); -void ippr_rpcb_fini __P((void)); -int ippr_rpcb_new __P((fr_info_t *, ap_session_t *, nat_t *)); -void ippr_rpcb_del __P((ap_session_t *)); -int ippr_rpcb_in __P((fr_info_t *, ap_session_t *, nat_t *)); -int ippr_rpcb_out __P((fr_info_t *, ap_session_t *, nat_t *)); +void ipf_p_rpcb_main_load __P((void)); +void ipf_p_rpcb_main_unload __P((void)); +int ipf_p_rpcb_new __P((void *, fr_info_t *, ap_session_t *, nat_t *)); +void ipf_p_rpcb_del __P((ipf_main_softc_t *, ap_session_t *)); +int ipf_p_rpcb_in __P((void *, fr_info_t *, ap_session_t *, nat_t *)); +int ipf_p_rpcb_out __P((void *, fr_info_t *, ap_session_t *, nat_t *)); -static void ippr_rpcb_flush __P((rpcb_session_t *)); -static int ippr_rpcb_decodereq __P((fr_info_t *, nat_t *, +static void ipf_p_rpcb_flush __P((rpcb_session_t *)); +static int ipf_p_rpcb_decodereq __P((fr_info_t *, nat_t *, rpcb_session_t *, rpc_msg_t *)); -static int ippr_rpcb_skipauth __P((rpc_msg_t *, xdr_auth_t *, u_32_t **)); -static int ippr_rpcb_insert __P((rpcb_session_t *, rpcb_xact_t *)); -static int ippr_rpcb_xdrrpcb __P((rpc_msg_t *, u_32_t *, rpcb_args_t *)); -static int ippr_rpcb_getuaddr __P((rpc_msg_t *, xdr_uaddr_t *, +static int ipf_p_rpcb_skipauth __P((rpc_msg_t *, xdr_auth_t *, u_32_t **)); +static int ipf_p_rpcb_insert __P((rpcb_session_t *, rpcb_xact_t *)); +static int ipf_p_rpcb_xdrrpcb __P((rpc_msg_t *, u_32_t *, rpcb_args_t *)); +static int ipf_p_rpcb_getuaddr __P((rpc_msg_t *, xdr_uaddr_t *, u_32_t **)); -static u_int ippr_rpcb_atoi __P((char *)); -static int ippr_rpcb_modreq __P((fr_info_t *, nat_t *, rpc_msg_t *, +static u_int ipf_p_rpcb_atoi __P((char *)); +static int ipf_p_rpcb_modreq __P((fr_info_t *, nat_t *, rpc_msg_t *, mb_t *, u_int)); -static int ippr_rpcb_decoderep __P((fr_info_t *, nat_t *, +static int ipf_p_rpcb_decoderep __P((fr_info_t *, nat_t *, rpcb_session_t *, rpc_msg_t *, rpcb_xact_t **)); -static rpcb_xact_t * ippr_rpcb_lookup __P((rpcb_session_t *, u_32_t)); -static void ippr_rpcb_deref __P((rpcb_session_t *, rpcb_xact_t *)); -static int ippr_rpcb_getproto __P((rpc_msg_t *, xdr_proto_t *, +static rpcb_xact_t * ipf_p_rpcb_lookup __P((rpcb_session_t *, u_32_t)); +static void ipf_p_rpcb_deref __P((rpcb_session_t *, rpcb_xact_t *)); +static int ipf_p_rpcb_getproto __P((rpc_msg_t *, xdr_proto_t *, u_32_t **)); -static int ippr_rpcb_getnat __P((fr_info_t *, nat_t *, u_int, u_int)); -static int ippr_rpcb_modv3 __P((fr_info_t *, nat_t *, rpc_msg_t *, +static int ipf_p_rpcb_getnat __P((fr_info_t *, nat_t *, u_int, u_int)); +static int ipf_p_rpcb_modv3 __P((fr_info_t *, nat_t *, rpc_msg_t *, mb_t *, u_int)); -static int ippr_rpcb_modv4 __P((fr_info_t *, nat_t *, rpc_msg_t *, +static int ipf_p_rpcb_modv4 __P((fr_info_t *, nat_t *, rpc_msg_t *, mb_t *, u_int)); -static void ippr_rpcb_fixlen __P((fr_info_t *, int)); +static void ipf_p_rpcb_fixlen __P((fr_info_t *, int)); /* * Global variables @@ -84,7 +83,7 @@ static frentry_t rpcbfr; /* Skeleton rule for reference by entities static int rpcbcnt; /* Upper bound of allocated RPCB sessions. */ /* XXX rpcbcnt still requires locking. */ -int rpcb_proxy_init = 0; +static int rpcb_proxy_init = 0; /* @@ -98,15 +97,15 @@ int rpcb_proxy_init = 0; * Public subroutines */ -/* -------------------------------------------------------------------- */ -/* Function: ippr_rpcb_init */ -/* Returns: int - 0 == success */ -/* Parameters: (void) */ -/* */ -/* Initialize the filter rule entry and session limiter. */ -/* -------------------------------------------------------------------- */ -int -ippr_rpcb_init() +/* -------------------------------------------------------------------- */ +/* Function: ipf_p_rpcb_main_load */ +/* Returns: void */ +/* Parameters: (void) */ +/* */ +/* Initialize the filter rule entry and session limiter. */ +/* -------------------------------------------------------------------- */ +void +ipf_p_rpcb_main_load() { rpcbcnt = 0; @@ -115,19 +114,17 @@ ippr_rpcb_init() rpcbfr.fr_flags = FR_PASS|FR_QUICK|FR_KEEPSTATE; MUTEX_INIT(&rpcbfr.fr_lock, "ipf Sun RPCB proxy rule lock"); rpcb_proxy_init = 1; - - return(0); } -/* -------------------------------------------------------------------- */ -/* Function: ippr_rpcb_fini */ -/* Returns: void */ -/* Parameters: (void) */ -/* */ -/* Destroy rpcbfr's mutex to avoid a lock leak. */ -/* -------------------------------------------------------------------- */ +/* -------------------------------------------------------------------- */ +/* Function: ipf_p_rpcb_main_unload */ +/* Returns: void */ +/* Parameters: (void) */ +/* */ +/* Destroy rpcbfr's mutex to avoid a lock leak. */ +/* -------------------------------------------------------------------- */ void -ippr_rpcb_fini() +ipf_p_rpcb_main_unload() { if (rpcb_proxy_init == 1) { MUTEX_DESTROY(&rpcbfr.fr_lock); @@ -136,7 +133,7 @@ ippr_rpcb_fini() } /* -------------------------------------------------------------------- */ -/* Function: ippr_rpcb_new */ +/* Function: ipf_p_rpcb_new */ /* Returns: int - -1 == failure, 0 == success */ /* Parameters: fin(I) - pointer to packet information */ /* aps(I) - pointer to proxy session structure */ @@ -145,16 +142,19 @@ ippr_rpcb_fini() /* Allocate resources for per-session proxy structures. */ /* -------------------------------------------------------------------- */ int -ippr_rpcb_new(fin, aps, nat) +ipf_p_rpcb_new(arg, fin, aps, nat) + void *arg; fr_info_t *fin; ap_session_t *aps; nat_t *nat; { rpcb_session_t *rs; - fin = fin; /* LINT */ nat = nat; /* LINT */ + if (fin->fin_v != 4) + return -1; + KMALLOC(rs, rpcb_session_t *); if (rs == NULL) return(-1); @@ -168,27 +168,28 @@ ippr_rpcb_new(fin, aps, nat) } /* -------------------------------------------------------------------- */ -/* Function: ippr_rpcb_del */ +/* Function: ipf_p_rpcb_del */ /* Returns: void */ /* Parameters: aps(I) - pointer to proxy session structure */ /* */ /* Free up a session's list of RPCB requests. */ /* -------------------------------------------------------------------- */ void -ippr_rpcb_del(aps) +ipf_p_rpcb_del(softc, aps) + ipf_main_softc_t *softc; ap_session_t *aps; { rpcb_session_t *rs; rs = (rpcb_session_t *)aps->aps_data; MUTEX_ENTER(&rs->rs_rxlock); - ippr_rpcb_flush(rs); + ipf_p_rpcb_flush(rs); MUTEX_EXIT(&rs->rs_rxlock); MUTEX_DESTROY(&rs->rs_rxlock); } /* -------------------------------------------------------------------- */ -/* Function: ippr_rpcb_in */ +/* Function: ipf_p_rpcb_in */ /* Returns: int - APR_ERR(1) == drop the packet, */ /* APR_ERR(2) == kill the proxy session, */ /* else change in packet length (in bytes) */ @@ -201,7 +202,8 @@ ippr_rpcb_del(aps) /* for decoding. Also pass packet off for a rewrite if necessary. */ /* -------------------------------------------------------------------- */ int -ippr_rpcb_in(fin, aps, nat) +ipf_p_rpcb_in(arg, fin, aps, nat) + void *arg; fr_info_t *fin; ap_session_t *aps; nat_t *nat; @@ -235,7 +237,7 @@ ippr_rpcb_in(fin, aps, nat) rm->rm_buflen = dlen; /* Send off to decode request. */ - rv = ippr_rpcb_decodereq(fin, nat, rs, rm); + rv = ipf_p_rpcb_decodereq(fin, nat, rs, rm); switch(rv) { @@ -246,18 +248,18 @@ ippr_rpcb_in(fin, aps, nat) case 0: break; case 1: - rv = ippr_rpcb_modreq(fin, nat, rm, m, off); + rv = ipf_p_rpcb_modreq(fin, nat, rm, m, off); break; default: /*CONSTANTCONDITION*/ - IPF_PANIC(1, ("illegal rv %d (ippr_rpcb_req)", rv)); + IPF_PANIC(1, ("illegal rv %d (ipf_p_rpcb_req)", rv)); } return(rv); } /* -------------------------------------------------------------------- */ -/* Function: ippr_rpcb_out */ +/* Function: ipf_p_rpcb_out */ /* Returns: int - APR_ERR(1) == drop the packet, */ /* APR_ERR(2) == kill the proxy session, */ /* else change in packet length (in bytes) */ @@ -272,7 +274,8 @@ ippr_rpcb_in(fin, aps, nat) /* allow direct communication between RPC client and server. */ /* -------------------------------------------------------------------- */ int -ippr_rpcb_out(fin, aps, nat) +ipf_p_rpcb_out(arg, fin, aps, nat) + void *arg; fr_info_t *fin; ap_session_t *aps; nat_t *nat; @@ -311,14 +314,14 @@ ippr_rpcb_out(fin, aps, nat) rx = NULL; /* XXX gcc */ /* Send off to decode reply. */ - rv = ippr_rpcb_decoderep(fin, nat, rs, rm, &rx); + rv = ipf_p_rpcb_decoderep(fin, nat, rs, rm, &rx); switch(rv) { case -1: /* Bad packet */ if (rx != NULL) { MUTEX_ENTER(&rs->rs_rxlock); - ippr_rpcb_deref(rs, rx); + ipf_p_rpcb_deref(rs, rx); MUTEX_EXIT(&rs->rs_rxlock); } return(APR_ERR(1)); @@ -334,16 +337,16 @@ ippr_rpcb_out(fin, aps, nat) * same. (i.e., this box is either a router or rpcbind * only listens on loopback.) */ - if (nat->nat_inip.s_addr != nat->nat_outip.s_addr) { + if (nat->nat_odstaddr != nat->nat_ndstaddr) { if (rx->rx_type == RPCB_RES_STRING) - diff = ippr_rpcb_modv3(fin, nat, rm, m, off); + diff = ipf_p_rpcb_modv3(fin, nat, rm, m, off); else if (rx->rx_type == RPCB_RES_LIST) - diff = ippr_rpcb_modv4(fin, nat, rm, m, off); + diff = ipf_p_rpcb_modv4(fin, nat, rm, m, off); } break; default: /*CONSTANTCONDITION*/ - IPF_PANIC(1, ("illegal rv %d (ippr_rpcb_decoderep)", rv)); + IPF_PANIC(1, ("illegal rv %d (ipf_p_rpcb_decoderep)", rv)); } if (rx != NULL) { @@ -354,8 +357,8 @@ ippr_rpcb_out(fin, aps, nat) * finished with rx, and the other signals that we've * processed its reply. */ - ippr_rpcb_deref(rs, rx); - ippr_rpcb_deref(rs, rx); + ipf_p_rpcb_deref(rs, rx); + ipf_p_rpcb_deref(rs, rx); MUTEX_EXIT(&rs->rs_rxlock); } @@ -367,14 +370,14 @@ ippr_rpcb_out(fin, aps, nat) */ /* -------------------------------------------------------------------- */ -/* Function: ippr_rpcb_flush */ +/* Function: ipf_p_rpcb_flush */ /* Returns: void */ /* Parameters: rs(I) - pointer to RPCB session structure */ /* */ /* Simply flushes the list of outstanding transactions, if any. */ /* -------------------------------------------------------------------- */ static void -ippr_rpcb_flush(rs) +ipf_p_rpcb_flush(rs) rpcb_session_t *rs; { rpcb_xact_t *r1, *r2; @@ -391,7 +394,7 @@ ippr_rpcb_flush(rs) } /* -------------------------------------------------------------------- */ -/* Function: ippr_rpcb_decodereq */ +/* Function: ipf_p_rpcb_decodereq */ /* Returns: int - -1 == bad request or critical failure, */ /* 0 == request successfully decoded, */ /* 1 == request successfully decoded; requires */ @@ -408,7 +411,7 @@ ippr_rpcb_flush(rs) /* is enough room in rs_buf for the basic RPC message "preamble". */ /* -------------------------------------------------------------------- */ static int -ippr_rpcb_decodereq(fin, nat, rs, rm) +ipf_p_rpcb_decodereq(fin, nat, rs, rm) fr_info_t *fin; nat_t *nat; rpcb_session_t *rs; @@ -440,9 +443,9 @@ ippr_rpcb_decodereq(fin, nat, rs, rm) rc->rc_proc = p++; /* Bypass RPC authentication stuff. */ - if (ippr_rpcb_skipauth(rm, &rc->rc_authcred, &p) != 0) + if (ipf_p_rpcb_skipauth(rm, &rc->rc_authcred, &p) != 0) return(-1); - if (ippr_rpcb_skipauth(rm, &rc->rc_authverf, &p) != 0) + if (ipf_p_rpcb_skipauth(rm, &rc->rc_authverf, &p) != 0) return(-1); /* Compare RPCB version and procedure numbers. */ @@ -488,17 +491,17 @@ ippr_rpcb_decodereq(fin, nat, rs, rm) ra = &rc->rc_rpcbargs; /* Decode the 'struct rpcb' request. */ - if (ippr_rpcb_xdrrpcb(rm, p, ra) != 0) + if (ipf_p_rpcb_xdrrpcb(rm, p, ra) != 0) return(-1); /* Are the target address & port valid? */ - if ((ra->ra_maddr.xu_ip != nat->nat_outip.s_addr) || - (ra->ra_maddr.xu_port != nat->nat_outport)) + if ((ra->ra_maddr.xu_ip != nat->nat_ndstaddr) || + (ra->ra_maddr.xu_port != nat->nat_ndport)) return(-1); /* Do we need to rewrite this packet? */ - if ((nat->nat_outip.s_addr != nat->nat_inip.s_addr) || - (nat->nat_outport != nat->nat_inport)) + if ((nat->nat_ndstaddr != nat->nat_odstaddr) || + (nat->nat_ndport != nat->nat_odport)) mod = 1; break; default: @@ -506,7 +509,7 @@ ippr_rpcb_decodereq(fin, nat, rs, rm) } MUTEX_ENTER(&rs->rs_rxlock); - if (ippr_rpcb_insert(rs, &rx) != 0) { + if (ipf_p_rpcb_insert(rs, &rx) != 0) { MUTEX_EXIT(&rs->rs_rxlock); return(-1); } @@ -516,7 +519,7 @@ ippr_rpcb_decodereq(fin, nat, rs, rm) } /* -------------------------------------------------------------------- */ -/* Function: ippr_rpcb_skipauth */ +/* Function: ipf_p_rpcb_skipauth */ /* Returns: int -- -1 == illegal auth parameters (lengths) */ /* 0 == valid parameters, pointer advanced */ /* Parameters: rm(I) - pointer to RPC message structure */ @@ -527,7 +530,7 @@ ippr_rpcb_decodereq(fin, nat, rs, rm) /* it. */ /* -------------------------------------------------------------------- */ static int -ippr_rpcb_skipauth(rm, auth, buf) +ipf_p_rpcb_skipauth(rm, auth, buf) rpc_msg_t *rm; xdr_auth_t *auth; u_32_t **buf; @@ -559,20 +562,20 @@ ippr_rpcb_skipauth(rm, auth, buf) } /* -------------------------------------------------------------------- */ -/* Function: ippr_rpcb_insert */ +/* Function: ipf_p_rpcb_insert */ /* Returns: int -- -1 == list insertion failed, */ /* 0 == item successfully added */ /* Parameters: rs(I) - pointer to RPCB session structure */ /* rx(I) - pointer to RPCB transaction structure */ /* -------------------------------------------------------------------- */ static int -ippr_rpcb_insert(rs, rx) +ipf_p_rpcb_insert(rs, rx) rpcb_session_t *rs; rpcb_xact_t *rx; { rpcb_xact_t *rxp; - rxp = ippr_rpcb_lookup(rs, rx->rx_xid); + rxp = ipf_p_rpcb_lookup(rs, rx->rx_xid); if (rxp != NULL) { ++rxp->rx_ref; return(0); @@ -602,7 +605,7 @@ ippr_rpcb_insert(rs, rx) } /* -------------------------------------------------------------------- */ -/* Function: ippr_rpcb_xdrrpcb */ +/* Function: ipf_p_rpcb_xdrrpcb */ /* Returns: int -- -1 == failure to properly decode the request */ /* 0 == rpcb successfully decoded */ /* Parameters: rs(I) - pointer to RPCB session structure */ @@ -613,7 +616,7 @@ ippr_rpcb_insert(rs, rx) /* within only the context of TCP/UDP over IP networks. */ /* -------------------------------------------------------------------- */ static int -ippr_rpcb_xdrrpcb(rm, p, ra) +ipf_p_rpcb_xdrrpcb(rm, p, ra) rpc_msg_t *rm; u_32_t *p; rpcb_args_t *ra; @@ -625,11 +628,11 @@ ippr_rpcb_xdrrpcb(rm, p, ra) p += 2; /* Decode r_netid. Must be "tcp" or "udp". */ - if (ippr_rpcb_getproto(rm, &ra->ra_netid, &p) != 0) + if (ipf_p_rpcb_getproto(rm, &ra->ra_netid, &p) != 0) return(-1); /* Decode r_maddr. */ - if (ippr_rpcb_getuaddr(rm, &ra->ra_maddr, &p) != 0) + if (ipf_p_rpcb_getuaddr(rm, &ra->ra_maddr, &p) != 0) return(-1); /* Advance to r_owner and make sure it's empty. */ @@ -640,7 +643,7 @@ ippr_rpcb_xdrrpcb(rm, p, ra) } /* -------------------------------------------------------------------- */ -/* Function: ippr_rpcb_getuaddr */ +/* Function: ipf_p_rpcb_getuaddr */ /* Returns: int -- -1 == illegal string, */ /* 0 == string parsed; contents recorded */ /* Parameters: rm(I) - pointer to RPC message structure */ @@ -650,7 +653,7 @@ ippr_rpcb_xdrrpcb(rm, p, ra) /* Decode the IP address / port at p and record them in xu. */ /* -------------------------------------------------------------------- */ static int -ippr_rpcb_getuaddr(rm, xu, p) +ipf_p_rpcb_getuaddr(rm, xu, p) rpc_msg_t *rm; xdr_uaddr_t *xu; u_32_t **p; @@ -699,7 +702,7 @@ ippr_rpcb_getuaddr(rm, xu, p) /* Check for ASCII byte. */ *c = '\0'; - t = ippr_rpcb_atoi(b); + t = ipf_p_rpcb_atoi(b); if (t > 255) return(-1); @@ -721,7 +724,7 @@ ippr_rpcb_getuaddr(rm, xu, p) return(-1); /* Handle the last byte (port low byte) */ - t = ippr_rpcb_atoi(b); + t = ipf_p_rpcb_atoi(b); if (t > 255) return(-1); pp[d - 4] = t & 0xff; @@ -730,14 +733,14 @@ ippr_rpcb_getuaddr(rm, xu, p) } /* -------------------------------------------------------------------- */ -/* Function: ippr_rpcb_atoi (XXX should be generic for all proxies) */ +/* Function: ipf_p_rpcb_atoi (XXX should be generic for all proxies) */ /* Returns: int -- integer representation of supplied string */ /* Parameters: ptr(I) - input string */ /* */ /* Simple version of atoi(3) ripped from ip_rcmd_pxy.c. */ /* -------------------------------------------------------------------- */ static u_int -ippr_rpcb_atoi(ptr) +ipf_p_rpcb_atoi(ptr) char *ptr; { register char *s = ptr, c; @@ -751,7 +754,7 @@ ippr_rpcb_atoi(ptr) } /* -------------------------------------------------------------------- */ -/* Function: ippr_rpcb_modreq */ +/* Function: ipf_p_rpcb_modreq */ /* Returns: int -- change in datagram length */ /* APR_ERR(2) - critical failure */ /* Parameters: fin(I) - pointer to packet information */ @@ -764,7 +767,7 @@ ippr_rpcb_atoi(ptr) /* with the latter. (This is exclusive to protocol versions 3 & 4). */ /* -------------------------------------------------------------------- */ static int -ippr_rpcb_modreq(fin, nat, rm, m, off) +ipf_p_rpcb_modreq(fin, nat, rm, m, off) fr_info_t *fin; nat_t *nat; rpc_msg_t *rm; @@ -779,8 +782,8 @@ ippr_rpcb_modreq(fin, nat, rm, m, off) int diff; ra = &rm->rm_call.rc_rpcbargs; - i = (char *)&nat->nat_inip.s_addr; - p = (char *)&nat->nat_inport; + i = (char *)&nat->nat_odstaddr; + p = (char *)&nat->nat_odport; /* Form new string. */ bzero(uaddr, sizeof(uaddr)); /* Just in case we need padding. */ @@ -821,9 +824,9 @@ ippr_rpcb_modreq(fin, nat, rm, m, off) if (diff != 0) { udp = fin->fin_dp; udp->uh_ulen = htons(ntohs(udp->uh_ulen) + diff); - fin->fin_ip->ip_len += diff; - fin->fin_dlen += diff; fin->fin_plen += diff; + fin->fin_ip->ip_len = htons(fin->fin_plen); + fin->fin_dlen += diff; /* XXX Storage lengths. */ } @@ -831,7 +834,7 @@ ippr_rpcb_modreq(fin, nat, rm, m, off) } /* -------------------------------------------------------------------- */ -/* Function: ippr_rpcb_decoderep */ +/* Function: ipf_p_rpcb_decoderep */ /* Returns: int - -1 == bad request or critical failure, */ /* 0 == valid, negative reply */ /* 1 == vaddlid, positive reply; needs no changes */ @@ -851,7 +854,7 @@ ippr_rpcb_modreq(fin, nat, rm, m, off) /* is enough room in rs_buf for the basic RPC message "preamble". */ /* -------------------------------------------------------------------- */ static int -ippr_rpcb_decoderep(fin, nat, rs, rm, rxp) +ipf_p_rpcb_decoderep(fin, nat, rs, rm, rxp) fr_info_t *fin; nat_t *nat; rpcb_session_t *rs; @@ -875,7 +878,7 @@ ippr_rpcb_decoderep(fin, nat, rs, rm, rxp) /* Lookup XID */ MUTEX_ENTER(&rs->rs_rxlock); - if ((rx = ippr_rpcb_lookup(rs, xdr)) == NULL) { + if ((rx = ipf_p_rpcb_lookup(rs, xdr)) == NULL) { MUTEX_EXIT(&rs->rs_rxlock); return(-1); } @@ -900,7 +903,7 @@ ippr_rpcb_decoderep(fin, nat, rs, rm, rxp) } /* Bypass RPC authentication stuff. */ - if (ippr_rpcb_skipauth(rm, &rr->rr_authverf, &p) != 0) + if (ipf_p_rpcb_skipauth(rm, &rr->rr_authverf, &p) != 0) return(-1); /* Test accept status */ @@ -916,20 +919,20 @@ ippr_rpcb_decoderep(fin, nat, rs, rm, rxp) /* There must be only one 4 byte argument. */ if (!RPCB_BUF_EQ(rm, p, 4)) return(-1); - + rr->rr_v2 = p; xdr = B(rr->rr_v2); - + /* Reply w/ a 0 port indicates service isn't registered */ if (xdr == 0) return(0); - + /* Is the value sane? */ if (xdr > 65535) return(-1); /* Create NAT & state table entries. */ - if (ippr_rpcb_getnat(fin, nat, rx->rx_proto, (u_int)xdr) != 0) + if (ipf_p_rpcb_getnat(fin, nat, rx->rx_proto, (u_int)xdr) != 0) return(-1); break; case RPCB_RES_STRING: @@ -947,15 +950,15 @@ ippr_rpcb_decoderep(fin, nat, rs, rm, rxp) return(0); /* Decode the target IP address / port. */ - if (ippr_rpcb_getuaddr(rm, &rr->rr_v3, &p) != 0) + if (ipf_p_rpcb_getuaddr(rm, &rr->rr_v3, &p) != 0) return(-1); /* Validate the IP address and port contained. */ - if (nat->nat_inip.s_addr != rr->rr_v3.xu_ip) + if (nat->nat_odstaddr != rr->rr_v3.xu_ip) return(-1); /* Create NAT & state table entries. */ - if (ippr_rpcb_getnat(fin, nat, rx->rx_proto, + if (ipf_p_rpcb_getnat(fin, nat, rx->rx_proto, (u_int)rr->rr_v3.xu_port) != 0) return(-1); break; @@ -980,9 +983,9 @@ ippr_rpcb_decoderep(fin, nat, rs, rm, rxp) for(;;) { re = &rl->rl_entries[rl->rl_cnt]; - if (ippr_rpcb_getuaddr(rm, &re->re_maddr, &p) != 0) + if (ipf_p_rpcb_getuaddr(rm, &re->re_maddr, &p) != 0) return(-1); - if (ippr_rpcb_getproto(rm, &re->re_netid, &p) != 0) + if (ipf_p_rpcb_getproto(rm, &re->re_netid, &p) != 0) return(-1); /* re_semantics & re_pfamily length */ if (!RPCB_BUF_GEQ(rm, p, 12)) @@ -992,7 +995,7 @@ ippr_rpcb_decoderep(fin, nat, rs, rm, rxp) if ((xdr != 4) || strncmp((char *)p, "inet", 4)) return(-1); p++; - if (ippr_rpcb_getproto(rm, &re->re_proto, &p) != 0) + if (ipf_p_rpcb_getproto(rm, &re->re_proto, &p) != 0) return(-1); if (!RPCB_BUF_GEQ(rm, p, 4)) return(-1); @@ -1011,7 +1014,7 @@ ippr_rpcb_decoderep(fin, nat, rs, rm, rxp) for(rl->rl_cnt = 0; rl->rl_cnt < cnt; rl->rl_cnt++) { re = &rl->rl_entries[rl->rl_cnt]; - rv = ippr_rpcb_getnat(fin, nat, + rv = ipf_p_rpcb_getnat(fin, nat, re->re_proto.xp_proto, (u_int)re->re_maddr.xu_port); if (rv != 0) @@ -1027,14 +1030,14 @@ ippr_rpcb_decoderep(fin, nat, rs, rm, rxp) } /* -------------------------------------------------------------------- */ -/* Function: ippr_rpcb_lookup */ +/* Function: ipf_p_rpcb_lookup */ /* Returns: rpcb_xact_t * - NULL == no matching record, */ /* else pointer to relevant entry */ /* Parameters: rs(I) - pointer to RPCB session */ /* xid(I) - XID to look for */ /* -------------------------------------------------------------------- */ static rpcb_xact_t * -ippr_rpcb_lookup(rs, xid) +ipf_p_rpcb_lookup(rs, xid) rpcb_session_t *rs; u_32_t xid; { @@ -1051,7 +1054,7 @@ ippr_rpcb_lookup(rs, xid) } /* -------------------------------------------------------------------- */ -/* Function: ippr_rpcb_deref */ +/* Function: ipf_p_rpcb_deref */ /* Returns: (void) */ /* Parameters: rs(I) - pointer to RPCB session */ /* rx(I) - pointer to RPC transaction struct to remove */ @@ -1062,7 +1065,7 @@ ippr_rpcb_lookup(rs, xid) /* Free the RPCB transaction record rx from the chain of entries. */ /* -------------------------------------------------------------------- */ static void -ippr_rpcb_deref(rs, rx) +ipf_p_rpcb_deref(rs, rx) rpcb_session_t *rs; rpcb_xact_t *rx; { @@ -1085,7 +1088,7 @@ ippr_rpcb_deref(rs, rx) } /* -------------------------------------------------------------------- */ -/* Function: ippr_rpcb_getproto */ +/* Function: ipf_p_rpcb_getproto */ /* Returns: int - -1 == illegal protocol/netid, */ /* 0 == legal protocol/netid */ /* Parameters: rm(I) - pointer to RPC message structure */ @@ -1095,7 +1098,7 @@ ippr_rpcb_deref(rs, rx) /* Decode netid/proto stored at p and record its numeric value. */ /* -------------------------------------------------------------------- */ static int -ippr_rpcb_getproto(rm, xp, p) +ipf_p_rpcb_getproto(rm, xp, p) rpc_msg_t *rm; xdr_proto_t *xp; u_32_t **p; @@ -1122,7 +1125,7 @@ ippr_rpcb_getproto(rm, xp, p) else { return(-1); } - + /* Advance past the string. */ (*p)++; @@ -1130,7 +1133,7 @@ ippr_rpcb_getproto(rm, xp, p) } /* -------------------------------------------------------------------- */ -/* Function: ippr_rpcb_getnat */ +/* Function: ipf_p_rpcb_getnat */ /* Returns: int -- -1 == failed to create table entries, */ /* 0 == success */ /* Parameters: fin(I) - pointer to packet information */ @@ -1142,12 +1145,13 @@ ippr_rpcb_getproto(rm, xp, p) /* attempt between RPC client and server. */ /* -------------------------------------------------------------------- */ static int -ippr_rpcb_getnat(fin, nat, proto, port) +ipf_p_rpcb_getnat(fin, nat, proto, port) fr_info_t *fin; nat_t *nat; u_int proto; u_int port; { + ipf_main_softc_t *softc = fin->fin_main_soft; ipnat_t *ipn, ipnat; tcphdr_t tcp; ipstate_t *is; @@ -1159,15 +1163,13 @@ ippr_rpcb_getnat(fin, nat, proto, port) /* Generate dummy fr_info */ bcopy((char *)fin, (char *)&fi, sizeof(fi)); - fi.fin_state = NULL; - fi.fin_nat = NULL; fi.fin_out = 0; - fi.fin_src = fin->fin_dst; - fi.fin_dst = nat->nat_outip; fi.fin_p = proto; fi.fin_sport = 0; fi.fin_dport = port & 0xffff; fi.fin_flx |= FI_IGNORE; + fi.fin_saddr = nat->nat_osrcaddr; + fi.fin_daddr = nat->nat_odstaddr; bzero((char *)&tcp, sizeof(tcp)); tcp.th_dport = htons(port); @@ -1195,18 +1197,18 @@ ippr_rpcb_getnat(fin, nat, proto, port) * If successful, fr_stlookup returns with ipf_state locked. We have * no use for this lock, so simply unlock it if necessary. */ - is = fr_stlookup(&fi, &tcp, NULL); + is = ipf_state_lookup(&fi, &tcp, NULL); if (is != NULL) { - RWLOCK_EXIT(&ipf_state); + RWLOCK_EXIT(&softc->ipf_state); } - RWLOCK_EXIT(&ipf_nat); + RWLOCK_EXIT(&softc->ipf_nat); - WRITE_ENTER(&ipf_nat); - natl = nat_inlookup(&fi, nflags, proto, fi.fin_src, fi.fin_dst); + WRITE_ENTER(&softc->ipf_nat); + natl = ipf_nat_inlookup(&fi, nflags, proto, fi.fin_src, fi.fin_dst); if ((natl != NULL) && (is != NULL)) { - MUTEX_DOWNGRADE(&ipf_nat); + MUTEX_DOWNGRADE(&softc->ipf_nat); return(0); } @@ -1220,6 +1222,10 @@ ippr_rpcb_getnat(fin, nat, proto, port) nflags &= ~NAT_SEARCH; if (natl == NULL) { +#ifdef USE_MUTEXES + ipf_nat_softc_t *softn = softc->ipf_nat_soft; +#endif + /* XXX Since we're just copying the original ipn contents * back, would we be better off just sending a pointer to * the 'temp' copy off to nat_new instead? @@ -1228,46 +1234,51 @@ ippr_rpcb_getnat(fin, nat, proto, port) bcopy((char *)ipn, (char *)&ipnat, sizeof(ipnat)); ipn->in_flags = nflags & IPN_TCPUDP; ipn->in_apr = NULL; - ipn->in_p = proto; - ipn->in_pmin = htons(fi.fin_dport); - ipn->in_pmax = htons(fi.fin_dport); - ipn->in_pnext = htons(fi.fin_dport); + ipn->in_pr[0] = proto; + ipn->in_pr[1] = proto; + ipn->in_dpmin = fi.fin_dport; + ipn->in_dpmax = fi.fin_dport; + ipn->in_dpnext = fi.fin_dport; ipn->in_space = 1; ipn->in_ippip = 1; if (ipn->in_flags & IPN_FILTER) { ipn->in_scmp = 0; ipn->in_dcmp = 0; } - *ipn->in_plabel = '\0'; + ipn->in_plabel = -1; /* Create NAT entry. return NULL if this fails. */ - natl = nat_new(&fi, ipn, NULL, nflags|SI_CLONE|NAT_SLAVE, + MUTEX_ENTER(&softn->ipf_nat_new); + natl = ipf_nat_add(&fi, ipn, NULL, nflags|SI_CLONE|NAT_SLAVE, NAT_INBOUND); + MUTEX_EXIT(&softn->ipf_nat_new); bcopy((char *)&ipnat, (char *)ipn, sizeof(ipnat)); if (natl == NULL) { - MUTEX_DOWNGRADE(&ipf_nat); + MUTEX_DOWNGRADE(&softc->ipf_nat); return(-1); } + natl->nat_ptr = ipn; + fi.fin_saddr = natl->nat_nsrcaddr; + fi.fin_daddr = natl->nat_ndstaddr; ipn->in_use++; - (void) nat_proto(&fi, natl, nflags); - nat_update(&fi, natl, natl->nat_ptr); + (void) ipf_nat_proto(&fi, natl, nflags); + MUTEX_ENTER(&natl->nat_lock); + ipf_nat_update(&fi, natl); + MUTEX_EXIT(&natl->nat_lock); } - MUTEX_DOWNGRADE(&ipf_nat); + MUTEX_DOWNGRADE(&softc->ipf_nat); if (is == NULL) { /* Create state entry. Return NULL if this fails. */ - fi.fin_dst = nat->nat_inip; - fi.fin_nat = (void *)natl; fi.fin_flx |= FI_NATED; fi.fin_flx &= ~FI_STATE; nflags &= NAT_TCPUDP; nflags |= SI_W_SPORT|SI_CLONE; - is = fr_addstate(&fi, NULL, nflags); - if (is == NULL) { + if (ipf_state_add(softc, &fi, NULL, nflags) != 0) { /* * XXX nat_delete is private to ip_nat.c. Should * check w/ Darren about this one. @@ -1276,15 +1287,13 @@ ippr_rpcb_getnat(fin, nat, proto, port) */ return(-1); } - if (fi.fin_state != NULL) - fr_statederef((ipstate_t **)&fi.fin_state); } return(0); } /* -------------------------------------------------------------------- */ -/* Function: ippr_rpcb_modv3 */ +/* Function: ipf_p_rpcb_modv3 */ /* Returns: int -- change in packet length */ /* Parameters: fin(I) - pointer to packet information */ /* nat(I) - pointer to NAT session */ @@ -1296,7 +1305,7 @@ ippr_rpcb_getnat(fin, nat, proto, port) /* lengths as necessary. */ /* -------------------------------------------------------------------- */ static int -ippr_rpcb_modv3(fin, nat, rm, m, off) +ipf_p_rpcb_modv3(fin, nat, rm, m, off) fr_info_t *fin; nat_t *nat; rpc_msg_t *rm; @@ -1310,7 +1319,7 @@ ippr_rpcb_modv3(fin, nat, rm, m, off) int diff; rr = &rm->rm_resp; - i = (char *)&nat->nat_outip.s_addr; + i = (char *)&nat->nat_ndstaddr; p = (char *)&rr->rr_v3.xu_port; /* Form new string. */ @@ -1336,7 +1345,7 @@ ippr_rpcb_modv3(fin, nat, rm, m, off) /* Write new string. */ COPYBACK(m, off, xlen, uaddr); - + /* Determine difference in data lengths. */ diff = xlen - XDRALIGN(B(rr->rr_v3.xu_xslen)); @@ -1345,13 +1354,13 @@ ippr_rpcb_modv3(fin, nat, rm, m, off) * adjustments. */ if (diff != 0) - ippr_rpcb_fixlen(fin, diff); + ipf_p_rpcb_fixlen(fin, diff); return(diff); } /* -------------------------------------------------------------------- */ -/* Function: ippr_rpcb_modv4 */ +/* Function: ipf_p_rpcb_modv4 */ /* Returns: int -- change in packet length */ /* Parameters: fin(I) - pointer to packet information */ /* nat(I) - pointer to NAT session */ @@ -1362,7 +1371,7 @@ ippr_rpcb_modv3(fin, nat, rm, m, off) /* Write new rpcb_entry list, adjusting lengths as necessary. */ /* -------------------------------------------------------------------- */ static int -ippr_rpcb_modv4(fin, nat, rm, m, off) +ipf_p_rpcb_modv4(fin, nat, rm, m, off) fr_info_t *fin; nat_t *nat; rpc_msg_t *rm; @@ -1381,7 +1390,7 @@ ippr_rpcb_modv4(fin, nat, rm, m, off) rr = &rm->rm_resp; rl = &rr->rr_v4; - i = (char *)&nat->nat_outip.s_addr; + i = (char *)&nat->nat_ndstaddr; /* Determine mbuf offset to write to. */ re = &rl->rl_entries[0]; @@ -1432,14 +1441,14 @@ ippr_rpcb_modv4(fin, nat, rm, m, off) * adjustments. */ if (diff != 0) - ippr_rpcb_fixlen(fin, diff); + ipf_p_rpcb_fixlen(fin, diff); return(diff); } /* -------------------------------------------------------------------- */ -/* Function: ippr_rpcb_fixlen */ +/* Function: ipf_p_rpcb_fixlen */ /* Returns: (void) */ /* Parameters: fin(I) - pointer to packet information */ /* len(I) - change in packet length */ @@ -1448,7 +1457,7 @@ ippr_rpcb_modv4(fin, nat, rm, m, off) /* header fields. */ /* -------------------------------------------------------------------- */ static void -ippr_rpcb_fixlen(fin, len) +ipf_p_rpcb_fixlen(fin, len) fr_info_t *fin; int len; { @@ -1456,9 +1465,9 @@ ippr_rpcb_fixlen(fin, len) udp = fin->fin_dp; udp->uh_ulen = htons(ntohs(udp->uh_ulen) + len); - fin->fin_ip->ip_len += len; - fin->fin_dlen += len; fin->fin_plen += len; + fin->fin_ip->ip_len = htons(fin->fin_plen); + fin->fin_dlen += len; } #undef B diff --git a/sys/contrib/ipfilter/netinet/ip_rules.c b/sys/contrib/ipfilter/netinet/ip_rules.c index f080ec5b8324..434b9de937b9 100644 --- a/sys/contrib/ipfilter/netinet/ip_rules.c +++ b/sys/contrib/ipfilter/netinet/ip_rules.c @@ -1,18 +1,29 @@ /* $FreeBSD$ */ /* -* Copyright (C) 1993-2000 by Darren Reed. +* Copyright (C) 2012 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 #include #include #include -#if !defined(__FreeBSD__) && !defined(__OpenBSD__) && !defined(__sgi) -# include +#if defined(__FreeBSD_version) && (__FreeBSD_version >= 40000) +# if defined(_KERNEL) +# include +# else +# include +# endif +#endif +#if defined(__NetBSD_Version__) && (__NetBSD_Version__ >= 399000000) +#else +# if !defined(__FreeBSD__) && !defined(__OpenBSD__) && !defined(__sgi) +# include +# endif #endif #include #include @@ -40,18 +51,32 @@ #ifdef IPFILTER_COMPILED +extern ipf_main_softc_t ipfmain; + + static u_long in_rule__0[] = { -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xffffffff, 0, 0, 0, 0, 0, 0, 0x1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x80000000, 0x8002, 0, 0, 0, 0xffff, 0, 0, 0x4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 +0, 0, 0, 0, 0, 0, 0, 0x8070d88, 0, 0, 0, 0xffffffff, 0, 0, 0, 0, 0, 0, 0, 0xffffffff, 0x1b0, 0x1, 0, 0, 0, 0x2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x40000000, 0x8002, 0, 0, 0, 0xffff, 0, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xffffffff, 0, 0, 0, 0, 0, 0, 0, 0, 0xffffffff, 0, 0, 0, 0, 0, 0, 0, 0, 0xffffffff, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xffffffff, 0, 0, 0, 0 }; static u_long out_rule__0[] = { -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xffffffff, 0, 0, 0, 0, 0, 0, 0x1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x80000000, 0x4002, 0, 0, 0, 0xffff, 0, 0, 0x4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 +0, 0, 0, 0, 0, 0, 0, 0x8070d88, 0, 0, 0, 0xffffffff, 0, 0, 0, 0, 0, 0, 0, 0xffffffff, 0x1b0, 0x1, 0, 0, 0, 0x3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x40000000, 0x4002, 0, 0, 0, 0xffff, 0, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xffffffff, 0, 0, 0, 0, 0, 0, 0, 0, 0xffffffff, 0, 0, 0, 0, 0, 0, 0, 0, 0xffffffff, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xffffffff, 0, 0, 0, 0 }; frentry_t *ipf_rules_in_[1] = { (frentry_t *)&in_rule__0 }; +/* XXX This file (ip_rules.c) is not part of the ipfilter tarball, it is + XXX generated by the ipfilter build process. Unfortunately the build + XXX process did not generate the following lines so they are added + XXX by hand here. This is a bit of a hack but it works for now. Future + XXX imports/merges of ipfilter may generate this so the following will + XXX need to be removed following some future merge. + XXX */ +frentry_t *ipf_rules_out_[1] = { + (frentry_t *)&out_rule__0 +}; + frentry_t *ipfrule_match_in_(fin, passp) fr_info_t *fin; u_32_t *passp; @@ -62,10 +87,6 @@ u_32_t *passp; return fr; } -frentry_t *ipf_rules_out_[1] = { - (frentry_t *)&out_rule__0 -}; - frentry_t *ipfrule_match_out_(fin, passp) fr_info_t *fin; u_32_t *passp; @@ -87,9 +108,14 @@ int ipfrule_add_out_() fp = ipf_rules_out_[i]; fp->fr_next = NULL; for (j = i + 1; j < max; j++) - if (strncmp(fp->fr_group, + if (strncmp(fp->fr_names + fp->fr_group, + ipf_rules_out_[j]->fr_names + ipf_rules_out_[j]->fr_group, FR_GROUPLEN) == 0) { + if (ipf_rules_out_[j] != NULL) + ipf_rules_out_[j]->fr_pnext = + &fp->fr_next; + fp->fr_pnext = &ipf_rules_out_[j]; fp->fr_next = ipf_rules_out_[j]; break; } @@ -97,13 +123,14 @@ int ipfrule_add_out_() fp = &ipfrule_out_; bzero((char *)fp, sizeof(*fp)); - fp->fr_type = FR_T_CALLFUNC|FR_T_BUILTIN; + fp->fr_type = FR_T_CALLFUNC_BUILTIN; fp->fr_flags = FR_OUTQUE|FR_NOMATCH; fp->fr_data = (void *)ipf_rules_out_[0]; fp->fr_dsize = sizeof(ipf_rules_out_[0]); - fp->fr_v = 4; + fp->fr_family = AF_INET; fp->fr_func = (ipfunc_t)ipfrule_match_out_; - err = frrequest(IPL_LOGIPF, SIOCADDFR, (caddr_t)fp, fr_active, 0); + err = frrequest(&ipfmain, IPL_LOGIPF, SIOCADDFR, (caddr_t)fp, + ipfmain.ipf_active, 0); return err; } @@ -129,8 +156,9 @@ int ipfrule_remove_out_() } } if (err == 0) - err = frrequest(IPL_LOGIPF, SIOCDELFR, - (caddr_t)&ipfrule_out_, fr_active, 0); + err = frrequest(&ipfmain, IPL_LOGIPF, SIOCDELFR, + (caddr_t)&ipfrule_out_, + ipfmain.ipf_active, 0); if (err) return err; @@ -149,9 +177,14 @@ int ipfrule_add_in_() fp = ipf_rules_in_[i]; fp->fr_next = NULL; for (j = i + 1; j < max; j++) - if (strncmp(fp->fr_group, + if (strncmp(fp->fr_names + fp->fr_group, + ipf_rules_in_[j]->fr_names + ipf_rules_in_[j]->fr_group, FR_GROUPLEN) == 0) { + if (ipf_rules_in_[j] != NULL) + ipf_rules_in_[j]->fr_pnext = + &fp->fr_next; + fp->fr_pnext = &ipf_rules_in_[j]; fp->fr_next = ipf_rules_in_[j]; break; } @@ -159,13 +192,14 @@ int ipfrule_add_in_() fp = &ipfrule_in_; bzero((char *)fp, sizeof(*fp)); - fp->fr_type = FR_T_CALLFUNC|FR_T_BUILTIN; + fp->fr_type = FR_T_CALLFUNC_BUILTIN; fp->fr_flags = FR_INQUE|FR_NOMATCH; fp->fr_data = (void *)ipf_rules_in_[0]; fp->fr_dsize = sizeof(ipf_rules_in_[0]); - fp->fr_v = 4; + fp->fr_family = AF_INET; fp->fr_func = (ipfunc_t)ipfrule_match_in_; - err = frrequest(IPL_LOGIPF, SIOCADDFR, (caddr_t)fp, fr_active, 0); + err = frrequest(&ipfmain, IPL_LOGIPF, SIOCADDFR, (caddr_t)fp, + ipfmain.ipf_active, 0); return err; } @@ -191,8 +225,9 @@ int ipfrule_remove_in_() } } if (err == 0) - err = frrequest(IPL_LOGIPF, SIOCDELFR, - (caddr_t)&ipfrule_in_, fr_active, 0); + err = frrequest(&ipfmain, IPL_LOGIPF, SIOCDELFR, + (caddr_t)&ipfrule_in_, + ipfmain.ipf_active, 0); if (err) return err; diff --git a/sys/contrib/ipfilter/netinet/ip_scan.c b/sys/contrib/ipfilter/netinet/ip_scan.c index 54acb2aa4297..5b7c77e4b102 100644 --- a/sys/contrib/ipfilter/netinet/ip_scan.c +++ b/sys/contrib/ipfilter/netinet/ip_scan.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 1995-2001 by Darren Reed. + * Copyright (C) 2012 by Darren Reed. * * See the IPFILTER.LICENCE file for details on licencing. */ @@ -58,17 +58,17 @@ struct file; #if !defined(lint) static const char sccsid[] = "@(#)ip_state.c 1.8 6/5/96 (C) 1993-2000 Darren Reed"; -static const char rcsid[] = "@(#)$Id: ip_scan.c,v 2.40.2.10 2007/06/02 21:22:28 darrenr Exp $"; +static const char rcsid[] = "@(#)$Id$"; #endif #ifdef IPFILTER_SCAN /* endif at bottom of file */ -ipscan_t *ipsc_list = NULL, - *ipsc_tail = NULL; -ipscanstat_t ipsc_stat; +ipscan_t *ipf_scan_list = NULL, + *ipf_scan_tail = NULL; +ipscanstat_t ipf_scan_stat; # ifdef USE_MUTEXES -ipfrwlock_t ipsc_rwlock; +ipfrwlock_t ipf_scan_rwlock; # endif # ifndef isalpha @@ -77,42 +77,47 @@ ipfrwlock_t ipsc_rwlock; # endif -int ipsc_add __P((caddr_t)); -int ipsc_delete __P((caddr_t)); -struct ipscan *ipsc_lookup __P((char *)); -int ipsc_matchstr __P((sinfo_t *, char *, int)); -int ipsc_matchisc __P((ipscan_t *, ipstate_t *, int, int, int *)); -int ipsc_match __P((ipstate_t *)); +int ipf_scan_add __P((caddr_t)); +int ipf_scan_remove __P((caddr_t)); +struct ipscan *ipf_scan_lookup __P((char *)); +int ipf_scan_matchstr __P((sinfo_t *, char *, int)); +int ipf_scan_matchisc __P((ipscan_t *, ipstate_t *, int, int, int *)); +int ipf_scan_match __P((ipstate_t *)); -static int ipsc_inited = 0; +static int ipf_scan_inited = 0; -int ipsc_init() +int +ipf_scan_init() { - RWLOCK_INIT(&ipsc_rwlock, "ip scan rwlock"); - ipsc_inited = 1; + RWLOCK_INIT(&ipf_scan_rwlock, "ip scan rwlock"); + ipf_scan_inited = 1; return 0; } -void fr_scanunload() +void +ipf_scan_unload(ipf_main_softc_t *arg) { - if (ipsc_inited == 1) { - RW_DESTROY(&ipsc_rwlock); - ipsc_inited = 0; + if (ipf_scan_inited == 1) { + RW_DESTROY(&ipf_scan_rwlock); + ipf_scan_inited = 0; } } -int ipsc_add(data) -caddr_t data; +int +ipf_scan_add(data) + caddr_t data; { ipscan_t *i, *isc; int err; KMALLOC(isc, ipscan_t *); - if (!isc) + if (!isc) { + ipf_interror = 90001; return ENOMEM; + } err = copyinptr(data, isc, sizeof(*isc)); if (err) { @@ -120,23 +125,24 @@ caddr_t data; return err; } - WRITE_ENTER(&ipsc_rwlock); + WRITE_ENTER(&ipf_scan_rwlock); - i = ipsc_lookup(isc->ipsc_tag); - if (i) { - RWLOCK_EXIT(&ipsc_rwlock); + i = ipf_scan_lookup(isc->ipsc_tag); + if (i != NULL) { + RWLOCK_EXIT(&ipf_scan_rwlock); KFREE(isc); + ipf_interror = 90002; return EEXIST; } - if (ipsc_tail) { - ipsc_tail->ipsc_next = isc; - isc->ipsc_pnext = &ipsc_tail->ipsc_next; - ipsc_tail = isc; + if (ipf_scan_tail) { + ipf_scan_tail->ipsc_next = isc; + isc->ipsc_pnext = &ipf_scan_tail->ipsc_next; + ipf_scan_tail = isc; } else { - ipsc_list = isc; - ipsc_tail = isc; - isc->ipsc_pnext = &ipsc_list; + ipf_scan_list = isc; + ipf_scan_tail = isc; + isc->ipsc_pnext = &ipf_scan_list; } isc->ipsc_next = NULL; @@ -145,14 +151,15 @@ caddr_t data; isc->ipsc_sref = 0; isc->ipsc_active = 0; - ipsc_stat.iscs_entries++; - RWLOCK_EXIT(&ipsc_rwlock); + ipf_scan_stat.iscs_entries++; + RWLOCK_EXIT(&ipf_scan_rwlock); return 0; } -int ipsc_delete(data) -caddr_t data; +int +ipf_scan_remove(data) + caddr_t data; { ipscan_t isc, *i; int err; @@ -161,14 +168,15 @@ caddr_t data; if (err) return err; - WRITE_ENTER(&ipsc_rwlock); + WRITE_ENTER(&ipf_scan_rwlock); - i = ipsc_lookup(isc.ipsc_tag); + i = ipf_scan_lookup(isc.ipsc_tag); if (i == NULL) err = ENOENT; else { if (i->ipsc_fref) { - RWLOCK_EXIT(&ipsc_rwlock); + RWLOCK_EXIT(&ipf_scan_rwlock); + ipf_interror = 90003; return EBUSY; } @@ -176,61 +184,66 @@ caddr_t data; if (i->ipsc_next) i->ipsc_next->ipsc_pnext = i->ipsc_pnext; else { - if (i->ipsc_pnext == &ipsc_list) - ipsc_tail = NULL; + if (i->ipsc_pnext == &ipf_scan_list) + ipf_scan_tail = NULL; else - ipsc_tail = *(*i->ipsc_pnext)->ipsc_pnext; + ipf_scan_tail = *(*i->ipsc_pnext)->ipsc_pnext; } - ipsc_stat.iscs_entries--; + ipf_scan_stat.iscs_entries--; KFREE(i); } - RWLOCK_EXIT(&ipsc_rwlock); + RWLOCK_EXIT(&ipf_scan_rwlock); return err; } -struct ipscan *ipsc_lookup(tag) -char *tag; +struct ipscan * +ipf_scan_lookup(tag) + char *tag; { ipscan_t *i; - for (i = ipsc_list; i; i = i->ipsc_next) + for (i = ipf_scan_list; i; i = i->ipsc_next) if (!strcmp(i->ipsc_tag, tag)) return i; return NULL; } -int ipsc_attachfr(fr) -struct frentry *fr; +int +ipf_scan_attachfr(fr) + struct frentry *fr; { ipscan_t *i; - if (fr->fr_isctag[0]) { - READ_ENTER(&ipsc_rwlock); - i = ipsc_lookup(fr->fr_isctag); + if (fr->fr_isctag != -1) { + READ_ENTER(&ipf_scan_rwlock); + i = ipf_scan_lookup(fr->fr_isctag + fr->fr_names); if (i != NULL) { ATOMIC_INC32(i->ipsc_fref); } - RWLOCK_EXIT(&ipsc_rwlock); - if (i == NULL) + RWLOCK_EXIT(&ipf_scan_rwlock); + if (i == NULL) { + ipf_interror = 90004; return ENOENT; + } fr->fr_isc = i; } return 0; } -int ipsc_attachis(is) -struct ipstate *is; +int +ipf_scan_attachis(is) + struct ipstate *is; { frentry_t *fr; ipscan_t *i; - READ_ENTER(&ipsc_rwlock); + READ_ENTER(&ipf_scan_rwlock); fr = is->is_rule; - if (fr) { + if (fr != NULL) { i = fr->fr_isc; if ((i != NULL) && (i != (ipscan_t *)-1)) { is->is_isc = i; @@ -245,13 +258,14 @@ struct ipstate *is; is->is_flags |= IS_SC_MATCHS; } } - RWLOCK_EXIT(&ipsc_rwlock); + RWLOCK_EXIT(&ipf_scan_rwlock); return 0; } -int ipsc_detachfr(fr) -struct frentry *fr; +int +ipf_scan_detachfr(fr) + struct frentry *fr; { ipscan_t *i; @@ -263,18 +277,19 @@ struct frentry *fr; } -int ipsc_detachis(is) -struct ipstate *is; +int +ipf_scan_detachis(is) + struct ipstate *is; { ipscan_t *i; - READ_ENTER(&ipsc_rwlock); + READ_ENTER(&ipf_scan_rwlock); if ((i = is->is_isc) && (i != (ipscan_t *)-1)) { ATOMIC_DEC32(i->ipsc_sref); is->is_isc = NULL; is->is_flags &= ~(IS_SC_CLIENT|IS_SC_SERVER); } - RWLOCK_EXIT(&ipsc_rwlock); + RWLOCK_EXIT(&ipf_scan_rwlock); return 0; } @@ -282,10 +297,11 @@ struct ipstate *is; /* * 'string' compare for scanning */ -int ipsc_matchstr(sp, str, n) -sinfo_t *sp; -char *str; -int n; +int +ipf_scan_matchstr(sp, str, n) + sinfo_t *sp; + char *str; + int n; { char *s, *t, *up; int i = n; @@ -316,10 +332,11 @@ int n; * Returns 3 if both server and client match, 2 if just server, * 1 if just client */ -int ipsc_matchisc(isc, is, cl, sl, maxm) -ipscan_t *isc; -ipstate_t *is; -int cl, sl, maxm[2]; +int +ipf_scan_matchisc(isc, is, cl, sl, maxm) + ipscan_t *isc; + ipstate_t *is; + int cl, sl, maxm[2]; { int i, j, k, n, ret = 0, flags; @@ -348,7 +365,8 @@ int cl, sl, maxm[2]; i = 0; n = MIN(cl, isc->ipsc_clen); if ((n > 0) && (!maxm || (n >= maxm[1]))) { - if (!ipsc_matchstr(&isc->ipsc_cl, is->is_sbuf[0], n)) { + if (!ipf_scan_matchstr(&isc->ipsc_cl, + is->is_sbuf[0], n)) { i++; ret |= 1; if (n > j) @@ -364,7 +382,8 @@ int cl, sl, maxm[2]; i = 0; n = MIN(cl, isc->ipsc_slen); if ((n > 0) && (!maxm || (n >= maxm[1]))) { - if (!ipsc_matchstr(&isc->ipsc_sl, is->is_sbuf[1], n)) { + if (!ipf_scan_matchstr(&isc->ipsc_sl, + is->is_sbuf[1], n)) { i++; ret |= 2; if (n > k) @@ -381,8 +400,9 @@ int cl, sl, maxm[2]; } -int ipsc_match(is) -ipstate_t *is; +int +ipf_scan_match(is) + ipstate_t *is; { int i, j, k, n, cl, sl, maxm[2]; ipscan_t *isc, *lm; @@ -399,7 +419,7 @@ ipstate_t *is; /* * Known object to scan for. */ - i = ipsc_matchisc(isc, is, cl, sl, NULL); + i = ipf_scan_matchisc(isc, is, cl, sl, NULL); if (i & 1) { is->is_flags |= IS_SC_MATCHC; is->is_flags &= ~IS_SC_CLIENT; @@ -415,8 +435,8 @@ ipstate_t *is; lm = NULL; maxm[0] = 0; maxm[1] = 0; - for (k = 0, isc = ipsc_list; isc; isc = isc->ipsc_next) { - i = ipsc_matchisc(isc, is, cl, sl, maxm); + for (k = 0, isc = ipf_scan_list; isc; isc = isc->ipsc_next) { + i = ipf_scan_matchisc(isc, is, cl, sl, maxm); if (i) { /* * We only want to remember the best match @@ -475,7 +495,7 @@ ipstate_t *is; j = ISC_A_NONE; if ((is->is_flags & IS_SC_MATCHALL) == IS_SC_MATCHALL) { j = isc->ipsc_action; - ipsc_stat.iscs_acted++; + ipf_scan_stat.iscs_acted++; } else if ((is->is_isc != NULL) && ((is->is_flags & IS_SC_MATCHALL) != IS_SC_MATCHALL) && !(is->is_flags & (IS_SC_CLIENT|IS_SC_SERVER))) { @@ -483,7 +503,7 @@ ipstate_t *is; * Matching failed... */ j = isc->ipsc_else; - ipsc_stat.iscs_else++; + ipf_scan_stat.iscs_else++; } switch (j) @@ -508,9 +528,10 @@ ipstate_t *is; /* * check if a packet matches what we're scanning for */ -int ipsc_packet(fin, is) -fr_info_t *fin; -ipstate_t *is; +int +ipf_scan_packet(fin, is) + fr_info_t *fin; + ipstate_t *is; { int i, j, rv, dlen, off, thoff; u_32_t seq, s0; @@ -552,7 +573,7 @@ ipstate_t *is; if (j == 0) return 1; - (void) ipsc_match(is); + (void) ipf_scan_match(is); #if 0 /* * There is the potential here for plain text passwords to get @@ -567,11 +588,12 @@ ipstate_t *is; } -int fr_scan_ioctl(data, cmd, mode, uid, ctx) -caddr_t data; -ioctlcmd_t cmd; -int mode, uid; -void *ctx; +int +ipf_scan_ioctl(data, cmd, mode, uid, ctx) + caddr_t data; + ioctlcmd_t cmd; + int mode, uid; + void *ctx; { ipscanstat_t ipscs; int err = 0; @@ -579,17 +601,19 @@ void *ctx; switch (cmd) { case SIOCADSCA : - err = ipsc_add(data); + err = ipf_scan_add(data); break; case SIOCRMSCA : - err = ipsc_delete(data); + err = ipf_scan_remove(data); break; case SIOCGSCST : - bcopy((char *)&ipsc_stat, (char *)&ipscs, sizeof(ipscs)); - ipscs.iscs_list = ipsc_list; + bcopy((char *)&ipf_scan_stat, (char *)&ipscs, sizeof(ipscs)); + ipscs.iscs_list = ipf_scan_list; err = BCOPYOUT(&ipscs, data, sizeof(ipscs)); - if (err != 0) + if (err != 0) { + ipf_interror = 90005; err = EFAULT; + } break; default : err = EINVAL; diff --git a/sys/contrib/ipfilter/netinet/ip_scan.h b/sys/contrib/ipfilter/netinet/ip_scan.h index 4772d28c012b..99032095ba05 100644 --- a/sys/contrib/ipfilter/netinet/ip_scan.h +++ b/sys/contrib/ipfilter/netinet/ip_scan.h @@ -1,10 +1,10 @@ /* - * Copyright (C) 1993-2001 by Darren Reed. + * Copyright (C) 2012 by Darren Reed. * * See the IPFILTER.LICENCE file for details on licencing. * * @(#)ip_fil.h 1.35 6/5/96 - * $Id: ip_scan.h,v 2.9.2.2 2006/07/14 06:12:19 darrenr Exp $ + * $Id$ */ #ifndef __IP_SCAN_H__ @@ -94,13 +94,13 @@ typedef struct ipscanstat { } ipscanstat_t; -extern int fr_scan_ioctl __P((caddr_t, ioctlcmd_t, int, int, void *)); -extern int ipsc_init __P((void)); -extern int ipsc_attachis __P((struct ipstate *)); -extern int ipsc_attachfr __P((struct frentry *)); -extern int ipsc_detachis __P((struct ipstate *)); -extern int ipsc_detachfr __P((struct frentry *)); -extern int ipsc_packet __P((struct fr_info *, struct ipstate *)); -extern void fr_scanunload __P((void)); +extern int ipf_scan_ioctl __P((ipf_main_softc_t *, caddr_t, ioctlcmd_t, int, int, void *)); +extern int ipf_scan_init __P((void)); +extern int ipf_scan_attachis __P((struct ipstate *)); +extern int ipf_scan_attachfr __P((struct frentry *)); +extern int ipf_scan_detachis __P((struct ipstate *)); +extern int ipf_scan_detachfr __P((struct frentry *)); +extern int ipf_scan_packet __P((struct fr_info *, struct ipstate *)); +extern void ipf_scan_unload __P((ipf_main_softc_t *)); #endif /* __IP_SCAN_H__ */ diff --git a/sys/contrib/ipfilter/netinet/ip_state.c b/sys/contrib/ipfilter/netinet/ip_state.c index 6c8b158f0bae..9c6a244233d0 100644 --- a/sys/contrib/ipfilter/netinet/ip_state.c +++ b/sys/contrib/ipfilter/netinet/ip_state.c @@ -1,9 +1,13 @@ /* $FreeBSD$ */ /* - * Copyright (C) 1995-2003 by Darren Reed. + * Copyright (C) 2012 by Darren Reed. * * See the IPFILTER.LICENCE file for details on licencing. + * + * Copyright 2008 Sun Microsystems. + * + * $Id$ */ #if defined(KERNEL) || defined(_KERNEL) # undef KERNEL @@ -15,14 +19,6 @@ #include #include #include -#if defined(__NetBSD__) && (NetBSD >= 199905) && !defined(IPFILTER_LKM) && \ - defined(_KERNEL) -# if (__NetBSD_Version__ < 399001400) -# include "opt_ipfilter_log.h" -# else -# include "opt_ipfilter.h" -# endif -#endif #if defined(_KERNEL) && defined(__FreeBSD_version) && \ (__FreeBSD_version >= 400000) && !defined(KLD_MODULE) #include "opt_inet6.h" @@ -41,9 +37,6 @@ struct file; #if defined(_KERNEL) && (__FreeBSD_version >= 220000) # include # include -# if (__FreeBSD_version >= 300000) && !defined(IPFILTER_LKM) -# include "opt_ipfilter.h" -# endif #else # include #endif @@ -72,36 +65,31 @@ struct file; #ifdef sun # include #endif -#include #include #include #include #include -#if !defined(linux) -# include -#endif #if !defined(__hpux) && !defined(linux) # include #endif #include #include +#if !defined(_KERNEL) +# include "ipf.h" +#endif #include "netinet/ip_compat.h" -#include #include "netinet/ip_fil.h" #include "netinet/ip_nat.h" #include "netinet/ip_frag.h" #include "netinet/ip_state.h" #include "netinet/ip_proxy.h" -#ifdef IPFILTER_SYNC +#include "netinet/ip_lookup.h" +#include "netinet/ip_dstlist.h" #include "netinet/ip_sync.h" -#endif -#ifdef IPFILTER_SCAN -#include "netinet/ip_scan.h" -#endif #ifdef USE_INET6 #include #endif -#if (__FreeBSD_version >= 300000) +#if FREEBSD_GE_REV(300000) # include # if defined(_KERNEL) && !defined(IPFILTER_LKM) # include @@ -113,342 +101,501 @@ struct file; #if !defined(lint) static const char sccsid[] = "@(#)ip_state.c 1.8 6/5/96 (C) 1993-2000 Darren Reed"; -static const char rcsid[] = "@(#)$Id: ip_state.c,v 2.186.2.80 2007/10/16 09:33:23 darrenr Exp $"; +static const char rcsid[] = "@(#)$Id$"; #endif -static ipstate_t **ips_table = NULL; -static u_long *ips_seed = NULL; -static int ips_num = 0; -static u_long ips_last_force_flush = 0; -ips_stat_t ips_stats; + +static ipftuneable_t ipf_state_tuneables[] = { + { { (void *)offsetof(ipf_state_softc_t, ipf_state_max) }, + "state_max", 1, 0x7fffffff, + stsizeof(ipf_state_softc_t, ipf_state_max), + 0, NULL, NULL }, + { { (void *)offsetof(ipf_state_softc_t, ipf_state_size) }, + "state_size", 1, 0x7fffffff, + stsizeof(ipf_state_softc_t, ipf_state_size), + 0, NULL, ipf_state_rehash }, + { { (void *)offsetof(ipf_state_softc_t, ipf_state_lock) }, + "state_lock", 0, 1, + stsizeof(ipf_state_softc_t, ipf_state_lock), + IPFT_RDONLY, NULL, NULL }, + { { (void *)offsetof(ipf_state_softc_t, ipf_state_maxbucket) }, + "state_maxbucket", 1, 0x7fffffff, + stsizeof(ipf_state_softc_t, ipf_state_maxbucket), + 0, NULL, NULL }, + { { (void *)offsetof(ipf_state_softc_t, ipf_state_logging) }, + "state_logging",0, 1, + stsizeof(ipf_state_softc_t, ipf_state_logging), + 0, NULL, NULL }, + { { (void *)offsetof(ipf_state_softc_t, ipf_state_wm_high) }, + "state_wm_high",2, 100, + stsizeof(ipf_state_softc_t, ipf_state_wm_high), + 0, NULL, NULL }, + { { (void *)offsetof(ipf_state_softc_t, ipf_state_wm_low) }, + "state_wm_low", 1, 99, + stsizeof(ipf_state_softc_t, ipf_state_wm_low), + 0, NULL, NULL }, + { { (void *)offsetof(ipf_state_softc_t, ipf_state_wm_freq) }, + "state_wm_freq",2, 999999, + stsizeof(ipf_state_softc_t, ipf_state_wm_freq), + 0, NULL, NULL }, + { { NULL }, + NULL, 0, 0, + 0, + 0, NULL, NULL } +}; + +#define SINCL(x) ATOMIC_INCL(softs->x) +#define SBUMP(x) (softs->x)++ +#define SBUMPD(x, y) do { (softs->x.y)++; DT(y); } while (0) +#define SBUMPDX(x, y, z)do { (softs->x.y)++; DT(z); } while (0) #ifdef USE_INET6 -static ipstate_t *fr_checkicmp6matchingstate __P((fr_info_t *)); +static ipstate_t *ipf_checkicmp6matchingstate __P((fr_info_t *)); #endif -static ipstate_t *fr_matchsrcdst __P((fr_info_t *, ipstate_t *, i6addr_t *, +static int ipf_allowstateicmp __P((fr_info_t *, ipstate_t *, i6addr_t *)); +static ipstate_t *ipf_matchsrcdst __P((fr_info_t *, ipstate_t *, i6addr_t *, i6addr_t *, tcphdr_t *, u_32_t)); -static ipstate_t *fr_checkicmpmatchingstate __P((fr_info_t *)); -static int fr_state_flush __P((int, int)); -static int fr_state_flush_entry __P((void *)); -static ips_stat_t *fr_statetstats __P((void)); -static int fr_delstate __P((ipstate_t *, int)); -static int fr_state_remove __P((caddr_t)); -static void fr_ipsmove __P((ipstate_t *, u_int)); -static int fr_tcpstate __P((fr_info_t *, tcphdr_t *, ipstate_t *)); -static int fr_tcpoptions __P((fr_info_t *, tcphdr_t *, tcpdata_t *)); -static ipstate_t *fr_stclone __P((fr_info_t *, tcphdr_t *, ipstate_t *)); -static void fr_fixinisn __P((fr_info_t *, ipstate_t *)); -static void fr_fixoutisn __P((fr_info_t *, ipstate_t *)); -static void fr_checknewisn __P((fr_info_t *, ipstate_t *)); -static int fr_stateiter __P((ipftoken_t *, ipfgeniter_t *)); -static int fr_stgettable __P((char *)); +static ipstate_t *ipf_checkicmpmatchingstate __P((fr_info_t *)); +static int ipf_state_flush_entry __P((ipf_main_softc_t *, void *)); +static ips_stat_t *ipf_state_stats __P((ipf_main_softc_t *)); +static int ipf_state_del __P((ipf_main_softc_t *, ipstate_t *, int)); +static int ipf_state_remove __P((ipf_main_softc_t *, caddr_t)); +static int ipf_state_match __P((ipstate_t *is1, ipstate_t *is2)); +static int ipf_state_matchaddresses __P((ipstate_t *is1, ipstate_t *is2)); +static int ipf_state_matchipv4addrs __P((ipstate_t *is1, ipstate_t *is2)); +static int ipf_state_matchipv6addrs __P((ipstate_t *is1, ipstate_t *is2)); +static int ipf_state_matchisps __P((ipstate_t *is1, ipstate_t *is2)); +static int ipf_state_matchports __P((udpinfo_t *is1, udpinfo_t *is2)); +static int ipf_state_matcharray __P((ipstate_t *, int *, u_long)); +static void ipf_ipsmove __P((ipf_state_softc_t *, ipstate_t *, u_int)); +static int ipf_state_tcp __P((ipf_main_softc_t *, ipf_state_softc_t *, + fr_info_t *, tcphdr_t *, ipstate_t *)); +static int ipf_tcpoptions __P((ipf_state_softc_t *, fr_info_t *, + tcphdr_t *, tcpdata_t *)); +static ipstate_t *ipf_state_clone __P((fr_info_t *, tcphdr_t *, ipstate_t *)); +static void ipf_fixinisn __P((fr_info_t *, ipstate_t *)); +static void ipf_fixoutisn __P((fr_info_t *, ipstate_t *)); +static void ipf_checknewisn __P((fr_info_t *, ipstate_t *)); +static int ipf_state_iter __P((ipf_main_softc_t *, ipftoken_t *, + ipfgeniter_t *, ipfobj_t *)); +static int ipf_state_gettable __P((ipf_main_softc_t *, ipf_state_softc_t *, + char *)); +static int ipf_state_tcpinwindow __P((struct fr_info *, struct tcpdata *, + struct tcpdata *, tcphdr_t *, int)); -int fr_stputent __P((caddr_t)); -int fr_stgetent __P((caddr_t)); +static int ipf_state_getent __P((ipf_main_softc_t *, ipf_state_softc_t *, + caddr_t)); +static int ipf_state_putent __P((ipf_main_softc_t *, ipf_state_softc_t *, + caddr_t)); #define ONE_DAY IPF_TTLVAL(1 * 86400) /* 1 day */ #define FIVE_DAYS (5 * ONE_DAY) -#define DOUBLE_HASH(x) (((x) + ips_seed[(x) % fr_statesize]) % fr_statesize) - -u_long fr_tcpidletimeout = FIVE_DAYS, - fr_tcpclosewait = IPF_TTLVAL(2 * TCP_MSL), - fr_tcplastack = IPF_TTLVAL(30), - fr_tcptimeout = IPF_TTLVAL(2 * TCP_MSL), - fr_tcptimewait = IPF_TTLVAL(2 * TCP_MSL), - fr_tcpclosed = IPF_TTLVAL(30), - fr_tcphalfclosed = IPF_TTLVAL(2 * 3600), /* 2 hours */ - fr_udptimeout = IPF_TTLVAL(120), - fr_udpacktimeout = IPF_TTLVAL(12), - fr_icmptimeout = IPF_TTLVAL(60), - fr_icmpacktimeout = IPF_TTLVAL(6), - fr_iptimeout = IPF_TTLVAL(60); -int fr_statemax = IPSTATE_MAX, - fr_statesize = IPSTATE_SIZE; -int fr_state_doflush = 0, - fr_state_lock = 0, - fr_state_maxbucket = 0, - fr_state_maxbucket_reset = 1, - fr_state_init = 0; -ipftq_t ips_tqtqb[IPF_TCP_NSTATES], - ips_udptq, - ips_udpacktq, - ips_iptq, - ips_icmptq, - ips_icmpacktq, - ips_deletetq, - *ips_utqe = NULL; -#ifdef IPFILTER_LOG -int ipstate_logging = 1; -#else -int ipstate_logging = 0; -#endif -ipstate_t *ips_list = NULL; +#define DOUBLE_HASH(x) (((x) + softs->ipf_state_seed[(x) % \ + softs->ipf_state_size]) % softs->ipf_state_size) /* ------------------------------------------------------------------------ */ -/* Function: fr_stateinit */ +/* Function: ipf_state_main_load */ /* Returns: int - 0 == success, -1 == failure */ /* Parameters: Nil */ /* */ -/* Initialise all the global variables used within the state code. */ -/* This action also includes initiailising locks. */ +/* A null-op function that exists as a placeholder so that the flow in */ +/* other functions is obvious. */ /* ------------------------------------------------------------------------ */ -int fr_stateinit() +int +ipf_state_main_load() { -#if defined(NEED_LOCAL_RAND) || !defined(_KERNEL) - struct timeval tv; -#endif - int i; - - KMALLOCS(ips_table, ipstate_t **, fr_statesize * sizeof(ipstate_t *)); - if (ips_table == NULL) - return -1; - bzero((char *)ips_table, fr_statesize * sizeof(ipstate_t *)); - - KMALLOCS(ips_seed, u_long *, fr_statesize * sizeof(*ips_seed)); - if (ips_seed == NULL) - return -2; -#if defined(NEED_LOCAL_RAND) || !defined(_KERNEL) - tv.tv_sec = 0; - GETKTIME(&tv); -#endif - for (i = 0; i < fr_statesize; i++) { - /* - * XXX - ips_seed[X] should be a random number of sorts. - */ -#if !defined(NEED_LOCAL_RAND) && defined(_KERNEL) - ips_seed[i] = arc4random(); -#else - ips_seed[i] = ((u_long)ips_seed + i) * fr_statesize; - ips_seed[i] += tv.tv_sec; - ips_seed[i] *= (u_long)ips_seed; - ips_seed[i] ^= 0x5a5aa5a5; - ips_seed[i] *= fr_statemax; -#endif - } -#if defined(NEED_LOCAL_RAND) && defined(_KERNEL) - ipf_rand_push(ips_seed, fr_statesize * sizeof(*ips_seed)); -#endif - - /* fill icmp reply type table */ - for (i = 0; i <= ICMP_MAXTYPE; i++) - icmpreplytype4[i] = -1; - icmpreplytype4[ICMP_ECHO] = ICMP_ECHOREPLY; - icmpreplytype4[ICMP_TSTAMP] = ICMP_TSTAMPREPLY; - icmpreplytype4[ICMP_IREQ] = ICMP_IREQREPLY; - icmpreplytype4[ICMP_MASKREQ] = ICMP_MASKREPLY; -#ifdef USE_INET6 - /* fill icmp reply type table */ - for (i = 0; i <= ICMP6_MAXTYPE; i++) - icmpreplytype6[i] = -1; - icmpreplytype6[ICMP6_ECHO_REQUEST] = ICMP6_ECHO_REPLY; - icmpreplytype6[ICMP6_MEMBERSHIP_QUERY] = ICMP6_MEMBERSHIP_REPORT; - icmpreplytype6[ICMP6_NI_QUERY] = ICMP6_NI_REPLY; - icmpreplytype6[ND_ROUTER_SOLICIT] = ND_ROUTER_ADVERT; - icmpreplytype6[ND_NEIGHBOR_SOLICIT] = ND_NEIGHBOR_ADVERT; -#endif - - KMALLOCS(ips_stats.iss_bucketlen, u_long *, - fr_statesize * sizeof(u_long)); - if (ips_stats.iss_bucketlen == NULL) - return -1; - bzero((char *)ips_stats.iss_bucketlen, fr_statesize * sizeof(u_long)); - - if (fr_state_maxbucket == 0) { - for (i = fr_statesize; i > 0; i >>= 1) - fr_state_maxbucket++; - fr_state_maxbucket *= 2; - } - - ips_stats.iss_tcptab = ips_tqtqb; - fr_sttab_init(ips_tqtqb); - ips_tqtqb[IPF_TCP_NSTATES - 1].ifq_next = &ips_udptq; - ips_udptq.ifq_ttl = (u_long)fr_udptimeout; - ips_udptq.ifq_ref = 1; - ips_udptq.ifq_head = NULL; - ips_udptq.ifq_tail = &ips_udptq.ifq_head; - MUTEX_INIT(&ips_udptq.ifq_lock, "ipftq udp tab"); - ips_udptq.ifq_next = &ips_udpacktq; - ips_udpacktq.ifq_ttl = (u_long)fr_udpacktimeout; - ips_udpacktq.ifq_ref = 1; - ips_udpacktq.ifq_head = NULL; - ips_udpacktq.ifq_tail = &ips_udpacktq.ifq_head; - MUTEX_INIT(&ips_udpacktq.ifq_lock, "ipftq udpack tab"); - ips_udpacktq.ifq_next = &ips_icmptq; - ips_icmptq.ifq_ttl = (u_long)fr_icmptimeout; - ips_icmptq.ifq_ref = 1; - ips_icmptq.ifq_head = NULL; - ips_icmptq.ifq_tail = &ips_icmptq.ifq_head; - MUTEX_INIT(&ips_icmptq.ifq_lock, "ipftq icmp tab"); - ips_icmptq.ifq_next = &ips_icmpacktq; - ips_icmpacktq.ifq_ttl = (u_long)fr_icmpacktimeout; - ips_icmpacktq.ifq_ref = 1; - ips_icmpacktq.ifq_head = NULL; - ips_icmpacktq.ifq_tail = &ips_icmpacktq.ifq_head; - MUTEX_INIT(&ips_icmpacktq.ifq_lock, "ipftq icmpack tab"); - ips_icmpacktq.ifq_next = &ips_iptq; - ips_iptq.ifq_ttl = (u_long)fr_iptimeout; - ips_iptq.ifq_ref = 1; - ips_iptq.ifq_head = NULL; - ips_iptq.ifq_tail = &ips_iptq.ifq_head; - MUTEX_INIT(&ips_iptq.ifq_lock, "ipftq ip tab"); - ips_iptq.ifq_next = &ips_deletetq; - ips_deletetq.ifq_ttl = (u_long)1; - ips_deletetq.ifq_ref = 1; - ips_deletetq.ifq_head = NULL; - ips_deletetq.ifq_tail = &ips_deletetq.ifq_head; - MUTEX_INIT(&ips_deletetq.ifq_lock, "state delete queue"); - ips_deletetq.ifq_next = NULL; - - RWLOCK_INIT(&ipf_state, "ipf IP state rwlock"); - MUTEX_INIT(&ipf_stinsert, "ipf state insert mutex"); - fr_state_init = 1; - - ips_last_force_flush = fr_ticks; return 0; } /* ------------------------------------------------------------------------ */ -/* Function: fr_stateunload */ -/* Returns: Nil */ +/* Function: ipf_state_main_unload */ +/* Returns: int - 0 == success, -1 == failure */ /* Parameters: Nil */ /* */ +/* A null-op function that exists as a placeholder so that the flow in */ +/* other functions is obvious. */ +/* ------------------------------------------------------------------------ */ +int +ipf_state_main_unload() +{ + return 0; +} + + +/* ------------------------------------------------------------------------ */ +/* Function: ipf_state_soft_create */ +/* Returns: void * - NULL = failure, else pointer to soft context */ +/* Parameters: softc(I) - pointer to soft context main structure */ +/* */ +/* Create a new state soft context structure and populate it with the list */ +/* of tunables and other default settings. */ +/* ------------------------------------------------------------------------ */ +void * +ipf_state_soft_create(softc) + ipf_main_softc_t *softc; +{ + ipf_state_softc_t *softs; + + KMALLOC(softs, ipf_state_softc_t *); + if (softs == NULL) + return NULL; + + bzero((char *)softs, sizeof(*softs)); + + softs->ipf_state_tune = ipf_tune_array_copy(softs, + sizeof(ipf_state_tuneables), + ipf_state_tuneables); + if (softs->ipf_state_tune == NULL) { + ipf_state_soft_destroy(softc, softs); + return NULL; + } + if (ipf_tune_array_link(softc, softs->ipf_state_tune) == -1) { + ipf_state_soft_destroy(softc, softs); + return NULL; + } + +#ifdef IPFILTER_LOG + softs->ipf_state_logging = 1; +#else + softs->ipf_state_logging = 0; +#endif + softs->ipf_state_size = IPSTATE_SIZE, + softs->ipf_state_maxbucket = 0; + softs->ipf_state_wm_freq = IPF_TTLVAL(10); + softs->ipf_state_max = IPSTATE_MAX; + softs->ipf_state_wm_last = 0; + softs->ipf_state_wm_high = 99; + softs->ipf_state_wm_low = 90; + softs->ipf_state_inited = 0; + softs->ipf_state_lock = 0; + softs->ipf_state_doflush = 0; + + return softs; +} + + +/* ------------------------------------------------------------------------ */ +/* Function: ipf_state_soft_destroy */ +/* Returns: Nil */ +/* Parameters: softc(I) - pointer to soft context main structure */ +/* arg(I) - pointer to local context to use */ +/* */ +/* Undo only what we did in soft create: unlink and free the tunables and */ +/* free the soft context structure itself. */ +/* ------------------------------------------------------------------------ */ +void +ipf_state_soft_destroy(softc, arg) + ipf_main_softc_t *softc; + void *arg; +{ + ipf_state_softc_t *softs = arg; + + if (softs->ipf_state_tune != NULL) { + ipf_tune_array_unlink(softc, softs->ipf_state_tune); + KFREES(softs->ipf_state_tune, sizeof(ipf_state_tuneables)); + softs->ipf_state_tune = NULL; + } + + KFREE(softs); +} + + +/* ------------------------------------------------------------------------ */ +/* Function: ipf_state_soft_init */ +/* Returns: int - 0 == success, -1 == failure */ +/* Parameters: softc(I) - pointer to soft context main structure */ +/* arg(I) - pointer to local context to use */ +/* */ +/* Initialise the state soft context structure so it is ready for use. */ +/* This involves: */ +/* - allocating a hash table and zero'ing it out */ +/* - building a secondary table of seeds for double hashing to make it more */ +/* difficult to attempt to attack the hash table itself (for DoS) */ +/* - initialise all of the timeout queues, including a table for TCP, some */ +/* pairs of query/response for UDP and other IP protocols (typically the */ +/* reply queue has a shorter timeout than the query) */ +/* ------------------------------------------------------------------------ */ +int +ipf_state_soft_init(softc, arg) + ipf_main_softc_t *softc; + void *arg; +{ + ipf_state_softc_t *softs = arg; + int i; + + KMALLOCS(softs->ipf_state_table, + ipstate_t **, softs->ipf_state_size * sizeof(ipstate_t *)); + if (softs->ipf_state_table == NULL) + return -1; + + bzero((char *)softs->ipf_state_table, + softs->ipf_state_size * sizeof(ipstate_t *)); + + KMALLOCS(softs->ipf_state_seed, u_long *, + softs->ipf_state_size * sizeof(*softs->ipf_state_seed)); + if (softs->ipf_state_seed == NULL) + return -2; + + for (i = 0; i < softs->ipf_state_size; i++) { + /* + * XXX - ipf_state_seed[X] should be a random number of sorts. + */ +#if FREEBSD_GE_REV(400000) + softs->ipf_state_seed[i] = arc4random(); +#else + softs->ipf_state_seed[i] = ((u_long)softs->ipf_state_seed + i) * + softs->ipf_state_size; + softs->ipf_state_seed[i] ^= 0xa5a55a5a; + softs->ipf_state_seed[i] *= (u_long)softs->ipf_state_seed; + softs->ipf_state_seed[i] ^= 0x5a5aa5a5; + softs->ipf_state_seed[i] *= softs->ipf_state_max; +#endif + } + + KMALLOCS(softs->ipf_state_stats.iss_bucketlen, u_int *, + softs->ipf_state_size * sizeof(u_int)); + if (softs->ipf_state_stats.iss_bucketlen == NULL) + return -3; + + bzero((char *)softs->ipf_state_stats.iss_bucketlen, + softs->ipf_state_size * sizeof(u_int)); + + if (softs->ipf_state_maxbucket == 0) { + for (i = softs->ipf_state_size; i > 0; i >>= 1) + softs->ipf_state_maxbucket++; + softs->ipf_state_maxbucket *= 2; + } + + ipf_sttab_init(softc, softs->ipf_state_tcptq); + softs->ipf_state_stats.iss_tcptab = softs->ipf_state_tcptq; + softs->ipf_state_tcptq[IPF_TCP_NSTATES - 1].ifq_next = + &softs->ipf_state_udptq; + + IPFTQ_INIT(&softs->ipf_state_udptq, softc->ipf_udptimeout, + "ipftq udp tab"); + softs->ipf_state_udptq.ifq_next = &softs->ipf_state_udpacktq; + + IPFTQ_INIT(&softs->ipf_state_udpacktq, softc->ipf_udpacktimeout, + "ipftq udpack tab"); + softs->ipf_state_udpacktq.ifq_next = &softs->ipf_state_icmptq; + + IPFTQ_INIT(&softs->ipf_state_icmptq, softc->ipf_icmptimeout, + "ipftq icmp tab"); + softs->ipf_state_icmptq.ifq_next = &softs->ipf_state_icmpacktq; + + IPFTQ_INIT(&softs->ipf_state_icmpacktq, softc->ipf_icmpacktimeout, + "ipftq icmpack tab"); + softs->ipf_state_icmpacktq.ifq_next = &softs->ipf_state_iptq; + + IPFTQ_INIT(&softs->ipf_state_iptq, softc->ipf_iptimeout, + "ipftq iptimeout tab"); + softs->ipf_state_iptq.ifq_next = &softs->ipf_state_pending; + + IPFTQ_INIT(&softs->ipf_state_pending, IPF_HZ_DIVIDE, "ipftq pending"); + softs->ipf_state_pending.ifq_next = &softs->ipf_state_deletetq; + + IPFTQ_INIT(&softs->ipf_state_deletetq, 1, "ipftq delete"); + softs->ipf_state_deletetq.ifq_next = NULL; + + MUTEX_INIT(&softs->ipf_stinsert, "ipf state insert mutex"); + + + softs->ipf_state_wm_last = softc->ipf_ticks; + softs->ipf_state_inited = 1; + + return 0; +} + + +/* ------------------------------------------------------------------------ */ +/* Function: ipf_state_soft_fini */ +/* Returns: int - 0 = success, -1 = failure */ +/* Parameters: softc(I) - pointer to soft context main structure */ +/* arg(I) - pointer to local context to use */ +/* */ /* Release and destroy any resources acquired or initialised so that */ /* IPFilter can be unloaded or re-initialised. */ /* ------------------------------------------------------------------------ */ -void fr_stateunload() +int +ipf_state_soft_fini(softc, arg) + ipf_main_softc_t *softc; + void *arg; { + ipf_state_softc_t *softs = arg; ipftq_t *ifq, *ifqnext; ipstate_t *is; - while ((is = ips_list) != NULL) - fr_delstate(is, ISL_UNLOAD); + while ((is = softs->ipf_state_list) != NULL) + ipf_state_del(softc, is, ISL_UNLOAD); /* * Proxy timeout queues are not cleaned here because although they - * exist on the state list, appr_unload is called after fr_stateunload - * and the proxies actually are responsible for them being created. - * Should the proxy timeouts have their own list? There's no real - * justification as this is the only complicationA + * exist on the state list, appr_unload is called after + * ipf_state_unload and the proxies actually are responsible for them + * being created. Should the proxy timeouts have their own list? + * There's no real justification as this is the only complication. */ - for (ifq = ips_utqe; ifq != NULL; ifq = ifqnext) { + for (ifq = softs->ipf_state_usertq; ifq != NULL; ifq = ifqnext) { ifqnext = ifq->ifq_next; - if (((ifq->ifq_flags & IFQF_PROXY) == 0) && - (fr_deletetimeoutqueue(ifq) == 0)) - fr_freetimeoutqueue(ifq); + + if (ipf_deletetimeoutqueue(ifq) == 0) + ipf_freetimeoutqueue(softc, ifq); } - ips_stats.iss_inuse = 0; - ips_num = 0; + softs->ipf_state_stats.iss_inuse = 0; + softs->ipf_state_stats.iss_active = 0; - if (fr_state_init == 1) { - fr_sttab_destroy(ips_tqtqb); - MUTEX_DESTROY(&ips_udptq.ifq_lock); - MUTEX_DESTROY(&ips_icmptq.ifq_lock); - MUTEX_DESTROY(&ips_udpacktq.ifq_lock); - MUTEX_DESTROY(&ips_icmpacktq.ifq_lock); - MUTEX_DESTROY(&ips_iptq.ifq_lock); - MUTEX_DESTROY(&ips_deletetq.ifq_lock); + if (softs->ipf_state_inited == 1) { + softs->ipf_state_inited = 0; + ipf_sttab_destroy(softs->ipf_state_tcptq); + MUTEX_DESTROY(&softs->ipf_state_udptq.ifq_lock); + MUTEX_DESTROY(&softs->ipf_state_icmptq.ifq_lock); + MUTEX_DESTROY(&softs->ipf_state_udpacktq.ifq_lock); + MUTEX_DESTROY(&softs->ipf_state_icmpacktq.ifq_lock); + MUTEX_DESTROY(&softs->ipf_state_iptq.ifq_lock); + MUTEX_DESTROY(&softs->ipf_state_deletetq.ifq_lock); + MUTEX_DESTROY(&softs->ipf_state_pending.ifq_lock); + MUTEX_DESTROY(&softs->ipf_stinsert); } - if (ips_table != NULL) { - KFREES(ips_table, fr_statesize * sizeof(*ips_table)); - ips_table = NULL; + if (softs->ipf_state_table != NULL) { + KFREES(softs->ipf_state_table, + softs->ipf_state_size * sizeof(*softs->ipf_state_table)); + softs->ipf_state_table = NULL; } - if (ips_seed != NULL) { - KFREES(ips_seed, fr_statesize * sizeof(*ips_seed)); - ips_seed = NULL; + if (softs->ipf_state_seed != NULL) { + KFREES(softs->ipf_state_seed, + softs->ipf_state_size * sizeof(*softs->ipf_state_seed)); + softs->ipf_state_seed = NULL; } - if (ips_stats.iss_bucketlen != NULL) { - KFREES(ips_stats.iss_bucketlen, fr_statesize * sizeof(u_long)); - ips_stats.iss_bucketlen = NULL; + if (softs->ipf_state_stats.iss_bucketlen != NULL) { + KFREES(softs->ipf_state_stats.iss_bucketlen, + softs->ipf_state_size * sizeof(u_int)); + softs->ipf_state_stats.iss_bucketlen = NULL; } - if (fr_state_maxbucket_reset == 1) - fr_state_maxbucket = 0; - - if (fr_state_init == 1) { - fr_state_init = 0; - RW_DESTROY(&ipf_state); - MUTEX_DESTROY(&ipf_stinsert); - } + return 0; } /* ------------------------------------------------------------------------ */ -/* Function: fr_statetstats */ +/* Function: ipf_state_set_lock */ +/* Returns: Nil */ +/* Parameters: arg(I) - pointer to local context to use */ +/* tmp(I) - new value for lock */ +/* */ +/* Stub function that allows for external manipulation of ipf_state_lock */ +/* ------------------------------------------------------------------------ */ +void +ipf_state_setlock(arg, tmp) + void *arg; + int tmp; +{ + ipf_state_softc_t *softs = arg; + + softs->ipf_state_lock = tmp; +} + + +/* ------------------------------------------------------------------------ */ +/* Function: ipf_state_stats */ /* Returns: ips_state_t* - pointer to state stats structure */ -/* Parameters: Nil */ +/* Parameters: softc(I) - pointer to soft context main structure */ /* */ /* Put all the current numbers and pointers into a single struct and return */ /* a pointer to it. */ /* ------------------------------------------------------------------------ */ -static ips_stat_t *fr_statetstats() +static ips_stat_t * +ipf_state_stats(softc) + ipf_main_softc_t *softc; { - ips_stats.iss_active = ips_num; - ips_stats.iss_statesize = fr_statesize; - ips_stats.iss_statemax = fr_statemax; - ips_stats.iss_table = ips_table; - ips_stats.iss_list = ips_list; - ips_stats.iss_ticks = fr_ticks; - return &ips_stats; + ipf_state_softc_t *softs = softc->ipf_state_soft; + ips_stat_t *issp = &softs->ipf_state_stats; + + issp->iss_state_size = softs->ipf_state_size; + issp->iss_state_max = softs->ipf_state_max; + issp->iss_table = softs->ipf_state_table; + issp->iss_list = softs->ipf_state_list; + issp->iss_ticks = softc->ipf_ticks; + +#ifdef IPFILTER_LOGGING + issp->iss_log_ok = ipf_log_logok(softc, IPF_LOGSTATE); + issp->iss_log_fail = ipf_log_failures(softc, IPF_LOGSTATE); +#else + issp->iss_log_ok = 0; + issp->iss_log_fail = 0; +#endif + return issp; } /* ------------------------------------------------------------------------ */ -/* Function: fr_state_remove */ +/* Function: ipf_state_remove */ /* Returns: int - 0 == success, != 0 == failure */ -/* Parameters: data(I) - pointer to state structure to delete from table */ +/* Parameters: softc(I) - pointer to soft context main structure */ +/* data(I) - pointer to state structure to delete from table */ /* */ /* Search for a state structure that matches the one passed, according to */ /* the IP addresses and other protocol specific information. */ /* ------------------------------------------------------------------------ */ -static int fr_state_remove(data) -caddr_t data; +static int +ipf_state_remove(softc, data) + ipf_main_softc_t *softc; + caddr_t data; { + ipf_state_softc_t *softs = softc->ipf_state_soft; ipstate_t *sp, st; int error; sp = &st; - error = fr_inobj(data, &st, IPFOBJ_IPSTATE); + error = ipf_inobj(softc, data, NULL, &st, IPFOBJ_IPSTATE); if (error) return EFAULT; - WRITE_ENTER(&ipf_state); - for (sp = ips_list; sp; sp = sp->is_next) + WRITE_ENTER(&softc->ipf_state); + for (sp = softs->ipf_state_list; sp; sp = sp->is_next) if ((sp->is_p == st.is_p) && (sp->is_v == st.is_v) && !bcmp((caddr_t)&sp->is_src, (caddr_t)&st.is_src, sizeof(st.is_src)) && - !bcmp((caddr_t)&sp->is_dst, (caddr_t)&st.is_src, + !bcmp((caddr_t)&sp->is_dst, (caddr_t)&st.is_dst, sizeof(st.is_dst)) && !bcmp((caddr_t)&sp->is_ps, (caddr_t)&st.is_ps, sizeof(st.is_ps))) { - fr_delstate(sp, ISL_REMOVE); - RWLOCK_EXIT(&ipf_state); + ipf_state_del(softc, sp, ISL_REMOVE); + RWLOCK_EXIT(&softc->ipf_state); return 0; } - RWLOCK_EXIT(&ipf_state); + RWLOCK_EXIT(&softc->ipf_state); + + IPFERROR(100001); return ESRCH; } /* ------------------------------------------------------------------------ */ -/* Function: fr_state_ioctl */ +/* Function: ipf_state_ioctl */ /* Returns: int - 0 == success, != 0 == failure */ -/* Parameters: data(I) - pointer to ioctl data */ -/* cmd(I) - ioctl command integer */ -/* mode(I) - file mode bits used with open */ +/* Parameters: softc(I) - pointer to soft context main structure */ +/* data(I) - pointer to ioctl data */ +/* cmd(I) - ioctl command integer */ +/* mode(I) - file mode bits used with open */ +/* uid(I) - uid of process making the ioctl call */ +/* ctx(I) - pointer specific to context of the call */ /* */ /* Processes an ioctl call made to operate on the IP Filter state device. */ /* ------------------------------------------------------------------------ */ -int fr_state_ioctl(data, cmd, mode, uid, ctx) -caddr_t data; -ioctlcmd_t cmd; -int mode, uid; -void *ctx; +int +ipf_state_ioctl(softc, data, cmd, mode, uid, ctx) + ipf_main_softc_t *softc; + caddr_t data; + ioctlcmd_t cmd; + int mode, uid; + void *ctx; { + ipf_state_softc_t *softs = softc->ipf_state_soft; int arg, ret, error = 0; SPL_INT(s); @@ -458,55 +605,75 @@ void *ctx; * Delete an entry from the state table. */ case SIOCDELST : - error = fr_state_remove(data); + error = ipf_state_remove(softc, data); break; /* * Flush the state table */ case SIOCIPFFL : - error = BCOPYIN(data, (char *)&arg, sizeof(arg)); + error = BCOPYIN(data, &arg, sizeof(arg)); if (error != 0) { + IPFERROR(100002); error = EFAULT; + } else { - WRITE_ENTER(&ipf_state); - ret = fr_state_flush(arg, 4); - RWLOCK_EXIT(&ipf_state); - error = BCOPYOUT((char *)&ret, data, sizeof(ret)); - if (error != 0) + WRITE_ENTER(&softc->ipf_state); + ret = ipf_state_flush(softc, arg, 4); + RWLOCK_EXIT(&softc->ipf_state); + + error = BCOPYOUT(&ret, data, sizeof(ret)); + if (error != 0) { + IPFERROR(100003); error = EFAULT; + } } break; #ifdef USE_INET6 case SIOCIPFL6 : - error = BCOPYIN(data, (char *)&arg, sizeof(arg)); + error = BCOPYIN(data, &arg, sizeof(arg)); if (error != 0) { + IPFERROR(100004); error = EFAULT; + } else { - WRITE_ENTER(&ipf_state); - ret = fr_state_flush(arg, 6); - RWLOCK_EXIT(&ipf_state); - error = BCOPYOUT((char *)&ret, data, sizeof(ret)); - if (error != 0) + WRITE_ENTER(&softc->ipf_state); + ret = ipf_state_flush(softc, arg, 6); + RWLOCK_EXIT(&softc->ipf_state); + + error = BCOPYOUT(&ret, data, sizeof(ret)); + if (error != 0) { + IPFERROR(100005); error = EFAULT; + } } break; #endif + + case SIOCMATCHFLUSH : + WRITE_ENTER(&softc->ipf_state); + error = ipf_state_matchflush(softc, data); + RWLOCK_EXIT(&softc->ipf_state); + break; + #ifdef IPFILTER_LOG /* * Flush the state log. */ case SIOCIPFFB : - if (!(mode & FWRITE)) + if (!(mode & FWRITE)) { + IPFERROR(100008); error = EPERM; - else { + } else { int tmp; - tmp = ipflog_clear(IPL_LOGSTATE); - error = BCOPYOUT((char *)&tmp, data, sizeof(tmp)); - if (error != 0) + tmp = ipf_log_clear(softc, IPL_LOGSTATE); + error = BCOPYOUT(&tmp, data, sizeof(tmp)); + if (error != 0) { + IPFERROR(100009); error = EFAULT; + } } break; @@ -514,13 +681,16 @@ void *ctx; * Turn logging of state information on/off. */ case SIOCSETLG : - if (!(mode & FWRITE)) + if (!(mode & FWRITE)) { + IPFERROR(100010); error = EPERM; - else { - error = BCOPYIN((char *)data, (char *)&ipstate_logging, - sizeof(ipstate_logging)); - if (error != 0) + } else { + error = BCOPYIN(data, &softs->ipf_state_logging, + sizeof(softs->ipf_state_logging)); + if (error != 0) { + IPFERROR(100011); error = EFAULT; + } } break; @@ -528,20 +698,24 @@ void *ctx; * Return the current state of logging. */ case SIOCGETLG : - error = BCOPYOUT((char *)&ipstate_logging, (char *)data, - sizeof(ipstate_logging)); - if (error != 0) + error = BCOPYOUT(&softs->ipf_state_logging, data, + sizeof(softs->ipf_state_logging)); + if (error != 0) { + IPFERROR(100012); error = EFAULT; + } break; /* * Return the number of bytes currently waiting to be read. */ case FIONREAD : - arg = iplused[IPL_LOGSTATE]; /* returned in an int */ - error = BCOPYOUT((char *)&arg, data, sizeof(arg)); - if (error != 0) + arg = ipf_log_bytesused(softc, IPL_LOGSTATE); + error = BCOPYOUT(&arg, data, sizeof(arg)); + if (error != 0) { + IPFERROR(100013); error = EFAULT; + } break; #endif @@ -549,7 +723,8 @@ void *ctx; * Get the current state statistics. */ case SIOCGETFS : - error = fr_outobj(data, fr_statetstats(), IPFOBJ_STATESTAT); + error = ipf_outobj(softc, data, ipf_state_stats(softc), + IPFOBJ_STATESTAT); break; /* @@ -558,9 +733,10 @@ void *ctx; */ case SIOCSTLCK : if (!(mode & FWRITE)) { + IPFERROR(100014); error = EPERM; } else { - error = fr_lock(data, &fr_state_lock); + error = ipf_lock(data, &softs->ipf_state_lock); } break; @@ -568,74 +744,86 @@ void *ctx; * Add an entry to the current state table. */ case SIOCSTPUT : - if (!fr_state_lock || !(mode &FWRITE)) { + if (!softs->ipf_state_lock || !(mode &FWRITE)) { + IPFERROR(100015); error = EACCES; break; } - error = fr_stputent(data); + error = ipf_state_putent(softc, softs, data); break; /* * Get a state table entry. */ case SIOCSTGET : - if (!fr_state_lock) { + if (!softs->ipf_state_lock) { + IPFERROR(100016); error = EACCES; break; } - error = fr_stgetent(data); + error = ipf_state_getent(softc, softs, data); break; /* * Return a copy of the hash table bucket lengths */ case SIOCSTAT1 : - error = BCOPYOUT(ips_stats.iss_bucketlen, data, - fr_statesize * sizeof(u_long)); - if (error != 0) + error = BCOPYOUT(softs->ipf_state_stats.iss_bucketlen, data, + softs->ipf_state_size * sizeof(u_int)); + if (error != 0) { + IPFERROR(100017); error = EFAULT; + } break; case SIOCGENITER : { ipftoken_t *token; ipfgeniter_t iter; + ipfobj_t obj; - error = fr_inobj(data, &iter, IPFOBJ_GENITER); + error = ipf_inobj(softc, data, &obj, &iter, IPFOBJ_GENITER); if (error != 0) break; SPL_SCHED(s); - token = ipf_findtoken(IPFGENITER_STATE, uid, ctx); - if (token != NULL) - error = fr_stateiter(token, &iter); - else + token = ipf_token_find(softc, IPFGENITER_STATE, uid, ctx); + if (token != NULL) { + error = ipf_state_iter(softc, token, &iter, &obj); + WRITE_ENTER(&softc->ipf_tokens); + ipf_token_deref(softc, token); + RWLOCK_EXIT(&softc->ipf_tokens); + } else { + IPFERROR(100018); error = ESRCH; - RWLOCK_EXIT(&ipf_tokens); + } SPL_X(s); break; } case SIOCGTABL : - error = fr_stgettable(data); + error = ipf_state_gettable(softc, softs, data); break; case SIOCIPFDELTOK : - error = BCOPYIN(data, (char *)&arg, sizeof(arg)); + error = BCOPYIN(data, &arg, sizeof(arg)); if (error != 0) { + IPFERROR(100019); error = EFAULT; } else { SPL_SCHED(s); - error = ipf_deltoken(arg, uid, ctx); + error = ipf_token_del(softc, arg, uid, ctx); SPL_X(s); } break; case SIOCGTQTAB : - error = fr_outobj(data, ips_tqtqb, IPFOBJ_STATETQTAB); + error = ipf_outobj(softc, data, softs->ipf_state_tcptq, + IPFOBJ_STATETQTAB); break; default : + IPFERROR(100020); error = EINVAL; break; } @@ -644,9 +832,11 @@ void *ctx; /* ------------------------------------------------------------------------ */ -/* Function: fr_stgetent */ +/* Function: ipf_state_getent */ /* Returns: int - 0 == success, != 0 == failure */ -/* Parameters: data(I) - pointer to state structure to retrieve from table */ +/* Parameters: softc(I) - pointer to soft context main structure */ +/* softs(I) - pointer to state context structure */ +/* data(I) - pointer to state structure to retrieve from table*/ /* */ /* Copy out state information from the kernel to a user space process. If */ /* there is a filter rule associated with the state entry, copy that out */ @@ -654,25 +844,30 @@ void *ctx; /* the struct passed in and if not null and not found in the list of current*/ /* state entries, the retrieval fails. */ /* ------------------------------------------------------------------------ */ -int fr_stgetent(data) -caddr_t data; +static int +ipf_state_getent(softc, softs, data) + ipf_main_softc_t *softc; + ipf_state_softc_t *softs; + caddr_t data; { ipstate_t *is, *isn; ipstate_save_t ips; int error; - error = fr_inobj(data, &ips, IPFOBJ_STATESAVE); - if (error != 0) - return error; + error = ipf_inobj(softc, data, NULL, &ips, IPFOBJ_STATESAVE); + if (error) + return EFAULT; - READ_ENTER(&ipf_state); + READ_ENTER(&softc->ipf_state); isn = ips.ips_next; if (isn == NULL) { - isn = ips_list; + isn = softs->ipf_state_list; if (isn == NULL) { - RWLOCK_EXIT(&ipf_state); - if (ips.ips_next == NULL) + if (ips.ips_next == NULL) { + RWLOCK_EXIT(&softc->ipf_state); + IPFERROR(100021); return ENOENT; + } return 0; } } else { @@ -681,11 +876,12 @@ caddr_t data; * current list of entries. Security precaution to prevent * copying of random kernel data. */ - for (is = ips_list; is; is = is->is_next) + for (is = softs->ipf_state_list; is; is = is->is_next) if (is == isn) break; - if (is == NULL) { - RWLOCK_EXIT(&ipf_state); + if (!is) { + RWLOCK_EXIT(&softc->ipf_state); + IPFERROR(100022); return ESRCH; } } @@ -695,24 +891,29 @@ caddr_t data; if (isn->is_rule != NULL) bcopy((char *)isn->is_rule, (char *)&ips.ips_fr, sizeof(ips.ips_fr)); - RWLOCK_EXIT(&ipf_state); - error = fr_outobj(data, &ips, IPFOBJ_STATESAVE); + RWLOCK_EXIT(&softc->ipf_state); + error = ipf_outobj(softc, data, &ips, IPFOBJ_STATESAVE); return error; } /* ------------------------------------------------------------------------ */ -/* Function: fr_stputent */ +/* Function: ipf_state_putent */ /* Returns: int - 0 == success, != 0 == failure */ -/* Parameters: data(I) - pointer to state information struct */ +/* Parameters: softc(I) - pointer to soft context main structure */ +/* softs(I) - pointer to state context structure */ +/* data(I) - pointer to state information struct */ /* */ /* This function implements the SIOCSTPUT ioctl: insert a state entry into */ /* the state table. If the state info. includes a pointer to a filter rule */ /* then also add in an orphaned rule (will not show up in any "ipfstat -io" */ /* output. */ /* ------------------------------------------------------------------------ */ -int fr_stputent(data) -caddr_t data; +int +ipf_state_putent(softc, softs, data) + ipf_main_softc_t *softc; + ipf_state_softc_t *softs; + caddr_t data; { ipstate_t *is, *isn; ipstate_save_t ips; @@ -720,13 +921,15 @@ caddr_t data; frentry_t *fr; char *name; - error = fr_inobj(data, &ips, IPFOBJ_STATESAVE); - if (error) - return EFAULT; + error = ipf_inobj(softc, data, NULL, &ips, IPFOBJ_STATESAVE); + if (error != 0) + return error; KMALLOC(isn, ipstate_t *); - if (isn == NULL) + if (isn == NULL) { + IPFERROR(100023); return ENOMEM; + } bcopy((char *)&ips.ips_is, (char *)isn, sizeof(*isn)); bzero((char *)isn, offsetof(struct ipstate, is_pkts)); @@ -742,17 +945,21 @@ caddr_t data; fr = ips.ips_rule; if (fr == NULL) { - READ_ENTER(&ipf_state); - fr_stinsert(isn, 0); + int inserr; + + READ_ENTER(&softc->ipf_state); + inserr = ipf_state_insert(softc, isn, 0); MUTEX_EXIT(&isn->is_lock); - RWLOCK_EXIT(&ipf_state); - return 0; + RWLOCK_EXIT(&softc->ipf_state); + + return inserr; } if (isn->is_flags & SI_NEWFR) { KMALLOC(fr, frentry_t *); if (fr == NULL) { KFREE(isn); + IPFERROR(100024); return ENOMEM; } bcopy((char *)&ips.ips_fr, (char *)fr, sizeof(*fr)); @@ -766,10 +973,19 @@ caddr_t data; * Look up all the interface names in the rule. */ for (i = 0; i < 4; i++) { - name = fr->fr_ifnames[i]; - fr->fr_ifas[i] = fr_resolvenic(name, fr->fr_v); + if (fr->fr_ifnames[i] == -1) { + fr->fr_ifas[i] = NULL; + continue; + } + name = fr->fr_names + fr->fr_ifnames[i]; + fr->fr_ifas[i] = ipf_resolvenic(softc, name, + fr->fr_family); + } + + for (i = 0; i < 4; i++) { name = isn->is_ifname[i]; - isn->is_ifp[i] = fr_resolvenic(name, isn->is_v); + isn->is_ifp[i] = ipf_resolvenic(softc, name, + isn->is_v); } fr->fr_ref = 0; @@ -777,31 +993,35 @@ caddr_t data; fr->fr_data = NULL; fr->fr_type = FR_T_NONE; - fr_resolvedest(&fr->fr_tifs[0], fr->fr_v); - fr_resolvedest(&fr->fr_tifs[1], fr->fr_v); - fr_resolvedest(&fr->fr_dif, fr->fr_v); + (void) ipf_resolvedest(softc, fr->fr_names, &fr->fr_tifs[0], + fr->fr_family); + (void) ipf_resolvedest(softc, fr->fr_names, &fr->fr_tifs[1], + fr->fr_family); + (void) ipf_resolvedest(softc, fr->fr_names, &fr->fr_dif, + fr->fr_family); /* * send a copy back to userland of what we ended up * to allow for verification. */ - error = fr_outobj(data, &ips, IPFOBJ_STATESAVE); - if (error) { + error = ipf_outobj(softc, data, &ips, IPFOBJ_STATESAVE); + if (error != 0) { KFREE(isn); MUTEX_DESTROY(&fr->fr_lock); KFREE(fr); + IPFERROR(100025); return EFAULT; } - READ_ENTER(&ipf_state); - fr_stinsert(isn, 0); + READ_ENTER(&softc->ipf_state); + error = ipf_state_insert(softc, isn, 0); MUTEX_EXIT(&isn->is_lock); - RWLOCK_EXIT(&ipf_state); + RWLOCK_EXIT(&softc->ipf_state); } else { - READ_ENTER(&ipf_state); - for (is = ips_list; is; is = is->is_next) + READ_ENTER(&softc->ipf_state); + for (is = softs->ipf_state_list; is; is = is->is_next) if (is->is_rule == fr) { - fr_stinsert(isn, 0); + error = ipf_state_insert(softc, isn, 0); MUTEX_EXIT(&isn->is_lock); break; } @@ -810,60 +1030,62 @@ caddr_t data; KFREE(isn); isn = NULL; } - RWLOCK_EXIT(&ipf_state); + RWLOCK_EXIT(&softc->ipf_state); - return (isn == NULL) ? ESRCH : 0; + if (isn == NULL) { + IPFERROR(100033); + error = ESRCH; + } } - return 0; + return error; } /* ------------------------------------------------------------------------ */ -/* Function: fr_stinsert */ -/* Returns: Nil */ -/* Parameters: is(I) - pointer to state structure */ -/* rev(I) - flag indicating forward/reverse direction of packet */ +/* Function: ipf_state_insert */ +/* Returns: int - 0 == success, -1 == failure */ +/* Parameters: softc(I) - pointer to soft context main structure */ +/* Parameters: is(I) - pointer to state structure */ +/* rev(I) - flag indicating direction of packet */ /* */ /* Inserts a state structure into the hash table (for lookups) and the list */ /* of state entries (for enumeration). Resolves all of the interface names */ /* to pointers and adjusts running stats for the hash table as appropriate. */ /* */ +/* This function can fail if the filter rule has had a population policy of */ +/* IP addresses used with stateful filteirng assigned to it. */ +/* */ /* Locking: it is assumed that some kind of lock on ipf_state is held. */ -/* Exits with is_lock initialised and held. */ +/* Exits with is_lock initialised and held - *EVEN IF ERROR*. */ /* ------------------------------------------------------------------------ */ -void fr_stinsert(is, rev) -ipstate_t *is; -int rev; +int +ipf_state_insert(softc, is, rev) + ipf_main_softc_t *softc; + ipstate_t *is; + int rev; { + ipf_state_softc_t *softs = softc->ipf_state_soft; frentry_t *fr; u_int hv; int i; - MUTEX_INIT(&is->is_lock, "ipf state entry"); - - fr = is->is_rule; - if (fr != NULL) { - MUTEX_ENTER(&fr->fr_lock); - fr->fr_ref++; - fr->fr_statecnt++; - MUTEX_EXIT(&fr->fr_lock); - } - /* * Look up all the interface names in the state entry. */ for (i = 0; i < 4; i++) { if (is->is_ifp[i] != NULL) continue; - is->is_ifp[i] = fr_resolvenic(is->is_ifname[i], is->is_v); + is->is_ifp[i] = ipf_resolvenic(softc, is->is_ifname[i], + is->is_v); } /* - * If we could trust is_hv, then the modulous would not be needed, but - * when running with IPFILTER_SYNC, this stops bad values. + * If we could trust is_hv, then the modulous would not be needed, + * but when running with IPFILTER_SYNC, this stops bad values. */ - hv = is->is_hv % fr_statesize; + hv = is->is_hv % softs->ipf_state_size; + /* TRACE is, hv */ is->is_hv = hv; /* @@ -871,37 +1093,265 @@ int rev; * possible that once the insert is complete another packet might * come along, match the entry and want to update it. */ + MUTEX_INIT(&is->is_lock, "ipf state entry"); MUTEX_ENTER(&is->is_lock); - MUTEX_ENTER(&ipf_stinsert); + MUTEX_ENTER(&softs->ipf_stinsert); + + fr = is->is_rule; + if (fr != NULL) { + if ((fr->fr_srctrack.ht_max_nodes != 0) && + (ipf_ht_node_add(softc, &fr->fr_srctrack, + is->is_family, &is->is_src) == -1)) { + SBUMPD(ipf_state_stats, iss_max_track); + MUTEX_EXIT(&softs->ipf_stinsert); + return -1; + } + + MUTEX_ENTER(&fr->fr_lock); + fr->fr_ref++; + MUTEX_EXIT(&fr->fr_lock); + fr->fr_statecnt++; + } + + if (is->is_flags & (SI_WILDP|SI_WILDA)) { + DT(iss_wild_plus_one); + SINCL(ipf_state_stats.iss_wild); + } + + SBUMP(ipf_state_stats.iss_proto[is->is_p]); + SBUMP(ipf_state_stats.iss_active_proto[is->is_p]); /* * add into list table. */ - if (ips_list != NULL) - ips_list->is_pnext = &is->is_next; - is->is_pnext = &ips_list; - is->is_next = ips_list; - ips_list = is; + if (softs->ipf_state_list != NULL) + softs->ipf_state_list->is_pnext = &is->is_next; + is->is_pnext = &softs->ipf_state_list; + is->is_next = softs->ipf_state_list; + softs->ipf_state_list = is; - if (ips_table[hv] != NULL) - ips_table[hv]->is_phnext = &is->is_hnext; + if (softs->ipf_state_table[hv] != NULL) + softs->ipf_state_table[hv]->is_phnext = &is->is_hnext; else - ips_stats.iss_inuse++; - is->is_phnext = ips_table + hv; - is->is_hnext = ips_table[hv]; - ips_table[hv] = is; - ips_stats.iss_bucketlen[hv]++; - ips_num++; - MUTEX_EXIT(&ipf_stinsert); + softs->ipf_state_stats.iss_inuse++; + is->is_phnext = softs->ipf_state_table + hv; + is->is_hnext = softs->ipf_state_table[hv]; + softs->ipf_state_table[hv] = is; + softs->ipf_state_stats.iss_bucketlen[hv]++; + softs->ipf_state_stats.iss_active++; + MUTEX_EXIT(&softs->ipf_stinsert); - fr_setstatequeue(is, rev); + ipf_state_setqueue(softc, is, rev); + + return 0; } /* ------------------------------------------------------------------------ */ -/* Function: fr_addstate */ -/* Returns: ipstate_t* - NULL == failure, else pointer to new state */ -/* Parameters: fin(I) - pointer to packet information */ +/* Function: ipf_state_matchipv4addrs */ +/* Returns: int - 2 addresses match (strong match), 1 reverse match, */ +/* 0 no match */ +/* Parameters: is1, is2 pointers to states we are checking */ +/* */ +/* Function matches IPv4 addresses it returns strong match for ICMP proto */ +/* even there is only reverse match */ +/* ------------------------------------------------------------------------ */ +static int +ipf_state_matchipv4addrs(is1, is2) + ipstate_t *is1, *is2; +{ + int rv; + + if (is1->is_saddr == is2->is_saddr && is1->is_daddr == is2->is_daddr) + rv = 2; + else if (is1->is_saddr == is2->is_daddr && + is1->is_daddr == is2->is_saddr) { + /* force strong match for ICMP protocol */ + rv = (is1->is_p == IPPROTO_ICMP) ? 2 : 1; + } + else + rv = 0; + + return (rv); +} + + +/* ------------------------------------------------------------------------ */ +/* Function: ipf_state_matchipv6addrs */ +/* Returns: int - 2 addresses match (strong match), 1 reverse match, */ +/* 0 no match */ +/* Parameters: is1, is2 pointers to states we are checking */ +/* */ +/* Function matches IPv6 addresses it returns strong match for ICMP proto */ +/* even there is only reverse match */ +/* ------------------------------------------------------------------------ */ +static int +ipf_state_matchipv6addrs(is1, is2) + ipstate_t *is1, *is2; +{ + int rv; + + if (IP6_EQ(&is1->is_src, &is2->is_src) && + IP6_EQ(&is1->is_dst, &is2->is_dst)) + rv = 2; + else if (IP6_EQ(&is1->is_src, &is2->is_dst) && + IP6_EQ(&is1->is_dst, &is2->is_src)) { + /* force strong match for ICMPv6 protocol */ + rv = (is1->is_p == IPPROTO_ICMPV6) ? 2 : 1; + } + else + rv = 0; + + return (rv); +} + + +/* ------------------------------------------------------------------------ */ +/* Function: ipf_state_matchaddresses */ +/* Returns: int - 2 addresses match, 1 reverse match, zero no match */ +/* Parameters: is1, is2 pointers to states we are checking */ +/* */ +/* function retruns true if two pairs of addresses belong to single */ +/* connection. suppose there are two endpoints: */ +/* endpoint1 1.1.1.1 */ +/* endpoint2 1.1.1.2 */ +/* */ +/* the state is established by packet flying from .1 to .2 so we see: */ +/* is1->src = 1.1.1.1 */ +/* is1->dst = 1.1.1.2 */ +/* now endpoint 1.1.1.2 sends answer */ +/* retreives is1 record created by first packat and compares it with is2 */ +/* temporal record, is2 is initialized as follows: */ +/* is2->src = 1.1.1.2 */ +/* is2->dst = 1.1.1.1 */ +/* in this case 1 will be returned */ +/* */ +/* the ipf_matchaddresses() assumes those two records to be same. of course */ +/* the ipf_matchaddresses() also assume records are same in case you pass */ +/* identical arguments (i.e. ipf_matchaddress(is1, is1) would return 2 */ +/* ------------------------------------------------------------------------ */ +static int +ipf_state_matchaddresses(is1, is2) + ipstate_t *is1, *is2; +{ + int rv; + + if (is1->is_v == 4) { + rv = ipf_state_matchipv4addrs(is1, is2); + } + else { + rv = ipf_state_matchipv6addrs(is1, is2); + } + + return (rv); +} + + +/* ------------------------------------------------------------------------ */ +/* Function: ipf_matchports */ +/* Returns: int - 2 match, 1 rverse match, 0 no match */ +/* Parameters: ppairs1, ppairs - src, dst ports we want to match */ +/* */ +/* performs the same match for isps members as for addresses */ +/* ------------------------------------------------------------------------ */ +static int +ipf_state_matchports(ppairs1, ppairs2) + udpinfo_t *ppairs1, *ppairs2; +{ + int rv; + + if (ppairs1->us_sport == ppairs2->us_sport && + ppairs1->us_dport == ppairs2->us_dport) + rv = 2; + else if (ppairs1->us_sport == ppairs2->us_dport && + ppairs1->us_dport == ppairs2->us_sport) + rv = 1; + else + rv = 0; + + return (rv); +} + + +/* ------------------------------------------------------------------------ */ +/* Function: ipf_matchisps */ +/* Returns: int - nonzero if isps members match, 0 nomatch */ +/* Parameters: is1, is2 - states we want to match */ +/* */ +/* performs the same match for isps members as for addresses */ +/* ------------------------------------------------------------------------ */ +static int +ipf_state_matchisps(is1, is2) + ipstate_t *is1, *is2; +{ + int rv; + + if (is1->is_p == is2->is_p) { + switch (is1->is_p) + { + case IPPROTO_TCP : + case IPPROTO_UDP : + case IPPROTO_GRE : + /* greinfo_t can be also interprted as port pair */ + rv = ipf_state_matchports(&is1->is_ps.is_us, + &is2->is_ps.is_us); + break; + + case IPPROTO_ICMP : + case IPPROTO_ICMPV6 : + /* force strong match for ICMP datagram. */ + if (bcmp(&is1->is_ps, &is2->is_ps, + sizeof(icmpinfo_t)) == 0) { + rv = 2; + } else { + rv = 0; + } + break; + + default: + rv = 0; + } + } else { + rv = 0; + } + + return (rv); +} + + +/* ------------------------------------------------------------------------ */ +/* Function: ipf_state_match */ +/* Returns: int - nonzero match, zero no match */ +/* Parameters: is1, is2 - states we want to match */ +/* */ +/* ------------------------------------------------------------------------ */ +static int +ipf_state_match(is1, is2) + ipstate_t *is1, *is2; +{ + int rv; + int amatch; + int pomatch; + + if (bcmp(&is1->is_pass, &is2->is_pass, + offsetof(struct ipstate, is_authmsk) - + offsetof(struct ipstate, is_pass)) == 0) { + + pomatch = ipf_state_matchisps(is1, is2); + amatch = ipf_state_matchaddresses(is1, is2); + rv = (amatch != 0) && (amatch == pomatch); + } else { + rv = 0; + } + + return (rv); +} + +/* ------------------------------------------------------------------------ */ +/* Function: ipf_state_add */ +/* Returns: ipstate_t - 0 = success */ +/* Parameters: softc(I) - pointer to soft context main structure */ +/* fin(I) - pointer to packet information */ /* stsave(O) - pointer to place to save pointer to created */ /* state structure. */ /* flags(I) - flags to use when creating the structure */ @@ -916,25 +1366,49 @@ int rev; /* either outlive this (not expired) or will deref the ip_state_t */ /* when they are deleted. */ /* ------------------------------------------------------------------------ */ -ipstate_t *fr_addstate(fin, stsave, flags) -fr_info_t *fin; -ipstate_t **stsave; -u_int flags; +int +ipf_state_add(softc, fin, stsave, flags) + ipf_main_softc_t *softc; + fr_info_t *fin; + ipstate_t **stsave; + u_int flags; { + ipf_state_softc_t *softs = softc->ipf_state_soft; ipstate_t *is, ips; struct icmp *ic; u_int pass, hv; frentry_t *fr; tcphdr_t *tcp; - grehdr_t *gre; + frdest_t *fdp; int out; - if (fr_state_lock || - (fin->fin_flx & (FI_SHORT|FI_STATE|FI_FRAGBODY|FI_BAD))) - return NULL; + /* + * If a packet that was created locally is trying to go out but we + * do not match here here because of this lock, it is likely that + * the policy will block it and return network unreachable back up + * the stack. To mitigate this error, EAGAIN is returned instead, + * telling the IP stack to try sending this packet again later. + */ + if (softs->ipf_state_lock) { + SBUMPD(ipf_state_stats, iss_add_locked); + fin->fin_error = EAGAIN; + return -1; + } - if ((fin->fin_flx & FI_OOW) && !(fin->fin_tcpf & TH_SYN)) - return NULL; + if (fin->fin_flx & (FI_SHORT|FI_STATE|FI_FRAGBODY|FI_BAD)) { + SBUMPD(ipf_state_stats, iss_add_bad); + return -1; + } + + if ((fin->fin_flx & FI_OOW) && !(fin->fin_tcpf & TH_SYN)) { + SBUMPD(ipf_state_stats, iss_add_oow); + return -1; + } + + if ((softs->ipf_state_stats.iss_active * 100 / softs->ipf_state_max) > + softs->ipf_state_wm_high) { + softs->ipf_state_doflush = 1; + } /* * If a "keep state" rule has reached the maximum number of references @@ -948,26 +1422,49 @@ u_int flags; */ fr = fin->fin_fr; if (fr != NULL) { - if ((ips_num >= fr_statemax) && (fr->fr_statemax == 0)) { - ATOMIC_INCL(ips_stats.iss_max); - fr_state_doflush = 1; - return NULL; + if ((softs->ipf_state_stats.iss_active >= + softs->ipf_state_max) && (fr->fr_statemax == 0)) { + SBUMPD(ipf_state_stats, iss_max); + return 1; } if ((fr->fr_statemax != 0) && (fr->fr_statecnt >= fr->fr_statemax)) { - ATOMIC_INCL(ips_stats.iss_maxref); - return NULL; + SBUMPD(ipf_state_stats, iss_max_ref); + return 2; } } - pass = (fr == NULL) ? 0 : fr->fr_flags; + is = &ips; + if (fr == NULL) { + pass = softc->ipf_flags; + is->is_tag = FR_NOLOGTAG; + } else { + pass = fr->fr_flags; + } ic = NULL; tcp = NULL; out = fin->fin_out; - is = &ips; bzero((char *)is, sizeof(*is)); - is->is_die = 1 + fr_ticks; + is->is_die = 1 + softc->ipf_ticks; + /* + * We want to check everything that is a property of this packet, + * but we don't (automatically) care about it's fragment status as + * this may change. + */ + is->is_pass = pass; + is->is_v = fin->fin_v; + is->is_sec = fin->fin_secmsk; + is->is_secmsk = 0xffff; + is->is_auth = fin->fin_auth; + is->is_authmsk = 0xffff; + is->is_family = fin->fin_family; + is->is_opt[0] = fin->fin_optmsk; + is->is_optmsk[0] = 0xffffffff; + if (is->is_v == 6) { + is->is_opt[0] &= ~0x8; + is->is_optmsk[0] &= ~0x8; + } /* * Copy and calculate... @@ -1008,13 +1505,8 @@ u_int flags; #endif if ((fin->fin_v == 4) && (fin->fin_flx & (FI_MULTICAST|FI_BROADCAST|FI_MBCAST))) { - if (fin->fin_out == 0) { - flags |= SI_W_DADDR|SI_CLONE; - hv -= is->is_daddr; - } else { - flags |= SI_W_SADDR|SI_CLONE; - hv -= is->is_saddr; - } + flags |= SI_W_DADDR; + hv -= is->is_daddr; } switch (is->is_p) @@ -1026,9 +1518,8 @@ u_int flags; switch (ic->icmp_type) { case ICMP6_ECHO_REQUEST : - is->is_icmp.ici_type = ic->icmp_type; hv += (is->is_icmp.ici_id = ic->icmp_id); - break; + /*FALLTHROUGH*/ case ICMP6_MEMBERSHIP_QUERY : case ND_ROUTER_SOLICIT : case ND_NEIGHBOR_SOLICIT : @@ -1036,9 +1527,9 @@ u_int flags; is->is_icmp.ici_type = ic->icmp_type; break; default : - return NULL; + SBUMPD(ipf_state_stats, iss_icmp6_notquery); + return -2; } - ATOMIC_INCL(ips_stats.iss_icmp); break; #endif case IPPROTO_ICMP : @@ -1054,11 +1545,12 @@ u_int flags; hv += (is->is_icmp.ici_id = ic->icmp_id); break; default : - return NULL; + SBUMPD(ipf_state_stats, iss_icmp_notquery); + return -3; } - ATOMIC_INCL(ips_stats.iss_icmp); break; +#if 0 case IPPROTO_GRE : gre = fin->fin_dp; @@ -1069,12 +1561,18 @@ u_int flags; is->is_call[1] = fin->fin_data[1]; } break; +#endif case IPPROTO_TCP : tcp = fin->fin_dp; - if (tcp->th_flags & TH_RST) - return NULL; + if (tcp->th_flags & TH_RST) { + SBUMPD(ipf_state_stats, iss_tcp_rstadd); + return -4; + } + + /* TRACE is, flags, hv */ + /* * The endian of the ports doesn't matter, but the ack and * sequence numbers do as we do mathematics on them later. @@ -1086,6 +1584,8 @@ u_int flags; hv += is->is_dport; } + /* TRACE is, flags, hv */ + /* * If this is a real packet then initialise fields in the * state information structure from the TCP header information. @@ -1110,15 +1610,14 @@ u_int flags; if ((tcp->th_flags & ~(TH_FIN|TH_ACK|TH_ECNALL)) == TH_SYN && (TCP_OFF(tcp) > (sizeof(tcphdr_t) >> 2))) { - if (fr_tcpoptions(fin, tcp, - &is->is_tcp.ts_data[0]) == -1) { + if (ipf_tcpoptions(softs, fin, tcp, + &is->is_tcp.ts_data[0]) == -1) fin->fin_flx |= FI_BAD; - } } if ((fin->fin_out != 0) && (pass & FR_NEWISN) != 0) { - fr_checknewisn(fin, is); - fr_fixoutisn(fin, is); + ipf_checknewisn(fin, is); + ipf_fixoutisn(fin, is); } if ((tcp->th_flags & TH_OPENING) == TH_SYN) @@ -1132,11 +1631,10 @@ u_int flags; } /* - * If we're creating state for a starting connection, start the - * timer on it as we'll never see an error if it fails to - * connect. + * If we're creating state for a starting connection, start + * the timer on it as we'll never see an error if it fails + * to connect. */ - ATOMIC_INCL(ips_stats.iss_tcp); break; case IPPROTO_UDP : @@ -1148,7 +1646,6 @@ u_int flags; hv += tcp->th_dport; hv += tcp->th_sport; } - ATOMIC_INCL(ips_stats.iss_udp); break; default : @@ -1156,144 +1653,173 @@ u_int flags; } hv = DOUBLE_HASH(hv); is->is_hv = hv; - is->is_rule = fr; - is->is_flags = flags & IS_INHERITED; /* * Look for identical state. */ - for (is = ips_table[is->is_hv % fr_statesize]; is != NULL; - is = is->is_hnext) { - if (bcmp(&ips.is_src, &is->is_src, - offsetof(struct ipstate, is_ps) - - offsetof(struct ipstate, is_src)) == 0) + for (is = softs->ipf_state_table[hv % softs->ipf_state_size]; + is != NULL; is = is->is_hnext) { + if (ipf_state_match(&ips, is) == 1) break; } - if (is != NULL) - return NULL; + if (is != NULL) { + SBUMPD(ipf_state_stats, iss_add_dup); + return 3; + } - if (ips_stats.iss_bucketlen[hv] >= fr_state_maxbucket) { - ATOMIC_INCL(ips_stats.iss_bucketfull); - return NULL; + if (softs->ipf_state_stats.iss_bucketlen[hv] >= + softs->ipf_state_maxbucket) { + SBUMPD(ipf_state_stats, iss_bucket_full); + return 4; } KMALLOC(is, ipstate_t *); if (is == NULL) { - ATOMIC_INCL(ips_stats.iss_nomem); - return NULL; + SBUMPD(ipf_state_stats, iss_nomem); + return 5; } bcopy((char *)&ips, (char *)is, sizeof(*is)); + is->is_flags = flags & IS_INHERITED; + is->is_rulen = fin->fin_rule; + is->is_rule = fr; + /* - * Do not do the modulous here, it is done in fr_stinsert(). + * Do not do the modulous here, it is done in ipf_state_insert(). */ if (fr != NULL) { - (void) strncpy(is->is_group, fr->fr_group, FR_GROUPLEN); + ipftq_t *tq; + + (void) strncpy(is->is_group, FR_NAME(fr, fr_group), + FR_GROUPLEN); if (fr->fr_age[0] != 0) { - is->is_tqehead[0] = fr_addtimeoutqueue(&ips_utqe, - fr->fr_age[0]); + tq = ipf_addtimeoutqueue(softc, + &softs->ipf_state_usertq, + fr->fr_age[0]); + is->is_tqehead[0] = tq; is->is_sti.tqe_flags |= TQE_RULEBASED; } if (fr->fr_age[1] != 0) { - is->is_tqehead[1] = fr_addtimeoutqueue(&ips_utqe, - fr->fr_age[1]); + tq = ipf_addtimeoutqueue(softc, + &softs->ipf_state_usertq, + fr->fr_age[1]); + is->is_tqehead[1] = tq; is->is_sti.tqe_flags |= TQE_RULEBASED; } is->is_tag = fr->fr_logtag; - - /* - * The name '-' is special for network interfaces and causes - * a NULL name to be present, always, allowing packets to - * match it, regardless of their interface. - */ - if ((fin->fin_ifp == NULL) || - (fr->fr_ifnames[out << 1][0] == '-' && - fr->fr_ifnames[out << 1][1] == '\0')) { - is->is_ifp[out << 1] = fr->fr_ifas[0]; - strncpy(is->is_ifname[out << 1], fr->fr_ifnames[0], - sizeof(fr->fr_ifnames[0])); - } else { - is->is_ifp[out << 1] = fin->fin_ifp; - COPYIFNAME(is->is_v, fin->fin_ifp, - is->is_ifname[out << 1]); - } - - is->is_ifp[(out << 1) + 1] = fr->fr_ifas[1]; - strncpy(is->is_ifname[(out << 1) + 1], fr->fr_ifnames[1], - sizeof(fr->fr_ifnames[1])); - - is->is_ifp[(1 - out) << 1] = fr->fr_ifas[2]; - strncpy(is->is_ifname[((1 - out) << 1)], fr->fr_ifnames[2], - sizeof(fr->fr_ifnames[2])); - - is->is_ifp[((1 - out) << 1) + 1] = fr->fr_ifas[3]; - strncpy(is->is_ifname[((1 - out) << 1) + 1], fr->fr_ifnames[3], - sizeof(fr->fr_ifnames[3])); - } else { - pass = fr_flags; - is->is_tag = FR_NOLOGTAG; - - if (fin->fin_ifp != NULL) { - is->is_ifp[out << 1] = fin->fin_ifp; - COPYIFNAME(is->is_v, fin->fin_ifp, - is->is_ifname[out << 1]); - } } /* - * It may seem strange to set is_ref to 2, but fr_check() will call - * fr_statederef() after calling fr_addstate() and the idea is to - * have it exist at the end of fr_check() with is_ref == 1. + * It may seem strange to set is_ref to 2, but if stsave is not NULL + * then a copy of the pointer is being stored somewhere else and in + * the end, it will expect to be able to do osmething with it. */ - is->is_ref = 2; - is->is_pass = pass; + is->is_me = stsave; + if (stsave != NULL) { + *stsave = is; + is->is_ref = 2; + } else { + is->is_ref = 1; + } is->is_pkts[0] = 0, is->is_bytes[0] = 0; is->is_pkts[1] = 0, is->is_bytes[1] = 0; is->is_pkts[2] = 0, is->is_bytes[2] = 0; is->is_pkts[3] = 0, is->is_bytes[3] = 0; if ((fin->fin_flx & FI_IGNORE) == 0) { is->is_pkts[out] = 1; + fin->fin_pktnum = 1; is->is_bytes[out] = fin->fin_plen; is->is_flx[out][0] = fin->fin_flx & FI_CMP; is->is_flx[out][0] &= ~FI_OOW; } + if (pass & FR_STLOOSE) + is->is_flags |= IS_LOOSE; + if (pass & FR_STSTRICT) is->is_flags |= IS_STRICT; if (pass & FR_STATESYNC) is->is_flags |= IS_STATESYNC; - /* - * We want to check everything that is a property of this packet, - * but we don't (automatically) care about it's fragment status as - * this may change. - */ - is->is_v = fin->fin_v; - is->is_opt[0] = fin->fin_optmsk; - is->is_optmsk[0] = 0xffffffff; - is->is_optmsk[1] = 0xffffffff; - if (is->is_v == 6) { - is->is_opt[0] &= ~0x8; - is->is_optmsk[0] &= ~0x8; - is->is_optmsk[1] &= ~0x8; - } - is->is_me = stsave; - is->is_sec = fin->fin_secmsk; - is->is_secmsk = 0xffff; - is->is_auth = fin->fin_auth; - is->is_authmsk = 0xffff; - if (flags & (SI_WILDP|SI_WILDA)) { - ATOMIC_INCL(ips_stats.iss_wild); - } - is->is_rulen = fin->fin_rule; - - if (pass & FR_LOGFIRST) is->is_pass &= ~(FR_LOGFIRST|FR_LOG); - READ_ENTER(&ipf_state); + READ_ENTER(&softc->ipf_state); - fr_stinsert(is, fin->fin_rev); + if (ipf_state_insert(softc, is, fin->fin_rev) == -1) { + RWLOCK_EXIT(&softc->ipf_state); + /* + * This is a bit more manual than it should be but + * ipf_state_del cannot be called. + */ + MUTEX_EXIT(&is->is_lock); + MUTEX_DESTROY(&is->is_lock); + if (is->is_tqehead[0] != NULL) { + if (ipf_deletetimeoutqueue(is->is_tqehead[0]) == 0) + ipf_freetimeoutqueue(softc, is->is_tqehead[0]); + is->is_tqehead[0] = NULL; + } + if (is->is_tqehead[1] != NULL) { + if (ipf_deletetimeoutqueue(is->is_tqehead[1]) == 0) + ipf_freetimeoutqueue(softc, is->is_tqehead[1]); + is->is_tqehead[1] = NULL; + } + KFREE(is); + return -1; + } + + /* + * Filling in the interface name is after the insert so that an + * event (such as add/delete) of an interface that is referenced + * by this rule will see this state entry. + */ + if (fr != NULL) { + /* + * The name '-' is special for network interfaces and causes + * a NULL name to be present, always, allowing packets to + * match it, regardless of their interface. + */ + if ((fin->fin_ifp == NULL) || + (fr->fr_ifnames[out << 1] != -1 && + fr->fr_names[fr->fr_ifnames[out << 1] + 0] == '-' && + fr->fr_names[fr->fr_ifnames[out << 1] + 1] == '\0')) { + is->is_ifp[out << 1] = fr->fr_ifas[0]; + strncpy(is->is_ifname[out << 1], + fr->fr_names + fr->fr_ifnames[0], + sizeof(fr->fr_ifnames[0])); + } else { + is->is_ifp[out << 1] = fin->fin_ifp; + COPYIFNAME(fin->fin_v, fin->fin_ifp, + is->is_ifname[out << 1]); + } + + is->is_ifp[(out << 1) + 1] = fr->fr_ifas[1]; + if (fr->fr_ifnames[1] != -1) { + strncpy(is->is_ifname[(out << 1) + 1], + fr->fr_names + fr->fr_ifnames[1], + sizeof(fr->fr_ifnames[1])); + } + + is->is_ifp[(1 - out) << 1] = fr->fr_ifas[2]; + if (fr->fr_ifnames[2] != -1) { + strncpy(is->is_ifname[((1 - out) << 1)], + fr->fr_names + fr->fr_ifnames[2], + sizeof(fr->fr_ifnames[2])); + } + + is->is_ifp[((1 - out) << 1) + 1] = fr->fr_ifas[3]; + if (fr->fr_ifnames[3] != -1) { + strncpy(is->is_ifname[((1 - out) << 1) + 1], + fr->fr_names + fr->fr_ifnames[3], + sizeof(fr->fr_ifnames[3])); + } + } else { + if (fin->fin_ifp != NULL) { + is->is_ifp[out << 1] = fin->fin_ifp; + COPYIFNAME(fin->fin_v, fin->fin_ifp, + is->is_ifname[out << 1]); + } + } if (fin->fin_p == IPPROTO_TCP) { /* @@ -1301,56 +1827,79 @@ u_int flags; * timer on it as we'll never see an error if it fails to * connect. */ - (void) fr_tcp_age(&is->is_sti, fin, ips_tqtqb, is->is_flags); - MUTEX_EXIT(&is->is_lock); -#ifdef IPFILTER_SCAN - if ((is->is_flags & SI_CLONE) == 0) - (void) ipsc_attachis(is); -#endif - } else { - MUTEX_EXIT(&is->is_lock); + (void) ipf_tcp_age(&is->is_sti, fin, softs->ipf_state_tcptq, + is->is_flags, 2); } -#ifdef IPFILTER_SYNC + MUTEX_EXIT(&is->is_lock); if ((is->is_flags & IS_STATESYNC) && ((is->is_flags & SI_CLONE) == 0)) - is->is_sync = ipfsync_new(SMC_STATE, fin, is); -#endif - if (ipstate_logging) - ipstate_log(is, ISL_NEW); + is->is_sync = ipf_sync_new(softc, SMC_STATE, fin, is); + if (softs->ipf_state_logging) + ipf_state_log(softc, is, ISL_NEW); + + RWLOCK_EXIT(&softc->ipf_state); - RWLOCK_EXIT(&ipf_state); - fin->fin_state = is; - fin->fin_rev = IP6_NEQ(&is->is_dst, &fin->fin_daddr); fin->fin_flx |= FI_STATE; if (fin->fin_flx & FI_FRAG) - (void) fr_newfrag(fin, pass ^ FR_KEEPSTATE); + (void) ipf_frag_new(softc, fin, pass); - return is; + fdp = &fr->fr_tifs[0]; + if (fdp->fd_type == FRD_DSTLIST) { + ipf_dstlist_select_node(fin, fdp->fd_ptr, NULL, + &is->is_tifs[0]); + } else { + bcopy(fdp, &is->is_tifs[0], sizeof(*fdp)); + } + + fdp = &fr->fr_tifs[1]; + if (fdp->fd_type == FRD_DSTLIST) { + ipf_dstlist_select_node(fin, fdp->fd_ptr, NULL, + &is->is_tifs[1]); + } else { + bcopy(fdp, &is->is_tifs[1], sizeof(*fdp)); + } + fin->fin_tif = &is->is_tifs[fin->fin_rev]; + + fdp = &fr->fr_dif; + if (fdp->fd_type == FRD_DSTLIST) { + ipf_dstlist_select_node(fin, fdp->fd_ptr, NULL, + &is->is_dif); + } else { + bcopy(fdp, &is->is_dif, sizeof(*fdp)); + } + fin->fin_dif = &is->is_dif; + + return 0; } /* ------------------------------------------------------------------------ */ -/* Function: fr_tcpoptions */ +/* Function: ipf_tcpoptions */ /* Returns: int - 1 == packet matches state entry, 0 == it does not, */ /* -1 == packet has bad TCP options data */ -/* Parameters: fin(I) - pointer to packet information */ +/* Parameters: softs(I) - pointer to state context structure */ +/* fin(I) - pointer to packet information */ /* tcp(I) - pointer to TCP packet header */ /* td(I) - pointer to TCP data held as part of the state */ /* */ /* Look after the TCP header for any options and deal with those that are */ /* present. Record details about those that we recogise. */ /* ------------------------------------------------------------------------ */ -static int fr_tcpoptions(fin, tcp, td) -fr_info_t *fin; -tcphdr_t *tcp; -tcpdata_t *td; +static int +ipf_tcpoptions(softs, fin, tcp, td) + ipf_state_softc_t *softs; + fr_info_t *fin; + tcphdr_t *tcp; + tcpdata_t *td; { int off, mlen, ol, i, len, retval; char buf[64], *s, opt; mb_t *m = NULL; len = (TCP_OFF(tcp) << 2); - if (fin->fin_dlen < len) + if (fin->fin_dlen < len) { + SBUMPD(ipf_state_stats, iss_tcp_toosmall); return 0; + } len -= sizeof(*tcp); off = fin->fin_plen - fin->fin_dlen + sizeof(*tcp) + fin->fin_ipoff; @@ -1422,14 +1971,19 @@ tcpdata_t *td; len -= ol; s += ol; } + if (retval == -1) { + SBUMPD(ipf_state_stats, iss_tcp_badopt); + } return retval; } /* ------------------------------------------------------------------------ */ -/* Function: fr_tcpstate */ +/* Function: ipf_state_tcp */ /* Returns: int - 1 == packet matches state entry, 0 == it does not */ -/* Parameters: fin(I) - pointer to packet information */ +/* Parameters: softc(I) - pointer to soft context main structure */ +/* softs(I) - pointer to state context structure */ +/* fin(I) - pointer to packet information */ /* tcp(I) - pointer to TCP packet header */ /* is(I) - pointer to master state structure */ /* */ @@ -1437,16 +1991,19 @@ tcpdata_t *td; /* Change timeout depending on whether new packet is a SYN-ACK returning */ /* for a SYN or a RST or FIN which indicate time to close up shop. */ /* ------------------------------------------------------------------------ */ -static int fr_tcpstate(fin, tcp, is) -fr_info_t *fin; -tcphdr_t *tcp; -ipstate_t *is; +static int +ipf_state_tcp(softc, softs, fin, tcp, is) + ipf_main_softc_t *softc; + ipf_state_softc_t *softs; + fr_info_t *fin; + tcphdr_t *tcp; + ipstate_t *is; { - int source, ret = 0, flags; tcpdata_t *fdata, *tdata; + int source, ret, flags; source = !fin->fin_rev; - if (((is->is_flags & IS_TCPFSM) != 0) && (source == 1) && + if (((is->is_flags & IS_TCPFSM) != 0) && (source == 1) && (ntohs(is->is_sport) != fin->fin_data[0])) source = 0; fdata = &is->is_tcp.ts_data[!source]; @@ -1462,34 +2019,37 @@ ipstate_t *is; if ((is->is_state[0] > IPF_TCPS_ESTABLISHED) && (is->is_state[1] > IPF_TCPS_ESTABLISHED)) { is->is_state[!source] = IPF_TCPS_CLOSED; - fr_movequeue(&is->is_sti, is->is_sti.tqe_ifq, - &ips_deletetq); + ipf_movequeue(softc->ipf_ticks, &is->is_sti, + is->is_sti.tqe_ifq, + &softs->ipf_state_deletetq); MUTEX_EXIT(&is->is_lock); + DT1(iss_tcp_closing, ipstate_t *, is); + SBUMP(ipf_state_stats.iss_tcp_closing); return 0; } } - ret = fr_tcpinwindow(fin, fdata, tdata, tcp, is->is_flags); + if (is->is_flags & IS_LOOSE) + ret = 1; + else + ret = ipf_state_tcpinwindow(fin, fdata, tdata, tcp, + is->is_flags); if (ret > 0) { -#ifdef IPFILTER_SCAN - if (is->is_flags & (IS_SC_CLIENT|IS_SC_SERVER)) { - ipsc_packet(fin, is); - if (FR_ISBLOCK(is->is_pass)) { - MUTEX_EXIT(&is->is_lock); - return 1; - } - } -#endif - /* * Nearing end of connection, start timeout. */ - ret = fr_tcp_age(&is->is_sti, fin, ips_tqtqb, is->is_flags); + ret = ipf_tcp_age(&is->is_sti, fin, softs->ipf_state_tcptq, + is->is_flags, ret); if (ret == 0) { MUTEX_EXIT(&is->is_lock); + DT2(iss_tcp_fsm, fr_info_t *, fin, ipstate_t *, is); + SBUMP(ipf_state_stats.iss_tcp_fsm); return 0; } + if (softs->ipf_state_logging > 4) + ipf_state_log(softc, is, ISL_STATECHANGE); + /* * set s0's as appropriate. Use syn-ack packet as it * contains both pieces of required information. @@ -1503,25 +2063,29 @@ ipstate_t *is; is->is_s0[source] = ntohl(tcp->th_ack); is->is_s0[!source] = ntohl(tcp->th_seq) + 1; if ((TCP_OFF(tcp) > (sizeof(tcphdr_t) >> 2))) { - if (fr_tcpoptions(fin, tcp, fdata) == -1) + if (ipf_tcpoptions(softs, fin, tcp, + fdata) == -1) fin->fin_flx |= FI_BAD; } if ((fin->fin_out != 0) && (is->is_pass & FR_NEWISN)) - fr_checknewisn(fin, is); + ipf_checknewisn(fin, is); } else if (flags == TH_SYN) { is->is_s0[source] = ntohl(tcp->th_seq) + 1; if ((TCP_OFF(tcp) > (sizeof(tcphdr_t) >> 2))) { - if (fr_tcpoptions(fin, tcp, fdata) == -1) + if (ipf_tcpoptions(softs, fin, tcp, + fdata) == -1) fin->fin_flx |= FI_BAD; } if ((fin->fin_out != 0) && (is->is_pass & FR_NEWISN)) - fr_checknewisn(fin, is); + ipf_checknewisn(fin, is); } ret = 1; } else { - fin->fin_flx |= FI_OOW; + DT2(iss_tcp_oow, fr_info_t *, fin, ipstate_t *, is); + SBUMP(ipf_state_stats.iss_tcp_oow); + ret = 0; } MUTEX_EXIT(&is->is_lock); return ret; @@ -1529,7 +2093,7 @@ ipstate_t *is; /* ------------------------------------------------------------------------ */ -/* Function: fr_checknewisn */ +/* Function: ipf_checknewisn */ /* Returns: Nil */ /* Parameters: fin(I) - pointer to packet information */ /* is(I) - pointer to master state structure */ @@ -1540,9 +2104,10 @@ ipstate_t *is; /* NOTE: This does not actually change the sequence numbers, only gets new */ /* one ready. */ /* ------------------------------------------------------------------------ */ -static void fr_checknewisn(fin, is) -fr_info_t *fin; -ipstate_t *is; +static void +ipf_checknewisn(fin, is) + fr_info_t *fin; + ipstate_t *is; { u_32_t sumd, old, new; tcphdr_t *tcp; @@ -1554,7 +2119,7 @@ ipstate_t *is; if (((i == 0) && !(is->is_flags & IS_ISNSYN)) || ((i == 1) && !(is->is_flags & IS_ISNACK))) { old = ntohl(tcp->th_seq); - new = fr_newisn(fin); + new = ipf_newisn(fin); is->is_isninc[i] = new - old; CALC_SUMD(old, new, sumd); is->is_sumd[i] = (sumd & 0xffff) + (sumd >> 16); @@ -1565,9 +2130,8 @@ ipstate_t *is; /* ------------------------------------------------------------------------ */ -/* Function: fr_tcpinwindow */ -/* Returns: int - 1 == packet inside TCP "window", 0 == not inside, */ -/* 2 == packet seq number matches next expected */ +/* Function: ipf_state_tcpinwindow */ +/* Returns: int - 1 == packet inside TCP "window", 0 == not inside. */ /* Parameters: fin(I) - pointer to packet information */ /* fdata(I) - pointer to tcp state informatio (forward) */ /* tdata(I) - pointer to tcp state informatio (reverse) */ @@ -1577,12 +2141,15 @@ ipstate_t *is; /* within the TCP data window. In a show of generosity, allow packets that */ /* are within the window space behind the current sequence # as well. */ /* ------------------------------------------------------------------------ */ -int fr_tcpinwindow(fin, fdata, tdata, tcp, flags) -fr_info_t *fin; -tcpdata_t *fdata, *tdata; -tcphdr_t *tcp; -int flags; +static int +ipf_state_tcpinwindow(fin, fdata, tdata, tcp, flags) + fr_info_t *fin; + tcpdata_t *fdata, *tdata; + tcphdr_t *tcp; + int flags; { + ipf_main_softc_t *softc = fin->fin_main_soft; + ipf_state_softc_t *softs = softc->ipf_state_soft; tcp_seq seq, ack, end; int ackskew, tcpflags; u_32_t win, maxwin; @@ -1651,12 +2218,17 @@ int flags; /* * Strict sequencing only allows in-order delivery. */ - if (seq != fdata->td_end) { - if ((flags & IS_STRICT) != 0) { + if ((flags & IS_STRICT) != 0) { + if (seq != fdata->td_end) { + DT2(iss_tcp_struct, tcpdata_t *, fdata, int, seq); + SBUMP(ipf_state_stats.iss_tcp_strict); + fin->fin_flx |= FI_OOW; return 0; } } +#define SEQ_GE(a,b) ((int)((a) - (b)) >= 0) +#define SEQ_GT(a,b) ((int)((a) - (b)) > 0) inseq = 0; if ((SEQ_GE(fdata->td_maxend, end)) && (SEQ_GE(seq, fdata->td_end - maxwin)) && @@ -1672,6 +2244,8 @@ int flags; } else if ((seq == fdata->td_maxend) && (ackskew == 0) && (fdata->td_winflags & TCP_SACK_PERMIT) && (tdata->td_winflags & TCP_SACK_PERMIT)) { + DT2(iss_sinsack, tcpdata_t *, fdata, int, seq); + SBUMP(ipf_state_stats.iss_winsack); inseq = 1; /* * Sometimes a TCP RST will be generated with only the ACK field @@ -1693,7 +2267,7 @@ int flags; * accepted, even if it appears out of sequence. */ inseq = 1; - } else + } else #endif if (!(fdata->td_winflags & (TCP_WSCALE_SEEN|TCP_WSCALE_FIRST))) { @@ -1737,12 +2311,14 @@ int flags; tdata->td_maxend = ack + win; return 1; } + SBUMP(ipf_state_stats.iss_oow); + fin->fin_flx |= FI_OOW; return 0; } /* ------------------------------------------------------------------------ */ -/* Function: fr_stclone */ +/* Function: ipf_state_clone */ /* Returns: ipstate_t* - NULL == cloning failed, */ /* else pointer to new state structure */ /* Parameters: fin(I) - pointer to packet information */ @@ -1751,27 +2327,40 @@ int flags; /* */ /* Create a "duplcate" state table entry from the master. */ /* ------------------------------------------------------------------------ */ -static ipstate_t *fr_stclone(fin, tcp, is) -fr_info_t *fin; -tcphdr_t *tcp; -ipstate_t *is; +static ipstate_t * +ipf_state_clone(fin, tcp, is) + fr_info_t *fin; + tcphdr_t *tcp; + ipstate_t *is; { + ipf_main_softc_t *softc = fin->fin_main_soft; + ipf_state_softc_t *softs = softc->ipf_state_soft; ipstate_t *clone; u_32_t send; - if (ips_num == fr_statemax) { - ATOMIC_INCL(ips_stats.iss_max); - fr_state_doflush = 1; + if (softs->ipf_state_stats.iss_active == softs->ipf_state_max) { + SBUMPD(ipf_state_stats, iss_max); + softs->ipf_state_doflush = 1; return NULL; } KMALLOC(clone, ipstate_t *); - if (clone == NULL) + if (clone == NULL) { + SBUMPD(ipf_state_stats, iss_clone_nomem); return NULL; + } bcopy((char *)is, (char *)clone, sizeof(*clone)); MUTEX_NUKE(&clone->is_lock); + /* + * It has not yet been placed on any timeout queue, so make sure + * all of that data is zero'd out. + */ + clone->is_sti.tqe_pnext = NULL; + clone->is_sti.tqe_next = NULL; + clone->is_sti.tqe_ifq = NULL; + clone->is_sti.tqe_parent = clone; - clone->is_die = ONE_DAY + fr_ticks; + clone->is_die = ONE_DAY + softc->ipf_ticks; clone->is_state[0] = 0; clone->is_state[1] = 0; send = ntohl(tcp->th_seq) + fin->fin_dlen - (TCP_OFF(tcp) << 2) + @@ -1798,49 +2387,61 @@ ipstate_t *is; clone->is_flags &= ~SI_CLONE; clone->is_flags |= SI_CLONED; - fr_stinsert(clone, fin->fin_rev); - clone->is_ref = 2; + if (ipf_state_insert(softc, clone, fin->fin_rev) == -1) { + KFREE(clone); + return NULL; + } + + clone->is_ref = 1; if (clone->is_p == IPPROTO_TCP) { - (void) fr_tcp_age(&clone->is_sti, fin, ips_tqtqb, - clone->is_flags); + (void) ipf_tcp_age(&clone->is_sti, fin, softs->ipf_state_tcptq, + clone->is_flags, 2); } MUTEX_EXIT(&clone->is_lock); -#ifdef IPFILTER_SCAN - (void) ipsc_attachis(is); -#endif -#ifdef IPFILTER_SYNC if (is->is_flags & IS_STATESYNC) - clone->is_sync = ipfsync_new(SMC_STATE, fin, clone); -#endif + clone->is_sync = ipf_sync_new(softc, SMC_STATE, fin, clone); + DT2(iss_clone, ipstate_t *, is, ipstate_t *, clone); + SBUMP(ipf_state_stats.iss_cloned); return clone; } /* ------------------------------------------------------------------------ */ -/* Function: fr_matchsrcdst */ +/* Function: ipf_matchsrcdst */ /* Returns: Nil */ -/* Parameters: fin(I) - pointer to packet information */ -/* is(I) - pointer to state structure */ -/* src(I) - pointer to source address */ -/* dst(I) - pointer to destination address */ -/* tcp(I) - pointer to TCP/UDP header */ +/* Parameters: fin(I) - pointer to packet information */ +/* is(I) - pointer to state structure */ +/* src(I) - pointer to source address */ +/* dst(I) - pointer to destination address */ +/* tcp(I) - pointer to TCP/UDP header */ +/* cmask(I) - mask of FI_* bits to check */ /* */ /* Match a state table entry against an IP packet. The logic below is that */ /* ret gets set to one if the match succeeds, else remains 0. If it is */ /* still 0 after the test. no match. */ /* ------------------------------------------------------------------------ */ -static ipstate_t *fr_matchsrcdst(fin, is, src, dst, tcp, cmask) -fr_info_t *fin; -ipstate_t *is; -i6addr_t *src, *dst; -tcphdr_t *tcp; -u_32_t cmask; +static ipstate_t * +ipf_matchsrcdst(fin, is, src, dst, tcp, cmask) + fr_info_t *fin; + ipstate_t *is; + i6addr_t *src, *dst; + tcphdr_t *tcp; + u_32_t cmask; { + ipf_main_softc_t *softc = fin->fin_main_soft; + ipf_state_softc_t *softs = softc->ipf_state_soft; int ret = 0, rev, out, flags, flx = 0, idx; u_short sp, dp; u_32_t cflx; void *ifp; + /* + * If a connection is about to be deleted, no packets + * are allowed to match it. + */ + if (is->is_sti.tqe_ifq == &softs->ipf_state_deletetq) + return NULL; + rev = IP6_NEQ(&is->is_dst, dst); ifp = fin->fin_ifp; out = fin->fin_out; @@ -1872,8 +2473,12 @@ u_32_t cmask; *is->is_ifname[idx] == '*'))) ret = 1; - if (ret == 0) + if (ret == 0) { + DT2(iss_lookup_badifp, fr_info_t *, fin, ipstate_t *, is); + SBUMP(ipf_state_stats.iss_lookup_badifp); + /* TRACE is, out, rev, idx */ return NULL; + } ret = 0; /* @@ -1883,7 +2488,8 @@ u_32_t cmask; if ((IP6_EQ(&is->is_dst, dst) || (flags & SI_W_DADDR)) && (IP6_EQ(&is->is_src, src) || (flags & SI_W_SADDR))) { if (tcp) { - if ((sp == is->is_sport || flags & SI_W_SPORT)&& + if ((sp == is->is_sport || flags & SI_W_SPORT) + && (dp == is->is_dport || flags & SI_W_DPORT)) ret = 1; } else { @@ -1894,7 +2500,8 @@ u_32_t cmask; if ((IP6_EQ(&is->is_dst, src) || (flags & SI_W_DADDR)) && (IP6_EQ(&is->is_src, dst) || (flags & SI_W_SADDR))) { if (tcp) { - if ((dp == is->is_sport || flags & SI_W_SPORT)&& + if ((dp == is->is_sport || flags & SI_W_SPORT) + && (sp == is->is_dport || flags & SI_W_DPORT)) ret = 1; } else { @@ -1903,8 +2510,12 @@ u_32_t cmask; } } - if (ret == 0) + if (ret == 0) { + SBUMP(ipf_state_stats.iss_lookup_badport); + DT2(iss_lookup_badport, fr_info_t *, fin, ipstate_t *, is); + /* TRACE rev, is, sp, dp, src, dst */ return NULL; + } /* * Whether or not this should be here, is questionable, but the aim @@ -1925,55 +2536,27 @@ u_32_t cmask; if ((flags & SI_W_SADDR) != 0) { if (rev == 0) { -#ifdef USE_INET6 - if (is->is_v == 6 && - IN6_IS_ADDR_MULTICAST(&fi->fi_src.in6)) - /*EMPTY*/; - else -#endif - { - is->is_src = fi->fi_src; - is->is_flags &= ~SI_W_SADDR; - } + is->is_src = fi->fi_src; + is->is_flags &= ~SI_W_SADDR; } else { -#ifdef USE_INET6 - if (is->is_v == 6 && - IN6_IS_ADDR_MULTICAST(&fi->fi_dst.in6)) - /*EMPTY*/; - else -#endif - { + if (!(fin->fin_flx & (FI_MULTICAST|FI_MBCAST))){ is->is_src = fi->fi_dst; is->is_flags &= ~SI_W_SADDR; } } } else if ((flags & SI_W_DADDR) != 0) { if (rev == 0) { -#ifdef USE_INET6 - if (is->is_v == 6 && - IN6_IS_ADDR_MULTICAST(&fi->fi_dst.in6)) - /*EMPTY*/; - else -#endif - { + if (!(fin->fin_flx & (FI_MULTICAST|FI_MBCAST))){ is->is_dst = fi->fi_dst; is->is_flags &= ~SI_W_DADDR; } } else { -#ifdef USE_INET6 - if (is->is_v == 6 && - IN6_IS_ADDR_MULTICAST(&fi->fi_src.in6)) - /*EMPTY*/; - else -#endif - { - is->is_dst = fi->fi_src; - is->is_flags &= ~SI_W_DADDR; - } + is->is_dst = fi->fi_src; + is->is_flags &= ~SI_W_DADDR; } } if ((is->is_flags & (SI_WILDA|SI_WILDP)) == 0) { - ATOMIC_DECL(ips_stats.iss_wild); + ATOMIC_DECL(softs->ipf_state_stats.iss_wild); } } @@ -1986,29 +2569,31 @@ u_32_t cmask; if ((cflx && (flx != (cflx & cmask))) || ((fin->fin_optmsk & is->is_optmsk[rev]) != is->is_opt[rev]) || ((fin->fin_secmsk & is->is_secmsk) != is->is_sec) || - ((fin->fin_auth & is->is_authmsk) != is->is_auth)) + ((fin->fin_auth & is->is_authmsk) != is->is_auth)) { + SBUMPD(ipf_state_stats, iss_miss_mask); return NULL; + } + + if ((fin->fin_flx & FI_IGNORE) != 0) { + fin->fin_rev = rev; + return is; + } /* * Only one of the source or destination port can be flagged as a * wildcard. When filling it in, fill in a copy of the matched entry * if it has the cloning flag set. */ - if ((fin->fin_flx & FI_IGNORE) != 0) { - fin->fin_rev = rev; - return is; - } - if ((flags & (SI_W_SPORT|SI_W_DPORT))) { if ((flags & SI_CLONE) != 0) { ipstate_t *clone; - clone = fr_stclone(fin, tcp, is); + clone = ipf_state_clone(fin, tcp, is); if (clone == NULL) return NULL; is = clone; } else { - ATOMIC_DECL(ips_stats.iss_wild); + ATOMIC_DECL(softs->ipf_state_stats.iss_wild); } if ((flags & SI_W_SPORT) != 0) { @@ -2031,18 +2616,21 @@ u_32_t cmask; is->is_maxdend = is->is_dend + 1; } is->is_flags &= ~(SI_W_SPORT|SI_W_DPORT); - if ((flags & SI_CLONED) && ipstate_logging) - ipstate_log(is, ISL_CLONE); + if ((flags & SI_CLONED) && softs->ipf_state_logging) + ipf_state_log(softc, is, ISL_CLONE); } ret = -1; if (is->is_flx[out][rev] == 0) { is->is_flx[out][rev] = flx; - is->is_opt[rev] = fin->fin_optmsk; - if (is->is_v == 6) { - is->is_opt[rev] &= ~0x8; - is->is_optmsk[rev] &= ~0x8; + if (rev == 1 && is->is_optmsk[1] == 0) { + is->is_opt[1] = fin->fin_optmsk; + is->is_optmsk[1] = 0xffffffff; + if (is->is_v == 6) { + is->is_opt[1] &= ~0x8; + is->is_optmsk[1] &= ~0x8; + } } } @@ -2053,7 +2641,7 @@ u_32_t cmask; if (is->is_ifp[idx] == NULL && (*is->is_ifname[idx] == '\0' || *is->is_ifname[idx] == '*')) { is->is_ifp[idx] = ifp; - COPYIFNAME(is->is_v, ifp, is->is_ifname[idx]); + COPYIFNAME(fin->fin_v, ifp, is->is_ifname[idx]); } fin->fin_rev = rev; return is; @@ -2061,7 +2649,7 @@ u_32_t cmask; /* ------------------------------------------------------------------------ */ -/* Function: fr_checkicmpmatchingstate */ +/* Function: ipf_checkicmpmatchingstate */ /* Returns: Nil */ /* Parameters: fin(I) - pointer to packet information */ /* */ @@ -2071,13 +2659,13 @@ u_32_t cmask; /* If we return NULL then no lock on ipf_state is held. */ /* If we return non-null then a read-lock on ipf_state is held. */ /* ------------------------------------------------------------------------ */ -static ipstate_t *fr_checkicmpmatchingstate(fin) -fr_info_t *fin; +static ipstate_t * +ipf_checkicmpmatchingstate(fin) + fr_info_t *fin; { + ipf_main_softc_t *softc = fin->fin_main_soft; + ipf_state_softc_t *softs = softc->ipf_state_soft; ipstate_t *is, **isp; - u_short sport, dport; - u_char pr; - int backward, i, oi; i6addr_t dst, src; struct icmp *ic; u_short savelen; @@ -2085,6 +2673,7 @@ fr_info_t *fin; fr_info_t ofin; tcphdr_t *tcp; int type, len; + u_char pr; ip_t *oip; u_int hv; @@ -2096,8 +2685,10 @@ fr_info_t *fin; */ if ((fin->fin_v != 4) || (fin->fin_hlen != sizeof(ip_t)) || (fin->fin_plen < ICMPERR_MINPKTLEN) || - !(fin->fin_flx & FI_ICMPERR)) + !(fin->fin_flx & FI_ICMPERR)) { + SBUMPD(ipf_state_stats, iss_icmp_bad); return NULL; + } ic = fin->fin_dp; type = ic->icmp_type; @@ -2106,15 +2697,20 @@ fr_info_t *fin; * Check if the at least the old IP header (with options) and * 8 bytes of payload is present. */ - if (fin->fin_plen < ICMPERR_MAXPKTLEN + ((IP_HL(oip) - 5) << 2)) + if (fin->fin_plen < ICMPERR_MAXPKTLEN + ((IP_HL(oip) - 5) << 2)) { + SBUMPDX(ipf_state_stats, iss_icmp_short, iss_icmp_short_1); return NULL; + } /* * Sanity Checks. */ len = fin->fin_dlen - ICMPERR_ICMPHLEN; - if ((len <= 0) || ((IP_HL(oip) << 2) > len)) + if ((len <= 0) || ((IP_HL(oip) << 2) > len)) { + DT2(iss_icmp_len, fr_info_t *, fin, struct ip*, oip); + SBUMPDX(ipf_state_stats, iss_icmp_short, iss_icmp_short_1); return NULL; + } /* * Is the buffer big enough for all of it ? It's the size of the IP @@ -2122,7 +2718,7 @@ fr_info_t *fin; * may be too big to be in this buffer but not so big that it's * outside the ICMP packet, leading to TCP deref's causing problems. * This is possible because we don't know how big oip_hl is when we - * do the pullup early in fr_check() and thus can't guarantee it is + * do the pullup early in ipf_check() and thus can't guarantee it is * all here now. */ #ifdef _KERNEL @@ -2131,14 +2727,19 @@ fr_info_t *fin; m = fin->fin_m; # if defined(MENTAT) - if ((char *)oip + len > (char *)m->b_wptr) + if ((char *)oip + len > (char *)m->b_wptr) { + SBUMPDX(ipf_state_stats, iss_icmp_short, iss_icmp_short_2); return NULL; + } # else - if ((char *)oip + len > (char *)fin->fin_ip + m->m_len) + if ((char *)oip + len > (char *)fin->fin_ip + m->m_len) { + SBUMPDX(ipf_state_stats, iss_icmp_short, iss_icmp_short_3); return NULL; + } # endif } #endif + bcopy((char *)fin, (char *)&ofin, sizeof(*fin)); /* @@ -2154,37 +2755,42 @@ fr_info_t *fin; * matchsrcdst note that not all fields are encessary * but this is the cleanest way. Note further we fill * in fin_mp such that if someone uses it we'll get - * a kernel panic. fr_matchsrcdst does not use this. + * a kernel panic. ipf_matchsrcdst does not use this. * * watch out here, as ip is in host order and oip in network * order. Any change we make must be undone afterwards, like - * oip->ip_off - it is still in network byte order so fix it. + * oip->ip_len. */ savelen = oip->ip_len; - oip->ip_len = len; - oip->ip_off = ntohs(oip->ip_off); + oip->ip_len = htons(len); ofin.fin_flx = FI_NOCKSUM; ofin.fin_v = 4; ofin.fin_ip = oip; ofin.fin_m = NULL; /* if dereferenced, panic XXX */ ofin.fin_mp = NULL; /* if dereferenced, panic XXX */ - (void) fr_makefrip(IP_HL(oip) << 2, oip, &ofin); + (void) ipf_makefrip(IP_HL(oip) << 2, oip, &ofin); ofin.fin_ifp = fin->fin_ifp; ofin.fin_out = !fin->fin_out; + + hv = (pr = oip->ip_p); + src.in4 = oip->ip_src; + hv += src.in4.s_addr; + dst.in4 = oip->ip_dst; + hv += dst.in4.s_addr; + /* - * Reset the short and bad flag here because in fr_matchsrcdst() + * Reset the short and bad flag here because in ipf_matchsrcdst() * the flags for the current packet (fin_flx) are compared against * those for the existing session. */ ofin.fin_flx &= ~(FI_BAD|FI_SHORT); /* - * Put old values of ip_len and ip_off back as we don't know - * if we have to forward the packet (or process it again. + * Put old values of ip_len back as we don't know + * if we have to forward the packet or process it again. */ oip->ip_len = savelen; - oip->ip_off = htons(oip->ip_off); switch (oip->ip_p) { @@ -2196,75 +2802,52 @@ fr_info_t *fin; * XXX theoretically ICMP_ECHOREP and the other reply's are * ICMP query's as well, but adding them here seems strange XXX */ - if ((ofin.fin_flx & FI_ICMPERR) != 0) + if ((ofin.fin_flx & FI_ICMPERR) != 0) { + DT1(iss_icmp_icmperr, fr_info_t *, &ofin); + SBUMP(ipf_state_stats.iss_icmp_icmperr); return NULL; + } /* * perform a lookup of the ICMP packet in the state table */ icmp = (icmphdr_t *)((char *)oip + (IP_HL(oip) << 2)); - hv = (pr = oip->ip_p); - src.in4 = oip->ip_src; - hv += src.in4.s_addr; - dst.in4 = oip->ip_dst; - hv += dst.in4.s_addr; hv += icmp->icmp_id; hv = DOUBLE_HASH(hv); - READ_ENTER(&ipf_state); - for (isp = &ips_table[hv]; ((is = *isp) != NULL); ) { + READ_ENTER(&softc->ipf_state); + for (isp = &softs->ipf_state_table[hv]; + ((is = *isp) != NULL); ) { isp = &is->is_hnext; if ((is->is_p != pr) || (is->is_v != 4)) continue; if (is->is_pass & FR_NOICMPERR) continue; - is = fr_matchsrcdst(&ofin, is, &src, &dst, + + is = ipf_matchsrcdst(&ofin, is, &src, &dst, NULL, FI_ICMPCMP); - if (is != NULL) { - /* - * i : the index of this packet (the icmp - * unreachable) - * oi : the index of the original packet found - * in the icmp header (i.e. the packet - * causing this icmp) - * backward : original packet was backward - * compared to the state - */ - backward = IP6_NEQ(&is->is_src, &src); - fin->fin_rev = !backward; - i = (!backward << 1) + fin->fin_out; - oi = (backward << 1) + ofin.fin_out; - if (is->is_icmppkts[i] > is->is_pkts[oi]) - continue; - ips_stats.iss_hits++; - is->is_icmppkts[i]++; + if ((is != NULL) && !ipf_allowstateicmp(fin, is, &src)) return is; - } } - RWLOCK_EXIT(&ipf_state); + RWLOCK_EXIT(&softc->ipf_state); + SBUMPDX(ipf_state_stats, iss_icmp_miss, iss_icmp_miss_1); return NULL; case IPPROTO_TCP : case IPPROTO_UDP : break; default : + SBUMPDX(ipf_state_stats, iss_icmp_miss, iss_icmp_miss_2); return NULL; } tcp = (tcphdr_t *)((char *)oip + (IP_HL(oip) << 2)); - dport = tcp->th_dport; - sport = tcp->th_sport; - hv = (pr = oip->ip_p); - src.in4 = oip->ip_src; - hv += src.in4.s_addr; - dst.in4 = oip->ip_dst; - hv += dst.in4.s_addr; - hv += dport; - hv += sport; + hv += tcp->th_dport;; + hv += tcp->th_sport;; hv = DOUBLE_HASH(hv); - READ_ENTER(&ipf_state); - for (isp = &ips_table[hv]; ((is = *isp) != NULL); ) { + READ_ENTER(&softc->ipf_state); + for (isp = &softs->ipf_state_table[hv]; ((is = *isp) != NULL); ) { isp = &is->is_hnext; /* * Only allow this icmp though if the @@ -2276,40 +2859,93 @@ fr_info_t *fin; * short flag is set. */ if ((is->is_p == pr) && (is->is_v == 4) && - (is = fr_matchsrcdst(&ofin, is, &src, &dst, - tcp, FI_ICMPCMP))) { - /* - * i : the index of this packet (the icmp unreachable) - * oi : the index of the original packet found in the - * icmp header (i.e. the packet causing this icmp) - * backward : original packet was backward compared to - * the state - */ - backward = IP6_NEQ(&is->is_src, &src); - fin->fin_rev = !backward; - i = (!backward << 1) + fin->fin_out; - oi = (backward << 1) + ofin.fin_out; - - if (((is->is_pass & FR_NOICMPERR) != 0) || - (is->is_icmppkts[i] > is->is_pkts[oi])) - break; - ips_stats.iss_hits++; - is->is_icmppkts[i]++; - /* - * we deliberately do not touch the timeouts - * for the accompanying state table entry. - * It remains to be seen if that is correct. XXX - */ - return is; + (is = ipf_matchsrcdst(&ofin, is, &src, &dst, + tcp, FI_ICMPCMP))) { + if (ipf_allowstateicmp(fin, is, &src) == 0) + return is; } } - RWLOCK_EXIT(&ipf_state); + RWLOCK_EXIT(&softc->ipf_state); + SBUMPDX(ipf_state_stats, iss_icmp_miss, iss_icmp_miss_3); return NULL; } /* ------------------------------------------------------------------------ */ -/* Function: fr_ipsmove */ +/* Function: ipf_allowstateicmp */ +/* Returns: int - 1 = packet denied, 0 = packet allowed */ +/* Parameters: fin(I) - pointer to packet information */ +/* is(I) - pointer to state table entry */ +/* src(I) - source address to check permission for */ +/* */ +/* For an ICMP packet that has so far matched a state table entry, check if */ +/* there are any further refinements that might mean we want to block this */ +/* packet. This code isn't specific to either IPv4 or IPv6. */ +/* ------------------------------------------------------------------------ */ +static int +ipf_allowstateicmp(fin, is, src) + fr_info_t *fin; + ipstate_t *is; + i6addr_t *src; +{ + ipf_main_softc_t *softc = fin->fin_main_soft; + ipf_state_softc_t *softs = softc->ipf_state_soft; + frentry_t *savefr; + frentry_t *fr; + u_32_t ipass; + int backward; + int oi; + int i; + + fr = is->is_rule; + if (fr != NULL && fr->fr_icmpgrp != NULL) { + savefr = fin->fin_fr; + fin->fin_fr = fr->fr_icmpgrp->fg_start; + + ipass = ipf_scanlist(fin, softc->ipf_pass); + fin->fin_fr = savefr; + if (FR_ISBLOCK(ipass)) { + SBUMPD(ipf_state_stats, iss_icmp_headblock); + return 1; + } + } + + /* + * i : the index of this packet (the icmp unreachable) + * oi : the index of the original packet found in the + * icmp header (i.e. the packet causing this icmp) + * backward : original packet was backward compared to + * the state + */ + backward = IP6_NEQ(&is->is_src, src); + fin->fin_rev = !backward; + i = (!backward << 1) + fin->fin_out; + oi = (backward << 1) + !fin->fin_out; + + if (is->is_pass & FR_NOICMPERR) { + SBUMPD(ipf_state_stats, iss_icmp_banned); + return 1; + } + if (is->is_icmppkts[i] > is->is_pkts[oi]) { + SBUMPD(ipf_state_stats, iss_icmp_toomany); + return 1; + } + + DT2(iss_icmp_hits, fr_info_t *, fin, ipstate_t *, is); + SBUMP(ipf_state_stats.iss_icmp_hits); + is->is_icmppkts[i]++; + + /* + * we deliberately do not touch the timeouts + * for the accompanying state table entry. + * It remains to be seen if that is correct. XXX + */ + return 0; +} + + +/* ------------------------------------------------------------------------ */ +/* Function: ipf_ipsmove */ /* Returns: Nil */ /* Parameters: is(I) - pointer to state table entry */ /* hv(I) - new hash value for state table entry */ @@ -2317,14 +2953,19 @@ fr_info_t *fin; /* */ /* Move a state entry from one position in the hash table to another. */ /* ------------------------------------------------------------------------ */ -static void fr_ipsmove(is, hv) -ipstate_t *is; -u_int hv; +static void +ipf_ipsmove(softs, is, hv) + ipf_state_softc_t *softs; + ipstate_t *is; + u_int hv; { ipstate_t **isp; u_int hvm; hvm = is->is_hv; + + /* TRACE is, is_hv, hvm */ + /* * Remove the hash from the old location... */ @@ -2332,21 +2973,24 @@ u_int hv; if (is->is_hnext) is->is_hnext->is_phnext = isp; *isp = is->is_hnext; - if (ips_table[hvm] == NULL) - ips_stats.iss_inuse--; - ips_stats.iss_bucketlen[hvm]--; + if (softs->ipf_state_table[hvm] == NULL) + softs->ipf_state_stats.iss_inuse--; + softs->ipf_state_stats.iss_bucketlen[hvm]--; /* * ...and put the hash in the new one. */ hvm = DOUBLE_HASH(hv); is->is_hv = hvm; - isp = &ips_table[hvm]; + + /* TRACE is, hv, is_hv, hvm */ + + isp = &softs->ipf_state_table[hvm]; if (*isp) (*isp)->is_phnext = &is->is_hnext; else - ips_stats.iss_inuse++; - ips_stats.iss_bucketlen[hvm]++; + softs->ipf_state_stats.iss_inuse++; + softs->ipf_state_stats.iss_bucketlen[hvm]++; is->is_phnext = isp; is->is_hnext = *isp; *isp = is; @@ -2354,23 +2998,28 @@ u_int hv; /* ------------------------------------------------------------------------ */ -/* Function: fr_stlookup */ +/* Function: ipf_state_lookup */ /* Returns: ipstate_t* - NULL == no matching state found, */ /* else pointer to state information is returned */ -/* Parameters: fin(I) - pointer to packet information */ -/* tcp(I) - pointer to TCP/UDP header. */ +/* Parameters: fin(I) - pointer to packet information */ +/* tcp(I) - pointer to TCP/UDP header. */ +/* ifqp(O) - pointer for storing tailq timeout */ /* */ /* Search the state table for a matching entry to the packet described by */ -/* the contents of *fin. */ +/* the contents of *fin. For certain protocols, when a match is found the */ +/* timeout queue is also selected and stored in ifpq if it is non-NULL. */ /* */ /* If we return NULL then no lock on ipf_state is held. */ /* If we return non-null then a read-lock on ipf_state is held. */ /* ------------------------------------------------------------------------ */ -ipstate_t *fr_stlookup(fin, tcp, ifqp) -fr_info_t *fin; -tcphdr_t *tcp; -ipftq_t **ifqp; +ipstate_t * +ipf_state_lookup(fin, tcp, ifqp) + fr_info_t *fin; + tcphdr_t *tcp; + ipftq_t **ifqp; { + ipf_main_softc_t *softc = fin->fin_main_soft; + ipf_state_softc_t *softs = softc->ipf_state_soft; u_int hv, hvm, pr, v, tryagain; ipstate_t *is, **isp; u_short dport, sport; @@ -2415,6 +3064,8 @@ ipftq_t **ifqp; } } + /* TRACE fin_saddr, fin_daddr, hv */ + /* * Search the hash table for matching packet header info. */ @@ -2429,28 +3080,22 @@ ipftq_t **ifqp; hv += ic->icmp_id; } } - READ_ENTER(&ipf_state); + READ_ENTER(&softc->ipf_state); icmp6again: hvm = DOUBLE_HASH(hv); - for (isp = &ips_table[hvm]; ((is = *isp) != NULL); ) { + for (isp = &softs->ipf_state_table[hvm]; + ((is = *isp) != NULL); ) { isp = &is->is_hnext; - /* - * If a connection is about to be deleted, no packets - * are allowed to match it. - */ - if (is->is_sti.tqe_ifq == &ips_deletetq) - continue; - if ((is->is_p != pr) || (is->is_v != v)) continue; - is = fr_matchsrcdst(fin, is, &src, &dst, NULL, FI_CMP); + is = ipf_matchsrcdst(fin, is, &src, &dst, NULL, FI_CMP); if (is != NULL && - fr_matchicmpqueryreply(v, &is->is_icmp, + ipf_matchicmpqueryreply(v, &is->is_icmp, ic, fin->fin_rev)) { if (fin->fin_rev) - ifq = &ips_icmpacktq; + ifq = &softs->ipf_state_icmpacktq; else - ifq = &ips_icmptq; + ifq = &softs->ipf_state_icmptq; break; } } @@ -2461,12 +3106,12 @@ ipftq_t **ifqp; hv += fin->fin_fi.fi_src.i6[1]; hv += fin->fin_fi.fi_src.i6[2]; hv += fin->fin_fi.fi_src.i6[3]; - fr_ipsmove(is, hv); - MUTEX_DOWNGRADE(&ipf_state); + ipf_ipsmove(softs, is, hv); + MUTEX_DOWNGRADE(&softc->ipf_state); } break; } - RWLOCK_EXIT(&ipf_state); + RWLOCK_EXIT(&softc->ipf_state); /* * No matching icmp state entry. Perhaps this is a @@ -2478,18 +3123,19 @@ ipftq_t **ifqp; * advantage of this requires some significant code changes * to handle the specific types where that is the case. */ - if ((ips_stats.iss_wild != 0) && (v == 6) && (tryagain == 0) && - !IN6_IS_ADDR_MULTICAST(&fin->fin_fi.fi_src.in6)) { + if ((softs->ipf_state_stats.iss_wild != 0) && + ((fin->fin_flx & FI_NOWILD) == 0) && + (v == 6) && (tryagain == 0)) { hv -= fin->fin_fi.fi_src.i6[0]; hv -= fin->fin_fi.fi_src.i6[1]; hv -= fin->fin_fi.fi_src.i6[2]; hv -= fin->fin_fi.fi_src.i6[3]; tryagain = 1; - WRITE_ENTER(&ipf_state); + WRITE_ENTER(&softc->ipf_state); goto icmp6again; } - is = fr_checkicmp6matchingstate(fin); + is = ipf_checkicmp6matchingstate(fin); if (is != NULL) return is; break; @@ -2500,25 +3146,26 @@ ipftq_t **ifqp; hv += ic->icmp_id; } hv = DOUBLE_HASH(hv); - READ_ENTER(&ipf_state); - for (isp = &ips_table[hv]; ((is = *isp) != NULL); ) { + READ_ENTER(&softc->ipf_state); + for (isp = &softs->ipf_state_table[hv]; + ((is = *isp) != NULL); ) { isp = &is->is_hnext; if ((is->is_p != pr) || (is->is_v != v)) continue; - is = fr_matchsrcdst(fin, is, &src, &dst, NULL, FI_CMP); + is = ipf_matchsrcdst(fin, is, &src, &dst, NULL, FI_CMP); if ((is != NULL) && (ic->icmp_id == is->is_icmp.ici_id) && - fr_matchicmpqueryreply(v, &is->is_icmp, + ipf_matchicmpqueryreply(v, &is->is_icmp, ic, fin->fin_rev)) { if (fin->fin_rev) - ifq = &ips_icmpacktq; + ifq = &softs->ipf_state_icmpacktq; else - ifq = &ips_icmptq; + ifq = &softs->ipf_state_icmptq; break; } } if (is == NULL) { - RWLOCK_EXIT(&ipf_state); + RWLOCK_EXIT(&softc->ipf_state); } break; @@ -2531,18 +3178,23 @@ ipftq_t **ifqp; hv += dport; oow = 0; tryagain = 0; - READ_ENTER(&ipf_state); + READ_ENTER(&softc->ipf_state); retry_tcpudp: hvm = DOUBLE_HASH(hv); - for (isp = &ips_table[hvm]; ((is = *isp) != NULL); ) { + + /* TRACE hv, hvm */ + + for (isp = &softs->ipf_state_table[hvm]; + ((is = *isp) != NULL); ) { isp = &is->is_hnext; if ((is->is_p != pr) || (is->is_v != v)) continue; fin->fin_flx &= ~FI_OOW; - is = fr_matchsrcdst(fin, is, &src, &dst, tcp, FI_CMP); + is = ipf_matchsrcdst(fin, is, &src, &dst, tcp, FI_CMP); if (is != NULL) { if (pr == IPPROTO_TCP) { - if (!fr_tcpstate(fin, tcp, is)) { + if (!ipf_state_tcp(softc, softs, fin, + tcp, is)) { oow |= fin->fin_flx & FI_OOW; continue; } @@ -2555,14 +3207,15 @@ ipftq_t **ifqp; !(is->is_flags & (SI_CLONE|SI_WILDP|SI_WILDA))) { hv += dport; hv += sport; - fr_ipsmove(is, hv); - MUTEX_DOWNGRADE(&ipf_state); + ipf_ipsmove(softs, is, hv); + MUTEX_DOWNGRADE(&softc->ipf_state); } break; } - RWLOCK_EXIT(&ipf_state); + RWLOCK_EXIT(&softc->ipf_state); - if (ips_stats.iss_wild) { + if ((softs->ipf_state_stats.iss_wild != 0) && + ((fin->fin_flx & FI_NOWILD) == 0)) { if (tryagain == 0) { hv -= dport; hv -= sport; @@ -2584,7 +3237,7 @@ ipftq_t **ifqp; } tryagain++; if (tryagain <= 2) { - WRITE_ENTER(&ipf_state); + WRITE_ENTER(&softc->ipf_state); goto retry_tcpudp; } } @@ -2602,19 +3255,20 @@ ipftq_t **ifqp; default : ifqp = NULL; hvm = DOUBLE_HASH(hv); - READ_ENTER(&ipf_state); - for (isp = &ips_table[hvm]; ((is = *isp) != NULL); ) { + READ_ENTER(&softc->ipf_state); + for (isp = &softs->ipf_state_table[hvm]; + ((is = *isp) != NULL); ) { isp = &is->is_hnext; if ((is->is_p != pr) || (is->is_v != v)) continue; - is = fr_matchsrcdst(fin, is, &src, &dst, NULL, FI_CMP); + is = ipf_matchsrcdst(fin, is, &src, &dst, NULL, FI_CMP); if (is != NULL) { - ifq = &ips_iptq; + ifq = &softs->ipf_state_iptq; break; } } if (is == NULL) { - RWLOCK_EXIT(&ipf_state); + RWLOCK_EXIT(&softc->ipf_state); } break; } @@ -2625,90 +3279,45 @@ ipftq_t **ifqp; ifq = is->is_tqehead[fin->fin_rev]; if (ifq != NULL && ifqp != NULL) *ifqp = ifq; + } else { + SBUMP(ipf_state_stats.iss_lookup_miss); } return is; } /* ------------------------------------------------------------------------ */ -/* Function: fr_updatestate */ -/* Returns: Nil */ -/* Parameters: fin(I) - pointer to packet information */ -/* is(I) - pointer to state table entry */ -/* Read Locks: ipf_state */ -/* */ -/* Updates packet and byte counters for a newly received packet. Seeds the */ -/* fragment cache with a new entry as required. */ -/* ------------------------------------------------------------------------ */ -void fr_updatestate(fin, is, ifq) -fr_info_t *fin; -ipstate_t *is; -ipftq_t *ifq; -{ - ipftqent_t *tqe; - int i, pass; - - i = (fin->fin_rev << 1) + fin->fin_out; - - /* - * For TCP packets, ifq == NULL. For all others, check if this new - * queue is different to the last one it was on and move it if so. - */ - tqe = &is->is_sti; - MUTEX_ENTER(&is->is_lock); - if ((tqe->tqe_flags & TQE_RULEBASED) != 0) - ifq = is->is_tqehead[fin->fin_rev]; - - if (ifq != NULL) - fr_movequeue(tqe, tqe->tqe_ifq, ifq); - - is->is_pkts[i]++; - is->is_bytes[i] += fin->fin_plen; - MUTEX_EXIT(&is->is_lock); - -#ifdef IPFILTER_SYNC - if (is->is_flags & IS_STATESYNC) - ipfsync_update(SMC_STATE, fin, is->is_sync); -#endif - - ATOMIC_INCL(ips_stats.iss_hits); - - fin->fin_fr = is->is_rule; - - /* - * If this packet is a fragment and the rule says to track fragments, - * then create a new fragment cache entry. - */ - pass = is->is_pass; - if ((fin->fin_flx & FI_FRAG) && FR_ISPASS(pass)) - (void) fr_newfrag(fin, pass ^ FR_KEEPSTATE); -} - - -/* ------------------------------------------------------------------------ */ -/* Function: fr_checkstate */ +/* Function: ipf_state_check */ /* Returns: frentry_t* - NULL == search failed, */ /* else pointer to rule for matching state */ -/* Parameters: ifp(I) - pointer to interface */ +/* Parameters: fin(I) - pointer to packet information */ /* passp(I) - pointer to filtering result flags */ /* */ /* Check if a packet is associated with an entry in the state table. */ /* ------------------------------------------------------------------------ */ -frentry_t *fr_checkstate(fin, passp) -fr_info_t *fin; -u_32_t *passp; +frentry_t * +ipf_state_check(fin, passp) + fr_info_t *fin; + u_32_t *passp; { + ipf_main_softc_t *softc = fin->fin_main_soft; + ipf_state_softc_t *softs = softc->ipf_state_soft; + ipftqent_t *tqe; ipstate_t *is; frentry_t *fr; tcphdr_t *tcp; ipftq_t *ifq; u_int pass; + int inout; - if (fr_state_lock || (ips_list == NULL) || - (fin->fin_flx & (FI_SHORT|FI_STATE|FI_FRAGBODY|FI_BAD))) + if (softs->ipf_state_lock || (softs->ipf_state_list == NULL)) return NULL; - is = NULL; + if (fin->fin_flx & (FI_SHORT|FI_FRAGBODY|FI_BAD)) { + SBUMPD(ipf_state_stats, iss_check_bad); + return NULL; + } + if ((fin->fin_flx & FI_TCPUDP) || (fin->fin_fi.fi_p == IPPROTO_ICMP) #ifdef USE_INET6 @@ -2719,13 +3328,12 @@ u_32_t *passp; else tcp = NULL; + ifq = NULL; /* * Search the hash table for matching packet header info. */ - ifq = NULL; - is = fin->fin_state; - if (is == NULL) - is = fr_stlookup(fin, tcp, &ifq); + is = ipf_state_lookup(fin, tcp, &ifq); + switch (fin->fin_p) { #ifdef USE_INET6 @@ -2733,9 +3341,7 @@ u_32_t *passp; if (is != NULL) break; if (fin->fin_v == 6) { - is = fr_checkicmp6matchingstate(fin); - if (is != NULL) - goto matched; + is = ipf_checkicmp6matchingstate(fin); } break; #endif @@ -2746,56 +3352,92 @@ u_32_t *passp; * No matching icmp state entry. Perhaps this is a * response to another state entry. */ - is = fr_checkicmpmatchingstate(fin); - if (is != NULL) - goto matched; + is = ipf_checkicmpmatchingstate(fin); break; + case IPPROTO_TCP : if (is == NULL) break; if (is->is_pass & FR_NEWISN) { if (fin->fin_out == 0) - fr_fixinisn(fin, is); + ipf_fixinisn(fin, is); else if (fin->fin_out == 1) - fr_fixoutisn(fin, is); + ipf_fixoutisn(fin, is); } break; default : if (fin->fin_rev) - ifq = &ips_udpacktq; + ifq = &softs->ipf_state_udpacktq; else - ifq = &ips_udptq; + ifq = &softs->ipf_state_udptq; break; } if (is == NULL) { - ATOMIC_INCL(ips_stats.iss_miss); + SBUMP(ipf_state_stats.iss_check_miss); return NULL; } -matched: fr = is->is_rule; if (fr != NULL) { if ((fin->fin_out == 0) && (fr->fr_nattag.ipt_num[0] != 0)) { - if (fin->fin_nattag == NULL) + if (fin->fin_nattag == NULL) { + RWLOCK_EXIT(&softc->ipf_state); + SBUMPD(ipf_state_stats, iss_check_notag); return NULL; - if (fr_matchtag(&fr->fr_nattag, fin->fin_nattag) != 0) + } + if (ipf_matchtag(&fr->fr_nattag, fin->fin_nattag)!=0) { + RWLOCK_EXIT(&softc->ipf_state); + SBUMPD(ipf_state_stats, iss_check_nattag); return NULL; + } } - (void) strncpy(fin->fin_group, fr->fr_group, FR_GROUPLEN); + (void) strncpy(fin->fin_group, FR_NAME(fr, fr_group), + FR_GROUPLEN); fin->fin_icode = fr->fr_icode; } fin->fin_rule = is->is_rulen; - pass = is->is_pass; - fr_updatestate(fin, is, ifq); + fin->fin_fr = fr; + + /* + * If this packet is a fragment and the rule says to track fragments, + * then create a new fragment cache entry. + */ + if ((fin->fin_flx & FI_FRAG) && FR_ISPASS(is->is_pass)) + (void) ipf_frag_new(softc, fin, is->is_pass); + + /* + * For TCP packets, ifq == NULL. For all others, check if this new + * queue is different to the last one it was on and move it if so. + */ + tqe = &is->is_sti; + if ((tqe->tqe_flags & TQE_RULEBASED) != 0) + ifq = is->is_tqehead[fin->fin_rev]; - fin->fin_state = is; - is->is_touched = fr_ticks; MUTEX_ENTER(&is->is_lock); - is->is_ref++; + + if (ifq != NULL) + ipf_movequeue(softc->ipf_ticks, tqe, tqe->tqe_ifq, ifq); + + inout = (fin->fin_rev << 1) + fin->fin_out; + is->is_pkts[inout]++; + is->is_bytes[inout] += fin->fin_plen; + fin->fin_pktnum = is->is_pkts[inout] + is->is_icmppkts[inout]; + MUTEX_EXIT(&is->is_lock); - RWLOCK_EXIT(&ipf_state); + + pass = is->is_pass; + + if (is->is_flags & IS_STATESYNC) + ipf_sync_update(softc, SMC_STATE, fin, is->is_sync); + + RWLOCK_EXIT(&softc->ipf_state); + + SBUMP(ipf_state_stats.iss_hits); + + fin->fin_dif = &is->is_dif; + fin->fin_tif = &is->is_tifs[fin->fin_rev]; fin->fin_flx |= FI_STATE; if ((pass & FR_LOGFIRST) != 0) pass &= ~(FR_LOGFIRST|FR_LOG); @@ -2805,17 +3447,18 @@ u_32_t *passp; /* ------------------------------------------------------------------------ */ -/* Function: fr_fixoutisn */ +/* Function: ipf_fixoutisn */ /* Returns: Nil */ -/* Parameters: fin(I) - pointer to packet information */ +/* Parameters: fin(I) - pointer to packet information */ /* is(I) - pointer to master state structure */ /* */ /* Called only for outbound packets, adjusts the sequence number and the */ /* TCP checksum to match that change. */ /* ------------------------------------------------------------------------ */ -static void fr_fixoutisn(fin, is) -fr_info_t *fin; -ipstate_t *is; +static void +ipf_fixoutisn(fin, is) + fr_info_t *fin; + ipstate_t *is; { tcphdr_t *tcp; int rev; @@ -2824,26 +3467,26 @@ ipstate_t *is; tcp = fin->fin_dp; rev = fin->fin_rev; if ((is->is_flags & IS_ISNSYN) != 0) { - if (rev == 0) { + if ((rev == 0) && (fin->fin_cksum < FI_CK_L4PART)) { seq = ntohl(tcp->th_seq); seq += is->is_isninc[0]; tcp->th_seq = htonl(seq); - fix_outcksum(fin, &tcp->th_sum, is->is_sumd[0]); + ipf_fix_outcksum(0, &tcp->th_sum, is->is_sumd[0], 0); } } if ((is->is_flags & IS_ISNACK) != 0) { - if (rev == 1) { + if ((rev == 1) && (fin->fin_cksum < FI_CK_L4PART)) { seq = ntohl(tcp->th_seq); seq += is->is_isninc[1]; tcp->th_seq = htonl(seq); - fix_outcksum(fin, &tcp->th_sum, is->is_sumd[1]); + ipf_fix_outcksum(0, &tcp->th_sum, is->is_sumd[1], 0); } } } /* ------------------------------------------------------------------------ */ -/* Function: fr_fixinisn */ +/* Function: ipf_fixinisn */ /* Returns: Nil */ /* Parameters: fin(I) - pointer to packet information */ /* is(I) - pointer to master state structure */ @@ -2851,9 +3494,10 @@ ipstate_t *is; /* Called only for inbound packets, adjusts the acknowledge number and the */ /* TCP checksum to match that change. */ /* ------------------------------------------------------------------------ */ -static void fr_fixinisn(fin, is) -fr_info_t *fin; -ipstate_t *is; +static void +ipf_fixinisn(fin, is) + fr_info_t *fin; + ipstate_t *is; { tcphdr_t *tcp; int rev; @@ -2862,28 +3506,29 @@ ipstate_t *is; tcp = fin->fin_dp; rev = fin->fin_rev; if ((is->is_flags & IS_ISNSYN) != 0) { - if (rev == 1) { + if ((rev == 1) && (fin->fin_cksum < FI_CK_L4PART)) { ack = ntohl(tcp->th_ack); ack -= is->is_isninc[0]; tcp->th_ack = htonl(ack); - fix_incksum(fin, &tcp->th_sum, is->is_sumd[0]); + ipf_fix_incksum(0, &tcp->th_sum, is->is_sumd[0], 0); } } if ((is->is_flags & IS_ISNACK) != 0) { - if (rev == 0) { + if ((rev == 0) && (fin->fin_cksum < FI_CK_L4PART)) { ack = ntohl(tcp->th_ack); ack -= is->is_isninc[1]; tcp->th_ack = htonl(ack); - fix_incksum(fin, &tcp->th_sum, is->is_sumd[1]); + ipf_fix_incksum(0, &tcp->th_sum, is->is_sumd[1], 0); } } } /* ------------------------------------------------------------------------ */ -/* Function: fr_statesync */ +/* Function: ipf_state_sync */ /* Returns: Nil */ -/* Parameters: ifp(I) - pointer to interface */ +/* Parameters: softc(I) - pointer to soft context main structure */ +/* ifp(I) - pointer to interface */ /* */ /* Walk through all state entries and if an interface pointer match is */ /* found then look it up again, based on its name in case the pointer has */ @@ -2892,40 +3537,45 @@ ipstate_t *is; /* If ifp is passed in as being non-null then we are only doing updates for */ /* existing, matching, uses of it. */ /* ------------------------------------------------------------------------ */ -void fr_statesync(ifp) -void *ifp; +void +ipf_state_sync(softc, ifp) + ipf_main_softc_t *softc; + void *ifp; { + ipf_state_softc_t *softs = softc->ipf_state_soft; ipstate_t *is; int i; - if (fr_running <= 0) + if (softc->ipf_running <= 0) return; - WRITE_ENTER(&ipf_state); + WRITE_ENTER(&softc->ipf_state); - if (fr_running <= 0) { - RWLOCK_EXIT(&ipf_state); + if (softc->ipf_running <= 0) { + RWLOCK_EXIT(&softc->ipf_state); return; } - for (is = ips_list; is; is = is->is_next) { + for (is = softs->ipf_state_list; is; is = is->is_next) { /* * Look up all the interface names in the state entry. */ for (i = 0; i < 4; i++) { if (ifp == NULL || ifp == is->is_ifp[i]) - is->is_ifp[i] = fr_resolvenic(is->is_ifname[i], + is->is_ifp[i] = ipf_resolvenic(softc, + is->is_ifname[i], is->is_v); } } - RWLOCK_EXIT(&ipf_state); + RWLOCK_EXIT(&softc->ipf_state); } /* ------------------------------------------------------------------------ */ -/* Function: fr_delstate */ -/* Returns: int - 0 = entry deleted, else reference count on struct */ -/* Parameters: is(I) - pointer to state structure to delete */ +/* Function: ipf_state_del */ +/* Returns: int - 0 = deleted, else refernce count on active struct */ +/* Parameters: softc(I) - pointer to soft context main structure */ +/* is(I) - pointer to state structure to delete */ /* why(I) - if not 0, log reason why it was deleted */ /* Write Locks: ipf_state */ /* */ @@ -2933,10 +3583,15 @@ void *ifp; /* and timeout queue lists. Make adjustments to hash table statistics and */ /* global counters as required. */ /* ------------------------------------------------------------------------ */ -static int fr_delstate(is, why) -ipstate_t *is; -int why; +static int +ipf_state_del(softc, is, why) + ipf_main_softc_t *softc; + ipstate_t *is; + int why; { + ipf_state_softc_t *softs = softc->ipf_state_soft; + int orphan = 1; + frentry_t *fr; /* * Since we want to delete this, remove it from the state table, @@ -2946,22 +3601,23 @@ int why; *is->is_phnext = is->is_hnext; if (is->is_hnext != NULL) is->is_hnext->is_phnext = is->is_phnext; - if (ips_table[is->is_hv] == NULL) - ips_stats.iss_inuse--; - ips_stats.iss_bucketlen[is->is_hv]--; + if (softs->ipf_state_table[is->is_hv] == NULL) + softs->ipf_state_stats.iss_inuse--; + softs->ipf_state_stats.iss_bucketlen[is->is_hv]--; is->is_phnext = NULL; is->is_hnext = NULL; + orphan = 0; } /* - * Because ips_stats.iss_wild is a count of entries in the state + * Because ipf_state_stats.iss_wild is a count of entries in the state * table that have wildcard flags set, only decerement it once * and do it here. */ if (is->is_flags & (SI_WILDP|SI_WILDA)) { if (!(is->is_flags & SI_CLONED)) { - ATOMIC_DECL(ips_stats.iss_wild); + ATOMIC_DECL(softs->ipf_state_stats.iss_wild); } is->is_flags &= ~(SI_WILDP|SI_WILDA); } @@ -2970,47 +3626,56 @@ int why; * Next, remove it from the timeout queue it is in. */ if (is->is_sti.tqe_ifq != NULL) - fr_deletequeueentry(&is->is_sti); - - if (is->is_me != NULL) { - *is->is_me = NULL; - is->is_me = NULL; - } + ipf_deletequeueentry(&is->is_sti); /* * If it is still in use by something else, do not go any further, * but note that at this point it is now an orphan. How can this - * be? fr_state_flush() calls fr_delete() directly because it wants + * be? ipf_state_flush() calls ipf_delete() directly because it wants * to empty the table out and if something has a hold on a state * entry (such as ipfstat), it'll do the deref path that'll bring * us back here to do the real delete & free. */ MUTEX_ENTER(&is->is_lock); - if (is->is_ref > 1) { + if (is->is_me != NULL) { + *is->is_me = NULL; + is->is_me = NULL; is->is_ref--; + } + if (is->is_ref > 1) { + int refs; + + is->is_ref--; + refs = is->is_ref; MUTEX_EXIT(&is->is_lock); - return is->is_ref; + if (!orphan) + softs->ipf_state_stats.iss_orphan++; + return refs; } MUTEX_EXIT(&is->is_lock); + fr = is->is_rule; + is->is_rule = NULL; + if (fr != NULL) { + if (fr->fr_srctrack.ht_max_nodes != 0) { + (void) ipf_ht_node_del(&fr->fr_srctrack, + is->is_family, &is->is_src); + } + } + is->is_ref = 0; if (is->is_tqehead[0] != NULL) { - if (fr_deletetimeoutqueue(is->is_tqehead[0]) == 0) - fr_freetimeoutqueue(is->is_tqehead[0]); + if (ipf_deletetimeoutqueue(is->is_tqehead[0]) == 0) + ipf_freetimeoutqueue(softc, is->is_tqehead[0]); } if (is->is_tqehead[1] != NULL) { - if (fr_deletetimeoutqueue(is->is_tqehead[1]) == 0) - fr_freetimeoutqueue(is->is_tqehead[1]); + if (ipf_deletetimeoutqueue(is->is_tqehead[1]) == 0) + ipf_freetimeoutqueue(softc, is->is_tqehead[1]); } -#ifdef IPFILTER_SYNC if (is->is_sync) - ipfsync_del(is->is_sync); -#endif -#ifdef IPFILTER_SCAN - (void) ipsc_detachis(is); -#endif + ipf_sync_del_state(softc->ipf_sync_soft, is->is_sync); /* * Now remove it from the linked list of known states @@ -3025,94 +3690,100 @@ int why; is->is_next = NULL; } - if (ipstate_logging != 0 && why != 0) - ipstate_log(is, why); + if (softs->ipf_state_logging != 0 && why != 0) + ipf_state_log(softc, is, why); if (is->is_p == IPPROTO_TCP) - ips_stats.iss_fin++; + softs->ipf_state_stats.iss_fin++; else - ips_stats.iss_expire++; + softs->ipf_state_stats.iss_expire++; + if (orphan) + softs->ipf_state_stats.iss_orphan--; - if (is->is_rule != NULL) { - is->is_rule->fr_statecnt--; - (void) fr_derefrule(&is->is_rule); + if (fr != NULL) { + fr->fr_statecnt--; + (void) ipf_derefrule(softc, &fr); } -#if defined(NEED_LOCAL_RAND) && defined(_KERNEL) - ipf_rand_push(is, sizeof(*is)); -#endif + softs->ipf_state_stats.iss_active_proto[is->is_p]--; MUTEX_DESTROY(&is->is_lock); KFREE(is); - ips_num--; + softs->ipf_state_stats.iss_active--; return 0; } /* ------------------------------------------------------------------------ */ -/* Function: fr_timeoutstate */ +/* Function: ipf_state_expire */ /* Returns: Nil */ -/* Parameters: Nil */ +/* Parameters: softc(I) - pointer to soft context main structure */ /* */ /* Slowly expire held state for thingslike UDP and ICMP. The algorithm */ /* used here is to keep the queue sorted with the oldest things at the top */ /* and the youngest at the bottom. So if the top one doesn't need to be */ /* expired then neither will any under it. */ /* ------------------------------------------------------------------------ */ -void fr_timeoutstate() +void +ipf_state_expire(softc) + ipf_main_softc_t *softc; { + ipf_state_softc_t *softs = softc->ipf_state_soft; ipftq_t *ifq, *ifqnext; ipftqent_t *tqe, *tqn; ipstate_t *is; SPL_INT(s); SPL_NET(s); - WRITE_ENTER(&ipf_state); - for (ifq = ips_tqtqb; ifq != NULL; ifq = ifq->ifq_next) + WRITE_ENTER(&softc->ipf_state); + for (ifq = softs->ipf_state_tcptq; ifq != NULL; ifq = ifq->ifq_next) for (tqn = ifq->ifq_head; ((tqe = tqn) != NULL); ) { - if (tqe->tqe_die > fr_ticks) + if (tqe->tqe_die > softc->ipf_ticks) break; tqn = tqe->tqe_next; is = tqe->tqe_parent; - fr_delstate(is, ISL_EXPIRE); + ipf_state_del(softc, is, ISL_EXPIRE); } - for (ifq = ips_utqe; ifq != NULL; ifq = ifqnext) { + for (ifq = softs->ipf_state_usertq; ifq != NULL; ifq = ifqnext) { ifqnext = ifq->ifq_next; for (tqn = ifq->ifq_head; ((tqe = tqn) != NULL); ) { - if (tqe->tqe_die > fr_ticks) + if (tqe->tqe_die > softc->ipf_ticks) break; tqn = tqe->tqe_next; is = tqe->tqe_parent; - fr_delstate(is, ISL_EXPIRE); + ipf_state_del(softc, is, ISL_EXPIRE); } } - for (ifq = ips_utqe; ifq != NULL; ifq = ifqnext) { + for (ifq = softs->ipf_state_usertq; ifq != NULL; ifq = ifqnext) { ifqnext = ifq->ifq_next; if (((ifq->ifq_flags & IFQF_DELETE) != 0) && (ifq->ifq_ref == 0)) { - fr_freetimeoutqueue(ifq); + ipf_freetimeoutqueue(softc, ifq); } } - if (fr_state_doflush) { - (void) fr_state_flush(2, 0); - fr_state_doflush = 0; + if (softs->ipf_state_doflush) { + (void) ipf_state_flush(softc, 2, 0); + softs->ipf_state_doflush = 0; + softs->ipf_state_wm_last = softc->ipf_ticks; } - RWLOCK_EXIT(&ipf_state); + RWLOCK_EXIT(&softc->ipf_state); SPL_X(s); } /* ------------------------------------------------------------------------ */ -/* Function: fr_state_flush */ +/* Function: ipf_state_flush */ /* Returns: int - 0 == success, -1 == failure */ -/* Parameters: Nil */ +/* Parameters: softc(I) - pointer to soft context main structure */ +/* which(I) - which flush action to perform */ +/* proto(I) - which protocol to flush (0 == ALL) */ /* Write Locks: ipf_state */ /* */ /* Flush state tables. Three actions currently defined: */ @@ -3126,12 +3797,15 @@ void fr_timeoutstate() /* If that too fails, then work backwards in 30 second intervals */ /* for the last 30 minutes to at worst 30 seconds idle. */ /* ------------------------------------------------------------------------ */ -static int fr_state_flush(which, proto) -int which, proto; +int +ipf_state_flush(softc, which, proto) + ipf_main_softc_t *softc; + int which, proto; { - ipftq_t *ifq, *ifqnext; + ipf_state_softc_t *softs = softc->ipf_state_soft; ipftqent_t *tqe, *tqn; ipstate_t *is, **isp; + ipftq_t *ifq; int removed; SPL_INT(s); @@ -3142,15 +3816,16 @@ int which, proto; switch (which) { case 0 : + SBUMP(ipf_state_stats.iss_flush_all); /* * Style 0 flush removes everything... */ - for (isp = &ips_list; ((is = *isp) != NULL); ) { + for (isp = &softs->ipf_state_list; ((is = *isp) != NULL); ) { if ((proto != 0) && (is->is_v != proto)) { isp = &is->is_next; continue; } - if (fr_delstate(is, ISL_FLUSH) == 0) + if (ipf_state_del(softc, is, ISL_FLUSH) == 0) removed++; else isp = &is->is_next; @@ -3158,19 +3833,20 @@ int which, proto; break; case 1 : + SBUMP(ipf_state_stats.iss_flush_closing); /* * Since we're only interested in things that are closing, * we can start with the appropriate timeout queue. */ - for (ifq = ips_tqtqb + IPF_TCPS_CLOSE_WAIT; ifq != NULL; - ifq = ifq->ifq_next) { + for (ifq = softs->ipf_state_tcptq + IPF_TCPS_CLOSE_WAIT; + ifq != NULL; ifq = ifq->ifq_next) { for (tqn = ifq->ifq_head; ((tqe = tqn) != NULL); ) { tqn = tqe->tqe_next; is = tqe->tqe_parent; if (is->is_p != IPPROTO_TCP) break; - if (fr_delstate(is, ISL_EXPIRE) == 0) + if (ipf_state_del(softc, is, ISL_FLUSH) == 0) removed++; } } @@ -3178,8 +3854,8 @@ int which, proto; /* * Also need to look through the user defined queues. */ - for (ifq = ips_utqe; ifq != NULL; ifq = ifqnext) { - ifqnext = ifq->ifq_next; + for (ifq = softs->ipf_state_usertq; ifq != NULL; + ifq = ifq->ifq_next) { for (tqn = ifq->ifq_head; ((tqe = tqn) != NULL); ) { tqn = tqe->tqe_next; is = tqe->tqe_parent; @@ -3188,7 +3864,8 @@ int which, proto; if ((is->is_state[0] > IPF_TCPS_ESTABLISHED) && (is->is_state[1] > IPF_TCPS_ESTABLISHED)) { - if (fr_delstate(is, ISL_EXPIRE) == 0) + if (ipf_state_del(softc, is, + ISL_FLUSH) == 0) removed++; } } @@ -3198,7 +3875,7 @@ int which, proto; case 2 : break; - /* + /* * Args 5-11 correspond to flushing those particular states * for TCP connections. */ @@ -3209,12 +3886,13 @@ int which, proto; case IPF_TCPS_FIN_WAIT_2 : case IPF_TCPS_TIME_WAIT : case IPF_TCPS_CLOSED : - tqn = ips_tqtqb[which].ifq_head; + SBUMP(ipf_state_stats.iss_flush_queue); + tqn = softs->ipf_state_tcptq[which].ifq_head; while (tqn != NULL) { tqe = tqn; tqn = tqe->tqe_next; is = tqe->tqe_parent; - if (fr_delstate(is, ISL_FLUSH) == 0) + if (ipf_state_del(softc, is, ISL_FLUSH) == 0) removed++; } break; @@ -3223,16 +3901,18 @@ int which, proto; if (which < 30) break; - /* + SBUMP(ipf_state_stats.iss_flush_state); + /* * Take a large arbitrary number to mean the number of seconds * for which which consider to be the maximum value we'll allow * the expiration to be. */ which = IPF_TTLVAL(which); - for (isp = &ips_list; ((is = *isp) != NULL); ) { + for (isp = &softs->ipf_state_list; ((is = *isp) != NULL); ) { if ((proto == 0) || (is->is_v == proto)) { - if (fr_ticks - is->is_touched > which) { - if (fr_delstate(is, ISL_FLUSH) == 0) { + if (softc->ipf_ticks - is->is_touched > which) { + if (ipf_state_del(softc, is, + ISL_FLUSH) == 0) { removed++; continue; } @@ -3248,13 +3928,23 @@ int which, proto; return removed; } + SBUMP(ipf_state_stats.iss_flush_timeout); /* - * Asked to remove inactive entries because the table is full. + * Asked to remove inactive entries because the table is full, try + * again, 3 times, if first attempt failed with a different criteria + * each time. The order tried in must be in decreasing age. + * Another alternative is to implement random drop and drop N entries + * at random until N have been freed up. */ - if (fr_ticks - ips_last_force_flush > IPF_TTLVAL(5)) { - ips_last_force_flush = fr_ticks; - removed = ipf_queueflush(fr_state_flush_entry, ips_tqtqb, - ips_utqe); + if (softc->ipf_ticks - softs->ipf_state_wm_last > + softs->ipf_state_wm_freq) { + removed = ipf_queueflush(softc, ipf_state_flush_entry, + softs->ipf_state_tcptq, + softs->ipf_state_usertq, + &softs->ipf_state_stats.iss_active, + softs->ipf_state_size, + softs->ipf_state_wm_low); + softs->ipf_state_wm_last = softc->ipf_ticks; } SPL_X(s); @@ -3263,29 +3953,33 @@ int which, proto; /* ------------------------------------------------------------------------ */ -/* Function: fr_state_flush_entry */ +/* Function: ipf_state_flush_entry */ /* Returns: int - 0 = entry deleted, else not deleted */ -/* Parameters: entry(I) - pointer to state structure to delete */ +/* Parameters: softc(I) - pointer to soft context main structure */ +/* entry(I) - pointer to state structure to delete */ /* Write Locks: ipf_state */ /* */ /* This function is a stepping stone between ipf_queueflush() and */ -/* fr_delstate(). It is used so we can provide a uniform interface via the */ -/* ipf_queueflush() function. */ +/* ipf_state_del(). It is used so we can provide a uniform interface via */ +/* the ipf_queueflush() function. */ /* ------------------------------------------------------------------------ */ -static int fr_state_flush_entry(entry) -void *entry; +static int +ipf_state_flush_entry(softc, entry) + ipf_main_softc_t *softc; + void *entry; { - return fr_delstate(entry, ISL_FLUSH); -} + return ipf_state_del(softc, entry, ISL_FLUSH); +} /* ------------------------------------------------------------------------ */ -/* Function: fr_tcp_age */ +/* Function: ipf_tcp_age */ /* Returns: int - 1 == state transition made, 0 == no change (rejected) */ -/* Parameters: tq(I) - pointer to timeout queue information */ +/* Parameters: tqe(I) - pointer to timeout queue information */ /* fin(I) - pointer to packet information */ /* tqtab(I) - TCP timeout queue table this is in */ /* flags(I) - flags from state/NAT entry */ +/* ok(I) - can we advance state */ /* */ /* Rewritten by Arjan de Vet , 2000-07-29: */ /* */ @@ -3297,7 +3991,7 @@ void *entry; /* */ /* - store the state of the source in state[0] such that ipfstat */ /* displays the state as source/dest instead of dest/source; the calls */ -/* to fr_tcp_age have been changed accordingly. */ +/* to ipf_tcp_age have been changed accordingly. */ /* */ /* Internal Parameters: */ /* */ @@ -3328,12 +4022,14 @@ void *entry; /* */ /* Locking: it is assumed that the parent of the tqe structure is locked. */ /* ------------------------------------------------------------------------ */ -int fr_tcp_age(tqe, fin, tqtab, flags) -ipftqent_t *tqe; -fr_info_t *fin; -ipftq_t *tqtab; -int flags; +int +ipf_tcp_age(tqe, fin, tqtab, flags, ok) + ipftqent_t *tqe; + fr_info_t *fin; + ipftq_t *tqtab; + int flags, ok; { + ipf_main_softc_t *softc = fin->fin_main_soft; int dlen, ostate, nstate, rval, dir; u_char tcpflags; tcphdr_t *tcp; @@ -3344,17 +4040,20 @@ int flags; dir = fin->fin_rev; tcpflags = tcp->th_flags; dlen = fin->fin_dlen - (TCP_OFF(tcp) << 2); + ostate = tqe->tqe_state[1 - dir]; + nstate = tqe->tqe_state[dir]; if (tcpflags & TH_RST) { if (!(tcpflags & TH_PUSH) && !dlen) nstate = IPF_TCPS_CLOSED; else nstate = IPF_TCPS_CLOSE_WAIT; + + if (ostate <= IPF_TCPS_ESTABLISHED) { + tqe->tqe_state[1 - dir] = IPF_TCPS_CLOSE_WAIT; + } rval = 1; } else { - ostate = tqe->tqe_state[1 - dir]; - nstate = tqe->tqe_state[dir]; - switch (nstate) { case IPF_TCPS_LISTEN: /* 0 */ @@ -3410,7 +4109,7 @@ int flags; if ((tcpflags & ~(TH_ECN|TH_CWR)) == TH_SYN) { /* * A retransmitted SYN packet. We do not reset - * the timeout here to fr_tcptimeout because a + * the timeout here to ipf_tcptimeout because a * connection connect timeout does not renew * after every packet that is sent. We need to * set rval so as to indicate the packet has @@ -3578,7 +4277,7 @@ int flags; * the FIN packet here? does the window code * guarantee that? */ - nstate = IPF_TCPS_TIME_WAIT; + nstate = IPF_TCPS_LAST_ACK; } else { /* * we closed our side of the connection @@ -3594,25 +4293,18 @@ int flags; if ((tcpflags & (TH_FIN|TH_ACK)) == TH_ACK) { nstate = IPF_TCPS_TIME_WAIT; } - rval = 2; + rval = 1; break; case IPF_TCPS_LAST_ACK: /* 8 */ if (tcpflags & TH_ACK) { - if ((tcpflags & TH_PUSH) || dlen) - /* - * there is still data to be delivered, - * reset timeout - */ - rval = 1; - else - rval = 2; + rval = 1; } /* - * we cannot detect when we go out of LAST_ACK state to - * CLOSED because that is based on the reception of ACK - * packets; ipfilter can only detect that a packet - * has been sent by a host + * we cannot detect when we go out of LAST_ACK state + * to CLOSED because that is based on the reception + * of ACK packets; ipfilter can only detect that a + * packet has been sent by a host */ break; @@ -3624,8 +4316,10 @@ int flags; /* we're in 2MSL timeout now */ if (ostate == IPF_TCPS_LAST_ACK) { nstate = IPF_TCPS_CLOSED; + rval = 1; + } else { + rval = 2; } - rval = 1; break; case IPF_TCPS_CLOSED: /* 11 */ @@ -3633,18 +4327,7 @@ int flags; break; default : -#if defined(_KERNEL) -# if SOLARIS - cmn_err(CE_NOTE, - "tcp %lx flags %x si %lx nstate %d ostate %d\n", - (u_long)tcp, tcpflags, (u_long)tqe, - nstate, ostate); -# else - printf("tcp %lx flags %x si %lx nstate %d ostate %d\n", - (u_long)tcp, tcpflags, (u_long)tqe, - nstate, ostate); -# endif -#else +#if !defined(_KERNEL) abort(); #endif break; @@ -3658,9 +4341,11 @@ int flags; if (rval == 2) rval = 1; else if (rval == 1) { - tqe->tqe_state[dir] = nstate; + if (ok) + tqe->tqe_state[dir] = nstate; if ((tqe->tqe_flags & TQE_RULEBASED) == 0) - fr_movequeue(tqe, tqe->tqe_ifq, tqtab + nstate); + ipf_movequeue(softc->ipf_ticks, tqe, tqe->tqe_ifq, + tqtab + nstate); } return rval; @@ -3668,18 +4353,21 @@ int flags; /* ------------------------------------------------------------------------ */ -/* Function: ipstate_log */ +/* Function: ipf_state_log */ /* Returns: Nil */ -/* Parameters: is(I) - pointer to state structure */ -/* type(I) - type of log entry to create */ +/* Parameters: softc(I) - pointer to soft context main structure */ +/* is(I) - pointer to state structure */ +/* type(I) - type of log entry to create */ /* */ /* Creates a state table log entry using the state structure and type info. */ /* passed in. Log packet/byte counts, source/destination address and other */ /* protocol specific information. */ /* ------------------------------------------------------------------------ */ -void ipstate_log(is, type) -struct ipstate *is; -u_int type; +void +ipf_state_log(softc, is, type) + ipf_main_softc_t *softc; + struct ipstate *is; + u_int type; { #ifdef IPFILTER_LOG struct ipslog ipsl; @@ -3729,18 +4417,14 @@ u_int type; sizes[0] = sizeof(ipsl); types[0] = 0; - if (ipllog(IPL_LOGSTATE, NULL, items, sizes, types, 1)) { - ATOMIC_INCL(ips_stats.iss_logged); - } else { - ATOMIC_INCL(ips_stats.iss_logfail); - } + (void) ipf_log_items(softc, IPL_LOGSTATE, NULL, items, sizes, types, 1); #endif } #ifdef USE_INET6 /* ------------------------------------------------------------------------ */ -/* Function: fr_checkicmp6matchingstate */ +/* Function: ipf_checkicmp6matchingstate */ /* Returns: ipstate_t* - NULL == no match found, */ /* else pointer to matching state entry */ /* Parameters: fin(I) - pointer to packet information */ @@ -3749,11 +4433,13 @@ u_int type; /* If we've got an ICMPv6 error message, using the information stored in */ /* the ICMPv6 packet, look for a matching state table entry. */ /* ------------------------------------------------------------------------ */ -static ipstate_t *fr_checkicmp6matchingstate(fin) -fr_info_t *fin; +static ipstate_t * +ipf_checkicmp6matchingstate(fin) + fr_info_t *fin; { + ipf_main_softc_t *softc = fin->fin_main_soft; + ipf_state_softc_t *softs = softc->ipf_state_soft; struct icmp6_hdr *ic6, *oic; - int type, backward, i; ipstate_t *is, **isp; u_short sport, dport; i6addr_t dst, src; @@ -3762,8 +4448,9 @@ fr_info_t *fin; fr_info_t ofin; tcphdr_t *tcp; ip6_t *oip6; - u_char pr; + u_char pr; u_int hv; + int type; /* * Does it at least have the return (basic) IP header ? @@ -3772,15 +4459,19 @@ fr_info_t *fin; * an ICMP error header. */ if ((fin->fin_v != 6) || (fin->fin_plen < ICMP6ERR_MINPKTLEN) || - !(fin->fin_flx & FI_ICMPERR)) + !(fin->fin_flx & FI_ICMPERR)) { + SBUMPD(ipf_state_stats, iss_icmp_bad); return NULL; + } ic6 = fin->fin_dp; type = ic6->icmp6_type; oip6 = (ip6_t *)((char *)ic6 + ICMPERR_ICMPHLEN); - if (fin->fin_plen < sizeof(*oip6)) + if (fin->fin_plen < sizeof(*oip6)) { + SBUMPD(ipf_state_stats, iss_icmp_short); return NULL; + } bcopy((char *)fin, (char *)&ofin, sizeof(*fin)); ofin.fin_v = 6; @@ -3794,21 +4485,31 @@ fr_info_t *fin; * matchsrcdst. Note that not all fields are necessary * but this is the cleanest way. Note further we fill * in fin_mp such that if someone uses it we'll get - * a kernel panic. fr_matchsrcdst does not use this. + * a kernel panic. ipf_matchsrcdst does not use this. * * watch out here, as ip is in host order and oip6 in network * order. Any change we make must be undone afterwards. */ savelen = oip6->ip6_plen; - oip6->ip6_plen = fin->fin_dlen - ICMPERR_ICMPHLEN; + oip6->ip6_plen = htons(fin->fin_dlen - ICMPERR_ICMPHLEN); ofin.fin_flx = FI_NOCKSUM; ofin.fin_ip = (ip_t *)oip6; - (void) fr_makefrip(sizeof(*oip6), (ip_t *)oip6, &ofin); + (void) ipf_makefrip(sizeof(*oip6), (ip_t *)oip6, &ofin); ofin.fin_flx &= ~(FI_BAD|FI_SHORT); oip6->ip6_plen = savelen; + pr = ofin.fin_p; + + /* + * an ICMP error can never generate an ICMP error in response. + */ + if (ofin.fin_flx & FI_ICMPERR) { + DT1(iss_icmp6_icmperr, fr_info_t *, &ofin); + SBUMP(ipf_state_stats.iss_icmp6_icmperr); + return NULL; + } if (oip6->ip6_nxt == IPPROTO_ICMPV6) { - oic = (struct icmp6_hdr *)(oip6 + 1); + oic = ofin.fin_dp; /* * an ICMP error can only be generated as a result of an * ICMP query, not as the response on an ICMP error @@ -3816,8 +4517,11 @@ fr_info_t *fin; * XXX theoretically ICMP_ECHOREP and the other reply's are * ICMP query's as well, but adding them here seems strange XXX */ - if (!(oic->icmp6_type & ICMP6_INFOMSG_MASK)) - return NULL; + if (!(oic->icmp6_type & ICMP6_INFOMSG_MASK)) { + DT1(iss_icmp6_notinfo, fr_info_t *, &ofin); + SBUMP(ipf_state_stats.iss_icmp6_notinfo); + return NULL; + } /* * perform a lookup of the ICMP packet in the state table @@ -3831,15 +4535,16 @@ fr_info_t *fin; hv += oic->icmp6_seq; hv = DOUBLE_HASH(hv); - READ_ENTER(&ipf_state); - for (isp = &ips_table[hv]; ((is = *isp) != NULL); ) { + READ_ENTER(&softc->ipf_state); + for (isp = &softs->ipf_state_table[hv]; + ((is = *isp) != NULL); ) { ic = &is->is_icmp; isp = &is->is_hnext; if ((is->is_p == pr) && !(is->is_pass & FR_NOICMPERR) && (oic->icmp6_id == ic->ici_id) && (oic->icmp6_seq == ic->ici_seq) && - (is = fr_matchsrcdst(&ofin, is, &src, + (is = ipf_matchsrcdst(&ofin, is, &src, &dst, NULL, FI_ICMPCMP))) { /* * in the state table ICMP query's are stored @@ -3849,16 +4554,13 @@ fr_info_t *fin; if (((ic->ici_type == ICMP6_ECHO_REPLY) && (oic->icmp6_type == ICMP6_ECHO_REQUEST)) || (ic->ici_type - 1 == oic->icmp6_type )) { - ips_stats.iss_hits++; - backward = IP6_NEQ(&is->is_dst, &src); - fin->fin_rev = !backward; - i = (backward << 1) + fin->fin_out; - is->is_icmppkts[i]++; - return is; + if (!ipf_allowstateicmp(fin, is, &src)) + return is; } } } - RWLOCK_EXIT(&ipf_state); + RWLOCK_EXIT(&softc->ipf_state); + SBUMPD(ipf_state_stats, iss_icmp6_miss); return NULL; } @@ -3874,18 +4576,33 @@ fr_info_t *fin; hv += dst.i6[2]; hv += dst.i6[3]; - if ((oip6->ip6_nxt == IPPROTO_TCP) || (oip6->ip6_nxt == IPPROTO_UDP)) { + tcp = NULL; + + switch (oip6->ip6_nxt) + { + case IPPROTO_TCP : + case IPPROTO_UDP : tcp = (tcphdr_t *)(oip6 + 1); dport = tcp->th_dport; sport = tcp->th_sport; hv += dport; hv += sport; - } else - tcp = NULL; + break; + + case IPPROTO_ICMPV6 : + oic = (struct icmp6_hdr *)(oip6 + 1); + hv += oic->icmp6_id; + hv += oic->icmp6_seq; + break; + + default : + break; + } + hv = DOUBLE_HASH(hv); - READ_ENTER(&ipf_state); - for (isp = &ips_table[hv]; ((is = *isp) != NULL); ) { + READ_ENTER(&softc->ipf_state); + for (isp = &softs->ipf_state_table[hv]; ((is = *isp) != NULL); ) { isp = &is->is_hnext; /* * Only allow this icmp though if the @@ -3897,73 +4614,63 @@ fr_info_t *fin; if ((is->is_p != pr) || (is->is_v != 6) || (is->is_pass & FR_NOICMPERR)) continue; - is = fr_matchsrcdst(&ofin, is, &src, &dst, tcp, FI_ICMPCMP); - if (is != NULL) { - ips_stats.iss_hits++; - backward = IP6_NEQ(&is->is_dst, &src); - fin->fin_rev = !backward; - i = (backward << 1) + fin->fin_out; - is->is_icmppkts[i]++; - /* - * we deliberately do not touch the timeouts - * for the accompanying state table entry. - * It remains to be seen if that is correct. XXX - */ + is = ipf_matchsrcdst(&ofin, is, &src, &dst, tcp, FI_ICMPCMP); + if ((is != NULL) && (ipf_allowstateicmp(fin, is, &src) == 0)) return is; - } } - RWLOCK_EXIT(&ipf_state); + RWLOCK_EXIT(&softc->ipf_state); + SBUMPD(ipf_state_stats, iss_icmp_miss); return NULL; } #endif /* ------------------------------------------------------------------------ */ -/* Function: fr_sttab_init */ +/* Function: ipf_sttab_init */ /* Returns: Nil */ -/* Parameters: tqp(I) - pointer to an array of timeout queues for TCP */ +/* Parameters: softc(I) - pointer to soft context main structure */ +/* tqp(I) - pointer to an array of timeout queues for TCP */ /* */ /* Initialise the array of timeout queues for TCP. */ /* ------------------------------------------------------------------------ */ -void fr_sttab_init(tqp) -ipftq_t *tqp; +void +ipf_sttab_init(softc, tqp) + ipf_main_softc_t *softc; + ipftq_t *tqp; { int i; for (i = IPF_TCP_NSTATES - 1; i >= 0; i--) { - tqp[i].ifq_ttl = 0; - tqp[i].ifq_ref = 1; - tqp[i].ifq_head = NULL; - tqp[i].ifq_tail = &tqp[i].ifq_head; + IPFTQ_INIT(&tqp[i], 0, "ipftq tcp tab"); tqp[i].ifq_next = tqp + i + 1; - MUTEX_INIT(&tqp[i].ifq_lock, "ipftq tcp tab"); } tqp[IPF_TCP_NSTATES - 1].ifq_next = NULL; - tqp[IPF_TCPS_CLOSED].ifq_ttl = fr_tcpclosed; - tqp[IPF_TCPS_LISTEN].ifq_ttl = fr_tcptimeout; - tqp[IPF_TCPS_SYN_SENT].ifq_ttl = fr_tcptimeout; - tqp[IPF_TCPS_SYN_RECEIVED].ifq_ttl = fr_tcptimeout; - tqp[IPF_TCPS_ESTABLISHED].ifq_ttl = fr_tcpidletimeout; - tqp[IPF_TCPS_CLOSE_WAIT].ifq_ttl = fr_tcphalfclosed; - tqp[IPF_TCPS_FIN_WAIT_1].ifq_ttl = fr_tcphalfclosed; - tqp[IPF_TCPS_CLOSING].ifq_ttl = fr_tcptimeout; - tqp[IPF_TCPS_LAST_ACK].ifq_ttl = fr_tcplastack; - tqp[IPF_TCPS_FIN_WAIT_2].ifq_ttl = fr_tcpclosewait; - tqp[IPF_TCPS_TIME_WAIT].ifq_ttl = fr_tcptimewait; - tqp[IPF_TCPS_HALF_ESTAB].ifq_ttl = fr_tcptimeout; + tqp[IPF_TCPS_CLOSED].ifq_ttl = softc->ipf_tcpclosed; + tqp[IPF_TCPS_LISTEN].ifq_ttl = softc->ipf_tcptimeout; + tqp[IPF_TCPS_SYN_SENT].ifq_ttl = softc->ipf_tcpsynsent; + tqp[IPF_TCPS_SYN_RECEIVED].ifq_ttl = softc->ipf_tcpsynrecv; + tqp[IPF_TCPS_ESTABLISHED].ifq_ttl = softc->ipf_tcpidletimeout; + tqp[IPF_TCPS_CLOSE_WAIT].ifq_ttl = softc->ipf_tcphalfclosed; + tqp[IPF_TCPS_FIN_WAIT_1].ifq_ttl = softc->ipf_tcphalfclosed; + tqp[IPF_TCPS_CLOSING].ifq_ttl = softc->ipf_tcptimeout; + tqp[IPF_TCPS_LAST_ACK].ifq_ttl = softc->ipf_tcplastack; + tqp[IPF_TCPS_FIN_WAIT_2].ifq_ttl = softc->ipf_tcpclosewait; + tqp[IPF_TCPS_TIME_WAIT].ifq_ttl = softc->ipf_tcptimewait; + tqp[IPF_TCPS_HALF_ESTAB].ifq_ttl = softc->ipf_tcptimeout; } /* ------------------------------------------------------------------------ */ -/* Function: fr_sttab_destroy */ +/* Function: ipf_sttab_destroy */ /* Returns: Nil */ /* Parameters: tqp(I) - pointer to an array of timeout queues for TCP */ /* */ /* Do whatever is necessary to "destroy" each of the entries in the array */ /* of timeout queues for TCP. */ /* ------------------------------------------------------------------------ */ -void fr_sttab_destroy(tqp) -ipftq_t *tqp; +void +ipf_sttab_destroy(tqp) + ipftq_t *tqp; { int i; @@ -3973,9 +4680,10 @@ ipftq_t *tqp; /* ------------------------------------------------------------------------ */ -/* Function: fr_statederef */ +/* Function: ipf_state_deref */ /* Returns: Nil */ -/* Parameters: isp(I) - pointer to pointer to state table entry */ +/* Parameters: softc(I) - pointer to soft context main structure */ +/* isp(I) - pointer to pointer to state table entry */ /* */ /* Decrement the reference counter for this state table entry and free it */ /* if there are no more things using it. */ @@ -4003,10 +4711,12 @@ ipftq_t *tqp; /* dir == 0 : a packet from source to dest */ /* dir == 1 : a packet from dest to source */ /* ------------------------------------------------------------------------ */ -void fr_statederef(isp) -ipstate_t **isp; +void +ipf_state_deref(softc, isp) + ipf_main_softc_t *softc; + ipstate_t **isp; { - ipstate_t *is; + ipstate_t *is = *isp; is = *isp; *isp = NULL; @@ -4017,37 +4727,40 @@ ipstate_t **isp; MUTEX_EXIT(&is->is_lock); #ifndef _KERNEL if ((is->is_sti.tqe_state[0] > IPF_TCPS_ESTABLISHED) || - (is->is_sti.tqe_state[1] > IPF_TCPS_ESTABLISHED)) { - fr_delstate(is, ISL_ORPHAN); + (is->is_sti.tqe_state[1] > IPF_TCPS_ESTABLISHED)) { + ipf_state_del(softc, is, ISL_EXPIRE); } #endif return; } MUTEX_EXIT(&is->is_lock); - WRITE_ENTER(&ipf_state); - fr_delstate(is, ISL_EXPIRE); - RWLOCK_EXIT(&ipf_state); + WRITE_ENTER(&softc->ipf_state); + ipf_state_del(softc, is, ISL_ORPHAN); + RWLOCK_EXIT(&softc->ipf_state); } /* ------------------------------------------------------------------------ */ -/* Function: fr_setstatequeue */ +/* Function: ipf_state_setqueue */ /* Returns: Nil */ -/* Parameters: is(I) - pointer to state structure */ -/* rev(I) - forward(0) or reverse(1) direction */ +/* Parameters: softc(I) - pointer to soft context main structure */ +/* is(I) - pointer to state structure */ +/* rev(I) - forward(0) or reverse(1) direction */ /* Locks: ipf_state (read or write) */ /* */ /* Put the state entry on its default queue entry, using rev as a helped in */ /* determining which queue it should be placed on. */ /* ------------------------------------------------------------------------ */ -void fr_setstatequeue(is, rev) -ipstate_t *is; -int rev; +void +ipf_state_setqueue(softc, is, rev) + ipf_main_softc_t *softc; + ipstate_t *is; + int rev; { + ipf_state_softc_t *softs = softc->ipf_state_soft; ipftq_t *oifq, *nifq; - if ((is->is_sti.tqe_flags & TQE_RULEBASED) != 0) nifq = is->is_tqehead[rev]; else @@ -4059,30 +4772,30 @@ int rev; #ifdef USE_INET6 case IPPROTO_ICMPV6 : if (rev == 1) - nifq = &ips_icmpacktq; + nifq = &softs->ipf_state_icmpacktq; else - nifq = &ips_icmptq; + nifq = &softs->ipf_state_icmptq; break; #endif case IPPROTO_ICMP : if (rev == 1) - nifq = &ips_icmpacktq; + nifq = &softs->ipf_state_icmpacktq; else - nifq = &ips_icmptq; + nifq = &softs->ipf_state_icmptq; break; case IPPROTO_TCP : - nifq = ips_tqtqb + is->is_state[rev]; + nifq = softs->ipf_state_tcptq + is->is_state[rev]; break; case IPPROTO_UDP : if (rev == 1) - nifq = &ips_udpacktq; + nifq = &softs->ipf_state_udpacktq; else - nifq = &ips_udptq; + nifq = &softs->ipf_state_udptq; break; default : - nifq = &ips_iptq; + nifq = &softs->ipf_state_iptq; break; } } @@ -4093,126 +4806,560 @@ int rev; * another, else put it on the end of the newly determined queue. */ if (oifq != NULL) - fr_movequeue(&is->is_sti, oifq, nifq); + ipf_movequeue(softc->ipf_ticks, &is->is_sti, oifq, nifq); else - fr_queueappend(&is->is_sti, nifq, is); + ipf_queueappend(softc->ipf_ticks, &is->is_sti, nifq, is); return; } /* ------------------------------------------------------------------------ */ -/* Function: fr_stateiter */ +/* Function: ipf_state_iter */ /* Returns: int - 0 == success, else error */ -/* Parameters: token(I) - pointer to ipftoken structure */ +/* Parameters: softc(I) - pointer to main soft context */ +/* token(I) - pointer to ipftoken structure */ /* itp(I) - pointer to ipfgeniter structure */ +/* obj(I) - pointer to data description structure */ /* */ /* This function handles the SIOCGENITER ioctl for the state tables and */ -/* walks through the list of entries in the state table list (ips_list.) */ +/* walks through the list of entries in the state table list (softs->ipf_state_list.) */ /* ------------------------------------------------------------------------ */ -static int fr_stateiter(token, itp) -ipftoken_t *token; -ipfgeniter_t *itp; +static int +ipf_state_iter(softc, token, itp, obj) + ipf_main_softc_t *softc; + ipftoken_t *token; + ipfgeniter_t *itp; + ipfobj_t *obj; { + ipf_state_softc_t *softs = softc->ipf_state_soft; ipstate_t *is, *next, zero; - int error, count; - char *dst; + int error; - if (itp->igi_data == NULL) + if (itp->igi_data == NULL) { + IPFERROR(100026); return EFAULT; + } - if (itp->igi_nitems < 1) + if (itp->igi_nitems < 1) { + IPFERROR(100027); return ENOSPC; + } - if (itp->igi_type != IPFGENITER_STATE) + if (itp->igi_type != IPFGENITER_STATE) { + IPFERROR(100028); return EINVAL; + } is = token->ipt_data; if (is == (void *)-1) { - ipf_freetoken(token); + IPFERROR(100029); return ESRCH; } error = 0; - dst = itp->igi_data; + obj->ipfo_type = IPFOBJ_IPSTATE; + obj->ipfo_size = sizeof(ipstate_t); - READ_ENTER(&ipf_state); + READ_ENTER(&softc->ipf_state); + + is = token->ipt_data; if (is == NULL) { - next = ips_list; + next = softs->ipf_state_list; } else { next = is->is_next; } - count = itp->igi_nitems; - for (;;) { - if (next != NULL) { - /* - * If we find a state entry to use, bump its - * reference count so that it can be used for - * is_next when we come back. - */ - if (count == 1) { - MUTEX_ENTER(&next->is_lock); - next->is_ref++; - MUTEX_EXIT(&next->is_lock); - token->ipt_data = next; - } - } else { - bzero(&zero, sizeof(zero)); - next = &zero; - count = 1; - token->ipt_data = NULL; - } - RWLOCK_EXIT(&ipf_state); - - /* - * This should arguably be via fr_outobj() so that the state - * structure can (if required) be massaged going out. - */ - error = COPYOUT(next, dst, sizeof(*next)); - if (error != 0) - error = EFAULT; - if ((count == 1) || (error != 0)) - break; - - dst += sizeof(*next); - count--; - - READ_ENTER(&ipf_state); - next = next->is_next; + /* + * If we find a state entry to use, bump its reference count so that + * it can be used for is_next when we come back. + */ + if (next != NULL) { + MUTEX_ENTER(&next->is_lock); + next->is_ref++; + MUTEX_EXIT(&next->is_lock); + token->ipt_data = next; + } else { + bzero(&zero, sizeof(zero)); + next = &zero; + token->ipt_data = NULL; } + if (next->is_next == NULL) + ipf_token_mark_complete(token); - if (is != NULL) { - fr_statederef(&is); - } + RWLOCK_EXIT(&softc->ipf_state); + + obj->ipfo_ptr = itp->igi_data; + error = ipf_outobjk(softc, obj, next); + if (is != NULL) + ipf_state_deref(softc, &is); return error; } /* ------------------------------------------------------------------------ */ -/* Function: fr_stgettable */ +/* Function: ipf_state_gettable */ /* Returns: int - 0 = success, else error */ -/* Parameters: data(I) - pointer to ioctl data */ +/* Parameters: softc(I) - pointer to main soft context */ +/* softs(I) - pointer to state context structure */ +/* data(I) - pointer to ioctl data */ /* */ /* This function handles ioctl requests for tables of state information. */ /* At present the only table it deals with is the hash bucket statistics. */ /* ------------------------------------------------------------------------ */ -static int fr_stgettable(data) -char *data; +static int +ipf_state_gettable(softc, softs, data) + ipf_main_softc_t *softc; + ipf_state_softc_t *softs; + char *data; { ipftable_t table; int error; - error = fr_inobj(data, &table, IPFOBJ_GTABLE); + error = ipf_inobj(softc, data, NULL, &table, IPFOBJ_GTABLE); if (error != 0) return error; - if (table.ita_type != IPFTABLE_BUCKETS) + if (table.ita_type != IPFTABLE_BUCKETS) { + IPFERROR(100031); return EINVAL; + } - error = COPYOUT(ips_stats.iss_bucketlen, table.ita_table, - fr_statesize * sizeof(u_long)); - if (error != 0) + error = COPYOUT(softs->ipf_state_stats.iss_bucketlen, table.ita_table, + softs->ipf_state_size * sizeof(u_int)); + if (error != 0) { + IPFERROR(100032); error = EFAULT; + } return error; } + + +/* ------------------------------------------------------------------------ */ +/* Function: ipf_state_setpending */ +/* Returns: Nil */ +/* Parameters: softc(I) - pointer to main soft context */ +/* is(I) - pointer to state structure */ +/* Locks: ipf_state (read or write) */ +/* */ +/* Put the state entry on to the pending queue - this queue has a very */ +/* short lifetime where items are put that can't be deleted straight away */ +/* because of locking issues but we want to delete them ASAP, anyway. */ +/* ------------------------------------------------------------------------ */ +void +ipf_state_setpending(softc, is) + ipf_main_softc_t *softc; + ipstate_t *is; +{ + ipf_state_softc_t *softs = softc->ipf_state_soft; + ipftq_t *oifq; + + oifq = is->is_sti.tqe_ifq; + if (oifq != NULL) + ipf_movequeue(softc->ipf_ticks, &is->is_sti, oifq, + &softs->ipf_state_pending); + else + ipf_queueappend(softc->ipf_ticks, &is->is_sti, + &softs->ipf_state_pending, is); + + MUTEX_ENTER(&is->is_lock); + if (is->is_me != NULL) { + *is->is_me = NULL; + is->is_me = NULL; + is->is_ref--; + } + MUTEX_EXIT(&is->is_lock); +} + + +/* ------------------------------------------------------------------------ */ +/* Function: ipf_state_matchflush */ +/* Returns: Nil */ +/* Parameters: softc(I) - pointer to main soft context */ +/* data(I) - pointer to state structure */ +/* Locks: ipf_state (read or write) */ +/* */ +/* Flush all entries from the list of state entries that match the */ +/* properties in the array loaded. */ +/* ------------------------------------------------------------------------ */ +int +ipf_state_matchflush(softc, data) + ipf_main_softc_t *softc; + caddr_t data; +{ + ipf_state_softc_t *softs = softc->ipf_state_soft; + int *array, flushed, error; + ipstate_t *state, *statenext; + ipfobj_t obj; + + error = ipf_matcharray_load(softc, data, &obj, &array); + if (error != 0) + return error; + + flushed = 0; + + for (state = softs->ipf_state_list; state != NULL; state = statenext) { + statenext = state->is_next; + if (ipf_state_matcharray(state, array, softc->ipf_ticks) == 0) { + ipf_state_del(softc, state, ISL_FLUSH); + flushed++; + } + } + + obj.ipfo_retval = flushed; + error = BCOPYOUT(&obj, data, sizeof(obj)); + + KFREES(array, array[0] * sizeof(*array)); + + return error; +} + + +/* ------------------------------------------------------------------------ */ +/* Function: ipf_state_matcharray */ +/* Returns: int - 0 = no match, 1 = match */ +/* Parameters: state(I) - pointer to state structure */ +/* array(I) - pointer to ipf matching expression */ +/* ticks(I) - current value of ipfilter tick timer */ +/* Locks: ipf_state (read or write) */ +/* */ +/* Compare a state entry with the match array passed in and return a value */ +/* to indicate whether or not the matching was successful. */ +/* ------------------------------------------------------------------------ */ +static int +ipf_state_matcharray(state, array, ticks) + ipstate_t *state; + int *array; + u_long ticks; +{ + int i, n, *x, rv, p; + ipfexp_t *e; + + rv = 0; + n = array[0]; + x = array + 1; + + for (; n > 0; x += 3 + x[3], rv = 0) { + e = (ipfexp_t *)x; + n -= e->ipfe_size; + if (x[0] == IPF_EXP_END) + break; + + /* + * If we need to match the protocol and that doesn't match, + * don't even both with the instruction array. + */ + p = e->ipfe_cmd >> 16; + if ((p != 0) && (p != state->is_p)) + break; + + switch (e->ipfe_cmd) + { + case IPF_EXP_IP_PR : + for (i = 0; !rv && i < e->ipfe_narg; i++) { + rv |= (state->is_p == e->ipfe_arg0[i]); + } + break; + + case IPF_EXP_IP_SRCADDR : + if (state->is_v != 4) + break; + for (i = 0; !rv && i < e->ipfe_narg; i++) { + rv |= ((state->is_saddr & + e->ipfe_arg0[i * 2 + 1]) == + e->ipfe_arg0[i * 2]); + } + break; + + case IPF_EXP_IP_DSTADDR : + if (state->is_v != 4) + break; + for (i = 0; !rv && i < e->ipfe_narg; i++) { + rv |= ((state->is_daddr & + e->ipfe_arg0[i * 2 + 1]) == + e->ipfe_arg0[i * 2]); + } + break; + + case IPF_EXP_IP_ADDR : + if (state->is_v != 4) + break; + for (i = 0; !rv && i < e->ipfe_narg; i++) { + rv |= ((state->is_saddr & + e->ipfe_arg0[i * 2 + 1]) == + e->ipfe_arg0[i * 2]) || + ((state->is_daddr & + e->ipfe_arg0[i * 2 + 1]) == + e->ipfe_arg0[i * 2]); + } + break; + +#ifdef USE_INET6 + case IPF_EXP_IP6_SRCADDR : + if (state->is_v != 6) + break; + for (i = 0; !rv && i < x[3]; i++) { + rv |= IP6_MASKEQ(&state->is_src.in6, + &e->ipfe_arg0[i * 8 + 4], + &e->ipfe_arg0[i * 8]); + } + break; + + case IPF_EXP_IP6_DSTADDR : + if (state->is_v != 6) + break; + for (i = 0; !rv && i < x[3]; i++) { + rv |= IP6_MASKEQ(&state->is_dst.in6, + &e->ipfe_arg0[i * 8 + 4], + &e->ipfe_arg0[i * 8]); + } + break; + + case IPF_EXP_IP6_ADDR : + if (state->is_v != 6) + break; + for (i = 0; !rv && i < x[3]; i++) { + rv |= IP6_MASKEQ(&state->is_src.in6, + &e->ipfe_arg0[i * 8 + 4], + &e->ipfe_arg0[i * 8]) || + IP6_MASKEQ(&state->is_dst.in6, + &e->ipfe_arg0[i * 8 + 4], + &e->ipfe_arg0[i * 8]); + } + break; +#endif + + case IPF_EXP_UDP_PORT : + case IPF_EXP_TCP_PORT : + for (i = 0; !rv && i < e->ipfe_narg; i++) { + rv |= (state->is_sport == e->ipfe_arg0[i]) || + (state->is_dport == e->ipfe_arg0[i]); + } + break; + + case IPF_EXP_UDP_SPORT : + case IPF_EXP_TCP_SPORT : + for (i = 0; !rv && i < e->ipfe_narg; i++) { + rv |= (state->is_sport == e->ipfe_arg0[i]); + } + break; + + case IPF_EXP_UDP_DPORT : + case IPF_EXP_TCP_DPORT : + for (i = 0; !rv && i < e->ipfe_narg; i++) { + rv |= (state->is_dport == e->ipfe_arg0[i]); + } + break; + + case IPF_EXP_TCP_STATE : + for (i = 0; !rv && i < e->ipfe_narg; i++) { + rv |= (state->is_state[0] == e->ipfe_arg0[i]) || + (state->is_state[1] == e->ipfe_arg0[i]); + } + break; + + case IPF_EXP_IDLE_GT : + rv |= (ticks - state->is_touched > e->ipfe_arg0[0]); + break; + } + + /* + * Factor in doing a negative match. + */ + rv ^= e->ipfe_not; + + if (rv == 0) + break; + } + + return rv; +} + + +/* ------------------------------------------------------------------------ */ +/* Function: ipf_state_settimeout */ +/* Returns: int 0 = success, else failure */ +/* Parameters: softc(I) - pointer to main soft context */ +/* t(I) - pointer to tuneable being changed */ +/* p(I) - pointer to the new value */ +/* */ +/* Sets a timeout value for one of the many timeout queues. We find the */ +/* correct queue using a somewhat manual process of comparing the timeout */ +/* names for each specific value available and calling ipf_apply_timeout on */ +/* that queue so that all of the items on it are updated accordingly. */ +/* ------------------------------------------------------------------------ */ +int +ipf_state_settimeout(softc, t, p) + struct ipf_main_softc_s *softc; + ipftuneable_t *t; + ipftuneval_t *p; +{ + ipf_state_softc_t *softs = softc->ipf_state_soft; + + /* + * In case there is nothing to do... + */ + if (*t->ipft_pint == p->ipftu_int) + return 0; + + if (!strncmp(t->ipft_name, "tcp_", 4)) + return ipf_settimeout_tcp(t, p, softs->ipf_state_tcptq); + + if (!strcmp(t->ipft_name, "udp_timeout")) { + ipf_apply_timeout(&softs->ipf_state_udptq, p->ipftu_int); + } else if (!strcmp(t->ipft_name, "udp_ack_timeout")) { + ipf_apply_timeout(&softs->ipf_state_udpacktq, p->ipftu_int); + } else if (!strcmp(t->ipft_name, "icmp_timeout")) { + ipf_apply_timeout(&softs->ipf_state_icmptq, p->ipftu_int); + } else if (!strcmp(t->ipft_name, "icmp_ack_timeout")) { + ipf_apply_timeout(&softs->ipf_state_icmpacktq, p->ipftu_int); + } else if (!strcmp(t->ipft_name, "ip_timeout")) { + ipf_apply_timeout(&softs->ipf_state_iptq, p->ipftu_int); + } else { + IPFERROR(100034); + return ESRCH; + } + + /* + * Update the tuneable being set. + */ + *t->ipft_pint = p->ipftu_int; + + return 0; +} + + +/* ------------------------------------------------------------------------ */ +/* Function: ipf_state_rehash */ +/* Returns: int 0 = success, else failure */ +/* Parameters: softc(I) - pointer to main soft context */ +/* t(I) - pointer to tuneable being changed */ +/* p(I) - pointer to the new value */ +/* */ +/* To change the size of the state hash table at runtime, a new table has */ +/* to be allocated and then all of the existing entries put in it, bumping */ +/* up the bucketlength for it as we go along. */ +/* ------------------------------------------------------------------------ */ +int +ipf_state_rehash(softc, t, p) + ipf_main_softc_t *softc; + ipftuneable_t *t; + ipftuneval_t *p; +{ + ipf_state_softc_t *softs = softc->ipf_state_soft; + ipstate_t **newtab, *is; + u_int *bucketlens; + u_int maxbucket; + u_int newsize; + u_int hv; + int i; + + newsize = p->ipftu_int; + /* + * In case there is nothing to do... + */ + if (newsize == softs->ipf_state_size) + return 0; + + KMALLOCS(newtab, ipstate_t **, newsize * sizeof(ipstate_t *)); + if (newtab == NULL) { + IPFERROR(100035); + return ENOMEM; + } + + KMALLOCS(bucketlens, u_int *, newsize * sizeof(u_int)); + if (bucketlens == NULL) { + KFREES(newtab, newsize * sizeof(*softs->ipf_state_table)); + IPFERROR(100036); + return ENOMEM; + } + + for (maxbucket = 0, i = newsize; i > 0; i >>= 1) + maxbucket++; + maxbucket *= 2; + + bzero((char *)newtab, newsize * sizeof(ipstate_t *)); + bzero((char *)bucketlens, newsize * sizeof(u_int)); + + WRITE_ENTER(&softc->ipf_state); + + if (softs->ipf_state_table != NULL) { + KFREES(softs->ipf_state_table, + softs->ipf_state_size * sizeof(*softs->ipf_state_table)); + } + softs->ipf_state_table = newtab; + + if (softs->ipf_state_stats.iss_bucketlen != NULL) { + KFREES(softs->ipf_state_stats.iss_bucketlen, + softs->ipf_state_size * sizeof(u_int)); + } + softs->ipf_state_stats.iss_bucketlen = bucketlens; + softs->ipf_state_maxbucket = maxbucket; + softs->ipf_state_size = newsize; + + /* + * Walk through the entire list of state table entries and put them + * in the new state table, somewhere. Because we have a new table, + * we need to restart the counter of how many chains are in use. + */ + softs->ipf_state_stats.iss_inuse = 0; + for (is = softs->ipf_state_list; is != NULL; is = is->is_next) { + is->is_hnext = NULL; + is->is_phnext = NULL; + hv = is->is_hv % softs->ipf_state_size; + + if (softs->ipf_state_table[hv] != NULL) + softs->ipf_state_table[hv]->is_phnext = &is->is_hnext; + else + softs->ipf_state_stats.iss_inuse++; + is->is_phnext = softs->ipf_state_table + hv; + is->is_hnext = softs->ipf_state_table[hv]; + softs->ipf_state_table[hv] = is; + softs->ipf_state_stats.iss_bucketlen[hv]++; + } + RWLOCK_EXIT(&softc->ipf_state); + + return 0; +} + + +/* ------------------------------------------------------------------------ */ +/* Function: ipf_state_add_tq */ +/* Returns: ipftq_t * - NULL = failure, else pointer to new timeout */ +/* queue */ +/* Parameters: softc(I) - pointer to main soft context */ +/* ttl(I) - pointer to the ttl for the new queue */ +/* */ +/* Request a pointer to a timeout queue that has a ttl as given by the */ +/* value being passed in. The timeout queue is added tot the list of those */ +/* used internally for stateful filtering. */ +/* ------------------------------------------------------------------------ */ +ipftq_t * +ipf_state_add_tq(softc, ttl) + ipf_main_softc_t *softc; + int ttl; +{ + ipf_state_softc_t *softs = softc->ipf_state_soft; + + return ipf_addtimeoutqueue(softc, &softs->ipf_state_usertq, ttl); +} + + +#ifndef _KERNEL +/* + * Display the built up state table rules and mapping entries. + */ +void +ipf_state_dump(softc, arg) + ipf_main_softc_t *softc; + void *arg; +{ + ipf_state_softc_t *softs = arg; + ipstate_t *ips; + + printf("List of active state sessions:\n"); + for (ips = softs->ipf_state_list; ips != NULL; ) + ips = printstate(ips, opts & (OPT_DEBUG|OPT_VERBOSE), + softc->ipf_ticks); +} +#endif diff --git a/sys/contrib/ipfilter/netinet/ip_state.h b/sys/contrib/ipfilter/netinet/ip_state.h index 9c4e8149d7fc..e765ac771538 100644 --- a/sys/contrib/ipfilter/netinet/ip_state.h +++ b/sys/contrib/ipfilter/netinet/ip_state.h @@ -1,7 +1,7 @@ /* $FreeBSD$ */ /* - * Copyright (C) 1995-2001 by Darren Reed. + * Copyright (C) 2012 by Darren Reed. * * See the IPFILTER.LICENCE file for details on licencing. * @@ -27,8 +27,10 @@ struct ipscan; # define IPSTATE_MAX 4013 /* Maximum number of states held */ #endif -#define SEQ_GE(a,b) ((int)((a) - (b)) >= 0) -#define SEQ_GT(a,b) ((int)((a) - (b)) > 0) +#define PAIRS(s1,d1,s2,d2) ((((s1) == (s2)) && ((d1) == (d2))) ||\ + (((s1) == (d2)) && ((d1) == (s2)))) +#define IPPAIR(s1,d1,s2,d2) PAIRS((s1).s_addr, (d1).s_addr, \ + (s2).s_addr, (d2).s_addr) typedef struct ipstate { @@ -56,6 +58,7 @@ typedef struct ipstate { u_int is_pass; u_char is_p; /* Protocol */ u_char is_v; + int is_family; u_32_t is_hv; u_32_t is_tag; u_32_t is_opt[2]; /* packet options set */ @@ -75,6 +78,8 @@ typedef struct ipstate { u_32_t is_rulen; /* rule number when created */ u_32_t is_s0[2]; u_short is_smsk[2]; + frdest_t is_dif; + frdest_t is_tifs[2]; char is_group[FR_GROUPLEN]; char is_sbuf[2][16]; char is_ifname[4][LIFNAMSIZ]; @@ -87,7 +92,6 @@ typedef struct ipstate { #define is_daddr is_dst.in4.s_addr #define is_icmp is_ps.is_ics #define is_type is_icmp.ici_type -#define is_code is_icmp.ici_code #define is_tcp is_ps.is_ts #define is_udp is_ps.is_us #define is_send is_tcp.ts_data[0].td_end @@ -119,6 +123,7 @@ typedef struct ipstate { #define IS_ISNSYN 0x40000 #define IS_ISNACK 0x80000 #define IS_STATESYNC 0x100000 +#define IS_LOOSE 0x200000 /* * IS_SC flags are for scan-operations that need to be recognised in state. */ @@ -130,7 +135,7 @@ typedef struct ipstate { #define IS_SC_ALL (IS_SC_MATCHC|IS_SC_MATCHC|IS_SC_CLIENT|IS_SC_SERVER) /* - * Flags that can be passed into fr_addstate + * Flags that can be passed into ipf_addstate */ #define IS_INHERITED 0x0fffff00 @@ -181,6 +186,7 @@ typedef struct ipslog { #define ISL_NEW 0 #define ISL_CLONE 1 +#define ISL_STATECHANGE 2 #define ISL_EXPIRE 0xffff #define ISL_FLUSH 0xfffe #define ISL_REMOVE 0xfffd @@ -191,71 +197,141 @@ typedef struct ipslog { typedef struct ips_stat { - u_long iss_hits; - u_long iss_miss; - u_long iss_max; - u_long iss_maxref; - u_long iss_tcp; - u_long iss_udp; - u_long iss_icmp; - u_long iss_nomem; + u_int iss_active; + u_int iss_active_proto[256]; + u_long iss_add_bad; + u_long iss_add_dup; + u_long iss_add_locked; + u_long iss_add_oow; + u_long iss_bucket_full; + u_long iss_check_bad; + u_long iss_check_miss; + u_long iss_check_nattag; + u_long iss_check_notag; + u_long iss_clone_nomem; + u_long iss_cloned; u_long iss_expire; u_long iss_fin; - u_long iss_active; - u_long iss_logged; - u_long iss_logfail; - u_long iss_inuse; - u_long iss_wild; - u_long iss_killed; - u_long iss_ticks; - u_long iss_bucketfull; - int iss_statesize; - int iss_statemax; - ipstate_t **iss_table; + u_long iss_flush_all; + u_long iss_flush_closing; + u_long iss_flush_queue; + u_long iss_flush_state; + u_long iss_flush_timeout; + u_long iss_hits; + u_long iss_icmp6_icmperr; + u_long iss_icmp6_miss; + u_long iss_icmp6_notinfo; + u_long iss_icmp6_notquery; + u_long iss_icmp_bad; + u_long iss_icmp_banned; + u_long iss_icmp_headblock; + u_long iss_icmp_hits; + u_long iss_icmp_icmperr; + u_long iss_icmp_miss; + u_long iss_icmp_notquery; + u_long iss_icmp_short; + u_long iss_icmp_toomany; + u_int iss_inuse; ipstate_t *iss_list; - u_long *iss_bucketlen; + u_long iss_log_fail; + u_long iss_log_ok; + u_long iss_lookup_badifp; + u_long iss_lookup_badport; + u_long iss_lookup_miss; + u_long iss_max; + u_long iss_max_ref; + u_long iss_max_track; + u_long iss_miss_mask; + u_long iss_nomem; + u_long iss_oow; + u_long iss_orphan; + u_long iss_proto[256]; + u_long iss_scan_block; + u_long iss_state_max; + u_long iss_state_size; + u_long iss_states[IPF_TCP_NSTATES]; + ipstate_t **iss_table; + u_long iss_tcp_closing; + u_long iss_tcp_oow; + u_long iss_tcp_rstadd; + u_long iss_tcp_toosmall; + u_long iss_tcp_badopt; + u_long iss_tcp_fsm; + u_long iss_tcp_strict; ipftq_t *iss_tcptab; + u_int iss_ticks; + u_long iss_wild; + u_long iss_winsack; + u_int *iss_bucketlen; } ips_stat_t; -extern u_long fr_tcpidletimeout; -extern u_long fr_tcpclosewait; -extern u_long fr_tcplastack; -extern u_long fr_tcptimeout; -extern u_long fr_tcpclosed; -extern u_long fr_tcphalfclosed; -extern u_long fr_udptimeout; -extern u_long fr_udpacktimeout; -extern u_long fr_icmptimeout; -extern u_long fr_icmpacktimeout; -extern u_long fr_iptimeout; -extern int fr_statemax; -extern int fr_statesize; -extern int fr_state_lock; -extern int fr_state_maxbucket; -extern int fr_state_maxbucket_reset; -extern ipstate_t *ips_list; -extern ipftq_t *ips_utqe; -extern ipftq_t ips_tqtqb[IPF_TCP_NSTATES]; +typedef struct ipf_state_softc_s { + ipfmutex_t ipf_stinsert; + int ipf_state_logging; + int ipf_state_lock; + int ipf_state_doflush; + u_int ipf_state_inited; + u_int ipf_state_max; + u_int ipf_state_maxbucket; + u_int ipf_state_size; + u_int ipf_state_wm_freq; + u_int ipf_state_wm_high; + u_int ipf_state_wm_low; + u_int ipf_state_wm_last; + u_long *ipf_state_seed; + ipstate_t *ipf_state_list; + ipstate_t **ipf_state_table; + ipftuneable_t *ipf_state_tune; + ipftq_t *ipf_state_usertq; + ipftq_t ipf_state_pending; + ipftq_t ipf_state_deletetq; + ipftq_t ipf_state_udptq; + ipftq_t ipf_state_udpacktq; + ipftq_t ipf_state_iptq; + ipftq_t ipf_state_icmptq; + ipftq_t ipf_state_icmpacktq; + ipftq_t ipf_state_tcptq[IPF_TCP_NSTATES]; + ips_stat_t ipf_state_stats; +} ipf_state_softc_t; -extern int fr_stateinit __P((void)); -extern ipstate_t *fr_addstate __P((fr_info_t *, ipstate_t **, u_int)); -extern frentry_t *fr_checkstate __P((struct fr_info *, u_32_t *)); -extern ipstate_t *fr_stlookup __P((fr_info_t *, tcphdr_t *, ipftq_t **)); -extern void fr_statesync __P((void *)); -extern void fr_timeoutstate __P((void)); -extern int fr_tcp_age __P((struct ipftqent *, struct fr_info *, - struct ipftq *, int)); -extern int fr_tcpinwindow __P((struct fr_info *, struct tcpdata *, + +#ifndef _KERNEL +extern void ipf_state_dump __P((ipf_main_softc_t *, void *)); +#endif +extern int ipf_tcp_age __P((struct ipftqent *, struct fr_info *, + struct ipftq *, int, int)); +extern int ipf_tcpinwindow __P((struct fr_info *, struct tcpdata *, struct tcpdata *, tcphdr_t *, int)); -extern void fr_stateunload __P((void)); -extern void ipstate_log __P((struct ipstate *, u_int)); -extern int fr_state_ioctl __P((caddr_t, ioctlcmd_t, int, int, void *)); -extern void fr_stinsert __P((struct ipstate *, int)); -extern void fr_sttab_init __P((struct ipftq *)); -extern void fr_sttab_destroy __P((struct ipftq *)); -extern void fr_updatestate __P((fr_info_t *, ipstate_t *, ipftq_t *)); -extern void fr_statederef __P((ipstate_t **)); -extern void fr_setstatequeue __P((ipstate_t *, int)); + +extern int ipf_state_add __P((ipf_main_softc_t *, fr_info_t *, + ipstate_t **, u_int)); +extern frentry_t *ipf_state_check __P((struct fr_info *, u_32_t *)); +extern void ipf_state_deref __P((ipf_main_softc_t *, ipstate_t **)); +extern void ipf_state_expire __P((ipf_main_softc_t *)); +extern int ipf_state_flush __P((ipf_main_softc_t *, int, int)); +extern ipstate_t *ipf_state_lookup __P((fr_info_t *, tcphdr_t *, ipftq_t **)); +extern int ipf_state_init __P((void)); +extern int ipf_state_insert __P((ipf_main_softc_t *, struct ipstate *, int)); +extern int ipf_state_ioctl __P((ipf_main_softc_t *, caddr_t, ioctlcmd_t, int, int, void *)); +extern void ipf_state_log __P((ipf_main_softc_t *, struct ipstate *, u_int)); +extern int ipf_state_matchflush __P((ipf_main_softc_t *, caddr_t)); +extern int ipf_state_rehash __P((ipf_main_softc_t *, ipftuneable_t *, ipftuneval_t *)); +extern void ipf_state_setqueue __P((ipf_main_softc_t *, ipstate_t *, int)); +extern void ipf_state_setpending __P((ipf_main_softc_t *, ipstate_t *)); +extern int ipf_state_settimeout __P((struct ipf_main_softc_s *, ipftuneable_t *, ipftuneval_t *)); +extern void ipf_state_sync __P((ipf_main_softc_t *, void *)); +extern void ipf_state_update __P((fr_info_t *, ipstate_t *)); + +extern void ipf_sttab_init __P((ipf_main_softc_t *, struct ipftq *)); +extern void ipf_sttab_destroy __P((struct ipftq *)); +extern void ipf_state_setlock __P((void *, int)); +extern int ipf_state_main_load __P((void)); +extern int ipf_state_main_unload __P((void)); +extern void *ipf_state_soft_create __P((ipf_main_softc_t *)); +extern void ipf_state_soft_destroy __P((ipf_main_softc_t *, void *)); +extern int ipf_state_soft_init __P((ipf_main_softc_t *, void *)); +extern int ipf_state_soft_fini __P((ipf_main_softc_t *, void *)); +extern ipftq_t *ipf_state_add_tq __P((ipf_main_softc_t *, int)); #endif /* __IP_STATE_H__ */ diff --git a/sys/contrib/ipfilter/netinet/ip_sync.c b/sys/contrib/ipfilter/netinet/ip_sync.c index a72f50f34bd4..0c2fe10b3ba3 100644 --- a/sys/contrib/ipfilter/netinet/ip_sync.c +++ b/sys/contrib/ipfilter/netinet/ip_sync.c @@ -1,7 +1,7 @@ /* $FreeBSD$ */ /* - * Copyright (C) 1995-1998 by Darren Reed. + * Copyright (C) 2012 by Darren Reed. * * See the IPFILTER.LICENCE file for details on licencing. */ @@ -32,6 +32,10 @@ struct file; # if !defined(__SVR4) && !defined(__svr4__) # include # endif +# include +# if __FreeBSD_version >= 500000 +# include +# endif #endif #if defined(__NetBSD__) && (__NetBSD_Version__ >= 104000000) # include @@ -39,9 +43,6 @@ struct file; #if defined(_KERNEL) && (__FreeBSD_version >= 220000) # include # include -# if (__FreeBSD_version >= 300000) && !defined(IPFILTER_LKM) -# include "opt_ipfilter.h" -# endif #else # include #endif @@ -64,7 +65,6 @@ struct file; #ifdef sun # include #endif -#include #include #include #include @@ -98,66 +98,219 @@ struct file; /* END OF INCLUDES */ #if !defined(lint) -static const char rcsid[] = "@(#)$Id: ip_sync.c,v 2.40.2.9 2007/06/02 21:22:28 darrenr Exp $"; +static const char rcsid[] = "@(#)$Id$"; #endif #define SYNC_STATETABSZ 256 #define SYNC_NATTABSZ 256 -#ifdef IPFILTER_SYNC -ipfmutex_t ipf_syncadd, ipsl_mutex; -ipfrwlock_t ipf_syncstate, ipf_syncnat; +typedef struct ipf_sync_softc_s { + ipfmutex_t ipf_syncadd; + ipfmutex_t ipsl_mutex; + ipfrwlock_t ipf_syncstate; + ipfrwlock_t ipf_syncnat; #if SOLARIS && defined(_KERNEL) -kcondvar_t ipslwait; + kcondvar_t ipslwait; #endif -synclist_t *syncstatetab[SYNC_STATETABSZ]; -synclist_t *syncnattab[SYNC_NATTABSZ]; -synclogent_t synclog[SYNCLOG_SZ]; -syncupdent_t syncupd[SYNCLOG_SZ]; -u_int ipf_syncnum = 1; -u_int ipf_syncwrap = 0; -u_int sl_idx = 0, /* next available sync log entry */ - su_idx = 0, /* next available sync update entry */ - sl_tail = 0, /* next sync log entry to read */ - su_tail = 0; /* next sync update entry to read */ -int ipf_sync_debug = 0; +#if defined(linux) && defined(_KERNEL) + wait_queue_head_t sl_tail_linux; +#endif + synclist_t **syncstatetab; + synclist_t **syncnattab; + synclogent_t *synclog; + syncupdent_t *syncupd; + u_int ipf_sync_num; + u_int ipf_sync_wrap; + u_int sl_idx; /* next available sync log entry */ + u_int su_idx; /* next available sync update entry */ + u_int sl_tail; /* next sync log entry to read */ + u_int su_tail; /* next sync update entry to read */ + int ipf_sync_log_sz; + int ipf_sync_nat_tab_sz; + int ipf_sync_state_tab_sz; + int ipf_sync_debug; + int ipf_sync_events; + u_32_t ipf_sync_lastwakeup; + int ipf_sync_wake_interval; + int ipf_sync_event_high_wm; + int ipf_sync_queue_high_wm; + int ipf_sync_inited; +} ipf_sync_softc_t; +static int ipf_sync_flush_table __P((ipf_sync_softc_t *, int, synclist_t **)); +static void ipf_sync_wakeup __P((ipf_main_softc_t *)); +static void ipf_sync_del __P((ipf_sync_softc_t *, synclist_t *)); +static void ipf_sync_poll_wakeup __P((ipf_main_softc_t *)); +static int ipf_sync_nat __P((ipf_main_softc_t *, synchdr_t *, void *)); +static int ipf_sync_state __P((ipf_main_softc_t *, synchdr_t *, void *)); # if !defined(sparc) && !defined(__hppa) -void ipfsync_tcporder __P((int, struct tcpdata *)); -void ipfsync_natorder __P((int, struct nat *)); -void ipfsync_storder __P((int, struct ipstate *)); +void ipf_sync_tcporder __P((int, struct tcpdata *)); +void ipf_sync_natorder __P((int, struct nat *)); +void ipf_sync_storder __P((int, struct ipstate *)); # endif +void * +ipf_sync_soft_create(softc) + ipf_main_softc_t *softc; +{ + ipf_sync_softc_t *softs; + + KMALLOC(softs, ipf_sync_softc_t *); + if (softs == NULL) { + IPFERROR(110024); + return NULL; + } + + bzero((char *)softs, sizeof(*softs)); + + softs->ipf_sync_log_sz = SYNCLOG_SZ; + softs->ipf_sync_nat_tab_sz = SYNC_STATETABSZ; + softs->ipf_sync_state_tab_sz = SYNC_STATETABSZ; + softs->ipf_sync_event_high_wm = SYNCLOG_SZ * 100 / 90; /* 90% */ + softs->ipf_sync_queue_high_wm = SYNCLOG_SZ * 100 / 90; /* 90% */ + + return softs; +} + + /* ------------------------------------------------------------------------ */ -/* Function: ipfsync_init */ +/* Function: ipf_sync_init */ /* Returns: int - 0 == success, -1 == failure */ /* Parameters: Nil */ /* */ /* Initialise all of the locks required for the sync code and initialise */ /* any data structures, as required. */ /* ------------------------------------------------------------------------ */ -int ipfsync_init() +int +ipf_sync_soft_init(softc, arg) + ipf_main_softc_t *softc; + void *arg; { - RWLOCK_INIT(&ipf_syncstate, "add things to state sync table"); - RWLOCK_INIT(&ipf_syncnat, "add things to nat sync table"); - MUTEX_INIT(&ipf_syncadd, "add things to sync table"); - MUTEX_INIT(&ipsl_mutex, "add things to sync table"); -# if SOLARIS && defined(_KERNEL) - cv_init(&ipslwait, "ipsl condvar", CV_DRIVER, NULL); -# endif + ipf_sync_softc_t *softs = arg; - bzero((char *)syncnattab, sizeof(syncnattab)); - bzero((char *)syncstatetab, sizeof(syncstatetab)); + KMALLOCS(softs->synclog, synclogent_t *, + softs->ipf_sync_log_sz * sizeof(*softs->synclog)); + if (softs->synclog == NULL) + return -1; + bzero((char *)softs->synclog, + softs->ipf_sync_log_sz * sizeof(*softs->synclog)); + + KMALLOCS(softs->syncupd, syncupdent_t *, + softs->ipf_sync_log_sz * sizeof(*softs->syncupd)); + if (softs->syncupd == NULL) + return -2; + bzero((char *)softs->syncupd, + softs->ipf_sync_log_sz * sizeof(*softs->syncupd)); + + KMALLOCS(softs->syncstatetab, synclist_t **, + softs->ipf_sync_state_tab_sz * sizeof(*softs->syncstatetab)); + if (softs->syncstatetab == NULL) + return -3; + bzero((char *)softs->syncstatetab, + softs->ipf_sync_state_tab_sz * sizeof(*softs->syncstatetab)); + + KMALLOCS(softs->syncnattab, synclist_t **, + softs->ipf_sync_nat_tab_sz * sizeof(*softs->syncnattab)); + if (softs->syncnattab == NULL) + return -3; + bzero((char *)softs->syncnattab, + softs->ipf_sync_nat_tab_sz * sizeof(*softs->syncnattab)); + + softs->ipf_sync_num = 1; + softs->ipf_sync_wrap = 0; + softs->sl_idx = 0; + softs->su_idx = 0; + softs->sl_tail = 0; + softs->su_tail = 0; + softs->ipf_sync_events = 0; + softs->ipf_sync_lastwakeup = 0; + + +# if SOLARIS && defined(_KERNEL) + cv_init(&softs->ipslwait, "ipsl condvar", CV_DRIVER, NULL); +# endif + RWLOCK_INIT(&softs->ipf_syncstate, "add things to state sync table"); + RWLOCK_INIT(&softs->ipf_syncnat, "add things to nat sync table"); + MUTEX_INIT(&softs->ipf_syncadd, "add things to sync table"); + MUTEX_INIT(&softs->ipsl_mutex, "read ring lock"); + + softs->ipf_sync_inited = 1; return 0; } +/* ------------------------------------------------------------------------ */ +/* Function: ipf_sync_unload */ +/* Returns: int - 0 == success, -1 == failure */ +/* Parameters: Nil */ +/* */ +/* Destroy the locks created when initialising and free any memory in use */ +/* with the synchronisation tables. */ +/* ------------------------------------------------------------------------ */ +int +ipf_sync_soft_fini(softc, arg) + ipf_main_softc_t *softc; + void *arg; +{ + ipf_sync_softc_t *softs = arg; + + if (softs->syncnattab != NULL) { + ipf_sync_flush_table(softs, softs->ipf_sync_nat_tab_sz, + softs->syncnattab); + KFREES(softs->syncnattab, + softs->ipf_sync_nat_tab_sz * sizeof(*softs->syncnattab)); + softs->syncnattab = NULL; + } + + if (softs->syncstatetab != NULL) { + ipf_sync_flush_table(softs, softs->ipf_sync_state_tab_sz, + softs->syncstatetab); + KFREES(softs->syncstatetab, + softs->ipf_sync_state_tab_sz * + sizeof(*softs->syncstatetab)); + softs->syncstatetab = NULL; + } + + if (softs->syncupd != NULL) { + KFREES(softs->syncupd, + softs->ipf_sync_log_sz * sizeof(*softs->syncupd)); + softs->syncupd = NULL; + } + + if (softs->synclog != NULL) { + KFREES(softs->synclog, + softs->ipf_sync_log_sz * sizeof(*softs->synclog)); + softs->synclog = NULL; + } + + if (softs->ipf_sync_inited == 1) { + MUTEX_DESTROY(&softs->ipsl_mutex); + MUTEX_DESTROY(&softs->ipf_syncadd); + RW_DESTROY(&softs->ipf_syncnat); + RW_DESTROY(&softs->ipf_syncstate); + softs->ipf_sync_inited = 0; + } + + return 0; +} + +void +ipf_sync_soft_destroy(softc, arg) + ipf_main_softc_t *softc; + void *arg; +{ + ipf_sync_softc_t *softs = arg; + + KFREE(softs); +} + + # if !defined(sparc) && !defined(__hppa) /* ------------------------------------------------------------------------ */ -/* Function: ipfsync_tcporder */ +/* Function: ipf_sync_tcporder */ /* Returns: Nil */ /* Parameters: way(I) - direction of byte order conversion. */ /* td(IO) - pointer to data to be converted. */ @@ -165,9 +318,10 @@ int ipfsync_init() /* Do byte swapping on values in the TCP state information structure that */ /* need to be used at both ends by the host in their native byte order. */ /* ------------------------------------------------------------------------ */ -void ipfsync_tcporder(way, td) -int way; -tcpdata_t *td; +void +ipf_sync_tcporder(way, td) + int way; + tcpdata_t *td; { if (way) { td->td_maxwin = htons(td->td_maxwin); @@ -182,7 +336,7 @@ tcpdata_t *td; /* ------------------------------------------------------------------------ */ -/* Function: ipfsync_natorder */ +/* Function: ipf_sync_natorder */ /* Returns: Nil */ /* Parameters: way(I) - direction of byte order conversion. */ /* nat(IO) - pointer to data to be converted. */ @@ -190,9 +344,10 @@ tcpdata_t *td; /* Do byte swapping on values in the NAT data structure that need to be */ /* used at both ends by the host in their native byte order. */ /* ------------------------------------------------------------------------ */ -void ipfsync_natorder(way, n) -int way; -nat_t *n; +void +ipf_sync_natorder(way, n) + int way; + nat_t *n; { if (way) { n->nat_age = htonl(n->nat_age); @@ -211,7 +366,7 @@ nat_t *n; /* ------------------------------------------------------------------------ */ -/* Function: ipfsync_storder */ +/* Function: ipf_sync_storder */ /* Returns: Nil */ /* Parameters: way(I) - direction of byte order conversion. */ /* ips(IO) - pointer to data to be converted. */ @@ -219,12 +374,13 @@ nat_t *n; /* Do byte swapping on values in the IP state data structure that need to */ /* be used at both ends by the host in their native byte order. */ /* ------------------------------------------------------------------------ */ -void ipfsync_storder(way, ips) -int way; -ipstate_t *ips; +void +ipf_sync_storder(way, ips) + int way; + ipstate_t *ips; { - ipfsync_tcporder(way, &ips->is_tcp.ts_data[0]); - ipfsync_tcporder(way, &ips->is_tcp.ts_data[1]); + ipf_sync_tcporder(way, &ips->is_tcp.ts_data[0]); + ipf_sync_tcporder(way, &ips->is_tcp.ts_data[1]); if (way) { ips->is_hv = htonl(ips->is_hv); @@ -263,36 +419,37 @@ ipstate_t *ips; } } # else /* !defined(sparc) && !defined(__hppa) */ -# define ipfsync_tcporder(x,y) -# define ipfsync_natorder(x,y) -# define ipfsync_storder(x,y) +# define ipf_sync_tcporder(x,y) +# define ipf_sync_natorder(x,y) +# define ipf_sync_storder(x,y) # endif /* !defined(sparc) && !defined(__hppa) */ -/* enable this for debugging */ -# ifdef _KERNEL /* ------------------------------------------------------------------------ */ -/* Function: ipfsync_write */ +/* Function: ipf_sync_write */ /* Returns: int - 0 == success, else error value. */ /* Parameters: uio(I) - pointer to information about data to write */ /* */ /* Moves data from user space into the kernel and uses it for updating data */ /* structures in the state/NAT tables. */ /* ------------------------------------------------------------------------ */ -int ipfsync_write(uio) -struct uio *uio; +int +ipf_sync_write(softc, uio) + ipf_main_softc_t *softc; + struct uio *uio; { + ipf_sync_softc_t *softs = softc->ipf_sync_soft; synchdr_t sh; - /* + /* * THIS MUST BE SUFFICIENT LARGE TO STORE - * ANY POSSIBLE DATA TYPE + * ANY POSSIBLE DATA TYPE */ - char data[2048]; + char data[2048]; int err = 0; -# if (BSD >= 199306) || defined(__FreeBSD__) || defined(__osf__) +# if BSD_GE_YEAR(199306) || defined(__FreeBSD__) || defined(__osf__) uio->uio_rw = UIO_WRITE; # endif @@ -304,7 +461,7 @@ struct uio *uio; err = UIOMOVE(&sh, sizeof(sh), UIO_WRITE, uio); if (err) { - if (ipf_sync_debug > 2) + if (softs->ipf_sync_debug > 2) printf("uiomove(header) failed: %d\n", err); return err; @@ -315,59 +472,65 @@ struct uio *uio; sh.sm_len = ntohl(sh.sm_len); sh.sm_num = ntohl(sh.sm_num); - if (ipf_sync_debug > 8) + if (softs->ipf_sync_debug > 8) printf("[%d] Read v:%d p:%d cmd:%d table:%d rev:%d len:%d magic:%x\n", sh.sm_num, sh.sm_v, sh.sm_p, sh.sm_cmd, sh.sm_table, sh.sm_rev, sh.sm_len, sh.sm_magic); if (sh.sm_magic != SYNHDRMAGIC) { - if (ipf_sync_debug > 2) - printf("uiomove(header) invalud %s\n", + if (softs->ipf_sync_debug > 2) + printf("uiomove(header) invalid %s\n", "magic"); + IPFERROR(110001); return EINVAL; } if (sh.sm_v != 4 && sh.sm_v != 6) { - if (ipf_sync_debug > 2) + if (softs->ipf_sync_debug > 2) printf("uiomove(header) invalid %s\n", "protocol"); + IPFERROR(110002); return EINVAL; } if (sh.sm_cmd > SMC_MAXCMD) { - if (ipf_sync_debug > 2) + if (softs->ipf_sync_debug > 2) printf("uiomove(header) invalid %s\n", "command"); + IPFERROR(110003); return EINVAL; } if (sh.sm_table > SMC_MAXTBL) { - if (ipf_sync_debug > 2) + if (softs->ipf_sync_debug > 2) printf("uiomove(header) invalid %s\n", "table"); + IPFERROR(110004); return EINVAL; } } else { /* unsufficient data, wait until next call */ - if (ipf_sync_debug > 2) + if (softs->ipf_sync_debug > 2) printf("uiomove(header) insufficient data"); + IPFERROR(110005); return EAGAIN; } /* - * We have a header, so try to read the amount of data + * We have a header, so try to read the amount of data * needed for the request */ /* not supported */ if (sh.sm_len == 0) { - if (ipf_sync_debug > 2) + if (softs->ipf_sync_debug > 2) printf("uiomove(data zero length %s\n", "not supported"); + IPFERROR(110006); return EINVAL; } @@ -376,33 +539,34 @@ struct uio *uio; err = UIOMOVE(data, sh.sm_len, UIO_WRITE, uio); if (err) { - if (ipf_sync_debug > 2) + if (softs->ipf_sync_debug > 2) printf("uiomove(data) failed: %d\n", err); return err; } - if (ipf_sync_debug > 7) + if (softs->ipf_sync_debug > 7) printf("uiomove(data) %d bytes read\n", sh.sm_len); if (sh.sm_table == SMC_STATE) - err = ipfsync_state(&sh, data); + err = ipf_sync_state(softc, &sh, data); else if (sh.sm_table == SMC_NAT) - err = ipfsync_nat(&sh, data); - if (ipf_sync_debug > 7) + err = ipf_sync_nat(softc, &sh, data); + if (softs->ipf_sync_debug > 7) printf("[%d] Finished with error %d\n", sh.sm_num, err); } else { /* insufficient data, wait until next call */ - if (ipf_sync_debug > 2) + if (softs->ipf_sync_debug > 2) printf("uiomove(data) %s %d bytes, got %d\n", "insufficient data, need", - sh.sm_len, uio->uio_resid); + sh.sm_len, (int)uio->uio_resid); + IPFERROR(110007); return EAGAIN; } - } + } /* no more data */ return 0; @@ -410,7 +574,7 @@ struct uio *uio; /* ------------------------------------------------------------------------ */ -/* Function: ipfsync_read */ +/* Function: ipf_sync_read */ /* Returns: int - 0 == success, else error value. */ /* Parameters: uio(O) - pointer to information about where to store data */ /* */ @@ -418,89 +582,105 @@ struct uio *uio; /* for pending state/NAT updates. If no data is available, the caller is */ /* put to sleep, pending a wakeup from the "lower half" of this code. */ /* ------------------------------------------------------------------------ */ -int ipfsync_read(uio) -struct uio *uio; +int +ipf_sync_read(softc, uio) + ipf_main_softc_t *softc; + struct uio *uio; { + ipf_sync_softc_t *softs = softc->ipf_sync_soft; syncupdent_t *su; synclogent_t *sl; int err = 0; - if ((uio->uio_resid & 3) || (uio->uio_resid < 8)) + if ((uio->uio_resid & 3) || (uio->uio_resid < 8)) { + IPFERROR(110008); return EINVAL; + } -# if (BSD >= 199306) || defined(__FreeBSD__) || defined(__osf__) +# if BSD_GE_YEAR(199306) || defined(__FreeBSD__) || defined(__osf__) uio->uio_rw = UIO_READ; # endif - MUTEX_ENTER(&ipsl_mutex); - while ((sl_tail == sl_idx) && (su_tail == su_idx)) { -# if SOLARIS && defined(_KERNEL) - if (!cv_wait_sig(&ipslwait, &ipsl_mutex)) { - MUTEX_EXIT(&ipsl_mutex); + MUTEX_ENTER(&softs->ipsl_mutex); + while ((softs->sl_tail == softs->sl_idx) && + (softs->su_tail == softs->su_idx)) { +# if defined(_KERNEL) +# if SOLARIS + if (!cv_wait_sig(&softs->ipslwait, &softs->ipsl_mutex.ipf_lk)) { + MUTEX_EXIT(&softs->ipsl_mutex); + IPFERROR(110009); return EINTR; } -# else -# ifdef __hpux +# else +# ifdef __hpux { lock_t *l; - l = get_sleep_lock(&sl_tail); - err = sleep(&sl_tail, PZERO+1); + l = get_sleep_lock(&softs->sl_tail); + err = sleep(&softs->sl_tail, PZERO+1); if (err) { - MUTEX_EXIT(&ipsl_mutex); + MUTEX_EXIT(&softs->ipsl_mutex); + IPFERROR(110010); return EINTR; } spinunlock(l); } -# else /* __hpux */ -# ifdef __osf__ - err = mpsleep(&sl_tail, PSUSP|PCATCH, "ipl sleep", 0, - &ipsl_mutex, MS_LOCK_SIMPLE); - if (err) +# else /* __hpux */ +# ifdef __osf__ + err = mpsleep(&softs->sl_tail, PSUSP|PCATCH, "ipl sleep", 0, + &softs->ipsl_mutex, MS_LOCK_SIMPLE); + if (err) { + IPFERROR(110011); return EINTR; -# else - MUTEX_EXIT(&ipsl_mutex); - err = SLEEP(&sl_tail, "ipl sleep"); - if (err) + } +# else + MUTEX_EXIT(&softs->ipsl_mutex); + err = SLEEP(&softs->sl_tail, "ipl sleep"); + if (err) { + IPFERROR(110012); return EINTR; - MUTEX_ENTER(&ipsl_mutex); -# endif /* __osf__ */ -# endif /* __hpux */ -# endif /* SOLARIS */ + } + MUTEX_ENTER(&softs->ipsl_mutex); +# endif /* __osf__ */ +# endif /* __hpux */ +# endif /* SOLARIS */ +# endif /* _KERNEL */ } - MUTEX_EXIT(&ipsl_mutex); - READ_ENTER(&ipf_syncstate); - while ((sl_tail < sl_idx) && (uio->uio_resid > sizeof(*sl))) { - sl = synclog + sl_tail++; + while ((softs->sl_tail < softs->sl_idx) && + (uio->uio_resid > sizeof(*sl))) { + sl = softs->synclog + softs->sl_tail++; + MUTEX_EXIT(&softs->ipsl_mutex); err = UIOMOVE(sl, sizeof(*sl), UIO_READ, uio); if (err != 0) - break; + goto goterror; + MUTEX_ENTER(&softs->ipsl_mutex); } - while ((su_tail < su_idx) && (uio->uio_resid > sizeof(*su))) { - su = syncupd + su_tail; - su_tail++; + while ((softs->su_tail < softs->su_idx) && + (uio->uio_resid > sizeof(*su))) { + su = softs->syncupd + softs->su_tail; + softs->su_tail++; + MUTEX_EXIT(&softs->ipsl_mutex); err = UIOMOVE(su, sizeof(*su), UIO_READ, uio); if (err != 0) - break; + goto goterror; + MUTEX_ENTER(&softs->ipsl_mutex); if (su->sup_hdr.sm_sl != NULL) su->sup_hdr.sm_sl->sl_idx = -1; } - - MUTEX_ENTER(&ipf_syncadd); - if (su_tail == su_idx) - su_tail = su_idx = 0; - if (sl_tail == sl_idx) - sl_tail = sl_idx = 0; - MUTEX_EXIT(&ipf_syncadd); - RWLOCK_EXIT(&ipf_syncstate); + if (softs->sl_tail == softs->sl_idx) + softs->sl_tail = softs->sl_idx = 0; + if (softs->su_tail == softs->su_idx) + softs->su_tail = softs->su_idx = 0; + MUTEX_EXIT(&softs->ipsl_mutex); +goterror: return err; } /* ------------------------------------------------------------------------ */ -/* Function: ipfsync_state */ +/* Function: ipf_sync_state */ /* Returns: int - 0 == success, else error value. */ /* Parameters: sp(I) - pointer to sync packet data header */ /* uio(I) - pointer to user data for further information */ @@ -511,10 +691,13 @@ struct uio *uio; /* create a new state entry or update one. Deletion is left to the state */ /* structures being timed out correctly. */ /* ------------------------------------------------------------------------ */ -int ipfsync_state(sp, data) -synchdr_t *sp; -void *data; +static int +ipf_sync_state(softc, sp, data) + ipf_main_softc_t *softc; + synchdr_t *sp; + void *data; { + ipf_sync_softc_t *softs = softc->ipf_sync_soft; synctcp_update_t su; ipstate_t *is, sn; synclist_t *sl; @@ -522,7 +705,7 @@ void *data; u_int hv; int err = 0; - hv = sp->sm_num & (SYNC_STATETABSZ - 1); + hv = sp->sm_num & (softs->ipf_sync_state_tab_sz - 1); switch (sp->sm_cmd) { @@ -531,12 +714,14 @@ void *data; bcopy(data, &sn, sizeof(sn)); KMALLOC(is, ipstate_t *); if (is == NULL) { + IPFERROR(110013); err = ENOMEM; break; } KMALLOC(sl, synclist_t *); if (sl == NULL) { + IPFERROR(110014); err = ENOMEM; KFREE(is); break; @@ -545,23 +730,23 @@ void *data; bzero((char *)is, offsetof(ipstate_t, is_die)); bcopy((char *)&sn.is_die, (char *)&is->is_die, sizeof(*is) - offsetof(ipstate_t, is_die)); - ipfsync_storder(0, is); + ipf_sync_storder(0, is); /* * We need to find the same rule on the slave as was used on * the master to create this state entry. */ - READ_ENTER(&ipf_mutex); - fr = fr_getrulen(IPL_LOGIPF, sn.is_group, sn.is_rulen); + READ_ENTER(&softc->ipf_mutex); + fr = ipf_getrulen(softc, IPL_LOGIPF, sn.is_group, sn.is_rulen); if (fr != NULL) { MUTEX_ENTER(&fr->fr_lock); fr->fr_ref++; fr->fr_statecnt++; MUTEX_EXIT(&fr->fr_lock); } - RWLOCK_EXIT(&ipf_mutex); + RWLOCK_EXIT(&softc->ipf_mutex); - if (ipf_sync_debug > 4) + if (softs->ipf_sync_debug > 4) printf("[%d] Filter rules = %p\n", sp->sm_num, fr); is->is_rule = fr; @@ -571,16 +756,16 @@ void *data; sl->sl_ips = is; bcopy(sp, &sl->sl_hdr, sizeof(struct synchdr)); - WRITE_ENTER(&ipf_syncstate); - WRITE_ENTER(&ipf_state); + WRITE_ENTER(&softs->ipf_syncstate); + WRITE_ENTER(&softc->ipf_state); - sl->sl_pnext = syncstatetab + hv; - sl->sl_next = syncstatetab[hv]; - if (syncstatetab[hv] != NULL) - syncstatetab[hv]->sl_pnext = &sl->sl_next; - syncstatetab[hv] = sl; - MUTEX_DOWNGRADE(&ipf_syncstate); - fr_stinsert(is, sp->sm_rev); + sl->sl_pnext = softs->syncstatetab + hv; + sl->sl_next = softs->syncstatetab[hv]; + if (softs->syncstatetab[hv] != NULL) + softs->syncstatetab[hv]->sl_pnext = &sl->sl_next; + softs->syncstatetab[hv] = sl; + MUTEX_DOWNGRADE(&softs->ipf_syncstate); + ipf_state_insert(softc, is, sp->sm_rev); /* * Do not initialise the interface pointers for the state * entry as the full complement of interface names may not @@ -594,29 +779,31 @@ void *data; case SMC_UPDATE : bcopy(data, &su, sizeof(su)); - if (ipf_sync_debug > 4) + if (softs->ipf_sync_debug > 4) printf("[%d] Update age %lu state %d/%d \n", sp->sm_num, su.stu_age, su.stu_state[0], su.stu_state[1]); - READ_ENTER(&ipf_syncstate); - for (sl = syncstatetab[hv]; (sl != NULL); sl = sl->sl_next) + READ_ENTER(&softs->ipf_syncstate); + for (sl = softs->syncstatetab[hv]; (sl != NULL); + sl = sl->sl_next) if (sl->sl_hdr.sm_num == sp->sm_num) break; if (sl == NULL) { - if (ipf_sync_debug > 1) + if (softs->ipf_sync_debug > 1) printf("[%d] State not found - can't update\n", sp->sm_num); - RWLOCK_EXIT(&ipf_syncstate); + RWLOCK_EXIT(&softs->ipf_syncstate); + IPFERROR(110015); err = ENOENT; break; } - READ_ENTER(&ipf_state); + READ_ENTER(&softc->ipf_state); - if (ipf_sync_debug > 6) - printf("[%d] Data from state v:%d p:%d cmd:%d table:%d rev:%d\n", - sp->sm_num, sl->sl_hdr.sm_v, sl->sl_hdr.sm_p, + if (softs->ipf_sync_debug > 6) + printf("[%d] Data from state v:%d p:%d cmd:%d table:%d rev:%d\n", + sp->sm_num, sl->sl_hdr.sm_v, sl->sl_hdr.sm_p, sl->sl_hdr.sm_cmd, sl->sl_hdr.sm_table, sl->sl_hdr.sm_rev); @@ -640,56 +827,97 @@ void *data; break; } - if (ipf_sync_debug > 6) + if (softs->ipf_sync_debug > 6) printf("[%d] Setting timers for state\n", sp->sm_num); - fr_setstatequeue(is, sp->sm_rev); + ipf_state_setqueue(softc, is, sp->sm_rev); MUTEX_EXIT(&is->is_lock); break; default : + IPFERROR(110016); err = EINVAL; break; } if (err == 0) { - RWLOCK_EXIT(&ipf_state); - RWLOCK_EXIT(&ipf_syncstate); + RWLOCK_EXIT(&softc->ipf_state); + RWLOCK_EXIT(&softs->ipf_syncstate); } - if (ipf_sync_debug > 6) + if (softs->ipf_sync_debug > 6) printf("[%d] Update completed with error %d\n", sp->sm_num, err); return err; } -# endif /* _KERNEL */ /* ------------------------------------------------------------------------ */ -/* Function: ipfsync_del */ +/* Function: ipf_sync_del */ /* Returns: Nil */ /* Parameters: sl(I) - pointer to synclist object to delete */ /* */ -/* Deletes an object from the synclist table and free's its memory. */ +/* Deletes an object from the synclist. */ /* ------------------------------------------------------------------------ */ -void ipfsync_del(sl) -synclist_t *sl; +static void +ipf_sync_del(softs, sl) + ipf_sync_softc_t *softs; + synclist_t *sl; { - WRITE_ENTER(&ipf_syncstate); *sl->sl_pnext = sl->sl_next; if (sl->sl_next != NULL) sl->sl_next->sl_pnext = sl->sl_pnext; if (sl->sl_idx != -1) - syncupd[sl->sl_idx].sup_hdr.sm_sl = NULL; - RWLOCK_EXIT(&ipf_syncstate); + softs->syncupd[sl->sl_idx].sup_hdr.sm_sl = NULL; +} + + +/* ------------------------------------------------------------------------ */ +/* Function: ipf_sync_del_state */ +/* Returns: Nil */ +/* Parameters: sl(I) - pointer to synclist object to delete */ +/* */ +/* Deletes an object from the synclist state table and free's its memory. */ +/* ------------------------------------------------------------------------ */ +void +ipf_sync_del_state(arg, sl) + void *arg; + synclist_t *sl; +{ + ipf_sync_softc_t *softs = arg; + + WRITE_ENTER(&softs->ipf_syncstate); + ipf_sync_del(softs, sl); + RWLOCK_EXIT(&softs->ipf_syncstate); KFREE(sl); } /* ------------------------------------------------------------------------ */ -/* Function: ipfsync_nat */ +/* Function: ipf_sync_del_nat */ +/* Returns: Nil */ +/* Parameters: sl(I) - pointer to synclist object to delete */ +/* */ +/* Deletes an object from the synclist nat table and free's its memory. */ +/* ------------------------------------------------------------------------ */ +void +ipf_sync_del_nat(arg, sl) + void *arg; + synclist_t *sl; +{ + ipf_sync_softc_t *softs = arg; + + WRITE_ENTER(&softs->ipf_syncnat); + ipf_sync_del(softs, sl); + RWLOCK_EXIT(&softs->ipf_syncnat); + KFREE(sl); +} + + +/* ------------------------------------------------------------------------ */ +/* Function: ipf_sync_nat */ /* Returns: int - 0 == success, else error value. */ /* Parameters: sp(I) - pointer to sync packet data header */ /* uio(I) - pointer to user data for further information */ @@ -700,29 +928,34 @@ synclist_t *sl; /* create a new NAT entry or update one. Deletion is left to the NAT */ /* structures being timed out correctly. */ /* ------------------------------------------------------------------------ */ -int ipfsync_nat(sp, data) -synchdr_t *sp; -void *data; +static int +ipf_sync_nat(softc, sp, data) + ipf_main_softc_t *softc; + synchdr_t *sp; + void *data; { + ipf_sync_softc_t *softs = softc->ipf_sync_soft; syncupdent_t su; nat_t *n, *nat; synclist_t *sl; u_int hv = 0; int err; - READ_ENTER(&ipf_syncstate); + READ_ENTER(&softs->ipf_syncnat); switch (sp->sm_cmd) { case SMC_CREATE : KMALLOC(n, nat_t *); if (n == NULL) { + IPFERROR(110017); err = ENOMEM; break; } KMALLOC(sl, synclist_t *); if (sl == NULL) { + IPFERROR(110018); err = ENOMEM; KFREE(n); break; @@ -732,59 +965,63 @@ void *data; bzero((char *)n, offsetof(nat_t, nat_age)); bcopy((char *)&nat->nat_age, (char *)&n->nat_age, sizeof(*n) - offsetof(nat_t, nat_age)); - ipfsync_natorder(0, n); + ipf_sync_natorder(0, n); n->nat_sync = sl; + n->nat_rev = sl->sl_rev; sl->sl_idx = -1; sl->sl_ipn = n; sl->sl_num = ntohl(sp->sm_num); - WRITE_ENTER(&ipf_nat); - sl->sl_pnext = syncstatetab + hv; - sl->sl_next = syncstatetab[hv]; - if (syncstatetab[hv] != NULL) - syncstatetab[hv]->sl_pnext = &sl->sl_next; - syncstatetab[hv] = sl; - nat_insert(n, sl->sl_rev); - RWLOCK_EXIT(&ipf_nat); + WRITE_ENTER(&softc->ipf_nat); + sl->sl_pnext = softs->syncnattab + hv; + sl->sl_next = softs->syncnattab[hv]; + if (softs->syncnattab[hv] != NULL) + softs->syncnattab[hv]->sl_pnext = &sl->sl_next; + softs->syncnattab[hv] = sl; + (void) ipf_nat_insert(softc, softc->ipf_nat_soft, n); + RWLOCK_EXIT(&softc->ipf_nat); break; case SMC_UPDATE : bcopy(data, &su, sizeof(su)); - READ_ENTER(&ipf_syncstate); - for (sl = syncstatetab[hv]; (sl != NULL); sl = sl->sl_next) + for (sl = softs->syncnattab[hv]; (sl != NULL); + sl = sl->sl_next) if (sl->sl_hdr.sm_num == sp->sm_num) break; if (sl == NULL) { + IPFERROR(110019); err = ENOENT; break; } - READ_ENTER(&ipf_nat); + READ_ENTER(&softc->ipf_nat); nat = sl->sl_ipn; + nat->nat_rev = sl->sl_rev; MUTEX_ENTER(&nat->nat_lock); - fr_setnatqueue(nat, sl->sl_rev); + ipf_nat_setqueue(softc, softc->ipf_nat_soft, nat); MUTEX_EXIT(&nat->nat_lock); - RWLOCK_EXIT(&ipf_nat); + RWLOCK_EXIT(&softc->ipf_nat); break; default : + IPFERROR(110020); err = EINVAL; break; } - RWLOCK_EXIT(&ipf_syncstate); + RWLOCK_EXIT(&softs->ipf_syncnat); return 0; } /* ------------------------------------------------------------------------ */ -/* Function: ipfsync_new */ +/* Function: ipf_sync_new */ /* Returns: synclist_t* - NULL == failure, else pointer to new synclist */ /* data structure. */ /* Parameters: tab(I) - type of synclist_t to create */ @@ -794,43 +1031,36 @@ void *data; /* Creates a new sync table entry and notifies any sleepers that it's there */ /* waiting to be processed. */ /* ------------------------------------------------------------------------ */ -synclist_t *ipfsync_new(tab, fin, ptr) -int tab; -fr_info_t *fin; -void *ptr; +synclist_t * +ipf_sync_new(softc, tab, fin, ptr) + ipf_main_softc_t *softc; + int tab; + fr_info_t *fin; + void *ptr; { + ipf_sync_softc_t *softs = softc->ipf_sync_soft; synclist_t *sl, *ss; synclogent_t *sle; u_int hv, sz; - if (sl_idx == SYNCLOG_SZ) + if (softs->sl_idx == softs->ipf_sync_log_sz) return NULL; KMALLOC(sl, synclist_t *); if (sl == NULL) return NULL; - MUTEX_ENTER(&ipf_syncadd); + MUTEX_ENTER(&softs->ipf_syncadd); /* * Get a unique number for this synclist_t. The number is only meant * to be unique for the lifetime of the structure and may be reused * later. */ - ipf_syncnum++; - if (ipf_syncnum == 0) { - ipf_syncnum = 1; - ipf_syncwrap = 1; + softs->ipf_sync_num++; + if (softs->ipf_sync_num == 0) { + softs->ipf_sync_num = 1; + softs->ipf_sync_wrap++; } - hv = ipf_syncnum & (SYNC_STATETABSZ - 1); - while (ipf_syncwrap != 0) { - for (ss = syncstatetab[hv]; ss; ss = ss->sl_next) - if (ss->sl_hdr.sm_num == ipf_syncnum) - break; - if (ss == NULL) - break; - ipf_syncnum++; - hv = ipf_syncnum & (SYNC_STATETABSZ - 1); - } /* * Use the synch number of the object as the hash key. Should end up * with relatively even distribution over time. @@ -839,11 +1069,48 @@ void *ptr; * nth connection they make, where n is a value in the interval * [0, SYNC_STATETABSZ-1]. */ - sl->sl_pnext = syncstatetab + hv; - sl->sl_next = syncstatetab[hv]; - syncstatetab[hv] = sl; - sl->sl_num = ipf_syncnum; - MUTEX_EXIT(&ipf_syncadd); + switch (tab) + { + case SMC_STATE : + hv = softs->ipf_sync_num & (softs->ipf_sync_state_tab_sz - 1); + while (softs->ipf_sync_wrap != 0) { + for (ss = softs->syncstatetab[hv]; ss; ss = ss->sl_next) + if (ss->sl_hdr.sm_num == softs->ipf_sync_num) + break; + if (ss == NULL) + break; + softs->ipf_sync_num++; + hv = softs->ipf_sync_num & + (softs->ipf_sync_state_tab_sz - 1); + } + sl->sl_pnext = softs->syncstatetab + hv; + sl->sl_next = softs->syncstatetab[hv]; + softs->syncstatetab[hv] = sl; + break; + + case SMC_NAT : + hv = softs->ipf_sync_num & (softs->ipf_sync_nat_tab_sz - 1); + while (softs->ipf_sync_wrap != 0) { + for (ss = softs->syncnattab[hv]; ss; ss = ss->sl_next) + if (ss->sl_hdr.sm_num == softs->ipf_sync_num) + break; + if (ss == NULL) + break; + softs->ipf_sync_num++; + hv = softs->ipf_sync_num & + (softs->ipf_sync_nat_tab_sz - 1); + } + sl->sl_pnext = softs->syncnattab + hv; + sl->sl_next = softs->syncnattab[hv]; + softs->syncnattab[hv] = sl; + break; + + default : + break; + } + + sl->sl_num = softs->ipf_sync_num; + MUTEX_EXIT(&softs->ipf_syncadd); sl->sl_magic = htonl(SYNHDRMAGIC); sl->sl_v = fin->fin_v; @@ -868,8 +1135,8 @@ void *ptr; * Create the log entry to be read by a user daemon. When it has been * finished and put on the queue, send a signal to wakeup any waiters. */ - MUTEX_ENTER(&ipf_syncadd); - sle = synclog + sl_idx++; + MUTEX_ENTER(&softs->ipf_syncadd); + sle = softs->synclog + softs->sl_idx++; bcopy((char *)&sl->sl_hdr, (char *)&sle->sle_hdr, sizeof(sle->sle_hdr)); sle->sle_hdr.sm_num = htonl(sle->sle_hdr.sm_num); @@ -877,31 +1144,20 @@ void *ptr; if (ptr != NULL) { bcopy((char *)ptr, (char *)&sle->sle_un, sz); if (tab == SMC_STATE) { - ipfsync_storder(1, &sle->sle_un.sleu_ips); + ipf_sync_storder(1, &sle->sle_un.sleu_ips); } else if (tab == SMC_NAT) { - ipfsync_natorder(1, &sle->sle_un.sleu_ipn); + ipf_sync_natorder(1, &sle->sle_un.sleu_ipn); } } - MUTEX_EXIT(&ipf_syncadd); + MUTEX_EXIT(&softs->ipf_syncadd); - MUTEX_ENTER(&ipsl_mutex); -# if SOLARIS -# ifdef _KERNEL - cv_signal(&ipslwait); -# endif - MUTEX_EXIT(&ipsl_mutex); -# else - MUTEX_EXIT(&ipsl_mutex); -# ifdef _KERNEL - wakeup(&sl_tail); -# endif -# endif + ipf_sync_wakeup(softc); return sl; } /* ------------------------------------------------------------------------ */ -/* Function: ipfsync_update */ +/* Function: ipf_sync_update */ /* Returns: Nil */ /* Parameters: tab(I) - type of synclist_t to create */ /* fin(I) - pointer to packet information */ @@ -910,24 +1166,36 @@ void *ptr; /* For outbound packets, only, create an sync update record for the user */ /* process to read. */ /* ------------------------------------------------------------------------ */ -void ipfsync_update(tab, fin, sl) -int tab; -fr_info_t *fin; -synclist_t *sl; +void +ipf_sync_update(softc, tab, fin, sl) + ipf_main_softc_t *softc; + int tab; + fr_info_t *fin; + synclist_t *sl; { + ipf_sync_softc_t *softs = softc->ipf_sync_soft; synctcp_update_t *st; syncupdent_t *slu; ipstate_t *ips; nat_t *nat; + ipfrwlock_t *lock; if (fin->fin_out == 0 || sl == NULL) return; - WRITE_ENTER(&ipf_syncstate); - MUTEX_ENTER(&ipf_syncadd); + if (tab == SMC_STATE) { + lock = &softs->ipf_syncstate; + } else { + lock = &softs->ipf_syncnat; + } + + READ_ENTER(lock); if (sl->sl_idx == -1) { - slu = syncupd + su_idx; - sl->sl_idx = su_idx++; + MUTEX_ENTER(&softs->ipf_syncadd); + slu = softs->syncupd + softs->su_idx; + sl->sl_idx = softs->su_idx++; + MUTEX_EXIT(&softs->ipf_syncadd); + bcopy((char *)&sl->sl_hdr, (char *)&slu->sup_hdr, sizeof(slu->sup_hdr)); slu->sup_hdr.sm_magic = htonl(SYNHDRMAGIC); @@ -944,9 +1212,7 @@ synclist_t *sl; } # endif } else - slu = syncupd + sl->sl_idx; - MUTEX_EXIT(&ipf_syncadd); - MUTEX_DOWNGRADE(&ipf_syncstate); + slu = softs->syncupd + sl->sl_idx; /* * Only TCP has complex timeouts, others just use default timeouts. @@ -970,25 +1236,61 @@ synclist_t *sl; st->stu_age = htonl(nat->nat_age); } } - RWLOCK_EXIT(&ipf_syncstate); + RWLOCK_EXIT(lock); - MUTEX_ENTER(&ipsl_mutex); -# if SOLARIS -# ifdef _KERNEL - cv_signal(&ipslwait); -# endif - MUTEX_EXIT(&ipsl_mutex); -# else - MUTEX_EXIT(&ipsl_mutex); -# ifdef _KERNEL - wakeup(&sl_tail); -# endif -# endif + ipf_sync_wakeup(softc); } /* ------------------------------------------------------------------------ */ -/* Function: fr_sync_ioctl */ +/* Function: ipf_sync_flush_table */ +/* Returns: int - number of entries freed by flushing table */ +/* Parameters: tabsize(I) - size of the array pointed to by table */ +/* table(I) - pointer to sync table to empty */ +/* */ +/* Walk through a table of sync entries and free each one. It is assumed */ +/* that some lock is held so that nobody else tries to access the table */ +/* during this cleanup. */ +/* ------------------------------------------------------------------------ */ +static int +ipf_sync_flush_table(softs, tabsize, table) + ipf_sync_softc_t *softs; + int tabsize; + synclist_t **table; +{ + synclist_t *sl; + int i, items; + + items = 0; + + for (i = 0; i < tabsize; i++) { + while ((sl = table[i]) != NULL) { + switch (sl->sl_table) { + case SMC_STATE : + if (sl->sl_ips != NULL) + sl->sl_ips->is_sync = NULL; + break; + case SMC_NAT : + if (sl->sl_ipn != NULL) + sl->sl_ipn->nat_sync = NULL; + break; + } + if (sl->sl_next != NULL) + sl->sl_next->sl_pnext = sl->sl_pnext; + table[i] = sl->sl_next; + if (sl->sl_idx != -1) + softs->syncupd[sl->sl_idx].sup_hdr.sm_sl = NULL; + KFREE(sl); + items++; + } + } + + return items; +} + + +/* ------------------------------------------------------------------------ */ +/* Function: ipf_sync_ioctl */ /* Returns: int - 0 == success, != 0 == failure */ /* Parameters: data(I) - pointer to ioctl data */ /* cmd(I) - ioctl command integer */ @@ -997,24 +1299,199 @@ synclist_t *sl; /* This function currently does not handle any ioctls and so just returns */ /* EINVAL on all occasions. */ /* ------------------------------------------------------------------------ */ -int fr_sync_ioctl(data, cmd, mode, uid, ctx) -caddr_t data; -ioctlcmd_t cmd; -int mode, uid; -void *ctx; +int +ipf_sync_ioctl(softc, data, cmd, mode, uid, ctx) + ipf_main_softc_t *softc; + caddr_t data; + ioctlcmd_t cmd; + int mode, uid; + void *ctx; { - return EINVAL; + ipf_sync_softc_t *softs = softc->ipf_sync_soft; + int error, i; + SPL_INT(s); + + switch (cmd) + { + case SIOCIPFFL: + error = BCOPYIN(data, &i, sizeof(i)); + if (error != 0) { + IPFERROR(110023); + error = EFAULT; + break; + } + + switch (i) + { + case SMC_RLOG : + SPL_NET(s); + MUTEX_ENTER(&softs->ipsl_mutex); + i = (softs->sl_tail - softs->sl_idx) + + (softs->su_tail - softs->su_idx); + softs->sl_idx = 0; + softs->su_idx = 0; + softs->sl_tail = 0; + softs->su_tail = 0; + MUTEX_EXIT(&softs->ipsl_mutex); + SPL_X(s); + break; + + case SMC_NAT : + SPL_NET(s); + WRITE_ENTER(&softs->ipf_syncnat); + i = ipf_sync_flush_table(softs, SYNC_NATTABSZ, + softs->syncnattab); + RWLOCK_EXIT(&softs->ipf_syncnat); + SPL_X(s); + break; + + case SMC_STATE : + SPL_NET(s); + WRITE_ENTER(&softs->ipf_syncstate); + i = ipf_sync_flush_table(softs, SYNC_STATETABSZ, + softs->syncstatetab); + RWLOCK_EXIT(&softs->ipf_syncstate); + SPL_X(s); + break; + } + + error = BCOPYOUT(&i, data, sizeof(i)); + if (error != 0) { + IPFERROR(110022); + error = EFAULT; + } + break; + + default : + IPFERROR(110021); + error = EINVAL; + break; + } + + return error; } -int ipfsync_canread() +/* ------------------------------------------------------------------------ */ +/* Function: ipf_sync_canread */ +/* Returns: int - 0 == success, != 0 == failure */ +/* Parameters: Nil */ +/* */ +/* This function provides input to the poll handler about whether or not */ +/* there is data waiting to be read from the /dev/ipsync device. */ +/* ------------------------------------------------------------------------ */ +int +ipf_sync_canread(arg) + void *arg; { - return !((sl_tail == sl_idx) && (su_tail == su_idx)); + ipf_sync_softc_t *softs = arg; + return !((softs->sl_tail == softs->sl_idx) && + (softs->su_tail == softs->su_idx)); } -int ipfsync_canwrite() +/* ------------------------------------------------------------------------ */ +/* Function: ipf_sync_canwrite */ +/* Returns: int - 1 == can always write */ +/* Parameters: Nil */ +/* */ +/* This function lets the poll handler know that it is always ready willing */ +/* to accept write events. */ +/* XXX Maybe this should return false if the sync table is full? */ +/* ------------------------------------------------------------------------ */ +int +ipf_sync_canwrite(arg) + void *arg; { return 1; } -#endif /* IPFILTER_SYNC */ + + +/* ------------------------------------------------------------------------ */ +/* Function: ipf_sync_wakeup */ +/* Parameters: Nil */ +/* Returns: Nil */ +/* */ +/* This function implements the heuristics that decide how often to */ +/* generate a poll wakeup for programs that are waiting for information */ +/* about when they can do a read on /dev/ipsync. */ +/* */ +/* There are three different considerations here: */ +/* - do not keep a program waiting too long: ipf_sync_wake_interval is the */ +/* maximum number of ipf ticks to let pass by; */ +/* - do not let the queue of ouststanding things to generate notifies for */ +/* get too full (ipf_sync_queue_high_wm is the high water mark); */ +/* - do not let too many events get collapsed in before deciding that the */ +/* other host(s) need an update (ipf_sync_event_high_wm is the high water */ +/* mark for this counter.) */ +/* ------------------------------------------------------------------------ */ +static void +ipf_sync_wakeup(softc) + ipf_main_softc_t *softc; +{ + ipf_sync_softc_t *softs = softc->ipf_sync_soft; + + softs->ipf_sync_events++; + if ((softc->ipf_ticks > + softs->ipf_sync_lastwakeup + softs->ipf_sync_wake_interval) || + (softs->ipf_sync_events > softs->ipf_sync_event_high_wm) || + ((softs->sl_tail - softs->sl_idx) > + softs->ipf_sync_queue_high_wm) || + ((softs->su_tail - softs->su_idx) > + softs->ipf_sync_queue_high_wm)) { + + ipf_sync_poll_wakeup(softc); + } +} + + +/* ------------------------------------------------------------------------ */ +/* Function: ipf_sync_poll_wakeup */ +/* Parameters: Nil */ +/* Returns: Nil */ +/* */ +/* Deliver a poll wakeup and reset counters for two of the three heuristics */ +/* ------------------------------------------------------------------------ */ +static void +ipf_sync_poll_wakeup(softc) + ipf_main_softc_t *softc; +{ + ipf_sync_softc_t *softs = softc->ipf_sync_soft; + + softs->ipf_sync_events = 0; + softs->ipf_sync_lastwakeup = softc->ipf_ticks; + +# ifdef _KERNEL +# if SOLARIS + MUTEX_ENTER(&softs->ipsl_mutex); + cv_signal(&softs->ipslwait); + MUTEX_EXIT(&softs->ipsl_mutex); + pollwakeup(&softc->ipf_poll_head[IPL_LOGSYNC], POLLIN|POLLRDNORM); +# else + WAKEUP(&softs->sl_tail, 0); + POLLWAKEUP(IPL_LOGSYNC); +# endif +# endif +} + + +/* ------------------------------------------------------------------------ */ +/* Function: ipf_sync_expire */ +/* Parameters: Nil */ +/* Returns: Nil */ +/* */ +/* This is the function called even ipf_tick. It implements one of the */ +/* three heuristics above *IF* there are events waiting. */ +/* ------------------------------------------------------------------------ */ +void +ipf_sync_expire(softc) + ipf_main_softc_t *softc; +{ + ipf_sync_softc_t *softs = softc->ipf_sync_soft; + + if ((softs->ipf_sync_events > 0) && + (softc->ipf_ticks > + softs->ipf_sync_lastwakeup + softs->ipf_sync_wake_interval)) { + ipf_sync_poll_wakeup(softc); + } +} diff --git a/sys/contrib/ipfilter/netinet/ip_sync.h b/sys/contrib/ipfilter/netinet/ip_sync.h index 8104db3f2c3d..d9d6d41046e8 100644 --- a/sys/contrib/ipfilter/netinet/ip_sync.h +++ b/sys/contrib/ipfilter/netinet/ip_sync.h @@ -1,10 +1,10 @@ /* - * Copyright (C) 1993-2001 by Darren Reed. + * Copyright (C) 2012 by Darren Reed. * * See the IPFILTER.LICENCE file for details on licencing. * * @(#)ip_fil.h 1.35 6/5/96 - * $Id: ip_sync.h,v 2.11.2.4 2006/07/14 06:12:20 darrenr Exp $ + * $Id$ */ #ifndef __IP_SYNC_H__ @@ -36,6 +36,7 @@ typedef struct synchdr { /* * Tables */ +#define SMC_RLOG -2 /* Only used with SIOCIPFFL */ #define SMC_NAT 0 #define SMC_STATE 1 #define SMC_MAXTBL 1 @@ -99,19 +100,22 @@ typedef struct syncupdent { /* 28 or 32 bytes */ struct synctcp_update sup_tcp; } syncupdent_t; -extern synclogent_t synclog[SYNCLOG_SZ]; +extern void *ipf_sync_create __P((ipf_main_softc_t *)); +extern int ipf_sync_soft_init __P((ipf_main_softc_t *, void *)); +extern int ipf_sync_soft_fini __P((ipf_main_softc_t *, void *)); +extern int ipf_sync_canread __P((void *)); +extern int ipf_sync_canwrite __P((void *)); +extern void ipf_sync_del_nat __P((void *, synclist_t *)); +extern void ipf_sync_del_state __P((void *, synclist_t *)); +extern int ipf_sync_init __P((void)); +extern int ipf_sync_ioctl __P((ipf_main_softc_t *, caddr_t, ioctlcmd_t, int, int, void *)); +extern synclist_t *ipf_sync_new __P((ipf_main_softc_t *, int, fr_info_t *, void *)); +extern int ipf_sync_read __P((ipf_main_softc_t *, struct uio *uio)); +extern int ipf_sync_write __P((ipf_main_softc_t *, struct uio *uio)); +extern int ipf_sync_main_unload __P((void)); +extern void ipf_sync_update __P((ipf_main_softc_t *, int, fr_info_t *, synclist_t *)); +extern void ipf_sync_expire __P((ipf_main_softc_t *)); +extern void ipf_sync_soft_destroy __P((ipf_main_softc_t *, void *)); +extern void *ipf_sync_soft_create __P((ipf_main_softc_t *)); - -extern int fr_sync_ioctl __P((caddr_t, ioctlcmd_t, int, int, void *)); -extern synclist_t *ipfsync_new __P((int, fr_info_t *, void *)); -extern void ipfsync_del __P((synclist_t *)); -extern void ipfsync_update __P((int, fr_info_t *, synclist_t *)); -extern int ipfsync_init __P((void)); -extern int ipfsync_nat __P((synchdr_t *sp, void *data)); -extern int ipfsync_state __P((synchdr_t *sp, void *data)); -extern int ipfsync_read __P((struct uio *uio)); -extern int ipfsync_write __P((struct uio *uio)); -extern int ipfsync_canread __P((void)); -extern int ipfsync_canwrite __P((void)); - -#endif /* IP_SYNC */ +#endif /* __IP_SYNC_H__ */ diff --git a/sys/contrib/ipfilter/netinet/ip_tftp_pxy.c b/sys/contrib/ipfilter/netinet/ip_tftp_pxy.c new file mode 100644 index 000000000000..409b982fe106 --- /dev/null +++ b/sys/contrib/ipfilter/netinet/ip_tftp_pxy.c @@ -0,0 +1,508 @@ +/* + * Copyright (C) 2012 by Darren Reed. + * + * See the IPFILTER.LICENCE file for details on licencing. + * + * $Id: ip_tftp_pxy.c,v 1.1.2.9 2012/07/22 08:04:23 darren_r Exp $ + */ + +#define IPF_TFTP_PROXY + +typedef struct ipf_tftp_softc_s { + int ipf_p_tftp_readonly; + ipftuneable_t *ipf_p_tftp_tune; +} ipf_tftp_softc_t; + +int ipf_p_tftp_backchannel __P((fr_info_t *, ap_session_t *, nat_t *)); +int ipf_p_tftp_client __P((ipf_tftp_softc_t *, fr_info_t *, ap_session_t *, + nat_t *)); +int ipf_p_tftp_in __P((void *, fr_info_t *, ap_session_t *, nat_t *)); +void ipf_p_tftp_main_load __P((void)); +void ipf_p_tftp_main_unload __P((void)); +int ipf_p_tftp_new __P((void *, fr_info_t *, ap_session_t *, nat_t *)); +void ipf_p_tftp_del __P((ipf_main_softc_t *, ap_session_t *)); +int ipf_p_tftp_out __P((void *, fr_info_t *, ap_session_t *, nat_t *)); +int ipf_p_tftp_server __P((ipf_tftp_softc_t *, fr_info_t *, ap_session_t *, + nat_t *)); +void *ipf_p_tftp_soft_create __P((ipf_main_softc_t *)); +void ipf_p_tftp_soft_destroy __P((ipf_main_softc_t *, void *)); + +static frentry_t tftpfr; +static int tftp_proxy_init = 0; + +typedef enum tftp_cmd_e { + TFTP_CMD_READ = 1, + TFTP_CMD_WRITE = 2, + TFTP_CMD_DATA = 3, + TFTP_CMD_ACK = 4, + TFTP_CMD_ERROR = 5 +} tftp_cmd_t; + +typedef struct tftpinfo { + tftp_cmd_t ti_lastcmd; + int ti_nextblk; + int ti_lastblk; + int ti_lasterror; + char ti_filename[80]; + ipnat_t *ti_rule; +} tftpinfo_t; + +static ipftuneable_t ipf_tftp_tuneables[] = { + { { (void *)offsetof(ipf_tftp_softc_t, ipf_p_tftp_readonly) }, + "tftp_read_only", 0, 1, + stsizeof(ipf_tftp_softc_t, ipf_p_tftp_readonly), + 0, NULL, NULL }, + { { NULL }, NULL, 0, 0, 0, 0, NULL, NULL } +}; + + +/* + * TFTP application proxy initialization. + */ +void +ipf_p_tftp_main_load() +{ + + bzero((char *)&tftpfr, sizeof(tftpfr)); + tftpfr.fr_ref = 1; + tftpfr.fr_flags = FR_INQUE|FR_PASS|FR_QUICK|FR_KEEPSTATE; + MUTEX_INIT(&tftpfr.fr_lock, "TFTP proxy rule lock"); + tftp_proxy_init = 1; +} + + +void +ipf_p_tftp_main_unload() +{ + + if (tftp_proxy_init == 1) { + MUTEX_DESTROY(&tftpfr.fr_lock); + tftp_proxy_init = 0; + } +} + + +void * +ipf_p_tftp_soft_create(softc) + ipf_main_softc_t *softc; +{ + ipf_tftp_softc_t *softt; + + KMALLOC(softt, ipf_tftp_softc_t *); + if (softt == NULL) + return NULL; + + bzero((char *)softt, sizeof(*softt)); + + softt->ipf_p_tftp_tune = ipf_tune_array_copy(softt, + sizeof(ipf_tftp_tuneables), + ipf_tftp_tuneables); + if (softt->ipf_p_tftp_tune == NULL) { + ipf_p_tftp_soft_destroy(softc, softt); + return NULL; + } + if (ipf_tune_array_link(softc, softt->ipf_p_tftp_tune) == -1) { + ipf_p_tftp_soft_destroy(softc, softt); + return NULL; + } + + softt->ipf_p_tftp_readonly = 1; + + return softt; +} + + +void +ipf_p_tftp_soft_destroy(softc, arg) + ipf_main_softc_t *softc; + void *arg; +{ + ipf_tftp_softc_t *softt = arg; + + if (softt->ipf_p_tftp_tune != NULL) { + ipf_tune_array_unlink(softc, softt->ipf_p_tftp_tune); + KFREES(softt->ipf_p_tftp_tune, sizeof(ipf_tftp_tuneables)); + softt->ipf_p_tftp_tune = NULL; + } + + KFREE(softt); +} + + +int +ipf_p_tftp_out(arg, fin, aps, nat) + void *arg; + fr_info_t *fin; + ap_session_t *aps; + nat_t *nat; +{ + ipf_tftp_softc_t *softt = arg; + + fin->fin_flx |= FI_NOWILD; + if (nat->nat_dir == NAT_OUTBOUND) + return ipf_p_tftp_client(softt, fin, aps, nat); + return ipf_p_tftp_server(softt, fin, aps, nat); +} + + +int +ipf_p_tftp_in(arg, fin, aps, nat) + void *arg; + fr_info_t *fin; + ap_session_t *aps; + nat_t *nat; +{ + ipf_tftp_softc_t *softt = arg; + + fin->fin_flx |= FI_NOWILD; + if (nat->nat_dir == NAT_INBOUND) + return ipf_p_tftp_client(softt, fin, aps, nat); + return ipf_p_tftp_server(softt, fin, aps, nat); +} + + +int +ipf_p_tftp_new(arg, fin, aps, nat) + void *arg; + fr_info_t *fin; + ap_session_t *aps; + nat_t *nat; +{ + udphdr_t *udp; + tftpinfo_t *ti; + ipnat_t *ipn; + ipnat_t *np; + int size; + + fin = fin; /* LINT */ + + np = nat->nat_ptr; + size = np->in_size; + + KMALLOC(ti, tftpinfo_t *); + if (ti == NULL) + return -1; + KMALLOCS(ipn, ipnat_t *, size); + if (ipn == NULL) { + KFREE(ti); + return -1; + } + + aps->aps_data = ti; + aps->aps_psiz = sizeof(*ti); + bzero((char *)ti, sizeof(*ti)); + bzero((char *)ipn, size); + ti->ti_rule = ipn; + + udp = (udphdr_t *)fin->fin_dp; + aps->aps_sport = udp->uh_sport; + aps->aps_dport = udp->uh_dport; + + ipn->in_size = size; + ipn->in_apr = NULL; + ipn->in_use = 1; + ipn->in_hits = 1; + ipn->in_ippip = 1; + ipn->in_pr[0] = IPPROTO_UDP; + ipn->in_pr[1] = IPPROTO_UDP; + ipn->in_ifps[0] = nat->nat_ifps[0]; + ipn->in_ifps[1] = nat->nat_ifps[1]; + ipn->in_v[0] = nat->nat_ptr->in_v[1]; + ipn->in_v[1] = nat->nat_ptr->in_v[0]; + ipn->in_flags = IPN_UDP|IPN_FIXEDDPORT|IPN_PROXYRULE; + + ipn->in_nsrcip6 = nat->nat_odst6; + ipn->in_osrcip6 = nat->nat_ndst6; + + if ((np->in_redir & NAT_REDIRECT) != 0) { + ipn->in_redir = NAT_MAP; + if (ipn->in_v[0] == 4) { + ipn->in_snip = ntohl(nat->nat_odstaddr); + ipn->in_dnip = ntohl(nat->nat_nsrcaddr); + } else { +#ifdef USE_INET6 + ipn->in_snip6 = nat->nat_odst6; + ipn->in_dnip6 = nat->nat_nsrc6; +#endif + } + ipn->in_ndstip6 = nat->nat_nsrc6; + ipn->in_odstip6 = nat->nat_osrc6; + } else { + ipn->in_redir = NAT_REDIRECT; + if (ipn->in_v[0] == 4) { + ipn->in_snip = ntohl(nat->nat_odstaddr); + ipn->in_dnip = ntohl(nat->nat_osrcaddr); + } else { +#ifdef USE_INET6 + ipn->in_snip6 = nat->nat_odst6; + ipn->in_dnip6 = nat->nat_osrc6; +#endif + } + ipn->in_ndstip6 = nat->nat_osrc6; + ipn->in_odstip6 = nat->nat_nsrc6; + } + ipn->in_odport = htons(fin->fin_sport); + ipn->in_ndport = htons(fin->fin_sport); + + IP6_SETONES(&ipn->in_osrcmsk6); + IP6_SETONES(&ipn->in_nsrcmsk6); + IP6_SETONES(&ipn->in_odstmsk6); + IP6_SETONES(&ipn->in_ndstmsk6); + MUTEX_INIT(&ipn->in_lock, "tftp proxy NAT rule"); + + ipn->in_namelen = np->in_namelen; + bcopy(np->in_names, ipn->in_ifnames, ipn->in_namelen); + ipn->in_ifnames[0] = np->in_ifnames[0]; + ipn->in_ifnames[1] = np->in_ifnames[1]; + + ti->ti_lastcmd = 0; + + return 0; +} + + +void +ipf_p_tftp_del(softc, aps) + ipf_main_softc_t *softc; + ap_session_t *aps; +{ + tftpinfo_t *tftp; + + tftp = aps->aps_data; + if (tftp != NULL) { + tftp->ti_rule->in_flags |= IPN_DELETE; + ipf_nat_rule_deref(softc, &tftp->ti_rule); + } +} + + +/* + * Setup for a new TFTP proxy. + */ +int +ipf_p_tftp_backchannel(fin, aps, nat) + fr_info_t *fin; + ap_session_t *aps; + nat_t *nat; +{ + ipf_main_softc_t *softc = fin->fin_main_soft; +#ifdef USE_MUTEXES + ipf_nat_softc_t *softn = softc->ipf_nat_soft; +#endif +#ifdef USE_INET6 + i6addr_t swip6, sw2ip6; + ip6_t *ip6; +#endif + struct in_addr swip, sw2ip; + tftpinfo_t *ti; + udphdr_t udp; + fr_info_t fi; + u_short slen; + nat_t *nat2; + int nflags; + ip_t *ip; + int dir; + + ti = aps->aps_data; + /* + * Add skeleton NAT entry for connection which will come back the + * other way. + */ + bcopy((char *)fin, (char *)&fi, sizeof(fi)); + fi.fin_flx |= FI_IGNORE; + fi.fin_data[1] = 0; + + bzero((char *)&udp, sizeof(udp)); + udp.uh_sport = 0; /* XXX - don't specify remote port */ + udp.uh_dport = ti->ti_rule->in_ndport; + udp.uh_ulen = htons(sizeof(udp)); + udp.uh_sum = 0; + + fi.fin_fr = &tftpfr; + fi.fin_dp = (char *)&udp; + fi.fin_sport = 0; + fi.fin_dport = ntohs(ti->ti_rule->in_ndport); + fi.fin_dlen = sizeof(udp); + fi.fin_plen = fi.fin_hlen + sizeof(udp); + fi.fin_flx &= FI_LOWTTL|FI_FRAG|FI_TCPUDP|FI_OPTIONS|FI_IGNORE; + nflags = NAT_SLAVE|IPN_UDP|SI_W_SPORT; +#ifdef USE_INET6 + ip6 = (ip6_t *)fin->fin_ip; +#endif + ip = fin->fin_ip; + sw2ip.s_addr = 0; + swip.s_addr = 0; + + fi.fin_src6 = nat->nat_ndst6; + fi.fin_dst6 = nat->nat_nsrc6; + if (nat->nat_v[0] == 4) { + slen = ip->ip_len; + ip->ip_len = htons(fin->fin_hlen + sizeof(udp)); + swip = ip->ip_src; + sw2ip = ip->ip_dst; + ip->ip_src = nat->nat_ndstip; + ip->ip_dst = nat->nat_nsrcip; + } else { +#ifdef USE_INET6 + slen = ip6->ip6_plen; + ip6->ip6_plen = htons(sizeof(udp)); + swip6.in6 = ip6->ip6_src; + sw2ip6.in6 = ip6->ip6_dst; + ip6->ip6_src = nat->nat_ndst6.in6; + ip6->ip6_dst = nat->nat_nsrc6.in6; +#endif + } + + if (nat->nat_dir == NAT_INBOUND) { + dir = NAT_OUTBOUND; + fi.fin_out = 1; + } else { + dir = NAT_INBOUND; + fi.fin_out = 0; + } + nflags |= NAT_NOTRULEPORT; + + MUTEX_ENTER(&softn->ipf_nat_new); +#ifdef USE_INET6 + if (nat->nat_v[0] == 6) + nat2 = ipf_nat6_add(&fi, ti->ti_rule, NULL, nflags, dir); + else +#endif + nat2 = ipf_nat_add(&fi, ti->ti_rule, NULL, nflags, dir); + MUTEX_EXIT(&softn->ipf_nat_new); + if (nat2 != NULL) { + (void) ipf_nat_proto(&fi, nat2, IPN_UDP); + ipf_nat_update(&fi, nat2); + fi.fin_ifp = NULL; + if (ti->ti_rule->in_redir == NAT_MAP) { + fi.fin_src6 = nat->nat_ndst6; + fi.fin_dst6 = nat->nat_nsrc6; + if (nat->nat_v[0] == 4) { + ip->ip_src = nat->nat_ndstip; + ip->ip_dst = nat->nat_nsrcip; + } else { +#ifdef USE_INET6 + ip6->ip6_src = nat->nat_ndst6.in6; + ip6->ip6_dst = nat->nat_nsrc6.in6; +#endif + } + } else { + fi.fin_src6 = nat->nat_odst6; + fi.fin_dst6 = nat->nat_osrc6; + if (fin->fin_v == 4) { + ip->ip_src = nat->nat_odstip; + ip->ip_dst = nat->nat_osrcip; + } else { +#ifdef USE_INET6 + ip6->ip6_src = nat->nat_odst6.in6; + ip6->ip6_dst = nat->nat_osrc6.in6; +#endif + } + } + if (ipf_state_add(softc, &fi, NULL, SI_W_SPORT) != 0) { + ipf_nat_setpending(softc, nat2); + } + } + if (nat->nat_v[0] == 4) { + ip->ip_len = slen; + ip->ip_src = swip; + ip->ip_dst = sw2ip; + } else { +#ifdef USE_INET6 + ip6->ip6_plen = slen; + ip6->ip6_src = swip6.in6; + ip6->ip6_dst = sw2ip6.in6; +#endif + } + return 0; +} + + +int +ipf_p_tftp_client(softt, fin, aps, nat) + ipf_tftp_softc_t *softt; + fr_info_t *fin; + ap_session_t *aps; + nat_t *nat; +{ + u_char *msg, *s, *t; + tftpinfo_t *ti; + u_short opcode; + udphdr_t *udp; + int len; + + if (fin->fin_dlen < 4) + return 0; + + ti = aps->aps_data; + msg = fin->fin_dp; + msg += sizeof(udphdr_t); + opcode = (msg[0] << 8) | msg[1]; + DT3(tftp_cmd, fr_info_t *, fin, int, opcode, nat_t *, nat); + + switch (opcode) + { + case TFTP_CMD_WRITE : + if (softt->ipf_p_tftp_readonly != 0) + break; + /* FALLTHROUGH */ + case TFTP_CMD_READ : + len = fin->fin_dlen - sizeof(*udp) - 2; + if (len > sizeof(ti->ti_filename) - 1) + len = sizeof(ti->ti_filename) - 1; + s = msg + 2; + for (t = (u_char *)ti->ti_filename; (len > 0); len--, s++) { + *t++ = *s; + if (*s == '\0') + break; + } + ipf_p_tftp_backchannel(fin, aps, nat); + break; + default : + return -1; + } + + ti = aps->aps_data; + ti->ti_lastcmd = opcode; + return 0; +} + + +int +ipf_p_tftp_server(softt, fin, aps, nat) + ipf_tftp_softc_t *softt; + fr_info_t *fin; + ap_session_t *aps; + nat_t *nat; +{ + tftpinfo_t *ti; + u_short opcode; + u_short arg; + u_char *msg; + + if (fin->fin_dlen < 4) + return 0; + + ti = aps->aps_data; + msg = fin->fin_dp; + msg += sizeof(udphdr_t); + arg = (msg[2] << 8) | msg[3]; + opcode = (msg[0] << 8) | msg[1]; + + switch (opcode) + { + case TFTP_CMD_ACK : + ti->ti_lastblk = arg; + break; + + case TFTP_CMD_ERROR : + ti->ti_lasterror = arg; + break; + + default : + return -1; + } + + ti->ti_lastcmd = opcode; + return 0; +} diff --git a/sys/contrib/ipfilter/netinet/ipf_rb.h b/sys/contrib/ipfilter/netinet/ipf_rb.h new file mode 100644 index 000000000000..3d7a59d99d36 --- /dev/null +++ b/sys/contrib/ipfilter/netinet/ipf_rb.h @@ -0,0 +1,364 @@ +/* + * Copyright (C) 2012 by Darren Reed. + * + * See the IPFILTER.LICENCE file for details on licencing. + * + */ +typedef enum rbcolour_e { + C_BLACK = 0, + C_RED = 1 +} rbcolour_t; + +#define RBI_LINK(_n, _t) \ + struct _n##_rb_link { \ + struct _t *left; \ + struct _t *right; \ + struct _t *parent; \ + rbcolour_t colour; \ + } + +#define RBI_HEAD(_n, _t) \ +struct _n##_rb_head { \ + struct _t top; \ + int count; \ + int (* compare)(struct _t *, struct _t *); \ +} + +#define RBI_CODE(_n, _t, _f, _cmp) \ + \ +typedef void (*_n##_rb_walker_t)(_t *, void *); \ + \ +_t * _n##_rb_delete(struct _n##_rb_head *, _t *); \ +void _n##_rb_init(struct _n##_rb_head *); \ +void _n##_rb_insert(struct _n##_rb_head *, _t *); \ +_t * _n##_rb_search(struct _n##_rb_head *, void *); \ +void _n##_rb_walktree(struct _n##_rb_head *, _n##_rb_walker_t, void *);\ + \ +static void \ +rotate_left(struct _n##_rb_head *head, _t *node) \ +{ \ + _t *parent, *tmp1, *tmp2; \ + \ + parent = node->_f.parent; \ + tmp1 = node->_f.right; \ + tmp2 = tmp1->_f.left; \ + node->_f.right = tmp2; \ + if (tmp2 != & _n##_rb_zero) \ + tmp2->_f.parent = node; \ + if (parent == & _n##_rb_zero) \ + head->top._f.right = tmp1; \ + else if (parent->_f.right == node) \ + parent->_f.right = tmp1; \ + else \ + parent->_f.left = tmp1; \ + tmp1->_f.left = node; \ + tmp1->_f.parent = parent; \ + node->_f.parent = tmp1; \ +} \ + \ +static void \ +rotate_right(struct _n##_rb_head *head, _t *node) \ +{ \ + _t *parent, *tmp1, *tmp2; \ + \ + parent = node->_f.parent; \ + tmp1 = node->_f.left; \ + tmp2 = tmp1->_f.right; \ + node->_f.left = tmp2; \ + if (tmp2 != &_n##_rb_zero) \ + tmp2->_f.parent = node; \ + if (parent == &_n##_rb_zero) \ + head->top._f.right = tmp1; \ + else if (parent->_f.right == node) \ + parent->_f.right = tmp1; \ + else \ + parent->_f.left = tmp1; \ + tmp1->_f.right = node; \ + tmp1->_f.parent = parent; \ + node->_f.parent = tmp1; \ +} \ + \ +void \ +_n##_rb_insert(struct _n##_rb_head *head, _t *node) \ +{ \ + _t *n, *parent, **p, *tmp1, *gparent; \ + \ + parent = &head->top; \ + node->_f.left = &_n##_rb_zero; \ + node->_f.right = &_n##_rb_zero; \ + p = &head->top._f.right; \ + while ((n = *p) != &_n##_rb_zero) { \ + if (_cmp(node, n) < 0) \ + p = &n->_f.left; \ + else \ + p = &n->_f.right; \ + parent = n; \ + } \ + *p = node; \ + node->_f.colour = C_RED; \ + node->_f.parent = parent; \ + \ + while ((node != &_n##_rb_zero) && (parent->_f.colour == C_RED)){\ + gparent = parent->_f.parent; \ + if (parent == gparent->_f.left) { \ + tmp1 = gparent->_f.right; \ + if (tmp1->_f.colour == C_RED) { \ + parent->_f.colour = C_BLACK; \ + tmp1->_f.colour = C_BLACK; \ + gparent->_f.colour = C_RED; \ + node = gparent; \ + } else { \ + if (node == parent->_f.right) { \ + node = parent; \ + rotate_left(head, node); \ + parent = node->_f.parent; \ + } \ + parent->_f.colour = C_BLACK; \ + gparent->_f.colour = C_RED; \ + rotate_right(head, gparent); \ + } \ + } else { \ + tmp1 = gparent->_f.left; \ + if (tmp1->_f.colour == C_RED) { \ + parent->_f.colour = C_BLACK; \ + tmp1->_f.colour = C_BLACK; \ + gparent->_f.colour = C_RED; \ + node = gparent; \ + } else { \ + if (node == parent->_f.left) { \ + node = parent; \ + rotate_right(head, node); \ + parent = node->_f.parent; \ + } \ + parent->_f.colour = C_BLACK; \ + gparent->_f.colour = C_RED; \ + rotate_left(head, parent->_f.parent); \ + } \ + } \ + parent = node->_f.parent; \ + } \ + head->top._f.right->_f.colour = C_BLACK; \ + head->count++; \ +} \ + \ +static void \ +deleteblack(struct _n##_rb_head *head, _t *parent, _t *node) \ +{ \ + _t *tmp; \ + \ + while ((node == &_n##_rb_zero || node->_f.colour == C_BLACK) && \ + node != &head->top) { \ + if (parent->_f.left == node) { \ + tmp = parent->_f.right; \ + if (tmp->_f.colour == C_RED) { \ + tmp->_f.colour = C_BLACK; \ + parent->_f.colour = C_RED; \ + rotate_left(head, parent); \ + tmp = parent->_f.right; \ + } \ + if ((tmp->_f.left == &_n##_rb_zero || \ + tmp->_f.left->_f.colour == C_BLACK) && \ + (tmp->_f.right == &_n##_rb_zero || \ + tmp->_f.right->_f.colour == C_BLACK)) { \ + tmp->_f.colour = C_RED; \ + node = parent; \ + parent = node->_f.parent; \ + } else { \ + if (tmp->_f.right == &_n##_rb_zero || \ + tmp->_f.right->_f.colour == C_BLACK) {\ + _t *tmp2 = tmp->_f.left; \ + \ + if (tmp2 != &_n##_rb_zero) \ + tmp2->_f.colour = C_BLACK;\ + tmp->_f.colour = C_RED; \ + rotate_right(head, tmp); \ + tmp = parent->_f.right; \ + } \ + tmp->_f.colour = parent->_f.colour; \ + parent->_f.colour = C_BLACK; \ + if (tmp->_f.right != &_n##_rb_zero) \ + tmp->_f.right->_f.colour = C_BLACK;\ + rotate_left(head, parent); \ + node = head->top._f.right; \ + } \ + } else { \ + tmp = parent->_f.left; \ + if (tmp->_f.colour == C_RED) { \ + tmp->_f.colour = C_BLACK; \ + parent->_f.colour = C_RED; \ + rotate_right(head, parent); \ + tmp = parent->_f.left; \ + } \ + if ((tmp->_f.left == &_n##_rb_zero || \ + tmp->_f.left->_f.colour == C_BLACK) && \ + (tmp->_f.right == &_n##_rb_zero || \ + tmp->_f.right->_f.colour == C_BLACK)) { \ + tmp->_f.colour = C_RED; \ + node = parent; \ + parent = node->_f.parent; \ + } else { \ + if (tmp->_f.left == &_n##_rb_zero || \ + tmp->_f.left->_f.colour == C_BLACK) {\ + _t *tmp2 = tmp->_f.right; \ + \ + if (tmp2 != &_n##_rb_zero) \ + tmp2->_f.colour = C_BLACK;\ + tmp->_f.colour = C_RED; \ + rotate_left(head, tmp); \ + tmp = parent->_f.left; \ + } \ + tmp->_f.colour = parent->_f.colour; \ + parent->_f.colour = C_BLACK; \ + if (tmp->_f.left != &_n##_rb_zero) \ + tmp->_f.left->_f.colour = C_BLACK;\ + rotate_right(head, parent); \ + node = head->top._f.right; \ + break; \ + } \ + } \ + } \ + if (node != &_n##_rb_zero) \ + node->_f.colour = C_BLACK; \ +} \ + \ +_t * \ +_n##_rb_delete(struct _n##_rb_head *head, _t *node) \ +{ \ + _t *child, *parent, *old = node, *left; \ + rbcolour_t color; \ + \ + if (node->_f.left == &_n##_rb_zero) { \ + child = node->_f.right; \ + } else if (node->_f.right == &_n##_rb_zero) { \ + child = node->_f.left; \ + } else { \ + node = node->_f.right; \ + while ((left = node->_f.left) != &_n##_rb_zero) \ + node = left; \ + child = node->_f.right; \ + parent = node->_f.parent; \ + color = node->_f.colour; \ + if (child != &_n##_rb_zero) \ + child->_f.parent = parent; \ + if (parent != &_n##_rb_zero) { \ + if (parent->_f.left == node) \ + parent->_f.left = child; \ + else \ + parent->_f.right = child; \ + } else { \ + head->top._f.right = child; \ + } \ + if (node->_f.parent == old) \ + parent = node; \ + *node = *old; \ + if (old->_f.parent != &_n##_rb_zero) { \ + if (old->_f.parent->_f.left == old) \ + old->_f.parent->_f.left = node; \ + else \ + old->_f.parent->_f.right = node; \ + } else { \ + head->top._f.right = child; \ + } \ + old->_f.left->_f.parent = node; \ + if (old->_f.right != &_n##_rb_zero) \ + old->_f.right->_f.parent = node; \ + if (parent != &_n##_rb_zero) { \ + left = parent; \ + } \ + goto colour; \ + } \ + parent = node->_f.parent; \ + color= node->_f.colour; \ + if (child != &_n##_rb_zero) \ + child->_f.parent = parent; \ + if (parent != &_n##_rb_zero) { \ + if (parent->_f.left == node) \ + parent->_f.left = child; \ + else \ + parent->_f.right = child; \ + } else { \ + head->top._f.right = child; \ + } \ +colour: \ + if (color == C_BLACK) \ + deleteblack(head, parent, node); \ + head->count--; \ + return old; \ +} \ + \ +void \ +_n##_rb_init(struct _n##_rb_head *head) \ +{ \ + memset(head, 0, sizeof(*head)); \ + memset(&_n##_rb_zero, 0, sizeof(_n##_rb_zero)); \ + head->top._f.left = &_n##_rb_zero; \ + head->top._f.right = &_n##_rb_zero; \ + head->top._f.parent = &head->top; \ + _n##_rb_zero._f.left = &_n##_rb_zero; \ + _n##_rb_zero._f.right = &_n##_rb_zero; \ + _n##_rb_zero._f.parent = &_n##_rb_zero; \ +} \ + \ +void \ +_n##_rb_walktree(struct _n##_rb_head *head, _n##_rb_walker_t func, void *arg)\ +{ \ + _t *prev; \ + _t *next; \ + _t *node = head->top._f.right; \ + _t *base; \ + \ + while (node != &_n##_rb_zero) \ + node = node->_f.left; \ + \ + for (;;) { \ + base = node; \ + prev = node; \ + while ((node->_f.parent->_f.right == node) && \ + (node != &_n##_rb_zero)) { \ + prev = node; \ + node = node->_f.parent; \ + } \ + \ + node = prev; \ + for (node = node->_f.parent->_f.right; node != &_n##_rb_zero;\ + node = node->_f.left) \ + prev = node; \ + next = prev; \ + \ + if (node != &_n##_rb_zero) \ + func(node, arg); \ + \ + node = next; \ + if (node == &_n##_rb_zero) \ + break; \ + } \ +} \ + \ +_t * \ +_n##_rb_search(struct _n##_rb_head *head, void *key) \ +{ \ + int match; \ + _t *node; \ + node = head->top._f.right; \ + while (node != &_n##_rb_zero) { \ + match = _cmp(key, node); \ + if (match == 0) \ + break; \ + if (match< 0) \ + node = node->_f.left; \ + else \ + node = node->_f.right; \ + } \ + if (node == &_n##_rb_zero || match != 0) \ + return (NULL); \ + return (node); \ +} + +#define RBI_DELETE(_n, _h, _v) _n##_rb_delete(_h, _v) +#define RBI_FIELD(_n) struct _n##_rb_link +#define RBI_INIT(_n, _h) _n##_rb_init(_h) +#define RBI_INSERT(_n, _h, _v) _n##_rb_insert(_h, _v) +#define RBI_ISEMPTY(_h) ((_h)->count == 0) +#define RBI_SEARCH(_n, _h, _k) _n##_rb_search(_h, _k) +#define RBI_WALK(_n, _h, _w, _a) _n##_rb_walktree(_h, _w, _a) +#define RBI_ZERO(_n) _n##_rb_zero diff --git a/sys/contrib/ipfilter/netinet/ipl.h b/sys/contrib/ipfilter/netinet/ipl.h index 4f2f122821a4..ca3baf2c926f 100644 --- a/sys/contrib/ipfilter/netinet/ipl.h +++ b/sys/contrib/ipfilter/netinet/ipl.h @@ -1,7 +1,7 @@ /* $FreeBSD$ */ /* - * Copyright (C) 1993-2001, 2003 by Darren Reed. + * Copyright (C) 2012 by Darren Reed. * * See the IPFILTER.LICENCE file for details on licencing. * @@ -13,8 +13,8 @@ #ifndef __IPL_H__ #define __IPL_H__ -#define IPL_VERSION "IP Filter: v4.1.28" +#define IPL_VERSION "IP Filter: v5.1.2" -#define IPFILTER_VERSION 4012800 +#define IPFILTER_VERSION 5010200 -#endif +#endif /* __IPL_H__ */ diff --git a/sys/contrib/ipfilter/netinet/mlfk_ipl.c b/sys/contrib/ipfilter/netinet/mlfk_ipl.c index 6dcb82159d33..3f4f2e9edf28 100644 --- a/sys/contrib/ipfilter/netinet/mlfk_ipl.c +++ b/sys/contrib/ipfilter/netinet/mlfk_ipl.c @@ -1,7 +1,7 @@ /* $FreeBSD$ */ /* - * Copyright (C) 2000 by Darren Reed. + * Copyright (C) 2012 by Darren Reed. * * $FreeBSD$ * See the IPFILTER.LICENCE file for details on licencing. @@ -18,20 +18,22 @@ #include #if __FreeBSD_version >= 500000 # include -#endif +#endif #include #include #include -#include -#include -#include -#include -#include -#include -#include -#include +#include "netinet/ipl.h" +#include "netinet/ip_compat.h" +#include "netinet/ip_fil.h" +#include "netinet/ip_state.h" +#include "netinet/ip_nat.h" +#include "netinet/ip_auth.h" +#include "netinet/ip_frag.h" +#include "netinet/ip_sync.h" + +extern ipf_main_softc_t ipfmain; #if __FreeBSD_version >= 502116 static struct cdev *ipf_devs[IPL_LOGSIZE]; @@ -39,10 +41,34 @@ static struct cdev *ipf_devs[IPL_LOGSIZE]; static dev_t ipf_devs[IPL_LOGSIZE]; #endif +#if 0 static int sysctl_ipf_int ( SYSCTL_HANDLER_ARGS ); +#endif static int ipf_modload(void); static int ipf_modunload(void); +#if (__FreeBSD_version >= 500024) +# if (__FreeBSD_version >= 502116) +static int ipfopen __P((struct cdev*, int, int, struct thread *)); +static int ipfclose __P((struct cdev*, int, int, struct thread *)); +# else +static int ipfopen __P((dev_t, int, int, struct thread *)); +static int ipfclose __P((dev_t, int, int, struct thread *)); +# endif /* __FreeBSD_version >= 502116 */ +#else +static int ipfopen __P((dev_t, int, int, struct proc *)); +static int ipfclose __P((dev_t, int, int, struct proc *)); +#endif +#if (__FreeBSD_version >= 502116) +static int ipfread __P((struct cdev*, struct uio *, int)); +static int ipfwrite __P((struct cdev*, struct uio *, int)); +#else +static int ipfread __P((dev_t, struct uio *, int)); +static int ipfwrite __P((dev_t, struct uio *, int)); +#endif /* __FreeBSD_version >= 502116 */ + + + SYSCTL_DECL(_net_inet); #define SYSCTL_IPF(parent, nbr, name, access, ptr, val, descr) \ SYSCTL_OID(parent, nbr, name, CTLTYPE_INT|access, \ @@ -50,91 +76,91 @@ SYSCTL_DECL(_net_inet); #define CTLFLAG_OFF 0x00800000 /* IPFilter must be disabled */ #define CTLFLAG_RWO (CTLFLAG_RW|CTLFLAG_OFF) SYSCTL_NODE(_net_inet, OID_AUTO, ipf, CTLFLAG_RW, 0, "IPF"); -SYSCTL_IPF(_net_inet_ipf, OID_AUTO, fr_flags, CTLFLAG_RW, &fr_flags, 0, ""); -SYSCTL_IPF(_net_inet_ipf, OID_AUTO, fr_pass, CTLFLAG_RW, &fr_pass, 0, ""); -SYSCTL_IPF(_net_inet_ipf, OID_AUTO, fr_active, CTLFLAG_RD, &fr_active, 0, ""); +#if 0 +SYSCTL_IPF(_net_inet_ipf, OID_AUTO, fr_flags, CTLFLAG_RW, &ipf_flags, 0, ""); +SYSCTL_IPF(_net_inet_ipf, OID_AUTO, ipf_pass, CTLFLAG_RW, &ipf_pass, 0, ""); +SYSCTL_IPF(_net_inet_ipf, OID_AUTO, fr_active, CTLFLAG_RD, &ipf_active, 0, ""); SYSCTL_IPF(_net_inet_ipf, OID_AUTO, fr_tcpidletimeout, CTLFLAG_RWO, - &fr_tcpidletimeout, 0, ""); + &ipf_tcpidletimeout, 0, ""); SYSCTL_IPF(_net_inet_ipf, OID_AUTO, fr_tcphalfclosed, CTLFLAG_RWO, - &fr_tcphalfclosed, 0, ""); + &ipf_tcphalfclosed, 0, ""); SYSCTL_IPF(_net_inet_ipf, OID_AUTO, fr_tcpclosewait, CTLFLAG_RWO, - &fr_tcpclosewait, 0, ""); + &ipf_tcpclosewait, 0, ""); SYSCTL_IPF(_net_inet_ipf, OID_AUTO, fr_tcplastack, CTLFLAG_RWO, - &fr_tcplastack, 0, ""); + &ipf_tcplastack, 0, ""); SYSCTL_IPF(_net_inet_ipf, OID_AUTO, fr_tcptimeout, CTLFLAG_RWO, - &fr_tcptimeout, 0, ""); + &ipf_tcptimeout, 0, ""); SYSCTL_IPF(_net_inet_ipf, OID_AUTO, fr_tcpclosed, CTLFLAG_RWO, - &fr_tcpclosed, 0, ""); + &ipf_tcpclosed, 0, ""); SYSCTL_IPF(_net_inet_ipf, OID_AUTO, fr_udptimeout, CTLFLAG_RWO, - &fr_udptimeout, 0, ""); + &ipf_udptimeout, 0, ""); SYSCTL_IPF(_net_inet_ipf, OID_AUTO, fr_udpacktimeout, CTLFLAG_RWO, - &fr_udpacktimeout, 0, ""); + &ipf_udpacktimeout, 0, ""); SYSCTL_IPF(_net_inet_ipf, OID_AUTO, fr_icmptimeout, CTLFLAG_RWO, - &fr_icmptimeout, 0, ""); + &ipf_icmptimeout, 0, ""); SYSCTL_IPF(_net_inet_ipf, OID_AUTO, fr_defnatage, CTLFLAG_RWO, - &fr_defnatage, 0, ""); + &ipf_nat_defage, 0, ""); SYSCTL_IPF(_net_inet_ipf, OID_AUTO, fr_ipfrttl, CTLFLAG_RW, - &fr_ipfrttl, 0, ""); -SYSCTL_IPF(_net_inet_ipf, OID_AUTO, fr_running, CTLFLAG_RD, - &fr_running, 0, ""); + &ipf_ipfrttl, 0, ""); +SYSCTL_IPF(_net_inet_ipf, OID_AUTO, ipf_running, CTLFLAG_RD, + &ipf_running, 0, ""); SYSCTL_IPF(_net_inet_ipf, OID_AUTO, fr_statesize, CTLFLAG_RWO, - &fr_statesize, 0, ""); + &ipf_state_size, 0, ""); SYSCTL_IPF(_net_inet_ipf, OID_AUTO, fr_statemax, CTLFLAG_RWO, - &fr_statemax, 0, ""); + &ipf_state_max, 0, ""); SYSCTL_IPF(_net_inet_ipf, OID_AUTO, ipf_nattable_sz, CTLFLAG_RWO, - &ipf_nattable_sz, 0, ""); + &ipf_nat_table_sz, 0, ""); SYSCTL_IPF(_net_inet_ipf, OID_AUTO, ipf_natrules_sz, CTLFLAG_RWO, - &ipf_natrules_sz, 0, ""); + &ipf_nat_maprules_sz, 0, ""); SYSCTL_IPF(_net_inet_ipf, OID_AUTO, ipf_rdrrules_sz, CTLFLAG_RWO, - &ipf_rdrrules_sz, 0, ""); + &ipf_nat_rdrrules_sz, 0, ""); SYSCTL_IPF(_net_inet_ipf, OID_AUTO, ipf_hostmap_sz, CTLFLAG_RWO, - &ipf_hostmap_sz, 0, ""); + &ipf_nat_hostmap_sz, 0, ""); SYSCTL_IPF(_net_inet_ipf, OID_AUTO, fr_authsize, CTLFLAG_RWO, - &fr_authsize, 0, ""); + &ipf_auth_size, 0, ""); SYSCTL_IPF(_net_inet_ipf, OID_AUTO, fr_authused, CTLFLAG_RD, - &fr_authused, 0, ""); + &ipf_auth_used, 0, ""); SYSCTL_IPF(_net_inet_ipf, OID_AUTO, fr_defaultauthage, CTLFLAG_RW, - &fr_defaultauthage, 0, ""); -SYSCTL_IPF(_net_inet_ipf, OID_AUTO, fr_chksrc, CTLFLAG_RW, &fr_chksrc, 0, ""); -SYSCTL_IPF(_net_inet_ipf, OID_AUTO, fr_minttl, CTLFLAG_RW, &fr_minttl, 0, ""); + &ipf_auth_defaultage, 0, ""); +SYSCTL_IPF(_net_inet_ipf, OID_AUTO, fr_chksrc, CTLFLAG_RW, &ipf_chksrc, 0, ""); +SYSCTL_IPF(_net_inet_ipf, OID_AUTO, fr_minttl, CTLFLAG_RW, &ipf_minttl, 0, ""); +#endif #define CDEV_MAJOR 79 #include #if __FreeBSD_version >= 500043 # include -static int iplpoll(struct cdev *dev, int events, struct thread *td); +static int ipfpoll(struct cdev *dev, int events, struct thread *td); -static struct cdevsw ipl_cdevsw = { -# if __FreeBSD_version >= 502103 +static struct cdevsw ipf_cdevsw = { +#if __FreeBSD_version >= 502103 .d_version = D_VERSION, .d_flags = 0, /* D_NEEDGIANT - Should be SMP safe */ -# endif - .d_open = iplopen, - .d_close = iplclose, - .d_read = iplread, - .d_write = iplwrite, - .d_ioctl = iplioctl, - .d_name = "ipl", -# if __FreeBSD_version >= 500043 - .d_poll = iplpoll, -# endif -# if __FreeBSD_version < 600000 +#endif + .d_open = ipfopen, + .d_close = ipfclose, + .d_read = ipfread, + .d_write = ipfwrite, + .d_ioctl = ipfioctl, + .d_poll = ipfpoll, + .d_name = "ipf", +#if __FreeBSD_version < 600000 .d_maj = CDEV_MAJOR, -# endif +#endif }; #else -static int iplpoll(dev_t dev, int events, struct proc *p); +static int ipfpoll(dev_t dev, int events, struct proc *td); -static struct cdevsw ipl_cdevsw = { - /* open */ iplopen, - /* close */ iplclose, - /* read */ iplread, - /* write */ iplwrite, - /* ioctl */ iplioctl, - /* poll */ iplpoll, +static struct cdevsw ipf_cdevsw = { + /* open */ ipfopen, + /* close */ ipfclose, + /* read */ ipfread, + /* write */ ipfwrite, + /* ioctl */ ipfioctl, + /* poll */ ipfpoll, /* mmap */ nommap, /* strategy */ nostrategy, - /* name */ "ipl", + /* name */ "ipf", /* maj */ CDEV_MAJOR, /* dump */ nodump, /* psize */ nopsize, @@ -142,7 +168,7 @@ static struct cdevsw ipl_cdevsw = { # if (__FreeBSD_version < 500043) /* bmaj */ -1, # endif -# if (__FreeBSD_version > 430000) +# if (__FreeBSD_version >= 430000) /* kqfilter */ NULL # endif }; @@ -180,17 +206,15 @@ ipf_modload() char *defpass, *c, *str; int i, j, error; - RWLOCK_INIT(&ipf_global, "ipf filter load/unload mutex"); - RWLOCK_INIT(&ipf_mutex, "ipf filter rwlock"); - RWLOCK_INIT(&ipf_frcache, "ipf cache rwlock"); + if (ipf_load_all() != 0) + return EIO; - error = ipfattach(); - if (error) { - RW_DESTROY(&ipf_global); - RW_DESTROY(&ipf_mutex); - RW_DESTROY(&ipf_frcache); + if (ipf_create_all(&ipfmain) == NULL) + return EIO; + + error = ipfattach(&ipfmain); + if (error) return error; - } for (i = 0; i < IPL_LOGSIZE; i++) ipf_devs[i] = NULL; @@ -204,7 +228,7 @@ ipf_modload() } if (!c) c = str; - ipf_devs[i] = make_dev(&ipl_cdevsw, i, 0, 0, 0600, "%s", c); + ipf_devs[i] = make_dev(&ipf_cdevsw, i, 0, 0, 0600, "%s", c); } error = ipf_pfil_hook(); @@ -212,15 +236,15 @@ ipf_modload() return error; ipf_event_reg(); - if (FR_ISPASS(fr_pass)) + if (FR_ISPASS(ipfmain.ipf_pass)) defpass = "pass"; - else if (FR_ISBLOCK(fr_pass)) + else if (FR_ISBLOCK(ipfmain.ipf_pass)) defpass = "block"; - else + else defpass = "no-match -> block"; printf("%s initialized. Default = %s all, Logging = %s%s\n", - ipfilter_version, defpass, + ipfilter_version, defpass, #ifdef IPFILTER_LOG "enabled", #else @@ -231,7 +255,7 @@ ipf_modload() #else "" #endif - ); + ); return 0; } @@ -241,25 +265,24 @@ ipf_modunload() { int error, i; - if (fr_refcnt) + if (ipfmain.ipf_refcnt) return EBUSY; - if (fr_running >= 0) { - ipf_pfil_unhook(); - ipf_event_dereg(); - WRITE_ENTER(&ipf_global); - error = ipfdetach(); - RWLOCK_EXIT(&ipf_global); + error = ipf_pfil_unhook(); + if (error != 0) + return error; + + if (ipfmain.ipf_running >= 0) { + error = ipfdetach(&ipfmain); if (error != 0) return error; + + ipf_destroy_all(&ipfmain); + ipf_unload_all(); } else error = 0; - RW_DESTROY(&ipf_global); - RW_DESTROY(&ipf_mutex); - RW_DESTROY(&ipf_frcache); - - fr_running = -2; + ipfmain.ipf_running = -2; for (i = 0; ipf_devfiles[i]; i++) { if (ipf_devs[i] != NULL) @@ -285,6 +308,7 @@ MODULE_VERSION(ipfilter, 1); #endif +#if 0 #ifdef SYSCTL_IPF int sysctl_ipf_int ( SYSCTL_HANDLER_ARGS ) @@ -302,7 +326,7 @@ sysctl_ipf_int ( SYSCTL_HANDLER_ARGS ) if (!arg1) error = EPERM; else { - if ((oidp->oid_kind & CTLFLAG_OFF) && (fr_running > 0)) + if ((oidp->oid_kind & CTLFLAG_OFF) && (ipfmain.ipf_running > 0)) error = EBUSY; else error = SYSCTL_IN(req, arg1, sizeof(int)); @@ -310,44 +334,43 @@ sysctl_ipf_int ( SYSCTL_HANDLER_ARGS ) return (error); } #endif +#endif static int #if __FreeBSD_version >= 500043 -iplpoll(struct cdev *dev, int events, struct thread *td) +ipfpoll(struct cdev *dev, int events, struct thread *td) #else -iplpoll(dev_t dev, int events, struct proc *td) +ipfpoll(dev_t dev, int events, struct proc *td) #endif { - u_int xmin = GET_MINOR(dev); + int unit = GET_MINOR(dev); int revents; - if (xmin < 0 || xmin > IPL_LOGMAX) + if (unit < 0 || unit > IPL_LOGMAX) return 0; revents = 0; - switch (xmin) + switch (unit) { case IPL_LOGIPF : case IPL_LOGNAT : case IPL_LOGSTATE : #ifdef IPFILTER_LOG - if ((events & (POLLIN | POLLRDNORM)) && ipflog_canread(xmin)) + if ((events & (POLLIN | POLLRDNORM)) && ipf_log_canread(&ipfmain, unit)) revents |= events & (POLLIN | POLLRDNORM); -#endif +#endif break; case IPL_LOGAUTH : - if ((events & (POLLIN | POLLRDNORM)) && fr_auth_waiting()) + if ((events & (POLLIN | POLLRDNORM)) && ipf_auth_waiting(&ipfmain)) revents |= events & (POLLIN | POLLRDNORM); - break; + break; case IPL_LOGSYNC : -#ifdef IPFILTER_SYNC - if ((events & (POLLIN | POLLRDNORM)) && ipfsync_canread()) + if ((events & (POLLIN | POLLRDNORM)) && ipf_sync_canread(&ipfmain)) revents |= events & (POLLIN | POLLRDNORM); - if ((events & (POLLOUT | POLLWRNORM)) && ipfsync_canwrite()) + if ((events & (POLLOUT | POLLWRNORM)) && ipf_sync_canwrite(&ipfmain)) revents |= events & (POLLOUT | POLLWRNORM); -#endif break; case IPL_LOGSCAN : case IPL_LOGLOOKUP : @@ -356,7 +379,152 @@ iplpoll(dev_t dev, int events, struct proc *td) } if ((revents == 0) && ((events & (POLLIN|POLLRDNORM)) != 0)) - selrecord(td, &ipfselwait[xmin]); + selrecord(td, &ipfmain.ipf_selwait[unit]); return revents; } + + +/* + * routines below for saving IP headers to buffer + */ +static int ipfopen(dev, flags +#if ((BSD >= 199506) || (__FreeBSD_version >= 220000)) +, devtype, p) + int devtype; +# if (__FreeBSD_version >= 500024) + struct thread *p; +# else + struct proc *p; +# endif /* __FreeBSD_version >= 500024 */ +#else +) +#endif +#if (__FreeBSD_version >= 502116) + struct cdev *dev; +#else + dev_t dev; +#endif + int flags; +{ + int unit = GET_MINOR(dev); + int error; + + if (IPL_LOGMAX < unit) + error = ENXIO; + else { + switch (unit) + { + case IPL_LOGIPF : + case IPL_LOGNAT : + case IPL_LOGSTATE : + case IPL_LOGAUTH : + case IPL_LOGLOOKUP : + case IPL_LOGSYNC : +#ifdef IPFILTER_SCAN + case IPL_LOGSCAN : +#endif + error = 0; + break; + default : + error = ENXIO; + break; + } + } + return error; +} + + +static int ipfclose(dev, flags +#if ((BSD >= 199506) || (__FreeBSD_version >= 220000)) +, devtype, p) + int devtype; +# if (__FreeBSD_version >= 500024) + struct thread *p; +# else + struct proc *p; +# endif /* __FreeBSD_version >= 500024 */ +#else +) +#endif +#if (__FreeBSD_version >= 502116) + struct cdev *dev; +#else + dev_t dev; +#endif + int flags; +{ + int unit = GET_MINOR(dev); + + if (IPL_LOGMAX < unit) + unit = ENXIO; + else + unit = 0; + return unit; +} + +/* + * ipfread/ipflog + * both of these must operate with at least splnet() lest they be + * called during packet processing and cause an inconsistancy to appear in + * the filter lists. + */ +#if (BSD >= 199306) +static int ipfread(dev, uio, ioflag) + int ioflag; +#else +static int ipfread(dev, uio) +#endif +#if (__FreeBSD_version >= 502116) + struct cdev *dev; +#else + dev_t dev; +#endif + struct uio *uio; +{ + int unit = GET_MINOR(dev); + + if (unit < 0) + return ENXIO; + + if (ipfmain.ipf_running < 1) + return EIO; + + if (unit == IPL_LOGSYNC) + return ipf_sync_read(&ipfmain, uio); + +#ifdef IPFILTER_LOG + return ipf_log_read(&ipfmain, unit, uio); +#else + return ENXIO; +#endif +} + + +/* + * ipfwrite + * both of these must operate with at least splnet() lest they be + * called during packet processing and cause an inconsistancy to appear in + * the filter lists. + */ +#if (BSD >= 199306) +static int ipfwrite(dev, uio, ioflag) + int ioflag; +#else +static int ipfwrite(dev, uio) +#endif +#if (__FreeBSD_version >= 502116) + struct cdev *dev; +#else + dev_t dev; +#endif + struct uio *uio; +{ + + if (ipfmain.ipf_running < 1) + return EIO; + + if (GET_MINOR(dev) == IPL_LOGSYNC) + return ipf_sync_write(&ipfmain, uio); + return ENXIO; +} diff --git a/sys/contrib/ipfilter/netinet/radix_ipf.c b/sys/contrib/ipfilter/netinet/radix_ipf.c new file mode 100644 index 000000000000..f145c38a94d6 --- /dev/null +++ b/sys/contrib/ipfilter/netinet/radix_ipf.c @@ -0,0 +1,1528 @@ +/* + * Copyright (C) 2012 by Darren Reed. + * + * See the IPFILTER.LICENCE file for details on licencing. + */ +#include +#include +#include +#include +#include +#include +#if !defined(_KERNEL) +# include +# include +# include +# include +#endif +#include "netinet/ip_compat.h" +#include "netinet/ip_fil.h" +#ifdef RDX_DEBUG +# include +# include +# include +#endif +#include "netinet/radix_ipf.h" + +#define ADF_OFF offsetof(addrfamily_t, adf_addr) +#define ADF_OFF_BITS (ADF_OFF << 3) + +static ipf_rdx_node_t *ipf_rx_insert __P((ipf_rdx_head_t *, + ipf_rdx_node_t nodes[2], int *)); +static void ipf_rx_attach_mask __P((ipf_rdx_node_t *, ipf_rdx_mask_t *)); +static int count_mask_bits __P((addrfamily_t *, u_32_t **)); +static void buildnodes __P((addrfamily_t *, addrfamily_t *, + ipf_rdx_node_t n[2])); +static ipf_rdx_node_t *ipf_rx_find_addr __P((ipf_rdx_node_t *, u_32_t *)); +static ipf_rdx_node_t *ipf_rx_lookup __P((ipf_rdx_head_t *, addrfamily_t *, + addrfamily_t *)); +static ipf_rdx_node_t *ipf_rx_match __P((ipf_rdx_head_t *, addrfamily_t *)); + +/* + * Foreword. + * --------- + * The code in this file has been written to target using the addrfamily_t + * data structure to house the address information and no other. Thus there + * are certain aspects of thise code (such as offsets to the address itself) + * that are hard coded here whilst they might be more variable elsewhere. + * Similarly, this code enforces no maximum key length as that's implied by + * all keys needing to be stored in addrfamily_t. + */ + +/* ------------------------------------------------------------------------ */ +/* Function: count_mask_bits */ +/* Returns: number of consecutive bits starting at "mask". */ +/* */ +/* Count the number of bits set in the address section of addrfamily_t and */ +/* return both that number and a pointer to the last word with a bit set if */ +/* lastp is not NULL. The bit count is performed using network byte order */ +/* as the guide for which bit is the most significant bit. */ +/* ------------------------------------------------------------------------ */ +static int +count_mask_bits(mask, lastp) + addrfamily_t *mask; + u_32_t **lastp; +{ + u_32_t *mp = (u_32_t *)&mask->adf_addr; + u_32_t m; + int count = 0; + int mlen; + + mlen = mask->adf_len - offsetof(addrfamily_t, adf_addr); + for (; mlen > 0; mlen -= 4, mp++) { + if ((m = ntohl(*mp)) == 0) + break; + if (lastp != NULL) + *lastp = mp; + for (; m & 0x80000000; m <<= 1) + count++; + } + + return count; +} + + +/* ------------------------------------------------------------------------ */ +/* Function: buildnodes */ +/* Returns: Nil */ +/* Parameters: addr(I) - network address for this radix node */ +/* mask(I) - netmask associated with the above address */ +/* nodes(O) - pair of ipf_rdx_node_t's to initialise with data */ +/* associated with addr and mask. */ +/* */ +/* Initialise the fields in a pair of radix tree nodes according to the */ +/* data supplied in the paramters "addr" and "mask". It is expected that */ +/* "mask" will contain a consecutive string of bits set. Masks with gaps in */ +/* the middle are not handled by this implementation. */ +/* ------------------------------------------------------------------------ */ +static void +buildnodes(addr, mask, nodes) + addrfamily_t *addr, *mask; + ipf_rdx_node_t nodes[2]; +{ + u_32_t maskbits; + u_32_t lastbits; + u_32_t lastmask; + u_32_t *last; + int masklen; + + last = NULL; + maskbits = count_mask_bits(mask, &last); + if (last == NULL) { + masklen = 0; + lastmask = 0; + } else { + masklen = last - (u_32_t *)mask; + lastmask = *last; + } + lastbits = maskbits & 0x1f; + + bzero(&nodes[0], sizeof(ipf_rdx_node_t) * 2); + nodes[0].maskbitcount = maskbits; + nodes[0].index = -1 - (ADF_OFF_BITS + maskbits); + nodes[0].addrkey = (u_32_t *)addr; + nodes[0].maskkey = (u_32_t *)mask; + nodes[0].addroff = nodes[0].addrkey + masklen; + nodes[0].maskoff = nodes[0].maskkey + masklen; + nodes[0].parent = &nodes[1]; + nodes[0].offset = masklen; + nodes[0].lastmask = lastmask; + nodes[1].offset = masklen; + nodes[1].left = &nodes[0]; + nodes[1].maskbitcount = maskbits; +#ifdef RDX_DEBUG + (void) strcpy(nodes[0].name, "_BUILD.0"); + (void) strcpy(nodes[1].name, "_BUILD.1"); +#endif +} + + +/* ------------------------------------------------------------------------ */ +/* Function: ipf_rx_find_addr */ +/* Returns: ipf_rdx_node_t * - pointer to a node in the radix tree. */ +/* Parameters: tree(I) - pointer to first right node in tree to search */ +/* addr(I) - pointer to address to match */ +/* */ +/* Walk the radix tree given by "tree", looking for a leaf node that is a */ +/* match for the address given by "addr". */ +/* ------------------------------------------------------------------------ */ +static ipf_rdx_node_t * +ipf_rx_find_addr(tree, addr) + ipf_rdx_node_t *tree; + u_32_t *addr; +{ + ipf_rdx_node_t *cur; + + for (cur = tree; cur->index >= 0;) { + if (cur->bitmask & addr[cur->offset]) { + cur = cur->right; + } else { + cur = cur->left; + } + } + + return (cur); +} + + +/* ------------------------------------------------------------------------ */ +/* Function: ipf_rx_match */ +/* Returns: ipf_rdx_node_t * - NULL on error, else pointer to the node */ +/* added to the tree. */ +/* Paramters: head(I) - pointer to tree head to search */ +/* addr(I) - pointer to address to find */ +/* */ +/* Search the radix tree for the best match to the address pointed to by */ +/* "addr" and return a pointer to that node. This search will not match the */ +/* address information stored in either of the root leaves as neither of */ +/* them are considered to be part of the tree of data being stored. */ +/* ------------------------------------------------------------------------ */ +static ipf_rdx_node_t * +ipf_rx_match(head, addr) + ipf_rdx_head_t *head; + addrfamily_t *addr; +{ + ipf_rdx_mask_t *masknode; + ipf_rdx_node_t *prev; + ipf_rdx_node_t *node; + ipf_rdx_node_t *cur; + u_32_t *data; + u_32_t *mask; + u_32_t *key; + u_32_t *end; + int len; + int i; + + len = addr->adf_len; + end = (u_32_t *)((u_char *)addr + len); + node = ipf_rx_find_addr(head->root, (u_32_t *)addr); + + /* + * Search the dupkey list for a potential match. + */ + for (cur = node; (cur != NULL) && (cur->root == 0); cur = cur->dupkey) { + i = cur[0].addroff - cur[0].addrkey; + data = cur[0].addrkey + i; + mask = cur[0].maskkey + i; + key = (u_32_t *)addr + i; + for (; key < end; data++, key++, mask++) + if ((*key & *mask) != *data) + break; + if ((end == key) && (cur->root == 0)) + return (cur); /* Equal keys */ + } + prev = node->parent; + key = (u_32_t *)addr; + + for (node = prev; node->root == 0; node = node->parent) { + /* + * We know that the node hasn't matched so therefore only + * the entries in the mask list are searched, not the top + * node nor the dupkey list. + */ + masknode = node->masks; + for (; masknode != NULL; masknode = masknode->next) { + if (masknode->maskbitcount > node->maskbitcount) + continue; + cur = masknode->node; + for (i = ADF_OFF >> 2; i <= node->offset; i++) { + if ((key[i] & masknode->mask[i]) == + cur->addrkey[i]) + return (cur); + } + } + } + + return NULL; +} + + +/* ------------------------------------------------------------------------ */ +/* Function: ipf_rx_lookup */ +/* Returns: ipf_rdx_node_t * - NULL on error, else pointer to the node */ +/* added to the tree. */ +/* Paramters: head(I) - pointer to tree head to search */ +/* addr(I) - address part of the key to match */ +/* mask(I) - netmask part of the key to match */ +/* */ +/* ipf_rx_lookup searches for an exact match on (addr,mask). The intention */ +/* is to see if a given key is in the tree, not to see if a route exists. */ +/* ------------------------------------------------------------------------ */ +ipf_rdx_node_t * +ipf_rx_lookup(head, addr, mask) + ipf_rdx_head_t *head; + addrfamily_t *addr, *mask; +{ + ipf_rdx_node_t *found; + ipf_rdx_node_t *node; + u_32_t *akey; + int count; + + found = ipf_rx_find_addr(head->root, (u_32_t *)addr); + if (found->root == 1) + return NULL; + + /* + * It is possible to find a matching address in the tree but for the + * netmask to not match. If the netmask does not match and there is + * no list of alternatives present at dupkey, return a failure. + */ + count = count_mask_bits(mask, NULL); + if (count != found->maskbitcount && found->dupkey == NULL) + return (NULL); + + akey = (u_32_t *)addr; + if ((found->addrkey[found->offset] & found->maskkey[found->offset]) != + akey[found->offset]) + return NULL; + + if (found->dupkey != NULL) { + node = found; + while (node != NULL && node->maskbitcount != count) + node = node->dupkey; + if (node == NULL) + return (NULL); + found = node; + } + return found; +} + + +/* ------------------------------------------------------------------------ */ +/* Function: ipf_rx_attach_mask */ +/* Returns: Nil */ +/* Parameters: node(I) - pointer to a radix tree node */ +/* mask(I) - pointer to mask structure to add */ +/* */ +/* Add the netmask to the given node in an ordering where the most specific */ +/* netmask is at the top of the list. */ +/* ------------------------------------------------------------------------ */ +static void +ipf_rx_attach_mask(node, mask) + ipf_rdx_node_t *node; + ipf_rdx_mask_t *mask; +{ + ipf_rdx_mask_t **pm; + ipf_rdx_mask_t *m; + + for (pm = &node->masks; (m = *pm) != NULL; pm = &m->next) + if (m->maskbitcount < mask->maskbitcount) + break; + mask->next = *pm; + *pm = mask; +} + + +/* ------------------------------------------------------------------------ */ +/* Function: ipf_rx_insert */ +/* Returns: ipf_rdx_node_t * - NULL on error, else pointer to the node */ +/* added to the tree. */ +/* Paramters: head(I) - pointer to tree head to add nodes to */ +/* nodes(I) - pointer to radix nodes to be added */ +/* dup(O) - set to 1 if node is a duplicate, else 0. */ +/* */ +/* Add the new radix tree entry that owns nodes[] to the tree given by head.*/ +/* If there is already a matching key in the table, "dup" will be set to 1 */ +/* and the existing node pointer returned if there is a complete key match. */ +/* A complete key match is a matching of all key data that is presented by */ +/* by the netmask. */ +/* ------------------------------------------------------------------------ */ +static ipf_rdx_node_t * +ipf_rx_insert(head, nodes, dup) + ipf_rdx_head_t *head; + ipf_rdx_node_t nodes[2]; + int *dup; +{ + ipf_rdx_mask_t **pmask; + ipf_rdx_node_t *node; + ipf_rdx_node_t *prev; + ipf_rdx_mask_t *mask; + ipf_rdx_node_t *cur; + u_32_t nodemask; + u_32_t *addr; + u_32_t *data; + int nodebits; + u_32_t *key; + u_32_t *end; + u_32_t bits; + int nodekey; + int nodeoff; + int nlen; + int len; + + addr = nodes[0].addrkey; + + node = ipf_rx_find_addr(head->root, addr); + len = ((addrfamily_t *)addr)->adf_len; + key = (u_32_t *)&((addrfamily_t *)addr)->adf_addr; + data= (u_32_t *)&((addrfamily_t *)node->addrkey)->adf_addr; + end = (u_32_t *)((u_char *)addr + len); + for (nlen = 0; key < end; data++, key++, nlen += 32) + if (*key != *data) + break; + if (end == data) { + *dup = 1; + return (node); /* Equal keys */ + } + *dup = 0; + + bits = (ntohl(*data) ^ ntohl(*key)); + for (; bits != 0; nlen++) { + if ((bits & 0x80000000) != 0) + break; + bits <<= 1; + } + nlen += ADF_OFF_BITS; + nodes[1].index = nlen; + nodes[1].bitmask = htonl(0x80000000 >> (nlen & 0x1f)); + nodes[0].offset = nlen / 32; + nodes[1].offset = nlen / 32; + + /* + * Walk through the tree and look for the correct place to attach + * this node. ipf_rx_fin_addr is not used here because the place + * to attach this node may be an internal node (same key, different + * netmask.) Additionally, the depth of the search is forcibly limited + * here to not exceed the netmask, so that a short netmask will be + * added higher up the tree even if there are lower branches. + */ + cur = head->root; + key = nodes[0].addrkey; + do { + prev = cur; + if (key[cur->offset] & cur->bitmask) { + cur = cur->right; + } else { + cur = cur->left; + } + } while (nlen > (unsigned)cur->index); + + if ((key[prev->offset] & prev->bitmask) == 0) { + prev->left = &nodes[1]; + } else { + prev->right = &nodes[1]; + } + cur->parent = &nodes[1]; + nodes[1].parent = prev; + if ((key[nodes[1].offset] & nodes[1].bitmask) == 0) { + nodes[1].right = cur; + } else { + nodes[1].right = &nodes[0]; + nodes[1].left = cur; + } + + nodeoff = nodes[0].offset; + nodekey = nodes[0].addrkey[nodeoff]; + nodemask = nodes[0].lastmask; + nodebits = nodes[0].maskbitcount; + prev = NULL; + /* + * Find the node up the tree with the largest pattern that still + * matches the node being inserted to see if this mask can be + * moved there. + */ + for (cur = nodes[1].parent; cur->root == 0; cur = cur->parent) { + if (cur->maskbitcount <= nodebits) + break; + if (((cur - 1)->addrkey[nodeoff] & nodemask) != nodekey) + break; + prev = cur; + } + + KMALLOC(mask, ipf_rdx_mask_t *); + if (mask == NULL) + return NULL; + bzero(mask, sizeof(*mask)); + mask->next = NULL; + mask->node = &nodes[0]; + mask->maskbitcount = nodebits; + mask->mask = nodes[0].maskkey; + nodes[0].mymask = mask; + + if (prev != NULL) { + ipf_rdx_mask_t *m; + + for (pmask = &prev->masks; (m = *pmask) != NULL; + pmask = &m->next) { + if (m->maskbitcount < nodebits) + break; + } + } else { + /* + * No higher up nodes qualify, so attach mask locally. + */ + pmask = &nodes[0].masks; + } + mask->next = *pmask; + *pmask = mask; + + /* + * Search the mask list on each child to see if there are any masks + * there that can be moved up to this newly inserted node. + */ + cur = nodes[1].right; + if (cur->root == 0) { + for (pmask = &cur->masks; (mask = *pmask) != NULL; ) { + if (mask->maskbitcount < nodebits) { + *pmask = mask->next; + ipf_rx_attach_mask(&nodes[0], mask); + } else { + pmask = &mask->next; + } + } + } + cur = nodes[1].left; + if (cur->root == 0 && cur != &nodes[0]) { + for (pmask = &cur->masks; (mask = *pmask) != NULL; ) { + if (mask->maskbitcount < nodebits) { + *pmask = mask->next; + ipf_rx_attach_mask(&nodes[0], mask); + } else { + pmask = &mask->next; + } + } + } + return (&nodes[0]); +} + +/* ------------------------------------------------------------------------ */ +/* Function: ipf_rx_addroute */ +/* Returns: ipf_rdx_node_t * - NULL on error, else pointer to the node */ +/* added to the tree. */ +/* Paramters: head(I) - pointer to tree head to search */ +/* addr(I) - address portion of "route" to add */ +/* mask(I) - netmask portion of "route" to add */ +/* nodes(I) - radix tree data nodes inside allocate structure */ +/* */ +/* Attempt to add a node to the radix tree. The key for the node is the */ +/* (addr,mask). No memory allocation for the radix nodes themselves is */ +/* performed here, the data structure that this radix node is being used to */ +/* find is expected to house the node data itself however the call to */ +/* ipf_rx_insert() will attempt to allocate memory in order for netmask to */ +/* be promoted further up the tree. */ +/* In this case, the ip_pool_node_t structure from ip_pool.h contains both */ +/* the key material (addr,mask) and the radix tree nodes[]. */ +/* */ +/* The mechanics of inserting the node into the tree is handled by the */ +/* function ipf_rx_insert() above. Here, the code deals with the case */ +/* where the data to be inserted is a duplicate. */ +/* ------------------------------------------------------------------------ */ +ipf_rdx_node_t * +ipf_rx_addroute(head, addr, mask, nodes) + ipf_rdx_head_t *head; + addrfamily_t *addr, *mask; + ipf_rdx_node_t *nodes; +{ + ipf_rdx_node_t *node; + ipf_rdx_node_t *prev; + ipf_rdx_node_t *x; + int dup; + + buildnodes(addr, mask, nodes); + x = ipf_rx_insert(head, nodes, &dup); + if (x == NULL) + return NULL; + + if (dup == 1) { + node = &nodes[0]; + prev = NULL; + /* + * The duplicate list is kept sorted with the longest + * mask at the top, meaning that the most specific entry + * in the listis found first. This list thus allows for + * duplicates such as 128.128.0.0/32 and 128.128.0.0/16. + */ + while ((x != NULL) && (x->maskbitcount > node->maskbitcount)) { + prev = x; + x = x->dupkey; + } + + /* + * Is it a complete duplicate? If so, return NULL and + * fail the insert. Otherwise, insert it into the list + * of netmasks active for this key. + */ + if ((x != NULL) && (x->maskbitcount == node->maskbitcount)) + return (NULL); + + if (prev != NULL) { + nodes[0].dupkey = x; + prev->dupkey = &nodes[0]; + nodes[0].parent = prev; + if (x != NULL) + x->parent = &nodes[0]; + } else { + nodes[0].dupkey = x->dupkey; + prev = x->parent; + nodes[0].parent = prev; + x->parent = &nodes[0]; + if (prev->left == x) + prev->left = &nodes[0]; + else + prev->right = &nodes[0]; + } + } + + return &nodes[0]; +} + + +/* ------------------------------------------------------------------------ */ +/* Function: ipf_rx_delete */ +/* Returns: ipf_rdx_node_t * - NULL on error, else node removed from */ +/* the tree. */ +/* Paramters: head(I) - pointer to tree head to search */ +/* addr(I) - pointer to the address part of the key */ +/* mask(I) - pointer to the netmask part of the key */ +/* */ +/* Search for an entry in the radix tree that is an exact match for (addr, */ +/* mask) and remove it if it exists. In the case where (addr,mask) is a not */ +/* a unique key, the tree structure itself is not changed - only the list */ +/* of duplicate keys. */ +/* ------------------------------------------------------------------------ */ +ipf_rdx_node_t * +ipf_rx_delete(head, addr, mask) + ipf_rdx_head_t *head; + addrfamily_t *addr, *mask; +{ + ipf_rdx_mask_t **pmask; + ipf_rdx_node_t *parent; + ipf_rdx_node_t *found; + ipf_rdx_node_t *prev; + ipf_rdx_node_t *node; + ipf_rdx_node_t *cur; + ipf_rdx_mask_t *m; + int count; + + found = ipf_rx_find_addr(head->root, (u_32_t *)addr); + if (found == NULL) + return NULL; + if (found->root == 1) + return NULL; + count = count_mask_bits(mask, NULL); + parent = found->parent; + if (found->dupkey != NULL) { + node = found; + while (node != NULL && node->maskbitcount != count) + node = node->dupkey; + if (node == NULL) + return (NULL); + if (node != found) { + /* + * Remove from the dupkey list. Here, "parent" is + * the previous node on the list (rather than tree) + * and "dupkey" is the next node on the list. + */ + parent = node->parent; + parent->dupkey = node->dupkey; + node->dupkey->parent = parent; + } else { + /* + * + * When removing the top node of the dupkey list, + * the pointers at the top of the list that point + * to other tree nodes need to be preserved and + * any children must have their parent updated. + */ + node = node->dupkey; + node->parent = found->parent; + node->right = found->right; + node->left = found->left; + found->right->parent = node; + found->left->parent = node; + if (parent->left == found) + parent->left = node; + else + parent->right= node; + } + } else { + if (count != found->maskbitcount) + return (NULL); + /* + * Remove the node from the tree and reconnect the subtree + * below. + */ + /* + * If there is a tree to the left, look for something to + * attach in place of "found". + */ + prev = found + 1; + cur = parent->parent; + if (parent != found + 1) { + if ((found + 1)->parent->right == found + 1) + (found + 1)->parent->right = parent; + else + (found + 1)->parent->left = parent; + if (cur->right == parent) { + if (parent->left == found) { + cur->right = parent->right; + } else if (parent->left != parent - 1) { + cur->right = parent->left; + } else { + cur->right = parent - 1; + } + cur->right->parent = cur; + } else { + if (parent->right == found) { + cur->left = parent->left; + } else if (parent->right != parent - 1) { + cur->left = parent->right; + } else { + cur->left = parent - 1; + } + cur->left->parent = cur; + } + parent->left = (found + 1)->left; + if ((found + 1)->right != parent) + parent->right = (found + 1)->right; + parent->left->parent = parent; + parent->right->parent = parent; + parent->parent = (found + 1)->parent; + + parent->bitmask = prev->bitmask; + parent->offset = prev->offset; + parent->index = prev->index; + } else { + /* + * We found an edge node. + */ + cur = parent->parent; + if (cur->left == parent) { + if (parent->left == found) { + cur->left = parent->right; + parent->right->parent = cur; + } else { + cur->left = parent->left; + parent->left->parent = cur; + } + } else { + if (parent->right != found) { + cur->right = parent->right; + parent->right->parent = cur; + } else { + cur->right = parent->left; + prev->left->parent = cur; + } + } + } + } + + /* + * Remove mask associated with this node. + */ + for (cur = parent; cur->root == 0; cur = cur->parent) { + ipf_rdx_mask_t **pm; + + if (cur->maskbitcount <= found->maskbitcount) + break; + if (((cur - 1)->addrkey[found->offset] & found->bitmask) != + found->addrkey[found->offset]) + break; + for (pm = &cur->masks; (m = *pm) != NULL; ) + if (m->node == cur) { + *pm = m->next; + break; + } else { + pm = &m->next; + } + } + KFREE(found->mymask); + + /* + * Masks that have been brought up to this node from below need to + * be sent back down. + */ + for (pmask = &parent->masks; (m = *pmask) != NULL; ) { + *pmask = m->next; + cur = m->node; + if (cur == found) + continue; + if (found->addrkey[cur->offset] & cur->lastmask) { + ipf_rx_attach_mask(parent->right, m); + } else if (parent->left != found) { + ipf_rx_attach_mask(parent->left, m); + } + } + + return (found); +} + + +/* ------------------------------------------------------------------------ */ +/* Function: ipf_rx_walktree */ +/* Returns: Nil */ +/* Paramters: head(I) - pointer to tree head to search */ +/* walker(I) - function to call for each node in the tree */ +/* arg(I) - parameter to pass to walker, in addition to the */ +/* node pointer */ +/* */ +/* A standard tree walking function except that it is iterative, rather */ +/* than recursive and tracks the next node in case the "walker" function */ +/* should happen to delete and free the current node. It thus goes without */ +/* saying that the "walker" function is not permitted to cause any change */ +/* in the validity of the data found at either the left or right child. */ +/* ------------------------------------------------------------------------ */ +void +ipf_rx_walktree(head, walker, arg) + ipf_rdx_head_t *head; + radix_walk_func_t walker; + void *arg; +{ + ipf_rdx_node_t *next; + ipf_rdx_node_t *node = head->root; + ipf_rdx_node_t *base; + + while (node->index >= 0) + node = node->left; + + for (;;) { + base = node; + while ((node->parent->right == node) && (node->root == 0)) + node = node->parent; + + for (node = node->parent->right; node->index >= 0; ) + node = node->left; + next = node; + + for (node = base; node != NULL; node = base) { + base = node->dupkey; + if (node->root == 0) + walker(node, arg); + } + node = next; + if (node->root) + return; + } +} + + +/* ------------------------------------------------------------------------ */ +/* Function: ipf_rx_inithead */ +/* Returns: int - 0 = success, else failure */ +/* Paramters: softr(I) - pointer to radix context */ +/* headp(O) - location for where to store allocated tree head */ +/* */ +/* This function allocates and initialises a radix tree head structure. */ +/* As a traditional radix tree, node 0 is used as the "0" sentinel and node */ +/* "2" is used as the all ones sentinel, leaving node "1" as the root from */ +/* which the tree is hung with node "0" on its left and node "2" to the */ +/* right. The context, "softr", is used here to provide a common source of */ +/* the zeroes and ones data rather than have one per head. */ +/* ------------------------------------------------------------------------ */ +int +ipf_rx_inithead(softr, headp) + radix_softc_t *softr; + ipf_rdx_head_t **headp; +{ + ipf_rdx_head_t *ptr; + ipf_rdx_node_t *node; + + KMALLOC(ptr, ipf_rdx_head_t *); + *headp = ptr; + if (ptr == NULL) + return -1; + bzero(ptr, sizeof(*ptr)); + node = ptr->nodes; + ptr->root = node + 1; + node[0].index = ADF_OFF_BITS; + node[0].index = -1 - node[0].index; + node[1].index = ADF_OFF_BITS; + node[2].index = node[0].index; + node[0].parent = node + 1; + node[1].parent = node + 1; + node[2].parent = node + 1; + node[1].bitmask = htonl(0x80000000); + node[0].root = 1; + node[1].root = 1; + node[2].root = 1; + node[0].offset = ADF_OFF_BITS >> 5; + node[1].offset = ADF_OFF_BITS >> 5; + node[2].offset = ADF_OFF_BITS >> 5; + node[1].left = &node[0]; + node[1].right = &node[2]; + node[0].addrkey = (u_32_t *)softr->zeros; + node[2].addrkey = (u_32_t *)softr->ones; +#ifdef RDX_DEBUG + (void) strcpy(node[0].name, "0_ROOT"); + (void) strcpy(node[1].name, "1_ROOT"); + (void) strcpy(node[2].name, "2_ROOT"); +#endif + + ptr->addaddr = ipf_rx_addroute; + ptr->deladdr = ipf_rx_delete; + ptr->lookup = ipf_rx_lookup; + ptr->matchaddr = ipf_rx_match; + ptr->walktree = ipf_rx_walktree; + return 0; +} + + +/* ------------------------------------------------------------------------ */ +/* Function: ipf_rx_freehead */ +/* Returns: Nil */ +/* Paramters: head(I) - pointer to tree head to free */ +/* */ +/* This function simply free's up the radix tree head. Prior to calling */ +/* this function, it is expected that the tree will have been emptied. */ +/* ------------------------------------------------------------------------ */ +void +ipf_rx_freehead(head) + ipf_rdx_head_t *head; +{ + KFREE(head); +} + + +/* ------------------------------------------------------------------------ */ +/* Function: ipf_rx_create */ +/* Parameters: Nil */ +/* */ +/* ------------------------------------------------------------------------ */ +void * +ipf_rx_create() +{ + radix_softc_t *softr; + + KMALLOC(softr, radix_softc_t *); + if (softr == NULL) + return NULL; + bzero((char *)softr, sizeof(*softr)); + + KMALLOCS(softr->zeros, u_char *, 3 * sizeof(addrfamily_t)); + if (softr->zeros == NULL) { + KFREE(softr); + return (NULL); + } + softr->ones = softr->zeros + sizeof(addrfamily_t); + + return softr; +} + + +/* ------------------------------------------------------------------------ */ +/* Function: ipf_rx_init */ +/* Returns: int - 0 = success (always) */ +/* */ +/* ------------------------------------------------------------------------ */ +int +ipf_rx_init(ctx) + void *ctx; +{ + radix_softc_t *softr = ctx; + + memset(softr->zeros, 0, 3 * sizeof(addrfamily_t)); + memset(softr->ones, 0xff, sizeof(addrfamily_t)); + + return (0); +} + + +/* ------------------------------------------------------------------------ */ +/* Function: ipf_rx_destroy */ +/* Returns: Nil */ +/* */ +/* ------------------------------------------------------------------------ */ +void +ipf_rx_destroy(ctx) + void *ctx; +{ + radix_softc_t *softr = ctx; + + if (softr->zeros != NULL) + KFREES(softr->zeros, 3 * sizeof(addrfamily_t)); + KFREE(softr); +} + +/* ====================================================================== */ + +#ifdef RDX_DEBUG +/* + * To compile this file as a standalone test unit, use -DRDX_DEBUG=1 + */ +#define NAME(x) ((x)->index < 0 ? (x)->name : (x)->name) +#define GNAME(y) ((y) == NULL ? "NULL" : NAME(y)) + +typedef struct myst { + struct ipf_rdx_node nodes[2]; + addrfamily_t dst; + addrfamily_t mask; + struct myst *next; + int printed; +} myst_t; + +typedef struct tabe_s { + char *host; + char *mask; + char *what; +} tabe_t; + +tabe_t builtin[] = { +#if 1 + { "192:168:100::0", "48", "d" }, + { "192:168:100::2", "128", "d" }, +#else + { "127.192.0.0", "255.255.255.0", "d" }, + { "127.128.0.0", "255.255.255.0", "d" }, + { "127.96.0.0", "255.255.255.0", "d" }, + { "127.80.0.0", "255.255.255.0", "d" }, + { "127.72.0.0", "255.255.255.0", "d" }, + { "127.64.0.0", "255.255.255.0", "d" }, + { "127.56.0.0", "255.255.255.0", "d" }, + { "127.48.0.0", "255.255.255.0", "d" }, + { "127.40.0.0", "255.255.255.0", "d" }, + { "127.32.0.0", "255.255.255.0", "d" }, + { "127.24.0.0", "255.255.255.0", "d" }, + { "127.16.0.0", "255.255.255.0", "d" }, + { "127.8.0.0", "255.255.255.0", "d" }, + { "124.0.0.0", "255.0.0.0", "d" }, + { "125.0.0.0", "255.0.0.0", "d" }, + { "126.0.0.0", "255.0.0.0", "d" }, + { "127.0.0.0", "255.0.0.0", "d" }, + { "10.0.0.0", "255.0.0.0", "d" }, + { "128.250.0.0", "255.255.0.0", "d" }, + { "192.168.0.0", "255.255.0.0", "d" }, + { "192.168.1.0", "255.255.255.0", "d" }, +#endif + { NULL, NULL, NULL } +}; + +char *mtable[][1] = { +#if 1 + { "192:168:100::2" }, + { "192:168:101::2" }, +#else + { "9.0.0.0" }, + { "9.0.0.1" }, + { "11.0.0.0" }, + { "11.0.0.1" }, + { "127.0.0.1" }, + { "127.0.1.0" }, + { "255.255.255.0" }, + { "126.0.0.1" }, + { "128.251.0.0" }, + { "128.251.0.1" }, + { "128.251.255.255" }, + { "129.250.0.0" }, + { "129.250.0.1" }, + { "192.168.255.255" }, +#endif + { NULL } +}; + + +int forder[22] = { + 14, 13, 12, 5, 10, 3, 19, 7, 4, 20, 8, + 2, 17, 9, 16, 11, 15, 1, 6, 18, 0, 21 +}; + +static int nodecount = 0; +myst_t *myst_top = NULL; +tabe_t *ttable = NULL; + +void add_addr(ipf_rdx_head_t *, int , int); +void checktree(ipf_rdx_head_t *); +void delete_addr(ipf_rdx_head_t *rnh, int item); +void dumptree(ipf_rdx_head_t *rnh); +void nodeprinter(ipf_rdx_node_t *, void *); +void printroots(ipf_rdx_head_t *); +void random_add(ipf_rdx_head_t *); +void random_delete(ipf_rdx_head_t *); +void test_addr(ipf_rdx_head_t *rnh, int pref, addrfamily_t *, int); + + +static void +ipf_rx_freenode(node, arg) + ipf_rdx_node_t *node; + void *arg; +{ + ipf_rdx_head_t *head = arg; + ipf_rdx_node_t *rv; + myst_t *stp; + + stp = (myst_t *)node; + rv = ipf_rx_delete(head, &stp->dst, &stp->mask); + if (rv != NULL) { + free(rv); + } +} + + +const char * +addrname(ap) + addrfamily_t *ap; +{ + static char name[80]; + const char *txt; + + bzero((char *)name, sizeof(name)); + txt = inet_ntop(ap->adf_family, &ap->adf_addr, name, + sizeof(name)); + return txt; +} + + +void +fill6bits(bits, msk) + int bits; + u_int *msk; +{ + if (bits == 0) { + msk[0] = 0; + msk[1] = 0; + msk[2] = 0; + msk[3] = 0; + return; + } + + msk[0] = 0xffffffff; + msk[1] = 0xffffffff; + msk[2] = 0xffffffff; + msk[3] = 0xffffffff; + + if (bits == 128) + return; + if (bits > 96) { + msk[3] = htonl(msk[3] << (128 - bits)); + } else if (bits > 64) { + msk[3] = 0; + msk[2] = htonl(msk[2] << (96 - bits)); + } else if (bits > 32) { + msk[3] = 0; + msk[2] = 0; + msk[1] = htonl(msk[1] << (64 - bits)); + } else { + msk[3] = 0; + msk[2] = 0; + msk[1] = 0; + msk[0] = htonl(msk[0] << (32 - bits)); + } +} + + +void +setaddr(afp, str) + addrfamily_t *afp; + char *str; +{ + + bzero((char *)afp, sizeof(*afp)); + + if (strchr(str, ':') == NULL) { + afp->adf_family = AF_INET; + afp->adf_len = offsetof(addrfamily_t, adf_addr) + 4; + } else { + afp->adf_family = AF_INET6; + afp->adf_len = offsetof(addrfamily_t, adf_addr) + 16; + } + inet_pton(afp->adf_family, str, &afp->adf_addr); +} + + +void +setmask(afp, str) + addrfamily_t *afp; + char *str; +{ + if (strchr(str, '.') != NULL) { + afp->adf_addr.in4.s_addr = inet_addr(str); + afp->adf_len = offsetof(addrfamily_t, adf_addr) + 4; + } else if (afp->adf_family == AF_INET) { + afp->adf_addr.i6[0] = htonl(0xffffffff << (32 - atoi(str))); + afp->adf_len = offsetof(addrfamily_t, adf_addr) + 4; + } else if (afp->adf_family == AF_INET6) { + fill6bits(atoi(str), afp->adf_addr.i6); + afp->adf_len = offsetof(addrfamily_t, adf_addr) + 16; + } +} + + +void +nodeprinter(node, arg) + ipf_rdx_node_t *node; + void *arg; +{ + myst_t *stp = (myst_t *)node; + + printf("Node %-9.9s L %-9.9s R %-9.9s P %9.9s/%-9.9s %s/%d\n", + node[0].name, + GNAME(node[1].left), GNAME(node[1].right), + GNAME(node[0].parent), GNAME(node[1].parent), + addrname(&stp->dst), node[0].maskbitcount); + if (stp->printed == -1) + printf("!!! %d\n", stp->printed); + else + stp->printed = 1; +} + + +void +printnode(stp) + myst_t *stp; +{ + ipf_rdx_node_t *node = &stp->nodes[0]; + + if (stp->nodes[0].index > 0) + stp = (myst_t *)&stp->nodes[-1]; + + printf("Node %-9.9s ", node[0].name); + printf("L %-9.9s ", GNAME(node[1].left)); + printf("R %-9.9s ", GNAME(node[1].right)); + printf("P %9.9s", GNAME(node[0].parent)); + printf("/%-9.9s ", GNAME(node[1].parent)); + printf("%s P%d\n", addrname(&stp->dst), stp->printed); +} + + +void +buildtab(void) +{ + char line[80], *s; + tabe_t *tab; + int lines; + FILE *fp; + + lines = 0; + fp = fopen("hosts", "r"); + + while (fgets(line, sizeof(line), fp) != NULL) { + s = strchr(line, '\n'); + if (s != NULL) + *s = '\0'; + lines++; + if (lines == 1) + tab = malloc(sizeof(*tab) * 2); + else + tab = realloc(tab, (lines + 1) * sizeof(*tab)); + tab[lines - 1].host = strdup(line); + s = strchr(tab[lines - 1].host, '/'); + *s++ = '\0'; + tab[lines - 1].mask = s; + tab[lines - 1].what = "d"; + } + fclose(fp); + + tab[lines].host = NULL; + tab[lines].mask = NULL; + tab[lines].what = NULL; + ttable = tab; +} + + +void +printroots(rnh) + ipf_rdx_head_t *rnh; +{ + printf("Root.0.%s b %3d p %-9.9s l %-9.9s r %-9.9s\n", + GNAME(&rnh->nodes[0]), + rnh->nodes[0].index, GNAME(rnh->nodes[0].parent), + GNAME(rnh->nodes[0].left), GNAME(rnh->nodes[0].right)); + printf("Root.1.%s b %3d p %-9.9s l %-9.9s r %-9.9s\n", + GNAME(&rnh->nodes[1]), + rnh->nodes[1].index, GNAME(rnh->nodes[1].parent), + GNAME(rnh->nodes[1].left), GNAME(rnh->nodes[1].right)); + printf("Root.2.%s b %3d p %-9.9s l %-9.9s r %-9.9s\n", + GNAME(&rnh->nodes[2]), + rnh->nodes[2].index, GNAME(rnh->nodes[2].parent), + GNAME(rnh->nodes[2].left), GNAME(rnh->nodes[2].right)); +} + + +int +main(int argc, char *argv[]) +{ + addrfamily_t af; + ipf_rdx_head_t *rnh; + radix_softc_t *ctx; + int j; + int i; + + rnh = NULL; + + buildtab(); + ctx = ipf_rx_create(); + ipf_rx_init(ctx); + ipf_rx_inithead(ctx, &rnh); + + printf("=== ADD-0 ===\n"); + for (i = 0; ttable[i].host != NULL; i++) { + add_addr(rnh, i, i); + checktree(rnh); + } + printroots(rnh); + ipf_rx_walktree(rnh, nodeprinter, NULL); + printf("=== DELETE-0 ===\n"); + for (i = 0; ttable[i].host != NULL; i++) { + delete_addr(rnh, i); + printroots(rnh); + ipf_rx_walktree(rnh, nodeprinter, NULL); + } + printf("=== ADD-1 ===\n"); + for (i = 0; ttable[i].host != NULL; i++) { + setaddr(&af, ttable[i].host); + add_addr(rnh, i, i); /*forder[i]); */ + checktree(rnh); + } + dumptree(rnh); + ipf_rx_walktree(rnh, nodeprinter, NULL); + printf("=== TEST-1 ===\n"); + for (i = 0; ttable[i].host != NULL; i++) { + setaddr(&af, ttable[i].host); + test_addr(rnh, i, &af, -1); + } + + printf("=== TEST-2 ===\n"); + for (i = 0; mtable[i][0] != NULL; i++) { + setaddr(&af, mtable[i][0]); + test_addr(rnh, i, &af, -1); + } + printf("=== DELETE-1 ===\n"); + for (i = 0; ttable[i].host != NULL; i++) { + if (ttable[i].what[0] != 'd') + continue; + delete_addr(rnh, i); + for (j = 0; ttable[j].host != NULL; j++) { + setaddr(&af, ttable[j].host); + test_addr(rnh, i, &af, 3); + } + printroots(rnh); + ipf_rx_walktree(rnh, nodeprinter, NULL); + } + + dumptree(rnh); + + printf("=== ADD-2 ===\n"); + random_add(rnh); + checktree(rnh); + dumptree(rnh); + ipf_rx_walktree(rnh, nodeprinter, NULL); + printf("=== DELETE-2 ===\n"); + random_delete(rnh); + checktree(rnh); + dumptree(rnh); + + ipf_rx_walktree(rnh, ipf_rx_freenode, rnh); + + return 0; +} + + +void +dumptree(rnh) + ipf_rdx_head_t *rnh; +{ + myst_t *stp; + + printf("VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV\n"); + printroots(rnh); + for (stp = myst_top; stp; stp = stp->next) + printnode(stp); + printf("^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n"); +} + + +void +test_addr(rnh, pref, addr, limit) + ipf_rdx_head_t *rnh; + int pref; + addrfamily_t *addr; +{ + static int extras[14] = { 0, -1, 1, 3, 5, 8, 9, + 15, 16, 19, 255, 256, 65535, 65536 + }; + ipf_rdx_node_t *rn; + addrfamily_t af; + char name[80]; + myst_t *stp; + int i; + + memset(&af, 0, sizeof(af)); +#if 0 + if (limit < 0 || limit > 14) + limit = 14; + + for (i = 0; i < limit; i++) { + if (ttable[i].host == NULL) + break; + setaddr(&af, ttable[i].host); + printf("%d.%d.LOOKUP(%s)", pref, i, addrname(&af)); + rn = ipf_rx_match(rnh, &af); + stp = (myst_t *)rn; + printf(" = %s (%s/%d)\n", GNAME(rn), + rn ? addrname(&stp->dst) : "NULL", + rn ? rn->maskbitcount : 0); + } +#else + printf("%d.%d.LOOKUP(%s)", pref, -1, addrname(addr)); + rn = ipf_rx_match(rnh, addr); + stp = (myst_t *)rn; + printf(" = %s (%s/%d)\n", GNAME(rn), + rn ? addrname(&stp->dst) : "NULL", rn ? rn->maskbitcount : 0); +#endif +} + + +void +delete_addr(rnh, item) + ipf_rdx_head_t *rnh; + int item; +{ + ipf_rdx_node_t *rn; + addrfamily_t mask; + addrfamily_t af; + myst_t **pstp; + myst_t *stp; + + memset(&af, 0, sizeof(af)); + memset(&mask, 0, sizeof(mask)); + setaddr(&af, ttable[item].host); + mask.adf_family = af.adf_family; + setmask(&mask, ttable[item].mask); + + printf("DELETE(%s)\n", addrname(&af)); + rn = ipf_rx_delete(rnh, &af, &mask); + if (rn == NULL) { + printf("FAIL LOOKUP DELETE\n"); + checktree(rnh); + for (stp = myst_top; stp != NULL; stp = stp->next) + if (stp->printed != -1) + stp->printed = -2; + ipf_rx_walktree(rnh, nodeprinter, NULL); + dumptree(rnh); + abort(); + } + printf("%d.delete(%s) = %s\n", item, addrname(&af), GNAME(rn)); + + for (pstp = &myst_top; (stp = *pstp) != NULL; pstp = &stp->next) + if (stp == (myst_t *)rn) + break; + stp->printed = -1; + stp->nodes[0].parent = &stp->nodes[0]; + stp->nodes[1].parent = &stp->nodes[1]; + *pstp = stp->next; + free(stp); + nodecount--; + checktree(rnh); +} + + +void +add_addr(rnh, n, item) + ipf_rdx_head_t *rnh; + int n, item; +{ + ipf_rdx_node_t *rn; + myst_t *stp; + + stp = calloc(1, sizeof(*stp)); + rn = (ipf_rdx_node_t *)stp; + setaddr(&stp->dst, ttable[item].host); + stp->mask.adf_family = stp->dst.adf_family; + setmask(&stp->mask, ttable[item].mask); + stp->next = myst_top; + myst_top = stp; + (void) sprintf(rn[0].name, "_BORN.0"); + (void) sprintf(rn[1].name, "_BORN.1"); + rn = ipf_rx_addroute(rnh, &stp->dst, &stp->mask, stp->nodes); + (void) sprintf(rn[0].name, "%d_NODE.0", item); + (void) sprintf(rn[1].name, "%d_NODE.1", item); + printf("ADD %d/%d %s/%s\n", n, item, rn[0].name, rn[1].name); + nodecount++; + checktree(rnh); +} + + +void +checktree(ipf_rdx_head_t *head) +{ + myst_t *s1; + ipf_rdx_node_t *rn; + + if (nodecount <= 1) + return; + + for (s1 = myst_top; s1 != NULL; s1 = s1->next) { + int fault = 0; + if (s1->printed == -1) + continue; + rn = &s1->nodes[1]; + if (rn->right->parent != rn) + fault |= 1; + if (rn->left->parent != rn) + fault |= 2; + if (rn->parent->left != rn && rn->parent->right != rn) + fault |= 4; + if (fault != 0) { + printf("FAULT %#x %s\n", fault, rn->name); + dumptree(head); + ipf_rx_walktree(head, nodeprinter, NULL); + fflush(stdout); + fflush(stderr); + printf("--\n"); + abort(); + } + } +} + + +int * +randomize(int *pnitems) +{ + int *order; + int nitems; + int choice; + int j; + int i; + + nitems = sizeof(ttable) / sizeof(ttable[0]); + *pnitems = nitems; + order = calloc(nitems, sizeof(*order)); + srandom(getpid() * time(NULL)); + memset(order, 0xff, nitems * sizeof(*order)); + order[21] = 21; + for (i = 0; i < nitems - 1; i++) { + do { + choice = rand() % (nitems - 1); + for (j = 0; j < nitems; j++) + if (order[j] == choice) + break; + } while (j != nitems); + order[i] = choice; + } + + return order; +} + + +void +random_add(rnh) + ipf_rdx_head_t *rnh; +{ + int *order; + int nitems; + int i; + + order = randomize(&nitems); + + for (i = 0; i < nitems - 1; i++) { + add_addr(rnh, i, order[i]); + checktree(rnh); + } +} + + +void +random_delete(rnh) + ipf_rdx_head_t *rnh; +{ + int *order; + int nitems; + int i; + + order = randomize(&nitems); + + for (i = 0; i < nitems - 1; i++) { + delete_addr(rnh, i); + checktree(rnh); + } +} +#endif /* RDX_DEBUG */ diff --git a/sys/contrib/ipfilter/netinet/radix_ipf.h b/sys/contrib/ipfilter/netinet/radix_ipf.h new file mode 100644 index 000000000000..73e66b0aa169 --- /dev/null +++ b/sys/contrib/ipfilter/netinet/radix_ipf.h @@ -0,0 +1,95 @@ +/* + * Copyright (C) 2012 by Darren Reed. + * + * See the IPFILTER.LICENCE file for details on licencing. + */ +#ifndef __RADIX_IPF_H__ +#define __RADIX_IPF_H__ + +#ifndef U_32_T +typedef unsigned int u_32_t; +# define U_32_T 1 +#endif + +typedef struct ipf_rdx_mask { + struct ipf_rdx_mask *next; + struct ipf_rdx_node *node; + u_32_t *mask; + int maskbitcount; +} ipf_rdx_mask_t; + +typedef struct ipf_rdx_node { + struct ipf_rdx_node *left; + struct ipf_rdx_node *right; + struct ipf_rdx_node *parent; + struct ipf_rdx_node *dupkey; + struct ipf_rdx_mask *masks; + struct ipf_rdx_mask *mymask; + u_32_t *addrkey; + u_32_t *maskkey; + u_32_t *addroff; + u_32_t *maskoff; + u_32_t lastmask; + u_32_t bitmask; + int offset; + int index; + int maskbitcount; + int root; +#ifdef RDX_DEBUG + char name[40]; +#endif +} ipf_rdx_node_t; + +struct ipf_rdx_head; + +typedef void (* radix_walk_func_t)(ipf_rdx_node_t *, void *); +typedef ipf_rdx_node_t *(* idx_hamn_func_t)(struct ipf_rdx_head *, + addrfamily_t *, addrfamily_t *, + ipf_rdx_node_t *); +typedef ipf_rdx_node_t *(* idx_ham_func_t)(struct ipf_rdx_head *, + addrfamily_t *, addrfamily_t *); +typedef ipf_rdx_node_t *(* idx_ha_func_t)(struct ipf_rdx_head *, + addrfamily_t *); +typedef void (* idx_walk_func_t)(struct ipf_rdx_head *, + radix_walk_func_t, void *); + +typedef struct ipf_rdx_head { + ipf_rdx_node_t *root; + ipf_rdx_node_t nodes[3]; + ipfmutex_t lock; + idx_hamn_func_t addaddr; /* add addr/mask to tree */ + idx_ham_func_t deladdr; /* delete addr/mask from tree */ + idx_ham_func_t lookup; /* look for specific addr/mask */ + idx_ha_func_t matchaddr; /* search tree for address match */ + idx_walk_func_t walktree; /* walk entire tree */ +} ipf_rdx_head_t; + +typedef struct radix_softc { + u_char *zeros; + u_char *ones; +} radix_softc_t; + +#undef RADIX_NODE_HEAD_LOCK +#undef RADIX_NODE_HEAD_UNLOCK +#ifdef _KERNEL +# define RADIX_NODE_HEAD_LOCK(x) MUTEX_ENTER(&(x)->lock) +# define RADIX_NODE_HEAD_UNLOCK(x) MUTEX_UNLOCK(&(x)->lock) +#else +# define RADIX_NODE_HEAD_LOCK(x) +# define RADIX_NODE_HEAD_UNLOCK(x) +#endif + +extern void *ipf_rx_create __P((void)); +extern int ipf_rx_init __P((void *)); +extern void ipf_rx_destroy __P((void *)); +extern int ipf_rx_inithead __P((radix_softc_t *, ipf_rdx_head_t **)); +extern void ipf_rx_freehead __P((ipf_rdx_head_t *)); +extern ipf_rdx_node_t *ipf_rx_addroute __P((ipf_rdx_head_t *, + addrfamily_t *, addrfamily_t *, + ipf_rdx_node_t *)); +extern ipf_rdx_node_t *ipf_rx_delete __P((ipf_rdx_head_t *, addrfamily_t *, + addrfamily_t *)); +extern void ipf_rx_walktree __P((ipf_rdx_head_t *, radix_walk_func_t, + void *)); + +#endif /* __RADIX_IPF_H__ */ diff --git a/sys/dev/aac/aac_linux.c b/sys/dev/aac/aac_linux.c index 049e2be78e5b..591dfbbdcaa0 100644 --- a/sys/dev/aac/aac_linux.c +++ b/sys/dev/aac/aac_linux.c @@ -75,11 +75,13 @@ MODULE_DEPEND(aac_linux, linux, 1, 1, 1); static int aac_linux_ioctl(struct thread *td, struct linux_ioctl_args *args) { + cap_rights_t rights; struct file *fp; u_long cmd; int error; - if ((error = fget(td, args->fd, CAP_IOCTL, &fp)) != 0) + error = fget(td, args->fd, cap_rights_init(&rights, CAP_IOCTL), &fp); + if (error != 0) return (error); cmd = args->cmd; diff --git a/sys/dev/aacraid/aacraid_linux.c b/sys/dev/aacraid/aacraid_linux.c index 3d85445fa823..e58d0a47a80a 100644 --- a/sys/dev/aacraid/aacraid_linux.c +++ b/sys/dev/aacraid/aacraid_linux.c @@ -34,6 +34,9 @@ __FBSDID("$FreeBSD$"); */ #include +#if __FreeBSD_version >= 900000 +#include +#endif #include #include #include @@ -77,15 +80,19 @@ static int aacraid_linux_ioctl(struct thread *td, struct linux_ioctl_args *args) { struct file *fp; +#if __FreeBSD_version >= 900000 + cap_rights_t rights; +#endif u_long cmd; int error; + if ((error = fget(td, args->fd, #if __FreeBSD_version >= 900000 - if ((error = fget(td, args->fd, 0, &fp)) != 0) -#else - if ((error = fget(td, args->fd, &fp)) != 0) + cap_rights_init(&rights, CAP_IOCTL), #endif + &fp)) != 0) { return (error); + } cmd = args->cmd; /* diff --git a/sys/dev/amr/amr_linux.c b/sys/dev/amr/amr_linux.c index 44e858ba804e..5b1a17f530b1 100644 --- a/sys/dev/amr/amr_linux.c +++ b/sys/dev/amr/amr_linux.c @@ -72,10 +72,12 @@ MODULE_DEPEND(amr, linux, 1, 1, 1); static int amr_linux_ioctl(struct thread *p, struct linux_ioctl_args *args) { + cap_rights_t rights; struct file *fp; int error; - if ((error = fget(p, args->fd, CAP_IOCTL, &fp)) != 0) + error = fget(p, args->fd, cap_rights_init(&rights, CAP_IOCTL), &fp); + if (error != 0) return (error); error = fo_ioctl(fp, args->cmd, (caddr_t)args->arg, p->td_ucred, p); fdrop(fp, p); diff --git a/sys/dev/atkbdc/psm.c b/sys/dev/atkbdc/psm.c index 5a1fd37f08d3..9a6ae72ae415 100644 --- a/sys/dev/atkbdc/psm.c +++ b/sys/dev/atkbdc/psm.c @@ -375,10 +375,10 @@ static devclass_t psm_devclass; static int tap_enabled = -1; TUNABLE_INT("hw.psm.tap_enabled", &tap_enabled); -static int synaptics_support = 1; +static int synaptics_support = 0; TUNABLE_INT("hw.psm.synaptics_support", &synaptics_support); -static int trackpoint_support = 1; +static int trackpoint_support = 0; TUNABLE_INT("hw.psm.trackpoint_support", &trackpoint_support); static int verbose = PSM_DEBUG; diff --git a/sys/dev/cpuctl/cpuctl.c b/sys/dev/cpuctl/cpuctl.c index 4e5abb291a7f..317fc08d1063 100644 --- a/sys/dev/cpuctl/cpuctl.c +++ b/sys/dev/cpuctl/cpuctl.c @@ -295,10 +295,10 @@ cpuctl_do_update(int cpu, cpuctl_update_args_t *data, struct thread *td) static int update_intel(int cpu, cpuctl_update_args_t *args, struct thread *td) { - void *ptr = NULL; + void *ptr; uint64_t rev0, rev1; uint32_t tmp[4]; - int is_bound = 0; + int is_bound; int oldcpu; int ret; @@ -312,10 +312,11 @@ update_intel(int cpu, cpuctl_update_args_t *args, struct thread *td) } /* - * 16 byte alignment required. + * 16 byte alignment required. Rely on the fact that + * malloc(9) always returns the pointer aligned at least on + * the size of the allocation. */ ptr = malloc(args->size + 16, M_CPUCTL, M_WAITOK); - ptr = (void *)(16 + ((intptr_t)ptr & ~0xf)); if (copyin(args->data, ptr, args->size) != 0) { DPRINTF("[cpuctl,%d]: copyin %p->%p of %zd bytes failed", __LINE__, args->data, ptr, args->size); @@ -408,10 +409,10 @@ update_amd(int cpu, cpuctl_update_args_t *args, struct thread *td) static int update_via(int cpu, cpuctl_update_args_t *args, struct thread *td) { - void *ptr = NULL; + void *ptr; uint64_t rev0, rev1, res; uint32_t tmp[4]; - int is_bound = 0; + int is_bound; int oldcpu; int ret; @@ -427,8 +428,7 @@ update_via(int cpu, cpuctl_update_args_t *args, struct thread *td) /* * 4 byte alignment required. */ - ptr = malloc(args->size + 16, M_CPUCTL, M_WAITOK); - ptr = (void *)(16 + ((intptr_t)ptr & ~0xf)); + ptr = malloc(args->size, M_CPUCTL, M_WAITOK); if (copyin(args->data, ptr, args->size) != 0) { DPRINTF("[cpuctl,%d]: copyin %p->%p of %zd bytes failed", __LINE__, args->data, ptr, args->size); diff --git a/sys/dev/cxgbe/tom/t4_cpl_io.c b/sys/dev/cxgbe/tom/t4_cpl_io.c index 99e9db444be3..2409b5d33cfa 100644 --- a/sys/dev/cxgbe/tom/t4_cpl_io.c +++ b/sys/dev/cxgbe/tom/t4_cpl_io.c @@ -444,22 +444,12 @@ max_dsgl_nsegs(int tx_credits) static inline void write_tx_wr(void *dst, struct toepcb *toep, unsigned int immdlen, - unsigned int plen, uint8_t credits, int more_to_come) + unsigned int plen, uint8_t credits, int shove) { struct fw_ofld_tx_data_wr *txwr = dst; - int shove = !more_to_come; - int compl = 1; - - /* - * We always request completion notifications from the firmware. The - * only exception is when we know we'll get more data to send shortly - * and that we'll have some tx credits remaining to transmit that data. - */ - if (more_to_come && toep->tx_credits - credits >= MIN_OFLD_TX_CREDITS) - compl = 0; txwr->op_to_immdlen = htobe32(V_WR_OP(FW_OFLD_TX_DATA_WR) | - V_FW_WR_COMPL(compl) | V_FW_WR_IMMDLEN(immdlen)); + V_FW_WR_IMMDLEN(immdlen)); txwr->flowid_len16 = htobe32(V_FW_WR_FLOWID(toep->tid) | V_FW_WR_LEN16(credits)); txwr->tunnel_to_proxy = @@ -529,19 +519,26 @@ write_tx_sgl(void *dst, struct mbuf *start, struct mbuf *stop, int nsegs, int n) * The socket's so_snd buffer consists of a stream of data starting with sb_mb * and linked together with m_next. sb_sndptr, if set, is the last mbuf that * was transmitted. + * + * drop indicates the number of bytes that should be dropped from the head of + * the send buffer. It is an optimization that lets do_fw4_ack avoid creating + * contention on the send buffer lock (before this change it used to do + * sowwakeup and then t4_push_frames right after that when recovering from tx + * stalls). When drop is set this function MUST drop the bytes and wake up any + * writers. */ static void -t4_push_frames(struct adapter *sc, struct toepcb *toep) +t4_push_frames(struct adapter *sc, struct toepcb *toep, int drop) { struct mbuf *sndptr, *m, *sb_sndptr; struct fw_ofld_tx_data_wr *txwr; struct wrqe *wr; - unsigned int plen, nsegs, credits, max_imm, max_nsegs, max_nsegs_1mbuf; + u_int plen, nsegs, credits, max_imm, max_nsegs, max_nsegs_1mbuf; struct inpcb *inp = toep->inp; struct tcpcb *tp = intotcpcb(inp); struct socket *so = inp->inp_socket; struct sockbuf *sb = &so->so_snd; - int tx_credits; + int tx_credits, shove, compl, space, sowwakeup; struct ofld_tx_sdesc *txsd = &toep->txsd[toep->txsd_pidx]; INP_WLOCK_ASSERT(inp); @@ -557,8 +554,11 @@ t4_push_frames(struct adapter *sc, struct toepcb *toep) * This function doesn't resume by itself. Someone else must clear the * flag and call this function. */ - if (__predict_false(toep->flags & TPF_TX_SUSPENDED)) + if (__predict_false(toep->flags & TPF_TX_SUSPENDED)) { + KASSERT(drop == 0, + ("%s: drop (%d) != 0 but tx is suspended", __func__, drop)); return; + } do { tx_credits = min(toep->tx_credits, MAX_OFLD_TX_CREDITS); @@ -566,6 +566,11 @@ t4_push_frames(struct adapter *sc, struct toepcb *toep) max_nsegs = max_dsgl_nsegs(tx_credits); SOCKBUF_LOCK(sb); + sowwakeup = drop; + if (drop) { + sbdrop_locked(sb, drop); + drop = 0; + } sb_sndptr = sb->sb_sndptr; sndptr = sb_sndptr ? sb_sndptr->m_next : sb->sb_mb; plen = 0; @@ -584,7 +589,11 @@ t4_push_frames(struct adapter *sc, struct toepcb *toep) if (plen == 0) { /* Too few credits */ toep->flags |= TPF_TX_SUSPENDED; - SOCKBUF_UNLOCK(sb); + if (sowwakeup) + sowwakeup_locked(so); + else + SOCKBUF_UNLOCK(sb); + SOCKBUF_UNLOCK_ASSERT(sb); return; } break; @@ -601,23 +610,32 @@ t4_push_frames(struct adapter *sc, struct toepcb *toep) } } + shove = m == NULL && !(tp->t_flags & TF_MORETOCOME); + space = sbspace(sb); + + if (space <= sb->sb_hiwat * 3 / 8 && + toep->plen_nocompl + plen >= sb->sb_hiwat / 4) + compl = 1; + else + compl = 0; + if (sb->sb_flags & SB_AUTOSIZE && V_tcp_do_autosndbuf && sb->sb_hiwat < V_tcp_autosndbuf_max && - sbspace(sb) < sb->sb_hiwat / 8 * 7) { + space < sb->sb_hiwat / 8) { int newsize = min(sb->sb_hiwat + V_tcp_autosndbuf_inc, V_tcp_autosndbuf_max); if (!sbreserve_locked(sb, newsize, so, NULL)) sb->sb_flags &= ~SB_AUTOSIZE; - else { - sowwakeup_locked(so); /* room available */ - SOCKBUF_UNLOCK_ASSERT(sb); - goto unlocked; - } + else + sowwakeup = 1; /* room available */ } - SOCKBUF_UNLOCK(sb); -unlocked: + if (sowwakeup) + sowwakeup_locked(so); + else + SOCKBUF_UNLOCK(sb); + SOCKBUF_UNLOCK_ASSERT(sb); /* nothing to send */ if (plen == 0) { @@ -642,9 +660,9 @@ t4_push_frames(struct adapter *sc, struct toepcb *toep) } txwr = wrtod(wr); credits = howmany(wr->wr_len, 16); - write_tx_wr(txwr, toep, plen, plen, credits, - tp->t_flags & TF_MORETOCOME); + write_tx_wr(txwr, toep, plen, plen, credits, shove); m_copydata(sndptr, 0, plen, (void *)(txwr + 1)); + nsegs = 0; } else { int wr_len; @@ -660,8 +678,7 @@ t4_push_frames(struct adapter *sc, struct toepcb *toep) } txwr = wrtod(wr); credits = howmany(wr_len, 16); - write_tx_wr(txwr, toep, 0, plen, credits, - tp->t_flags & TF_MORETOCOME); + write_tx_wr(txwr, toep, 0, plen, credits, shove); write_tx_sgl(txwr + 1, sndptr, m, nsegs, max_nsegs_1mbuf); if (wr_len & 0xf) { @@ -675,6 +692,17 @@ t4_push_frames(struct adapter *sc, struct toepcb *toep) ("%s: not enough credits", __func__)); toep->tx_credits -= credits; + toep->tx_nocompl += credits; + toep->plen_nocompl += plen; + if (toep->tx_credits <= toep->tx_total * 3 / 8 && + toep->tx_nocompl >= toep->tx_total / 4) + compl = 1; + + if (compl) { + txwr->op_to_immdlen |= htobe32(F_FW_WR_COMPL); + toep->tx_nocompl = 0; + toep->plen_nocompl = 0; + } tp->snd_nxt += plen; tp->snd_max += plen; @@ -685,6 +713,8 @@ t4_push_frames(struct adapter *sc, struct toepcb *toep) SOCKBUF_UNLOCK(sb); toep->flags |= TPF_TX_DATA_SENT; + if (toep->tx_credits < MIN_OFLD_TX_CREDITS) + toep->flags |= TPF_TX_SUSPENDED; KASSERT(toep->txsd_avail > 0, ("%s: no txsd", __func__)); txsd->plen = plen; @@ -718,7 +748,7 @@ t4_tod_output(struct toedev *tod, struct tcpcb *tp) ("%s: inp %p dropped.", __func__, inp)); KASSERT(toep != NULL, ("%s: toep is NULL", __func__)); - t4_push_frames(sc, toep); + t4_push_frames(sc, toep, 0); return (0); } @@ -738,7 +768,8 @@ t4_send_fin(struct toedev *tod, struct tcpcb *tp) KASSERT(toep != NULL, ("%s: toep is NULL", __func__)); toep->flags |= TPF_SEND_FIN; - t4_push_frames(sc, toep); + if (tp->t_state >= TCPS_ESTABLISHED) + t4_push_frames(sc, toep, 0); return (0); } @@ -1369,7 +1400,16 @@ do_fw4_ack(struct sge_iq *iq, const struct rss_header *rss, struct mbuf *m) } } - if (plen > 0) { + if (toep->tx_credits == toep->tx_total) { + toep->tx_nocompl = 0; + toep->plen_nocompl = 0; + } + + if (toep->flags & TPF_TX_SUSPENDED && + toep->tx_credits >= toep->tx_total / 4) { + toep->flags &= ~TPF_TX_SUSPENDED; + t4_push_frames(sc, toep, plen); + } else if (plen > 0) { struct sockbuf *sb = &so->so_snd; SOCKBUF_LOCK(sb); @@ -1378,14 +1418,6 @@ do_fw4_ack(struct sge_iq *iq, const struct rss_header *rss, struct mbuf *m) SOCKBUF_UNLOCK_ASSERT(sb); } - /* XXX */ - if ((toep->flags & TPF_TX_SUSPENDED && - toep->tx_credits >= MIN_OFLD_TX_CREDITS) || - toep->tx_credits == toep->txsd_total * - howmany((sizeof(struct fw_ofld_tx_data_wr) + 1), 16)) { - toep->flags &= ~TPF_TX_SUSPENDED; - t4_push_frames(sc, toep); - } INP_WUNLOCK(inp); return (0); diff --git a/sys/dev/cxgbe/tom/t4_tom.c b/sys/dev/cxgbe/tom/t4_tom.c index c9f4baac6717..8c787a75e3fb 100644 --- a/sys/dev/cxgbe/tom/t4_tom.c +++ b/sys/dev/cxgbe/tom/t4_tom.c @@ -148,6 +148,7 @@ alloc_toepcb(struct port_info *pi, int txqid, int rxqid, int flags) toep->td = sc->tom_softc; toep->port = pi; + toep->tx_total = tx_credits; toep->tx_credits = tx_credits; toep->ofld_txq = &sc->sge.ofld_txq[txqid]; toep->ofld_rxq = &sc->sge.ofld_rxq[rxqid]; diff --git a/sys/dev/cxgbe/tom/t4_tom.h b/sys/dev/cxgbe/tom/t4_tom.h index b86a76ce28f0..927bc94e1e09 100644 --- a/sys/dev/cxgbe/tom/t4_tom.h +++ b/sys/dev/cxgbe/tom/t4_tom.h @@ -99,7 +99,7 @@ struct ddp_buffer { struct toepcb { TAILQ_ENTRY(toepcb) link; /* toep_list */ - unsigned int flags; /* miscellaneous flags */ + u_int flags; /* miscellaneous flags */ struct tom_data *td; struct inpcb *inp; /* backpointer to host stack's PCB */ struct port_info *port; /* physical port */ @@ -109,13 +109,20 @@ struct toepcb { struct l2t_entry *l2te; /* L2 table entry used by this connection */ struct clip_entry *ce; /* CLIP table entry used by this tid */ int tid; /* Connection identifier */ - unsigned int tx_credits;/* tx WR credits (in 16 byte units) remaining */ - unsigned int sb_cc; /* last noted value of so_rcv->sb_cc */ + + /* tx credit handling */ + u_int tx_total; /* total tx WR credits (in 16B units) */ + u_int tx_credits; /* tx WR credits (in 16B units) available */ + u_int tx_nocompl; /* tx WR credits since last compl request */ + u_int plen_nocompl; /* payload since last compl request */ + + /* rx credit handling */ + u_int sb_cc; /* last noted value of so_rcv->sb_cc */ int rx_credits; /* rx credits (in bytes) to be returned to hw */ - unsigned int ulp_mode; /* ULP mode */ + u_int ulp_mode; /* ULP mode */ - unsigned int ddp_flags; + u_int ddp_flags; struct ddp_buffer *db[2]; time_t ddp_disabled; uint8_t ddp_score; diff --git a/sys/dev/drm2/i915/i915_gem.c b/sys/dev/drm2/i915/i915_gem.c index 5afea4e1e138..9af50d8f32dd 100644 --- a/sys/dev/drm2/i915/i915_gem.c +++ b/sys/dev/drm2/i915/i915_gem.c @@ -1291,7 +1291,7 @@ i915_gem_mmap_ioctl(struct drm_device *dev, void *data, addr = 0; vm_object_reference(obj->vm_obj); DRM_UNLOCK(dev); - rv = vm_map_find(map, obj->vm_obj, args->offset, &addr, args->size, + rv = vm_map_find(map, obj->vm_obj, args->offset, &addr, args->size, 0, VMFS_OPTIMAL_SPACE, VM_PROT_READ | VM_PROT_WRITE, VM_PROT_READ | VM_PROT_WRITE, MAP_INHERIT_SHARE); if (rv != KERN_SUCCESS) { diff --git a/sys/dev/filemon/filemon.c b/sys/dev/filemon/filemon.c index ce84e3df4252..e3fda1829ec0 100644 --- a/sys/dev/filemon/filemon.c +++ b/sys/dev/filemon/filemon.c @@ -138,12 +138,6 @@ filemon_dtr(void *data) } } -#if __FreeBSD_version < 900041 -#define FGET_WRITE(a1, a2, a3) fget_write((a1), (a2), (a3)) -#else -#define FGET_WRITE(a1, a2, a3) fget_write((a1), (a2), CAP_WRITE | CAP_SEEK, (a3)) -#endif - static int filemon_ioctl(struct cdev *dev, u_long cmd, caddr_t data, int flag __unused, struct thread *td) @@ -151,13 +145,21 @@ filemon_ioctl(struct cdev *dev, u_long cmd, caddr_t data, int flag __unused, int error = 0; struct filemon *filemon; struct proc *p; +#if __FreeBSD_version >= 900041 + cap_rights_t rights; +#endif devfs_get_cdevpriv((void **) &filemon); switch (cmd) { /* Set the output file descriptor. */ case FILEMON_SET_FD: - if ((error = FGET_WRITE(td, *(int *)data, &filemon->fp)) == 0) + error = fget_write(td, *(int *)data, +#if __FreeBSD_version >= 900041 + cap_rights_init(&rights, CAP_PWRITE), +#endif + &filemon->fp); + if (error == 0) /* Write the file header. */ filemon_comment(filemon); break; diff --git a/sys/dev/firewire/fwdev.c b/sys/dev/firewire/fwdev.c index 1475d00e3c38..d26810d30545 100644 --- a/sys/dev/firewire/fwdev.c +++ b/sys/dev/firewire/fwdev.c @@ -992,11 +992,9 @@ fwdev_clone(void *arg, struct ucred *cred, char *name, int namelen, sc = devclass_get_softc(firewire_devclass, unit); if (sc == NULL) return; - *dev = make_dev(&firewire_cdevsw, MAKEMINOR(devflag[i], unit, sub), - UID_ROOT, GID_OPERATOR, 0660, - "%s%d.%d", devnames[i], unit, sub); - dev_ref(*dev); - (*dev)->si_flags |= SI_CHEAPCLONE; + *dev = make_dev_credf(MAKEDEV_REF, &firewire_cdevsw, + MAKEMINOR(devflag[i], unit, sub), cred, UID_ROOT, GID_OPERATOR, + 0660, "%s%d.%d", devnames[i], unit, sub); dev_depends(sc->dev, *dev); return; } diff --git a/sys/dev/glxsb/glxsb.c b/sys/dev/glxsb/glxsb.c index aa1721742d6b..52041534da3e 100644 --- a/sys/dev/glxsb/glxsb.c +++ b/sys/dev/glxsb/glxsb.c @@ -476,7 +476,7 @@ glxsb_rnd(void *v) if (status & SB_RNS_TRNG_VALID) { value = bus_read_4(sc->sc_sr, SB_RANDOM_NUM); /* feed with one uint32 */ - random_harvest(&value, 4, 32, 0, RANDOM_PURE); + random_harvest(&value, 4, 32/2, 0, RANDOM_PURE); } callout_reset(&sc->sc_rngco, sc->sc_rnghz, glxsb_rnd, sc); diff --git a/sys/dev/gpio/gpiobus.c b/sys/dev/gpio/gpiobus.c index d61f7aad7fd1..6abb10c1e09b 100644 --- a/sys/dev/gpio/gpiobus.c +++ b/sys/dev/gpio/gpiobus.c @@ -131,7 +131,7 @@ gpiobus_parse_pins(struct gpiobus_softc *sc, device_t child, int mask) } if (npins == 0) { - device_printf(child, "empty pin mask"); + device_printf(child, "empty pin mask\n"); return (EINVAL); } diff --git a/sys/dev/gxemul/cons/gxemul_cons.c b/sys/dev/gxemul/cons/gxemul_cons.c index b83aa9400bf4..cb3b0001ee6c 100644 --- a/sys/dev/gxemul/cons/gxemul_cons.c +++ b/sys/dev/gxemul/cons/gxemul_cons.c @@ -99,18 +99,16 @@ static void gxemul_cons_timeout(void *); * XXXRW: Should be using FreeBSD's bus routines here, but they are not * available until later in the boot. */ -typedef uint64_t paddr_t; -typedef uint64_t vaddr_t; -static inline vaddr_t -mips_phys_to_uncached(paddr_t phys) +static inline vm_offset_t +mips_phys_to_uncached(vm_paddr_t phys) { return (MIPS_PHYS_TO_DIRECT_UNCACHED(phys)); } static inline uint8_t -mips_ioread_uint8(vaddr_t vaddr) +mips_ioread_uint8(vm_offset_t vaddr) { uint8_t v; @@ -119,7 +117,7 @@ mips_ioread_uint8(vaddr_t vaddr) } static inline void -mips_iowrite_uint8(vaddr_t vaddr, uint8_t v) +mips_iowrite_uint8(vm_offset_t vaddr, uint8_t v) { __asm__ __volatile__ ("sb %0, 0(%1)" : : "r" (v), "r" (vaddr)); diff --git a/sys/dev/gxemul/disk/gxemul_disk.c b/sys/dev/gxemul/disk/gxemul_disk.c index 8cf52e42824a..3b7e649c6559 100644 --- a/sys/dev/gxemul/disk/gxemul_disk.c +++ b/sys/dev/gxemul/disk/gxemul_disk.c @@ -214,7 +214,14 @@ gxemul_disk_read(unsigned diskid, void *buf, off_t off) if (off < 0 || off % GXEMUL_DISK_DEV_BLOCKSIZE != 0) return (EINVAL); +#ifdef _LP64 GXEMUL_DISK_DEV_WRITE(GXEMUL_DISK_DEV_OFFSET, (uint64_t)off); +#else + GXEMUL_DISK_DEV_WRITE(GXEMUL_DISK_DEV_OFFSET_LO, + (uint32_t)(off & 0xffffffff)); + GXEMUL_DISK_DEV_WRITE(GXEMUL_DISK_DEV_OFFSET_HI, + (uint32_t)((off >> 32) & 0xffffffff)); +#endif GXEMUL_DISK_DEV_WRITE(GXEMUL_DISK_DEV_DISKID, diskid); GXEMUL_DISK_DEV_WRITE(GXEMUL_DISK_DEV_START, GXEMUL_DISK_DEV_START_READ); switch (GXEMUL_DISK_DEV_READ(GXEMUL_DISK_DEV_STATUS)) { @@ -280,7 +287,15 @@ gxemul_disk_write(unsigned diskid, const void *buf, off_t off) if (off < 0 || off % GXEMUL_DISK_DEV_BLOCKSIZE != 0) return (EINVAL); +#ifdef _LP64 GXEMUL_DISK_DEV_WRITE(GXEMUL_DISK_DEV_OFFSET, (uint64_t)off); +#else + GXEMUL_DISK_DEV_WRITE(GXEMUL_DISK_DEV_OFFSET_LO, + (uint32_t)(off & 0xffffffff)); + GXEMUL_DISK_DEV_WRITE(GXEMUL_DISK_DEV_OFFSET_HI, + (uint32_t)((off >> 32) & 0xffffffff)); +#endif + GXEMUL_DISK_DEV_WRITE(GXEMUL_DISK_DEV_DISKID, diskid); dst = GXEMUL_DISK_DEV_FUNCTION(GXEMUL_DISK_DEV_BLOCK); diff --git a/sys/dev/gxemul/disk/gxemul_diskreg.h b/sys/dev/gxemul/disk/gxemul_diskreg.h index c3460e55299d..f83794486b15 100644 --- a/sys/dev/gxemul/disk/gxemul_diskreg.h +++ b/sys/dev/gxemul/disk/gxemul_diskreg.h @@ -36,16 +36,28 @@ #define GXEMUL_DISK_DEV_ID_START (0x0000) #define GXEMUL_DISK_DEV_ID_END (0x0100) -#define GXEMUL_DISK_DEV_OFFSET (0x0000) +#ifdef _LP64 +#define GXEMUL_DISK_DEV_OFFSET (0x0000) +#else +#define GXEMUL_DISK_DEV_OFFSET_LO (0x0000) +#define GXEMUL_DISK_DEV_OFFSET_HI (0x0008) +#endif #define GXEMUL_DISK_DEV_DISKID (0x0010) #define GXEMUL_DISK_DEV_START (0x0020) #define GXEMUL_DISK_DEV_STATUS (0x0030) #define GXEMUL_DISK_DEV_BLOCK (0x4000) +#ifdef _LP64 #define GXEMUL_DISK_DEV_FUNCTION(f) \ (volatile uint64_t *)MIPS_PHYS_TO_DIRECT_UNCACHED(GXEMUL_DISK_DEV_BASE + (f)) #define GXEMUL_DISK_DEV_READ(f) \ (volatile uint64_t)*GXEMUL_DISK_DEV_FUNCTION(f) +#else +#define GXEMUL_DISK_DEV_FUNCTION(f) \ + (volatile uint32_t *)MIPS_PHYS_TO_DIRECT_UNCACHED(GXEMUL_DISK_DEV_BASE + (f)) +#define GXEMUL_DISK_DEV_READ(f) \ + (volatile uint32_t)*GXEMUL_DISK_DEV_FUNCTION(f) +#endif #define GXEMUL_DISK_DEV_WRITE(f, v) \ *GXEMUL_DISK_DEV_FUNCTION(f) = (v) diff --git a/sys/dev/gxemul/ether/gxreg.h b/sys/dev/gxemul/ether/gxreg.h index e67f43d0ce84..a528250b2aa8 100644 --- a/sys/dev/gxemul/ether/gxreg.h +++ b/sys/dev/gxemul/ether/gxreg.h @@ -40,10 +40,17 @@ #define GXEMUL_ETHER_DEV_COMMAND (0x4020) #define GXEMUL_ETHER_DEV_MAC (0x4040) +#ifdef _LP64 #define GXEMUL_ETHER_DEV_FUNCTION(f) \ (volatile uint64_t *)MIPS_PHYS_TO_DIRECT_UNCACHED(GXEMUL_ETHER_DEV_BASE + (f)) #define GXEMUL_ETHER_DEV_READ(f) \ (volatile uint64_t)*GXEMUL_ETHER_DEV_FUNCTION(f) +#else +#define GXEMUL_ETHER_DEV_FUNCTION(f) \ + (volatile uint32_t *)MIPS_PHYS_TO_DIRECT_UNCACHED(GXEMUL_ETHER_DEV_BASE + (f)) +#define GXEMUL_ETHER_DEV_READ(f) \ + (volatile uint32_t)*GXEMUL_ETHER_DEV_FUNCTION(f) +#endif #define GXEMUL_ETHER_DEV_WRITE(f, v) \ *GXEMUL_ETHER_DEV_FUNCTION(f) = (v) diff --git a/sys/dev/hifn/hifn7751.c b/sys/dev/hifn/hifn7751.c index c5c5af1b3fa4..ae6c5ac6353b 100644 --- a/sys/dev/hifn/hifn7751.c +++ b/sys/dev/hifn/hifn7751.c @@ -258,7 +258,7 @@ hifn_partname(struct hifn_softc *sc) static void default_harvest(struct rndtest_state *rsp, void *buf, u_int count) { - random_harvest(buf, count, count*NBBY, 0, RANDOM_PURE); + random_harvest(buf, count, count*NBBY/2, 0, RANDOM_PURE); } static u_int diff --git a/sys/dev/hpt27xx/hpt27xx_osm_bsd.c b/sys/dev/hpt27xx/hpt27xx_osm_bsd.c index 636906d14377..3c9f0ace838b 100644 --- a/sys/dev/hpt27xx/hpt27xx_osm_bsd.c +++ b/sys/dev/hpt27xx/hpt27xx_osm_bsd.c @@ -52,7 +52,7 @@ static int hpt_probe(device_t dev) memset(hba, 0, sizeof(HBA)); hba->ext_type = EXT_TYPE_HBA; hba->ldm_adapter.him = him; - return 0; + return (BUS_PROBE_DEFAULT); } } } diff --git a/sys/dev/hwpmc/hwpmc_logging.c b/sys/dev/hwpmc/hwpmc_logging.c index 880bcaac0a0b..a60e096eed25 100644 --- a/sys/dev/hwpmc/hwpmc_logging.c +++ b/sys/dev/hwpmc/hwpmc_logging.c @@ -570,6 +570,7 @@ pmclog_configure_log(struct pmc_mdep *md, struct pmc_owner *po, int logfd) { int error; struct proc *p; + cap_rights_t rights; /* * As long as it is possible to get a LOR between pmc_sx lock and @@ -593,7 +594,8 @@ pmclog_configure_log(struct pmc_mdep *md, struct pmc_owner *po, int logfd) po->po_file)); /* get a reference to the file state */ - error = fget_write(curthread, logfd, CAP_WRITE, &po->po_file); + error = fget_write(curthread, logfd, + cap_rights_init(&rights, CAP_WRITE), &po->po_file); if (error) goto error; diff --git a/sys/dev/hwpmc/hwpmc_powerpc.c b/sys/dev/hwpmc/hwpmc_powerpc.c index c7d8f3dcfdc4..25a32fa35d36 100644 --- a/sys/dev/hwpmc/hwpmc_powerpc.c +++ b/sys/dev/hwpmc/hwpmc_powerpc.c @@ -46,6 +46,8 @@ __FBSDID("$FreeBSD$"); #define INKERNEL(x) (((vm_offset_t)(x)) <= VM_MAX_KERNEL_ADDRESS && \ ((vm_offset_t)(x)) >= VM_MIN_KERNEL_ADDRESS) +struct powerpc_cpu **powerpc_pcpu; + int pmc_save_kernel_callchain(uintptr_t *cc, int maxsamples, struct trapframe *tf) diff --git a/sys/dev/ipmi/ipmi_linux.c b/sys/dev/ipmi/ipmi_linux.c index 430bd0858948..b6b38f22b16a 100644 --- a/sys/dev/ipmi/ipmi_linux.c +++ b/sys/dev/ipmi/ipmi_linux.c @@ -89,11 +89,13 @@ MODULE_DEPEND(ipmi_linux, linux, 1, 1, 1); static int ipmi_linux_ioctl(struct thread *td, struct linux_ioctl_args *args) { + cap_rights_t rights; struct file *fp; u_long cmd; int error; - if ((error = fget(td, args->fd, CAP_IOCTL, &fp)) != 0) + error = fget(td, args->fd, cap_rights_init(&rights, CAP_IOCTL), &fp); + if (error != 0) return (error); cmd = args->cmd; diff --git a/sys/dev/iscsi_initiator/iscsi.c b/sys/dev/iscsi_initiator/iscsi.c index 4dbf16349903..4a1cb967ffa0 100644 --- a/sys/dev/iscsi_initiator/iscsi.c +++ b/sys/dev/iscsi_initiator/iscsi.c @@ -382,16 +382,19 @@ i_ping(struct cdev *dev) static int i_setsoc(isc_session_t *sp, int fd, struct thread *td) { + cap_rights_t rights; int error = 0; if(sp->soc != NULL) isc_stop_receiver(sp); - error = fget(td, fd, CAP_SOCK_CLIENT, &sp->fp); + error = fget(td, fd, cap_rights_init(&rights, CAP_SOCK_CLIENT), &sp->fp); if(error) return error; - if((error = fgetsock(td, fd, CAP_SOCK_CLIENT, &sp->soc, 0)) == 0) { + error = fgetsock(td, fd, cap_rights_init(&rights, CAP_SOCK_CLIENT), + &sp->soc, 0); + if(error == 0) { sp->td = td; isc_start_receiver(sp); } diff --git a/sys/dev/mfi/mfi_linux.c b/sys/dev/mfi/mfi_linux.c index 3328a6650cd6..429d49600c07 100644 --- a/sys/dev/mfi/mfi_linux.c +++ b/sys/dev/mfi/mfi_linux.c @@ -84,6 +84,7 @@ MODULE_DEPEND(mfi, linux, 1, 1, 1); static int mfi_linux_ioctl(struct thread *p, struct linux_ioctl_args *args) { + cap_rights_t rights; struct file *fp; int error; u_long cmd = args->cmd; @@ -97,7 +98,8 @@ mfi_linux_ioctl(struct thread *p, struct linux_ioctl_args *args) break; } - if ((error = fget(p, args->fd, CAP_IOCTL, &fp)) != 0) + error = fget(p, args->fd, cap_rights_init(&rights, CAP_IOCTL), &fp); + if (error != 0) return (error); error = fo_ioctl(fp, cmd, (caddr_t)args->arg, p->td_ucred, p); fdrop(fp, p); diff --git a/sys/dev/ntb/if_ntb/if_ntb.c b/sys/dev/ntb/if_ntb/if_ntb.c index 55b19c5dd434..e86ed53b3bb3 100644 --- a/sys/dev/ntb/if_ntb/if_ntb.c +++ b/sys/dev/ntb/if_ntb/if_ntb.c @@ -104,7 +104,7 @@ struct ntb_transport_qp { bool client_ready; bool qp_link; - uint8_t qp_num; /* Only 64 QP's are allowed. 0-63 */ + uint8_t qp_num; /* Only 64 QPs are allowed. 0-63 */ struct ntb_rx_info *rx_info; struct ntb_rx_info *remote_rx_info; @@ -279,14 +279,14 @@ ntb_handle_module_events(struct module *m, int what, void *arg) return (err); } -static moduledata_t ntb_transport_mod = { - "ntb_transport", +static moduledata_t if_ntb_mod = { + "if_ntb", ntb_handle_module_events, NULL }; -DECLARE_MODULE(ntb_transport, ntb_transport_mod, SI_SUB_KLD, SI_ORDER_ANY); -MODULE_DEPEND(ntb_transport, ntb_hw, 1, 1, 1); +DECLARE_MODULE(if_ntb, if_ntb_mod, SI_SUB_KLD, SI_ORDER_ANY); +MODULE_DEPEND(if_ntb, ntb_hw, 1, 1, 1); static int ntb_setup_interface() @@ -297,7 +297,7 @@ ntb_setup_interface() net_softc.ntb = devclass_get_softc(devclass_find("ntb_hw"), 0); if (net_softc.ntb == NULL) { - printf("ntb: Can't find devclass\n"); + printf("ntb: Cannot find devclass\n"); return (ENXIO); } @@ -334,14 +334,19 @@ ntb_setup_interface() static int ntb_teardown_interface() { - struct ifnet *ifp = net_softc.ifp; - ntb_transport_link_down(net_softc.qp); + if (net_softc.qp != NULL) + ntb_transport_link_down(net_softc.qp); - ether_ifdetach(ifp); - if_free(ifp); - ntb_transport_free_queue(net_softc.qp); - ntb_transport_free(&net_softc); + if (net_softc.ifp != NULL) { + ether_ifdetach(net_softc.ifp); + if_free(net_softc.ifp); + } + + if (net_softc.qp != NULL) { + ntb_transport_free_queue(net_softc.qp); + ntb_transport_free(&net_softc); + } return (0); } @@ -405,7 +410,7 @@ ntb_start(struct ifnet *ifp) m_length(m_head, NULL)); if (rc != 0) { CTR1(KTR_NTB, - "TX: couldn't tx mbuf %p. Returning to snd q", + "TX: could not tx mbuf %p. Returning to snd q", m_head); if (rc == EAGAIN) { ifp->if_drv_flags |= IFF_DRV_OACTIVE; @@ -475,8 +480,11 @@ ntb_transport_init(struct ntb_softc *ntb) if (rc != 0) goto err; - if (ntb_query_link_status(ntb)) + if (ntb_query_link_status(ntb)) { + if (bootverbose) + device_printf(ntb_get_device(ntb), "link up\n"); callout_reset(&nt->link_work, 0, ntb_transport_link_work, nt); + } return (0); @@ -497,7 +505,7 @@ ntb_transport_free(void *transport) callout_drain(&nt->link_work); - /* verify that all the qp's are freed */ + /* verify that all the qps are freed */ for (i = 0; i < nt->max_qps; i++) if (!test_bit(i, &nt->qp_bitmap)) ntb_transport_free_queue(&nt->qps[i]); @@ -673,6 +681,8 @@ ntb_transport_link_up(struct ntb_transport_qp *qp) return; qp->client_ready = NTB_LINK_UP; + if (bootverbose) + device_printf(ntb_get_device(qp->ntb), "qp client ready\n"); if (qp->transport->transport_link == NTB_LINK_UP) callout_reset(&qp->link_work, 0, ntb_qp_link_work, qp); @@ -709,7 +719,7 @@ ntb_transport_tx_enqueue(struct ntb_transport_qp *qp, void *cb, void *data, entry = ntb_list_rm(&qp->ntb_tx_free_q_lock, &qp->tx_free_q); if (entry == NULL) { - CTR0(KTR_NTB, "TX: couldn't get entry from tx_free_q"); + CTR0(KTR_NTB, "TX: could not get entry from tx_free_q"); return (ENOMEM); } CTR1(KTR_NTB, "TX: got entry %p from tx_free_q", entry); @@ -988,9 +998,13 @@ ntb_transport_event_callback(void *data, enum ntb_hw_event event) switch (event) { case NTB_EVENT_HW_LINK_UP: + if (bootverbose) + device_printf(ntb_get_device(nt->ntb), "HW link up\n"); callout_reset(&nt->link_work, 0, ntb_transport_link_work, nt); break; case NTB_EVENT_HW_LINK_DOWN: + if (bootverbose) + device_printf(ntb_get_device(nt->ntb), "HW link down\n"); ntb_transport_link_cleanup(nt); break; default: @@ -1071,6 +1085,8 @@ ntb_transport_link_work(void *arg) return; nt->transport_link = NTB_LINK_UP; + if (bootverbose) + device_printf(ntb_get_device(ntb), "transport link up\n"); for (i = 0; i < nt->max_qps; i++) { qp = &nt->qps[i]; @@ -1176,6 +1192,8 @@ ntb_qp_link_work(void *arg) qp->qp_link = NTB_LINK_UP; if (qp->event_handler != NULL) qp->event_handler(qp->cb_data, NTB_LINK_UP); + if (bootverbose) + device_printf(ntb_get_device(ntb), "qp link up\n"); } else if (nt->transport_link == NTB_LINK_UP) { callout_reset(&qp->link_work, NTB_LINK_DOWN_TIMEOUT * hz / 1000, ntb_qp_link_work, qp); diff --git a/sys/dev/ntb/ntb_hw/ntb_hw.c b/sys/dev/ntb/ntb_hw/ntb_hw.c index 72314dd5f273..019f2a77c8d9 100644 --- a/sys/dev/ntb/ntb_hw/ntb_hw.c +++ b/sys/dev/ntb/ntb_hw/ntb_hw.c @@ -76,10 +76,18 @@ enum ntb_device_type { NTB_SOC }; +/* Device features and workarounds */ +#define HAS_FEATURE(feature) \ + ((ntb->features & (feature)) != 0) + +#define NTB_BAR_SIZE_4K (1 << 0) +#define NTB_REGS_THRU_MW (1 << 1) + struct ntb_hw_info { uint32_t device_id; - enum ntb_device_type type; const char *desc; + enum ntb_device_type type; + uint64_t features; }; struct ntb_pci_bar_info { @@ -108,6 +116,7 @@ struct ntb_db_cb { struct ntb_softc { device_t device; enum ntb_device_type type; + uint64_t features; struct ntb_pci_bar_info bar_info[NTB_MAX_BARS]; struct ntb_int_info int_info[MAX_MSIX_INTERRUPTS]; @@ -145,26 +154,31 @@ struct ntb_softc { uint8_t link_speed; }; -#define ntb_reg_read(SIZE, offset) \ - bus_space_read_ ## SIZE (ntb->bar_info[NTB_CONFIG_BAR].pci_bus_tag, \ - ntb->bar_info[NTB_CONFIG_BAR].pci_bus_handle, (offset)) +#define ntb_bar_read(SIZE, bar, offset) \ + bus_space_read_ ## SIZE (ntb->bar_info[(bar)].pci_bus_tag, \ + ntb->bar_info[(bar)].pci_bus_handle, (offset)) +#define ntb_bar_write(SIZE, bar, offset, val) \ + bus_space_write_ ## SIZE (ntb->bar_info[(bar)].pci_bus_tag, \ + ntb->bar_info[(bar)].pci_bus_handle, (offset), (val)) +#define ntb_reg_read(SIZE, offset) ntb_bar_read(SIZE, NTB_CONFIG_BAR, offset) #define ntb_reg_write(SIZE, offset, val) \ - bus_space_write_ ## SIZE (ntb->bar_info[NTB_CONFIG_BAR].pci_bus_tag, \ - ntb->bar_info[NTB_CONFIG_BAR].pci_bus_handle, (offset), (val)) + ntb_bar_write(SIZE, NTB_CONFIG_BAR, offset, val) +#define ntb_mw_read(SIZE, offset) ntb_bar_read(SIZE, NTB_B2B_BAR_2, offset) +#define ntb_mw_write(SIZE, offset, val) \ + ntb_bar_write(SIZE, NTB_B2B_BAR_2, offset, val) -#define ntb_read_1(offset) ntb_reg_read(1, (offset)) -#define ntb_read_2(offset) ntb_reg_read(2, (offset)) -#define ntb_read_4(offset) ntb_reg_read(4, (offset)) -#define ntb_read_8(offset) ntb_reg_read(8, (offset)) -#define ntb_write_1(offset, val) ntb_reg_write(1, (offset), (val)) -#define ntb_write_2(offset, val) ntb_reg_write(2, (offset), (val)) -#define ntb_write_4(offset, val) ntb_reg_write(4, (offset), (val)) -#define ntb_write_8(offset, val) ntb_reg_write(8, (offset), (val)) +typedef int (*bar_map_strategy)(struct ntb_softc *ntb, + struct ntb_pci_bar_info *bar); static int ntb_probe(device_t device); static int ntb_attach(device_t device); static int ntb_detach(device_t device); -static int ntb_map_pci_bar(struct ntb_softc *ntb); +static int ntb_map_pci_bars(struct ntb_softc *ntb); +static int map_pci_bar(struct ntb_softc *ntb, bar_map_strategy strategy, + struct ntb_pci_bar_info *bar); +static int map_mmr_bar(struct ntb_softc *ntb, struct ntb_pci_bar_info *bar); +static int map_memory_window_bar(struct ntb_softc *ntb, + struct ntb_pci_bar_info *bar); static void ntb_unmap_pci_bar(struct ntb_softc *ntb); static int ntb_setup_interrupts(struct ntb_softc *ntb); static void ntb_teardown_interrupts(struct ntb_softc *ntb); @@ -178,17 +192,21 @@ static struct ntb_hw_info *ntb_get_device_info(uint32_t device_id); static int ntb_initialize_hw(struct ntb_softc *ntb); static int ntb_setup_xeon(struct ntb_softc *ntb); static int ntb_setup_soc(struct ntb_softc *ntb); +static void configure_soc_secondary_side_bars(struct ntb_softc *ntb); +static void configure_xeon_secondary_side_bars(struct ntb_softc *ntb); static void ntb_handle_heartbeat(void *arg); static void ntb_handle_link_event(struct ntb_softc *ntb, int link_state); static void recover_soc_link(void *arg); static int ntb_check_link_status(struct ntb_softc *ntb); -static bool is_bar_for_data_transfer(int bar_num); +static void save_bar_parameters(struct ntb_pci_bar_info *bar); static struct ntb_hw_info pci_ids[] = { - { 0x3C0D8086, NTB_XEON, "Xeon E5/Core i7 Non-Transparent Bridge B2B" }, - { 0x0C4E8086, NTB_SOC, "Atom Processor S1200 NTB Primary B2B" }, - { 0x0E0D8086, NTB_XEON, "Xeon E5 V2 Non-Transparent Bridge B2B" }, - { 0x00000000, NTB_SOC, NULL } + { 0x3C0D8086, "Xeon E5/Core i7 Non-Transparent Bridge B2B", NTB_XEON, + NTB_REGS_THRU_MW }, + { 0x0C4E8086, "Atom Processor S1200 NTB Primary B2B", NTB_SOC, 0 }, + { 0x0E0D8086, "Xeon E5 V2 Non-Transparent Bridge B2B", NTB_XEON, + NTB_REGS_THRU_MW | NTB_BAR_SIZE_4K }, + { 0x00000000, NULL, NTB_SOC, 0 } }; /* @@ -245,12 +263,13 @@ ntb_attach(device_t device) ntb->device = device; ntb->type = p->type; + ntb->features = p->features; /* Heartbeat timer for NTB_SOC since there is no link interrupt */ callout_init(&ntb->heartbeat_timer, CALLOUT_MPSAFE); callout_init(&ntb->lr_timer, CALLOUT_MPSAFE); - DETACH_ON_ERROR(ntb_map_pci_bar(ntb)); + DETACH_ON_ERROR(ntb_map_pci_bars(ntb)); DETACH_ON_ERROR(ntb_initialize_hw(ntb)); DETACH_ON_ERROR(ntb_setup_interrupts(ntb)); @@ -273,59 +292,122 @@ ntb_detach(device_t device) } static int -ntb_map_pci_bar(struct ntb_softc *ntb) +ntb_map_pci_bars(struct ntb_softc *ntb) { - struct ntb_pci_bar_info *current_bar; - int rc, i; + int rc; ntb->bar_info[NTB_CONFIG_BAR].pci_resource_id = PCIR_BAR(0); + rc = map_pci_bar(ntb, map_mmr_bar, &ntb->bar_info[NTB_CONFIG_BAR]); + if (rc != 0) + return rc; + ntb->bar_info[NTB_B2B_BAR_1].pci_resource_id = PCIR_BAR(2); + rc = map_pci_bar(ntb, map_memory_window_bar, + &ntb->bar_info[NTB_B2B_BAR_1]); + if (rc != 0) + return rc; + ntb->bar_info[NTB_B2B_BAR_2].pci_resource_id = PCIR_BAR(4); + if (HAS_FEATURE(NTB_REGS_THRU_MW)) + rc = map_pci_bar(ntb, map_mmr_bar, + &ntb->bar_info[NTB_B2B_BAR_2]); + else + rc = map_pci_bar(ntb, map_memory_window_bar, + &ntb->bar_info[NTB_B2B_BAR_2]); + if (rc != 0) + return rc; - for (i = 0; i< NTB_MAX_BARS; i++) { - current_bar = &ntb->bar_info[i]; - current_bar->pci_resource = - bus_alloc_resource(ntb->device, - SYS_RES_MEMORY, - ¤t_bar->pci_resource_id, 0, ~0, 1, - RF_ACTIVE); + return (0); +} - if (current_bar->pci_resource == NULL) { - device_printf(ntb->device, - "unable to allocate pci resource\n"); - return (ENXIO); +static int +map_pci_bar(struct ntb_softc *ntb, bar_map_strategy strategy, + struct ntb_pci_bar_info *bar) +{ + int rc; + + rc = strategy(ntb, bar); + if (rc != 0) { + device_printf(ntb->device, + "unable to allocate pci resource\n"); + } else { + device_printf(ntb->device, + "Bar size = %lx, v %p, p %p\n", + bar->size, bar->vbase, + (void *)(bar->pbase)); + } + return (rc); +} + +static int +map_mmr_bar(struct ntb_softc *ntb, struct ntb_pci_bar_info *bar) +{ + + bar->pci_resource = bus_alloc_resource_any(ntb->device, SYS_RES_MEMORY, + &bar->pci_resource_id, RF_ACTIVE); + + if (bar->pci_resource == NULL) + return (ENXIO); + else { + save_bar_parameters(bar); + return (0); + } +} + +static int +map_memory_window_bar(struct ntb_softc *ntb, struct ntb_pci_bar_info *bar) +{ + int rc; + uint8_t bar_size_bits = 0; + + bar->pci_resource = bus_alloc_resource_any(ntb->device, + SYS_RES_MEMORY, &bar->pci_resource_id, RF_ACTIVE); + + if (bar->pci_resource == NULL) + return (ENXIO); + else { + save_bar_parameters(bar); + /* + * Ivytown NTB BAR sizes are misreported by the hardware due to + * a hardware issue. To work around this, query the size it + * should be configured to by the device and modify the resource + * to correspond to this new size. The BIOS on systems with this + * problem is required to provide enough address space to allow + * the driver to make this change safely. + * + * Ideally I could have just specified the size when I allocated + * the resource like: + * bus_alloc_resource(ntb->device, + * SYS_RES_MEMORY, &bar->pci_resource_id, 0ul, ~0ul, + * 1ul << bar_size_bits, RF_ACTIVE); + * but the PCI driver does not honor the size in this call, so + * we have to modify it after the fact. + */ + if (HAS_FEATURE(NTB_BAR_SIZE_4K)) { + if (bar->pci_resource_id == PCIR_BAR(2)) + bar_size_bits = pci_read_config(ntb->device, + XEON_PBAR23SZ_OFFSET, 1); + else + bar_size_bits = pci_read_config(ntb->device, + XEON_PBAR45SZ_OFFSET, 1); + rc = bus_adjust_resource(ntb->device, SYS_RES_MEMORY, + bar->pci_resource, bar->pbase, + bar->pbase + (1ul << bar_size_bits) - 1); + if (rc != 0 ) { + device_printf(ntb->device, + "unable to resize bar\n"); + return (rc); + } else + save_bar_parameters(bar); } - else { - current_bar->pci_bus_tag = - rman_get_bustag(current_bar->pci_resource); - current_bar->pci_bus_handle = - rman_get_bushandle(current_bar->pci_resource); - current_bar->pbase = - rman_get_start(current_bar->pci_resource); - current_bar->size = - rman_get_size(current_bar->pci_resource); - current_bar->vbase = - rman_get_virtual(current_bar->pci_resource); - if (is_bar_for_data_transfer(i)) { - /* - * Mark bar region as write combining to improve - * performance. - */ - rc = pmap_change_attr( - (vm_offset_t)current_bar->vbase, - current_bar->size, - VM_MEMATTR_WRITE_COMBINING); - if (rc != 0) { - device_printf(ntb->device, - "Couldn't mark bar as" - " WRITE_COMBINING\n"); - return (rc); - } - } - device_printf(ntb->device, - "Bar size = %lx, v %p, p %p\n", - current_bar->size, current_bar->vbase, - (void *)(current_bar->pbase)); + + /* Mark bar region as write combining to improve performance. */ + rc = pmap_change_attr((vm_offset_t)bar->vbase, bar->size, + VM_MEMATTR_WRITE_COMBINING); + if (rc != 0) { + device_printf(ntb->device, "unable to mark bar as" + " WRITE_COMBINING\n"); + return (rc); } } return (0); @@ -361,9 +443,9 @@ ntb_setup_interrupts(struct ntb_softc *ntb) * Interrupt. The rest will be unmasked as callbacks are registered. */ if (ntb->type == NTB_SOC) - ntb_write_8(ntb->reg_ofs.pdb_mask, ~0); + ntb_reg_write(8, ntb->reg_ofs.pdb_mask, ~0); else - ntb_write_2(ntb->reg_ofs.pdb_mask, + ntb_reg_write(2, ntb->reg_ofs.pdb_mask, ~(1 << ntb->limits.max_db_bits)); num_vectors = MIN(pci_msix_count(ntb->device), @@ -393,7 +475,8 @@ ntb_setup_interrupts(struct ntb_softc *ntb) int_arg = &ntb->db_cb[i]; } else { if (i == num_vectors - 1) { - interrupt_handler = handle_xeon_event_irq; + interrupt_handler = + handle_xeon_event_irq; int_arg = ntb; } else { interrupt_handler = @@ -413,8 +496,8 @@ ntb_setup_interrupts(struct ntb_softc *ntb) } else { ntb->int_info[0].rid = 0; - ntb->int_info[0].res = bus_alloc_resource_any(ntb->device, SYS_RES_IRQ, - &ntb->int_info[0].rid, RF_SHAREABLE|RF_ACTIVE); + ntb->int_info[0].res = bus_alloc_resource_any(ntb->device, + SYS_RES_IRQ, &ntb->int_info[0].rid, RF_SHAREABLE|RF_ACTIVE); interrupt_handler = ntb_handle_legacy_interrupt; if (ntb->int_info[0].res == NULL) { device_printf(ntb->device, @@ -463,7 +546,7 @@ handle_soc_irq(void *arg) struct ntb_db_cb *db_cb = arg; struct ntb_softc *ntb = db_cb->ntb; - ntb_write_8(ntb->reg_ofs.pdb, (uint64_t) 1 << db_cb->db_num); + ntb_reg_write(8, ntb->reg_ofs.pdb, (uint64_t) 1 << db_cb->db_num); if (db_cb->callback != NULL) db_cb->callback(db_cb->data, db_cb->db_num); @@ -481,7 +564,7 @@ handle_xeon_irq(void *arg) * vectors, with the 4th having a single bit for link * interrupts. */ - ntb_write_2(ntb->reg_ofs.pdb, + ntb_reg_write(2, ntb->reg_ofs.pdb, ((1 << ntb->bits_per_vector) - 1) << (db_cb->db_num * ntb->bits_per_vector)); @@ -501,7 +584,7 @@ handle_xeon_event_irq(void *arg) device_printf(ntb->device, "Error determining link status\n"); /* bit 15 is always the link bit */ - ntb_write_2(ntb->reg_ofs.pdb, 1 << ntb->limits.max_db_bits); + ntb_reg_write(2, ntb->reg_ofs.pdb, 1 << ntb->limits.max_db_bits); } static void @@ -513,7 +596,7 @@ ntb_handle_legacy_interrupt(void *arg) uint16_t pdb16; if (ntb->type == NTB_SOC) { - pdb64 = ntb_read_8(ntb->reg_ofs.pdb); + pdb64 = ntb_reg_read(8, ntb->reg_ofs.pdb); while (pdb64) { i = ffs(pdb64); @@ -521,7 +604,7 @@ ntb_handle_legacy_interrupt(void *arg) handle_soc_irq(&ntb->db_cb[i]); } } else { - pdb16 = ntb_read_2(ntb->reg_ofs.pdb); + pdb16 = ntb_reg_read(2, ntb->reg_ofs.pdb); if ((pdb16 & XEON_DB_HW_LINK) != 0) { handle_xeon_event_irq(ntb); @@ -634,10 +717,15 @@ ntb_setup_xeon(struct ntb_softc *ntb) ntb->limits.msix_cnt = XEON_MSIX_CNT; ntb->bits_per_vector = XEON_DB_BITS_PER_VEC; + configure_xeon_secondary_side_bars(ntb); /* Enable Bus Master and Memory Space on the secondary side */ - ntb_write_2(ntb->reg_ofs.spci_cmd, + ntb_reg_write(2, ntb->reg_ofs.spci_cmd, PCIM_CMD_MEMEN | PCIM_CMD_BUSMASTEREN); + /* Enable link training */ + ntb_reg_write(4, ntb->reg_ofs.lnk_cntl, + NTB_CNTL_BAR23_SNOOP | NTB_CNTL_BAR45_SNOOP); + return (0); } @@ -698,49 +786,63 @@ ntb_setup_soc(struct ntb_softc *ntb) */ pci_write_config(ntb->device, 0xFC, 0x4, 4); - /* - * Some BIOSes aren't filling out the XLAT offsets. - * Check and correct the issue. - */ - if (ntb->dev_type == NTB_DEV_USD) { - if (ntb_read_8(SOC_PBAR2XLAT_OFFSET) == 0) - ntb_write_8(SOC_PBAR2XLAT_OFFSET, - SOC_PBAR2XLAT_USD_ADDR); - - if (ntb_read_8(SOC_PBAR4XLAT_OFFSET) == 0) - ntb_write_8(SOC_PBAR4XLAT_OFFSET, - SOC_PBAR4XLAT_USD_ADDR); - - if (ntb_read_8(SOC_MBAR23_OFFSET) == 0xC) - ntb_write_8(SOC_MBAR23_OFFSET, SOC_MBAR23_USD_ADDR); - - if (ntb_read_8(SOC_MBAR45_OFFSET) == 0xC) - ntb_write_8(SOC_MBAR45_OFFSET, SOC_MBAR45_USD_ADDR); - } else { - if (ntb_read_8(SOC_PBAR2XLAT_OFFSET) == 0) - ntb_write_8(SOC_PBAR2XLAT_OFFSET, - SOC_PBAR2XLAT_DSD_ADDR); - - if (ntb_read_8(SOC_PBAR4XLAT_OFFSET) == 0) - ntb_write_8(SOC_PBAR4XLAT_OFFSET, - SOC_PBAR4XLAT_DSD_ADDR); - - if (ntb_read_8(SOC_MBAR23_OFFSET) == 0xC) - ntb_write_8(SOC_MBAR23_OFFSET, SOC_MBAR23_DSD_ADDR); - - if (ntb_read_8(SOC_MBAR45_OFFSET) == 0xC) - ntb_write_8(SOC_MBAR45_OFFSET, SOC_MBAR45_DSD_ADDR); - } + configure_soc_secondary_side_bars(ntb); /* Enable Bus Master and Memory Space on the secondary side */ - ntb_write_2(ntb->reg_ofs.spci_cmd, + ntb_reg_write(2, ntb->reg_ofs.spci_cmd, PCIM_CMD_MEMEN | PCIM_CMD_BUSMASTEREN); callout_reset(&ntb->heartbeat_timer, 0, ntb_handle_heartbeat, ntb); return (0); } -/* SOC doesn't have link status interrupt, poll on that platform */ +static void +configure_soc_secondary_side_bars(struct ntb_softc *ntb) +{ + + if (ntb->dev_type == NTB_DEV_USD) { + ntb_reg_write(8, SOC_PBAR2XLAT_OFFSET, PBAR2XLAT_USD_ADDR); + ntb_reg_write(8, SOC_PBAR4XLAT_OFFSET, PBAR4XLAT_USD_ADDR); + ntb_reg_write(8, SOC_MBAR23_OFFSET, MBAR23_USD_ADDR); + ntb_reg_write(8, SOC_MBAR45_OFFSET, MBAR45_USD_ADDR); + } else { + ntb_reg_write(8, SOC_PBAR2XLAT_OFFSET, PBAR2XLAT_DSD_ADDR); + ntb_reg_write(8, SOC_PBAR4XLAT_OFFSET, PBAR4XLAT_DSD_ADDR); + ntb_reg_write(8, SOC_MBAR23_OFFSET, MBAR23_DSD_ADDR); + ntb_reg_write(8, SOC_MBAR45_OFFSET, MBAR45_DSD_ADDR); + } +} + +static void +configure_xeon_secondary_side_bars(struct ntb_softc *ntb) +{ + + if (ntb->dev_type == NTB_DEV_USD) { + ntb_reg_write(8, XEON_PBAR2XLAT_OFFSET, PBAR2XLAT_USD_ADDR); + if (HAS_FEATURE(NTB_REGS_THRU_MW)) + ntb_reg_write(8, XEON_PBAR4XLAT_OFFSET, + MBAR01_DSD_ADDR); + else + ntb_reg_write(8, XEON_PBAR4XLAT_OFFSET, + PBAR4XLAT_USD_ADDR); + ntb_reg_write(8, XEON_SBAR0BASE_OFFSET, MBAR01_USD_ADDR); + ntb_reg_write(8, XEON_SBAR2BASE_OFFSET, MBAR23_USD_ADDR); + ntb_reg_write(8, XEON_SBAR4BASE_OFFSET, MBAR45_USD_ADDR); + } else { + ntb_reg_write(8, XEON_PBAR2XLAT_OFFSET, PBAR2XLAT_DSD_ADDR); + if (HAS_FEATURE(NTB_REGS_THRU_MW)) + ntb_reg_write(8, XEON_PBAR4XLAT_OFFSET, + MBAR01_USD_ADDR); + else + ntb_reg_write(8, XEON_PBAR4XLAT_OFFSET, + PBAR4XLAT_DSD_ADDR); + ntb_reg_write(8, XEON_SBAR0BASE_OFFSET, MBAR01_DSD_ADDR); + ntb_reg_write(8, XEON_SBAR2BASE_OFFSET, MBAR23_DSD_ADDR); + ntb_reg_write(8, XEON_SBAR4BASE_OFFSET, MBAR45_DSD_ADDR); + } +} + +/* SOC does not have link status interrupt, poll on that platform */ static void ntb_handle_heartbeat(void *arg) { @@ -753,7 +855,7 @@ ntb_handle_heartbeat(void *arg) "Error determining link status\n"); /* Check to see if a link error is the cause of the link down */ if (ntb->link_status == NTB_LINK_DOWN) { - status32 = ntb_read_4(SOC_LTSSMSTATEJMP_OFFSET); + status32 = ntb_reg_read(4, SOC_LTSSMSTATEJMP_OFFSET); if ((status32 & SOC_LTSSMSTATEJMP_FORCEDETECT) != 0) { callout_reset(&ntb->lr_timer, 0, recover_soc_link, ntb); @@ -771,37 +873,37 @@ soc_perform_link_restart(struct ntb_softc *ntb) uint32_t status; /* Driver resets the NTB ModPhy lanes - magic! */ - ntb_write_1(SOC_MODPHY_PCSREG6, 0xe0); - ntb_write_1(SOC_MODPHY_PCSREG4, 0x40); - ntb_write_1(SOC_MODPHY_PCSREG4, 0x60); - ntb_write_1(SOC_MODPHY_PCSREG6, 0x60); + ntb_reg_write(1, SOC_MODPHY_PCSREG6, 0xe0); + ntb_reg_write(1, SOC_MODPHY_PCSREG4, 0x40); + ntb_reg_write(1, SOC_MODPHY_PCSREG4, 0x60); + ntb_reg_write(1, SOC_MODPHY_PCSREG6, 0x60); /* Driver waits 100ms to allow the NTB ModPhy to settle */ pause("ModPhy", hz / 10); /* Clear AER Errors, write to clear */ - status = ntb_read_4(SOC_ERRCORSTS_OFFSET); + status = ntb_reg_read(4, SOC_ERRCORSTS_OFFSET); status &= PCIM_AER_COR_REPLAY_ROLLOVER; - ntb_write_4(SOC_ERRCORSTS_OFFSET, status); + ntb_reg_write(4, SOC_ERRCORSTS_OFFSET, status); /* Clear unexpected electrical idle event in LTSSM, write to clear */ - status = ntb_read_4(SOC_LTSSMERRSTS0_OFFSET); + status = ntb_reg_read(4, SOC_LTSSMERRSTS0_OFFSET); status |= SOC_LTSSMERRSTS0_UNEXPECTEDEI; - ntb_write_4(SOC_LTSSMERRSTS0_OFFSET, status); + ntb_reg_write(4, SOC_LTSSMERRSTS0_OFFSET, status); /* Clear DeSkew Buffer error, write to clear */ - status = ntb_read_4(SOC_DESKEWSTS_OFFSET); + status = ntb_reg_read(4, SOC_DESKEWSTS_OFFSET); status |= SOC_DESKEWSTS_DBERR; - ntb_write_4(SOC_DESKEWSTS_OFFSET, status); + ntb_reg_write(4, SOC_DESKEWSTS_OFFSET, status); - status = ntb_read_4(SOC_IBSTERRRCRVSTS0_OFFSET); + status = ntb_reg_read(4, SOC_IBSTERRRCRVSTS0_OFFSET); status &= SOC_IBIST_ERR_OFLOW; - ntb_write_4(SOC_IBSTERRRCRVSTS0_OFFSET, status); + ntb_reg_write(4, SOC_IBSTERRRCRVSTS0_OFFSET, status); /* Releases the NTB state machine to allow the link to retrain */ - status = ntb_read_4(SOC_LTSSMSTATEJMP_OFFSET); + status = ntb_reg_read(4, SOC_LTSSMSTATEJMP_OFFSET); status &= ~SOC_LTSSMSTATEJMP_FORCEDETECT; - ntb_write_4(SOC_LTSSMSTATEJMP_OFFSET, status); + ntb_reg_write(4, SOC_LTSSMSTATEJMP_OFFSET, status); } static void @@ -819,7 +921,7 @@ ntb_handle_link_event(struct ntb_softc *ntb, int link_state) event = NTB_EVENT_HW_LINK_UP; if (ntb->type == NTB_SOC) - status = ntb_read_2(ntb->reg_ofs.lnk_stat); + status = ntb_reg_read(2, ntb->reg_ofs.lnk_stat); else status = pci_read_config(ntb->device, XEON_LINK_STATUS_OFFSET, 2); @@ -833,7 +935,7 @@ ntb_handle_link_event(struct ntb_softc *ntb, int link_state) device_printf(ntb->device, "Link Down\n"); ntb->link_status = NTB_LINK_DOWN; event = NTB_EVENT_HW_LINK_DOWN; - /* Don't modify link width/speed, we need it in link recovery */ + /* Do not modify link width/speed, we need it in link recovery */ } /* notify the upper layer if we have an event change */ @@ -852,15 +954,15 @@ recover_soc_link(void *arg) soc_perform_link_restart(ntb); pause("Link", SOC_LINK_RECOVERY_TIME * hz / 1000); - status32 = ntb_read_4(SOC_LTSSMSTATEJMP_OFFSET); + status32 = ntb_reg_read(4, SOC_LTSSMSTATEJMP_OFFSET); if ((status32 & SOC_LTSSMSTATEJMP_FORCEDETECT) != 0) goto retry; - status32 = ntb_read_4(SOC_IBSTERRRCRVSTS0_OFFSET); + status32 = ntb_reg_read(4, SOC_IBSTERRRCRVSTS0_OFFSET); if ((status32 & SOC_IBIST_ERR_OFLOW) != 0) goto retry; - status16 = ntb_read_2(ntb->reg_ofs.lnk_stat); + status16 = ntb_reg_read(2, ntb->reg_ofs.lnk_stat); width = (status16 & NTB_LINK_WIDTH_MASK) >> 4; speed = (status16 & NTB_LINK_SPEED_MASK); if (ntb->link_width != width || ntb->link_speed != speed) @@ -883,7 +985,7 @@ ntb_check_link_status(struct ntb_softc *ntb) uint16_t status; if (ntb->type == NTB_SOC) { - ntb_cntl = ntb_read_4(ntb->reg_ofs.lnk_cntl); + ntb_cntl = ntb_reg_read(4, ntb->reg_ofs.lnk_cntl); if ((ntb_cntl & SOC_CNTL_LINK_DOWN) != 0) link_state = NTB_LINK_DOWN; else @@ -965,9 +1067,9 @@ ntb_register_db_callback(struct ntb_softc *ntb, unsigned int idx, void *data, ntb->db_cb[idx].data = data; /* unmask interrupt */ - mask = ntb_read_2(ntb->reg_ofs.pdb_mask); + mask = ntb_reg_read(2, ntb->reg_ofs.pdb_mask); mask &= ~(1 << (idx * ntb->bits_per_vector)); - ntb_write_2(ntb->reg_ofs.pdb_mask, mask); + ntb_reg_write(2, ntb->reg_ofs.pdb_mask, mask); return (0); } @@ -988,9 +1090,9 @@ ntb_unregister_db_callback(struct ntb_softc *ntb, unsigned int idx) if (idx >= ntb->allocated_interrupts || !ntb->db_cb[idx].callback) return; - mask = ntb_read_2(ntb->reg_ofs.pdb_mask); + mask = ntb_reg_read(2, ntb->reg_ofs.pdb_mask); mask |= 1 << (idx * ntb->bits_per_vector); - ntb_write_2(ntb->reg_ofs.pdb_mask, mask); + ntb_reg_write(2, ntb->reg_ofs.pdb_mask, mask); ntb->db_cb[idx].callback = NULL; } @@ -1091,7 +1193,7 @@ ntb_write_local_spad(struct ntb_softc *ntb, unsigned int idx, uint32_t val) if (idx >= ntb->limits.max_spads) return (EINVAL); - ntb_write_4(ntb->reg_ofs.spad_local + idx * 4, val); + ntb_reg_write(4, ntb->reg_ofs.spad_local + idx * 4, val); return (0); } @@ -1114,7 +1216,7 @@ ntb_read_local_spad(struct ntb_softc *ntb, unsigned int idx, uint32_t *val) if (idx >= ntb->limits.max_spads) return (EINVAL); - *val = ntb_read_4(ntb->reg_ofs.spad_local + idx * 4); + *val = ntb_reg_read(4, ntb->reg_ofs.spad_local + idx * 4); return (0); } @@ -1137,7 +1239,10 @@ ntb_write_remote_spad(struct ntb_softc *ntb, unsigned int idx, uint32_t val) if (idx >= ntb->limits.max_spads) return (EINVAL); - ntb_write_4(ntb->reg_ofs.spad_remote + idx * 4, val); + if (HAS_FEATURE(NTB_REGS_THRU_MW)) + ntb_mw_write(4, XEON_SHADOW_SPAD_OFFSET + idx * 4, val); + else + ntb_reg_write(4, ntb->reg_ofs.spad_remote + idx * 4, val); return (0); } @@ -1160,7 +1265,10 @@ ntb_read_remote_spad(struct ntb_softc *ntb, unsigned int idx, uint32_t *val) if (idx >= ntb->limits.max_spads) return (EINVAL); - *val = ntb_read_4(ntb->reg_ofs.spad_remote + idx * 4); + if (HAS_FEATURE(NTB_REGS_THRU_MW)) + *val = ntb_mw_read(4, XEON_SHADOW_SPAD_OFFSET + idx * 4); + else + *val = ntb_reg_read(4, ntb->reg_ofs.spad_remote + idx * 4); return (0); } @@ -1233,10 +1341,10 @@ ntb_set_mw_addr(struct ntb_softc *ntb, unsigned int mw, uint64_t addr) switch (NTB_MW_TO_BAR(mw)) { case NTB_B2B_BAR_1: - ntb_write_8(ntb->reg_ofs.sbar2_xlat, addr); + ntb_reg_write(8, ntb->reg_ofs.sbar2_xlat, addr); break; case NTB_B2B_BAR_2: - ntb_write_8(ntb->reg_ofs.sbar4_xlat, addr); + ntb_reg_write(8, ntb->reg_ofs.sbar4_xlat, addr); break; } } @@ -1256,11 +1364,16 @@ ntb_ring_sdb(struct ntb_softc *ntb, unsigned int db) { if (ntb->type == NTB_SOC) - ntb_write_8(ntb->reg_ofs.sdb, (uint64_t) 1 << db); + ntb_reg_write(8, ntb->reg_ofs.sdb, (uint64_t) 1 << db); else - ntb_write_2(ntb->reg_ofs.sdb, - ((1 << ntb->bits_per_vector) - 1) << - (db * ntb->bits_per_vector)); + if (HAS_FEATURE(NTB_REGS_THRU_MW)) + ntb_mw_write(2, XEON_SHADOW_PDOORBELL_OFFSET, + ((1 << ntb->bits_per_vector) - 1) << + (db * ntb->bits_per_vector)); + else + ntb_reg_write(2, ntb->reg_ofs.sdb, + ((1 << ntb->bits_per_vector) - 1) << + (db * ntb->bits_per_vector)); } /** @@ -1278,11 +1391,24 @@ ntb_query_link_status(struct ntb_softc *ntb) return (ntb->link_status == NTB_LINK_UP); } -static bool -is_bar_for_data_transfer(int bar_num) +static void +save_bar_parameters(struct ntb_pci_bar_info *bar) { - if ((bar_num > NTB_CONFIG_BAR) && (bar_num < NTB_MAX_BARS)) - return true; - else - return false; + bar->pci_bus_tag = + rman_get_bustag(bar->pci_resource); + bar->pci_bus_handle = + rman_get_bushandle(bar->pci_resource); + bar->pbase = + rman_get_start(bar->pci_resource); + bar->size = + rman_get_size(bar->pci_resource); + bar->vbase = + rman_get_virtual(bar->pci_resource); + +} + +device_t ntb_get_device(struct ntb_softc *ntb) +{ + + return (ntb->device); } diff --git a/sys/dev/ntb/ntb_hw/ntb_hw.h b/sys/dev/ntb/ntb_hw/ntb_hw.h index 4f44031a024b..c6c1274d17bc 100644 --- a/sys/dev/ntb/ntb_hw/ntb_hw.h +++ b/sys/dev/ntb/ntb_hw/ntb_hw.h @@ -69,5 +69,6 @@ u_long ntb_get_mw_size(struct ntb_softc *ntb, unsigned int mw); void ntb_set_mw_addr(struct ntb_softc *ntb, unsigned int mw, uint64_t addr); void ntb_ring_sdb(struct ntb_softc *ntb, unsigned int db); bool ntb_query_link_status(struct ntb_softc *ntb); +device_t ntb_get_device(struct ntb_softc *ntb); #endif /* _NTB_HW_H_ */ diff --git a/sys/dev/ntb/ntb_hw/ntb_regs.h b/sys/dev/ntb/ntb_hw/ntb_regs.h index 34ad779632fd..bd55a59184ba 100644 --- a/sys/dev/ntb/ntb_hw/ntb_regs.h +++ b/sys/dev/ntb/ntb_hw/ntb_regs.h @@ -39,14 +39,14 @@ #define XEON_MAX_SPADS 16 #define XEON_MAX_COMPAT_SPADS 8 /* Reserve the uppermost bit for link interrupt */ -#define XEON_MAX_DB_BITS 15 +#define XEON_MAX_DB_BITS 15 #define XEON_DB_BITS_PER_VEC 5 #define XEON_DB_HW_LINK 0x8000 #define XEON_PCICMD_OFFSET 0x0504 #define XEON_DEVCTRL_OFFSET 0x0598 -#define XEON_LINK_STATUS_OFFSET 0x01A2 +#define XEON_LINK_STATUS_OFFSET 0x01a2 #define XEON_PBAR2LMT_OFFSET 0x0000 #define XEON_PBAR4LMT_OFFSET 0x0008 @@ -60,13 +60,13 @@ #define XEON_SBAR2BASE_OFFSET 0x0048 #define XEON_SBAR4BASE_OFFSET 0x0050 #define XEON_NTBCNTL_OFFSET 0x0058 -#define XEON_SBDF_OFFSET 0x005C +#define XEON_SBDF_OFFSET 0x005c #define XEON_PDOORBELL_OFFSET 0x0060 #define XEON_PDBMSK_OFFSET 0x0062 #define XEON_SDOORBELL_OFFSET 0x0064 #define XEON_SDBMSK_OFFSET 0x0066 #define XEON_USMEMMISS 0x0070 -#define XEON_SPAD_OFFSET 0x0080 +#define XEON_SPAD_OFFSET 0x0080 #define XEON_SPADSEMA4_OFFSET 0x00c0 #define XEON_WCCNTRL_OFFSET 0x00e0 #define XEON_B2B_SPAD_OFFSET 0x0100 @@ -105,7 +105,7 @@ #define SOC_MODPHY_PCSREG4 0x1c004 #define SOC_MODPHY_PCSREG6 0x1c006 -#define SOC_IP_BASE 0xC000 +#define SOC_IP_BASE 0xc000 #define SOC_DESKEWSTS_OFFSET (SOC_IP_BASE + 0x3024) #define SOC_LTSSMERRSTS0_OFFSET (SOC_IP_BASE + 0x3180) #define SOC_LTSSMSTATEJMP_OFFSET (SOC_IP_BASE + 0x3040) @@ -114,13 +114,15 @@ #define SOC_DESKEWSTS_DBERR (1 << 15) #define SOC_LTSSMERRSTS0_UNEXPECTEDEI (1 << 20) #define SOC_LTSSMSTATEJMP_FORCEDETECT (1 << 2) -#define SOC_IBIST_ERR_OFLOW 0x7FFF7FFF +#define SOC_IBIST_ERR_OFLOW 0x7fff7fff #define NTB_CNTL_BAR23_SNOOP (1 << 2) #define NTB_CNTL_BAR45_SNOOP (1 << 6) #define SOC_CNTL_LINK_DOWN (1 << 16) -#define NTB_PPD_OFFSET 0x00D4 +#define XEON_PBAR23SZ_OFFSET 0x00d0 +#define XEON_PBAR45SZ_OFFSET 0x00d1 +#define NTB_PPD_OFFSET 0x00d4 #define XEON_PPD_CONN_TYPE 0x0003 #define XEON_PPD_DEV_TYPE 0x0010 #define SOC_PPD_INIT_LINK 0x0008 @@ -134,13 +136,19 @@ #define NTB_DEV_DSD 1 #define NTB_DEV_USD 0 -#define SOC_PBAR2XLAT_USD_ADDR 0x0000004000000000 -#define SOC_PBAR4XLAT_USD_ADDR 0x0000008000000000 -#define SOC_MBAR23_USD_ADDR 0x000000410000000C -#define SOC_MBAR45_USD_ADDR 0x000000810000000C -#define SOC_PBAR2XLAT_DSD_ADDR 0x0000004100000000 -#define SOC_PBAR4XLAT_DSD_ADDR 0x0000008100000000 -#define SOC_MBAR23_DSD_ADDR 0x000000400000000C -#define SOC_MBAR45_DSD_ADDR 0x000000800000000C +#define PBAR2XLAT_USD_ADDR 0x0000004000000000 +#define PBAR4XLAT_USD_ADDR 0x0000008000000000 +#define MBAR01_USD_ADDR 0x000000210000000c +#define MBAR23_USD_ADDR 0x000000410000000c +#define MBAR45_USD_ADDR 0x000000810000000c +#define PBAR2XLAT_DSD_ADDR 0x0000004100000000 +#define PBAR4XLAT_DSD_ADDR 0x0000008100000000 +#define MBAR01_DSD_ADDR 0x000000200000000c +#define MBAR23_DSD_ADDR 0x000000400000000c +#define MBAR45_DSD_ADDR 0x000000800000000c + +/* XEON Shadowed MMIO Space */ +#define XEON_SHADOW_PDOORBELL_OFFSET 0x60 +#define XEON_SHADOW_SPAD_OFFSET 0x80 #endif /* _NTB_REGS_H_ */ diff --git a/sys/dev/ofw/ofw_console.c b/sys/dev/ofw/ofw_console.c index e71d5c19eb8f..01f86bf7fe84 100644 --- a/sys/dev/ofw/ofw_console.c +++ b/sys/dev/ofw/ofw_console.c @@ -88,17 +88,19 @@ cn_drvinit(void *unused) if (ofw_consdev.cn_pri != CN_DEAD && ofw_consdev.cn_name[0] != '\0') { - if ((options = OF_finddevice("/options")) == -1 || - OF_getprop(options, "output-device", output, - sizeof(output)) == -1) - return; + tp = tty_alloc(&ofw_ttydevsw, NULL); + tty_makedev(tp, NULL, "%s", "ofwcons"); + /* * XXX: This is a hack and it may result in two /dev/ttya * XXX: devices on platforms where the sab driver works. */ - tp = tty_alloc(&ofw_ttydevsw, NULL); - tty_makedev(tp, NULL, "%s", output); - tty_makealias(tp, "ofwcons"); + if ((options = OF_finddevice("/options")) == -1 || + OF_getprop(options, "output-device", output, + sizeof(output)) == -1) + return; + if (strlen(output) > 0) + tty_makealias(tp, output); } } diff --git a/sys/dev/random/harvest.c b/sys/dev/random/harvest.c index a1ff8dde4c60..473e429317a8 100644 --- a/sys/dev/random/harvest.c +++ b/sys/dev/random/harvest.c @@ -1,5 +1,5 @@ /*- - * Copyright (c) 2000-2004 Mark R V Murray + * Copyright (c) 2000-2013 Mark R V Murray * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -60,7 +60,7 @@ static int (*read_func)(void *, int) = read_random_phony; /* Initialise the harvester at load time */ void -random_yarrow_init_harvester(void (*reaper)(u_int64_t, const void *, u_int, +randomdev_init_harvester(void (*reaper)(u_int64_t, const void *, u_int, u_int, u_int, enum esource), int (*reader)(void *, int)) { reap_func = reaper; @@ -69,7 +69,7 @@ random_yarrow_init_harvester(void (*reaper)(u_int64_t, const void *, u_int, /* Deinitialise the harvester at unload time */ void -random_yarrow_deinit_harvester(void) +randomdev_deinit_harvester(void) { reap_func = NULL; read_func = read_random_phony; diff --git a/sys/dev/random/hash.c b/sys/dev/random/hash.c index 611f866c4242..cf0feaa66ef9 100644 --- a/sys/dev/random/hash.c +++ b/sys/dev/random/hash.c @@ -1,5 +1,5 @@ /*- - * Copyright (c) 2000-2004 Mark R V Murray + * Copyright (c) 2000-2013 Mark R V Murray * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -36,46 +36,46 @@ __FBSDID("$FreeBSD$"); #include -/* initialise the hash */ +/* Initialise the hash */ void -yarrow_hash_init(struct yarrowhash *context) +randomdev_hash_init(struct randomdev_hash *context) { SHA256_Init(&context->sha); } -/* iterate the hash */ +/* Iterate the hash */ void -yarrow_hash_iterate(struct yarrowhash *context, void *data, size_t size) +randomdev_hash_iterate(struct randomdev_hash *context, void *data, size_t size) { SHA256_Update(&context->sha, data, size); } -/* Conclude by returning the hash in the supplied /buf/ which must be +/* Conclude by returning the hash in the supplied <*buf> which must be * KEYSIZE bytes long. */ void -yarrow_hash_finish(struct yarrowhash *context, void *buf) +randomdev_hash_finish(struct randomdev_hash *context, void *buf) { SHA256_Final(buf, &context->sha); } /* Initialise the encryption routine by setting up the key schedule - * from the supplied /data/ which must be KEYSIZE bytes of binary - * data. + * from the supplied <*data> which must be KEYSIZE bytes of binary + * data. Use CBC mode for better avalanche. */ void -yarrow_encrypt_init(struct yarrowkey *context, void *data) +randomdev_encrypt_init(struct randomdev_key *context, void *data) { rijndael_cipherInit(&context->cipher, MODE_CBC, NULL); rijndael_makeKey(&context->key, DIR_ENCRYPT, KEYSIZE*8, data); } /* Encrypt the supplied data using the key schedule preset in the context. - * KEYSIZE bytes are encrypted from /d_in/ to /d_out/. + * bytes are encrypted from <*d_in> to <*d_out>. must be + * a multiple of BLOCKSIZE. */ void -yarrow_encrypt(struct yarrowkey *context, void *d_in, void *d_out) +randomdev_encrypt(struct randomdev_key *context, void *d_in, void *d_out, unsigned length) { - rijndael_blockEncrypt(&context->cipher, &context->key, d_in, - KEYSIZE*8, d_out); + rijndael_blockEncrypt(&context->cipher, &context->key, d_in, length*8, d_out); } diff --git a/sys/dev/random/hash.h b/sys/dev/random/hash.h index 8580d145d683..62f116daa00d 100644 --- a/sys/dev/random/hash.h +++ b/sys/dev/random/hash.h @@ -1,5 +1,5 @@ /*- - * Copyright (c) 2000-2004 Mark R V Murray + * Copyright (c) 2000-2013 Mark R V Murray * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -26,19 +26,20 @@ * $FreeBSD$ */ -#define KEYSIZE 32 /* (in bytes) 32 bytes == 256 bits */ +#define KEYSIZE 32 /* (in bytes) == 256 bits */ +#define BLOCKSIZE 16 /* (in bytes) == 128 bits */ -struct yarrowhash { /* Big! Make static! */ +struct randomdev_hash { /* Big! Make static! */ SHA256_CTX sha; }; -struct yarrowkey { /* Big! Make static! */ +struct randomdev_key { /* Big! Make static! */ keyInstance key; /* Key schedule */ cipherInstance cipher; /* Rijndael internal */ }; -void yarrow_hash_init(struct yarrowhash *); -void yarrow_hash_iterate(struct yarrowhash *, void *, size_t); -void yarrow_hash_finish(struct yarrowhash *, void *); -void yarrow_encrypt_init(struct yarrowkey *, void *); -void yarrow_encrypt(struct yarrowkey *context, void *, void *); +void randomdev_hash_init(struct randomdev_hash *); +void randomdev_hash_iterate(struct randomdev_hash *, void *, size_t); +void randomdev_hash_finish(struct randomdev_hash *, void *); +void randomdev_encrypt_init(struct randomdev_key *, void *); +void randomdev_encrypt(struct randomdev_key *context, void *, void *, unsigned); diff --git a/sys/dev/random/pseudo_rng.c b/sys/dev/random/pseudo_rng.c new file mode 100644 index 000000000000..15cc7b3785d2 --- /dev/null +++ b/sys/dev/random/pseudo_rng.c @@ -0,0 +1,125 @@ +/*- + * Copyright (c) 2013 Arthur Mesh + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer + * in this position and unchanged. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ +#include +__FBSDID("$FreeBSD$"); + +#include +#include +#include +#include +#include +#include + +#include +#include + +static struct mtx pseudo_random_block_mtx; + +/* Used to fake out unused random calls in random_adaptor */ +void +random_null_func(void) +{ +} + +static int +pseudo_random_block_read(void *buf __unused, int c __unused) +{ + + mtx_lock(&pseudo_random_block_mtx); + + printf("random(4) device is blocking.\n"); + msleep(pseudo_random_block_read, &pseudo_random_block_mtx, 0, + "block", 0); + + mtx_unlock(&pseudo_random_block_mtx); + + return (0); +} + +static void +pseudo_random_block_init(void) +{ + + mtx_init(&pseudo_random_block_mtx, "sleep mtx for random_block", + NULL, MTX_DEF); +} + +static void +pseudo_random_block_deinit(void) +{ + + mtx_destroy(&pseudo_random_block_mtx); +} + +struct random_adaptor pseudo_random_block = { + .ident = "pseudo-RNG that always blocks", + .init = pseudo_random_block_init, + .deinit = pseudo_random_block_deinit, + .read = pseudo_random_block_read, + .write = (random_write_func_t *)random_null_func, + .reseed = (random_reseed_func_t *)random_null_func, + .seeded = 1, +}; + +static int +pseudo_random_panic_read(void *buf, int c) +{ + + panic("Insert a witty panic msg in here."); + + return (0); +} + +struct random_adaptor pseudo_random_panic = { + .ident = "pseudo-RNG that always panics on first read(2)", + .init = (random_init_func_t *)random_null_func, + .deinit = (random_deinit_func_t *)random_null_func, + .read = pseudo_random_panic_read, + .write = (random_write_func_t *)random_null_func, + .reseed = (random_reseed_func_t *)random_null_func, + .seeded = 1, +}; + +static int +pseudo_random_modevent(module_t mod, int type, void *unused) +{ + + switch (type) { + case MOD_LOAD: + random_adaptor_register("block", &pseudo_random_block); + EVENTHANDLER_INVOKE(random_adaptor_attach, + &pseudo_random_block); + + random_adaptor_register("panic", &pseudo_random_panic); + + return (0); + } + + return (EINVAL); +} + +RANDOM_ADAPTOR_MODULE(pseudo, pseudo_random_modevent, 1); diff --git a/sys/dev/random/random_adaptors.c b/sys/dev/random/random_adaptors.c index c187bdb7fcfe..43f55f22fe43 100644 --- a/sys/dev/random/random_adaptors.c +++ b/sys/dev/random/random_adaptors.c @@ -1,6 +1,7 @@ /*- * Copyright (c) 2013 Arthur Mesh * Copyright (c) 2013 David E. O'Brien + * Copyright (c) 2004 Mark R V Murray * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -30,16 +31,20 @@ __FBSDID("$FreeBSD$"); #include #include +#include #include +#include #include #include #include #include #include #include +#include -#include #include +#include +#include LIST_HEAD(adaptors_head, random_adaptors); static struct adaptors_head adaptors = LIST_HEAD_INITIALIZER(adaptors); @@ -48,6 +53,8 @@ static struct sx adaptors_lock; /* need a sleepable lock */ /* List for the dynamic sysctls */ static struct sysctl_ctx_list random_clist; +struct random_adaptor *random_adaptor; + MALLOC_DEFINE(M_RANDOM_ADAPTORS, "random_adaptors", "Random adaptors buffers"); int @@ -57,7 +64,8 @@ random_adaptor_register(const char *name, struct random_adaptor *rsp) KASSERT(name != NULL && rsp != NULL, ("invalid input to %s", __func__)); - rpp = malloc(sizeof(struct random_adaptors), M_RANDOM_ADAPTORS, M_WAITOK); + rpp = malloc(sizeof(struct random_adaptors), M_RANDOM_ADAPTORS, + M_WAITOK); rpp->name = name; rpp->rsp = rsp; @@ -87,6 +95,93 @@ random_adaptor_get(const char *name) return (rsp); } +/* + * In the past, the logic of the random_adaptor selection was inverted, such + * that hardware RNGs would be chosen unless disabled. This routine is here to + * preserve that functionality to avoid folks losing their hardware RNGs by + * upgrading to newer kernel. + */ +static void +random_adaptor_choose_legacy(struct random_adaptor **adaptor) +{ + struct random_adaptor *tmp; + int enable; + + /* Then go looking for hardware */ + enable = 1; + TUNABLE_INT_FETCH("hw.nehemiah_rng_enable", &enable); + if (enable && (tmp = random_adaptor_get("nehemiah"))) + *adaptor = tmp; + + enable = 1; + TUNABLE_INT_FETCH("hw.ivy_rng_enable", &enable); + if (enable && (tmp = random_adaptor_get("rdrand"))) + *adaptor = tmp; +} + +/* + * Walk a list of registered random(4) adaptors and pick the last non-selected + * one. + * + * If none are selected, use yarrow if available. + */ +void +random_adaptor_choose(struct random_adaptor **adaptor) +{ + char rngs[128], *token, *cp; + struct random_adaptors *rpp; + + KASSERT(adaptor != NULL, ("pre-conditions failed")); + + *adaptor = NULL; + + random_adaptor_choose_legacy(adaptor); + + if (*adaptor != NULL) + return; + + if (TUNABLE_STR_FETCH("rngs_want", rngs, sizeof(rngs))) { + cp = rngs; + + while ((token = strsep(&cp, ",")) != NULL) { + if ((*adaptor = random_adaptor_get(token)) != NULL) + break; + else if (bootverbose) + printf( + "%s random adaptor is not available, skipping\n", + token); + } + } + + if (*adaptor == NULL) { + /* + * Either no RNGs are prefered via rngs_want tunable, or + * no prefered RNGs are registered. + * Fallback to Yarrow. + */ + *adaptor = random_adaptor_get("yarrow"); + + if (*adaptor == NULL) { + /* + * Yarrow doesn't seem to be available. + * Fallback to the first thing that's on the list of + * available RNGs. + */ + sx_slock(&adaptors_lock); + + rpp = LIST_FIRST(&adaptors); + if (rpp != NULL) + *adaptor = rpp->rsp; + + sx_sunlock(&adaptors_lock); + } + + if (bootverbose && *adaptor) + printf("Falling back to <%s> random adaptor\n", + (*adaptor)->ident); + } +} + static void random_adaptors_deinit(void *unused) { @@ -99,18 +194,28 @@ static int random_sysctl_adaptors_handler(SYSCTL_HANDLER_ARGS) { struct random_adaptors *rpp; - int error; + int error, count; - error = 0; + count = error = 0; sx_slock(&adaptors_lock); - if (LIST_EMPTY(&adaptors)) - error = SYSCTL_OUT(req, "", strlen("")); + if (LIST_EMPTY(&adaptors)) { + error = SYSCTL_OUT(req, "", 0); + } else { - LIST_FOREACH(rpp, &adaptors, entries) { - if (0 != SYSCTL_OUT(req, rpp->name, strlen(rpp->name))) - break; + LIST_FOREACH(rpp, &adaptors, entries) { + + error = SYSCTL_OUT(req, ",", count++ ? 1 : 0); + + if (error) + break; + + error = SYSCTL_OUT(req, rpp->name, strlen(rpp->name)); + + if (error) + break; + } } sx_sunlock(&adaptors_lock); @@ -118,6 +223,37 @@ random_sysctl_adaptors_handler(SYSCTL_HANDLER_ARGS) return (error); } +static int +random_sysctl_active_adaptor_handler(SYSCTL_HANDLER_ARGS) +{ + struct random_adaptor *rsp; + struct random_adaptors *rpp; + const char *name; + int error; + + name = NULL; + rsp = random_adaptor; + + if (rsp != NULL) { + sx_slock(&adaptors_lock); + + LIST_FOREACH(rpp, &adaptors, entries) { + if (rpp->rsp == rsp) + name = rpp->name; + } + + sx_sunlock(&adaptors_lock); + } + + if (rsp == NULL || name == NULL) { + error = SYSCTL_OUT(req, "", 0); + } else { + error = SYSCTL_OUT(req, name, strlen(name)); + } + + return (error); +} + static void random_adaptors_init(void *unused) { @@ -127,6 +263,11 @@ random_adaptors_init(void *unused) NULL, 0, random_sysctl_adaptors_handler, "", "Random Number Generator adaptors"); + SYSCTL_PROC(_kern_random, OID_AUTO, active_adaptor, + CTLTYPE_STRING | CTLFLAG_RD | CTLFLAG_MPSAFE, + NULL, 0, random_sysctl_active_adaptor_handler, "", + "Active Random Number Generator Adaptor"); + sx_init(&adaptors_lock, "random_adaptors"); } diff --git a/sys/dev/random/random_adaptors.h b/sys/dev/random/random_adaptors.h index 50a7a0fea017..fa5f7c82883d 100644 --- a/sys/dev/random/random_adaptors.h +++ b/sys/dev/random/random_adaptors.h @@ -39,6 +39,9 @@ struct random_adaptors { struct random_adaptor *random_adaptor_get(const char *); int random_adaptor_register(const char *, struct random_adaptor *); +void random_adaptor_choose(struct random_adaptor **); + +extern struct random_adaptor *random_adaptor; /* * random_adaptor's should be registered prior to diff --git a/sys/dev/random/random_harvestq.c b/sys/dev/random/random_harvestq.c new file mode 100644 index 000000000000..fc87cde0068d --- /dev/null +++ b/sys/dev/random/random_harvestq.c @@ -0,0 +1,251 @@ +/*- + * Copyright (c) 2013 Arthur Mesh + * Copyright (c) 2000-2009 Mark R V Murray + * Copyright (c) 2004 Robert N. M. Watson + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer + * in this position and unchanged. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * $FreeBSD$ + */ + +#include +__FBSDID("$FreeBSD$"); + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "random_harvestq.h" + +#define RANDOM_FIFO_MAX 256 /* How many events to queue up */ + +MALLOC_DEFINE(M_ENTROPY, "entropy", "Entropy harvesting buffers"); + +/* + * The harvest mutex protects the consistency of the entropy fifos and + * empty fifo. + */ +struct mtx harvest_mtx; + +/* Lockable FIFO queue holding entropy buffers */ +struct entropyfifo { + int count; + STAILQ_HEAD(harvestlist, harvest) head; +}; + +/* Empty entropy buffers */ +static struct entropyfifo emptyfifo; + +#define EMPTYBUFFERS 1024 + +/* Harvested entropy */ +static struct entropyfifo harvestfifo[ENTROPYSOURCE]; + +/* <0 to end the kthread, 0 to let it run, 1 to flush the harvest queues */ +int random_kthread_control = 0; + +static struct proc *random_kthread_proc; + +static void +random_kthread(void *arg) +{ + STAILQ_HEAD(, harvest) local_queue; + struct harvest *event = NULL; + int local_count; + enum esource source; + event_proc_f func = arg; + + STAILQ_INIT(&local_queue); + local_count = 0; + + /* Process until told to stop */ + mtx_lock_spin(&harvest_mtx); + for (; random_kthread_control >= 0;) { + + /* Cycle through all the entropy sources */ + for (source = RANDOM_START; source < ENTROPYSOURCE; source++) { + /* + * Drain entropy source records into a thread-local + * queue for processing while not holding the mutex. + */ + STAILQ_CONCAT(&local_queue, &harvestfifo[source].head); + local_count += harvestfifo[source].count; + harvestfifo[source].count = 0; + } + + /* + * Deal with events, if any, dropping the mutex as we process + * each event. Then push the events back into the empty + * fifo. + */ + if (!STAILQ_EMPTY(&local_queue)) { + mtx_unlock_spin(&harvest_mtx); + STAILQ_FOREACH(event, &local_queue, next) + func(event); + mtx_lock_spin(&harvest_mtx); + STAILQ_CONCAT(&emptyfifo.head, &local_queue); + emptyfifo.count += local_count; + local_count = 0; + } + + KASSERT(local_count == 0, ("random_kthread: local_count %d", + local_count)); + + /* + * If a queue flush was commanded, it has now happened, + * and we can mark this by resetting the command. + */ + if (random_kthread_control == 1) + random_kthread_control = 0; + + /* Work done, so don't belabour the issue */ + msleep_spin_sbt(&random_kthread_control, &harvest_mtx, + "-", SBT_1S / 10, 0, C_PREL(1)); + + } + mtx_unlock_spin(&harvest_mtx); + + random_set_wakeup_exit(&random_kthread_control); + /* NOTREACHED */ +} + +void +random_harvestq_init(event_proc_f cb) +{ + int error, i; + struct harvest *np; + enum esource e; + + /* Initialise the harvest fifos */ + STAILQ_INIT(&emptyfifo.head); + emptyfifo.count = 0; + for (i = 0; i < EMPTYBUFFERS; i++) { + np = malloc(sizeof(struct harvest), M_ENTROPY, M_WAITOK); + STAILQ_INSERT_TAIL(&emptyfifo.head, np, next); + } + for (e = RANDOM_START; e < ENTROPYSOURCE; e++) { + STAILQ_INIT(&harvestfifo[e].head); + harvestfifo[e].count = 0; + } + + mtx_init(&harvest_mtx, "entropy harvest mutex", NULL, MTX_SPIN); + + + /* Start the hash/reseed thread */ + error = kproc_create(random_kthread, cb, + &random_kthread_proc, RFHIGHPID, 0, "rand_harvestq"); /* RANDOM_CSPRNG_NAME */ + + if (error != 0) + panic("Cannot create entropy maintenance thread."); +} + +void +random_harvestq_deinit(void) +{ + struct harvest *np; + enum esource e; + + /* Destroy the harvest fifos */ + while (!STAILQ_EMPTY(&emptyfifo.head)) { + np = STAILQ_FIRST(&emptyfifo.head); + STAILQ_REMOVE_HEAD(&emptyfifo.head, next); + free(np, M_ENTROPY); + } + for (e = RANDOM_START; e < ENTROPYSOURCE; e++) { + while (!STAILQ_EMPTY(&harvestfifo[e].head)) { + np = STAILQ_FIRST(&harvestfifo[e].head); + STAILQ_REMOVE_HEAD(&harvestfifo[e].head, next); + free(np, M_ENTROPY); + } + } + + mtx_destroy(&harvest_mtx); +} + +/* + * Entropy harvesting routine. This is supposed to be fast; do + * not do anything slow in here! + */ +void +random_harvestq_internal(u_int64_t somecounter, const void *entropy, + u_int count, u_int bits, u_int frac, enum esource origin) +{ + struct harvest *event; + + KASSERT(origin >= RANDOM_START && origin <= RANDOM_PURE, + ("random_harvest_internal: origin %d invalid\n", origin)); + + /* Lockless read to avoid lock operations if fifo is full. */ + if (harvestfifo[origin].count >= RANDOM_FIFO_MAX) + return; + + mtx_lock_spin(&harvest_mtx); + + /* + * Don't make the harvest queues too big - help to prevent low-grade + * entropy swamping + */ + if (harvestfifo[origin].count < RANDOM_FIFO_MAX) { + event = STAILQ_FIRST(&emptyfifo.head); + if (event != NULL) { + /* Add the harvested data to the fifo */ + STAILQ_REMOVE_HEAD(&emptyfifo.head, next); + harvestfifo[origin].count++; + event->somecounter = somecounter; + event->size = count; + event->bits = bits; + event->frac = frac; + event->source = origin; + + /* XXXX Come back and make this dynamic! */ + count = MIN(count, HARVESTSIZE); + memcpy(event->entropy, entropy, count); + +#if 0 + { + int i; + printf("Harvest:%16jX ", event->somecounter); + for (i = 0; i < event->size; i++) + printf("%02X", event->entropy[i]); + for (; i < 16; i++) + printf(" "); + printf(" %2d 0x%2X.%03X %02X\n", event->size, event->bits, event->frac, event->source); + } +#endif + + STAILQ_INSERT_TAIL(&harvestfifo[origin].head, + event, next); + } + } + mtx_unlock_spin(&harvest_mtx); +} + diff --git a/sys/dev/random/probe.c b/sys/dev/random/random_harvestq.h similarity index 61% rename from sys/dev/random/probe.c rename to sys/dev/random/random_harvestq.h index 7039b92606eb..9766c7728c44 100644 --- a/sys/dev/random/probe.c +++ b/sys/dev/random/random_harvestq.h @@ -1,5 +1,5 @@ /*- - * Copyright (c) 2004 Mark R V Murray + * Copyright (c) 2013 Arthur Mesh * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -23,40 +23,19 @@ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * + * $FreeBSD$ */ -#include -__FBSDID("$FreeBSD$"); +#ifndef __RANDOM_HARVEST_H__ +#define __RANDOM_HARVEST_H__ -#if defined(__amd64__) || defined(__i386__) -#include "opt_cpu.h" -#endif +typedef void (*event_proc_f)(struct harvest *event); -#include -#include -#include -#include +void random_harvestq_init(event_proc_f); +void random_harvestq_deinit(void); +void random_harvestq_internal(u_int64_t, const void *, + u_int, u_int, u_int, enum esource); -#include -#include +extern int random_kthread_control; -void -random_ident_hardware(struct random_adaptor **adaptor) -{ - struct random_adaptor *tmp; - int enable; - - /* Set default to software (yarrow) */ - *adaptor = random_adaptor_get("yarrow"); - - /* Then go looking for hardware */ - enable = 1; - TUNABLE_INT_FETCH("hw.nehemiah_rng_enable", &enable); - if (enable && (tmp = random_adaptor_get("nehemiah"))) - *adaptor = tmp; - - enable = 1; - TUNABLE_INT_FETCH("hw.ivy_rng_enable", &enable); - if (enable && (tmp = random_adaptor_get("rdrand"))) - *adaptor = tmp; -} +#endif /* __RANDOM_HARVEST_H__ */ diff --git a/sys/dev/random/randomdev.c b/sys/dev/random/randomdev.c index d18641fe3098..0f10e6c627f2 100644 --- a/sys/dev/random/randomdev.c +++ b/sys/dev/random/randomdev.c @@ -51,6 +51,7 @@ __FBSDID("$FreeBSD$"); #include #include +#include #include #define RANDOM_MINOR 0 @@ -71,20 +72,12 @@ static struct cdevsw random_cdevsw = { .d_name = "random", }; -static struct random_adaptor *random_adaptor; static eventhandler_tag attach_tag; static int random_inited; - /* For use with make_dev(9)/destroy_dev(9). */ static struct cdev *random_dev; -/* Used to fake out unused random calls in random_adaptor */ -void -random_null_func(void) -{ -} - /* ARGSUSED */ static int random_close(struct cdev *dev __unused, int flags, int fmt __unused, @@ -215,7 +208,7 @@ random_modevent(module_t mod __unused, int type, void *data __unused) switch (type) { case MOD_LOAD: - random_ident_hardware(&random_adaptor); + random_adaptor_choose(&random_adaptor); if (random_adaptor == NULL) { printf( diff --git a/sys/dev/random/randomdev_soft.c b/sys/dev/random/randomdev_soft.c index 7e537fe0a0da..61afb1b76a71 100644 --- a/sys/dev/random/randomdev_soft.c +++ b/sys/dev/random/randomdev_soft.c @@ -1,5 +1,5 @@ /*- - * Copyright (c) 2000-2009 Mark R V Murray + * Copyright (c) 2000-2013 Mark R V Murray * Copyright (c) 2004 Robert N. M. Watson * All rights reserved. * @@ -26,22 +26,24 @@ * */ +#if !defined(YARROW_RNG) && !defined(FORTUNA_RNG) +#define YARROW_RNG +#elif defined(YARROW_RNG) && defined(FORTUNA_RNG) +#error "Must define either YARROW_RNG or FORTUNA_RNG" +#endif + #include __FBSDID("$FreeBSD$"); #include #include -#include -#include #include #include -#include #include #include #include #include #include -#include #include #include #include @@ -54,55 +56,51 @@ __FBSDID("$FreeBSD$"); #include #include #include +#if defined(YARROW_RNG) +#include +#endif +#if defined(FORTUNA_RNG) +#include +#endif -#define RANDOM_FIFO_MAX 256 /* How many events to queue up */ +#include "random_harvestq.h" -static void random_kthread(void *); -static void -random_harvest_internal(u_int64_t, const void *, u_int, - u_int, u_int, enum esource); -static int random_yarrow_poll(int event,struct thread *td); -static int random_yarrow_block(int flag); -static void random_yarrow_flush_reseed(void); +static int randomdev_poll(int event, struct thread *td); +static int randomdev_block(int flag); +static void randomdev_flush_reseed(void); -struct random_adaptor random_yarrow = { +#if defined(YARROW_RNG) +static struct random_adaptor random_context = { .ident = "Software, Yarrow", - .init = random_yarrow_init, - .deinit = random_yarrow_deinit, - .block = random_yarrow_block, + .init = randomdev_init, + .deinit = randomdev_deinit, + .block = randomdev_block, .read = random_yarrow_read, - .write = random_yarrow_write, - .poll = random_yarrow_poll, - .reseed = random_yarrow_flush_reseed, + .write = randomdev_write, + .poll = randomdev_poll, + .reseed = randomdev_flush_reseed, .seeded = 1, }; +#define RANDOM_MODULE_NAME yarrow +#define RANDOM_CSPRNG_NAME "yarrow" +#endif -MALLOC_DEFINE(M_ENTROPY, "entropy", "Entropy harvesting buffers"); - -/* - * The harvest mutex protects the consistency of the entropy fifos and - * empty fifo. - */ -struct mtx harvest_mtx; - -/* Lockable FIFO queue holding entropy buffers */ -struct entropyfifo { - int count; - STAILQ_HEAD(harvestlist, harvest) head; +#if defined(FORTUNA_RNG) +static struct random_adaptor random_context = { + .ident = "Software, Fortuna", + .init = randomdev_init, + .deinit = randomdev_deinit, + .block = randomdev_block, + .read = random_fortuna_read, + .write = randomdev_write, + .poll = randomdev_poll, + .reseed = randomdev_flush_reseed, + .seeded = 1, }; +#define RANDOM_MODULE_NAME fortuna +#define RANDOM_CSPRNG_NAME "fortuna" -/* Empty entropy buffers */ -static struct entropyfifo emptyfifo; - -#define EMPTYBUFFERS 1024 - -/* Harvested entropy */ -static struct entropyfifo harvestfifo[ENTROPYSOURCE]; - -/* <0 to end the kthread, 0 to let it run, 1 to flush the harvest queues */ -static int random_kthread_control = 0; - -static struct proc *random_kthread_proc; +#endif /* List for the dynamic sysctls */ static struct sysctl_ctx_list random_clist; @@ -116,16 +114,17 @@ random_check_boolean(SYSCTL_HANDLER_ARGS) return sysctl_handle_int(oidp, oidp->oid_arg1, oidp->oid_arg2, req); } -/* ARGSUSED */ void -random_yarrow_init(void) +randomdev_init(void) { - int error, i; - struct harvest *np; struct sysctl_oid *random_sys_o, *random_sys_harvest_o; - enum esource e; +#if defined(YARROW_RNG) random_yarrow_init_alg(&random_clist); +#endif +#if defined(FORTUNA_RNG) + random_fortuna_init_alg(&random_clist); +#endif random_sys_o = SYSCTL_ADD_NODE(&random_clist, SYSCTL_STATIC_CHILDREN(_kern_random), @@ -135,7 +134,7 @@ random_yarrow_init(void) SYSCTL_ADD_PROC(&random_clist, SYSCTL_CHILDREN(random_sys_o), OID_AUTO, "seeded", CTLTYPE_INT | CTLFLAG_RW, - &random_yarrow.seeded, 1, random_check_boolean, "I", + &random_context.seeded, 1, random_check_boolean, "I", "Seeded State"); random_sys_harvest_o = SYSCTL_ADD_NODE(&random_clist, @@ -156,7 +155,7 @@ random_yarrow_init(void) SYSCTL_ADD_PROC(&random_clist, SYSCTL_CHILDREN(random_sys_harvest_o), OID_AUTO, "interrupt", CTLTYPE_INT | CTLFLAG_RW, - &harvest.interrupt, 1, random_check_boolean, "I", + &harvest.interrupt, 0, random_check_boolean, "I", "Harvest IRQ entropy"); SYSCTL_ADD_PROC(&random_clist, SYSCTL_CHILDREN(random_sys_harvest_o), @@ -164,40 +163,18 @@ random_yarrow_init(void) &harvest.swi, 0, random_check_boolean, "I", "Harvest SWI entropy"); - /* Initialise the harvest fifos */ - STAILQ_INIT(&emptyfifo.head); - emptyfifo.count = 0; - for (i = 0; i < EMPTYBUFFERS; i++) { - np = malloc(sizeof(struct harvest), M_ENTROPY, M_WAITOK); - STAILQ_INSERT_TAIL(&emptyfifo.head, np, next); - } - for (e = RANDOM_START; e < ENTROPYSOURCE; e++) { - STAILQ_INIT(&harvestfifo[e].head); - harvestfifo[e].count = 0; - } - - mtx_init(&harvest_mtx, "entropy harvest mutex", NULL, MTX_SPIN); - - /* Start the hash/reseed thread */ - error = kproc_create(random_kthread, NULL, - &random_kthread_proc, RFHIGHPID, 0, "yarrow"); - if (error != 0) - panic("Cannot create entropy maintenance thread."); + random_harvestq_init(random_process_event); /* Register the randomness harvesting routine */ - random_yarrow_init_harvester(random_harvest_internal, - random_yarrow_read); + randomdev_init_harvester(random_harvestq_internal, + random_context.read); } -/* ARGSUSED */ void -random_yarrow_deinit(void) +randomdev_deinit(void) { - struct harvest *np; - enum esource e; - /* Deregister the randomness harvesting routine */ - random_yarrow_deinit_harvester(); + randomdev_deinit_harvester(); /* * Command the hash/reseed thread to end and wait for it to finish @@ -205,140 +182,18 @@ random_yarrow_deinit(void) random_kthread_control = -1; tsleep((void *)&random_kthread_control, 0, "term", 0); - /* Destroy the harvest fifos */ - while (!STAILQ_EMPTY(&emptyfifo.head)) { - np = STAILQ_FIRST(&emptyfifo.head); - STAILQ_REMOVE_HEAD(&emptyfifo.head, next); - free(np, M_ENTROPY); - } - for (e = RANDOM_START; e < ENTROPYSOURCE; e++) { - while (!STAILQ_EMPTY(&harvestfifo[e].head)) { - np = STAILQ_FIRST(&harvestfifo[e].head); - STAILQ_REMOVE_HEAD(&harvestfifo[e].head, next); - free(np, M_ENTROPY); - } - } - +#if defined(YARROW_RNG) random_yarrow_deinit_alg(); - - mtx_destroy(&harvest_mtx); +#endif +#if defined(FORTUNA_RNG) + random_fortuna_deinit_alg(); +#endif sysctl_ctx_free(&random_clist); } -/* ARGSUSED */ -static void -random_kthread(void *arg __unused) -{ - STAILQ_HEAD(, harvest) local_queue; - struct harvest *event = NULL; - int local_count; - enum esource source; - - STAILQ_INIT(&local_queue); - local_count = 0; - - /* Process until told to stop */ - mtx_lock_spin(&harvest_mtx); - for (; random_kthread_control >= 0;) { - - /* Cycle through all the entropy sources */ - for (source = RANDOM_START; source < ENTROPYSOURCE; source++) { - /* - * Drain entropy source records into a thread-local - * queue for processing while not holding the mutex. - */ - STAILQ_CONCAT(&local_queue, &harvestfifo[source].head); - local_count += harvestfifo[source].count; - harvestfifo[source].count = 0; - } - - /* - * Deal with events, if any, dropping the mutex as we process - * each event. Then push the events back into the empty - * fifo. - */ - if (!STAILQ_EMPTY(&local_queue)) { - mtx_unlock_spin(&harvest_mtx); - STAILQ_FOREACH(event, &local_queue, next) - random_process_event(event); - mtx_lock_spin(&harvest_mtx); - STAILQ_CONCAT(&emptyfifo.head, &local_queue); - emptyfifo.count += local_count; - local_count = 0; - } - - KASSERT(local_count == 0, ("random_kthread: local_count %d", - local_count)); - - /* - * If a queue flush was commanded, it has now happened, - * and we can mark this by resetting the command. - */ - if (random_kthread_control == 1) - random_kthread_control = 0; - - /* Work done, so don't belabour the issue */ - msleep_spin_sbt(&random_kthread_control, &harvest_mtx, - "-", SBT_1S / 10, 0, C_PREL(1)); - - } - mtx_unlock_spin(&harvest_mtx); - - random_set_wakeup_exit(&random_kthread_control); - /* NOTREACHED */ -} - -/* Entropy harvesting routine. This is supposed to be fast; do - * not do anything slow in here! - */ -static void -random_harvest_internal(u_int64_t somecounter, const void *entropy, - u_int count, u_int bits, u_int frac, enum esource origin) -{ - struct harvest *event; - - KASSERT(origin == RANDOM_START || origin == RANDOM_WRITE || - origin == RANDOM_KEYBOARD || origin == RANDOM_MOUSE || - origin == RANDOM_NET || origin == RANDOM_INTERRUPT || - origin == RANDOM_PURE, - ("random_harvest_internal: origin %d invalid\n", origin)); - - /* Lockless read to avoid lock operations if fifo is full. */ - if (harvestfifo[origin].count >= RANDOM_FIFO_MAX) - return; - - mtx_lock_spin(&harvest_mtx); - - /* - * Don't make the harvest queues too big - help to prevent low-grade - * entropy swamping - */ - if (harvestfifo[origin].count < RANDOM_FIFO_MAX) { - event = STAILQ_FIRST(&emptyfifo.head); - if (event != NULL) { - /* Add the harvested data to the fifo */ - STAILQ_REMOVE_HEAD(&emptyfifo.head, next); - harvestfifo[origin].count++; - event->somecounter = somecounter; - event->size = count; - event->bits = bits; - event->frac = frac; - event->source = origin; - - /* XXXX Come back and make this dynamic! */ - count = MIN(count, HARVESTSIZE); - memcpy(event->entropy, entropy, count); - - STAILQ_INSERT_TAIL(&harvestfifo[origin].head, - event, next); - } - } - mtx_unlock_spin(&harvest_mtx); -} - void -random_yarrow_write(void *buf, int count) +randomdev_write(void *buf, int count) { int i; u_int chunk; @@ -351,52 +206,52 @@ random_yarrow_write(void *buf, int count) chunk = HARVESTSIZE; if (i + chunk >= count) chunk = (u_int)(count - i); - random_harvest_internal(get_cyclecount(), (char *)buf + i, + random_harvestq_internal(get_cyclecount(), (char *)buf + i, chunk, 0, 0, RANDOM_WRITE); } } void -random_yarrow_unblock(void) +randomdev_unblock(void) { - if (!random_yarrow.seeded) { - random_yarrow.seeded = 1; - selwakeuppri(&random_yarrow.rsel, PUSER); - wakeup(&random_yarrow); + if (!random_context.seeded) { + random_context.seeded = 1; + selwakeuppri(&random_context.rsel, PUSER); + wakeup(&random_context); } (void)atomic_cmpset_int(&arc4rand_iniseed_state, ARC4_ENTR_NONE, ARC4_ENTR_HAVE); } static int -random_yarrow_poll(int events, struct thread *td) +randomdev_poll(int events, struct thread *td) { int revents = 0; mtx_lock(&random_reseed_mtx); - if (random_yarrow.seeded) + if (random_context.seeded) revents = events & (POLLIN | POLLRDNORM); else - selrecord(td, &random_yarrow.rsel); + selrecord(td, &random_context.rsel); mtx_unlock(&random_reseed_mtx); return revents; } static int -random_yarrow_block(int flag) +randomdev_block(int flag) { int error = 0; mtx_lock(&random_reseed_mtx); /* Blocking logic */ - while (!random_yarrow.seeded && !error) { + while (!random_context.seeded && !error) { if (flag & O_NONBLOCK) error = EWOULDBLOCK; else { printf("Entropy device is blocking.\n"); - error = msleep(&random_yarrow, + error = msleep(&random_context, &random_reseed_mtx, PUSER | PCATCH, "block", 0); } @@ -408,23 +263,28 @@ random_yarrow_block(int flag) /* Helper routine to perform explicit reseeds */ static void -random_yarrow_flush_reseed(void) +randomdev_flush_reseed(void) { /* Command a entropy queue flush and wait for it to finish */ random_kthread_control = 1; while (random_kthread_control) pause("-", hz / 10); +#if defined(YARROW_RNG) random_yarrow_reseed(); +#endif +#if defined(FORTUNA_RNG) + random_fortuna_reseed(); +#endif } static int -yarrow_modevent(module_t mod, int type, void *unused) +randomdev_modevent(module_t mod, int type, void *unused) { switch (type) { case MOD_LOAD: - random_adaptor_register("yarrow", &random_yarrow); + random_adaptor_register(RANDOM_CSPRNG_NAME, &random_context); /* * For statically built kernels that contain both device * random and options PADLOCK_RNG/RDRAND_RNG/etc.., @@ -437,11 +297,11 @@ yarrow_modevent(module_t mod, int type, void *unused) * (by dependency). This event handler is there to delay * creation of /dev/{u,}random and attachment of this *_rng.ko. */ - EVENTHANDLER_INVOKE(random_adaptor_attach, &random_yarrow); + EVENTHANDLER_INVOKE(random_adaptor_attach, &random_context); return (0); } return (EINVAL); } -RANDOM_ADAPTOR_MODULE(yarrow, yarrow_modevent, 1); +RANDOM_ADAPTOR_MODULE(RANDOM_MODULE_NAME, randomdev_modevent, 1); diff --git a/sys/dev/random/randomdev_soft.h b/sys/dev/random/randomdev_soft.h index 2007694c50a2..c92a5a8e0725 100644 --- a/sys/dev/random/randomdev_soft.h +++ b/sys/dev/random/randomdev_soft.h @@ -1,5 +1,5 @@ /*- - * Copyright (c) 2000-2004 Mark R V Murray + * Copyright (c) 2000-2013 Mark R V Murray * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -35,9 +35,6 @@ * an enum in sys/random.h */ -/* Cryptographic block size in bits */ -#define BLOCKSIZE 256 - /* The ring size _MUST_ be a power of 2 */ #define HARVEST_RING_SIZE 1024 /* harvest ring buffer size */ #define HARVEST_RING_MASK (HARVEST_RING_SIZE - 1) @@ -51,34 +48,28 @@ MALLOC_DECLARE(M_ENTROPY); */ struct harvest { uintmax_t somecounter; /* fast counter for clock jitter */ - u_char entropy[HARVESTSIZE]; /* the harvested entropy */ + uint8_t entropy[HARVESTSIZE]; /* the harvested entropy */ u_int size, bits, frac; /* stats about the entropy */ enum esource source; /* stats about the entropy */ STAILQ_ENTRY(harvest) next; /* next item on the list */ }; -void random_yarrow_init(void); -void random_yarrow_deinit(void); +void randomdev_init(void); +void randomdev_deinit(void); -int random_yarrow_read(void *, int); -void random_yarrow_write(void *, int); +void randomdev_write(void *, int); -void random_yarrow_init_harvester(void (*)(u_int64_t, const void *, u_int, +void randomdev_init_harvester(void (*)(u_int64_t, const void *, u_int, u_int, u_int, enum esource), int (*)(void *, int)); -void random_yarrow_deinit_harvester(void); +void randomdev_deinit_harvester(void); void random_set_wakeup_exit(void *); void random_process_event(struct harvest *event); -void random_yarrow_reseed(void); -void random_yarrow_unblock(void); +void randomdev_unblock(void); -void random_yarrow_init_alg(struct sysctl_ctx_list *); -void random_yarrow_deinit_alg(void); - -extern struct random_adaptor random_yarrow; extern struct mtx random_reseed_mtx; -/* If this was c++, this would be a template */ +/* If this was C++, the macro below would be a template */ #define RANDOM_CHECK_UINT(name, min, max) \ static int \ random_check_uint_##name(SYSCTL_HANDLER_ARGS) \ diff --git a/sys/dev/random/yarrow.c b/sys/dev/random/yarrow.c index 09f079afa728..21913f924f66 100644 --- a/sys/dev/random/yarrow.c +++ b/sys/dev/random/yarrow.c @@ -1,5 +1,5 @@ /*- - * Copyright (c) 2000-2004 Mark R V Murray + * Copyright (c) 2000-2013 Mark R V Murray * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -45,21 +45,68 @@ __FBSDID("$FreeBSD$"); #include #include +#define TIMEBIN 16 /* max value for Pt/t */ + +#define FAST 0 +#define SLOW 1 + +/* This is the beastie that needs protecting. It contains all of the + * state that we are excited about. + * Exactly one is instantiated. + */ +static struct random_state { + union { + uint8_t byte[BLOCKSIZE]; + uint64_t qword[BLOCKSIZE/sizeof(uint64_t)]; + } counter; /* C */ + struct randomdev_key key; /* K */ + u_int gengateinterval; /* Pg */ + u_int bins; /* Pt/t */ + u_int outputblocks; /* count output blocks for gates */ + u_int slowoverthresh; /* slow pool overthreshhold reseed count */ + struct pool { + struct source { + u_int bits; /* estimated bits of entropy */ + u_int frac; /* fractional bits of entropy + (given as 1024/n) */ + } source[ENTROPYSOURCE]; + u_int thresh; /* pool reseed threshhold */ + struct randomdev_hash hash; /* accumulated entropy */ + } pool[2]; /* pool[0] is fast, pool[1] is slow */ + u_int which; /* toggle - sets the current insertion pool */ +} random_state; + RANDOM_CHECK_UINT(gengateinterval, 4, 64); RANDOM_CHECK_UINT(bins, 2, 16); -RANDOM_CHECK_UINT(fastthresh, BLOCKSIZE/4, BLOCKSIZE); -RANDOM_CHECK_UINT(slowthresh, BLOCKSIZE/4, BLOCKSIZE); +RANDOM_CHECK_UINT(fastthresh, (BLOCKSIZE*8)/4, (BLOCKSIZE*8)); /* Bit counts */ +RANDOM_CHECK_UINT(slowthresh, (BLOCKSIZE*8)/4, (BLOCKSIZE*8)); /* Bit counts */ RANDOM_CHECK_UINT(slowoverthresh, 1, 5); -/* Structure holding the entropy state */ -static struct random_state random_state; - static void generator_gate(void); static void reseed(u_int); /* The reseed thread mutex */ struct mtx random_reseed_mtx; +/* 128-bit C = 0 */ +/* Nothing to see here, folks, just an ugly mess. */ +static void +clear_counter(void) +{ + random_state.counter.qword[0] = 0UL; + random_state.counter.qword[1] = 0UL; +} + +/* 128-bit C = C + 1 */ +/* Nothing to see here, folks, just an ugly mess. */ +static void +increment_counter(void) +{ + random_state.counter.qword[0]++; + if (!random_state.counter.qword[0]) + random_state.counter.qword[1]++; +} + /* Process a single stochastic event off the harvest queue */ void random_process_event(struct harvest *event) @@ -71,13 +118,13 @@ random_process_event(struct harvest *event) /* Unpack the event into the appropriate source accumulator */ pl = random_state.which; source = &random_state.pool[pl].source[event->source]; - yarrow_hash_iterate(&random_state.pool[pl].hash, event->entropy, + randomdev_hash_iterate(&random_state.pool[pl].hash, event->entropy, sizeof(event->entropy)); - yarrow_hash_iterate(&random_state.pool[pl].hash, &event->somecounter, + randomdev_hash_iterate(&random_state.pool[pl].hash, &event->somecounter, sizeof(event->somecounter)); source->frac += event->frac; - source->bits += event->bits + source->frac/1024; - source->frac %= 1024; + source->bits += event->bits + (source->frac >> 12); /* bits + frac/0x1000 */ + source->frac &= 0xFFF; /* Keep the fractional bits */ /* Count the over-threshold sources in each pool */ for (pl = 0; pl < 2; pl++) { @@ -132,14 +179,14 @@ random_yarrow_init_alg(struct sysctl_ctx_list *clist) SYSCTL_ADD_PROC(clist, SYSCTL_CHILDREN(random_yarrow_o), OID_AUTO, "fastthresh", CTLTYPE_INT|CTLFLAG_RW, - &random_state.pool[0].thresh, (3*BLOCKSIZE)/4, + &random_state.pool[0].thresh, (3*(BLOCKSIZE*8))/4, random_check_uint_fastthresh, "I", "Fast reseed threshold"); SYSCTL_ADD_PROC(clist, SYSCTL_CHILDREN(random_yarrow_o), OID_AUTO, "slowthresh", CTLTYPE_INT|CTLFLAG_RW, - &random_state.pool[1].thresh, BLOCKSIZE, + &random_state.pool[1].thresh, (BLOCKSIZE*8), random_check_uint_slowthresh, "I", "Slow reseed threshold"); @@ -152,21 +199,20 @@ random_yarrow_init_alg(struct sysctl_ctx_list *clist) random_state.gengateinterval = 10; random_state.bins = 10; - random_state.pool[0].thresh = (3*BLOCKSIZE)/4; - random_state.pool[1].thresh = BLOCKSIZE; + random_state.pool[0].thresh = (3*(BLOCKSIZE*8))/4; + random_state.pool[1].thresh = (BLOCKSIZE*8); random_state.slowoverthresh = 2; random_state.which = FAST; /* Initialise the fast and slow entropy pools */ for (i = 0; i < 2; i++) - yarrow_hash_init(&random_state.pool[i].hash); + randomdev_hash_init(&random_state.pool[i].hash); /* Clear the counter */ - for (i = 0; i < 4; i++) - random_state.counter[i] = 0; + clear_counter(); /* Set up a lock for the reseed process */ - mtx_init(&random_reseed_mtx, "random reseed", NULL, MTX_DEF); + mtx_init(&random_reseed_mtx, "Yarrow reseed", NULL, MTX_DEF); } void @@ -181,10 +227,10 @@ reseed(u_int fastslow) /* Interrupt-context stack is a limited resource; make large * structures static. */ - static u_char v[TIMEBIN][KEYSIZE]; /* v[i] */ - static struct yarrowhash context; - u_char hash[KEYSIZE]; /* h' */ - u_char temp[KEYSIZE]; + static uint8_t v[TIMEBIN][KEYSIZE]; /* v[i] */ + static struct randomdev_hash context; + uint8_t hash[KEYSIZE]; /* h' */ + uint8_t temp[KEYSIZE]; u_int i; enum esource j; @@ -193,15 +239,15 @@ reseed(u_int fastslow) /* 1. Hash the accumulated entropy into v[0] */ - yarrow_hash_init(&context); + randomdev_hash_init(&context); /* Feed the slow pool hash in if slow */ if (fastslow == SLOW) - yarrow_hash_iterate(&context, + randomdev_hash_iterate(&context, &random_state.pool[SLOW].hash, - sizeof(struct yarrowhash)); - yarrow_hash_iterate(&context, - &random_state.pool[FAST].hash, sizeof(struct yarrowhash)); - yarrow_hash_finish(&context, v[0]); + sizeof(struct randomdev_hash)); + randomdev_hash_iterate(&context, + &random_state.pool[FAST].hash, sizeof(struct randomdev_hash)); + randomdev_hash_finish(&context, v[0]); /* 2. Compute hash values for all v. _Supposed_ to be computationally * intensive. @@ -210,34 +256,33 @@ reseed(u_int fastslow) if (random_state.bins > TIMEBIN) random_state.bins = TIMEBIN; for (i = 1; i < random_state.bins; i++) { - yarrow_hash_init(&context); + randomdev_hash_init(&context); /* v[i] #= h(v[i - 1]) */ - yarrow_hash_iterate(&context, v[i - 1], KEYSIZE); + randomdev_hash_iterate(&context, v[i - 1], KEYSIZE); /* v[i] #= h(v[0]) */ - yarrow_hash_iterate(&context, v[0], KEYSIZE); + randomdev_hash_iterate(&context, v[0], KEYSIZE); /* v[i] #= h(i) */ - yarrow_hash_iterate(&context, &i, sizeof(u_int)); + randomdev_hash_iterate(&context, &i, sizeof(u_int)); /* Return the hashval */ - yarrow_hash_finish(&context, v[i]); + randomdev_hash_finish(&context, v[i]); } /* 3. Compute a new key; h' is the identity function here; * it is not being ignored! */ - yarrow_hash_init(&context); - yarrow_hash_iterate(&context, &random_state.key, KEYSIZE); + randomdev_hash_init(&context); + randomdev_hash_iterate(&context, &random_state.key, KEYSIZE); for (i = 1; i < random_state.bins; i++) - yarrow_hash_iterate(&context, &v[i], KEYSIZE); - yarrow_hash_finish(&context, temp); - yarrow_encrypt_init(&random_state.key, temp); + randomdev_hash_iterate(&context, &v[i], KEYSIZE); + randomdev_hash_finish(&context, temp); + randomdev_encrypt_init(&random_state.key, temp); /* 4. Recompute the counter */ - for (i = 0; i < 4; i++) - random_state.counter[i] = 0; - yarrow_encrypt(&random_state.key, random_state.counter, temp); - memcpy(random_state.counter, temp, sizeof(random_state.counter)); + clear_counter(); + randomdev_encrypt(&random_state.key, random_state.counter.byte, temp, BLOCKSIZE); + memcpy(random_state.counter.byte, temp, BLOCKSIZE); /* 5. Reset entropy estimate accumulators to zero */ @@ -258,7 +303,7 @@ reseed(u_int fastslow) /* XXX Not done here yet */ /* Unblock the device if it was blocked due to being unseeded */ - random_yarrow_unblock(); + randomdev_unblock(); /* Release the reseed mutex */ mtx_unlock(&random_reseed_mtx); @@ -270,7 +315,7 @@ random_yarrow_read(void *buf, int count) { static int cur = 0; static int gate = 1; - static u_char genval[KEYSIZE]; + static uint8_t genval[KEYSIZE]; size_t tomove; int i; int retval; @@ -283,16 +328,14 @@ random_yarrow_read(void *buf, int count) random_state.outputblocks = 0; gate = 0; } - if (count > 0 && (size_t)count >= sizeof(random_state.counter)) { + if (count > 0 && (size_t)count >= BLOCKSIZE) { retval = 0; - for (i = 0; i < count; i += (int)sizeof(random_state.counter)) { - random_state.counter[0]++; - yarrow_encrypt(&random_state.key, random_state.counter, - genval); - tomove = min(count - i, sizeof(random_state.counter)); + for (i = 0; i < count; i += BLOCKSIZE) { + increment_counter(); + randomdev_encrypt(&random_state.key, random_state.counter.byte, genval, BLOCKSIZE); + tomove = MIN(count - i, BLOCKSIZE); memcpy((char *)buf + i, genval, tomove); - if (++random_state.outputblocks >= - random_state.gengateinterval) { + if (++random_state.outputblocks >= random_state.gengateinterval) { generator_gate(); random_state.outputblocks = 0; } @@ -302,13 +345,11 @@ random_yarrow_read(void *buf, int count) } else { if (!cur) { - random_state.counter[0]++; - yarrow_encrypt(&random_state.key, random_state.counter, - genval); + increment_counter(); + randomdev_encrypt(&random_state.key, random_state.counter.byte, genval, BLOCKSIZE); memcpy(buf, genval, (size_t)count); - cur = (int)sizeof(random_state.counter) - count; - if (++random_state.outputblocks >= - random_state.gengateinterval) { + cur = BLOCKSIZE - count; + if (++random_state.outputblocks >= random_state.gengateinterval) { generator_gate(); random_state.outputblocks = 0; } @@ -316,9 +357,7 @@ random_yarrow_read(void *buf, int count) } else { retval = MIN(cur, count); - memcpy(buf, - &genval[(int)sizeof(random_state.counter) - cur], - (size_t)retval); + memcpy(buf, &genval[BLOCKSIZE - cur], (size_t)retval); cur -= retval; } } @@ -330,17 +369,15 @@ static void generator_gate(void) { u_int i; - u_char temp[KEYSIZE]; + uint8_t temp[KEYSIZE]; - for (i = 0; i < KEYSIZE; i += sizeof(random_state.counter)) { - random_state.counter[0]++; - yarrow_encrypt(&random_state.key, random_state.counter, - &(temp[i])); + for (i = 0; i < KEYSIZE; i += BLOCKSIZE) { + increment_counter(); + randomdev_encrypt(&random_state.key, random_state.counter.byte, temp + i, BLOCKSIZE); } - yarrow_encrypt_init(&random_state.key, temp); + randomdev_encrypt_init(&random_state.key, temp); memset((void *)temp, 0, KEYSIZE); - } /* Helper routine to perform explicit reseeds */ diff --git a/sys/dev/random/yarrow.h b/sys/dev/random/yarrow.h index 558354d27f73..0bde5b582d32 100644 --- a/sys/dev/random/yarrow.h +++ b/sys/dev/random/yarrow.h @@ -1,5 +1,5 @@ /*- - * Copyright (c) 2000-2004 Mark R V Murray + * Copyright (c) 2000-2013 Mark R V Murray * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -26,34 +26,7 @@ * $FreeBSD$ */ -/* This contains Yarrow-specific declarations. - * See http://www.counterpane.com/yarrow.html - */ - -#define TIMEBIN 16 /* max value for Pt/t */ - -#define FAST 0 -#define SLOW 1 - -/* This is the beastie that needs protecting. It contains all of the - * state that we are excited about. - * Exactly one will be instantiated. - */ -struct random_state { - u_int64_t counter[4]; /* C - 256 bits */ - struct yarrowkey key; /* K */ - u_int gengateinterval; /* Pg */ - u_int bins; /* Pt/t */ - u_int outputblocks; /* count output blocks for gates */ - u_int slowoverthresh; /* slow pool overthreshhold reseed count */ - struct pool { - struct source { - u_int bits; /* estimated bits of entropy */ - u_int frac; /* fractional bits of entropy - (given as 1024/n) */ - } source[ENTROPYSOURCE]; - u_int thresh; /* pool reseed threshhold */ - struct yarrowhash hash; /* accumulated entropy */ - } pool[2]; /* pool[0] is fast, pool[1] is slow */ - u_int which; /* toggle - sets the current insertion pool */ -}; +void random_yarrow_init_alg(struct sysctl_ctx_list *); +void random_yarrow_deinit_alg(void); +int random_yarrow_read(void *, int); +void random_yarrow_reseed(void); diff --git a/sys/dev/rndtest/rndtest.c b/sys/dev/rndtest/rndtest.c index 13ecdd6b0105..3c42972c36f7 100644 --- a/sys/dev/rndtest/rndtest.c +++ b/sys/dev/rndtest/rndtest.c @@ -152,7 +152,7 @@ rndtest_harvest(struct rndtest_state *rsp, void *buf, u_int len) for (len /= sizeof (u_int32_t); len; len--) add_true_randomness(*p++); #else - random_harvest(buf, len, len*NBBY, 0, RANDOM_PURE); + random_harvest(buf, len, len*NBBY/2, 0, RANDOM_PURE); #endif } } diff --git a/sys/dev/safe/safe.c b/sys/dev/safe/safe.c index 6bfcf26032f4..721b9f4b2b60 100644 --- a/sys/dev/safe/safe.c +++ b/sys/dev/safe/safe.c @@ -211,7 +211,7 @@ safe_partname(struct safe_softc *sc) static void default_harvest(struct rndtest_state *rsp, void *buf, u_int count) { - random_harvest(buf, count, count*NBBY, 0, RANDOM_PURE); + random_harvest(buf, count, count*NBBY/2, 0, RANDOM_PURE); } #endif /* SAFE_NO_RNG */ diff --git a/sys/dev/tdfx/tdfx_linux.c b/sys/dev/tdfx/tdfx_linux.c index 0b769f01a241..fa39ab1903b9 100644 --- a/sys/dev/tdfx/tdfx_linux.c +++ b/sys/dev/tdfx/tdfx_linux.c @@ -45,6 +45,7 @@ LINUX_IOCTL_SET(tdfx, LINUX_IOCTL_TDFX_MIN, LINUX_IOCTL_TDFX_MAX); static int linux_ioctl_tdfx(struct thread *td, struct linux_ioctl_args* args) { + cap_rights_t rights; int error = 0; u_long cmd = args->cmd & 0xffff; @@ -54,7 +55,8 @@ linux_ioctl_tdfx(struct thread *td, struct linux_ioctl_args* args) struct file *fp; - if ((error = fget(td, args->fd, CAP_IOCTL, &fp)) != 0) + error = fget(td, args->fd, cap_rights_init(&rights, CAP_IOCTL), &fp); + if (error != 0) return (error); /* We simply copy the data and send it right to ioctl */ copyin((caddr_t)args->arg, &d_pio, sizeof(d_pio)); diff --git a/sys/dev/ubsec/ubsec.c b/sys/dev/ubsec/ubsec.c index 2c0fad4fa93f..0e1b7cb5df67 100644 --- a/sys/dev/ubsec/ubsec.c +++ b/sys/dev/ubsec/ubsec.c @@ -259,7 +259,7 @@ ubsec_partname(struct ubsec_softc *sc) static void default_harvest(struct rndtest_state *rsp, void *buf, u_int count) { - random_harvest(buf, count, count*NBBY, 0, RANDOM_PURE); + random_harvest(buf, count, count*NBBY/2, 0, RANDOM_PURE); } static int diff --git a/sys/dev/usb/controller/xhci.c b/sys/dev/usb/controller/xhci.c index 6c9a6101f64c..ec8b75a4d40d 100644 --- a/sys/dev/usb/controller/xhci.c +++ b/sys/dev/usb/controller/xhci.c @@ -87,12 +87,18 @@ ((struct xhci_softc *)(((uint8_t *)(bus)) - \ ((uint8_t *)&(((struct xhci_softc *)0)->sc_bus)))) +static SYSCTL_NODE(_hw_usb, OID_AUTO, xhci, CTLFLAG_RW, 0, "USB XHCI"); + +static int xhcistreams; +SYSCTL_INT(_hw_usb_xhci, OID_AUTO, streams, CTLFLAG_RW | CTLFLAG_TUN, + &xhcistreams, 0, "Set to enable streams mode support"); +TUNABLE_INT("hw.usb.xhci.streams", &xhcistreams); + #ifdef USB_DEBUG static int xhcidebug; static int xhciroute; static int xhcipolling; -static SYSCTL_NODE(_hw_usb, OID_AUTO, xhci, CTLFLAG_RW, 0, "USB XHCI"); SYSCTL_INT(_hw_usb_xhci, OID_AUTO, debug, CTLFLAG_RW | CTLFLAG_TUN, &xhcidebug, 0, "Debug level"); TUNABLE_INT("hw.usb.xhci.debug", &xhcidebug); @@ -1474,7 +1480,6 @@ void xhci_interrupt(struct xhci_softc *sc) { uint32_t status; - uint32_t iman; USB_BUS_LOCK(&sc->sc_bus); @@ -1489,15 +1494,6 @@ xhci_interrupt(struct xhci_softc *sc) DPRINTFN(16, "real interrupt (status=0x%08x)\n", status); if (status & XHCI_STS_EINT) { - - /* acknowledge pending event */ - iman = XREAD4(sc, runt, XHCI_IMAN(0)); - - /* reset interrupt */ - XWRITE4(sc, runt, XHCI_IMAN(0), iman); - - DPRINTFN(16, "real interrupt (iman=0x%08x)\n", iman); - /* check for event(s) */ xhci_interrupt_poll(sc); } @@ -4127,7 +4123,8 @@ xhci_set_endpoint_mode(struct usb_device *udev, struct usb_endpoint *ep, case USB_EP_MODE_DEFAULT: return (0); case USB_EP_MODE_STREAMS: - if ((ep->edesc->bmAttributes & UE_XFERTYPE) != UE_BULK || + if (xhcistreams == 0 || + (ep->edesc->bmAttributes & UE_XFERTYPE) != UE_BULK || udev->speed != USB_SPEED_SUPER) return (USB_ERR_INVAL); return (0); diff --git a/sys/dev/usb/usbdevs b/sys/dev/usb/usbdevs index 307453068d37..e6a32aecf9d8 100644 --- a/sys/dev/usb/usbdevs +++ b/sys/dev/usb/usbdevs @@ -1547,6 +1547,7 @@ product DLINK DWLG122 0x3c00 DWL-G122 b1 Wireless Adapter product DLINK DUBE100B1 0x3c05 DUB-E100 rev B1 product DLINK RT2870 0x3c09 RT2870 product DLINK RT3072 0x3c0a RT3072 +product DLINK DWA127 0x3c1b DWA-127 Wireless Adapter product DLINK DSB650C 0x4000 10Mbps Ethernet product DLINK DSB650TX1 0x4001 10/100 Ethernet product DLINK DSB650TX 0x4002 10/100 Ethernet diff --git a/sys/dev/usb/wlan/if_run.c b/sys/dev/usb/wlan/if_run.c index aed07a205e47..5b4587fd6c17 100644 --- a/sys/dev/usb/wlan/if_run.c +++ b/sys/dev/usb/wlan/if_run.c @@ -171,6 +171,7 @@ static const STRUCT_USB_HOST_ID run_devs[] = { RUN_DEV(CYBERTAN, RT2870), RUN_DEV(DLINK, RT2870), RUN_DEV(DLINK, RT3072), + RUN_DEV(DLINK, DWA127), RUN_DEV(DLINK2, DWA130), RUN_DEV(DLINK2, RT2870_1), RUN_DEV(DLINK2, RT2870_2), diff --git a/sys/dev/vkbd/vkbd.c b/sys/dev/vkbd/vkbd.c index 81418f2d4334..fc5452a98279 100644 --- a/sys/dev/vkbd/vkbd.c +++ b/sys/dev/vkbd/vkbd.c @@ -186,14 +186,10 @@ vkbd_dev_clone(void *arg, struct ucred *cred, char *name, int namelen, return; /* don't recognize the name */ /* find any existing device, or allocate new unit number */ - if (clone_create(&vkbd_dev_clones, &vkbd_dev_cdevsw, &unit, dev, 0)) { - *dev = make_dev(&vkbd_dev_cdevsw, unit, - UID_ROOT, GID_WHEEL, 0600, DEVICE_NAME "%d", unit); - if (*dev != NULL) { - dev_ref(*dev); - (*dev)->si_flags |= SI_CHEAPCLONE; - } - } + if (clone_create(&vkbd_dev_clones, &vkbd_dev_cdevsw, &unit, dev, 0)) + *dev = make_dev_credf(MAKEDEV_REF, &vkbd_dev_cdevsw, unit, + cred, UID_ROOT, GID_WHEEL, 0600, DEVICE_NAME "%d", + unit); } /* Open device */ diff --git a/sys/dev/vmware/vmxnet3/if_vmxvar.h b/sys/dev/vmware/vmxnet3/if_vmxvar.h index bbe5a4a547a5..2e7d02d316b2 100644 --- a/sys/dev/vmware/vmxnet3/if_vmxvar.h +++ b/sys/dev/vmware/vmxnet3/if_vmxvar.h @@ -228,7 +228,7 @@ struct vmxnet3_softc { struct ifmedia vmx_media; eventhandler_tag vmx_vlan_attach; eventhandler_tag vmx_vlan_detach; - uint8_t vmx_vlan_filter[4096/32]; + uint32_t vmx_vlan_filter[4096/32]; uint8_t vmx_lladdr[ETHER_ADDR_LEN]; }; diff --git a/sys/dev/xen/blkback/blkback.c b/sys/dev/xen/blkback/blkback.c index 3ea3c9789afc..21fbb41f77fa 100644 --- a/sys/dev/xen/blkback/blkback.c +++ b/sys/dev/xen/blkback/blkback.c @@ -230,7 +230,7 @@ struct xbb_xen_reqlist { int num_children; /** - * Number of I/O requests dispatched to the backend. + * Number of I/O requests still pending on the backend. */ int pendcnt; @@ -326,13 +326,6 @@ struct xbb_xen_req { */ int nr_512b_sectors; - /** - * The number of struct bio requests still outstanding for this - * request on the backend device. This field is only used for - * device (rather than file) backed I/O. - */ - int pendcnt; - /** * BLKIF_OP code for this request. */ @@ -1240,6 +1233,7 @@ xbb_get_resources(struct xbb_softc *xbb, struct xbb_xen_reqlist **reqlist, nreq->reqlist = *reqlist; nreq->req_ring_idx = ring_idx; nreq->id = ring_req->id; + nreq->operation = ring_req->operation; if (xbb->abi != BLKIF_PROTOCOL_NATIVE) { bcopy(ring_req, &nreq->ring_req_storage, sizeof(*ring_req)); @@ -2062,7 +2056,6 @@ xbb_dispatch_dev(struct xbb_softc *xbb, struct xbb_xen_reqlist *reqlist, { struct xbb_dev_data *dev_data; struct bio *bios[XBB_MAX_SEGMENTS_PER_REQLIST]; - struct xbb_xen_req *nreq; off_t bio_offset; struct bio *bio; struct xbb_sg *xbb_sg; @@ -2080,7 +2073,6 @@ xbb_dispatch_dev(struct xbb_softc *xbb, struct xbb_xen_reqlist *reqlist, bio_idx = 0; if (operation == BIO_FLUSH) { - nreq = STAILQ_FIRST(&reqlist->contig_req_list); bio = g_new_bio(); if (__predict_false(bio == NULL)) { DPRINTF("Unable to allocate bio for BIO_FLUSH\n"); @@ -2094,10 +2086,10 @@ xbb_dispatch_dev(struct xbb_softc *xbb, struct xbb_xen_reqlist *reqlist, bio->bio_offset = 0; bio->bio_data = 0; bio->bio_done = xbb_bio_done; - bio->bio_caller1 = nreq; + bio->bio_caller1 = reqlist; bio->bio_pblkno = 0; - nreq->pendcnt = 1; + reqlist->pendcnt = 1; SDT_PROBE1(xbb, kernel, xbb_dispatch_dev, flush, device_get_unit(xbb->dev)); diff --git a/sys/fs/ext2fs/ext2_htree.c b/sys/fs/ext2fs/ext2_htree.c index 0b5d9205b61a..ff1e1a5ef61e 100644 --- a/sys/fs/ext2fs/ext2_htree.c +++ b/sys/fs/ext2fs/ext2_htree.c @@ -89,10 +89,12 @@ static int ext2_htree_writebuf(struct ext2fs_htree_lookup_info *info); int ext2_htree_has_idx(struct inode *ip) { +#ifdef EXT2FS_HTREE if (EXT2_HAS_COMPAT_FEATURE(ip->i_e2fs, EXT2F_COMPAT_DIRHASHINDEX) && ip->i_flags & EXT4_INDEX) return (1); else +#endif return (0); } diff --git a/sys/fs/ext2fs/ext2_lookup.c b/sys/fs/ext2fs/ext2_lookup.c index 990ed330217f..d6075542fa8d 100644 --- a/sys/fs/ext2fs/ext2_lookup.c +++ b/sys/fs/ext2fs/ext2_lookup.c @@ -884,6 +884,7 @@ ext2_direnter(struct inode *ip, struct vnode *dvp, struct componentname *cnp) bcopy(cnp->cn_nameptr, newdir.e2d_name, (unsigned)cnp->cn_namelen + 1); newentrysize = EXT2_DIR_REC_LEN(newdir.e2d_namlen); +#ifdef EXT2FS_HTREE if (ext2_htree_has_idx(dp)) { error = ext2_htree_add_entry(dvp, &newdir, cnp); if (error) { @@ -904,6 +905,7 @@ ext2_direnter(struct inode *ip, struct vnode *dvp, struct componentname *cnp) return ext2_htree_create_index(dvp, cnp, &newdir); } } +#endif /* EXT2FS_HTREE */ if (dp->i_count == 0) { /* diff --git a/sys/fs/fdescfs/fdesc_vnops.c b/sys/fs/fdescfs/fdesc_vnops.c index f18c0fc13f95..b976504353c9 100644 --- a/sys/fs/fdescfs/fdesc_vnops.c +++ b/sys/fs/fdescfs/fdesc_vnops.c @@ -309,7 +309,7 @@ fdesc_lookup(ap) /* * No rights to check since 'fp' isn't actually used. */ - if ((error = fget(td, fd, 0, &fp)) != 0) + if ((error = fget(td, fd, NULL, &fp)) != 0) goto bad; /* Check if we're looking up ourselves. */ @@ -445,6 +445,7 @@ fdesc_setattr(ap) struct mount *mp; struct file *fp; struct thread *td = curthread; + cap_rights_t rights; unsigned fd; int error; @@ -459,7 +460,8 @@ fdesc_setattr(ap) /* * Allow setattr where there is an underlying vnode. */ - error = getvnode(td->td_proc->p_fd, fd, CAP_EXTATTR_SET, &fp); + error = getvnode(td->td_proc->p_fd, fd, + cap_rights_init(&rights, CAP_EXTATTR_SET), &fp); if (error) { /* * getvnode() returns EINVAL if the file descriptor is not diff --git a/sys/fs/fuse/fuse_vfsops.c b/sys/fs/fuse/fuse_vfsops.c index 639550a88c8d..0b4f19b9ea42 100644 --- a/sys/fs/fuse/fuse_vfsops.c +++ b/sys/fs/fuse/fuse_vfsops.c @@ -220,6 +220,7 @@ fuse_vfsop_mount(struct mount *mp) struct file *fp, *fptmp; char *fspec, *subtype; struct vfsoptlist *opts; + cap_rights_t rights; subtype = NULL; max_read_set = 0; @@ -289,7 +290,7 @@ fuse_vfsop_mount(struct mount *mp) FS_DEBUG2G("mntopts 0x%jx\n", (uintmax_t)mntopts); - err = fget(td, fd, CAP_READ, &fp); + err = fget(td, fd, cap_rights_init(&rights, CAP_READ), &fp); if (err != 0) { FS_DEBUG("invalid or not opened device: data=%p\n", data); goto out; diff --git a/sys/fs/nfsclient/nfs_clkrpc.c b/sys/fs/nfsclient/nfs_clkrpc.c index 8b0b2346759e..502fec5f24ae 100644 --- a/sys/fs/nfsclient/nfs_clkrpc.c +++ b/sys/fs/nfsclient/nfs_clkrpc.c @@ -278,17 +278,15 @@ nfsrvd_cbinit(int terminating) while (nfs_numnfscbd > 0) msleep(&nfs_numnfscbd, NFSDLOCKMUTEXPTR, PZERO, "nfscbdt", 0); - NFSD_UNLOCK(); - svcpool_destroy(nfscbd_pool); - nfscbd_pool = NULL; - } else - NFSD_UNLOCK(); + } - nfscbd_pool = svcpool_create("nfscbd", NULL); - nfscbd_pool->sp_rcache = NULL; - nfscbd_pool->sp_assign = NULL; - nfscbd_pool->sp_done = NULL; - - NFSD_LOCK(); + if (nfscbd_pool == NULL) { + NFSD_UNLOCK(); + nfscbd_pool = svcpool_create("nfscbd", NULL); + nfscbd_pool->sp_rcache = NULL; + nfscbd_pool->sp_assign = NULL; + nfscbd_pool->sp_done = NULL; + NFSD_LOCK(); + } } diff --git a/sys/fs/nfsclient/nfs_clport.c b/sys/fs/nfsclient/nfs_clport.c index d7b082b6ae89..b198d5976982 100644 --- a/sys/fs/nfsclient/nfs_clport.c +++ b/sys/fs/nfsclient/nfs_clport.c @@ -1219,10 +1219,11 @@ nfssvc_nfscl(struct thread *td, struct nfssvc_args *uap) struct file *fp; struct nfscbd_args nfscbdarg; struct nfsd_nfscbd_args nfscbdarg2; - int error; struct nameidata nd; struct nfscl_dumpmntopts dumpmntopts; + cap_rights_t rights; char *buf; + int error; if (uap->flag & NFSSVC_CBADDSOCK) { error = copyin(uap->argp, (caddr_t)&nfscbdarg, sizeof(nfscbdarg)); @@ -1233,10 +1234,10 @@ nfssvc_nfscl(struct thread *td, struct nfssvc_args *uap) * pretend that we need them all. It is better to be too * careful than too reckless. */ - if ((error = fget(td, nfscbdarg.sock, CAP_SOCK_CLIENT, &fp)) - != 0) { + error = fget(td, nfscbdarg.sock, + cap_rights_init(&rights, CAP_SOCK_CLIENT), &fp); + if (error) return (error); - } if (fp->f_type != DTYPE_SOCKET) { fdrop(fp, td); return (EPERM); diff --git a/sys/fs/nfsserver/nfs_nfsdport.c b/sys/fs/nfsserver/nfs_nfsdport.c index a6a01692edf0..2f9d40a8f2e3 100644 --- a/sys/fs/nfsserver/nfs_nfsdport.c +++ b/sys/fs/nfsserver/nfs_nfsdport.c @@ -3035,6 +3035,7 @@ nfssvc_nfsd(struct thread *td, struct nfssvc_args *uap) struct file *fp; struct nfsd_addsock_args sockarg; struct nfsd_nfsd_args nfsdarg; + cap_rights_t rights; int error; if (uap->flag & NFSSVC_NFSDADDSOCK) { @@ -3046,7 +3047,9 @@ nfssvc_nfsd(struct thread *td, struct nfssvc_args *uap) * pretend that we need them all. It is better to be too * careful than too reckless. */ - if ((error = fget(td, sockarg.sock, CAP_SOCK_SERVER, &fp)) != 0) + error = fget(td, sockarg.sock, + cap_rights_init(&rights, CAP_SOCK_SERVER), &fp); + if (error != 0) goto out; if (fp->f_type != DTYPE_SOCKET) { fdrop(fp, td); diff --git a/sys/fs/nullfs/null_vnops.c b/sys/fs/nullfs/null_vnops.c index 70402e35f1db..cf3762eda39d 100644 --- a/sys/fs/nullfs/null_vnops.c +++ b/sys/fs/nullfs/null_vnops.c @@ -858,6 +858,15 @@ null_vptocnp(struct vop_vptocnp_args *ap) return (error); } +static int +null_link(struct vop_link_args *ap) +{ + + if (ap->a_tdvp->v_mount != ap->a_vp->v_mount) + return (EXDEV); + return (null_bypass((struct vop_generic_args *)ap)); +} + /* * Global vfs data structures */ @@ -871,6 +880,7 @@ struct vop_vector null_vnodeops = { .vop_getwritemount = null_getwritemount, .vop_inactive = null_inactive, .vop_islocked = vop_stdislocked, + .vop_link = null_link, .vop_lock1 = null_lock, .vop_lookup = null_lookup, .vop_open = null_open, diff --git a/sys/geom/part/g_part_ldm.c b/sys/geom/part/g_part_ldm.c index 81abc84365a8..40c2eb877b07 100644 --- a/sys/geom/part/g_part_ldm.c +++ b/sys/geom/part/g_part_ldm.c @@ -339,8 +339,6 @@ static int g_part_ldm_read(struct g_part_table *, struct g_consumer *); static const char *g_part_ldm_type(struct g_part_table *, struct g_part_entry *, char *, size_t); static int g_part_ldm_write(struct g_part_table *, struct g_consumer *); -static int g_part_ldm_resize(struct g_part_table *, struct g_part_entry *, - struct g_part_parms *); static kobj_method_t g_part_ldm_methods[] = { KOBJMETHOD(g_part_add, g_part_ldm_add), @@ -350,7 +348,6 @@ static kobj_method_t g_part_ldm_methods[] = { KOBJMETHOD(g_part_dumpconf, g_part_ldm_dumpconf), KOBJMETHOD(g_part_dumpto, g_part_ldm_dumpto), KOBJMETHOD(g_part_modify, g_part_ldm_modify), - KOBJMETHOD(g_part_resize, g_part_ldm_resize), KOBJMETHOD(g_part_name, g_part_ldm_name), KOBJMETHOD(g_part_probe, g_part_ldm_probe), KOBJMETHOD(g_part_read, g_part_ldm_read), @@ -1206,14 +1203,6 @@ g_part_ldm_modify(struct g_part_table *basetable, return (ENOSYS); } -static int -g_part_ldm_resize(struct g_part_table *basetable, - struct g_part_entry *baseentry, struct g_part_parms *gpp) -{ - - return (ENOSYS); -} - static const char * g_part_ldm_name(struct g_part_table *table, struct g_part_entry *baseentry, char *buf, size_t bufsz) diff --git a/sys/i386/conf/NOTES b/sys/i386/conf/NOTES index 3cb1264dbb0a..92be9473439f 100644 --- a/sys/i386/conf/NOTES +++ b/sys/i386/conf/NOTES @@ -580,6 +580,7 @@ hint.mse.0.irq="5" # nfe: nVidia nForce MCP on-board Ethernet Networking (BSD open source) # nve: nVidia nForce MCP on-board Ethernet Networking # sbni: Granch SBNI12-xx ISA and PCI adapters +# vmx: VMware VMXNET3 Ethernet (BSD open source) # wl: Lucent Wavelan (ISA card only). # wpi: Intel 3945ABG Wireless LAN controller # Requires the wpi firmware module @@ -629,6 +630,7 @@ hint.sbni.0.at="isa" hint.sbni.0.port="0x210" hint.sbni.0.irq="0xefdead" hint.sbni.0.flags="0" +device vmx # VMware VMXNET3 Ethernet device wl hint.wl.0.at="isa" hint.wl.0.port="0x300" diff --git a/sys/i386/i386/mp_machdep.c b/sys/i386/i386/mp_machdep.c index 479168bbbea9..60b36a24f97c 100644 --- a/sys/i386/i386/mp_machdep.c +++ b/sys/i386/i386/mp_machdep.c @@ -81,6 +81,7 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #ifdef XENHVM #include @@ -170,6 +171,11 @@ u_long *ipi_lazypmap_counts[MAXCPU]; static u_long *ipi_hardclock_counts[MAXCPU]; #endif +/* Default cpu_ops implementation. */ +struct cpu_ops cpu_ops = { + .ipi_vectored = lapic_ipi_vectored +}; + /* * Local data and functions. */ @@ -1209,7 +1215,7 @@ ipi_send_cpu(int cpu, u_int ipi) if (old_pending) return; } - lapic_ipi_vectored(ipi, cpu_apic_ids[cpu]); + cpu_ops.ipi_vectored(ipi, cpu_apic_ids[cpu]); } /* @@ -1460,7 +1466,7 @@ ipi_all_but_self(u_int ipi) CPU_OR_ATOMIC(&ipi_nmi_pending, &other_cpus); CTR2(KTR_SMP, "%s: ipi: %x", __func__, ipi); - lapic_ipi_vectored(ipi, APIC_IPI_DEST_OTHERS); + cpu_ops.ipi_vectored(ipi, APIC_IPI_DEST_OTHERS); } int diff --git a/sys/i386/ibcs2/ibcs2_fcntl.c b/sys/i386/ibcs2/ibcs2_fcntl.c index 2902da74bcdf..d061b7968742 100644 --- a/sys/i386/ibcs2/ibcs2_fcntl.c +++ b/sys/i386/ibcs2/ibcs2_fcntl.c @@ -201,10 +201,12 @@ ibcs2_open(td, uap) free(path, M_TEMP); PROC_LOCK(p); if (!ret && !noctty && SESS_LEADER(p) && !(p->p_flag & P_CONTROLT)) { + cap_rights_t rights; struct file *fp; int error; - error = fget(td, td->td_retval[0], CAP_IOCTL, &fp); + error = fget(td, td->td_retval[0], + cap_rights_init(&rights, CAP_IOCTL), &fp); PROC_UNLOCK(p); if (error) return (EBADF); diff --git a/sys/i386/ibcs2/ibcs2_ioctl.c b/sys/i386/ibcs2/ibcs2_ioctl.c index 83e68cd45197..03fa5f6218ba 100644 --- a/sys/i386/ibcs2/ibcs2_ioctl.c +++ b/sys/i386/ibcs2/ibcs2_ioctl.c @@ -331,10 +331,12 @@ ibcs2_ioctl(td, uap) struct ibcs2_ioctl_args *uap; { struct proc *p = td->td_proc; + cap_rights_t rights; struct file *fp; int error; - if ((error = fget(td, uap->fd, CAP_IOCTL, &fp)) != 0) { + error = fget(td, uap->fd, cap_rights_init(&rights, CAP_IOCTL), &fp); + if (error != 0) { DPRINTF(("ibcs2_ioctl(%d): bad fd %d ", p->p_pid, uap->fd)); return EBADF; diff --git a/sys/i386/ibcs2/ibcs2_misc.c b/sys/i386/ibcs2/ibcs2_misc.c index 9f382aaf7070..28cd83cbd5a0 100644 --- a/sys/i386/ibcs2/ibcs2_misc.c +++ b/sys/i386/ibcs2/ibcs2_misc.c @@ -326,6 +326,7 @@ ibcs2_getdents(td, uap) register int len, reclen; /* BSD-format */ register caddr_t outp; /* iBCS2-format */ register int resid; /* iBCS2-format */ + cap_rights_t rights; struct file *fp; struct uio auio; struct iovec aiov; @@ -337,7 +338,9 @@ ibcs2_getdents(td, uap) #define BSD_DIRENT(cp) ((struct dirent *)(cp)) #define IBCS2_RECLEN(reclen) (reclen + sizeof(u_short)) - if ((error = getvnode(td->td_proc->p_fd, uap->fd, CAP_READ, &fp)) != 0) + error = getvnode(td->td_proc->p_fd, uap->fd, + cap_rights_init(&rights, CAP_READ), &fp); + if (error != 0) return (error); if ((fp->f_flag & FREAD) == 0) { fdrop(fp, td); @@ -478,6 +481,7 @@ ibcs2_read(td, uap) register int len, reclen; /* BSD-format */ register caddr_t outp; /* iBCS2-format */ register int resid; /* iBCS2-format */ + cap_rights_t rights; struct file *fp; struct uio auio; struct iovec aiov; @@ -490,8 +494,9 @@ ibcs2_read(td, uap) u_long *cookies = NULL, *cookiep; int ncookies; - if ((error = getvnode(td->td_proc->p_fd, uap->fd, CAP_READ, - &fp)) != 0) { + error = getvnode(td->td_proc->p_fd, uap->fd, + cap_rights_init(&rights, CAP_READ), &fp); + if (error != 0) { if (error == EINVAL) return sys_read(td, (struct read_args *)uap); else diff --git a/sys/i386/ibcs2/imgact_coff.c b/sys/i386/ibcs2/imgact_coff.c index 1e335366d76d..a7543d734dec 100644 --- a/sys/i386/ibcs2/imgact_coff.c +++ b/sys/i386/ibcs2/imgact_coff.c @@ -128,7 +128,7 @@ load_coff_section(struct vmspace *vmspace, struct vnode *vp, vm_offset_t offset, if (map_len != 0) { error = vm_map_find(&vmspace->vm_map, NULL, 0, &map_addr, - map_len, VMFS_NO_SPACE, VM_PROT_ALL, VM_PROT_ALL, 0); + map_len, 0, VMFS_NO_SPACE, VM_PROT_ALL, VM_PROT_ALL, 0); if (error) return (vm_mmap_to_errno(error)); } @@ -473,7 +473,7 @@ exec_coff_imgact(imgp) DPRINTF(("imgact: error = %d\n", error)); vm_map_find(&vmspace->vm_map, NULL, 0, - (vm_offset_t *)&hole, PAGE_SIZE, VMFS_NO_SPACE, + (vm_offset_t *)&hole, PAGE_SIZE, 0, VMFS_NO_SPACE, VM_PROT_ALL, VM_PROT_ALL, 0); DPRINTF(("IBCS2: start vm_dsize = 0x%x, vm_daddr = 0x%p end = 0x%p\n", ctob(vmspace->vm_dsize), vmspace->vm_daddr, diff --git a/sys/i386/include/cpu.h b/sys/i386/include/cpu.h index 5bc9f5c04c11..9655a153540f 100644 --- a/sys/i386/include/cpu.h +++ b/sys/i386/include/cpu.h @@ -54,6 +54,17 @@ #define TRAPF_PC(framep) ((framep)->tf_eip) #ifdef _KERNEL +/* + * Struct containing pointers to CPU management functions whose + * implementation is run time selectable. Selection can be made, + * for example, based on detection of a particular CPU variant or + * hypervisor environment. + */ +struct cpu_ops { + void (*ipi_vectored)(u_int, int); +}; + +extern struct cpu_ops cpu_ops; extern char btext[]; extern char etext[]; diff --git a/sys/i386/include/pcpu.h b/sys/i386/include/pcpu.h index 3a684bfde245..60e50f8167bb 100644 --- a/sys/i386/include/pcpu.h +++ b/sys/i386/include/pcpu.h @@ -44,15 +44,6 @@ * other processors" */ -#if defined(XEN) || defined(XENHVM) -#ifndef NR_VIRQS -#define NR_VIRQS 24 -#endif -#ifndef NR_IPIS -#define NR_IPIS 2 -#endif -#endif - #if defined(XEN) /* These are peridically updated in shared_info, and then copied here. */ diff --git a/sys/i386/include/sf_buf.h b/sys/i386/include/sf_buf.h index 415dcbb86e63..20296b3c1537 100644 --- a/sys/i386/include/sf_buf.h +++ b/sys/i386/include/sf_buf.h @@ -45,6 +45,9 @@ struct sf_buf { #endif }; +struct sf_buf * sf_buf_alloc(struct vm_page *m, int flags); +void sf_buf_free(struct sf_buf *sf); + static __inline vm_offset_t sf_buf_kva(struct sf_buf *sf) { diff --git a/sys/i386/include/smp.h b/sys/i386/include/smp.h index 7c11820ddc67..43dad10c3b6d 100644 --- a/sys/i386/include/smp.h +++ b/sys/i386/include/smp.h @@ -84,11 +84,6 @@ void smp_masked_invltlb(cpuset_t mask); #ifdef XEN void ipi_to_irq_init(void); - -#define RESCHEDULE_VECTOR 0 -#define CALL_FUNCTION_VECTOR 1 -#define NR_IPIS 2 - #endif #endif /* !LOCORE */ #endif /* SMP */ diff --git a/sys/i386/linux/imgact_linux.c b/sys/i386/linux/imgact_linux.c index d92621026bfb..0a4114bc7b14 100644 --- a/sys/i386/linux/imgact_linux.c +++ b/sys/i386/linux/imgact_linux.c @@ -139,8 +139,8 @@ exec_linux_imgact(struct image_params *imgp) */ vmaddr = virtual_offset; error = vm_map_find(&vmspace->vm_map, NULL, 0, &vmaddr, - a_out->a_text + a_out->a_data + bss_size, FALSE, - VM_PROT_ALL, VM_PROT_ALL, 0); + a_out->a_text + a_out->a_data + bss_size, 0, VMFS_NO_SPACE, + VM_PROT_ALL, VM_PROT_ALL, 0); if (error) goto fail; @@ -204,7 +204,7 @@ exec_linux_imgact(struct image_params *imgp) if (bss_size != 0) { vmaddr = virtual_offset + a_out->a_text + a_out->a_data; error = vm_map_find(&vmspace->vm_map, NULL, 0, &vmaddr, - bss_size, FALSE, VM_PROT_ALL, VM_PROT_ALL, 0); + bss_size, 0, VMFS_NO_SPACE, VM_PROT_ALL, VM_PROT_ALL, 0); if (error) goto fail; #ifdef DEBUG diff --git a/sys/i386/linux/linux_machdep.c b/sys/i386/linux/linux_machdep.c index 14d18920b61e..2d792046eb3d 100644 --- a/sys/i386/linux/linux_machdep.c +++ b/sys/i386/linux/linux_machdep.c @@ -422,6 +422,7 @@ linux_mmap_common(struct thread *td, l_uintptr_t addr, l_size_t len, l_int prot, } */ bsd_args; int error; struct file *fp; + cap_rights_t rights; error = 0; bsd_args.flags = 0; @@ -473,7 +474,9 @@ linux_mmap_common(struct thread *td, l_uintptr_t addr, l_size_t len, l_int prot, * is done in the FreeBSD mmap(). */ - if ((error = fget(td, bsd_args.fd, CAP_MMAP, &fp)) != 0) + error = fget(td, bsd_args.fd, + cap_rights_init(&rights, CAP_MMAP), &fp); + if (error != 0) return (error); if (fp->f_type != DTYPE_VNODE) { fdrop(fp, td); diff --git a/sys/i386/xen/mp_machdep.c b/sys/i386/xen/mp_machdep.c index 7ac1dbbf9227..d6eb35b9ad2f 100644 --- a/sys/i386/xen/mp_machdep.c +++ b/sys/i386/xen/mp_machdep.c @@ -99,25 +99,37 @@ extern void failsafe_callback(void); extern void pmap_lazyfix_action(void); /*--------------------------- Forward Declarations ---------------------------*/ -static void assign_cpu_ids(void); -static void set_interrupt_apic_ids(void); -static int start_all_aps(void); -static int start_ap(int apic_id); -static void release_aps(void *dummy); +static driver_filter_t smp_reschedule_interrupt; +static driver_filter_t smp_call_function_interrupt; +static void assign_cpu_ids(void); +static void set_interrupt_apic_ids(void); +static int start_all_aps(void); +static int start_ap(int apic_id); +static void release_aps(void *dummy); + +/*---------------------------------- Macros ----------------------------------*/ +#define IPI_TO_IDX(ipi) ((ipi) - APIC_IPI_INTS) /*-------------------------------- Local Types -------------------------------*/ typedef void call_data_func_t(uintptr_t , uintptr_t); -/* - * Store data from cpu_add() until later in the boot when we actually setup - * the APs. - */ struct cpu_info { int cpu_present:1; int cpu_bsp:1; int cpu_disabled:1; }; +struct xen_ipi_handler +{ + driver_filter_t *filter; + const char *description; +}; + +enum { + RESCHEDULE_VECTOR, + CALL_FUNCTION_VECTOR, +}; + /*-------------------------------- Global Data -------------------------------*/ static u_int hyperthreading_cpus; static cpuset_t hyperthreading_cpus_mask; @@ -161,8 +173,14 @@ static volatile u_int cpu_ipi_pending[MAXCPU]; static int cpu_logical; static int cpu_cores; +static const struct xen_ipi_handler xen_ipis[] = +{ + [RESCHEDULE_VECTOR] = { smp_reschedule_interrupt, "resched" }, + [CALL_FUNCTION_VECTOR] = { smp_call_function_interrupt,"callfunc" } +}; + /*------------------------------- Per-CPU Data -------------------------------*/ -DPCPU_DEFINE(xen_intr_handle_t, ipi_port[NR_IPIS]); +DPCPU_DEFINE(xen_intr_handle_t, ipi_handle[nitems(xen_ipis)]); DPCPU_DEFINE(struct vcpu_info *, vcpu_info); /*------------------------------ Implementation ------------------------------*/ @@ -362,7 +380,7 @@ iv_lazypmap(uintptr_t a, uintptr_t b) /* * These start from "IPI offset" APIC_IPI_INTS */ -static call_data_func_t *ipi_vectors[] = +static call_data_func_t *ipi_vectors[6] = { iv_rendezvous, iv_invltlb, @@ -427,7 +445,7 @@ smp_call_function_interrupt(void *unused) call_data->func_id > IPI_BITMAP_VECTOR) panic("invalid function id %u", call_data->func_id); - func = ipi_vectors[call_data->func_id - APIC_IPI_INTS]; + func = ipi_vectors[IPI_TO_IDX(call_data->func_id)]; /* * Notify initiating CPU that I've grabbed the data and am * about to execute the function @@ -473,44 +491,43 @@ cpu_mp_announce(void) static int xen_smp_cpu_init(unsigned int cpu) { - int rc; - xen_intr_handle_t irq_handle; + xen_intr_handle_t *ipi_handle; + const struct xen_ipi_handler *ipi; + int idx, rc; - DPCPU_ID_SET(cpu, ipi_port[RESCHEDULE_VECTOR], NULL); - DPCPU_ID_SET(cpu, ipi_port[CALL_FUNCTION_VECTOR], NULL); + ipi_handle = DPCPU_ID_GET(cpu, ipi_handle); + for (ipi = xen_ipis, idx = 0; idx < nitems(xen_ipis); ipi++, idx++) { - /* - * The PCPU variable pc_device is not initialized on i386 PV, - * so we have to use the root_bus device in order to setup - * the IPIs. - */ - rc = xen_intr_bind_ipi(root_bus, RESCHEDULE_VECTOR, - cpu, smp_reschedule_interrupt, INTR_TYPE_TTY, &irq_handle); - if (rc < 0) - goto fail; - xen_intr_describe(irq_handle, "resched%u", cpu); - DPCPU_ID_SET(cpu, ipi_port[RESCHEDULE_VECTOR], irq_handle); + /* + * The PCPU variable pc_device is not initialized on i386 PV, + * so we have to use the root_bus device in order to setup + * the IPIs. + */ + rc = xen_intr_alloc_and_bind_ipi(root_bus, cpu, + ipi->filter, INTR_TYPE_TTY, &ipi_handle[idx]); + if (rc != 0) { + printf("Unable to allocate a XEN IPI port. " + "Error %d\n", rc); + break; + } + xen_intr_describe(ipi_handle[idx], "%s", ipi->description); + } - printf("[XEN] IPI cpu=%d port=%d vector=RESCHEDULE_VECTOR (%d)\n", - cpu, xen_intr_port(irq_handle), RESCHEDULE_VECTOR); + for (;idx < nitems(xen_ipis); idx++) + ipi_handle[idx] = NULL; - rc = xen_intr_bind_ipi(root_bus, CALL_FUNCTION_VECTOR, - cpu, smp_call_function_interrupt, INTR_TYPE_TTY, &irq_handle); - if (rc < 0) - goto fail; - xen_intr_describe(irq_handle, "callfunc%u", cpu); - DPCPU_ID_SET(cpu, ipi_port[CALL_FUNCTION_VECTOR], irq_handle); + if (rc == 0) + return (0); - printf("[XEN] IPI cpu=%d port=%d vector=CALL_FUNCTION_VECTOR (%d)\n", - cpu, xen_intr_port(irq_handle), CALL_FUNCTION_VECTOR); + /* Either all are successfully mapped, or none at all. */ + for (idx = 0; idx < nitems(xen_ipis); idx++) { + if (ipi_handle[idx] == NULL) + continue; - return (0); + xen_intr_unbind(ipi_handle[idx]); + ipi_handle[idx] = NULL; + } - fail: - xen_intr_unbind(DPCPU_ID_GET(cpu, ipi_port[RESCHEDULE_VECTOR])); - DPCPU_ID_SET(cpu, ipi_port[RESCHEDULE_VECTOR], NULL); - xen_intr_unbind(DPCPU_ID_GET(cpu, ipi_port[CALL_FUNCTION_VECTOR])); - DPCPU_ID_SET(cpu, ipi_port[CALL_FUNCTION_VECTOR], NULL); return (rc); } @@ -980,8 +997,8 @@ start_ap(int apic_id) static void ipi_pcpu(int cpu, u_int ipi) { - KASSERT((ipi <= NR_IPIS), ("invalid IPI")); - xen_intr_signal(DPCPU_ID_GET(cpu, ipi_port[ipi])); + KASSERT((ipi <= nitems(xen_ipis)), ("invalid IPI")); + xen_intr_signal(DPCPU_ID_GET(cpu, ipi_handle[ipi])); } /* diff --git a/sys/ia64/ia32/ia32_signal.c b/sys/ia64/ia32/ia32_signal.c index 695a04bc1f6b..d17f06049280 100644 --- a/sys/ia64/ia32/ia32_signal.c +++ b/sys/ia64/ia32/ia32_signal.c @@ -169,8 +169,8 @@ ia32_setregs(struct thread *td, struct image_params *imgp, u_long stack) * Build the GDT and LDT. */ gdt = sv->sv_usrstack; - vm_map_find(&vmspace->vm_map, 0, 0, &gdt, IA32_PAGE_SIZE << 1, 0, - VM_PROT_ALL, VM_PROT_ALL, 0); + vm_map_find(&vmspace->vm_map, NULL, 0, &gdt, IA32_PAGE_SIZE << 1, 0, + VMFS_NO_SPACE, VM_PROT_ALL, VM_PROT_ALL, 0); ldt = gdt + IA32_PAGE_SIZE; desc.sd_lolimit = 8*NLDT-1; diff --git a/sys/ia64/ia64/vm_machdep.c b/sys/ia64/ia64/vm_machdep.c index 09987fd7b77f..186897ba8553 100644 --- a/sys/ia64/ia64/vm_machdep.c +++ b/sys/ia64/ia64/vm_machdep.c @@ -79,7 +79,6 @@ #include #include #include -#include #include #include @@ -352,27 +351,6 @@ cpu_exit(struct thread *td) { } -/* - * Allocate an sf_buf for the given vm_page. On this machine, however, there - * is no sf_buf object. Instead, an opaque pointer to the given vm_page is - * returned. - */ -struct sf_buf * -sf_buf_alloc(struct vm_page *m, int pri) -{ - - return ((struct sf_buf *)m); -} - -/* - * Free the sf_buf. In fact, do nothing because there are no resources - * associated with the sf_buf. - */ -void -sf_buf_free(struct sf_buf *sf) -{ -} - /* * Software interrupt handler for queued VM system processing. */ diff --git a/sys/ia64/include/sf_buf.h b/sys/ia64/include/sf_buf.h index 75bcdfa0dcd3..44d0109b2452 100644 --- a/sys/ia64/include/sf_buf.h +++ b/sys/ia64/include/sf_buf.h @@ -41,6 +41,18 @@ */ struct sf_buf; +static inline struct sf_buf * +sf_buf_alloc(struct vm_page *m, int pri) +{ + + return ((struct sf_buf *)m); +} + +static inline void +sf_buf_free(struct sf_buf *sf) +{ +} + static __inline vm_page_t sf_buf_page(struct sf_buf *sf) { diff --git a/sys/kern/capabilities.conf b/sys/kern/capabilities.conf index d2fa51c4ef84..7f68668a542e 100644 --- a/sys/kern/capabilities.conf +++ b/sys/kern/capabilities.conf @@ -114,15 +114,14 @@ cap_fcntls_limit cap_getmode cap_ioctls_get cap_ioctls_limit -cap_new -cap_rights_get +__cap_rights_get cap_rights_limit ## ## Allow read-only clock operations. ## -clock_gettime clock_getres +clock_gettime ## ## Always allow file descriptor close(2). diff --git a/sys/kern/imgact_elf.c b/sys/kern/imgact_elf.c index 61a2aefe4e06..f6da68e6fea5 100644 --- a/sys/kern/imgact_elf.c +++ b/sys/kern/imgact_elf.c @@ -417,8 +417,9 @@ __elfN(map_insert)(vm_map_t map, vm_object_t object, vm_ooffset_t offset, * The mapping is not page aligned. This means we have * to copy the data. Sigh. */ - rv = vm_map_find(map, NULL, 0, &start, end - start, - FALSE, prot | VM_PROT_WRITE, VM_PROT_ALL, 0); + rv = vm_map_find(map, NULL, 0, &start, end - start, 0, + VMFS_NO_SPACE, prot | VM_PROT_WRITE, VM_PROT_ALL, + 0); if (rv) return (rv); if (object == NULL) diff --git a/sys/kern/imgact_gzip.c b/sys/kern/imgact_gzip.c index 230854b21cea..ab77a885524a 100644 --- a/sys/kern/imgact_gzip.c +++ b/sys/kern/imgact_gzip.c @@ -269,12 +269,9 @@ do_aout_hdr(struct imgact_gzip * gz) */ vmaddr = gz->virtual_offset + gz->a_out.a_text + gz->a_out.a_data; - error = vm_map_find(&vmspace->vm_map, - NULL, - 0, - &vmaddr, - gz->bss_size, - FALSE, VM_PROT_ALL, VM_PROT_ALL, 0); + error = vm_map_find(&vmspace->vm_map, NULL, 0, &vmaddr, + gz->bss_size, 0, VMFS_NO_SPACE, VM_PROT_ALL, VM_PROT_ALL, + 0); if (error) { gz->where = __LINE__; return (error); diff --git a/sys/kern/init_main.c b/sys/kern/init_main.c index 40eff025f8e4..0828e4803f98 100644 --- a/sys/kern/init_main.c +++ b/sys/kern/init_main.c @@ -709,8 +709,8 @@ start_init(void *dummy) * Need just enough stack to hold the faked-up "execve()" arguments. */ addr = p->p_sysent->sv_usrstack - PAGE_SIZE; - if (vm_map_find(&p->p_vmspace->vm_map, NULL, 0, &addr, PAGE_SIZE, - FALSE, VM_PROT_ALL, VM_PROT_ALL, 0) != 0) + if (vm_map_find(&p->p_vmspace->vm_map, NULL, 0, &addr, PAGE_SIZE, 0, + VMFS_NO_SPACE, VM_PROT_ALL, VM_PROT_ALL, 0) != 0) panic("init: couldn't allocate argument space"); p->p_vmspace->vm_maxsaddr = (caddr_t)addr; p->p_vmspace->vm_ssize = 1; diff --git a/sys/kern/init_sysent.c b/sys/kern/init_sysent.c index 0fcb9dfcf758..64b0201aa279 100644 --- a/sys/kern/init_sysent.c +++ b/sys/kern/init_sysent.c @@ -3,7 +3,7 @@ * * DO NOT EDIT-- this file is automatically generated. * $FreeBSD$ - * created from FreeBSD: head/sys/kern/syscalls.master 251526 2013-06-08 13:27:57Z glebius + * created from FreeBSD: head/sys/kern/syscalls.master 255219 2013-09-05 00:09:56Z pjd */ #include "opt_compat.h" @@ -548,8 +548,8 @@ struct sysent sysent[] = { { AS(msgctl_args), (sy_call_t *)lkmressys, AUE_NULL, NULL, 0, 0, 0, SY_THR_ABSENT }, /* 511 = msgctl */ { AS(shmctl_args), (sy_call_t *)lkmressys, AUE_NULL, NULL, 0, 0, 0, SY_THR_ABSENT }, /* 512 = shmctl */ { AS(lpathconf_args), (sy_call_t *)sys_lpathconf, AUE_LPATHCONF, NULL, 0, 0, 0, SY_THR_STATIC }, /* 513 = lpathconf */ - { AS(cap_new_args), (sy_call_t *)sys_cap_new, AUE_CAP_NEW, NULL, 0, 0, SYF_CAPENABLED, SY_THR_STATIC }, /* 514 = cap_new */ - { AS(cap_rights_get_args), (sy_call_t *)sys_cap_rights_get, AUE_CAP_RIGHTS_GET, NULL, 0, 0, SYF_CAPENABLED, SY_THR_STATIC }, /* 515 = cap_rights_get */ + { 0, (sy_call_t *)nosys, AUE_NULL, NULL, 0, 0, 0, SY_THR_ABSENT }, /* 514 = obsolete cap_new */ + { AS(__cap_rights_get_args), (sy_call_t *)sys___cap_rights_get, AUE_CAP_RIGHTS_GET, NULL, 0, 0, SYF_CAPENABLED, SY_THR_STATIC }, /* 515 = __cap_rights_get */ { 0, (sy_call_t *)sys_cap_enter, AUE_CAP_ENTER, NULL, 0, 0, SYF_CAPENABLED, SY_THR_STATIC }, /* 516 = cap_enter */ { AS(cap_getmode_args), (sy_call_t *)sys_cap_getmode, AUE_CAP_GETMODE, NULL, 0, 0, SYF_CAPENABLED, SY_THR_STATIC }, /* 517 = cap_getmode */ { AS(pdfork_args), (sy_call_t *)sys_pdfork, AUE_PDFORK, NULL, 0, 0, SYF_CAPENABLED, SY_THR_STATIC }, /* 518 = pdfork */ diff --git a/sys/kern/kern_descrip.c b/sys/kern/kern_descrip.c index d0de6b99b8be..9e9010f0f62a 100644 --- a/sys/kern/kern_descrip.c +++ b/sys/kern/kern_descrip.c @@ -455,6 +455,7 @@ kern_fcntl(struct thread *td, int fd, int cmd, intptr_t arg) struct filedescent *fde; struct proc *p; struct vnode *vp; + cap_rights_t rights; int error, flg, tmp; u_int old, new; uint64_t bsize; @@ -515,7 +516,8 @@ kern_fcntl(struct thread *td, int fd, int cmd, intptr_t arg) break; case F_GETFL: - error = fget_unlocked(fdp, fd, CAP_FCNTL, F_GETFL, &fp, NULL); + error = fget_unlocked(fdp, fd, + cap_rights_init(&rights, CAP_FCNTL), F_GETFL, &fp, NULL); if (error != 0) break; td->td_retval[0] = OFLAGS(fp->f_flag); @@ -523,7 +525,8 @@ kern_fcntl(struct thread *td, int fd, int cmd, intptr_t arg) break; case F_SETFL: - error = fget_unlocked(fdp, fd, CAP_FCNTL, F_SETFL, &fp, NULL); + error = fget_unlocked(fdp, fd, + cap_rights_init(&rights, CAP_FCNTL), F_SETFL, &fp, NULL); if (error != 0) break; do { @@ -550,7 +553,8 @@ kern_fcntl(struct thread *td, int fd, int cmd, intptr_t arg) break; case F_GETOWN: - error = fget_unlocked(fdp, fd, CAP_FCNTL, F_GETOWN, &fp, NULL); + error = fget_unlocked(fdp, fd, + cap_rights_init(&rights, CAP_FCNTL), F_GETOWN, &fp, NULL); if (error != 0) break; error = fo_ioctl(fp, FIOGETOWN, &tmp, td->td_ucred, td); @@ -560,7 +564,8 @@ kern_fcntl(struct thread *td, int fd, int cmd, intptr_t arg) break; case F_SETOWN: - error = fget_unlocked(fdp, fd, CAP_FCNTL, F_SETOWN, &fp, NULL); + error = fget_unlocked(fdp, fd, + cap_rights_init(&rights, CAP_FCNTL), F_SETOWN, &fp, NULL); if (error != 0) break; tmp = arg; @@ -581,7 +586,8 @@ kern_fcntl(struct thread *td, int fd, int cmd, intptr_t arg) case F_SETLK: do_setlk: - error = fget_unlocked(fdp, fd, CAP_FLOCK, 0, &fp, NULL); + cap_rights_init(&rights, CAP_FLOCK); + error = fget_unlocked(fdp, fd, &rights, 0, &fp, NULL); if (error != 0) break; if (fp->f_type != DTYPE_VNODE) { @@ -670,7 +676,7 @@ kern_fcntl(struct thread *td, int fd, int cmd, intptr_t arg) * that the closing thread was a bit slower and that the * advisory lock succeeded before the close. */ - error = fget_unlocked(fdp, fd, 0, 0, &fp2, NULL); + error = fget_unlocked(fdp, fd, &rights, 0, &fp2, NULL); if (error != 0) { fdrop(fp, td); break; @@ -688,7 +694,8 @@ kern_fcntl(struct thread *td, int fd, int cmd, intptr_t arg) break; case F_GETLK: - error = fget_unlocked(fdp, fd, CAP_FLOCK, 0, &fp, NULL); + error = fget_unlocked(fdp, fd, + cap_rights_init(&rights, CAP_FLOCK), 0, &fp, NULL); if (error != 0) break; if (fp->f_type != DTYPE_VNODE) { @@ -726,7 +733,7 @@ kern_fcntl(struct thread *td, int fd, int cmd, intptr_t arg) arg = arg ? 128 * 1024: 0; /* FALLTHROUGH */ case F_READAHEAD: - error = fget_unlocked(fdp, fd, 0, 0, &fp, NULL); + error = fget_unlocked(fdp, fd, NULL, 0, &fp, NULL); if (error != 0) break; if (fp->f_type != DTYPE_VNODE) { @@ -1281,11 +1288,13 @@ int kern_fstat(struct thread *td, int fd, struct stat *sbp) { struct file *fp; + cap_rights_t rights; int error; AUDIT_ARG_FD(fd); - if ((error = fget(td, fd, CAP_FSTAT, &fp)) != 0) + error = fget(td, fd, cap_rights_init(&rights, CAP_FSTAT), &fp); + if (error != 0) return (error); AUDIT_ARG_FILE(td->td_proc, fp); @@ -1339,9 +1348,11 @@ sys_fpathconf(struct thread *td, struct fpathconf_args *uap) { struct file *fp; struct vnode *vp; + cap_rights_t rights; int error; - if ((error = fget(td, uap->fd, CAP_FPATHCONF, &fp)) != 0) + error = fget(td, uap->fd, cap_rights_init(&rights, CAP_FPATHCONF), &fp); + if (error != 0) return (error); /* If asynchronous I/O is available, it works for all descriptors. */ @@ -1417,7 +1428,7 @@ static void filecaps_fill(struct filecaps *fcaps) { - fcaps->fc_rights = CAP_ALL; + CAP_ALL(&fcaps->fc_rights); fcaps->fc_ioctls = NULL; fcaps->fc_nioctls = -1; fcaps->fc_fcntls = CAP_FCNTL_ALL; @@ -1441,16 +1452,18 @@ static void filecaps_validate(const struct filecaps *fcaps, const char *func) { - KASSERT((fcaps->fc_rights & ~CAP_MASK_VALID) == 0, + KASSERT(cap_rights_is_valid(&fcaps->fc_rights), ("%s: invalid rights", func)); KASSERT((fcaps->fc_fcntls & ~CAP_FCNTL_ALL) == 0, ("%s: invalid fcntls", func)); - KASSERT(fcaps->fc_fcntls == 0 || (fcaps->fc_rights & CAP_FCNTL) != 0, + KASSERT(fcaps->fc_fcntls == 0 || + cap_rights_is_set(&fcaps->fc_rights, CAP_FCNTL), ("%s: fcntls without CAP_FCNTL", func)); KASSERT(fcaps->fc_ioctls != NULL ? fcaps->fc_nioctls > 0 : (fcaps->fc_nioctls == -1 || fcaps->fc_nioctls == 0), ("%s: invalid ioctls", func)); - KASSERT(fcaps->fc_nioctls == 0 || (fcaps->fc_rights & CAP_IOCTL) != 0, + KASSERT(fcaps->fc_nioctls == 0 || + cap_rights_is_set(&fcaps->fc_rights, CAP_IOCTL), ("%s: ioctls without CAP_IOCTL", func)); } @@ -2285,7 +2298,7 @@ finit(struct file *fp, u_int flag, short type, void *data, struct fileops *ops) } int -fget_unlocked(struct filedesc *fdp, int fd, cap_rights_t needrights, +fget_unlocked(struct filedesc *fdp, int fd, cap_rights_t *needrightsp, int needfcntl, struct file **fpp, cap_rights_t *haverightsp) { struct file *fp; @@ -2310,14 +2323,16 @@ fget_unlocked(struct filedesc *fdp, int fd, cap_rights_t needrights, if (fp == NULL) return (EBADF); #ifdef CAPABILITIES - haverights = cap_rights(fdp, fd); - error = cap_check(haverights, needrights); - if (error != 0) - return (error); - if ((needrights & CAP_FCNTL) != 0) { - error = cap_fcntl_check(fdp, fd, needfcntl); + haverights = *cap_rights(fdp, fd); + if (needrightsp != NULL) { + error = cap_check(&haverights, needrightsp); if (error != 0) return (error); + if (cap_rights_is_set(needrightsp, CAP_FCNTL)) { + error = cap_fcntl_check(fdp, fd, needfcntl); + if (error != 0) + return (error); + } } #endif count = fp->f_count; @@ -2338,7 +2353,7 @@ fget_unlocked(struct filedesc *fdp, int fd, cap_rights_t needrights, #ifdef CAPABILITIES *haverightsp = haverights; #else - *haverightsp = CAP_ALL; + CAP_ALL(haverightsp); #endif } return (0); @@ -2359,19 +2374,23 @@ fget_unlocked(struct filedesc *fdp, int fd, cap_rights_t needrights, */ static __inline int _fget(struct thread *td, int fd, struct file **fpp, int flags, - cap_rights_t needrights, u_char *maxprotp) + cap_rights_t *needrightsp, u_char *maxprotp) { struct filedesc *fdp; struct file *fp; - cap_rights_t haverights; + cap_rights_t haverights, needrights; int error; *fpp = NULL; if (td == NULL || (fdp = td->td_proc->p_fd) == NULL) return (EBADF); + if (needrightsp != NULL) + needrights = *needrightsp; + else + cap_rights_init(&needrights); if (maxprotp != NULL) - needrights |= CAP_MMAP; - error = fget_unlocked(fdp, fd, needrights, 0, &fp, &haverights); + cap_rights_set(&needrights, CAP_MMAP); + error = fget_unlocked(fdp, fd, &needrights, 0, &fp, &haverights); if (error != 0) return (error); if (fp->f_ops == &badfileops) { @@ -2384,7 +2403,7 @@ _fget(struct thread *td, int fd, struct file **fpp, int flags, * If requested, convert capability rights to access flags. */ if (maxprotp != NULL) - *maxprotp = cap_rights_to_vmprot(haverights); + *maxprotp = cap_rights_to_vmprot(&haverights); #else /* !CAPABILITIES */ if (maxprotp != NULL) *maxprotp = VM_PROT_ALL; @@ -2421,32 +2440,32 @@ _fget(struct thread *td, int fd, struct file **fpp, int flags, } int -fget(struct thread *td, int fd, cap_rights_t rights, struct file **fpp) +fget(struct thread *td, int fd, cap_rights_t *rightsp, struct file **fpp) { - return(_fget(td, fd, fpp, 0, rights, NULL)); + return(_fget(td, fd, fpp, 0, rightsp, NULL)); } int -fget_mmap(struct thread *td, int fd, cap_rights_t rights, u_char *maxprotp, +fget_mmap(struct thread *td, int fd, cap_rights_t *rightsp, u_char *maxprotp, struct file **fpp) { - return (_fget(td, fd, fpp, 0, rights, maxprotp)); + return (_fget(td, fd, fpp, 0, rightsp, maxprotp)); } int -fget_read(struct thread *td, int fd, cap_rights_t rights, struct file **fpp) +fget_read(struct thread *td, int fd, cap_rights_t *rightsp, struct file **fpp) { - return(_fget(td, fd, fpp, FREAD, rights, NULL)); + return(_fget(td, fd, fpp, FREAD, rightsp, NULL)); } int -fget_write(struct thread *td, int fd, cap_rights_t rights, struct file **fpp) +fget_write(struct thread *td, int fd, cap_rights_t *rightsp, struct file **fpp) { - return (_fget(td, fd, fpp, FWRITE, rights, NULL)); + return (_fget(td, fd, fpp, FWRITE, rightsp, NULL)); } /* @@ -2457,15 +2476,15 @@ fget_write(struct thread *td, int fd, cap_rights_t rights, struct file **fpp) * XXX: what about the unused flags ? */ static __inline int -_fgetvp(struct thread *td, int fd, int flags, cap_rights_t needrights, +_fgetvp(struct thread *td, int fd, int flags, cap_rights_t *needrightsp, struct vnode **vpp) { struct file *fp; int error; *vpp = NULL; - error = _fget(td, fd, &fp, flags, needrights, NULL); - if (error) + error = _fget(td, fd, &fp, flags, needrightsp, NULL); + if (error != 0) return (error); if (fp->f_vnode == NULL) { error = EINVAL; @@ -2479,14 +2498,14 @@ _fgetvp(struct thread *td, int fd, int flags, cap_rights_t needrights, } int -fgetvp(struct thread *td, int fd, cap_rights_t rights, struct vnode **vpp) +fgetvp(struct thread *td, int fd, cap_rights_t *rightsp, struct vnode **vpp) { - return (_fgetvp(td, fd, 0, rights, vpp)); + return (_fgetvp(td, fd, 0, rightsp, vpp)); } int -fgetvp_rights(struct thread *td, int fd, cap_rights_t need, +fgetvp_rights(struct thread *td, int fd, cap_rights_t *needrightsp, struct filecaps *havecaps, struct vnode **vpp) { struct filedesc *fdp; @@ -2503,9 +2522,11 @@ fgetvp_rights(struct thread *td, int fd, cap_rights_t need, return (EBADF); #ifdef CAPABILITIES - error = cap_check(cap_rights(fdp, fd), need); - if (error != 0) - return (error); + if (needrightsp != NULL) { + error = cap_check(cap_rights(fdp, fd), needrightsp); + if (error != 0) + return (error); + } #endif if (fp->f_vnode == NULL) @@ -2519,26 +2540,26 @@ fgetvp_rights(struct thread *td, int fd, cap_rights_t need, } int -fgetvp_read(struct thread *td, int fd, cap_rights_t rights, struct vnode **vpp) +fgetvp_read(struct thread *td, int fd, cap_rights_t *rightsp, struct vnode **vpp) { - return (_fgetvp(td, fd, FREAD, rights, vpp)); + return (_fgetvp(td, fd, FREAD, rightsp, vpp)); } int -fgetvp_exec(struct thread *td, int fd, cap_rights_t rights, struct vnode **vpp) +fgetvp_exec(struct thread *td, int fd, cap_rights_t *rightsp, struct vnode **vpp) { - return (_fgetvp(td, fd, FEXEC, rights, vpp)); + return (_fgetvp(td, fd, FEXEC, rightsp, vpp)); } #ifdef notyet int -fgetvp_write(struct thread *td, int fd, cap_rights_t rights, +fgetvp_write(struct thread *td, int fd, cap_rights_t *rightsp, struct vnode **vpp) { - return (_fgetvp(td, fd, FWRITE, rights, vpp)); + return (_fgetvp(td, fd, FWRITE, rightsp, vpp)); } #endif @@ -2554,7 +2575,7 @@ fgetvp_write(struct thread *td, int fd, cap_rights_t rights, * during use. */ int -fgetsock(struct thread *td, int fd, cap_rights_t rights, struct socket **spp, +fgetsock(struct thread *td, int fd, cap_rights_t *rightsp, struct socket **spp, u_int *fflagp) { struct file *fp; @@ -2563,7 +2584,7 @@ fgetsock(struct thread *td, int fd, cap_rights_t rights, struct socket **spp, *spp = NULL; if (fflagp != NULL) *fflagp = 0; - if ((error = _fget(td, fd, &fp, 0, rights, NULL)) != 0) + if ((error = _fget(td, fd, &fp, 0, rightsp, NULL)) != 0) return (error); if (fp->f_type != DTYPE_SOCKET) { error = ENOTSOCK; @@ -2637,9 +2658,11 @@ sys_flock(struct thread *td, struct flock_args *uap) struct file *fp; struct vnode *vp; struct flock lf; + cap_rights_t rights; int error; - if ((error = fget(td, uap->fd, CAP_FLOCK, &fp)) != 0) + error = fget(td, uap->fd, cap_rights_init(&rights, CAP_FLOCK), &fp); + if (error != 0) return (error); if (fp->f_type != DTYPE_VNODE) { fdrop(fp, td); @@ -3185,7 +3208,7 @@ struct export_fd_buf { static int export_fd_to_sb(void *data, int type, int fd, int fflags, int refcnt, - int64_t offset, cap_rights_t fd_cap_rights, struct export_fd_buf *efbuf) + int64_t offset, cap_rights_t *rightsp, struct export_fd_buf *efbuf) { struct { int fflag; @@ -3259,7 +3282,10 @@ export_fd_to_sb(void *data, int type, int fd, int fflags, int refcnt, for (i = 0; i < NFFLAGS; i++) if (fflags & fflags_table[i].fflag) kif->kf_flags |= fflags_table[i].kf_fflag; - kif->kf_cap_rights = fd_cap_rights; + if (rightsp != NULL) + kif->kf_cap_rights = *rightsp; + else + cap_rights_init(&kif->kf_cap_rights); kif->kf_fd = fd; kif->kf_type = type; kif->kf_ref_count = refcnt; @@ -3302,7 +3328,7 @@ kern_proc_filedesc_out(struct proc *p, struct sbuf *sb, ssize_t maxlen) void *data; int error, i; int type, refcnt, fflags; - cap_rights_t fd_cap_rights; + cap_rights_t rights; PROC_LOCK_ASSERT(p, MA_OWNED); @@ -3329,13 +3355,13 @@ kern_proc_filedesc_out(struct proc *p, struct sbuf *sb, ssize_t maxlen) efbuf->remainder = maxlen; if (tracevp != NULL) export_fd_to_sb(tracevp, KF_TYPE_VNODE, KF_FD_TYPE_TRACE, - FREAD | FWRITE, -1, -1, 0, efbuf); + FREAD | FWRITE, -1, -1, NULL, efbuf); if (textvp != NULL) export_fd_to_sb(textvp, KF_TYPE_VNODE, KF_FD_TYPE_TEXT, - FREAD, -1, -1, 0, efbuf); + FREAD, -1, -1, NULL, efbuf); if (cttyvp != NULL) export_fd_to_sb(cttyvp, KF_TYPE_VNODE, KF_FD_TYPE_CTTY, - FREAD | FWRITE, -1, -1, 0, efbuf); + FREAD | FWRITE, -1, -1, NULL, efbuf); error = 0; if (fdp == NULL) goto fail; @@ -3346,30 +3372,30 @@ kern_proc_filedesc_out(struct proc *p, struct sbuf *sb, ssize_t maxlen) vref(fdp->fd_cdir); data = fdp->fd_cdir; export_fd_to_sb(data, KF_TYPE_VNODE, KF_FD_TYPE_CWD, - FREAD, -1, -1, 0, efbuf); + FREAD, -1, -1, NULL, efbuf); } /* root directory */ if (fdp->fd_rdir != NULL) { vref(fdp->fd_rdir); data = fdp->fd_rdir; export_fd_to_sb(data, KF_TYPE_VNODE, KF_FD_TYPE_ROOT, - FREAD, -1, -1, 0, efbuf); + FREAD, -1, -1, NULL, efbuf); } /* jail directory */ if (fdp->fd_jdir != NULL) { vref(fdp->fd_jdir); data = fdp->fd_jdir; export_fd_to_sb(data, KF_TYPE_VNODE, KF_FD_TYPE_JAIL, - FREAD, -1, -1, 0, efbuf); + FREAD, -1, -1, NULL, efbuf); } for (i = 0; i < fdp->fd_nfiles; i++) { if ((fp = fdp->fd_ofiles[i].fde_file) == NULL) continue; data = NULL; #ifdef CAPABILITIES - fd_cap_rights = cap_rights(fdp, i); + rights = *cap_rights(fdp, i); #else /* !CAPABILITIES */ - fd_cap_rights = 0; + cap_rights_init(&rights); #endif switch (fp->f_type) { case DTYPE_VNODE: @@ -3443,8 +3469,8 @@ kern_proc_filedesc_out(struct proc *p, struct sbuf *sb, ssize_t maxlen) * the loop continues. */ error = export_fd_to_sb(data, type, i, fflags, refcnt, - offset, fd_cap_rights, efbuf); - if (error) + offset, &rights, efbuf); + if (error != 0) break; } FILEDESC_SUNLOCK(fdp); diff --git a/sys/kern/kern_event.c b/sys/kern/kern_event.c index dfd1c46d625e..8bde25a3e155 100644 --- a/sys/kern/kern_event.c +++ b/sys/kern/kern_event.c @@ -824,9 +824,11 @@ kern_kevent(struct thread *td, int fd, int nchanges, int nevents, struct kevent *kevp, *changes; struct kqueue *kq; struct file *fp; + cap_rights_t rights; int i, n, nerrors, error; - if ((error = fget(td, fd, CAP_POST_EVENT, &fp)) != 0) + error = fget(td, fd, cap_rights_init(&rights, CAP_POST_EVENT), &fp); + if (error != 0) return (error); if ((error = kqueue_acquire(fp, &kq)) != 0) goto done_norel; @@ -964,6 +966,7 @@ kqueue_register(struct kqueue *kq, struct kevent *kev, struct thread *td, int wa struct filterops *fops; struct file *fp; struct knote *kn, *tkn; + cap_rights_t rights; int error, filt, event; int haskqglobal; @@ -982,7 +985,8 @@ kqueue_register(struct kqueue *kq, struct kevent *kev, struct thread *td, int wa findkn: if (fops->f_isfd) { KASSERT(td != NULL, ("td is NULL")); - error = fget(td, kev->ident, CAP_POLL_EVENT, &fp); + error = fget(td, kev->ident, + cap_rights_init(&rights, CAP_POLL_EVENT), &fp); if (error) goto done; @@ -2237,9 +2241,11 @@ kqfd_register(int fd, struct kevent *kev, struct thread *td, int waitok) { struct kqueue *kq; struct file *fp; + cap_rights_t rights; int error; - if ((error = fget(td, fd, CAP_POST_EVENT, &fp)) != 0) + error = fget(td, fd, cap_rights_init(&rights, CAP_POST_EVENT), &fp); + if (error != 0) return (error); if ((error = kqueue_acquire(fp, &kq)) != 0) goto noacquire; diff --git a/sys/kern/kern_exec.c b/sys/kern/kern_exec.c index 833fd18ae790..45f732b2f85d 100644 --- a/sys/kern/kern_exec.c +++ b/sys/kern/kern_exec.c @@ -338,6 +338,7 @@ do_execve(td, args, mac_p) struct ucred *tracecred = NULL; #endif struct vnode *textvp = NULL, *binvp = NULL; + cap_rights_t rights; int credential_changing; int textset; #ifdef MAC @@ -438,7 +439,8 @@ do_execve(td, args, mac_p) /* * Descriptors opened only with O_EXEC or O_RDONLY are allowed. */ - error = fgetvp_exec(td, args->fd, CAP_FEXECVE, &binvp); + error = fgetvp_exec(td, args->fd, + cap_rights_init(&rights, CAP_FEXECVE), &binvp); if (error) goto exec_fail; vn_lock(binvp, LK_EXCLUSIVE | LK_RETRY); diff --git a/sys/kern/kern_intr.c b/sys/kern/kern_intr.c index 63d84694a560..f4b04c3f71b4 100644 --- a/sys/kern/kern_intr.c +++ b/sys/kern/kern_intr.c @@ -1147,7 +1147,7 @@ swi_sched(void *cookie, int flags) entropy.event = (uintptr_t)ih; entropy.td = curthread; random_harvest(&entropy, sizeof(entropy), 1, 0, - RANDOM_INTERRUPT); + RANDOM_SWI); } /* diff --git a/sys/kern/kern_jail.c b/sys/kern/kern_jail.c index 6451825172d9..331b0e1a9437 100644 --- a/sys/kern/kern_jail.c +++ b/sys/kern/kern_jail.c @@ -3885,6 +3885,13 @@ prison_priv_check(struct ucred *cred, int priv) case PRIV_VFS_SETGID: case PRIV_VFS_STAT: case PRIV_VFS_STICKYFILE: + + /* + * As in the non-jail case, non-root users are expected to be + * able to read kernel/phyiscal memory (provided /dev/[k]mem + * exists in the jail and they have permission to access it). + */ + case PRIV_KMEM_READ: return (0); /* diff --git a/sys/kern/kern_ktrace.c b/sys/kern/kern_ktrace.c index e512a33b2c9c..3b34fb0d8ee9 100644 --- a/sys/kern/kern_ktrace.c +++ b/sys/kern/kern_ktrace.c @@ -779,8 +779,8 @@ ktrstruct(name, data, datalen) void ktrcapfail(type, needed, held) enum ktr_cap_fail_type type; - cap_rights_t needed; - cap_rights_t held; + const cap_rights_t *needed; + const cap_rights_t *held; { struct thread *td = curthread; struct ktr_request *req; @@ -791,8 +791,8 @@ ktrcapfail(type, needed, held) return; kcf = &req->ktr_data.ktr_cap_fail; kcf->cap_type = type; - kcf->cap_needed = needed; - kcf->cap_held = held; + kcf->cap_needed = *needed; + kcf->cap_held = *held; ktr_enqueuerequest(td, req); ktrace_exit(td); } diff --git a/sys/kern/kern_mbuf.c b/sys/kern/kern_mbuf.c index 4d45553c1ffc..5d589425fff6 100644 --- a/sys/kern/kern_mbuf.c +++ b/sys/kern/kern_mbuf.c @@ -106,7 +106,7 @@ int nmbjumbo16; /* limits number of 16k jumbo clusters */ static quad_t maxmbufmem; /* overall real memory limit for all mbufs */ SYSCTL_QUAD(_kern_ipc, OID_AUTO, maxmbufmem, CTLFLAG_RDTUN, &maxmbufmem, 0, - "Maximum real memory allocateable to various mbuf types"); + "Maximum real memory allocatable to various mbuf types"); /* * tunable_mbinit() has to be run before any mbuf allocations are done. diff --git a/sys/kern/kern_sig.c b/sys/kern/kern_sig.c index 22fc1b78bac5..1797ebc7dd43 100644 --- a/sys/kern/kern_sig.c +++ b/sys/kern/kern_sig.c @@ -1726,6 +1726,7 @@ sys_pdkill(td, uap) { #ifdef PROCDESC struct proc *p; + cap_rights_t rights; int error; AUDIT_ARG_SIGNUM(uap->signum); @@ -1733,7 +1734,8 @@ sys_pdkill(td, uap) if ((u_int)uap->signum > _SIG_MAXSIG) return (EINVAL); - error = procdesc_find(td, uap->fd, CAP_PDKILL, &p); + error = procdesc_find(td, uap->fd, + cap_rights_init(&rights, CAP_PDKILL), &p); if (error) return (error); AUDIT_ARG_PROCESS(p); diff --git a/sys/kern/link_elf.c b/sys/kern/link_elf.c index 6252a8d04ca1..631ba752b7d6 100644 --- a/sys/kern/link_elf.c +++ b/sys/kern/link_elf.c @@ -891,7 +891,7 @@ link_elf_load_file(linker_class_t cls, const char* filename, } ef->address = (caddr_t) vm_map_min(kernel_map); error = vm_map_find(kernel_map, ef->object, 0, - (vm_offset_t *) &ef->address, mapsize, 1, + (vm_offset_t *) &ef->address, mapsize, 0, VMFS_OPTIMAL_SPACE, VM_PROT_ALL, VM_PROT_ALL, 0); if (error != 0) { vm_object_deallocate(ef->object); diff --git a/sys/kern/link_elf_obj.c b/sys/kern/link_elf_obj.c index a9208df3a659..0334779afac8 100644 --- a/sys/kern/link_elf_obj.c +++ b/sys/kern/link_elf_obj.c @@ -689,7 +689,8 @@ link_elf_load_file(linker_class_t cls, const char *filename, mapbase = VM_MIN_KERNEL_ADDRESS; #endif error = vm_map_find(kernel_map, ef->object, 0, &mapbase, - round_page(mapsize), TRUE, VM_PROT_ALL, VM_PROT_ALL, FALSE); + round_page(mapsize), 0, VMFS_OPTIMAL_SPACE, VM_PROT_ALL, + VM_PROT_ALL, 0); if (error) { vm_object_deallocate(ef->object); ef->object = 0; diff --git a/sys/kern/sched_ule.c b/sys/kern/sched_ule.c index 95105d80475e..cba9d804a3ab 100644 --- a/sys/kern/sched_ule.c +++ b/sys/kern/sched_ule.c @@ -667,10 +667,14 @@ cpu_search(const struct cpu_group *cg, struct cpu_search *low, } /* Iterate through the child CPU groups and then remaining CPUs. */ - for (i = cg->cg_children, cpu = mp_maxid; i >= 0; ) { + for (i = cg->cg_children, cpu = mp_maxid; ; ) { if (i == 0) { +#ifdef HAVE_INLINE_FFSL + cpu = CPU_FFS(&cpumask) - 1; +#else while (cpu >= 0 && !CPU_ISSET(cpu, &cpumask)) cpu--; +#endif if (cpu < 0) break; child = NULL; @@ -695,6 +699,7 @@ cpu_search(const struct cpu_group *cg, struct cpu_search *low, break; } } else { /* Handle child CPU. */ + CPU_CLR(cpu, &cpumask); tdq = TDQ_CPU(cpu); load = tdq->tdq_load * 256; rndptr = DPCPU_PTR(randomval); @@ -742,8 +747,11 @@ cpu_search(const struct cpu_group *cg, struct cpu_search *low, i--; if (i == 0 && CPU_EMPTY(&cpumask)) break; - } else + } +#ifndef HAVE_INLINE_FFSL + else cpu--; +#endif } return (total); } diff --git a/sys/kern/subr_capability.c b/sys/kern/subr_capability.c new file mode 100644 index 000000000000..61ace5ab6e42 --- /dev/null +++ b/sys/kern/subr_capability.c @@ -0,0 +1,298 @@ +/*- + * Copyright (c) 2013 FreeBSD Foundation + * All rights reserved. + * + * This software was developed by Pawel Jakub Dawidek under sponsorship from + * the FreeBSD Foundation. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include +__FBSDID("$FreeBSD$"); + +#ifdef _KERNEL +#include +#include +#include + +#include +#else /* !_KERNEL */ +#include +#include + +#include +#include +#include +#include +#include +#endif + +#ifdef _KERNEL +#define assert(exp) KASSERT((exp), ("%s:%u", __func__, __LINE__)) +#endif + +#define CAPARSIZE_MIN (CAP_RIGHTS_VERSION_00 + 2) +#define CAPARSIZE_MAX (CAP_RIGHTS_VERSION + 2) + +static __inline int +right_to_index(uint64_t right) +{ + static const int bit2idx[] = { + -1, 0, 1, -1, 2, -1, -1, -1, 3, -1, -1, -1, -1, -1, -1, -1, + 4, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 + }; + int idx; + + idx = CAPIDXBIT(right); + assert(idx >= 0 && idx < sizeof(bit2idx) / sizeof(bit2idx[0])); + return (bit2idx[idx]); +} + +static void +cap_rights_vset(cap_rights_t *rights, va_list ap) +{ + uint64_t right; + int i, n; + + assert(CAPVER(rights) == CAP_RIGHTS_VERSION_00); + + n = CAPARSIZE(rights); + assert(n >= CAPARSIZE_MIN && n <= CAPARSIZE_MAX); + + for (;;) { + right = (uint64_t)va_arg(ap, unsigned long long); + if (right == 0) + break; + assert(CAPRVER(right) == 0); + i = right_to_index(right); + assert(i >= 0); + assert(i < n); + assert(CAPIDXBIT(rights->cr_rights[i]) == CAPIDXBIT(right)); + rights->cr_rights[i] |= right; + assert(CAPIDXBIT(rights->cr_rights[i]) == CAPIDXBIT(right)); + } +} + +static void +cap_rights_vclear(cap_rights_t *rights, va_list ap) +{ + uint64_t right; + int i, n; + + assert(CAPVER(rights) == CAP_RIGHTS_VERSION_00); + + n = CAPARSIZE(rights); + assert(n >= CAPARSIZE_MIN && n <= CAPARSIZE_MAX); + + for (;;) { + right = (uint64_t)va_arg(ap, unsigned long long); + if (right == 0) + break; + assert(CAPRVER(right) == 0); + i = right_to_index(right); + assert(i >= 0); + assert(i < n); + assert(CAPIDXBIT(rights->cr_rights[i]) == CAPIDXBIT(right)); + rights->cr_rights[i] &= ~(right & 0x01FFFFFFFFFFFFFFULL); + assert(CAPIDXBIT(rights->cr_rights[i]) == CAPIDXBIT(right)); + } +} + +static bool +cap_rights_is_vset(const cap_rights_t *rights, va_list ap) +{ + uint64_t right; + int i, n; + + assert(CAPVER(rights) == CAP_RIGHTS_VERSION_00); + + n = CAPARSIZE(rights); + assert(n >= CAPARSIZE_MIN && n <= CAPARSIZE_MAX); + + for (;;) { + right = (uint64_t)va_arg(ap, unsigned long long); + if (right == 0) + break; + assert(CAPRVER(right) == 0); + i = right_to_index(right); + assert(i >= 0); + assert(i < n); + assert(CAPIDXBIT(rights->cr_rights[i]) == CAPIDXBIT(right)); + if ((rights->cr_rights[i] & right) != right) + return (false); + } + + return (true); +} + +cap_rights_t * +__cap_rights_init(int version, cap_rights_t *rights, ...) +{ + unsigned int n; + va_list ap; + + assert(version == CAP_RIGHTS_VERSION_00); + + n = version + 2; + assert(n >= CAPARSIZE_MIN && n <= CAPARSIZE_MAX); + memset(rights->cr_rights, 0, sizeof(rights->cr_rights[0]) * n); + CAP_NONE(rights); + va_start(ap, rights); + cap_rights_vset(rights, ap); + va_end(ap); + + return (rights); +} + +void +__cap_rights_set(cap_rights_t *rights, ...) +{ + va_list ap; + + assert(CAPVER(rights) == CAP_RIGHTS_VERSION_00); + + va_start(ap, rights); + cap_rights_vset(rights, ap); + va_end(ap); +} + +void +__cap_rights_clear(cap_rights_t *rights, ...) +{ + va_list ap; + + assert(CAPVER(rights) == CAP_RIGHTS_VERSION_00); + + va_start(ap, rights); + cap_rights_vclear(rights, ap); + va_end(ap); +} + +bool +__cap_rights_is_set(const cap_rights_t *rights, ...) +{ + va_list ap; + bool ret; + + assert(CAPVER(rights) == CAP_RIGHTS_VERSION_00); + + va_start(ap, rights); + ret = cap_rights_is_vset(rights, ap); + va_end(ap); + + return (ret); +} + +bool +cap_rights_is_valid(const cap_rights_t *rights) +{ + cap_rights_t allrights; + int i, j; + + if (CAPVER(rights) != CAP_RIGHTS_VERSION_00) + return (false); + if (CAPARSIZE(rights) < CAPARSIZE_MIN || + CAPARSIZE(rights) > CAPARSIZE_MAX) { + return (false); + } + CAP_ALL(&allrights); + if (!cap_rights_contains(&allrights, rights)) + return (false); + for (i = 0; i < CAPARSIZE(rights); i++) { + j = right_to_index(rights->cr_rights[i]); + if (i != j) + return (false); + if (i > 0) { + if (CAPRVER(rights->cr_rights[i]) != 0) + return (false); + } + } + + return (true); +} + +void +cap_rights_merge(cap_rights_t *dst, const cap_rights_t *src) +{ + unsigned int i, n; + + assert(CAPVER(dst) == CAP_RIGHTS_VERSION_00); + assert(CAPVER(src) == CAP_RIGHTS_VERSION_00); + assert(CAPVER(dst) == CAPVER(src)); + assert(cap_rights_is_valid(src)); + assert(cap_rights_is_valid(dst)); + + n = CAPARSIZE(dst); + assert(n >= CAPARSIZE_MIN && n <= CAPARSIZE_MAX); + + for (i = 0; i < n; i++) + dst->cr_rights[i] |= src->cr_rights[i]; + + assert(cap_rights_is_valid(src)); + assert(cap_rights_is_valid(dst)); +} + +void +cap_rights_remove(cap_rights_t *dst, const cap_rights_t *src) +{ + unsigned int i, n; + + assert(CAPVER(dst) == CAP_RIGHTS_VERSION_00); + assert(CAPVER(src) == CAP_RIGHTS_VERSION_00); + assert(CAPVER(dst) == CAPVER(src)); + assert(cap_rights_is_valid(src)); + assert(cap_rights_is_valid(dst)); + + n = CAPARSIZE(dst); + assert(n >= CAPARSIZE_MIN && n <= CAPARSIZE_MAX); + + for (i = 0; i < n; i++) { + dst->cr_rights[i] &= + ~(src->cr_rights[i] & 0x01FFFFFFFFFFFFFFULL); + } + + assert(cap_rights_is_valid(src)); + assert(cap_rights_is_valid(dst)); +} + +bool +cap_rights_contains(const cap_rights_t *big, const cap_rights_t *little) +{ + unsigned int i, n; + + assert(CAPVER(big) == CAP_RIGHTS_VERSION_00); + assert(CAPVER(little) == CAP_RIGHTS_VERSION_00); + assert(CAPVER(big) == CAPVER(little)); + + n = CAPARSIZE(big); + assert(n >= CAPARSIZE_MIN && n <= CAPARSIZE_MAX); + + for (i = 0; i < n; i++) { + if ((big->cr_rights[i] & little->cr_rights[i]) != + little->cr_rights[i]) { + return (false); + } + } + + return (true); +} diff --git a/sys/kern/subr_prf.c b/sys/kern/subr_prf.c index d8e8e0582a7d..042afa3e4e31 100644 --- a/sys/kern/subr_prf.c +++ b/sys/kern/subr_prf.c @@ -175,15 +175,24 @@ uprintf(const char *fmt, ...) } /* - * tprintf prints on the controlling terminal associated with the given - * session, possibly to the log as well. + * tprintf and vtprintf print on the controlling terminal associated with the + * given session, possibly to the log as well. */ void tprintf(struct proc *p, int pri, const char *fmt, ...) +{ + va_list ap; + + va_start(ap, fmt); + vtprintf(p, pri, fmt, ap); + va_end(ap); +} + +void +vtprintf(struct proc *p, int pri, const char *fmt, va_list ap) { struct tty *tp = NULL; int flags = 0; - va_list ap; struct putchar_arg pca; struct session *sess = NULL; @@ -208,13 +217,11 @@ tprintf(struct proc *p, int pri, const char *fmt, ...) pca.tty = tp; pca.flags = flags; pca.p_bufr = NULL; - va_start(ap, fmt); if (pca.tty != NULL) tty_lock(pca.tty); kvprintf(fmt, putchar, &pca, 10, ap); if (pca.tty != NULL) tty_unlock(pca.tty); - va_end(ap); if (sess != NULL) sess_release(sess); msgbuftrigger = 1; diff --git a/sys/kern/sys_capability.c b/sys/kern/sys_capability.c index 224042ead5a3..7a820179633f 100644 --- a/sys/kern/sys_capability.c +++ b/sys/kern/sys_capability.c @@ -148,16 +148,19 @@ FEATURE(security_capabilities, "Capsicum Capabilities"); MALLOC_DECLARE(M_FILECAPS); static inline int -_cap_check(cap_rights_t have, cap_rights_t need, enum ktr_cap_fail_type type) +_cap_check(const cap_rights_t *havep, const cap_rights_t *needp, + enum ktr_cap_fail_type type) { + int i; - - if ((need & ~have) != 0) { + for (i = 0; i < nitems(havep->cr_rights); i++) { + if (!cap_rights_contains(havep, needp)) { #ifdef KTRACE - if (KTRPOINT(curthread, KTR_CAPFAIL)) - ktrcapfail(type, need, have); + if (KTRPOINT(curthread, KTR_CAPFAIL)) + ktrcapfail(type, needp, havep); #endif - return (ENOTCAPABLE); + return (ENOTCAPABLE); + } } return (0); } @@ -166,26 +169,26 @@ _cap_check(cap_rights_t have, cap_rights_t need, enum ktr_cap_fail_type type) * Test whether a capability grants the requested rights. */ int -cap_check(cap_rights_t have, cap_rights_t need) +cap_check(const cap_rights_t *havep, const cap_rights_t *needp) { - return (_cap_check(have, need, CAPFAIL_NOTCAPABLE)); + return (_cap_check(havep, needp, CAPFAIL_NOTCAPABLE)); } /* * Convert capability rights into VM access flags. */ u_char -cap_rights_to_vmprot(cap_rights_t have) +cap_rights_to_vmprot(cap_rights_t *havep) { u_char maxprot; maxprot = VM_PROT_NONE; - if (have & CAP_MMAP_R) + if (cap_rights_is_set(havep, CAP_MMAP_R)) maxprot |= VM_PROT_READ; - if (have & CAP_MMAP_W) + if (cap_rights_is_set(havep, CAP_MMAP_W)) maxprot |= VM_PROT_WRITE; - if (have & CAP_MMAP_X) + if (cap_rights_is_set(havep, CAP_MMAP_X)) maxprot |= VM_PROT_EXECUTE; return (maxprot); @@ -196,11 +199,11 @@ cap_rights_to_vmprot(cap_rights_t have) * any other way, as we want to keep all capability permission evaluation in * this one file. */ -cap_rights_t +cap_rights_t * cap_rights(struct filedesc *fdp, int fd) { - return (fdp->fd_ofiles[fd].fde_rights); + return (&fdp->fd_ofiles[fd].fde_rights); } /* @@ -211,16 +214,41 @@ sys_cap_rights_limit(struct thread *td, struct cap_rights_limit_args *uap) { struct filedesc *fdp; cap_rights_t rights; - int error, fd; + int error, fd, version; + + cap_rights_init(&rights); + + error = copyin(uap->rightsp, &rights, sizeof(rights.cr_rights[0])); + if (error != 0) + return (error); + version = CAPVER(&rights); + if (version != CAP_RIGHTS_VERSION_00) + return (EINVAL); + + error = copyin(uap->rightsp, &rights, + sizeof(rights.cr_rights[0]) * CAPARSIZE(&rights)); + if (error != 0) + return (error); + /* Check for race. */ + if (CAPVER(&rights) != version) + return (EINVAL); + + if (!cap_rights_is_valid(&rights)) + return (EINVAL); + + if (version != CAP_RIGHTS_VERSION) { + rights.cr_rights[0] &= ~(0x3ULL << 62); + rights.cr_rights[0] |= ((uint64_t)CAP_RIGHTS_VERSION << 62); + } +#ifdef KTRACE + if (KTRPOINT(td, KTR_STRUCT)) + ktrcaprights(&rights); +#endif fd = uap->fd; - rights = uap->rights; AUDIT_ARG_FD(fd); - AUDIT_ARG_RIGHTS(rights); - - if ((rights & ~CAP_ALL) != 0) - return (EINVAL); + AUDIT_ARG_RIGHTS(&rights); fdp = td->td_proc->p_fd; FILEDESC_XLOCK(fdp); @@ -228,15 +256,15 @@ sys_cap_rights_limit(struct thread *td, struct cap_rights_limit_args *uap) FILEDESC_XUNLOCK(fdp); return (EBADF); } - error = _cap_check(cap_rights(fdp, fd), rights, CAPFAIL_INCREASE); + error = _cap_check(cap_rights(fdp, fd), &rights, CAPFAIL_INCREASE); if (error == 0) { fdp->fd_ofiles[fd].fde_rights = rights; - if ((rights & CAP_IOCTL) == 0) { + if (!cap_rights_is_set(&rights, CAP_IOCTL)) { free(fdp->fd_ofiles[fd].fde_ioctls, M_FILECAPS); fdp->fd_ofiles[fd].fde_ioctls = NULL; fdp->fd_ofiles[fd].fde_nioctls = 0; } - if ((rights & CAP_FCNTL) == 0) + if (!cap_rights_is_set(&rights, CAP_FCNTL)) fdp->fd_ofiles[fd].fde_fcntls = 0; } FILEDESC_XUNLOCK(fdp); @@ -247,11 +275,14 @@ sys_cap_rights_limit(struct thread *td, struct cap_rights_limit_args *uap) * System call to query the rights mask associated with a capability. */ int -sys_cap_rights_get(struct thread *td, struct cap_rights_get_args *uap) +sys___cap_rights_get(struct thread *td, struct __cap_rights_get_args *uap) { struct filedesc *fdp; cap_rights_t rights; - int fd; + int error, fd, i, n; + + if (uap->version != CAP_RIGHTS_VERSION_00) + return (EINVAL); fd = uap->fd; @@ -263,9 +294,26 @@ sys_cap_rights_get(struct thread *td, struct cap_rights_get_args *uap) FILEDESC_SUNLOCK(fdp); return (EBADF); } - rights = cap_rights(fdp, fd); + rights = *cap_rights(fdp, fd); FILEDESC_SUNLOCK(fdp); - return (copyout(&rights, uap->rightsp, sizeof(*uap->rightsp))); + n = uap->version + 2; + if (uap->version != CAPVER(&rights)) { + /* + * For older versions we need to check if the descriptor + * doesn't contain rights not understood by the caller. + * If it does, we have to return an error. + */ + for (i = n; i < CAPARSIZE(&rights); i++) { + if ((rights.cr_rights[i] & ~(0x7FULL << 57)) != 0) + return (EINVAL); + } + } + error = copyout(&rights, uap->rightsp, sizeof(rights.cr_rights[0]) * n); +#ifdef KTRACE + if (error == 0 && KTRPOINT(td, KTR_STRUCT)) + ktrcaprights(&rights); +#endif + return (error); } /* @@ -513,65 +561,6 @@ sys_cap_fcntls_get(struct thread *td, struct cap_fcntls_get_args *uap) return (copyout(&rights, uap->fcntlrightsp, sizeof(rights))); } -/* - * For backward compatibility. - */ -int -sys_cap_new(struct thread *td, struct cap_new_args *uap) -{ - struct filedesc *fdp; - cap_rights_t rights; - register_t newfd; - int error, fd; - - fd = uap->fd; - rights = uap->rights; - - AUDIT_ARG_FD(fd); - AUDIT_ARG_RIGHTS(rights); - - if ((rights & ~CAP_ALL) != 0) - return (EINVAL); - - fdp = td->td_proc->p_fd; - FILEDESC_SLOCK(fdp); - if (fget_locked(fdp, fd) == NULL) { - FILEDESC_SUNLOCK(fdp); - return (EBADF); - } - error = _cap_check(cap_rights(fdp, fd), rights, CAPFAIL_INCREASE); - FILEDESC_SUNLOCK(fdp); - if (error != 0) - return (error); - - error = do_dup(td, 0, fd, 0, &newfd); - if (error != 0) - return (error); - - FILEDESC_XLOCK(fdp); - /* - * We don't really care about the race between checking capability - * rights for the source descriptor and now. If capability rights - * were ok at that earlier point, the process had this descriptor - * with those rights, so we don't increase them in security sense, - * the process might have done the cap_new(2) a bit earlier to get - * the same effect. - */ - fdp->fd_ofiles[newfd].fde_rights = rights; - if ((rights & CAP_IOCTL) == 0) { - free(fdp->fd_ofiles[newfd].fde_ioctls, M_FILECAPS); - fdp->fd_ofiles[newfd].fde_ioctls = NULL; - fdp->fd_ofiles[newfd].fde_nioctls = 0; - } - if ((rights & CAP_FCNTL) == 0) - fdp->fd_ofiles[newfd].fde_fcntls = 0; - FILEDESC_XUNLOCK(fdp); - - td->td_retval[0] = newfd; - - return (0); -} - #else /* !CAPABILITIES */ /* @@ -587,7 +576,7 @@ sys_cap_rights_limit(struct thread *td, struct cap_rights_limit_args *uap) } int -sys_cap_rights_get(struct thread *td, struct cap_rights_get_args *uap) +sys___cap_rights_get(struct thread *td, struct __cap_rights_get_args *uap) { return (ENOSYS); @@ -621,11 +610,4 @@ sys_cap_fcntls_get(struct thread *td, struct cap_fcntls_get_args *uap) return (ENOSYS); } -int -sys_cap_new(struct thread *td, struct cap_new_args *uap) -{ - - return (ENOSYS); -} - #endif /* CAPABILITIES */ diff --git a/sys/kern/sys_generic.c b/sys/kern/sys_generic.c index 44d1a8994645..d4d6293034ab 100644 --- a/sys/kern/sys_generic.c +++ b/sys/kern/sys_generic.c @@ -243,9 +243,10 @@ int kern_readv(struct thread *td, int fd, struct uio *auio) { struct file *fp; + cap_rights_t rights; int error; - error = fget_read(td, fd, CAP_READ, &fp); + error = fget_read(td, fd, cap_rights_init(&rights, CAP_READ), &fp); if (error) return (error); error = dofileread(td, fd, fp, auio, (off_t)-1, 0); @@ -286,9 +287,10 @@ kern_preadv(td, fd, auio, offset) off_t offset; { struct file *fp; + cap_rights_t rights; int error; - error = fget_read(td, fd, CAP_PREAD, &fp); + error = fget_read(td, fd, cap_rights_init(&rights, CAP_PREAD), &fp); if (error) return (error); if (!(fp->f_ops->fo_flags & DFLAG_SEEKABLE)) @@ -452,9 +454,10 @@ int kern_writev(struct thread *td, int fd, struct uio *auio) { struct file *fp; + cap_rights_t rights; int error; - error = fget_write(td, fd, CAP_WRITE, &fp); + error = fget_write(td, fd, cap_rights_init(&rights, CAP_WRITE), &fp); if (error) return (error); error = dofilewrite(td, fd, fp, auio, (off_t)-1, 0); @@ -495,9 +498,10 @@ kern_pwritev(td, fd, auio, offset) off_t offset; { struct file *fp; + cap_rights_t rights; int error; - error = fget_write(td, fd, CAP_PWRITE, &fp); + error = fget_write(td, fd, cap_rights_init(&rights, CAP_PWRITE), &fp); if (error) return (error); if (!(fp->f_ops->fo_flags & DFLAG_SEEKABLE)) @@ -575,12 +579,13 @@ kern_ftruncate(td, fd, length) off_t length; { struct file *fp; + cap_rights_t rights; int error; AUDIT_ARG_FD(fd); if (length < 0) return (EINVAL); - error = fget(td, fd, CAP_FTRUNCATE, &fp); + error = fget(td, fd, cap_rights_init(&rights, CAP_FTRUNCATE), &fp); if (error) return (error); AUDIT_ARG_FILE(td->td_proc, fp); @@ -705,6 +710,9 @@ kern_ioctl(struct thread *td, int fd, u_long com, caddr_t data) { struct file *fp; struct filedesc *fdp; +#ifndef CAPABILITIES + cap_rights_t rights; +#endif int error, tmp, locked; AUDIT_ARG_FD(fd); @@ -743,7 +751,8 @@ kern_ioctl(struct thread *td, int fd, u_long com, caddr_t data) locked = LA_UNLOCKED; } #else - if ((error = fget(td, fd, CAP_IOCTL, &fp)) != 0) { + error = fget(td, fd, cap_rights_init(&rights, CAP_IOCTL), &fp); + if (error != 0) { fp = NULL; goto out; } @@ -1180,8 +1189,10 @@ selsetbits(fd_mask **ibits, fd_mask **obits, int idx, fd_mask bit, int events) static __inline int getselfd_cap(struct filedesc *fdp, int fd, struct file **fpp) { + cap_rights_t rights; - return (fget_unlocked(fdp, fd, CAP_POLL_EVENT, 0, fpp, NULL)); + return (fget_unlocked(fdp, fd, cap_rights_init(&rights, CAP_POLL_EVENT), + 0, fpp, NULL)); } /* @@ -1357,6 +1368,9 @@ pollrescan(struct thread *td) struct filedesc *fdp; struct file *fp; struct pollfd *fd; +#ifdef CAPABILITIES + cap_rights_t rights; +#endif int n; n = 0; @@ -1373,7 +1387,8 @@ pollrescan(struct thread *td) fp = fdp->fd_ofiles[fd->fd].fde_file; #ifdef CAPABILITIES if (fp == NULL || - cap_check(cap_rights(fdp, fd->fd), CAP_POLL_EVENT) != 0) + cap_check(cap_rights(fdp, fd->fd), + cap_rights_init(&rights, CAP_POLL_EVENT)) != 0) #else if (fp == NULL) #endif @@ -1431,6 +1446,9 @@ pollscan(td, fds, nfd) { struct filedesc *fdp = td->td_proc->p_fd; struct file *fp; +#ifdef CAPABILITIES + cap_rights_t rights; +#endif int i, n = 0; FILEDESC_SLOCK(fdp); @@ -1445,7 +1463,7 @@ pollscan(td, fds, nfd) #ifdef CAPABILITIES if (fp == NULL || cap_check(cap_rights(fdp, fds->fd), - CAP_POLL_EVENT) != 0) + cap_rights_init(&rights, CAP_POLL_EVENT)) != 0) #else if (fp == NULL) #endif diff --git a/sys/kern/sys_pipe.c b/sys/kern/sys_pipe.c index 76c295eb71ba..6ba52e37c5f2 100644 --- a/sys/kern/sys_pipe.c +++ b/sys/kern/sys_pipe.c @@ -524,7 +524,7 @@ pipespace_new(cpipe, size) buffer = (caddr_t) vm_map_min(pipe_map); error = vm_map_find(pipe_map, NULL, 0, - (vm_offset_t *) &buffer, size, 1, + (vm_offset_t *) &buffer, size, 0, VMFS_ANY_SPACE, VM_PROT_ALL, VM_PROT_ALL, 0); if (error != KERN_SUCCESS) { if ((cpipe->pipe_buffer.buffer == NULL) && diff --git a/sys/kern/sys_procdesc.c b/sys/kern/sys_procdesc.c index bacaf182e1c2..4bafeabaab48 100644 --- a/sys/kern/sys_procdesc.c +++ b/sys/kern/sys_procdesc.c @@ -138,14 +138,14 @@ SYSINIT(vfs, SI_SUB_VFS, SI_ORDER_ANY, procdesc_init, NULL); * died. */ int -procdesc_find(struct thread *td, int fd, cap_rights_t rights, +procdesc_find(struct thread *td, int fd, cap_rights_t *rightsp, struct proc **p) { struct procdesc *pd; struct file *fp; int error; - error = fget(td, fd, rights, &fp); + error = fget(td, fd, rightsp, &fp); if (error) return (error); if (fp->f_type != DTYPE_PROCDESC) { @@ -185,12 +185,12 @@ procdesc_pid(struct file *fp_procdesc) * Retrieve the PID associated with a process descriptor. */ int -kern_pdgetpid(struct thread *td, int fd, cap_rights_t rights, pid_t *pidp) +kern_pdgetpid(struct thread *td, int fd, cap_rights_t *rightsp, pid_t *pidp) { struct file *fp; int error; - error = fget(td, fd, rights, &fp); + error = fget(td, fd, rightsp, &fp); if (error) return (error); if (fp->f_type != DTYPE_PROCDESC) { @@ -209,11 +209,13 @@ kern_pdgetpid(struct thread *td, int fd, cap_rights_t rights, pid_t *pidp) int sys_pdgetpid(struct thread *td, struct pdgetpid_args *uap) { + cap_rights_t rights; pid_t pid; int error; AUDIT_ARG_FD(uap->fd); - error = kern_pdgetpid(td, uap->fd, CAP_PDGETPID, &pid); + error = kern_pdgetpid(td, uap->fd, + cap_rights_init(&rights, CAP_PDGETPID), &pid); if (error == 0) error = copyout(&pid, uap->pidp, sizeof(pid)); return (error); diff --git a/sys/kern/syscalls.c b/sys/kern/syscalls.c index 17f5448559d0..f33087952eed 100644 --- a/sys/kern/syscalls.c +++ b/sys/kern/syscalls.c @@ -3,7 +3,7 @@ * * DO NOT EDIT-- this file is automatically generated. * $FreeBSD$ - * created from FreeBSD: head/sys/kern/syscalls.master 251526 2013-06-08 13:27:57Z glebius + * created from FreeBSD: head/sys/kern/syscalls.master 255219 2013-09-05 00:09:56Z pjd */ const char *syscallnames[] = { @@ -521,8 +521,8 @@ const char *syscallnames[] = { "msgctl", /* 511 = msgctl */ "shmctl", /* 512 = shmctl */ "lpathconf", /* 513 = lpathconf */ - "cap_new", /* 514 = cap_new */ - "cap_rights_get", /* 515 = cap_rights_get */ + "obs_cap_new", /* 514 = obsolete cap_new */ + "__cap_rights_get", /* 515 = __cap_rights_get */ "cap_enter", /* 516 = cap_enter */ "cap_getmode", /* 517 = cap_getmode */ "pdfork", /* 518 = pdfork */ diff --git a/sys/kern/syscalls.master b/sys/kern/syscalls.master index 789f95a5b4dd..e19e310578b6 100644 --- a/sys/kern/syscalls.master +++ b/sys/kern/syscalls.master @@ -917,9 +917,9 @@ 512 AUE_SHMCTL NOSTD { int shmctl(int shmid, int cmd, \ struct shmid_ds *buf); } 513 AUE_LPATHCONF STD { int lpathconf(char *path, int name); } -514 AUE_CAP_NEW STD { int cap_new(int fd, uint64_t rights); } -515 AUE_CAP_RIGHTS_GET STD { int cap_rights_get(int fd, \ - uint64_t *rightsp); } +514 AUE_NULL OBSOL cap_new +515 AUE_CAP_RIGHTS_GET STD { int __cap_rights_get(int version, \ + int fd, cap_rights_t *rightsp); } 516 AUE_CAP_ENTER STD { int cap_enter(void); } 517 AUE_CAP_GETMODE STD { int cap_getmode(u_int *modep); } 518 AUE_PDFORK STD { int pdfork(int *fdp, int flags); } @@ -957,7 +957,7 @@ struct __wrusage *wrusage, \ siginfo_t *info); } 533 AUE_CAP_RIGHTS_LIMIT STD { int cap_rights_limit(int fd, \ - uint64_t rights); } + cap_rights_t *rightsp); } 534 AUE_CAP_IOCTLS_LIMIT STD { int cap_ioctls_limit(int fd, \ const u_long *cmds, size_t ncmds); } 535 AUE_CAP_IOCTLS_GET STD { ssize_t cap_ioctls_get(int fd, \ diff --git a/sys/kern/systrace_args.c b/sys/kern/systrace_args.c index 59e046bd3529..0a6bae4275d7 100644 --- a/sys/kern/systrace_args.c +++ b/sys/kern/systrace_args.c @@ -3126,20 +3126,13 @@ systrace_args(int sysnum, void *params, uint64_t *uarg, int *n_args) *n_args = 2; break; } - /* cap_new */ - case 514: { - struct cap_new_args *p = params; - iarg[0] = p->fd; /* int */ - uarg[1] = p->rights; /* uint64_t */ - *n_args = 2; - break; - } - /* cap_rights_get */ + /* __cap_rights_get */ case 515: { - struct cap_rights_get_args *p = params; - iarg[0] = p->fd; /* int */ - uarg[1] = (intptr_t) p->rightsp; /* uint64_t * */ - *n_args = 2; + struct __cap_rights_get_args *p = params; + iarg[0] = p->version; /* int */ + iarg[1] = p->fd; /* int */ + uarg[2] = (intptr_t) p->rightsp; /* cap_rights_t * */ + *n_args = 3; break; } /* cap_enter */ @@ -3290,7 +3283,7 @@ systrace_args(int sysnum, void *params, uint64_t *uarg, int *n_args) case 533: { struct cap_rights_limit_args *p = params; iarg[0] = p->fd; /* int */ - uarg[1] = p->rights; /* uint64_t */ + uarg[1] = (intptr_t) p->rightsp; /* cap_rights_t * */ *n_args = 2; break; } @@ -8561,27 +8554,17 @@ systrace_entry_setargdesc(int sysnum, int ndx, char *desc, size_t descsz) break; }; break; - /* cap_new */ - case 514: - switch(ndx) { - case 0: - p = "int"; - break; - case 1: - p = "uint64_t"; - break; - default: - break; - }; - break; - /* cap_rights_get */ + /* __cap_rights_get */ case 515: switch(ndx) { case 0: p = "int"; break; case 1: - p = "uint64_t *"; + p = "int"; + break; + case 2: + p = "cap_rights_t *"; break; default: break; @@ -8849,7 +8832,7 @@ systrace_entry_setargdesc(int sysnum, int ndx, char *desc, size_t descsz) p = "int"; break; case 1: - p = "uint64_t"; + p = "cap_rights_t *"; break; default: break; @@ -10818,12 +10801,7 @@ systrace_return_setargdesc(int sysnum, int ndx, char *desc, size_t descsz) if (ndx == 0 || ndx == 1) p = "int"; break; - /* cap_new */ - case 514: - if (ndx == 0 || ndx == 1) - p = "int"; - break; - /* cap_rights_get */ + /* __cap_rights_get */ case 515: if (ndx == 0 || ndx == 1) p = "int"; diff --git a/sys/kern/sysv_shm.c b/sys/kern/sysv_shm.c index 90f5d7764fdc..ea44debd176f 100644 --- a/sys/kern/sysv_shm.c +++ b/sys/kern/sysv_shm.c @@ -413,7 +413,7 @@ kern_shmat(td, shmid, shmaddr, shmflg) vm_object_reference(shmseg->object); rv = vm_map_find(&p->p_vmspace->vm_map, shmseg->object, - 0, &attach_va, size, (flags & MAP_FIXED) ? VMFS_NO_SPACE : + 0, &attach_va, size, 0, (flags & MAP_FIXED) ? VMFS_NO_SPACE : VMFS_OPTIMAL_SPACE, prot, prot, MAP_INHERIT_SHARE); if (rv != KERN_SUCCESS) { vm_object_deallocate(shmseg->object); diff --git a/sys/kern/tty.c b/sys/kern/tty.c index 02eccd7ca0ff..4fce6072d652 100644 --- a/sys/kern/tty.c +++ b/sys/kern/tty.c @@ -1837,11 +1837,13 @@ ttyhook_register(struct tty **rtp, struct proc *p, int fd, struct cdev *dev; struct cdevsw *cdp; struct filedesc *fdp; + cap_rights_t rights; int error, ref; /* Validate the file descriptor. */ fdp = p->p_fd; - error = fget_unlocked(fdp, fd, CAP_TTYHOOK, 0, &fp, NULL); + error = fget_unlocked(fdp, fd, cap_rights_init(&rights, CAP_TTYHOOK), + 0, &fp, NULL); if (error != 0) return (error); if (fp->f_ops == &badfileops) { diff --git a/sys/kern/uipc_mqueue.c b/sys/kern/uipc_mqueue.c index 62c54d332593..fe7e88645b1d 100644 --- a/sys/kern/uipc_mqueue.c +++ b/sys/kern/uipc_mqueue.c @@ -2086,19 +2086,19 @@ sys_kmq_unlink(struct thread *td, struct kmq_unlink_args *uap) return (error); } -typedef int (*_fgetf)(struct thread *, int, cap_rights_t, struct file **); +typedef int (*_fgetf)(struct thread *, int, cap_rights_t *, struct file **); /* * Get message queue by giving file slot */ static int -_getmq(struct thread *td, int fd, cap_rights_t rights, _fgetf func, +_getmq(struct thread *td, int fd, cap_rights_t *rightsp, _fgetf func, struct file **fpp, struct mqfs_node **ppn, struct mqueue **pmq) { struct mqfs_node *pn; int error; - error = func(td, fd, rights, fpp); + error = func(td, fd, rightsp, fpp); if (error) return (error); if (&mqueueops != (*fpp)->f_ops) { @@ -2117,21 +2117,30 @@ static __inline int getmq(struct thread *td, int fd, struct file **fpp, struct mqfs_node **ppn, struct mqueue **pmq) { - return _getmq(td, fd, CAP_POLL_EVENT, fget, fpp, ppn, pmq); + cap_rights_t rights; + + return _getmq(td, fd, cap_rights_init(&rights, CAP_POLL_EVENT), fget, + fpp, ppn, pmq); } static __inline int getmq_read(struct thread *td, int fd, struct file **fpp, struct mqfs_node **ppn, struct mqueue **pmq) { - return _getmq(td, fd, CAP_READ, fget_read, fpp, ppn, pmq); + cap_rights_t rights; + + return _getmq(td, fd, cap_rights_init(&rights, CAP_READ), fget_read, + fpp, ppn, pmq); } static __inline int getmq_write(struct thread *td, int fd, struct file **fpp, struct mqfs_node **ppn, struct mqueue **pmq) { - return _getmq(td, fd, CAP_WRITE, fget_write, fpp, ppn, pmq); + cap_rights_t rights; + + return _getmq(td, fd, cap_rights_init(&rights, CAP_WRITE), fget_write, + fpp, ppn, pmq); } static int @@ -2238,6 +2247,9 @@ sys_kmq_timedsend(struct thread *td, struct kmq_timedsend_args *uap) static int kern_kmq_notify(struct thread *td, int mqd, struct sigevent *sigev) { +#ifdef CAPABILITIES + cap_rights_t rights; +#endif struct filedesc *fdp; struct proc *p; struct mqueue *mq; @@ -2269,7 +2281,8 @@ kern_kmq_notify(struct thread *td, int mqd, struct sigevent *sigev) goto out; } #ifdef CAPABILITIES - error = cap_check(cap_rights(fdp, mqd), CAP_POLL_EVENT); + error = cap_check(cap_rights(fdp, mqd), + cap_rights_init(&rights, CAP_POLL_EVENT)); if (error) { FILEDESC_SUNLOCK(fdp); goto out; diff --git a/sys/kern/uipc_sem.c b/sys/kern/uipc_sem.c index 8c86cc4611e5..f641654e8a5e 100644 --- a/sys/kern/uipc_sem.c +++ b/sys/kern/uipc_sem.c @@ -116,7 +116,7 @@ static int ksem_create(struct thread *td, const char *path, semid_t *semidp, mode_t mode, unsigned int value, int flags, int compat32); static void ksem_drop(struct ksem *ks); -static int ksem_get(struct thread *td, semid_t id, cap_rights_t rights, +static int ksem_get(struct thread *td, semid_t id, cap_rights_t *rightsp, struct file **fpp); static struct ksem *ksem_hold(struct ksem *ks); static void ksem_insert(char *path, Fnv32_t fnv, struct ksem *ks); @@ -600,13 +600,14 @@ ksem_create(struct thread *td, const char *name, semid_t *semidp, mode_t mode, } static int -ksem_get(struct thread *td, semid_t id, cap_rights_t rights, struct file **fpp) +ksem_get(struct thread *td, semid_t id, cap_rights_t *rightsp, + struct file **fpp) { struct ksem *ks; struct file *fp; int error; - error = fget(td, id, rights, &fp); + error = fget(td, id, rightsp, &fp); if (error) return (EINVAL); if (fp->f_type != DTYPE_SEM) { @@ -720,11 +721,13 @@ struct ksem_post_args { int sys_ksem_post(struct thread *td, struct ksem_post_args *uap) { + cap_rights_t rights; struct file *fp; struct ksem *ks; int error; - error = ksem_get(td, uap->id, CAP_SEM_POST, &fp); + error = ksem_get(td, uap->id, + cap_rights_init(&rights, CAP_SEM_POST), &fp); if (error) return (error); ks = fp->f_data; @@ -809,12 +812,13 @@ kern_sem_wait(struct thread *td, semid_t id, int tryflag, { struct timespec ts1, ts2; struct timeval tv; + cap_rights_t rights; struct file *fp; struct ksem *ks; int error; DP((">>> kern_sem_wait entered! pid=%d\n", (int)td->td_proc->p_pid)); - error = ksem_get(td, id, CAP_SEM_WAIT, &fp); + error = ksem_get(td, id, cap_rights_init(&rights, CAP_SEM_WAIT), &fp); if (error) return (error); ks = fp->f_data; @@ -876,11 +880,13 @@ struct ksem_getvalue_args { int sys_ksem_getvalue(struct thread *td, struct ksem_getvalue_args *uap) { + cap_rights_t rights; struct file *fp; struct ksem *ks; int error, val; - error = ksem_get(td, uap->id, CAP_SEM_GETVALUE, &fp); + error = ksem_get(td, uap->id, + cap_rights_init(&rights, CAP_SEM_GETVALUE), &fp); if (error) return (error); ks = fp->f_data; diff --git a/sys/kern/uipc_shm.c b/sys/kern/uipc_shm.c index 54366af5357f..70829f38f444 100644 --- a/sys/kern/uipc_shm.c +++ b/sys/kern/uipc_shm.c @@ -954,7 +954,7 @@ shm_map(struct file *fp, size_t size, off_t offset, void **memp) ofs = offset & PAGE_MASK; offset = trunc_page(offset); size = round_page(size + ofs); - rv = vm_map_find(kernel_map, obj, offset, &kva, size, + rv = vm_map_find(kernel_map, obj, offset, &kva, size, 0, VMFS_OPTIMAL_SPACE, VM_PROT_READ | VM_PROT_WRITE, VM_PROT_READ | VM_PROT_WRITE, 0); if (rv == KERN_SUCCESS) { diff --git a/sys/kern/uipc_syscalls.c b/sys/kern/uipc_syscalls.c index 72663a24cfd3..f88677c1ca25 100644 --- a/sys/kern/uipc_syscalls.c +++ b/sys/kern/uipc_syscalls.c @@ -164,13 +164,13 @@ SYSCTL_PROC(_kern_ipc, OID_AUTO, sfstat, CTLTYPE_OPAQUE | CTLFLAG_RW, * A reference on the file entry is held upon returning. */ static int -getsock_cap(struct filedesc *fdp, int fd, cap_rights_t rights, +getsock_cap(struct filedesc *fdp, int fd, cap_rights_t *rightsp, struct file **fpp, u_int *fflagp) { struct file *fp; int error; - error = fget_unlocked(fdp, fd, rights, 0, &fp, NULL); + error = fget_unlocked(fdp, fd, rightsp, 0, &fp, NULL); if (error != 0) return (error); if (fp->f_type != DTYPE_SOCKET) { @@ -220,16 +220,16 @@ sys_socket(td, uap) #ifdef MAC error = mac_socket_check_create(td->td_ucred, uap->domain, type, uap->protocol); - if (error) + if (error != 0) return (error); #endif error = falloc(td, &fp, &fd, oflag); - if (error) + if (error != 0) return (error); /* An extra reference on `fp' has been held for us by falloc(). */ error = socreate(uap->domain, &so, type, uap->protocol, td->td_ucred, td); - if (error) { + if (error != 0) { fdclose(td->td_proc->p_fd, fp, fd, td); } else { finit(fp, FREAD | FWRITE | fflag, DTYPE_SOCKET, so, &socketops); @@ -267,12 +267,14 @@ kern_bindat(struct thread *td, int dirfd, int fd, struct sockaddr *sa) { struct socket *so; struct file *fp; + cap_rights_t rights; int error; AUDIT_ARG_FD(fd); AUDIT_ARG_SOCKADDR(td, dirfd, sa); - error = getsock_cap(td->td_proc->p_fd, fd, CAP_BIND, &fp, NULL); - if (error) + error = getsock_cap(td->td_proc->p_fd, fd, + cap_rights_init(&rights, CAP_BIND), &fp, NULL); + if (error != 0) return (error); so = fp->f_data; #ifdef KTRACE @@ -334,10 +336,12 @@ sys_listen(td, uap) { struct socket *so; struct file *fp; + cap_rights_t rights; int error; AUDIT_ARG_FD(uap->s); - error = getsock_cap(td->td_proc->p_fd, uap->s, CAP_LISTEN, &fp, NULL); + error = getsock_cap(td->td_proc->p_fd, uap->s, + cap_rights_init(&rights, CAP_LISTEN), &fp, NULL); if (error == 0) { so = fp->f_data; #ifdef MAC @@ -370,7 +374,7 @@ accept1(td, s, uname, anamelen, flags) return (kern_accept4(td, s, NULL, NULL, flags, NULL)); error = copyin(anamelen, &namelen, sizeof (namelen)); - if (error) + if (error != 0) return (error); error = kern_accept4(td, s, &name, &namelen, flags, &fp); @@ -379,7 +383,7 @@ accept1(td, s, uname, anamelen, flags) * return a namelen of zero for older code which might * ignore the return value from accept. */ - if (error) { + if (error != 0) { (void) copyout(&namelen, anamelen, sizeof(*anamelen)); return (error); } @@ -395,7 +399,7 @@ accept1(td, s, uname, anamelen, flags) if (error == 0) error = copyout(&namelen, anamelen, sizeof(namelen)); - if (error) + if (error != 0) fdclose(td->td_proc->p_fd, fp, td->td_retval[0], td); fdrop(fp, td); free(name, M_SONAME); @@ -416,20 +420,20 @@ kern_accept4(struct thread *td, int s, struct sockaddr **name, struct filedesc *fdp; struct file *headfp, *nfp = NULL; struct sockaddr *sa = NULL; - int error; struct socket *head, *so; - int fd; + cap_rights_t rights; u_int fflag; pid_t pgid; - int tmp; + int error, fd, tmp; - if (name) + if (name != NULL) *name = NULL; AUDIT_ARG_FD(s); fdp = td->td_proc->p_fd; - error = getsock_cap(fdp, s, CAP_ACCEPT, &headfp, &fflag); - if (error) + error = getsock_cap(fdp, s, cap_rights_init(&rights, CAP_ACCEPT), + &headfp, &fflag); + if (error != 0) return (error); head = headfp->f_data; if ((head->so_options & SO_ACCEPTCONN) == 0) { @@ -442,7 +446,7 @@ kern_accept4(struct thread *td, int s, struct sockaddr **name, goto done; #endif error = falloc(td, &nfp, &fd, (flags & SOCK_CLOEXEC) ? O_CLOEXEC : 0); - if (error) + if (error != 0) goto done; ACCEPT_LOCK(); if ((head->so_state & SS_NBIO) && TAILQ_EMPTY(&head->so_comp)) { @@ -457,7 +461,7 @@ kern_accept4(struct thread *td, int s, struct sockaddr **name, } error = msleep(&head->so_timeo, &accept_mtx, PSOCK | PCATCH, "accept", 0); - if (error) { + if (error != 0) { ACCEPT_UNLOCK(); goto noconnection; } @@ -516,7 +520,7 @@ kern_accept4(struct thread *td, int s, struct sockaddr **name, (void) fo_ioctl(nfp, FIOASYNC, &tmp, td->td_ucred, td); sa = 0; error = soaccept(so, &sa); - if (error) { + if (error != 0) { /* * return a namelen of zero for older code which might * ignore the return value from accept. @@ -543,14 +547,13 @@ kern_accept4(struct thread *td, int s, struct sockaddr **name, sa = NULL; } noconnection: - if (sa) - free(sa, M_SONAME); + free(sa, M_SONAME); /* * close the new descriptor, assuming someone hasn't ripped it * out from under us. */ - if (error) + if (error != 0) fdclose(fdp, nfp, fd, td); /* @@ -585,6 +588,7 @@ sys_accept4(td, uap) struct thread *td; struct accept4_args *uap; { + if (uap->flags & ~(SOCK_CLOEXEC | SOCK_NONBLOCK)) return (EINVAL); @@ -629,13 +633,14 @@ kern_connectat(struct thread *td, int dirfd, int fd, struct sockaddr *sa) { struct socket *so; struct file *fp; - int error; - int interrupted = 0; + cap_rights_t rights; + int error, interrupted = 0; AUDIT_ARG_FD(fd); AUDIT_ARG_SOCKADDR(td, dirfd, sa); - error = getsock_cap(td->td_proc->p_fd, fd, CAP_CONNECT, &fp, NULL); - if (error) + error = getsock_cap(td->td_proc->p_fd, fd, + cap_rights_init(&rights, CAP_CONNECT), &fp, NULL); + if (error != 0) return (error); so = fp->f_data; if (so->so_state & SS_ISCONNECTING) { @@ -648,14 +653,14 @@ kern_connectat(struct thread *td, int dirfd, int fd, struct sockaddr *sa) #endif #ifdef MAC error = mac_socket_check_connect(td->td_ucred, so, sa); - if (error) + if (error != 0) goto bad; #endif if (dirfd == AT_FDCWD) error = soconnect(so, sa, td); else error = soconnectat(dirfd, so, sa, td); - if (error) + if (error != 0) goto bad; if ((so->so_state & SS_NBIO) && (so->so_state & SS_ISCONNECTING)) { error = EINPROGRESS; @@ -665,7 +670,7 @@ kern_connectat(struct thread *td, int dirfd, int fd, struct sockaddr *sa) while ((so->so_state & SS_ISCONNECTING) && so->so_error == 0) { error = msleep(&so->so_timeo, SOCK_MTX(so), PSOCK | PCATCH, "connec", 0); - if (error) { + if (error != 0) { if (error == EINTR || error == ERESTART) interrupted = 1; break; @@ -740,35 +745,35 @@ kern_socketpair(struct thread *td, int domain, int type, int protocol, /* We might want to have a separate check for socket pairs. */ error = mac_socket_check_create(td->td_ucred, domain, type, protocol); - if (error) + if (error != 0) return (error); #endif error = socreate(domain, &so1, type, protocol, td->td_ucred, td); - if (error) + if (error != 0) return (error); error = socreate(domain, &so2, type, protocol, td->td_ucred, td); - if (error) + if (error != 0) goto free1; /* On success extra reference to `fp1' and 'fp2' is set by falloc. */ error = falloc(td, &fp1, &fd, oflag); - if (error) + if (error != 0) goto free2; rsv[0] = fd; fp1->f_data = so1; /* so1 already has ref count */ error = falloc(td, &fp2, &fd, oflag); - if (error) + if (error != 0) goto free3; fp2->f_data = so2; /* so2 already has ref count */ rsv[1] = fd; error = soconnect2(so1, so2); - if (error) + if (error != 0) goto free4; if (type == SOCK_DGRAM) { /* * Datagram socket connection is asymmetric. */ error = soconnect2(so2, so1); - if (error) + if (error != 0) goto free4; } finit(fp1, FREAD | FWRITE | fflag, DTYPE_SOCKET, fp1->f_data, @@ -804,10 +809,10 @@ sys_socketpair(struct thread *td, struct socketpair_args *uap) error = kern_socketpair(td, uap->domain, uap->type, uap->protocol, sv); - if (error) + if (error != 0) return (error); error = copyout(sv, uap->rsv, 2 * sizeof(int)); - if (error) { + if (error != 0) { (void)kern_close(td, sv[0]); (void)kern_close(td, sv[1]); } @@ -832,7 +837,7 @@ sendit(td, s, mp, flags) if (mp->msg_name != NULL) { error = getsockaddr(&to, mp->msg_name, mp->msg_namelen); - if (error) { + if (error != 0) { to = NULL; goto bad; } @@ -852,7 +857,7 @@ sendit(td, s, mp, flags) } error = sockargs(&control, mp->msg_control, mp->msg_controllen, MT_CONTROL); - if (error) + if (error != 0) goto bad; #ifdef COMPAT_OLDSOCK if (mp->msg_flags == MSG_COMPAT) { @@ -872,8 +877,7 @@ sendit(td, s, mp, flags) error = kern_sendit(td, s, mp, flags, control, UIO_USERSPACE); bad: - if (to) - free(to, M_SONAME); + free(to, M_SONAME); return (error); } @@ -890,21 +894,21 @@ kern_sendit(td, s, mp, flags, control, segflg) struct uio auio; struct iovec *iov; struct socket *so; - int i, error; - ssize_t len; cap_rights_t rights; #ifdef KTRACE struct uio *ktruio = NULL; #endif + ssize_t len; + int i, error; AUDIT_ARG_FD(s); - rights = CAP_SEND; + cap_rights_init(&rights, CAP_SEND); if (mp->msg_name != NULL) { AUDIT_ARG_SOCKADDR(td, AT_FDCWD, mp->msg_name); - rights |= CAP_CONNECT; + cap_rights_set(&rights, CAP_CONNECT); } - error = getsock_cap(td->td_proc->p_fd, s, rights, &fp, NULL); - if (error) + error = getsock_cap(td->td_proc->p_fd, s, &rights, &fp, NULL); + if (error != 0) return (error); so = (struct socket *)fp->f_data; @@ -916,11 +920,11 @@ kern_sendit(td, s, mp, flags, control, segflg) if (mp->msg_name != NULL) { error = mac_socket_check_connect(td->td_ucred, so, mp->msg_name); - if (error) + if (error != 0) goto bad; } error = mac_socket_check_send(td->td_ucred, so); - if (error) + if (error != 0) goto bad; #endif @@ -944,7 +948,7 @@ kern_sendit(td, s, mp, flags, control, segflg) #endif len = auio.uio_resid; error = sosend(so, mp->msg_name, &auio, 0, control, flags, td); - if (error) { + if (error != 0) { if (auio.uio_resid != len && (error == ERESTART || error == EINTR || error == EWOULDBLOCK)) error = 0; @@ -983,7 +987,6 @@ sys_sendto(td, uap) { struct msghdr msg; struct iovec aiov; - int error; msg.msg_name = uap->to; msg.msg_namelen = uap->tolen; @@ -995,8 +998,7 @@ sys_sendto(td, uap) #endif aiov.iov_base = uap->buf; aiov.iov_len = uap->len; - error = sendit(td, uap->s, &msg, uap->flags); - return (error); + return (sendit(td, uap->s, &msg, uap->flags)); } #ifdef COMPAT_OLDSOCK @@ -1012,7 +1014,6 @@ osend(td, uap) { struct msghdr msg; struct iovec aiov; - int error; msg.msg_name = 0; msg.msg_namelen = 0; @@ -1022,8 +1023,7 @@ osend(td, uap) aiov.iov_len = uap->len; msg.msg_control = 0; msg.msg_flags = 0; - error = sendit(td, uap->s, &msg, uap->flags); - return (error); + return (sendit(td, uap->s, &msg, uap->flags)); } int @@ -1040,10 +1040,10 @@ osendmsg(td, uap) int error; error = copyin(uap->msg, &msg, sizeof (struct omsghdr)); - if (error) + if (error != 0) return (error); error = copyiniov(msg.msg_iov, msg.msg_iovlen, &iov, EMSGSIZE); - if (error) + if (error != 0) return (error); msg.msg_iov = iov; msg.msg_flags = MSG_COMPAT; @@ -1067,10 +1067,10 @@ sys_sendmsg(td, uap) int error; error = copyin(uap->msg, &msg, sizeof (msg)); - if (error) + if (error != 0) return (error); error = copyiniov(msg.msg_iov, msg.msg_iovlen, &iov, EMSGSIZE); - if (error) + if (error != 0) return (error); msg.msg_iov = iov; #ifdef COMPAT_OLDSOCK @@ -1091,30 +1091,31 @@ kern_recvit(td, s, mp, fromseg, controlp) { struct uio auio; struct iovec *iov; - int i; - ssize_t len; - int error; struct mbuf *m, *control = NULL; caddr_t ctlbuf; struct file *fp; struct socket *so; struct sockaddr *fromsa = NULL; + cap_rights_t rights; #ifdef KTRACE struct uio *ktruio = NULL; #endif + ssize_t len; + int error, i; if (controlp != NULL) *controlp = NULL; AUDIT_ARG_FD(s); - error = getsock_cap(td->td_proc->p_fd, s, CAP_RECV, &fp, NULL); - if (error) + error = getsock_cap(td->td_proc->p_fd, s, + cap_rights_init(&rights, CAP_RECV), &fp, NULL); + if (error != 0) return (error); so = fp->f_data; #ifdef MAC error = mac_socket_check_receive(td->td_ucred, so); - if (error) { + if (error != 0) { fdrop(fp, td); return (error); } @@ -1142,7 +1143,7 @@ kern_recvit(td, s, mp, fromseg, controlp) error = soreceive(so, &fromsa, &auio, NULL, (mp->msg_control || controlp) ? &control : NULL, &mp->msg_flags); - if (error) { + if (error != 0) { if (auio.uio_resid != len && (error == ERESTART || error == EINTR || error == EWOULDBLOCK)) error = 0; @@ -1155,7 +1156,7 @@ kern_recvit(td, s, mp, fromseg, controlp) ktrgenio(s, UIO_READ, ktruio, error); } #endif - if (error) + if (error != 0) goto out; td->td_retval[0] = len - auio.uio_resid; if (mp->msg_name) { @@ -1173,7 +1174,7 @@ kern_recvit(td, s, mp, fromseg, controlp) if (fromseg == UIO_USERSPACE) { error = copyout(fromsa, mp->msg_name, (unsigned)len); - if (error) + if (error != 0) goto out; } else bcopy(fromsa, mp->msg_name, len); @@ -1232,8 +1233,7 @@ kern_recvit(td, s, mp, fromseg, controlp) if (fromsa && KTRPOINT(td, KTR_STRUCT)) ktrsockaddr(fromsa); #endif - if (fromsa) - free(fromsa, M_SONAME); + free(fromsa, M_SONAME); if (error == 0 && controlp != NULL) *controlp = control; @@ -1253,9 +1253,9 @@ recvit(td, s, mp, namelenp) int error; error = kern_recvit(td, s, mp, UIO_USERSPACE, NULL); - if (error) + if (error != 0) return (error); - if (namelenp) { + if (namelenp != NULL) { error = copyout(&mp->msg_namelen, namelenp, sizeof (socklen_t)); #ifdef COMPAT_OLDSOCK if (mp->msg_flags & MSG_COMPAT) @@ -1284,7 +1284,7 @@ sys_recvfrom(td, uap) if (uap->fromlenaddr) { error = copyin(uap->fromlenaddr, &msg.msg_namelen, sizeof (msg.msg_namelen)); - if (error) + if (error != 0) goto done2; } else { msg.msg_namelen = 0; @@ -1298,7 +1298,7 @@ sys_recvfrom(td, uap) msg.msg_flags = uap->flags; error = recvit(td, uap->s, &msg, uap->fromlenaddr); done2: - return(error); + return (error); } #ifdef COMPAT_OLDSOCK @@ -1326,7 +1326,6 @@ orecv(td, uap) { struct msghdr msg; struct iovec aiov; - int error; msg.msg_name = 0; msg.msg_namelen = 0; @@ -1336,8 +1335,7 @@ orecv(td, uap) aiov.iov_len = uap->len; msg.msg_control = 0; msg.msg_flags = uap->flags; - error = recvit(td, uap->s, &msg, NULL); - return (error); + return (recvit(td, uap->s, &msg, NULL)); } /* @@ -1359,10 +1357,10 @@ orecvmsg(td, uap) int error; error = copyin(uap->msg, &msg, sizeof (struct omsghdr)); - if (error) + if (error != 0) return (error); error = copyiniov(msg.msg_iov, msg.msg_iovlen, &iov, EMSGSIZE); - if (error) + if (error != 0) return (error); msg.msg_flags = uap->flags | MSG_COMPAT; msg.msg_iov = iov; @@ -1389,10 +1387,10 @@ sys_recvmsg(td, uap) int error; error = copyin(uap->msg, &msg, sizeof (msg)); - if (error) + if (error != 0) return (error); error = copyiniov(msg.msg_iov, msg.msg_iovlen, &iov, EMSGSIZE); - if (error) + if (error != 0) return (error); msg.msg_flags = uap->flags; #ifdef COMPAT_OLDSOCK @@ -1420,11 +1418,12 @@ sys_shutdown(td, uap) { struct socket *so; struct file *fp; + cap_rights_t rights; int error; AUDIT_ARG_FD(uap->s); - error = getsock_cap(td->td_proc->p_fd, uap->s, CAP_SHUTDOWN, &fp, - NULL); + error = getsock_cap(td->td_proc->p_fd, uap->s, + cap_rights_init(&rights, CAP_SHUTDOWN), &fp, NULL); if (error == 0) { so = fp->f_data; error = soshutdown(so, uap->how); @@ -1460,10 +1459,11 @@ kern_setsockopt(td, s, level, name, val, valseg, valsize) enum uio_seg valseg; socklen_t valsize; { - int error; struct socket *so; struct file *fp; struct sockopt sopt; + cap_rights_t rights; + int error; if (val == NULL && valsize != 0) return (EFAULT); @@ -1487,7 +1487,8 @@ kern_setsockopt(td, s, level, name, val, valseg, valsize) } AUDIT_ARG_FD(s); - error = getsock_cap(td->td_proc->p_fd, s, CAP_SETSOCKOPT, &fp, NULL); + error = getsock_cap(td->td_proc->p_fd, s, + cap_rights_init(&rights, CAP_SETSOCKOPT), &fp, NULL); if (error == 0) { so = fp->f_data; error = sosetopt(so, &sopt); @@ -1509,11 +1510,11 @@ sys_getsockopt(td, uap) } */ *uap; { socklen_t valsize; - int error; + int error; if (uap->val) { error = copyin(uap->avalsize, &valsize, sizeof (valsize)); - if (error) + if (error != 0) return (error); } @@ -1539,10 +1540,11 @@ kern_getsockopt(td, s, level, name, val, valseg, valsize) enum uio_seg valseg; socklen_t *valsize; { - int error; - struct socket *so; + struct socket *so; struct file *fp; - struct sockopt sopt; + struct sockopt sopt; + cap_rights_t rights; + int error; if (val == NULL) *valsize = 0; @@ -1566,7 +1568,8 @@ kern_getsockopt(td, s, level, name, val, valseg, valsize) } AUDIT_ARG_FD(s); - error = getsock_cap(td->td_proc->p_fd, s, CAP_GETSOCKOPT, &fp, NULL); + error = getsock_cap(td->td_proc->p_fd, s, + cap_rights_init(&rights, CAP_GETSOCKOPT), &fp, NULL); if (error == 0) { so = fp->f_data; error = sogetopt(so, &sopt); @@ -1595,11 +1598,11 @@ getsockname1(td, uap, compat) int error; error = copyin(uap->alen, &len, sizeof(len)); - if (error) + if (error != 0) return (error); error = kern_getsockname(td, uap->fdes, &sa, &len); - if (error) + if (error != 0) return (error); if (len != 0) { @@ -1621,19 +1624,21 @@ kern_getsockname(struct thread *td, int fd, struct sockaddr **sa, { struct socket *so; struct file *fp; + cap_rights_t rights; socklen_t len; int error; AUDIT_ARG_FD(fd); - error = getsock_cap(td->td_proc->p_fd, fd, CAP_GETSOCKNAME, &fp, NULL); - if (error) + error = getsock_cap(td->td_proc->p_fd, fd, + cap_rights_init(&rights, CAP_GETSOCKNAME), &fp, NULL); + if (error != 0) return (error); so = fp->f_data; *sa = NULL; CURVNET_SET(so->so_vnet); error = (*so->so_proto->pr_usrreqs->pru_sockaddr)(so, sa); CURVNET_RESTORE(); - if (error) + if (error != 0) goto bad; if (*sa == NULL) len = 0; @@ -1646,7 +1651,7 @@ kern_getsockname(struct thread *td, int fd, struct sockaddr **sa, #endif bad: fdrop(fp, td); - if (error && *sa) { + if (error != 0 && *sa != NULL) { free(*sa, M_SONAME); *sa = NULL; } @@ -1692,11 +1697,11 @@ getpeername1(td, uap, compat) int error; error = copyin(uap->alen, &len, sizeof (len)); - if (error) + if (error != 0) return (error); error = kern_getpeername(td, uap->fdes, &sa, &len); - if (error) + if (error != 0) return (error); if (len != 0) { @@ -1718,12 +1723,14 @@ kern_getpeername(struct thread *td, int fd, struct sockaddr **sa, { struct socket *so; struct file *fp; + cap_rights_t rights; socklen_t len; int error; AUDIT_ARG_FD(fd); - error = getsock_cap(td->td_proc->p_fd, fd, CAP_GETPEERNAME, &fp, NULL); - if (error) + error = getsock_cap(td->td_proc->p_fd, fd, + cap_rights_init(&rights, CAP_GETPEERNAME), &fp, NULL); + if (error != 0) return (error); so = fp->f_data; if ((so->so_state & (SS_ISCONNECTED|SS_ISCONFIRMING)) == 0) { @@ -1734,7 +1741,7 @@ kern_getpeername(struct thread *td, int fd, struct sockaddr **sa, CURVNET_SET(so->so_vnet); error = (*so->so_proto->pr_usrreqs->pru_peeraddr)(so, sa); CURVNET_RESTORE(); - if (error) + if (error != 0) goto bad; if (*sa == NULL) len = 0; @@ -1746,7 +1753,7 @@ kern_getpeername(struct thread *td, int fd, struct sockaddr **sa, ktrsockaddr(*sa); #endif bad: - if (error && *sa) { + if (error != 0 && *sa != NULL) { free(*sa, M_SONAME); *sa = NULL; } @@ -1798,7 +1805,7 @@ sockargs(mp, buf, buflen, type) m = m_get2(buflen, M_WAITOK, type, 0); m->m_len = buflen; error = copyin(buf, mtod(m, caddr_t), (u_int)buflen); - if (error) + if (error != 0) (void) m_free(m); else { *mp = m; @@ -1830,7 +1837,7 @@ getsockaddr(namp, uaddr, len) return (EINVAL); sa = malloc(len, M_SONAME, M_WAITOK); error = copyin(uaddr, sa, len); - if (error) { + if (error != 0) { free(sa, M_SONAME); } else { #if defined(COMPAT_OLDSOCK) && BYTE_ORDER != BIG_ENDIAN @@ -1907,6 +1914,7 @@ do_sendfile(struct thread *td, struct sendfile_args *uap, int compat) struct sf_hdtr hdtr; struct uio *hdr_uio, *trl_uio; struct file *fp; + cap_rights_t rights; int error; if (uap->offset < 0) @@ -1916,16 +1924,16 @@ do_sendfile(struct thread *td, struct sendfile_args *uap, int compat) if (uap->hdtr != NULL) { error = copyin(uap->hdtr, &hdtr, sizeof(hdtr)); - if (error) + if (error != 0) goto out; if (hdtr.headers != NULL) { error = copyinuio(hdtr.headers, hdtr.hdr_cnt, &hdr_uio); - if (error) + if (error != 0) goto out; } if (hdtr.trailers != NULL) { error = copyinuio(hdtr.trailers, hdtr.trl_cnt, &trl_uio); - if (error) + if (error != 0) goto out; } @@ -1937,18 +1945,18 @@ do_sendfile(struct thread *td, struct sendfile_args *uap, int compat) * sendfile(2) can start at any offset within a file so we require * CAP_READ+CAP_SEEK = CAP_PREAD. */ - if ((error = fget_read(td, uap->fd, CAP_PREAD, &fp)) != 0) + if ((error = fget_read(td, uap->fd, + cap_rights_init(&rights, CAP_PREAD), &fp)) != 0) { goto out; + } error = fo_sendfile(fp, uap->s, hdr_uio, trl_uio, uap->offset, uap->nbytes, uap->sbytes, uap->flags, compat ? SFK_COMPAT : 0, td); fdrop(fp, td); out: - if (hdr_uio) - free(hdr_uio, M_IOV); - if (trl_uio) - free(trl_uio, M_IOV); + free(hdr_uio, M_IOV); + free(trl_uio, M_IOV); return (error); } @@ -1983,10 +1991,10 @@ vn_sendfile(struct file *fp, int sockfd, struct uio *hdr_uio, struct sf_buf *sf; struct vm_page *pg; struct vattr va; - off_t off, xfsize, fsbytes = 0, sbytes = 0, rem = 0; - int error, hdrlen = 0, mnw = 0; - int bsize; struct sendfile_sync *sfs = NULL; + cap_rights_t rights; + off_t off, xfsize, fsbytes = 0, sbytes = 0, rem = 0; + int bsize, error, hdrlen = 0, mnw = 0; vn_lock(vp, LK_SHARED | LK_RETRY); if (vp->v_type == VREG) { @@ -2030,8 +2038,9 @@ vn_sendfile(struct file *fp, int sockfd, struct uio *hdr_uio, * The socket must be a stream socket and connected. * Remember if it a blocking or non-blocking socket. */ - if ((error = getsock_cap(td->td_proc->p_fd, sockfd, CAP_SEND, - &sock_fp, NULL)) != 0) + error = getsock_cap(td->td_proc->p_fd, sockfd, + cap_rights_init(&rights, CAP_SEND), &sock_fp, NULL); + if (error != 0) goto out; so = sock_fp->f_data; if (so->so_type != SOCK_STREAM) { @@ -2058,7 +2067,7 @@ vn_sendfile(struct file *fp, int sockfd, struct uio *hdr_uio, #ifdef MAC error = mac_socket_check_send(td->td_ucred, so); - if (error) + if (error != 0) goto out; #endif @@ -2173,7 +2182,7 @@ vn_sendfile(struct file *fp, int sockfd, struct uio *hdr_uio, * been interrupted by a signal. If we've sent anything * then return bytes sent, otherwise return the error. */ - if (error) { + if (error != 0) { SOCKBUF_UNLOCK(&so->so_snd); goto done; } @@ -2212,11 +2221,10 @@ vn_sendfile(struct file *fp, int sockfd, struct uio *hdr_uio, * or the passed in nbytes. */ pgoff = (vm_offset_t)(off & PAGE_MASK); - if (nbytes) - rem = (nbytes - fsbytes - loopbytes); - else - rem = va.va_size - - offset - fsbytes - loopbytes; + rem = va.va_size - offset; + if (nbytes != 0) + rem = omin(rem, nbytes); + rem -= fsbytes + loopbytes; xfsize = omin(PAGE_SIZE - pgoff, rem); xfsize = omin(space - loopbytes, xfsize); if (xfsize <= 0) { @@ -2265,10 +2273,10 @@ vn_sendfile(struct file *fp, int sockfd, struct uio *hdr_uio, IO_VMIO | ((readahead / bsize) << IO_SEQSHIFT), td->td_ucred, NOCRED, &resid, td); SFSTAT_INC(sf_iocnt); - if (error) + if (error != 0) VM_OBJECT_WLOCK(obj); } - if (error) { + if (error != 0) { vm_page_lock(pg); vm_page_unwire(pg, 0); /* @@ -2393,7 +2401,7 @@ vn_sendfile(struct file *fp, int sockfd, struct uio *hdr_uio, /* Quit outer loop on error or when we're done. */ if (done) break; - if (error) + if (error != 0) goto done; } @@ -2460,21 +2468,22 @@ sys_sctp_peeloff(td, uap) { #if (defined(INET) || defined(INET6)) && defined(SCTP) struct file *nfp = NULL; - int error; struct socket *head, *so; - int fd; + cap_rights_t rights; u_int fflag; + int error, fd; AUDIT_ARG_FD(uap->sd); - error = fgetsock(td, uap->sd, CAP_PEELOFF, &head, &fflag); - if (error) + error = fgetsock(td, uap->sd, cap_rights_init(&rights, CAP_PEELOFF), + &head, &fflag); + if (error != 0) goto done2; if (head->so_proto->pr_protocol != IPPROTO_SCTP) { error = EOPNOTSUPP; goto done; } error = sctp_can_peel_off(head, (sctp_assoc_t)uap->name); - if (error) + if (error != 0) goto done; /* * At this point we know we do have a assoc to pull @@ -2483,7 +2492,7 @@ sys_sctp_peeloff(td, uap) */ error = falloc(td, &nfp, &fd, 0); - if (error) + if (error != 0) goto done; td->td_retval[0] = fd; @@ -2513,7 +2522,7 @@ sys_sctp_peeloff(td, uap) ACCEPT_UNLOCK(); finit(nfp, fflag, DTYPE_SOCKET, so, &socketops); error = sctp_do_peeloff(head, so, (sctp_assoc_t)uap->name); - if (error) + if (error != 0) goto noconnection; if (head->so_sigio != NULL) fsetown(fgetown(&head->so_sigio), &so->so_sigio); @@ -2523,7 +2532,7 @@ sys_sctp_peeloff(td, uap) * close the new descriptor, assuming someone hasn't ripped it * out from under us. */ - if (error) + if (error != 0) fdclose(td->td_proc->p_fd, nfp, fd, td); /* @@ -2558,7 +2567,6 @@ sys_sctp_generic_sendmsg (td, uap) struct sctp_sndrcvinfo sinfo, *u_sinfo = NULL; struct socket *so; struct file *fp = NULL; - int error = 0, len; struct sockaddr *to = NULL; #ifdef KTRACE struct uio *ktruio = NULL; @@ -2566,27 +2574,28 @@ sys_sctp_generic_sendmsg (td, uap) struct uio auio; struct iovec iov[1]; cap_rights_t rights; + int error = 0, len; - if (uap->sinfo) { + if (uap->sinfo != NULL) { error = copyin(uap->sinfo, &sinfo, sizeof (sinfo)); - if (error) + if (error != 0) return (error); u_sinfo = &sinfo; } - rights = CAP_SEND; - if (uap->tolen) { + cap_rights_init(&rights, CAP_SEND); + if (uap->tolen != 0) { error = getsockaddr(&to, uap->to, uap->tolen); - if (error) { + if (error != 0) { to = NULL; goto sctp_bad2; } - rights |= CAP_CONNECT; + cap_rights_set(&rights, CAP_CONNECT); } AUDIT_ARG_FD(uap->sd); - error = getsock_cap(td->td_proc->p_fd, uap->sd, rights, &fp, NULL); - if (error) + error = getsock_cap(td->td_proc->p_fd, uap->sd, &rights, &fp, NULL); + if (error != 0) goto sctp_bad; #ifdef KTRACE if (to && (KTRPOINT(td, KTR_STRUCT))) @@ -2603,7 +2612,7 @@ sys_sctp_generic_sendmsg (td, uap) } #ifdef MAC error = mac_socket_check_send(td->td_ucred, so); - if (error) + if (error != 0) goto sctp_bad; #endif /* MAC */ @@ -2616,11 +2625,10 @@ sys_sctp_generic_sendmsg (td, uap) auio.uio_resid = 0; len = auio.uio_resid = uap->mlen; CURVNET_SET(so->so_vnet); - error = sctp_lower_sosend(so, to, &auio, - (struct mbuf *)NULL, (struct mbuf *)NULL, - uap->flags, u_sinfo, td); + error = sctp_lower_sosend(so, to, &auio, (struct mbuf *)NULL, + (struct mbuf *)NULL, uap->flags, u_sinfo, td); CURVNET_RESTORE(); - if (error) { + if (error != 0) { if (auio.uio_resid != len && (error == ERESTART || error == EINTR || error == EWOULDBLOCK)) error = 0; @@ -2641,11 +2649,10 @@ sys_sctp_generic_sendmsg (td, uap) } #endif /* KTRACE */ sctp_bad: - if (fp) + if (fp != NULL) fdrop(fp, td); sctp_bad2: - if (to) - free(to, M_SONAME); + free(to, M_SONAME); return (error); #else /* SCTP */ return (EOPNOTSUPP); @@ -2669,8 +2676,6 @@ sys_sctp_generic_sendmsg_iov(td, uap) struct sctp_sndrcvinfo sinfo, *u_sinfo = NULL; struct socket *so; struct file *fp = NULL; - int error=0, i; - ssize_t len; struct sockaddr *to = NULL; #ifdef KTRACE struct uio *ktruio = NULL; @@ -2678,26 +2683,28 @@ sys_sctp_generic_sendmsg_iov(td, uap) struct uio auio; struct iovec *iov, *tiov; cap_rights_t rights; + ssize_t len; + int error, i; - if (uap->sinfo) { + if (uap->sinfo != NULL) { error = copyin(uap->sinfo, &sinfo, sizeof (sinfo)); - if (error) + if (error != 0) return (error); u_sinfo = &sinfo; } - rights = CAP_SEND; - if (uap->tolen) { + cap_rights_init(&rights, CAP_SEND); + if (uap->tolen != 0) { error = getsockaddr(&to, uap->to, uap->tolen); - if (error) { + if (error != 0) { to = NULL; goto sctp_bad2; } - rights |= CAP_CONNECT; + cap_rights_set(&rights, CAP_CONNECT); } AUDIT_ARG_FD(uap->sd); - error = getsock_cap(td->td_proc->p_fd, uap->sd, rights, &fp, NULL); - if (error) + error = getsock_cap(td->td_proc->p_fd, uap->sd, &rights, &fp, NULL); + if (error != 0) goto sctp_bad1; #ifdef COMPAT_FREEBSD32 @@ -2707,7 +2714,7 @@ sys_sctp_generic_sendmsg_iov(td, uap) else #endif error = copyiniov(uap->iov, uap->iovlen, &iov, EMSGSIZE); - if (error) + if (error != 0) goto sctp_bad1; #ifdef KTRACE if (to && (KTRPOINT(td, KTR_STRUCT))) @@ -2721,7 +2728,7 @@ sys_sctp_generic_sendmsg_iov(td, uap) } #ifdef MAC error = mac_socket_check_send(td->td_ucred, so); - if (error) + if (error != 0) goto sctp_bad; #endif /* MAC */ @@ -2745,7 +2752,7 @@ sys_sctp_generic_sendmsg_iov(td, uap) (struct mbuf *)NULL, (struct mbuf *)NULL, uap->flags, u_sinfo, td); CURVNET_RESTORE(); - if (error) { + if (error != 0) { if (auio.uio_resid != len && (error == ERESTART || error == EINTR || error == EWOULDBLOCK)) error = 0; @@ -2768,11 +2775,10 @@ sys_sctp_generic_sendmsg_iov(td, uap) sctp_bad: free(iov, M_IOV); sctp_bad1: - if (fp) + if (fp != NULL) fdrop(fp, td); sctp_bad2: - if (to) - free(to, M_SONAME); + free(to, M_SONAME); return (error); #else /* SCTP */ return (EOPNOTSUPP); @@ -2800,19 +2806,18 @@ sys_sctp_generic_recvmsg(td, uap) struct socket *so; struct file *fp = NULL; struct sockaddr *fromsa; - int fromlen; - ssize_t len; - int i, msg_flags; - int error = 0; + cap_rights_t rights; #ifdef KTRACE struct uio *ktruio = NULL; #endif + ssize_t len; + int error, fromlen, i, msg_flags; AUDIT_ARG_FD(uap->sd); - error = getsock_cap(td->td_proc->p_fd, uap->sd, CAP_RECV, &fp, NULL); - if (error) { + error = getsock_cap(td->td_proc->p_fd, uap->sd, + cap_rights_init(&rights, CAP_RECV), &fp, NULL); + if (error != 0) return (error); - } #ifdef COMPAT_FREEBSD32 if (SV_CURPROC_FLAG(SV_ILP32)) error = freebsd32_copyiniov((struct iovec32 *)uap->iov, @@ -2820,7 +2825,7 @@ sys_sctp_generic_recvmsg(td, uap) else #endif error = copyiniov(uap->iov, uap->iovlen, &iov, EMSGSIZE); - if (error) + if (error != 0) goto out1; so = fp->f_data; @@ -2830,25 +2835,21 @@ sys_sctp_generic_recvmsg(td, uap) } #ifdef MAC error = mac_socket_check_receive(td->td_ucred, so); - if (error) { + if (error != 0) goto out; - } #endif /* MAC */ - if (uap->fromlenaddr) { - error = copyin(uap->fromlenaddr, - &fromlen, sizeof (fromlen)); - if (error) { + if (uap->fromlenaddr != NULL) { + error = copyin(uap->fromlenaddr, &fromlen, sizeof (fromlen)); + if (error != 0) goto out; - } } else { fromlen = 0; } if (uap->msg_flags) { error = copyin(uap->msg_flags, &msg_flags, sizeof (int)); - if (error) { + if (error != 0) goto out; - } } else { msg_flags = 0; } @@ -2879,7 +2880,7 @@ sys_sctp_generic_recvmsg(td, uap) fromsa, fromlen, &msg_flags, (struct sctp_sndrcvinfo *)&sinfo, 1); CURVNET_RESTORE(); - if (error) { + if (error != 0) { if (auio.uio_resid != len && (error == ERESTART || error == EINTR || error == EWOULDBLOCK)) error = 0; @@ -2893,7 +2894,7 @@ sys_sctp_generic_recvmsg(td, uap) ktrgenio(uap->sd, UIO_READ, ktruio, error); } #endif /* KTRACE */ - if (error) + if (error != 0) goto out; td->td_retval[0] = len - auio.uio_resid; @@ -2904,13 +2905,12 @@ sys_sctp_generic_recvmsg(td, uap) else { len = MIN(len, fromsa->sa_len); error = copyout(fromsa, uap->from, (size_t)len); - if (error) + if (error != 0) goto out; } error = copyout(&len, uap->fromlenaddr, sizeof (socklen_t)); - if (error) { + if (error != 0) goto out; - } } #ifdef KTRACE if (KTRPOINT(td, KTR_STRUCT)) @@ -2918,14 +2918,13 @@ sys_sctp_generic_recvmsg(td, uap) #endif if (uap->msg_flags) { error = copyout(&msg_flags, uap->msg_flags, sizeof (int)); - if (error) { + if (error != 0) goto out; - } } out: free(iov, M_IOV); out1: - if (fp) + if (fp != NULL) fdrop(fp, td); return (error); diff --git a/sys/kern/uipc_usrreq.c b/sys/kern/uipc_usrreq.c index 7a4db04130fe..c0a5d2eb5f40 100644 --- a/sys/kern/uipc_usrreq.c +++ b/sys/kern/uipc_usrreq.c @@ -464,6 +464,7 @@ uipc_bindat(int fd, struct socket *so, struct sockaddr *nam, struct thread *td) struct unpcb *unp; struct vnode *vp; struct mount *mp; + cap_rights_t rights; char *buf; unp = sotounpcb(so); @@ -502,7 +503,7 @@ uipc_bindat(int fd, struct socket *so, struct sockaddr *nam, struct thread *td) restart: NDINIT_ATRIGHTS(&nd, CREATE, NOFOLLOW | LOCKPARENT | SAVENAME, - UIO_SYSSPACE, buf, fd, CAP_BINDAT, td); + UIO_SYSSPACE, buf, fd, cap_rights_init(&rights, CAP_BINDAT), td); /* SHOULD BE ABLE TO ADOPT EXISTING AND wakeup() ALA FIFO's */ error = namei(&nd); if (error) @@ -1276,10 +1277,11 @@ unp_connectat(int fd, struct socket *so, struct sockaddr *nam, struct vnode *vp; struct socket *so2, *so3; struct unpcb *unp, *unp2, *unp3; - int error, len; struct nameidata nd; char buf[SOCK_MAXADDRLEN]; struct sockaddr *sa; + cap_rights_t rights; + int error, len; UNP_LINK_WLOCK_ASSERT(); @@ -1305,7 +1307,7 @@ unp_connectat(int fd, struct socket *so, struct sockaddr *nam, sa = malloc(sizeof(struct sockaddr_un), M_SONAME, M_WAITOK); NDINIT_ATRIGHTS(&nd, LOOKUP, FOLLOW | LOCKSHARED | LOCKLEAF, - UIO_SYSSPACE, buf, fd, CAP_CONNECTAT, td); + UIO_SYSSPACE, buf, fd, cap_rights_init(&rights, CAP_CONNECTAT), td); error = namei(&nd); if (error) vp = NULL; diff --git a/sys/kern/vfs_acl.c b/sys/kern/vfs_acl.c index 1c9923d9d2a8..362792b46dce 100644 --- a/sys/kern/vfs_acl.c +++ b/sys/kern/vfs_acl.c @@ -399,9 +399,11 @@ int sys___acl_get_fd(struct thread *td, struct __acl_get_fd_args *uap) { struct file *fp; + cap_rights_t rights; int error; - error = getvnode(td->td_proc->p_fd, uap->filedes, CAP_ACL_GET, &fp); + error = getvnode(td->td_proc->p_fd, uap->filedes, + cap_rights_init(&rights, CAP_ACL_GET), &fp); if (error == 0) { error = vacl_get_acl(td, fp->f_vnode, uap->type, uap->aclp); fdrop(fp, td); @@ -416,9 +418,11 @@ int sys___acl_set_fd(struct thread *td, struct __acl_set_fd_args *uap) { struct file *fp; + cap_rights_t rights; int error; - error = getvnode(td->td_proc->p_fd, uap->filedes, CAP_ACL_SET, &fp); + error = getvnode(td->td_proc->p_fd, uap->filedes, + cap_rights_init(&rights, CAP_ACL_SET), &fp); if (error == 0) { error = vacl_set_acl(td, fp->f_vnode, uap->type, uap->aclp); fdrop(fp, td); @@ -469,10 +473,11 @@ int sys___acl_delete_fd(struct thread *td, struct __acl_delete_fd_args *uap) { struct file *fp; + cap_rights_t rights; int error; - error = getvnode(td->td_proc->p_fd, uap->filedes, CAP_ACL_DELETE, - &fp); + error = getvnode(td->td_proc->p_fd, uap->filedes, + cap_rights_init(&rights, CAP_ACL_DELETE), &fp); if (error == 0) { error = vacl_delete(td, fp->f_vnode, uap->type); fdrop(fp, td); @@ -523,10 +528,11 @@ int sys___acl_aclcheck_fd(struct thread *td, struct __acl_aclcheck_fd_args *uap) { struct file *fp; + cap_rights_t rights; int error; - error = getvnode(td->td_proc->p_fd, uap->filedes, CAP_ACL_CHECK, - &fp); + error = getvnode(td->td_proc->p_fd, uap->filedes, + cap_rights_init(&rights, CAP_ACL_CHECK), &fp); if (error == 0) { error = vacl_aclcheck(td, fp->f_vnode, uap->type, uap->aclp); fdrop(fp, td); diff --git a/sys/kern/vfs_aio.c b/sys/kern/vfs_aio.c index a66f7c20c233..7f9f88151932 100644 --- a/sys/kern/vfs_aio.c +++ b/sys/kern/vfs_aio.c @@ -1567,6 +1567,7 @@ aio_aqueue(struct thread *td, struct aiocb *job, struct aioliojob *lj, int type, struct aiocb_ops *ops) { struct proc *p = td->td_proc; + cap_rights_t rights; struct file *fp; struct socket *so; struct aiocblist *aiocbe, *cb; @@ -1647,19 +1648,21 @@ aio_aqueue(struct thread *td, struct aiocb *job, struct aioliojob *lj, fd = aiocbe->uaiocb.aio_fildes; switch (opcode) { case LIO_WRITE: - error = fget_write(td, fd, CAP_PWRITE, &fp); + error = fget_write(td, fd, + cap_rights_init(&rights, CAP_PWRITE), &fp); break; case LIO_READ: - error = fget_read(td, fd, CAP_PREAD, &fp); + error = fget_read(td, fd, + cap_rights_init(&rights, CAP_PREAD), &fp); break; case LIO_SYNC: - error = fget(td, fd, CAP_FSYNC, &fp); + error = fget(td, fd, cap_rights_init(&rights, CAP_FSYNC), &fp); break; case LIO_MLOCK: fp = NULL; break; case LIO_NOP: - error = fget(td, fd, CAP_NONE, &fp); + error = fget(td, fd, cap_rights_init(&rights), &fp); break; default: error = EINVAL; @@ -2047,7 +2050,7 @@ sys_aio_cancel(struct thread *td, struct aio_cancel_args *uap) struct vnode *vp; /* Lookup file object. */ - error = fget(td, uap->fd, 0, &fp); + error = fget(td, uap->fd, NULL, &fp); if (error) return (error); diff --git a/sys/kern/vfs_bio.c b/sys/kern/vfs_bio.c index 04eab14f0573..ea8a002dbc41 100644 --- a/sys/kern/vfs_bio.c +++ b/sys/kern/vfs_bio.c @@ -1693,6 +1693,12 @@ brelse(struct buf *bp) KASSERT(presid >= 0, ("brelse: extra page")); VM_OBJECT_WLOCK(obj); + while (vm_page_xbusied(m)) { + vm_page_lock(m); + VM_OBJECT_WUNLOCK(obj); + vm_page_busy_sleep(m, "mbncsh"); + VM_OBJECT_WLOCK(obj); + } if (pmap_page_wired_mappings(m) == 0) vm_page_set_invalid(m, poffset, presid); VM_OBJECT_WUNLOCK(obj); @@ -3994,7 +4000,7 @@ vfs_drain_busy_pages(struct buf *bp) m = bp->b_pages[i]; if (vm_page_xbusied(m)) { for (; last_busied < i; last_busied++) - vm_page_xbusy(bp->b_pages[last_busied]); + vm_page_sbusy(bp->b_pages[last_busied]); while (vm_page_xbusied(m)) { vm_page_lock(m); VM_OBJECT_WUNLOCK(bp->b_bufobj->bo_object); @@ -4004,7 +4010,7 @@ vfs_drain_busy_pages(struct buf *bp) } } for (i = 0; i < last_busied; i++) - vm_page_xunbusy(bp->b_pages[i]); + vm_page_sunbusy(bp->b_pages[i]); } /* diff --git a/sys/kern/vfs_extattr.c b/sys/kern/vfs_extattr.c index 700a70c2c5e8..bc7b942525e7 100644 --- a/sys/kern/vfs_extattr.c +++ b/sys/kern/vfs_extattr.c @@ -216,6 +216,7 @@ sys_extattr_set_fd(td, uap) { struct file *fp; char attrname[EXTATTR_MAXNAMELEN]; + cap_rights_t rights; int error; AUDIT_ARG_FD(uap->fd); @@ -225,7 +226,8 @@ sys_extattr_set_fd(td, uap) return (error); AUDIT_ARG_TEXT(attrname); - error = getvnode(td->td_proc->p_fd, uap->fd, CAP_EXTATTR_SET, &fp); + error = getvnode(td->td_proc->p_fd, uap->fd, + cap_rights_init(&rights, CAP_EXTATTR_SET), &fp); if (error) return (error); @@ -389,6 +391,7 @@ sys_extattr_get_fd(td, uap) { struct file *fp; char attrname[EXTATTR_MAXNAMELEN]; + cap_rights_t rights; int error; AUDIT_ARG_FD(uap->fd); @@ -398,7 +401,8 @@ sys_extattr_get_fd(td, uap) return (error); AUDIT_ARG_TEXT(attrname); - error = getvnode(td->td_proc->p_fd, uap->fd, CAP_EXTATTR_GET, &fp); + error = getvnode(td->td_proc->p_fd, uap->fd, + cap_rights_init(&rights, CAP_EXTATTR_GET), &fp); if (error) return (error); @@ -531,6 +535,7 @@ sys_extattr_delete_fd(td, uap) { struct file *fp; char attrname[EXTATTR_MAXNAMELEN]; + cap_rights_t rights; int error; AUDIT_ARG_FD(uap->fd); @@ -540,8 +545,8 @@ sys_extattr_delete_fd(td, uap) return (error); AUDIT_ARG_TEXT(attrname); - error = getvnode(td->td_proc->p_fd, uap->fd, CAP_EXTATTR_DELETE, - &fp); + error = getvnode(td->td_proc->p_fd, uap->fd, + cap_rights_init(&rights, CAP_EXTATTR_DELETE), &fp); if (error) return (error); @@ -687,11 +692,13 @@ sys_extattr_list_fd(td, uap) } */ *uap; { struct file *fp; + cap_rights_t rights; int error; AUDIT_ARG_FD(uap->fd); AUDIT_ARG_VALUE(uap->attrnamespace); - error = getvnode(td->td_proc->p_fd, uap->fd, CAP_EXTATTR_LIST, &fp); + error = getvnode(td->td_proc->p_fd, uap->fd, + cap_rights_init(&rights, CAP_EXTATTR_LIST), &fp); if (error) return (error); diff --git a/sys/kern/vfs_lookup.c b/sys/kern/vfs_lookup.c index 7fe19085dd4b..d4d01665a991 100644 --- a/sys/kern/vfs_lookup.c +++ b/sys/kern/vfs_lookup.c @@ -222,20 +222,26 @@ namei(struct nameidata *ndp) dp = ndp->ni_startdir; error = 0; } else if (ndp->ni_dirfd != AT_FDCWD) { + cap_rights_t rights; + + rights = ndp->ni_rightsneeded; + cap_rights_set(&rights, CAP_LOOKUP); + if (cnp->cn_flags & AUDITVNODE1) AUDIT_ARG_ATFD1(ndp->ni_dirfd); if (cnp->cn_flags & AUDITVNODE2) AUDIT_ARG_ATFD2(ndp->ni_dirfd); error = fgetvp_rights(td, ndp->ni_dirfd, - ndp->ni_rightsneeded | CAP_LOOKUP, - &ndp->ni_filecaps, &dp); + &rights, &ndp->ni_filecaps, &dp); #ifdef CAPABILITIES /* * If file descriptor doesn't have all rights, * all lookups relative to it must also be * strictly relative. */ - if (ndp->ni_filecaps.fc_rights != CAP_ALL || + CAP_ALL(&rights); + if (!cap_rights_contains(&ndp->ni_filecaps.fc_rights, + &rights) || ndp->ni_filecaps.fc_fcntls != CAP_FCNTL_ALL || ndp->ni_filecaps.fc_nioctls != -1) { ndp->ni_strictrelative = 1; @@ -1059,6 +1065,27 @@ relookup(struct vnode *dvp, struct vnode **vpp, struct componentname *cnp) return (error); } +void +NDINIT_ALL(struct nameidata *ndp, u_long op, u_long flags, enum uio_seg segflg, + const char *namep, int dirfd, struct vnode *startdir, cap_rights_t *rightsp, + struct thread *td) +{ + + ndp->ni_cnd.cn_nameiop = op; + ndp->ni_cnd.cn_flags = flags; + ndp->ni_segflg = segflg; + ndp->ni_dirp = namep; + ndp->ni_dirfd = dirfd; + ndp->ni_startdir = startdir; + ndp->ni_strictrelative = 0; + if (rightsp != NULL) + ndp->ni_rightsneeded = *rightsp; + else + cap_rights_init(&ndp->ni_rightsneeded); + filecaps_init(&ndp->ni_filecaps); + ndp->ni_cnd.cn_thread = td; +} + /* * Free data allocated by namei(); see namei(9) for details. */ diff --git a/sys/kern/vfs_mountroot.c b/sys/kern/vfs_mountroot.c index e873cf93907e..322fc9a00c21 100644 --- a/sys/kern/vfs_mountroot.c +++ b/sys/kern/vfs_mountroot.c @@ -710,7 +710,7 @@ parse_mount(char **conf) errmsg = malloc(ERRMSGL, M_TEMP, M_WAITOK | M_ZERO); if (vfs_byname(fs) == NULL) { - strlcpy(errmsg, "unknown file system", sizeof(errmsg)); + strlcpy(errmsg, "unknown file system", ERRMSGL); error = ENOENT; goto out; } diff --git a/sys/kern/vfs_syscalls.c b/sys/kern/vfs_syscalls.c index 2877ad2535e3..4b82df8d7ef5 100644 --- a/sys/kern/vfs_syscalls.c +++ b/sys/kern/vfs_syscalls.c @@ -181,8 +181,8 @@ sys_quotactl(td, uap) } */ *uap; { struct mount *mp; - int error; struct nameidata nd; + int error; AUDIT_ARG_CMD(uap->cmd); AUDIT_ARG_UID(uap->uid); @@ -198,7 +198,7 @@ sys_quotactl(td, uap) vput(nd.ni_vp); error = vfs_busy(mp, 0); vfs_rel(mp); - if (error) + if (error != 0) return (error); error = VFS_QUOTACTL(mp, uap->cmd, uap->uid, uap->arg); @@ -291,13 +291,13 @@ kern_statfs(struct thread *td, char *path, enum uio_seg pathseg, { struct mount *mp; struct statfs *sp, sb; - int error; struct nameidata nd; + int error; NDINIT(&nd, LOOKUP, FOLLOW | LOCKSHARED | LOCKLEAF | AUDITVNODE1, pathseg, path, td); error = namei(&nd); - if (error) + if (error != 0) return (error); mp = nd.ni_vp->v_mount; vfs_ref(mp); @@ -305,11 +305,11 @@ kern_statfs(struct thread *td, char *path, enum uio_seg pathseg, vput(nd.ni_vp); error = vfs_busy(mp, 0); vfs_rel(mp); - if (error) + if (error != 0) return (error); #ifdef MAC error = mac_mount_check_stat(td->td_ucred, mp); - if (error) + if (error != 0) goto out; #endif /* @@ -320,7 +320,7 @@ kern_statfs(struct thread *td, char *path, enum uio_seg pathseg, sp->f_namemax = NAME_MAX; sp->f_flags = mp->mnt_flag & MNT_VISFLAGMASK; error = VFS_STATFS(mp, sp); - if (error) + if (error != 0) goto out; if (priv_check(td, PRIV_VFS_GENERATION)) { bcopy(sp, &sb, sizeof(sb)); @@ -367,11 +367,13 @@ kern_fstatfs(struct thread *td, int fd, struct statfs *buf) struct mount *mp; struct statfs *sp, sb; struct vnode *vp; + cap_rights_t rights; int error; AUDIT_ARG_FD(fd); - error = getvnode(td->td_proc->p_fd, fd, CAP_FSTATFS, &fp); - if (error) + error = getvnode(td->td_proc->p_fd, fd, + cap_rights_init(&rights, CAP_FSTATFS), &fp); + if (error != 0) return (error); vp = fp->f_vnode; vn_lock(vp, LK_SHARED | LK_RETRY); @@ -389,11 +391,11 @@ kern_fstatfs(struct thread *td, int fd, struct statfs *buf) } error = vfs_busy(mp, 0); vfs_rel(mp); - if (error) + if (error != 0) return (error); #ifdef MAC error = mac_mount_check_stat(td->td_ucred, mp); - if (error) + if (error != 0) goto out; #endif /* @@ -404,7 +406,7 @@ kern_fstatfs(struct thread *td, int fd, struct statfs *buf) sp->f_namemax = NAME_MAX; sp->f_flags = mp->mnt_flag & MNT_VISFLAGMASK; error = VFS_STATFS(mp, sp); - if (error) + if (error != 0) goto out; if (priv_check(td, PRIV_VFS_GENERATION)) { bcopy(sp, &sb, sizeof(sb)); @@ -523,7 +525,7 @@ kern_getfsstat(struct thread *td, struct statfs **buf, size_t bufsize, bcopy(sp, sfsp, sizeof(*sp)); else /* if (bufseg == UIO_USERSPACE) */ { error = copyout(sp, sfsp, sizeof(*sp)); - if (error) { + if (error != 0) { vfs_unbusy(mp); return (error); } @@ -568,7 +570,7 @@ freebsd4_statfs(td, uap) int error; error = kern_statfs(td, uap->path, UIO_USERSPACE, &sf); - if (error) + if (error != 0) return (error); cvtstatfs(&sf, &osb); return (copyout(&osb, uap->buf, sizeof(osb))); @@ -596,7 +598,7 @@ freebsd4_fstatfs(td, uap) int error; error = kern_fstatfs(td, uap->fd, &sf); - if (error) + if (error != 0) return (error); cvtstatfs(&sf, &osb); return (copyout(&osb, uap->buf, sizeof(osb))); @@ -667,10 +669,10 @@ freebsd4_fhstatfs(td, uap) int error; error = copyin(uap->u_fhp, &fh, sizeof(fhandle_t)); - if (error) + if (error != 0) return (error); error = kern_fhstatfs(td, fh, &sf); - if (error) + if (error != 0) return (error); cvtstatfs(&sf, &osb); return (copyout(&osb, uap->buf, sizeof(osb))); @@ -730,10 +732,13 @@ sys_fchdir(td, uap) struct vnode *vp, *tdp, *vpold; struct mount *mp; struct file *fp; + cap_rights_t rights; int error; AUDIT_ARG_FD(uap->fd); - if ((error = getvnode(fdp, uap->fd, CAP_FCHDIR, &fp)) != 0) + error = getvnode(fdp, uap->fd, cap_rights_init(&rights, CAP_FCHDIR), + &fp); + if (error != 0) return (error); vp = fp->f_vnode; VREF(vp); @@ -746,12 +751,12 @@ sys_fchdir(td, uap) continue; error = VFS_ROOT(mp, LK_SHARED, &tdp); vfs_unbusy(mp); - if (error) + if (error != 0) break; vput(vp); vp = tdp; } - if (error) { + if (error != 0) { vput(vp); return (error); } @@ -787,9 +792,9 @@ int kern_chdir(struct thread *td, char *path, enum uio_seg pathseg) { register struct filedesc *fdp = td->td_proc->p_fd; - int error; struct nameidata nd; struct vnode *vp; + int error; NDINIT(&nd, LOOKUP, FOLLOW | LOCKSHARED | LOCKLEAF | AUDITVNODE1, pathseg, path, td); @@ -866,21 +871,23 @@ sys_chroot(td, uap) char *path; } */ *uap; { - int error; struct nameidata nd; + int error; error = priv_check(td, PRIV_VFS_CHROOT); - if (error) + if (error != 0) return (error); NDINIT(&nd, LOOKUP, FOLLOW | LOCKSHARED | LOCKLEAF | AUDITVNODE1, UIO_USERSPACE, uap->path, td); error = namei(&nd); - if (error) + if (error != 0) goto error; - if ((error = change_dir(nd.ni_vp, td)) != 0) + error = change_dir(nd.ni_vp, td); + if (error != 0) goto e_vunlock; #ifdef MAC - if ((error = mac_vnode_check_chroot(td->td_ucred, nd.ni_vp))) + error = mac_vnode_check_chroot(td->td_ucred, nd.ni_vp); + if (error != 0) goto e_vunlock; #endif VOP_UNLOCK(nd.ni_vp, 0); @@ -904,18 +911,19 @@ change_dir(vp, td) struct vnode *vp; struct thread *td; { +#ifdef MAC int error; +#endif ASSERT_VOP_LOCKED(vp, "change_dir(): vp not locked"); if (vp->v_type != VDIR) return (ENOTDIR); #ifdef MAC error = mac_vnode_check_chdir(td->td_ucred, vp); - if (error) + if (error != 0) return (error); #endif - error = VOP_ACCESS(vp, VEXEC, td->td_ucred, td); - return (error); + return (VOP_ACCESS(vp, VEXEC, td->td_ucred, td)); } /* @@ -937,7 +945,7 @@ change_root(vp, td) if (chroot_allow_open_directories == 0 || (chroot_allow_open_directories == 1 && fdp->fd_rdir != rootvnode)) { error = chroot_refuse_vdir_fds(fdp); - if (error) { + if (error != 0) { FILEDESC_XUNLOCK(fdp); return (error); } @@ -954,42 +962,39 @@ change_root(vp, td) return (0); } -static __inline cap_rights_t -flags_to_rights(int flags) +static __inline void +flags_to_rights(int flags, cap_rights_t *rightsp) { - cap_rights_t rights = 0; if (flags & O_EXEC) { - rights |= CAP_FEXECVE; + cap_rights_set(rightsp, CAP_FEXECVE); } else { switch ((flags & O_ACCMODE)) { case O_RDONLY: - rights |= CAP_READ; + cap_rights_set(rightsp, CAP_READ); break; case O_RDWR: - rights |= CAP_READ; + cap_rights_set(rightsp, CAP_READ); /* FALLTHROUGH */ case O_WRONLY: - rights |= CAP_WRITE; + cap_rights_set(rightsp, CAP_WRITE); if (!(flags & (O_APPEND | O_TRUNC))) - rights |= CAP_SEEK; + cap_rights_set(rightsp, CAP_SEEK); break; } } if (flags & O_CREAT) - rights |= CAP_CREATE; + cap_rights_set(rightsp, CAP_CREATE); if (flags & O_TRUNC) - rights |= CAP_FTRUNCATE; + cap_rights_set(rightsp, CAP_FTRUNCATE); if (flags & (O_SYNC | O_FSYNC)) - rights |= CAP_FSYNC; + cap_rights_set(rightsp, CAP_FSYNC); if (flags & (O_EXLOCK | O_SHLOCK)) - rights |= CAP_FLOCK; - - return (rights); + cap_rights_set(rightsp, CAP_FLOCK); } /* @@ -1048,15 +1053,17 @@ kern_openat(struct thread *td, int fd, char *path, enum uio_seg pathseg, struct filedesc *fdp = p->p_fd; struct file *fp; struct vnode *vp; - int cmode; - int indx = -1, error; struct nameidata nd; - cap_rights_t rights_needed = CAP_LOOKUP; + cap_rights_t rights; + int cmode, error, indx; + + indx = -1; AUDIT_ARG_FFLAGS(flags); AUDIT_ARG_MODE(mode); /* XXX: audit dirfd */ - rights_needed |= flags_to_rights(flags); + cap_rights_init(&rights, CAP_LOOKUP); + flags_to_rights(flags, &rights); /* * Only one of the O_EXEC, O_RDONLY, O_WRONLY and O_RDWR flags * may be specified. @@ -1074,7 +1081,7 @@ kern_openat(struct thread *td, int fd, char *path, enum uio_seg pathseg, * Allocate the file descriptor, but don't install a descriptor yet. */ error = falloc_noinstall(td, &fp); - if (error) + if (error != 0) return (error); /* * An extra reference on `fp' has been held for us by @@ -1082,12 +1089,12 @@ kern_openat(struct thread *td, int fd, char *path, enum uio_seg pathseg, */ /* Set the flags early so the finit in devfs can pick them up. */ fp->f_flag = flags & FMASK; - cmode = ((mode &~ fdp->fd_cmask) & ALLPERMS) &~ S_ISTXT; + cmode = ((mode & ~fdp->fd_cmask) & ALLPERMS) & ~S_ISTXT; NDINIT_ATRIGHTS(&nd, LOOKUP, FOLLOW | AUDITVNODE1, pathseg, path, fd, - rights_needed, td); + &rights, td); td->td_dupfd = -1; /* XXX check for fdopen */ error = vn_open(&nd, &flags, cmode, fp); - if (error) { + if (error != 0) { /* * If the vn_open replaced the method vector, something * wonderous happened deep below and we just pass it up @@ -1131,14 +1138,14 @@ kern_openat(struct thread *td, int fd, char *path, enum uio_seg pathseg, if (fp->f_ops == &badfileops) { KASSERT(vp->v_type != VFIFO, ("Unexpected fifo.")); fp->f_seqcount = 1; - finit(fp, (flags & FMASK) | (fp->f_flag & FHASLOCK), DTYPE_VNODE, - vp, &vnops); + finit(fp, (flags & FMASK) | (fp->f_flag & FHASLOCK), + DTYPE_VNODE, vp, &vnops); } VOP_UNLOCK(vp, 0); if (flags & O_TRUNC) { error = fo_truncate(fp, 0, td->td_ucred, td); - if (error) + if (error != 0) goto bad; } success: @@ -1255,9 +1262,9 @@ kern_mknodat(struct thread *td, int fd, char *path, enum uio_seg pathseg, struct vnode *vp; struct mount *mp; struct vattr vattr; - int error; - int whiteout = 0; struct nameidata nd; + cap_rights_t rights; + int error, whiteout = 0; AUDIT_ARG_MODE(mode); AUDIT_ARG_DEV(dev); @@ -1280,12 +1287,12 @@ kern_mknodat(struct thread *td, int fd, char *path, enum uio_seg pathseg, error = EINVAL; break; } - if (error) + if (error != 0) return (error); restart: bwillwrite(); NDINIT_ATRIGHTS(&nd, CREATE, LOCKPARENT | SAVENAME | AUDITVNODE1, - pathseg, path, fd, CAP_MKNODAT, td); + pathseg, path, fd, cap_rights_init(&rights, CAP_MKNODAT), td); if ((error = namei(&nd)) != 0) return (error); vp = nd.ni_vp; @@ -1333,7 +1340,7 @@ kern_mknodat(struct thread *td, int fd, char *path, enum uio_seg pathseg, error = mac_vnode_check_create(td->td_ucred, nd.ni_dvp, &nd.ni_cnd, &vattr); #endif - if (!error) { + if (error == 0) { if (whiteout) error = VOP_WHITEOUT(nd.ni_dvp, &nd.ni_cnd, CREATE); else { @@ -1398,14 +1405,15 @@ kern_mkfifoat(struct thread *td, int fd, char *path, enum uio_seg pathseg, { struct mount *mp; struct vattr vattr; - int error; struct nameidata nd; + cap_rights_t rights; + int error; AUDIT_ARG_MODE(mode); restart: bwillwrite(); NDINIT_ATRIGHTS(&nd, CREATE, LOCKPARENT | SAVENAME | AUDITVNODE1, - pathseg, path, fd, CAP_MKFIFOAT, td); + pathseg, path, fd, cap_rights_init(&rights, CAP_MKFIFOAT), td); if ((error = namei(&nd)) != 0) return (error); if (nd.ni_vp != NULL) { @@ -1430,7 +1438,7 @@ kern_mkfifoat(struct thread *td, int fd, char *path, enum uio_seg pathseg, #ifdef MAC error = mac_vnode_check_create(td->td_ucred, nd.ni_dvp, &nd.ni_cnd, &vattr); - if (error) + if (error != 0) goto out; #endif error = VOP_MKNOD(nd.ni_dvp, &nd.ni_vp, &nd.ni_cnd, &vattr); @@ -1514,13 +1522,13 @@ can_hardlink(struct vnode *vp, struct ucred *cred) if (hardlink_check_uid && cred->cr_uid != va.va_uid) { error = priv_check_cred(cred, PRIV_VFS_LINK, 0); - if (error) + if (error != 0) return (error); } if (hardlink_check_gid && !groupmember(va.va_gid, cred)) { error = priv_check_cred(cred, PRIV_VFS_LINK, 0); - if (error) + if (error != 0) return (error); } @@ -1541,6 +1549,7 @@ kern_linkat(struct thread *td, int fd1, int fd2, char *path1, char *path2, struct vnode *vp; struct mount *mp; struct nameidata nd; + cap_rights_t rights; int error; bwillwrite(); @@ -1559,7 +1568,7 @@ kern_linkat(struct thread *td, int fd1, int fd2, char *path1, char *path2, return (error); } NDINIT_ATRIGHTS(&nd, CREATE, LOCKPARENT | SAVENAME | AUDITVNODE2, - segflg, path2, fd2, CAP_LINKAT, td); + segflg, path2, fd2, cap_rights_init(&rights, CAP_LINKAT), td); if ((error = namei(&nd)) == 0) { if (nd.ni_vp != NULL) { if (nd.ni_dvp == nd.ni_vp) @@ -1638,8 +1647,9 @@ kern_symlinkat(struct thread *td, char *path1, int fd, char *path2, struct mount *mp; struct vattr vattr; char *syspath; - int error; struct nameidata nd; + int error; + cap_rights_t rights; if (segflg == UIO_SYSSPACE) { syspath = path1; @@ -1652,7 +1662,7 @@ kern_symlinkat(struct thread *td, char *path1, int fd, char *path2, restart: bwillwrite(); NDINIT_ATRIGHTS(&nd, CREATE, LOCKPARENT | SAVENAME | AUDITVNODE1, - segflg, path2, fd, CAP_SYMLINKAT, td); + segflg, path2, fd, cap_rights_init(&rights, CAP_SYMLINKAT), td); if ((error = namei(&nd)) != 0) goto out; if (nd.ni_vp) { @@ -1678,7 +1688,7 @@ kern_symlinkat(struct thread *td, char *path1, int fd, char *path2, vattr.va_type = VLNK; error = mac_vnode_check_create(td->td_ucred, nd.ni_dvp, &nd.ni_cnd, &vattr); - if (error) + if (error != 0) goto out2; #endif error = VOP_SYMLINK(nd.ni_dvp, &nd.ni_vp, &nd.ni_cnd, &vattr, syspath); @@ -1706,16 +1716,16 @@ sys_undelete(td, uap) char *path; } */ *uap; { - int error; struct mount *mp; struct nameidata nd; + int error; restart: bwillwrite(); NDINIT(&nd, DELETE, LOCKPARENT | DOWHITEOUT | AUDITVNODE1, UIO_USERSPACE, uap->path, td); error = namei(&nd); - if (error) + if (error != 0) return (error); if (nd.ni_vp != NULLVP || !(nd.ni_cnd.cn_flags & ISWHITEOUT)) { @@ -1797,14 +1807,15 @@ kern_unlinkat(struct thread *td, int fd, char *path, enum uio_seg pathseg, { struct mount *mp; struct vnode *vp; - int error; struct nameidata nd; struct stat sb; + cap_rights_t rights; + int error; restart: bwillwrite(); NDINIT_ATRIGHTS(&nd, DELETE, LOCKPARENT | LOCKLEAF | AUDITVNODE1, - pathseg, path, fd, CAP_UNLINKAT, td); + pathseg, path, fd, cap_rights_init(&rights, CAP_UNLINKAT), td); if ((error = namei(&nd)) != 0) return (error == EINVAL ? EPERM : error); vp = nd.ni_vp; @@ -1839,7 +1850,7 @@ kern_unlinkat(struct thread *td, int fd, char *path, enum uio_seg pathseg, #ifdef MAC error = mac_vnode_check_unlink(td->td_ucred, nd.ni_dvp, vp, &nd.ni_cnd); - if (error) + if (error != 0) goto out; #endif vfs_notify_upper(vp, VFS_NOTIFY_UPPER_UNLINK); @@ -1880,10 +1891,12 @@ sys_lseek(td, uap) } */ *uap; { struct file *fp; + cap_rights_t rights; int error; AUDIT_ARG_FD(uap->fd); - if ((error = fget(td, uap->fd, CAP_SEEK, &fp)) != 0) + error = fget(td, uap->fd, cap_rights_init(&rights, CAP_SEEK), &fp); + if (error != 0) return (error); error = (fp->f_ops->fo_flags & DFLAG_SEEKABLE) != 0 ? fo_seek(fp, uap->offset, uap->whence, td) : ESPIPE; @@ -1949,8 +1962,8 @@ vn_access(vp, user_flags, cred, td) struct ucred *cred; struct thread *td; { - int error; accmode_t accmode; + int error; /* Flags == 0 means only check for existence. */ error = 0; @@ -1964,7 +1977,7 @@ vn_access(vp, user_flags, cred, td) accmode |= VEXEC; #ifdef MAC error = mac_vnode_check_access(cred, vp, accmode); - if (error) + if (error != 0) return (error); #endif if ((accmode & VWRITE) == 0 || (error = vn_writechk(vp)) == 0) @@ -2026,6 +2039,7 @@ kern_accessat(struct thread *td, int fd, char *path, enum uio_seg pathseg, struct ucred *cred, *tmpcred; struct vnode *vp; struct nameidata nd; + cap_rights_t rights; int error; /* @@ -2042,7 +2056,8 @@ kern_accessat(struct thread *td, int fd, char *path, enum uio_seg pathseg, cred = tmpcred = td->td_ucred; AUDIT_ARG_VALUE(amode); NDINIT_ATRIGHTS(&nd, LOOKUP, FOLLOW | LOCKSHARED | LOCKLEAF | - AUDITVNODE1, pathseg, path, fd, CAP_FSTAT, td); + AUDITVNODE1, pathseg, path, fd, cap_rights_init(&rights, CAP_FSTAT), + td); if ((error = namei(&nd)) != 0) goto out1; vp = nd.ni_vp; @@ -2109,11 +2124,10 @@ ostat(td, uap) int error; error = kern_stat(td, uap->path, UIO_USERSPACE, &sb); - if (error) + if (error != 0) return (error); cvtstat(&sb, &osb); - error = copyout(&osb, uap->ub, sizeof (osb)); - return (error); + return (copyout(&osb, uap->ub, sizeof (osb))); } /* @@ -2138,11 +2152,10 @@ olstat(td, uap) int error; error = kern_lstat(td, uap->path, UIO_USERSPACE, &sb); - if (error) + if (error != 0) return (error); cvtstat(&sb, &osb); - error = copyout(&osb, uap->ub, sizeof (osb)); - return (error); + return (copyout(&osb, uap->ub, sizeof (osb))); } /* @@ -2244,6 +2257,7 @@ kern_statat_vnhook(struct thread *td, int flag, int fd, char *path, { struct nameidata nd; struct stat sb; + cap_rights_t rights; int error; if (flag & ~AT_SYMLINK_NOFOLLOW) @@ -2251,12 +2265,12 @@ kern_statat_vnhook(struct thread *td, int flag, int fd, char *path, NDINIT_ATRIGHTS(&nd, LOOKUP, ((flag & AT_SYMLINK_NOFOLLOW) ? NOFOLLOW : FOLLOW) | LOCKSHARED | LOCKLEAF | AUDITVNODE1, pathseg, path, fd, - CAP_FSTAT, td); + cap_rights_init(&rights, CAP_FSTAT), td); if ((error = namei(&nd)) != 0) return (error); error = vn_stat(nd.ni_vp, &sb, td->td_ucred, NOCRED, td); - if (!error) { + if (error == 0) { SDT_PROBE(vfs, , stat, mode, path, sb.st_mode, 0, 0, 0); if (S_ISREG(sb.st_mode)) SDT_PROBE(vfs, , stat, reg, path, pathseg, 0, 0, 0); @@ -2265,7 +2279,7 @@ kern_statat_vnhook(struct thread *td, int flag, int fd, char *path, } NDFREE(&nd, NDF_ONLY_PNBUF); vput(nd.ni_vp); - if (error) + if (error != 0) return (error); *sbp = sb; #ifdef KTRACE @@ -2317,6 +2331,7 @@ cvtnstat(sb, nsb) struct stat *sb; struct nstat *nsb; { + bzero(nsb, sizeof *nsb); nsb->st_dev = sb->st_dev; nsb->st_ino = sb->st_ino; @@ -2355,11 +2370,10 @@ sys_nstat(td, uap) int error; error = kern_stat(td, uap->path, UIO_USERSPACE, &sb); - if (error) + if (error != 0) return (error); cvtnstat(&sb, &nsb); - error = copyout(&nsb, uap->ub, sizeof (nsb)); - return (error); + return (copyout(&nsb, uap->ub, sizeof (nsb))); } /* @@ -2384,11 +2398,10 @@ sys_nlstat(td, uap) int error; error = kern_lstat(td, uap->path, UIO_USERSPACE, &sb); - if (error) + if (error != 0) return (error); cvtnstat(&sb, &nsb); - error = copyout(&nsb, uap->ub, sizeof (nsb)); - return (error); + return (copyout(&nsb, uap->ub, sizeof (nsb))); } /* @@ -2508,8 +2521,8 @@ kern_readlinkat(struct thread *td, int fd, char *path, enum uio_seg pathseg, struct vnode *vp; struct iovec aiov; struct uio auio; - int error; struct nameidata nd; + int error; if (count > IOSIZE_MAX) return (EINVAL); @@ -2523,7 +2536,7 @@ kern_readlinkat(struct thread *td, int fd, char *path, enum uio_seg pathseg, vp = nd.ni_vp; #ifdef MAC error = mac_vnode_check_readlink(td->td_ucred, vp); - if (error) { + if (error != 0) { vput(vp); return (error); } @@ -2556,9 +2569,9 @@ setfflags(td, vp, flags) struct vnode *vp; u_long flags; { - int error; struct mount *mp; struct vattr vattr; + int error; /* We can't support the value matching VNOVAL. */ if (flags == VNOVAL) @@ -2572,7 +2585,7 @@ setfflags(td, vp, flags) */ if (vp->v_type == VCHR || vp->v_type == VBLK) { error = priv_check(td, PRIV_VFS_CHFLAGS_DEV); - if (error) + if (error != 0) return (error); } @@ -2663,12 +2676,13 @@ kern_chflagsat(struct thread *td, int fd, const char *path, enum uio_seg pathseg, u_long flags, int atflag) { struct nameidata nd; + cap_rights_t rights; int error, follow; AUDIT_ARG_FFLAGS(flags); follow = (atflag & AT_SYMLINK_NOFOLLOW) ? NOFOLLOW : FOLLOW; NDINIT_ATRIGHTS(&nd, LOOKUP, follow | AUDITVNODE1, pathseg, path, fd, - CAP_FCHFLAGS, td); + cap_rights_init(&rights, CAP_FCHFLAGS), td); if ((error = namei(&nd)) != 0) return (error); NDFREE(&nd, NDF_ONLY_PNBUF); @@ -2695,12 +2709,14 @@ sys_fchflags(td, uap) } */ *uap; { struct file *fp; + cap_rights_t rights; int error; AUDIT_ARG_FD(uap->fd); AUDIT_ARG_FFLAGS(uap->flags); - if ((error = getvnode(td->td_proc->p_fd, uap->fd, CAP_FCHFLAGS, - &fp)) != 0) + error = getvnode(td->td_proc->p_fd, uap->fd, + cap_rights_init(&rights, CAP_FCHFLAGS), &fp); + if (error != 0) return (error); #ifdef AUDIT vn_lock(fp->f_vnode, LK_SHARED | LK_RETRY); @@ -2722,9 +2738,9 @@ setfmode(td, cred, vp, mode) struct vnode *vp; int mode; { - int error; struct mount *mp; struct vattr vattr; + int error; if ((error = vn_start_write(vp, &mp, V_WAIT | PCATCH)) != 0) return (error); @@ -2817,14 +2833,14 @@ int kern_fchmodat(struct thread *td, int fd, char *path, enum uio_seg pathseg, mode_t mode, int flag) { - int error; struct nameidata nd; - int follow; + cap_rights_t rights; + int error, follow; AUDIT_ARG_MODE(mode); follow = (flag & AT_SYMLINK_NOFOLLOW) ? NOFOLLOW : FOLLOW; NDINIT_ATRIGHTS(&nd, LOOKUP, follow | AUDITVNODE1, pathseg, path, fd, - CAP_FCHMOD, td); + cap_rights_init(&rights, CAP_FCHMOD), td); if ((error = namei(&nd)) != 0) return (error); NDFREE(&nd, NDF_ONLY_PNBUF); @@ -2846,12 +2862,13 @@ int sys_fchmod(struct thread *td, struct fchmod_args *uap) { struct file *fp; + cap_rights_t rights; int error; AUDIT_ARG_FD(uap->fd); AUDIT_ARG_MODE(uap->mode); - error = fget(td, uap->fd, CAP_FCHMOD, &fp); + error = fget(td, uap->fd, cap_rights_init(&rights, CAP_FCHMOD), &fp); if (error != 0) return (error); error = fo_chmod(fp, uap->mode, td->td_ucred, td); @@ -2870,9 +2887,9 @@ setfown(td, cred, vp, uid, gid) uid_t uid; gid_t gid; { - int error; struct mount *mp; struct vattr vattr; + int error; if ((error = vn_start_write(vp, &mp, V_WAIT | PCATCH)) != 0) return (error); @@ -2949,12 +2966,13 @@ kern_fchownat(struct thread *td, int fd, char *path, enum uio_seg pathseg, int uid, int gid, int flag) { struct nameidata nd; + cap_rights_t rights; int error, follow; AUDIT_ARG_OWNER(uid, gid); follow = (flag & AT_SYMLINK_NOFOLLOW) ? NOFOLLOW : FOLLOW; NDINIT_ATRIGHTS(&nd, LOOKUP, follow | AUDITVNODE1, pathseg, path, fd, - CAP_FCHOWN, td); + cap_rights_init(&rights, CAP_FCHOWN), td); if ((error = namei(&nd)) != 0) return (error); @@ -3016,11 +3034,12 @@ sys_fchown(td, uap) } */ *uap; { struct file *fp; + cap_rights_t rights; int error; AUDIT_ARG_FD(uap->fd); AUDIT_ARG_OWNER(uap->uid, uap->gid); - error = fget(td, uap->fd, CAP_FCHOWN, &fp); + error = fget(td, uap->fd, cap_rights_init(&rights, CAP_FCHOWN), &fp); if (error != 0) return (error); error = fo_chown(fp, uap->uid, uap->gid, td->td_ucred, td); @@ -3073,9 +3092,9 @@ setutimes(td, vp, ts, numtimes, nullflag) int numtimes; int nullflag; { - int error, setbirthtime; struct mount *mp; struct vattr vattr; + int error, setbirthtime; if ((error = vn_start_write(vp, &mp, V_WAIT | PCATCH)) != 0) return (error); @@ -3155,12 +3174,13 @@ kern_utimesat(struct thread *td, int fd, char *path, enum uio_seg pathseg, { struct nameidata nd; struct timespec ts[2]; + cap_rights_t rights; int error; if ((error = getutimes(tptr, tptrseg, ts)) != 0) return (error); NDINIT_ATRIGHTS(&nd, LOOKUP, FOLLOW | AUDITVNODE1, pathseg, path, fd, - CAP_FUTIMES, td); + cap_rights_init(&rights, CAP_FUTIMES), td); if ((error = namei(&nd)) != 0) return (error); @@ -3197,8 +3217,8 @@ kern_lutimes(struct thread *td, char *path, enum uio_seg pathseg, struct timeval *tptr, enum uio_seg tptrseg) { struct timespec ts[2]; - int error; struct nameidata nd; + int error; if ((error = getutimes(tptr, tptrseg, ts)) != 0) return (error); @@ -3238,12 +3258,16 @@ kern_futimes(struct thread *td, int fd, struct timeval *tptr, { struct timespec ts[2]; struct file *fp; + cap_rights_t rights; int error; AUDIT_ARG_FD(fd); - if ((error = getutimes(tptr, tptrseg, ts)) != 0) + error = getutimes(tptr, tptrseg, ts); + if (error != 0) return (error); - if ((error = getvnode(td->td_proc->p_fd, fd, CAP_FUTIMES, &fp)) != 0) + error = getvnode(td->td_proc->p_fd, fd, + cap_rights_init(&rights, CAP_FUTIMES), &fp); + if (error != 0) return (error); #ifdef AUDIT vn_lock(fp->f_vnode, LK_SHARED | LK_RETRY); @@ -3390,13 +3414,17 @@ sys_fsync(td, uap) struct vnode *vp; struct mount *mp; struct file *fp; + cap_rights_t rights; int error, lock_flags; AUDIT_ARG_FD(uap->fd); - if ((error = getvnode(td->td_proc->p_fd, uap->fd, CAP_FSYNC, &fp)) != 0) + error = getvnode(td->td_proc->p_fd, uap->fd, + cap_rights_init(&rights, CAP_FSYNC), &fp); + if (error != 0) return (error); vp = fp->f_vnode; - if ((error = vn_start_write(vp, &mp, V_WAIT | PCATCH)) != 0) + error = vn_start_write(vp, &mp, V_WAIT | PCATCH); + if (error != 0) goto drop; if (MNT_SHARED_WRITES(mp) || ((mp == NULL) && MNT_SHARED_WRITES(vp->v_mount))) { @@ -3472,15 +3500,17 @@ kern_renameat(struct thread *td, int oldfd, char *old, int newfd, char *new, struct mount *mp = NULL; struct vnode *tvp, *fvp, *tdvp; struct nameidata fromnd, tond; + cap_rights_t rights; int error; bwillwrite(); #ifdef MAC NDINIT_ATRIGHTS(&fromnd, DELETE, LOCKPARENT | LOCKLEAF | SAVESTART | - AUDITVNODE1, pathseg, old, oldfd, CAP_RENAMEAT, td); + AUDITVNODE1, pathseg, old, oldfd, + cap_rights_init(&rights, CAP_RENAMEAT), td); #else NDINIT_ATRIGHTS(&fromnd, DELETE, WANTPARENT | SAVESTART | AUDITVNODE1, - pathseg, old, oldfd, CAP_RENAMEAT, td); + pathseg, old, oldfd, cap_rights_init(&rights, CAP_RENAMEAT), td); #endif if ((error = namei(&fromnd)) != 0) @@ -3502,7 +3532,8 @@ kern_renameat(struct thread *td, int oldfd, char *old, int newfd, char *new, goto out1; } NDINIT_ATRIGHTS(&tond, RENAME, LOCKPARENT | LOCKLEAF | NOCACHE | - SAVESTART | AUDITVNODE2, pathseg, new, newfd, CAP_LINKAT, td); + SAVESTART | AUDITVNODE2, pathseg, new, newfd, + cap_rights_init(&rights, CAP_LINKAT), td); if (fromnd.ni_vp->v_type == VDIR) tond.ni_cnd.cn_flags |= WILLBEDIR; if ((error = namei(&tond)) != 0) { @@ -3531,8 +3562,8 @@ kern_renameat(struct thread *td, int oldfd, char *old, int newfd, char *new, * If the target already exists we require CAP_UNLINKAT * from 'newfd'. */ - error = cap_check(tond.ni_filecaps.fc_rights, - CAP_UNLINKAT); + error = cap_check(&tond.ni_filecaps.fc_rights, + cap_rights_init(&rights, CAP_UNLINKAT)); if (error != 0) goto out; } @@ -3554,15 +3585,15 @@ kern_renameat(struct thread *td, int oldfd, char *old, int newfd, char *new, tond.ni_vp, fromnd.ni_dvp == tdvp, &tond.ni_cnd); #endif out: - if (!error) { + if (error == 0) { error = VOP_RENAME(fromnd.ni_dvp, fromnd.ni_vp, &fromnd.ni_cnd, - tond.ni_dvp, tond.ni_vp, &tond.ni_cnd); + tond.ni_dvp, tond.ni_vp, &tond.ni_cnd); NDFREE(&fromnd, NDF_ONLY_PNBUF); NDFREE(&tond, NDF_ONLY_PNBUF); } else { NDFREE(&fromnd, NDF_ONLY_PNBUF); NDFREE(&tond, NDF_ONLY_PNBUF); - if (tvp) + if (tvp != NULL) vput(tvp); if (tdvp == tvp) vrele(tdvp); @@ -3630,14 +3661,15 @@ kern_mkdirat(struct thread *td, int fd, char *path, enum uio_seg segflg, struct mount *mp; struct vnode *vp; struct vattr vattr; - int error; struct nameidata nd; + cap_rights_t rights; + int error; AUDIT_ARG_MODE(mode); restart: bwillwrite(); NDINIT_ATRIGHTS(&nd, CREATE, LOCKPARENT | SAVENAME | AUDITVNODE1, - segflg, path, fd, CAP_MKDIRAT, td); + segflg, path, fd, cap_rights_init(&rights, CAP_MKDIRAT), td); nd.ni_cnd.cn_flags |= WILLBEDIR; if ((error = namei(&nd)) != 0) return (error); @@ -3669,7 +3701,7 @@ kern_mkdirat(struct thread *td, int fd, char *path, enum uio_seg segflg, #ifdef MAC error = mac_vnode_check_create(td->td_ucred, nd.ni_dvp, &nd.ni_cnd, &vattr); - if (error) + if (error != 0) goto out; #endif error = VOP_MKDIR(nd.ni_dvp, &nd.ni_vp, &nd.ni_cnd, &vattr); @@ -3678,7 +3710,7 @@ kern_mkdirat(struct thread *td, int fd, char *path, enum uio_seg segflg, #endif NDFREE(&nd, NDF_ONLY_PNBUF); vput(nd.ni_dvp); - if (!error) + if (error == 0) vput(nd.ni_vp); vn_finished_write(mp); return (error); @@ -3715,13 +3747,14 @@ kern_rmdirat(struct thread *td, int fd, char *path, enum uio_seg pathseg) { struct mount *mp; struct vnode *vp; - int error; struct nameidata nd; + cap_rights_t rights; + int error; restart: bwillwrite(); NDINIT_ATRIGHTS(&nd, DELETE, LOCKPARENT | LOCKLEAF | AUDITVNODE1, - pathseg, path, fd, CAP_UNLINKAT, td); + pathseg, path, fd, cap_rights_init(&rights, CAP_UNLINKAT), td); if ((error = namei(&nd)) != 0) return (error); vp = nd.ni_vp; @@ -3746,7 +3779,7 @@ kern_rmdirat(struct thread *td, int fd, char *path, enum uio_seg pathseg) #ifdef MAC error = mac_vnode_check_unlink(td->td_ucred, nd.ni_dvp, vp, &nd.ni_cnd); - if (error) + if (error != 0) goto out; #endif if (vn_start_write(nd.ni_dvp, &mp, V_NOWAIT) != 0) { @@ -3806,6 +3839,7 @@ kern_ogetdirentries(struct thread *td, struct ogetdirentries_args *uap, struct uio auio, kuio; struct iovec aiov, kiov; struct dirent *dp, *edp; + cap_rights_t rights; caddr_t dirbuf; int error, eofflag, readcnt; long loff; @@ -3814,7 +3848,9 @@ kern_ogetdirentries(struct thread *td, struct ogetdirentries_args *uap, /* XXX arbitrary sanity limit on `count'. */ if (uap->count > 64 * 1024) return (EINVAL); - if ((error = getvnode(td->td_proc->p_fd, uap->fd, CAP_READ, &fp)) != 0) + error = getvnode(td->td_proc->p_fd, uap->fd, + cap_rights_init(&rights, CAP_READ), &fp); + if (error != 0) return (error); if ((fp->f_flag & FREAD) == 0) { fdrop(fp, td); @@ -3840,7 +3876,7 @@ kern_ogetdirentries(struct thread *td, struct ogetdirentries_args *uap, loff = auio.uio_offset = foffset; #ifdef MAC error = mac_vnode_check_readdir(td->td_ucred, vp); - if (error) { + if (error != 0) { VOP_UNLOCK(vp, 0); foffset_unlock(fp, foffset, FOF_NOUPDATE); fdrop(fp, td); @@ -3898,7 +3934,7 @@ kern_ogetdirentries(struct thread *td, struct ogetdirentries_args *uap, } free(dirbuf, M_TEMP); } - if (error) { + if (error != 0) { VOP_UNLOCK(vp, 0); foffset_unlock(fp, foffset, 0); fdrop(fp, td); @@ -3952,7 +3988,7 @@ sys_getdirentries(td, uap) error = kern_getdirentries(td, uap->fd, uap->buf, uap->count, &base, NULL, UIO_USERSPACE); - if (error) + if (error != 0) return (error); if (uap->basep != NULL) error = copyout(&base, uap->basep, sizeof(long)); @@ -3967,6 +4003,7 @@ kern_getdirentries(struct thread *td, int fd, char *buf, u_int count, struct file *fp; struct uio auio; struct iovec aiov; + cap_rights_t rights; long loff; int error, eofflag; off_t foffset; @@ -3975,7 +4012,9 @@ kern_getdirentries(struct thread *td, int fd, char *buf, u_int count, if (count > IOSIZE_MAX) return (EINVAL); auio.uio_resid = count; - if ((error = getvnode(td->td_proc->p_fd, fd, CAP_READ, &fp)) != 0) + error = getvnode(td->td_proc->p_fd, fd, + cap_rights_init(&rights, CAP_READ), &fp); + if (error != 0) return (error); if ((fp->f_flag & FREAD) == 0) { fdrop(fp, td); @@ -4005,7 +4044,7 @@ kern_getdirentries(struct thread *td, int fd, char *buf, u_int count, error = VOP_READDIR(vp, &auio, fp->f_cred, &eofflag, NULL, NULL); foffset = auio.uio_offset; - if (error) { + if (error != 0) { VOP_UNLOCK(vp, 0); goto fail; } @@ -4013,6 +4052,7 @@ kern_getdirentries(struct thread *td, int fd, char *buf, u_int count, (vp->v_vflag & VV_ROOT) && (vp->v_mount->mnt_flag & MNT_UNION)) { struct vnode *tvp = vp; + vp = vp->v_mount->mnt_vnodecovered; VREF(vp); fp->f_vnode = vp; @@ -4049,6 +4089,7 @@ sys_getdents(td, uap) } */ *uap; { struct getdirentries_args ap; + ap.fd = uap->fd; ap.buf = uap->buf; ap.count = uap->count; @@ -4099,8 +4140,8 @@ sys_revoke(td, uap) { struct vnode *vp; struct vattr vattr; - int error; struct nameidata nd; + int error; NDINIT(&nd, LOOKUP, FOLLOW | LOCKLEAF | AUDITVNODE1, UIO_USERSPACE, uap->path, td); @@ -4114,15 +4155,15 @@ sys_revoke(td, uap) } #ifdef MAC error = mac_vnode_check_revoke(td->td_ucred, vp); - if (error) + if (error != 0) goto out; #endif error = VOP_GETATTR(vp, &vattr, td->td_ucred); - if (error) + if (error != 0) goto out; if (td->td_ucred->cr_uid != vattr.va_uid) { error = priv_check(td, PRIV_VFS_ADMIN); - if (error) + if (error != 0) goto out; } if (vcount(vp) > 1) @@ -4138,12 +4179,12 @@ sys_revoke(td, uap) * entry is held upon returning. */ int -getvnode(struct filedesc *fdp, int fd, cap_rights_t rights, struct file **fpp) +getvnode(struct filedesc *fdp, int fd, cap_rights_t *rightsp, struct file **fpp) { struct file *fp; int error; - error = fget_unlocked(fdp, fd, rights, 0, &fp, NULL); + error = fget_unlocked(fdp, fd, rightsp, 0, &fp, NULL); if (error != 0) return (error); @@ -4188,12 +4229,12 @@ sys_lgetfh(td, uap) int error; error = priv_check(td, PRIV_VFS_GETFH); - if (error) + if (error != 0) return (error); NDINIT(&nd, LOOKUP, NOFOLLOW | LOCKLEAF | AUDITVNODE1, UIO_USERSPACE, uap->fname, td); error = namei(&nd); - if (error) + if (error != 0) return (error); NDFREE(&nd, NDF_ONLY_PNBUF); vp = nd.ni_vp; @@ -4201,9 +4242,8 @@ sys_lgetfh(td, uap) fh.fh_fsid = vp->v_mount->mnt_stat.f_fsid; error = VOP_VPTOFH(vp, &fh.fh_fid); vput(vp); - if (error) - return (error); - error = copyout(&fh, uap->fhp, sizeof (fh)); + if (error == 0) + error = copyout(&fh, uap->fhp, sizeof (fh)); return (error); } @@ -4224,12 +4264,12 @@ sys_getfh(td, uap) int error; error = priv_check(td, PRIV_VFS_GETFH); - if (error) + if (error != 0) return (error); NDINIT(&nd, LOOKUP, FOLLOW | LOCKLEAF | AUDITVNODE1, UIO_USERSPACE, uap->fname, td); error = namei(&nd); - if (error) + if (error != 0) return (error); NDFREE(&nd, NDF_ONLY_PNBUF); vp = nd.ni_vp; @@ -4237,9 +4277,8 @@ sys_getfh(td, uap) fh.fh_fsid = vp->v_mount->mnt_stat.f_fsid; error = VOP_VPTOFH(vp, &fh.fh_fid); vput(vp); - if (error) - return (error); - error = copyout(&fh, uap->fhp, sizeof (fh)); + if (error == 0) + error = copyout(&fh, uap->fhp, sizeof (fh)); return (error); } @@ -4272,7 +4311,7 @@ sys_fhopen(td, uap) int indx; error = priv_check(td, PRIV_VFS_FHOPEN); - if (error) + if (error != 0) return (error); indx = -1; fmode = FFLAGS(uap->flags); @@ -4280,7 +4319,7 @@ sys_fhopen(td, uap) if (((fmode & (FREAD | FWRITE)) == 0) || (fmode & O_CREAT)) return (EINVAL); error = copyin(uap->u_fhp, &fhp, sizeof(fhp)); - if (error) + if (error != 0) return(error); /* find the mount point */ mp = vfs_busyfs(&fhp.fh_fsid); @@ -4289,11 +4328,11 @@ sys_fhopen(td, uap) /* now give me my vnode, it gets returned to me locked */ error = VFS_FHTOVP(mp, &fhp.fh_fid, LK_EXCLUSIVE, &vp); vfs_unbusy(mp); - if (error) + if (error != 0) return (error); error = falloc_noinstall(td, &fp); - if (error) { + if (error != 0) { vput(vp); return (error); } @@ -4306,7 +4345,7 @@ sys_fhopen(td, uap) td->td_dupfd = -1; #endif error = vn_open_vnode(vp, fmode, td->td_ucred, td, fp); - if (error) { + if (error != 0) { KASSERT(fp->f_ops == &badfileops, ("VOP_OPEN in fhopen() set f_ops")); KASSERT(td->td_dupfd < 0, @@ -4323,9 +4362,9 @@ sys_fhopen(td, uap) finit(fp, (fmode & FMASK) | (fp->f_flag & FHASLOCK), DTYPE_VNODE, vp, &vnops); VOP_UNLOCK(vp, 0); - if (fmode & O_TRUNC) { + if ((fmode & O_TRUNC) != 0) { error = fo_truncate(fp, 0, td->td_ucred, td); - if (error) + if (error != 0) goto bad; } @@ -4361,9 +4400,8 @@ sys_fhstat(td, uap) if (error != 0) return (error); error = kern_fhstat(td, fh, &sb); - if (error != 0) - return (error); - error = copyout(&sb, uap->sb, sizeof(sb)); + if (error == 0) + error = copyout(&sb, uap->sb, sizeof(sb)); return (error); } @@ -4375,13 +4413,13 @@ kern_fhstat(struct thread *td, struct fhandle fh, struct stat *sb) int error; error = priv_check(td, PRIV_VFS_FHSTAT); - if (error) + if (error != 0) return (error); if ((mp = vfs_busyfs(&fh.fh_fsid)) == NULL) return (ESTALE); error = VFS_FHTOVP(mp, &fh.fh_fid, LK_EXCLUSIVE, &vp); vfs_unbusy(mp); - if (error) + if (error != 0) return (error); error = vn_stat(vp, sb, td->td_ucred, NOCRED, td); vput(vp); @@ -4410,10 +4448,10 @@ sys_fhstatfs(td, uap) int error; error = copyin(uap->u_fhp, &fh, sizeof(fhandle_t)); - if (error) + if (error != 0) return (error); error = kern_fhstatfs(td, fh, &sf); - if (error) + if (error != 0) return (error); return (copyout(&sf, uap->buf, sizeof(sf))); } @@ -4427,22 +4465,22 @@ kern_fhstatfs(struct thread *td, fhandle_t fh, struct statfs *buf) int error; error = priv_check(td, PRIV_VFS_FHSTATFS); - if (error) + if (error != 0) return (error); if ((mp = vfs_busyfs(&fh.fh_fsid)) == NULL) return (ESTALE); error = VFS_FHTOVP(mp, &fh.fh_fid, LK_EXCLUSIVE, &vp); - if (error) { + if (error != 0) { vfs_unbusy(mp); return (error); } vput(vp); error = prison_canseemount(td->td_ucred, mp); - if (error) + if (error != 0) goto out; #ifdef MAC error = mac_mount_check_stat(td->td_ucred, mp); - if (error) + if (error != 0) goto out; #endif /* @@ -4466,11 +4504,12 @@ kern_posix_fallocate(struct thread *td, int fd, off_t offset, off_t len) struct file *fp; struct mount *mp; struct vnode *vp; + cap_rights_t rights; off_t olen, ooffset; int error; fp = NULL; - error = fget(td, fd, CAP_WRITE, &fp); + error = fget(td, fd, cap_rights_init(&rights, CAP_WRITE), &fp); if (error != 0) goto out; @@ -4562,6 +4601,7 @@ kern_posix_fadvise(struct thread *td, int fd, off_t offset, off_t len, struct fadvise_info *fa, *new; struct file *fp; struct vnode *vp; + cap_rights_t rights; off_t end; int error; @@ -4582,7 +4622,7 @@ kern_posix_fadvise(struct thread *td, int fd, off_t offset, off_t len, return (EINVAL); } /* XXX: CAP_POSIX_FADVISE? */ - error = fget(td, fd, CAP_NONE, &fp); + error = fget(td, fd, cap_rights_init(&rights), &fp); if (error != 0) goto out; diff --git a/sys/mips/atheros/ar71xx_gpio.c b/sys/mips/atheros/ar71xx_gpio.c index 6ad8df4242a7..c6933bc1b067 100644 --- a/sys/mips/atheros/ar71xx_gpio.c +++ b/sys/mips/atheros/ar71xx_gpio.c @@ -41,6 +41,7 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include #include @@ -418,7 +419,14 @@ ar71xx_gpio_attach(device_t dev) "pinon", &pinon) != 0) pinon = 0; device_printf(dev, "gpio pinmask=0x%x\n", mask); - for (i = 0, j = 0; j < maxpin; j++) { + for (j = 0; j <= maxpin; j++) { + if ((mask & (1 << j)) == 0) + continue; + sc->gpio_npins++; + } + sc->gpio_pins = malloc(sizeof(*sc->gpio_pins) * sc->gpio_npins, + M_DEVBUF, M_WAITOK | M_ZERO); + for (i = 0, j = 0; j <= maxpin; j++) { if ((mask & (1 << j)) == 0) continue; snprintf(sc->gpio_pins[i].gp_name, GPIOMAXNAME, @@ -429,7 +437,6 @@ ar71xx_gpio_attach(device_t dev) ar71xx_gpio_pin_configure(sc, &sc->gpio_pins[i], DEFAULT_CAPS); i++; } - sc->gpio_npins = i; for (i = 0; i < sc->gpio_npins; i++) { j = sc->gpio_pins[i].gp_pin; if ((pinon & (1 << j)) != 0) @@ -455,6 +462,7 @@ ar71xx_gpio_detach(device_t dev) bus_release_resource(dev, SYS_RES_MEMORY, sc->gpio_mem_rid, sc->gpio_mem_res); + free(sc->gpio_pins, M_DEVBUF); mtx_destroy(&sc->gpio_mtx); return(0); diff --git a/sys/mips/atheros/ar71xx_gpiovar.h b/sys/mips/atheros/ar71xx_gpiovar.h index 3489f5a7aea5..a1c6e2f1c5a6 100644 --- a/sys/mips/atheros/ar71xx_gpiovar.h +++ b/sys/mips/atheros/ar71xx_gpiovar.h @@ -64,7 +64,7 @@ struct ar71xx_gpio_softc { int gpio_irq_rid; void *gpio_ih; int gpio_npins; - struct gpio_pin gpio_pins[AR71XX_GPIO_PINS]; + struct gpio_pin *gpio_pins; }; #endif /* __AR71XX_GPIOVAR_H__ */ diff --git a/sys/mips/atheros/if_arge.c b/sys/mips/atheros/if_arge.c index 21b945f3f6d1..aabab52187bf 100644 --- a/sys/mips/atheros/if_arge.c +++ b/sys/mips/atheros/if_arge.c @@ -142,6 +142,7 @@ static int arge_resume(device_t); static int arge_rx_ring_init(struct arge_softc *); static void arge_rx_ring_free(struct arge_softc *sc); static int arge_tx_ring_init(struct arge_softc *); +static void arge_tx_ring_free(struct arge_softc *); #ifdef DEVICE_POLLING static int arge_poll(struct ifnet *, enum poll_cmd, int); #endif @@ -1278,6 +1279,7 @@ arge_stop(struct arge_softc *sc) /* Flush FIFO and free any existing mbufs */ arge_flush_ddr(sc); arge_rx_ring_free(sc); + arge_tx_ring_free(sc); } @@ -1707,6 +1709,30 @@ arge_tx_ring_init(struct arge_softc *sc) return (0); } +/* + * Free the Tx ring, unload any pending dma transaction and free the mbuf. + */ +static void +arge_tx_ring_free(struct arge_softc *sc) +{ + struct arge_txdesc *txd; + int i; + + /* Free the Tx buffers. */ + for (i = 0; i < ARGE_TX_RING_COUNT; i++) { + txd = &sc->arge_cdata.arge_txdesc[i]; + if (txd->tx_dmamap) { + bus_dmamap_sync(sc->arge_cdata.arge_tx_tag, + txd->tx_dmamap, BUS_DMASYNC_POSTWRITE); + bus_dmamap_unload(sc->arge_cdata.arge_tx_tag, + txd->tx_dmamap); + } + if (txd->tx_m) + m_freem(txd->tx_m); + txd->tx_m = NULL; + } +} + /* * Initialize the RX descriptors and allocate mbufs for them. Note that * we arrange the descriptors in a closed ring, so that the last descriptor diff --git a/sys/mips/cavium/octeon_rnd.c b/sys/mips/cavium/octeon_rnd.c index 634a4fa86f04..298f06aee1dd 100644 --- a/sys/mips/cavium/octeon_rnd.c +++ b/sys/mips/cavium/octeon_rnd.c @@ -131,7 +131,7 @@ octeon_rnd_harvest(void *arg) for (i = 0; i < OCTEON_RND_WORDS; i++) sc->sc_entropy[i] = cvmx_rng_get_random64(); random_harvest(sc->sc_entropy, sizeof sc->sc_entropy, - sizeof sc->sc_entropy * 8, 0, RANDOM_PURE); + (sizeof(sc->sc_entropy)*8)/2, 0, RANDOM_PURE); callout_reset(&sc->sc_callout, hz * 5, octeon_rnd_harvest, sc); } diff --git a/sys/mips/conf/GXEMUL32 b/sys/mips/conf/GXEMUL32 new file mode 100644 index 000000000000..6bd756f20f7d --- /dev/null +++ b/sys/mips/conf/GXEMUL32 @@ -0,0 +1,61 @@ +# +# GXEMUL "oldtestmips" sample kernel configuration. +# +# $FreeBSD$ +# + +ident GXEMUL + +machine mips mips +cpu CPU_MIPS4KC + +options HZ=100 + +makeoptions KERNLOADADDR=0x80100000 + +include "../gxemul/std.gxemul" + +hints "GXEMUL.hints" #Default places to look for devices. + +makeoptions DEBUG=-g #Build kernel with gdb(1) debug symbols + +makeoptions MODULES_OVERRIDE="" + +options DDB +options KDB + +# Make an SMP-capable kernel by default +options SMP # Symmetric MultiProcessor Kernel + +options SCHED_ULE +options INET # InterNETworking +options INET6 # IPv6 communications protocols + +options FFS #Berkeley Fast Filesystem + +# Debugging for use in -current +#options DEADLKRES #Enable the deadlock resolver +options INVARIANTS #Enable calls of extra sanity checking +options INVARIANT_SUPPORT #Extra sanity checks of internal structures, required by INVARIANTS +#options WITNESS #Enable checks to detect deadlocks and cycles +#options WITNESS_SKIPSPIN #Don't run witness on spinlocks for speed + +options ROOTDEVNAME=\"ufs:gxemul_disk0\" + +device gxemul_cons +device gxemul_disk +device gxemul_ether + +# Pseudo devices. +device loop # Network loopback +device random # Entropy device +device ether # Ethernet support +device tun # Packet tunnel. +device md # Memory "disks" +device gif # IPv6 and IPv4 tunneling +device faith # IPv6-to-IPv4 relaying (translation) + +# The `bpf' device enables the Berkeley Packet Filter. +# Be aware of the administrative consequences of enabling this! +# Note that 'bpf' is required for DHCP. +device bpf # Berkeley packet filter diff --git a/sys/mips/gxemul/mpreg.h b/sys/mips/gxemul/mpreg.h index e09946d88e10..f562d07cb586 100644 --- a/sys/mips/gxemul/mpreg.h +++ b/sys/mips/gxemul/mpreg.h @@ -43,10 +43,17 @@ #define GXEMUL_MP_DEV_IPI_READ 0x00c0 #define GXEMUL_MP_DEV_CYCLES 0x00d0 +#ifdef _LP64 #define GXEMUL_MP_DEV_FUNCTION(f) \ (volatile uint64_t *)MIPS_PHYS_TO_DIRECT_UNCACHED(GXEMUL_MP_DEV_BASE + (f)) #define GXEMUL_MP_DEV_READ(f) \ (volatile uint64_t)*GXEMUL_MP_DEV_FUNCTION(f) +#else +#define GXEMUL_MP_DEV_FUNCTION(f) \ + (volatile uint32_t *)MIPS_PHYS_TO_DIRECT_UNCACHED(GXEMUL_MP_DEV_BASE + (f)) +#define GXEMUL_MP_DEV_READ(f) \ + (volatile uint32_t)*GXEMUL_MP_DEV_FUNCTION(f) +#endif #define GXEMUL_MP_DEV_WRITE(f, v) \ *GXEMUL_MP_DEV_FUNCTION(f) = (v) diff --git a/sys/mips/include/sf_buf.h b/sys/mips/include/sf_buf.h index b9efaf0d8b24..e5d981f3b789 100644 --- a/sys/mips/include/sf_buf.h +++ b/sys/mips/include/sf_buf.h @@ -41,6 +41,18 @@ /* In 64 bit the whole memory is directly mapped */ struct sf_buf; +static inline struct sf_buf * +sf_buf_alloc(struct vm_page *m, int pri) +{ + + return ((struct sf_buf *)m); +} + +static inline void +sf_buf_free(struct sf_buf *sf) +{ +} + static __inline vm_offset_t sf_buf_kva(struct sf_buf *sf) { @@ -66,6 +78,9 @@ struct sf_buf { vm_offset_t kva; /* va of mapping */ }; +struct sf_buf * sf_buf_alloc(struct vm_page *m, int flags); +void sf_buf_free(struct sf_buf *sf); + static __inline vm_offset_t sf_buf_kva(struct sf_buf *sf) { diff --git a/sys/mips/mips/bcopy.S b/sys/mips/mips/bcopy.S new file mode 100644 index 000000000000..a7ac1f2aee3d --- /dev/null +++ b/sys/mips/mips/bcopy.S @@ -0,0 +1,286 @@ +/* $NetBSD: bcopy.S,v 1.3 2009/12/14 00:39:00 matt Exp $ */ + +/* + * Mach Operating System + * Copyright (c) 1993 Carnegie Mellon University + * All Rights Reserved. + * + * Permission to use, copy, modify and distribute this software and its + * documentation is hereby granted, provided that both the copyright + * notice and this permission notice appear in all copies of the + * software, derivative works or modified versions, and any portions + * thereof, and that both notices appear in supporting documentation. + * + * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" + * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR + * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. + * + * Carnegie Mellon requests users of this software to return to + * + * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU + * School of Computer Science + * Carnegie Mellon University + * Pittsburgh PA 15213-3890 + * + * any improvements or extensions that they make and grant Carnegie Mellon + * the rights to redistribute these changes. + */ + +/* + * File: mips_bcopy.s + * Author: Chris Maeda + * Date: June 1993 + * + * Fast copy routine. Derived from aligned_block_copy. + */ + + +#include +__FBSDID("$FreeBSD$"); + +#include + +#if defined(LIBC_SCCS) && !defined(lint) +#if 0 + ASMSTR("from: @(#)mips_bcopy.s 2.2 CMU 18/06/93") +#else + ASMSTR("$NetBSD: bcopy.S,v 1.3 2009/12/14 00:39:00 matt Exp $") +#endif +#endif /* LIBC_SCCS and not lint */ + +#ifdef __ABICALLS__ + .abicalls +#endif + +/* + * bcopy(caddr_t src, caddr_t dst, unsigned int len) + * + * a0 src address + * a1 dst address + * a2 length + */ + +#define SRCREG a0 +#define DSTREG a1 +#define SIZEREG a2 + +LEAF(memcpy) + .set noat + .set noreorder + + move v0, a0 + move a0, a1 + move a1, v0 + +ALEAF(bcopy) +ALEAF(ovbcopy) + /* + * Make sure we can copy forwards. + */ + sltu t0,SRCREG,DSTREG # t0 == SRCREG < DSTREG + bne t0,zero,6f # copy backwards + + /* + * There are four alignment cases (with frequency) + * (Based on measurements taken with a DECstation 5000/200 + * inside a Mach kernel.) + * + * aligned -> aligned (mostly) + * unaligned -> aligned (sometimes) + * aligned,unaligned -> unaligned (almost never) + * + * Note that we could add another case that checks if + * the destination and source are unaligned but the + * copy is alignable. eg if src and dest are both + * on a halfword boundary. + */ + andi t1,DSTREG,(SZREG-1) # get last bits of dest + bne t1,zero,3f # dest unaligned + andi t0,SRCREG,(SZREG-1) # get last bits of src + bne t0,zero,5f + + /* + * Forward aligned->aligned copy, 8 words at a time. + */ +98: + li AT,-(SZREG*8) + and t0,SIZEREG,AT # count truncated to multiples + PTR_ADDU a3,SRCREG,t0 # run fast loop up to this addr + sltu AT,SRCREG,a3 # any work to do? + beq AT,zero,2f + PTR_SUBU SIZEREG,t0 + + /* + * loop body + */ +1: # cp + REG_L t3,(0*SZREG)(SRCREG) + REG_L v1,(1*SZREG)(SRCREG) + REG_L t0,(2*SZREG)(SRCREG) + REG_L t1,(3*SZREG)(SRCREG) + PTR_ADDU SRCREG,SZREG*8 + REG_S t3,(0*SZREG)(DSTREG) + REG_S v1,(1*SZREG)(DSTREG) + REG_S t0,(2*SZREG)(DSTREG) + REG_S t1,(3*SZREG)(DSTREG) + REG_L t1,(-1*SZREG)(SRCREG) + REG_L t0,(-2*SZREG)(SRCREG) + REG_L v1,(-3*SZREG)(SRCREG) + REG_L t3,(-4*SZREG)(SRCREG) + PTR_ADDU DSTREG,SZREG*8 + REG_S t1,(-1*SZREG)(DSTREG) + REG_S t0,(-2*SZREG)(DSTREG) + REG_S v1,(-3*SZREG)(DSTREG) + bne SRCREG,a3,1b + REG_S t3,(-4*SZREG)(DSTREG) + + /* + * Copy a word at a time, no loop unrolling. + */ +2: # wordcopy + andi t2,SIZEREG,(SZREG-1) # get byte count / SZREG + PTR_SUBU t2,SIZEREG,t2 # t2 = words to copy * SZREG + beq t2,zero,3f + PTR_ADDU t0,SRCREG,t2 # stop at t0 + PTR_SUBU SIZEREG,SIZEREG,t2 +1: + REG_L t3,0(SRCREG) + PTR_ADDU SRCREG,SZREG + REG_S t3,0(DSTREG) + bne SRCREG,t0,1b + PTR_ADDU DSTREG,SZREG + +3: # bytecopy + beq SIZEREG,zero,4f # nothing left to do? + nop +1: + lb t3,0(SRCREG) + PTR_ADDU SRCREG,1 + sb t3,0(DSTREG) + PTR_SUBU SIZEREG,1 + bgtz SIZEREG,1b + PTR_ADDU DSTREG,1 + +4: # copydone + j ra + nop + + /* + * Copy from unaligned source to aligned dest. + */ +5: # destaligned + andi t0,SIZEREG,(SZREG-1) # t0 = bytecount mod SZREG + PTR_SUBU a3,SIZEREG,t0 # number of words to transfer + beq a3,zero,3b + nop + move SIZEREG,t0 # this many to do after we are done + PTR_ADDU a3,SRCREG,a3 # stop point + +1: + REG_LHI t3,0(SRCREG) + REG_LLO t3,SZREG-1(SRCREG) + PTR_ADDI SRCREG,SZREG + REG_S t3,0(DSTREG) + bne SRCREG,a3,1b + PTR_ADDI DSTREG,SZREG + + b 3b + nop + +6: # backcopy -- based on above + PTR_ADDU SRCREG,SIZEREG + PTR_ADDU DSTREG,SIZEREG + andi t1,DSTREG,SZREG-1 # get last 3 bits of dest + bne t1,zero,3f + andi t0,SRCREG,SZREG-1 # get last 3 bits of src + bne t0,zero,5f + + /* + * Forward aligned->aligned copy, 8*4 bytes at a time. + */ + li AT,(-8*SZREG) + and t0,SIZEREG,AT # count truncated to multiple of 32 + beq t0,zero,2f # any work to do? + PTR_SUBU SIZEREG,t0 + PTR_SUBU a3,SRCREG,t0 + + /* + * loop body + */ +1: # cp + REG_L t3,(-4*SZREG)(SRCREG) + REG_L v1,(-3*SZREG)(SRCREG) + REG_L t0,(-2*SZREG)(SRCREG) + REG_L t1,(-1*SZREG)(SRCREG) + PTR_SUBU SRCREG,8*SZREG + REG_S t3,(-4*SZREG)(DSTREG) + REG_S v1,(-3*SZREG)(DSTREG) + REG_S t0,(-2*SZREG)(DSTREG) + REG_S t1,(-1*SZREG)(DSTREG) + REG_L t1,(3*SZREG)(SRCREG) + REG_L t0,(2*SZREG)(SRCREG) + REG_L v1,(1*SZREG)(SRCREG) + REG_L t3,(0*SZREG)(SRCREG) + PTR_SUBU DSTREG,8*SZREG + REG_S t1,(3*SZREG)(DSTREG) + REG_S t0,(2*SZREG)(DSTREG) + REG_S v1,(1*SZREG)(DSTREG) + bne SRCREG,a3,1b + REG_S t3,(0*SZREG)(DSTREG) + + /* + * Copy a word at a time, no loop unrolling. + */ +2: # wordcopy + andi t2,SIZEREG,SZREG-1 # get byte count / 4 + PTR_SUBU t2,SIZEREG,t2 # t2 = number of words to copy + beq t2,zero,3f + PTR_SUBU t0,SRCREG,t2 # stop at t0 + PTR_SUBU SIZEREG,SIZEREG,t2 +1: + REG_L t3,-SZREG(SRCREG) + PTR_SUBU SRCREG,SZREG + REG_S t3,-SZREG(DSTREG) + bne SRCREG,t0,1b + PTR_SUBU DSTREG,SZREG + +3: # bytecopy + beq SIZEREG,zero,4f # nothing left to do? + nop +1: + lb t3,-1(SRCREG) + PTR_SUBU SRCREG,1 + sb t3,-1(DSTREG) + PTR_SUBU SIZEREG,1 + bgtz SIZEREG,1b + PTR_SUBU DSTREG,1 + +4: # copydone + j ra + nop + + /* + * Copy from unaligned source to aligned dest. + */ +5: # destaligned + andi t0,SIZEREG,SZREG-1 # t0 = bytecount mod 4 + PTR_SUBU a3,SIZEREG,t0 # number of words to transfer + beq a3,zero,3b + nop + move SIZEREG,t0 # this many to do after we are done + PTR_SUBU a3,SRCREG,a3 # stop point + +1: + REG_LHI t3,-SZREG(SRCREG) + REG_LLO t3,-1(SRCREG) + PTR_SUBU SRCREG,SZREG + REG_S t3,-SZREG(DSTREG) + bne SRCREG,a3,1b + PTR_SUBU DSTREG,SZREG + + b 3b + nop + + .set reorder + .set at +END(memcpy) diff --git a/sys/mips/mips/support.S b/sys/mips/mips/support.S index 7acebf028728..42800000ceb2 100644 --- a/sys/mips/mips/support.S +++ b/sys/mips/mips/support.S @@ -506,98 +506,6 @@ LEAF(fswintrberr) li v0, -1 END(fswintrberr) -/* - * memcpy(to, from, len) - * {ov}bcopy(from, to, len) - */ -LEAF(memcpy) - .set noreorder - move v0, a0 # swap from and to - move a0, a1 - move a1, v0 -ALEAF(bcopy) -ALEAF(ovbcopy) - .set noreorder - PTR_ADDU t0, a0, a2 # t0 = end of s1 region - sltu t1, a1, t0 - sltu t2, a0, a1 - and t1, t1, t2 # t1 = true if from < to < (from+len) - beq t1, zero, forward # non overlapping, do forward copy - slt t2, a2, 12 # check for small copy - - ble a2, zero, 2f - PTR_ADDU t1, a1, a2 # t1 = end of to region -1: - lb v1, -1(t0) # copy bytes backwards, - PTR_SUBU t0, t0, 1 # doesnt happen often so do slow way - PTR_SUBU t1, t1, 1 - bne t0, a0, 1b - sb v1, 0(t1) -2: - j ra - nop -forward: - bne t2, zero, smallcpy # do a small bcopy - xor v1, a0, a1 # compare low two bits of addresses - and v1, v1, 3 - PTR_SUBU a3, zero, a1 # compute # bytes to word align address - beq v1, zero, aligned # addresses can be word aligned - and a3, a3, 3 - - beq a3, zero, 1f - PTR_SUBU a2, a2, a3 # subtract from remaining count - LWHI v1, 0(a0) # get next 4 bytes (unaligned) - LWLO v1, 3(a0) - PTR_ADDU a0, a0, a3 - SWHI v1, 0(a1) # store 1, 2, or 3 bytes to align a1 - PTR_ADDU a1, a1, a3 -1: - and v1, a2, 3 # compute number of words left - PTR_SUBU a3, a2, v1 - move a2, v1 - PTR_ADDU a3, a3, a0 # compute ending address -2: - LWHI v1, 0(a0) # copy words a0 unaligned, a1 aligned - LWLO v1, 3(a0) - PTR_ADDU a0, a0, 4 - sw v1, 0(a1) - PTR_ADDU a1, a1, 4 - bne a0, a3, 2b - nop # We have to do this mmu-bug. - b smallcpy - nop -aligned: - beq a3, zero, 1f - PTR_SUBU a2, a2, a3 # subtract from remaining count - LWHI v1, 0(a0) # copy 1, 2, or 3 bytes to align - PTR_ADDU a0, a0, a3 - SWHI v1, 0(a1) - PTR_ADDU a1, a1, a3 -1: - and v1, a2, 3 # compute number of whole words left - PTR_SUBU a3, a2, v1 - move a2, v1 - PTR_ADDU a3, a3, a0 # compute ending address -2: - lw v1, 0(a0) # copy words - PTR_ADDU a0, a0, 4 - sw v1, 0(a1) - bne a0, a3, 2b - PTR_ADDU a1, a1, 4 -smallcpy: - ble a2, zero, 2f - PTR_ADDU a3, a2, a0 # compute ending address -1: - lbu v1, 0(a0) # copy bytes - PTR_ADDU a0, a0, 1 - sb v1, 0(a1) - bne a0, a3, 1b - PTR_ADDU a1, a1, 1 # MMU BUG ? can not do -1(a1) at 0x80000000!! -2: - j ra - nop -END(memcpy) - /* * memset(void *s1, int c, int len) * NetBSD: memset.S,v 1.3 2001/10/16 15:40:53 uch Exp diff --git a/sys/mips/mips/vm_machdep.c b/sys/mips/mips/vm_machdep.c index 86dfde9c137f..c42f6406f26b 100644 --- a/sys/mips/mips/vm_machdep.c +++ b/sys/mips/mips/vm_machdep.c @@ -76,7 +76,9 @@ __FBSDID("$FreeBSD$"); #include #include +#ifndef __mips_n64 #include +#endif #ifndef NSFBUFS #define NSFBUFS (512 + maxusers * 16) @@ -523,7 +525,6 @@ sf_buf_init(void *arg) } sf_buf_alloc_want = 0; } -#endif /* * Get an sf_buf from the freelist. Will block if none are available. @@ -531,7 +532,6 @@ sf_buf_init(void *arg) struct sf_buf * sf_buf_alloc(struct vm_page *m, int flags) { -#ifndef __mips_n64 struct sf_buf *sf; int error; @@ -560,9 +560,6 @@ sf_buf_alloc(struct vm_page *m, int flags) } mtx_unlock(&sf_freelist.sf_lock); return (sf); -#else - return ((struct sf_buf *)m); -#endif } /* @@ -571,7 +568,6 @@ sf_buf_alloc(struct vm_page *m, int flags) void sf_buf_free(struct sf_buf *sf) { -#ifndef __mips_n64 pmap_qremove(sf->kva, 1); mtx_lock(&sf_freelist.sf_lock); SLIST_INSERT_HEAD(&sf_freelist.sf_head, sf, free_list); @@ -579,8 +575,8 @@ sf_buf_free(struct sf_buf *sf) if (sf_buf_alloc_want > 0) wakeup(&sf_freelist); mtx_unlock(&sf_freelist.sf_lock); -#endif } +#endif /* !__mips_n64 */ /* * Software interrupt handler for queued VM system processing. diff --git a/sys/mips/nlm/board.c b/sys/mips/nlm/board.c index c6fd59d49216..e7fd92efe3cd 100644 --- a/sys/mips/nlm/board.c +++ b/sys/mips/nlm/board.c @@ -280,15 +280,8 @@ nlm_setup_port_defaults(struct xlp_port_ivars *p) * 1 3 9 0 */ static void -nlm_board_get_phyaddr(int block, int port, int *mdio, int *phyaddr) +nlm_board_get_phyaddr(int block, int port, int *phyaddr) { - - /* XXXJC: this is a board feature, check for chip not proper */ - if (nlm_is_xlp3xx() || (nlm_is_xlp8xx() && block == 4)) - *mdio = 0; - else - *mdio = 1; - switch (block) { case 0: switch (port) { case 0: *phyaddr = 4; break; @@ -377,7 +370,7 @@ nlm_print_processor_info(void) * at run-time goes here */ static int -nlm_setup_xlp_board(void) +nlm_setup_xlp_board(int node) { struct xlp_board_info *boardp; struct xlp_node_info *nodep; @@ -385,17 +378,18 @@ nlm_setup_xlp_board(void) struct xlp_block_ivars *blockp; struct xlp_port_ivars *portp; uint64_t cpldbase, nae_pcibase; - int node, block, port, rv, dbtype, usecpld; + int block, port, rv, dbtype, usecpld = 0, evp = 0, svp = 0; uint8_t *b; /* start with a clean slate */ boardp = &xlp_board_info; - memset(boardp, 0, sizeof(xlp_board_info)); - boardp->nodemask = 0x1; /* only node 0 */ + if (boardp->nodemask == 0) + memset(boardp, 0, sizeof(xlp_board_info)); + boardp->nodemask |= (1 << node); nlm_print_processor_info(); b = board_eeprom_buf; - rv = nlm_board_eeprom_read(0, EEPROM_I2CBUS, EEPROM_I2CADDR, 0, b, + rv = nlm_board_eeprom_read(node, EEPROM_I2CBUS, EEPROM_I2CADDR, 0, b, EEPROM_SIZE); if (rv == 0) { board_eeprom_set = 1; @@ -409,88 +403,48 @@ nlm_setup_xlp_board(void) printf("Board Info: Error on EEPROM read (i2c@%d %#X).\n", EEPROM_I2CBUS, EEPROM_I2CADDR); + nae_pcibase = nlm_get_nae_pcibase(node); + nodep = &boardp->nodes[node]; + naep = &nodep->nae_ivars; + naep->node = node; - /* XXXJC: check for boards with right CPLD, for now - * 4xx PCI cards don't have CPLD with daughter - * card info */ - usecpld = !nlm_is_xlp4xx(); + /* frequency at which network block runs */ + naep->freq = 500; - for (node = 0; node < XLP_MAX_NODES; node++) { - if ((boardp->nodemask & (1 << node)) == 0) - continue; - nae_pcibase = nlm_get_nae_pcibase(node); - nodep = &boardp->nodes[node]; - naep = &nodep->nae_ivars; - naep->node = node; + /* CRC16 polynomial used for flow table generation */ + naep->flow_crc_poly = 0xffff; + naep->hw_parser_en = 1; + naep->prepad_en = 1; + naep->prepad_size = 3; /* size in 16 byte units */ + naep->ieee_1588_en = 1; - naep->nblocks = nae_num_complex(nae_pcibase); - /* 3xx chips lie shamelessly about this */ - if (nlm_is_xlp3xx()) - naep->nblocks = naep->nblocks - 1; - naep->blockmask = (1 << naep->nblocks) - 1; /* XXXJC: redundant */ - naep->xauimask = 0x0; /* set this based on daughter card */ - naep->sgmiimask = 0x0; /* set this based on daughter card */ - - /* frequency at which network block runs */ - naep->freq = 500; - - /* CRC16 polynomial used for flow table generation */ - naep->flow_crc_poly = 0xffff; - naep->hw_parser_en = 1; - naep->prepad_en = 1; - naep->prepad_size = 3; /* size in 16 byte units */ - - naep->ieee_1588_en = 1; - cpldbase = nlm_board_cpld_base(node, XLP_EVB_CPLD_CHIPSELECT); - - for (block = 0; block < naep->nblocks; block++) { - blockp = &naep->block_ivars[block]; - blockp->block = block; - if (usecpld) - dbtype = nlm_board_cpld_dboard_type(cpldbase, - block); - else - dbtype = DCARD_XAUI; /* default XAUI */ - - if (block == 4) { - /* management block 4 on 8xx */ - blockp->type = SGMIIC; - blockp->portmask = 0x3; - naep->sgmiimask |= (1 << block); - } else { - switch (dbtype) { - case DCARD_ILAKEN: - blockp->type = ILC; - blockp->portmask = 0x1; - naep->xauimask |= (1 << block); - break; - case DCARD_SGMII: - blockp->type = SGMIIC; - blockp->portmask = 0xf; - naep->sgmiimask |= (1 << block); - break; - case DCARD_XAUI: - default: - blockp->type = XAUIC; - blockp->portmask = 0x1; - naep->xauimask |= (1 << block); - break; - } - } - for (port = 0; port < PORTS_PER_CMPLX; port++) { - if ((blockp->portmask & (1 << port)) == 0) - continue; - portp = &blockp->port_ivars[port]; - nlm_board_get_phyaddr(block, port, - &portp->mdio_bus, &portp->phy_addr); - portp->port = port; - portp->block = block; - portp->node = node; - portp->type = blockp->type; - nlm_setup_port_defaults(portp); - } - } + naep->ilmask = 0x0; /* set this based on daughter card */ + naep->xauimask = 0x0; /* set this based on daughter card */ + naep->sgmiimask = 0x0; /* set this based on daughter card */ + naep->nblocks = nae_num_complex(nae_pcibase); + if (strncmp(&b[16], "PCIE", 4) == 0) { + usecpld = 0; /* XLP PCIe card */ + /* Broadcom's XLP PCIe card has the following + * blocks fixed. + * blk 0-XAUI, 1-XAUI, 4-SGMII(one port) */ + naep->blockmask = 0x13; + } else if (strncmp(&b[16], "MB-EVP", 6) == 0) { + usecpld = 1; /* XLP non-PCIe card which has CPLD */ + evp = 1; + naep->blockmask = (1 << naep->nblocks) - 1; + } else if ((strncmp(&b[16], "MB-S", 4) == 0) || + (strncmp(&b[16], "MB_S", 4) == 0)) { + usecpld = 1; /* XLP non-PCIe card which has CPLD */ + svp = 1; + /* 3xx chip reports one block extra which is a bug */ + naep->nblocks = naep->nblocks - 1; + naep->blockmask = (1 << naep->nblocks) - 1; + } else { + printf("ERROR!!! Board type:%7s didn't match any board" + " type we support\n", &b[16]); + return (-1); } + cpldbase = nlm_board_cpld_base(node, XLP_EVB_CPLD_CHIPSELECT); /* pretty print network config */ printf("Network config"); @@ -498,30 +452,86 @@ nlm_setup_xlp_board(void) printf("(from CPLD@%d):\n", XLP_EVB_CPLD_CHIPSELECT); else printf("(defaults):\n"); - for (node = 0; node < XLP_MAX_NODES; node++) { - if ((boardp->nodemask & (1 << node)) == 0) - continue; - nodep = &boardp->nodes[node]; - naep = &nodep->nae_ivars; - printf(" NAE@%d Blocks: ", node); - for (block = 0; block < naep->nblocks; block++) { - char *s = "???"; + printf(" NAE@%d Blocks: ", node); + for (block = 0; block < naep->nblocks; block++) { + char *s = "???"; - blockp = &naep->block_ivars[block]; - switch (blockp->type) { - case SGMIIC : s = "SGMII"; break; - case XAUIC : s = "XAUI"; break; - case ILC : s = "IL"; break; + if ((naep->blockmask & (1 << block)) == 0) + continue; + blockp = &naep->block_ivars[block]; + blockp->block = block; + if (usecpld) + dbtype = nlm_board_cpld_dboard_type(cpldbase, block); + else + dbtype = DCARD_XAUI; /* default XAUI */ + + /* XLP PCIe cards */ + if ((!evp && !svp) && ((block == 2) || (block == 3))) + dbtype = DCARD_NOT_PRSNT; + + if (block == 4) { + /* management block 4 on 8xx or XLP PCIe */ + blockp->type = SGMIIC; + if (evp) + blockp->portmask = 0x3; + else + blockp->portmask = 0x1; + naep->sgmiimask |= (1 << block); + } else { + switch (dbtype) { + case DCARD_ILAKEN: + blockp->type = ILC; + blockp->portmask = 0x1; + naep->ilmask |= (1 << block); + break; + case DCARD_SGMII: + blockp->type = SGMIIC; + blockp->portmask = 0xf; + naep->sgmiimask |= (1 << block); + break; + case DCARD_XAUI: + blockp->type = XAUIC; + blockp->portmask = 0x1; + naep->xauimask |= (1 << block); + break; + default: /* DCARD_NOT_PRSNT */ + blockp->type = UNKNOWN; + blockp->portmask = 0; + break; } - printf(" [%d %s]", block, s); } - printf("\n"); + if (blockp->type != UNKNOWN) { + for (port = 0; port < PORTS_PER_CMPLX; port++) { + if ((blockp->portmask & (1 << port)) == 0) + continue; + portp = &blockp->port_ivars[port]; + nlm_board_get_phyaddr(block, port, + &portp->phy_addr); + if (svp || (block == 4)) + portp->mdio_bus = 0; + else + portp->mdio_bus = 1; + portp->port = port; + portp->block = block; + portp->node = node; + portp->type = blockp->type; + nlm_setup_port_defaults(portp); + } + } + switch (blockp->type) { + case SGMIIC : s = "SGMII"; break; + case XAUIC : s = "XAUI"; break; + case ILC : s = "IL"; break; + } + printf(" [%d %s]", block, s); } + printf("\n"); return (0); } int nlm_board_info_setup(void) { - nlm_setup_xlp_board(); + if (nlm_setup_xlp_board(0) != 0) + return (-1); return (0); } diff --git a/sys/mips/nlm/board.h b/sys/mips/nlm/board.h index 859a65416f9c..2f1b433cd3d3 100644 --- a/sys/mips/nlm/board.h +++ b/sys/mips/nlm/board.h @@ -116,6 +116,7 @@ struct xlp_nae_ivars { int node; int nblocks; u_int blockmask; + u_int ilmask; u_int xauimask; u_int sgmiimask; int freq; diff --git a/sys/mips/nlm/board_cpld.c b/sys/mips/nlm/board_cpld.c index 883a32128c9d..ac55c0b883a9 100644 --- a/sys/mips/nlm/board_cpld.c +++ b/sys/mips/nlm/board_cpld.c @@ -55,13 +55,13 @@ int nlm_cpld_read(uint64_t base, int reg) uint16_t val; val = *(volatile uint16_t *)(long)(base + reg * 2); - return bswap16(val); + return le16toh(val); } static __inline void nlm_cpld_write(uint64_t base, int reg, uint16_t data) { - bswap16(data); + data = htole16(data); *(volatile uint16_t *)(long)(base + reg * 2) = data; } diff --git a/sys/mips/nlm/dev/net/nae.c b/sys/mips/nlm/dev/net/nae.c index d97b29038625..9f06372885e7 100644 --- a/sys/mips/nlm/dev/net/nae.c +++ b/sys/mips/nlm/dev/net/nae.c @@ -59,31 +59,17 @@ nlm_nae_flush_free_fifo(uint64_t nae_base, int nblocks) } void -nlm_program_nae_parser_seq_fifo(uint64_t nae_base, int nblock, +nlm_program_nae_parser_seq_fifo(uint64_t nae_base, int maxports, struct nae_port_config *cfg) { uint32_t val; - int start = 0, size, i, j; - - for (i = 0; i < nblock; i++) { - for (j = 0; j < PORTS_PER_CMPLX; j++) { - if ((i == 4) && (j > 1)) - size = 0; - else - size = cfg[(i*4)+j].pseq_fifo_size; - start += size; - } - } - - for (j = 0; j < PORTS_PER_CMPLX; j++) { - if ((i == 4) && (j > 1)) - size = 0; - else - size = cfg[(i*4)+j].pseq_fifo_size; + int start = 0, size, i; + for (i = 0; i < maxports; i++) { + size = cfg[i].pseq_fifo_size; val = (((size & 0x1fff) << 17) | ((start & 0xfff) << 5) | - (((i * 4) + j) & 0x1f)); + (i & 0x1f)); nlm_write_nae_reg(nae_base, NAE_PARSER_SEQ_FIFO_CFG, val); start += size; } @@ -255,105 +241,66 @@ nlm_setup_flow_crc_poly(uint64_t nae_base, uint32_t poly) } void -nlm_setup_iface_fifo_cfg(uint64_t nae_base, int nblock, +nlm_setup_iface_fifo_cfg(uint64_t nae_base, int maxports, struct nae_port_config *cfg) { uint32_t reg; int fifo_xoff_thresh = 12; - int i, size, j; + int i, size; int cur_iface_start = 0; - for (i = 0; i < nblock; i++) { - for (j = 0; j < PORTS_PER_CMPLX; j++) { - if ((i == 4) && (j > 1)) - size = 0; - else - size = cfg[(i*4)+j].iface_fifo_size; - cur_iface_start += size; - } - } - - for (j = 0; j < PORTS_PER_CMPLX; j++) { - if ((i == 4) && (j > 1)) - size = 0; - else - size = cfg[(i*4)+j].iface_fifo_size; + for (i = 0; i < maxports; i++) { + size = cfg[i].iface_fifo_size; reg = ((fifo_xoff_thresh << 25) | ((size & 0x1ff) << 16) | ((cur_iface_start & 0xff) << 8) | - (((i * 4) + j) & 0x1f)); + (i & 0x1f)); nlm_write_nae_reg(nae_base, NAE_IFACE_FIFO_CFG, reg); cur_iface_start += size; } } void -nlm_setup_rx_base_config(uint64_t nae_base, int nblock, +nlm_setup_rx_base_config(uint64_t nae_base, int maxports, struct nae_port_config *cfg) { - uint32_t val, nc; int base = 0; - int i, j; + uint32_t val; + int i; int id; - for (i = 0; i < nblock; i++) { - for (j = 0; j < (PORTS_PER_CMPLX/2); j++) { - base += cfg[(i*4)+(2*j)].num_channels; - base += cfg[(i*4)+(2*j + 1)].num_channels; - } - } + for (i = 0; i < (maxports/2); i++) { + id = 0x12 + i; /* RX_IF_BASE_CONFIG0 */ - id = 0x12 + (i * 2); /* RX_IF_BASE_CONFIG0 */ - - for (j = 0; j < (PORTS_PER_CMPLX/2); j++) { val = (base & 0x3ff); - nc = cfg[(i*4)+(2*j)].num_channels; - base += nc; + base += cfg[(i * 2)].num_channels; val |= ((base & 0x3ff) << 16); - nc = cfg[(i*4)+(2*j + 1)].num_channels; - base += nc; + base += cfg[(i * 2) + 1].num_channels; - nlm_write_nae_reg(nae_base, NAE_REG(7, 0, (id+j)), val); + nlm_write_nae_reg(nae_base, NAE_REG(7, 0, id), val); } } void -nlm_setup_rx_buf_config(uint64_t nae_base, int nblock, +nlm_setup_rx_buf_config(uint64_t nae_base, int maxports, struct nae_port_config *cfg) { uint32_t val; - int i, sz, j, k; + int i, sz, k; int context = 0; int base = 0; - int nc = 0; - for (i = 0; i < nblock; i++) { - for (j = 0; j < PORTS_PER_CMPLX; j++) { - if ((i == 4) && (j > 1)) - nc = 0; - else - nc = cfg[(i*4)+j].num_channels; - for (k = 0; k < nc; k++) { - sz = cfg[(i*4)+j].rxbuf_size; - base += sz; - } - context += nc; - } - } - - for (j = 0; j < PORTS_PER_CMPLX; j++) { - if ((i == 4) && (j > 1)) - nc = 0; - else - nc = cfg[(i*4)+j].num_channels; - for (k = 0; k < nc; k++) { + for (i = 0; i < maxports; i++) { + if (cfg[i].type == UNKNOWN) + continue; + for (k = 0; k < cfg[i].num_channels; k++) { /* write index (context num) */ nlm_write_nae_reg(nae_base, NAE_RXBUF_BASE_DPTH_ADDR, (context+k)); /* write value (rx buf sizes) */ - sz = cfg[(i*4)+j].rxbuf_size; + sz = cfg[i].rxbuf_size; val = 0x80000000 | ((base << 2) & 0x3fff); /* base */ val |= (((sz << 2) & 0x3fff) << 16); /* size */ @@ -362,46 +309,29 @@ nlm_setup_rx_buf_config(uint64_t nae_base, int nblock, (0x7fffffff & val)); base += sz; } - context += nc; + context += cfg[i].num_channels; } } void -nlm_setup_freein_fifo_cfg(uint64_t nae_base, int nblock, - struct nae_port_config *cfg) +nlm_setup_freein_fifo_cfg(uint64_t nae_base, struct nae_port_config *cfg) { - int size, i, cp = 0; + int size, i; uint32_t reg; - int start = 0; + int start = 0, maxbufpool; - for (cp = 0 ; cp < nblock; cp++ ) { - for (i = 0; i < PORTS_PER_CMPLX; i++) { /* 4 interfaces */ - if ((cp == 4) && (i > 1)) - size = 0; - else { - /* Each entry represents 2 descs; hence division by 2 */ - size = cfg[(cp*4)+i].num_free_descs / 2; - } - if (size == 0) - size = 8; - start += size; - } - } - - for (i = 0; i < PORTS_PER_CMPLX; i++) { /* 4 interfaces */ - if ((cp == 4) && (i > 1)) - size = 0; - else { - /* Each entry represents 2 descs; hence division by 2 */ - size = cfg[(cp*4)+i].num_free_descs / 2; - } + if (nlm_is_xlp8xx()) + maxbufpool = MAX_FREE_FIFO_POOL_8XX; + else + maxbufpool = MAX_FREE_FIFO_POOL_3XX; + for (i = 0; i < maxbufpool; i++) { /* Each entry represents 2 descs; hence division by 2 */ + size = (cfg[i].num_free_descs / 2); if (size == 0) size = 8; - reg = ((size & 0x3ff ) << 20) | /* fcSize */ ((start & 0x1ff) << 8) | /* fcStart */ - (((cp * 4) + i) & 0x1f); + (i & 0x1f); nlm_write_nae_reg(nae_base, NAE_FREE_IN_FIFO_CFG, reg); start += size; diff --git a/sys/mips/nlm/dev/net/xaui.c b/sys/mips/nlm/dev/net/xaui.c index 8b4c6a9b9e7b..3b18ef9ba9f4 100644 --- a/sys/mips/nlm/dev/net/xaui.c +++ b/sys/mips/nlm/dev/net/xaui.c @@ -211,12 +211,10 @@ nlm_config_xaui(uint64_t nae_base, int nblock, nlm_write_nae_reg(nae_base, XAUI_CONFIG0(nblock), 0); /* Enable tx/rx frame */ - val = 0xF00010A8; + val = 0x000010A8; val |= XAUI_CONFIG_LENCHK; val |= XAUI_CONFIG_GENFCS; val |= XAUI_CONFIG_PAD_64; - val |= XAUI_CONFIG_TFEN; - val |= XAUI_CONFIG_RFEN; nlm_write_nae_reg(nae_base, XAUI_CONFIG1(nblock), val); /* write max frame length */ diff --git a/sys/mips/nlm/dev/net/xlpge.c b/sys/mips/nlm/dev/net/xlpge.c index 18a14b132d01..3ae114821f74 100644 --- a/sys/mips/nlm/dev/net/xlpge.c +++ b/sys/mips/nlm/dev/net/xlpge.c @@ -306,29 +306,12 @@ static int xlpnae_get_maxchannels(struct nlm_xlpnae_softc *sc) { int maxchans = 0; - int i, j, port = 0; + int i; - for (i = 0; i < sc->nblocks; i++) { - switch (sc->cmplx_type[i]) { - case SGMIIC: - for (j = 0; j < 4; j++) { /* 4 ports */ - if ((i == 4) && (j > 1)) - continue; - maxchans += sc->portcfg[port].num_channels; - port++; - } - break; - case XAUIC: - maxchans += sc->portcfg[port].num_channels; - port += 4; - break; - case ILC: - if (((i%2) == 0) && (i != 4)) { - maxchans += sc->portcfg[port].num_channels; - port += 4; - break; - } - } + for (i = 0; i < sc->max_ports; i++) { + if (sc->portcfg[i].type == UNKNOWN) + continue; + maxchans += sc->portcfg[i].num_channels; } return (maxchans); @@ -374,7 +357,7 @@ nlm_setup_interfaces(struct nlm_xlpnae_softc *sc) uint32_t cur_slot, cur_slot_base; uint32_t cur_flow_base, port, flow_mask; int max_channels; - int i, j, context; + int i, context; cur_slot = 0; cur_slot_base = 0; @@ -386,39 +369,13 @@ nlm_setup_interfaces(struct nlm_xlpnae_softc *sc) port = 0; context = 0; - for (i = 0; i < sc->nblocks; i++) { - switch (sc->cmplx_type[i]) { - case SGMIIC: - for (j = 0; j < 4; j++) { /* 4 ports */ - if ((i == 4) && (j > 1)) - continue; - nlm_setup_interface(sc, i, port, - cur_flow_base, flow_mask, - max_channels, context); - cur_flow_base += sc->per_port_num_flows; - context += sc->portcfg[port].num_channels; - port++; - } - break; - case XAUIC: - nlm_setup_interface(sc, i, port, cur_flow_base, - flow_mask, max_channels, context); - cur_flow_base += sc->per_port_num_flows; - context += sc->portcfg[port].num_channels; - port += 4; - break; - case ILC: - if (((i%2) == 0) && (i != 4)) { - nlm_setup_interface(sc, i, port, - cur_flow_base, flow_mask, - max_channels, context); - cur_flow_base += sc->per_port_num_flows; - context += sc->portcfg[port].num_channels; - port += 4; - } - break; - } - cur_slot_base++; + for (i = 0; i < sc->max_ports; i++) { + if (sc->portcfg[i].type == UNKNOWN) + continue; + nlm_setup_interface(sc, sc->portcfg[i].block, i, cur_flow_base, + flow_mask, max_channels, context); + cur_flow_base += sc->per_port_num_flows; + context += sc->portcfg[i].num_channels; } } @@ -481,8 +438,6 @@ nlm_xlpnae_init(int node, struct nlm_xlpnae_softc *sc) nlm_setup_interfaces(sc); nlm_config_poe(sc->poe_base, sc->poedv_base); - nlm_xlpnae_print_frin_desc_carving(sc); - if (sc->hw_parser_en) nlm_enable_hardware_parser(nae_base); @@ -530,6 +485,12 @@ nlm_setup_portcfg(struct nlm_xlpnae_softc *sc, struct xlp_nae_ivars *naep, bp = &(naep->block_ivars[block]); p = &(bp->port_ivars[port & 0x3]); + sc->portcfg[port].node = p->node; + sc->portcfg[port].block = p->block; + sc->portcfg[port].port = p->port; + sc->portcfg[port].type = p->type; + sc->portcfg[port].mdio_bus = p->mdio_bus; + sc->portcfg[port].phy_addr = p->phy_addr; sc->portcfg[port].loopback_mode = p->loopback_mode; sc->portcfg[port].num_channels = p->num_channels; if (p->free_desc_sizes != MCLBYTES) { @@ -584,7 +545,7 @@ nlm_xlpnae_attach(device_t dev) struct nlm_xlpnae_softc *sc; device_t tmpd; uint32_t dv[NUM_WORDS_PER_DV]; - int port, i, j, n, nchan, nblock, node, qstart, qnum; + int port, i, j, nchan, nblock, node, qstart, qnum; int offset, context, txq_base, rxvcbase; uint64_t poe_pcibase, nae_pcibase; @@ -598,6 +559,8 @@ nlm_xlpnae_attach(device_t dev) sc->poe_base = nlm_get_poe_regbase(sc->node); sc->poedv_base = nlm_get_poedv_regbase(sc->node); sc->portcfg = nae_port_config; + sc->blockmask = nae_ivars->blockmask; + sc->ilmask = nae_ivars->ilmask; sc->xauimask = nae_ivars->xauimask; sc->sgmiimask = nae_ivars->sgmiimask; sc->nblocks = nae_ivars->nblocks; @@ -615,9 +578,10 @@ nlm_xlpnae_attach(device_t dev) sc->ncontexts = nlm_read_reg(nae_pcibase, XLP_PCI_DEVINFO_REG5); sc->nucores = nlm_num_uengines(nae_pcibase); - /* Initialize the 1st four complexes from board config */ - for (nblock = 0; nblock < sc->nblocks; nblock++) + for (nblock = 0; nblock < sc->nblocks; nblock++) { sc->cmplx_type[nblock] = nae_ivars->block_ivars[nblock].type; + sc->portmask[nblock] = nae_ivars->block_ivars[nblock].portmask; + } for (i = 0; i < sc->ncontexts; i++) cntx2port[i] = 18; /* 18 is an invalid port */ @@ -627,6 +591,8 @@ nlm_xlpnae_attach(device_t dev) else sc->max_ports = sc->nblocks * PORTS_PER_CMPLX; + for (i = 0; i < sc->max_ports; i++) + sc->portcfg[i].type = UNKNOWN; /* Port Not Present */ /* * Now setup all internal fifo carvings based on * total number of ports in the system @@ -638,13 +604,15 @@ nlm_xlpnae_attach(device_t dev) txq_base = nlm_qidstart(nae_pcibase); rxvcbase = txq_base + sc->ncontexts; for (i = 0; i < sc->nblocks; i++) { - /* only 2 SGMII ports in last complex */ - n = (sc->cmplx_type[i] == SGMIIC && i == 4) ? 2 : 4; - for (j = 0; j < n; j++, port++) { - if (sc->cmplx_type[i] == XAUIC && j != 0) - continue; - if (sc->cmplx_type[i] == ILC && - (i != 0 || i != 2 || j != 0)) + uint32_t portmask; + + if ((nae_ivars->blockmask & (1 << i)) == 0) { + port += 4; + continue; + } + portmask = nae_ivars->block_ivars[i].portmask; + for (j = 0; j < PORTS_PER_CMPLX; j++, port++) { + if ((portmask & (1 << j)) == 0) continue; nlm_setup_portcfg(sc, nae_ivars, i, port); nchan = sc->portcfg[port].num_channels; @@ -687,31 +655,27 @@ nlm_xlpnae_attach(device_t dev) nlm_xlpnae_init(node, sc); - for (i = 0; i < sc->nblocks; i++) { + for (i = 0; i < sc->max_ports; i++) { char desc[32]; - struct xlp_block_ivars *bv; + int block, port; - if ((nae_ivars->blockmask & (1 << i)) == 0) + if (sc->portcfg[i].type == UNKNOWN) continue; - bv = &nae_ivars->block_ivars[i]; - for (j = 0; j < PORTS_PER_CMPLX; j++) { - int port = i * 4 + j; - - if ((bv->portmask & (1 << j)) == 0) - continue; - tmpd = device_add_child(dev, "xlpge", port); - device_set_ivars(tmpd, &(bv->port_ivars[j])); - sprintf(desc, "XLP NAE Port %d,%d", i, j); - device_set_desc_copy(tmpd, desc); - } - - nlm_setup_iface_fifo_cfg(sc->base, i, sc->portcfg); - nlm_setup_rx_base_config(sc->base, i, sc->portcfg); - nlm_setup_rx_buf_config(sc->base, i, sc->portcfg); - nlm_setup_freein_fifo_cfg(sc->base, i, sc->portcfg); - nlm_program_nae_parser_seq_fifo(sc->base, i, sc->portcfg); + block = sc->portcfg[i].block; + port = sc->portcfg[i].port; + tmpd = device_add_child(dev, "xlpge", i); + device_set_ivars(tmpd, + &(nae_ivars->block_ivars[block].port_ivars[port])); + sprintf(desc, "XLP NAE Port %d,%d", block, port); + device_set_desc_copy(tmpd, desc); } + nlm_setup_iface_fifo_cfg(sc->base, sc->max_ports, sc->portcfg); + nlm_setup_rx_base_config(sc->base, sc->max_ports, sc->portcfg); + nlm_setup_rx_buf_config(sc->base, sc->max_ports, sc->portcfg); + nlm_setup_freein_fifo_cfg(sc->base, sc->portcfg); + nlm_program_nae_parser_seq_fifo(sc->base, sc->max_ports, sc->portcfg); + nlm_xlpnae_print_frin_desc_carving(sc); bus_generic_probe(dev); bus_generic_attach(dev); diff --git a/sys/mips/nlm/dev/net/xlpge.h b/sys/mips/nlm/dev/net/xlpge.h index 883653d77eb3..ccf9d124f4a0 100644 --- a/sys/mips/nlm/dev/net/xlpge.h +++ b/sys/mips/nlm/dev/net/xlpge.h @@ -75,6 +75,9 @@ struct nlm_xlpnae_softc { /* NetIOR configs */ u_int cmplx_type[8]; /* XXXJC: redundant? */ struct nae_port_config *portcfg; + u_int blockmask; + u_int portmask[XLP_NAE_NBLOCKS]; + u_int ilmask; u_int xauimask; u_int sgmiimask; u_int hw_parser_en; diff --git a/sys/mips/nlm/hal/nae.h b/sys/mips/nlm/hal/nae.h index 0738bc72dc24..5ebddca06fcc 100644 --- a/sys/mips/nlm/hal/nae.h +++ b/sys/mips/nlm/hal/nae.h @@ -473,6 +473,9 @@ #define XLP_MAX_PORTS 18 #define XLP_STORM_MAX_PORTS 8 +#define MAX_FREE_FIFO_POOL_8XX 20 +#define MAX_FREE_FIFO_POOL_3XX 9 + #if !defined(LOCORE) && !defined(__ASSEMBLY__) #define nlm_read_nae_reg(b, r) nlm_read_reg_xkphys(b, r) @@ -494,6 +497,7 @@ enum XLPNAE_TX_TYPE { }; enum nblock_type { + UNKNOWN = 0, /* DONT MAKE IT NON-ZERO */ SGMIIC = 1, XAUIC = 2, ILC = 3 @@ -550,6 +554,12 @@ nae_num_context(uint64_t nae_pcibase) /* per port config structure */ struct nae_port_config { + int node; /* node id (quickread) */ + int block; /* network block id (quickread) */ + int port; /* port id - among the 18 in XLP */ + int type; /* port type - see xlp_gmac_port_types */ + int mdio_bus; + int phy_addr; int num_channels; int num_free_descs; int free_desc_sizes; @@ -605,7 +615,7 @@ void nlm_setup_flow_crc_poly(uint64_t, uint32_t); void nlm_setup_iface_fifo_cfg(uint64_t, int, struct nae_port_config *); void nlm_setup_rx_base_config(uint64_t, int, struct nae_port_config *); void nlm_setup_rx_buf_config(uint64_t, int, struct nae_port_config *); -void nlm_setup_freein_fifo_cfg(uint64_t, int, struct nae_port_config *); +void nlm_setup_freein_fifo_cfg(uint64_t, struct nae_port_config *); int nlm_get_flow_mask(int); void nlm_program_flow_cfg(uint64_t, int, uint32_t, uint32_t); void xlp_ax_nae_lane_reset_txpll(uint64_t, int, int, int); diff --git a/sys/mips/nlm/hal/nlm_hal.c b/sys/mips/nlm/hal/nlm_hal.c index 00b79dd713b3..fa4287e5defe 100644 --- a/sys/mips/nlm/hal/nlm_hal.c +++ b/sys/mips/nlm/hal/nlm_hal.c @@ -75,7 +75,10 @@ nlm_get_device_frequency(uint64_t sysbase, int devtype) dfsdiv = ((div_val >> (devtype << 2)) & 0xf) + 1; spf = (pllctrl >> 3 & 0x7f) + 1; spr = (pllctrl >> 1 & 0x03) + 1; - extra_div = nlm_is_xlp8xx_ax() ? 1 : 2; + if (devtype == DFS_DEVICE_NAE && !nlm_is_xlp8xx_ax()) + extra_div = 2; + else + extra_div = 1; return ((400 * spf) / (3 * extra_div * spr * dfsdiv)); } diff --git a/sys/mips/nlm/hal/sys.h b/sys/mips/nlm/hal/sys.h index 2092d37d2999..078e63d69123 100644 --- a/sys/mips/nlm/hal/sys.h +++ b/sys/mips/nlm/hal/sys.h @@ -95,9 +95,11 @@ #define SYS_UCO_S_ECC 0x38 #define SYS_UCO_M_ECC 0x39 #define SYS_UCO_ADDR 0x3a +#define SYS_PLL_DFS_BYP_CTRL 0x3a /* Bx stepping */ #define SYS_UCO_INSTR 0x3b #define SYS_MEM_BIST0 0x3c #define SYS_MEM_BIST1 0x3d +#define SYS_PLL_DFS_DIV_VALUE 0x3d /* Bx stepping */ #define SYS_MEM_BIST2 0x3e #define SYS_MEM_BIST3 0x3f #define SYS_MEM_BIST4 0x40 diff --git a/sys/modules/ipfilter/Makefile b/sys/modules/ipfilter/Makefile index db780e9a6797..6e6accf46ed7 100644 --- a/sys/modules/ipfilter/Makefile +++ b/sys/modules/ipfilter/Makefile @@ -7,7 +7,8 @@ KMOD= ipl SRCS= mlfk_ipl.c ip_nat.c ip_frag.c ip_state.c ip_proxy.c ip_auth.c \ ip_log.c ip_fil_freebsd.c fil.c ip_lookup.c ip_pool.c ip_htable.c \ - ip_sync.c + ip_sync.c \ + ip_nat6.c ip_rules.c ip_scan.c ip_dstlist.c radix_ipf.c SRCS+= opt_bpf.h opt_inet6.h .if !defined(KERNBUILDDIR) diff --git a/sys/modules/random/Makefile b/sys/modules/random/Makefile index ad14899e7efc..60b62afde1d9 100644 --- a/sys/modules/random/Makefile +++ b/sys/modules/random/Makefile @@ -5,7 +5,7 @@ .PATH: ${.CURDIR}/../../crypto/sha2 KMOD= random -SRCS= randomdev.c probe.c +SRCS= randomdev.c .if ${MACHINE} == "amd64" || ${MACHINE} == "i386" SRCS+= nehemiah.c SRCS+= ivy.c diff --git a/sys/net/if.c b/sys/net/if.c index 2cb3da013c21..0356ec7fbf46 100644 --- a/sys/net/if.c +++ b/sys/net/if.c @@ -2553,11 +2553,23 @@ ifioctl(struct socket *so, u_long cmd, caddr_t data, struct thread *td) CURVNET_RESTORE(); return (EOPNOTSUPP); } + + /* + * Pass the request on to the socket control method, and if the + * latter returns EOPNOTSUPP, directly to the interface. + * + * Make an exception for the legacy SIOCSIF* requests. Drivers + * trust SIOCSIFADDR et al to come from an already privileged + * layer, and do not perform any credentials checks or input + * validation. + */ #ifndef COMPAT_43 error = ((*so->so_proto->pr_usrreqs->pru_control)(so, cmd, data, ifp, td)); - if (error == EOPNOTSUPP && ifp != NULL && ifp->if_ioctl != NULL) + if (error == EOPNOTSUPP && ifp != NULL && ifp->if_ioctl != NULL && + cmd != SIOCSIFADDR && cmd != SIOCSIFBRDADDR && + cmd != SIOCSIFDSTADDR && cmd != SIOCSIFNETMASK) error = (*ifp->if_ioctl)(ifp, cmd, data); #else { @@ -2601,7 +2613,9 @@ ifioctl(struct socket *so, u_long cmd, caddr_t data, struct thread *td) data, ifp, td)); if (error == EOPNOTSUPP && ifp != NULL && - ifp->if_ioctl != NULL) + ifp->if_ioctl != NULL && + cmd != SIOCSIFADDR && cmd != SIOCSIFBRDADDR && + cmd != SIOCSIFDSTADDR && cmd != SIOCSIFNETMASK) error = (*ifp->if_ioctl)(ifp, cmd, data); switch (ocmd) { diff --git a/sys/net/if_ethersubr.c b/sys/net/if_ethersubr.c index e8d395ad46cb..638b3647f6ba 100644 --- a/sys/net/if_ethersubr.c +++ b/sys/net/if_ethersubr.c @@ -638,9 +638,8 @@ ether_input_internal(struct ifnet *ifp, struct mbuf *m) m->m_flags |= M_PROMISC; } - /* First chunk of an mbuf contains good entropy */ if (harvest.ethernet) - random_harvest(m, 16, 3, 0, RANDOM_NET); + random_harvest(&(m->m_data), 12, 3, 0, RANDOM_NET_ETHER); ether_demux(ifp, m); CURVNET_RESTORE(); diff --git a/sys/net/if_tap.c b/sys/net/if_tap.c index 45bd7d269b9e..ad6f781b6e5b 100644 --- a/sys/net/if_tap.c +++ b/sys/net/if_tap.c @@ -409,8 +409,6 @@ tapcreate(struct cdev *dev) const char *name = NULL; u_char eaddr[6]; - dev->si_flags &= ~SI_CHEAPCLONE; - /* allocate driver storage and create device */ tp = malloc(sizeof(*tp), M_TAP, M_WAITOK | M_ZERO); mtx_init(&tp->tap_mtx, "tap_mtx", NULL, MTX_DEF); diff --git a/sys/net/if_tun.c b/sys/net/if_tun.c index e917793a0fba..e67b213e636f 100644 --- a/sys/net/if_tun.c +++ b/sys/net/if_tun.c @@ -361,8 +361,6 @@ tuncreate(const char *name, struct cdev *dev) struct tun_softc *sc; struct ifnet *ifp; - dev->si_flags &= ~SI_CHEAPCLONE; - sc = malloc(sizeof(*sc), M_TUN, M_WAITOK | M_ZERO); mtx_init(&sc->tun_mtx, "tun_mtx", NULL, MTX_DEF); cv_init(&sc->tun_cv, "tun_condvar"); @@ -922,9 +920,8 @@ tunwrite(struct cdev *dev, struct uio *uio, int flag) m_freem(m); return (EAFNOSUPPORT); } - /* First chunk of an mbuf contains good junk */ if (harvest.point_to_point) - random_harvest(m, 16, 3, 0, RANDOM_NET); + random_harvest(&(m->m_data), 12, 3, 0, RANDOM_NET_TUN); ifp->if_ibytes += m->m_pkthdr.len; ifp->if_ipackets++; CURVNET_SET(ifp->if_vnet); diff --git a/sys/net/netisr.c b/sys/net/netisr.c index 534d80cce68b..3045e95bb706 100644 --- a/sys/net/netisr.c +++ b/sys/net/netisr.c @@ -153,19 +153,6 @@ SYSCTL_PROC(_net_isr, OID_AUTO, dispatch, CTLTYPE_STRING | CTLFLAG_RW | CTLFLAG_TUN, 0, 0, sysctl_netisr_dispatch_policy, "A", "netisr dispatch policy"); -/* - * These sysctls were used in previous versions to control and export - * dispatch policy state. Now, we provide read-only export via them so that - * older netstat binaries work. At some point they can be garbage collected. - */ -static int netisr_direct_force; -SYSCTL_INT(_net_isr, OID_AUTO, direct_force, CTLFLAG_RD, - &netisr_direct_force, 0, "compat: force direct dispatch"); - -static int netisr_direct; -SYSCTL_INT(_net_isr, OID_AUTO, direct, CTLFLAG_RD, &netisr_direct, 0, - "compat: enable direct dispatch"); - /* * Allow the administrator to limit the number of threads (CPUs) to use for * netisr. We don't check netisr_maxthreads before creating the thread for @@ -338,32 +325,6 @@ netisr_dispatch_policy_from_str(const char *str, u_int *dispatch_policyp) return (EINVAL); } -static void -netisr_dispatch_policy_compat(void) -{ - - switch (netisr_dispatch_policy) { - case NETISR_DISPATCH_DEFERRED: - netisr_direct_force = 0; - netisr_direct = 0; - break; - - case NETISR_DISPATCH_HYBRID: - netisr_direct_force = 0; - netisr_direct = 1; - break; - - case NETISR_DISPATCH_DIRECT: - netisr_direct_force = 1; - netisr_direct = 1; - break; - - default: - panic("%s: unknown policy %u", __func__, - netisr_dispatch_policy); - } -} - static int sysctl_netisr_dispatch_policy(SYSCTL_HANDLER_ARGS) { @@ -379,10 +340,8 @@ sysctl_netisr_dispatch_policy(SYSCTL_HANDLER_ARGS) &dispatch_policy); if (error == 0 && dispatch_policy == NETISR_DISPATCH_DEFAULT) error = EINVAL; - if (error == 0) { + if (error == 0) netisr_dispatch_policy = dispatch_policy; - netisr_dispatch_policy_compat(); - } } return (error); } @@ -1199,10 +1158,9 @@ netisr_init(void *arg) &dispatch_policy); if (error == 0 && dispatch_policy == NETISR_DISPATCH_DEFAULT) error = EINVAL; - if (error == 0) { + if (error == 0) netisr_dispatch_policy = dispatch_policy; - netisr_dispatch_policy_compat(); - } else + else printf( "%s: invalid dispatch policy %s, using default\n", __func__, tmp); diff --git a/sys/netgraph/ng_iface.c b/sys/netgraph/ng_iface.c index e6ac5085368d..72fc16201df9 100644 --- a/sys/netgraph/ng_iface.c +++ b/sys/netgraph/ng_iface.c @@ -774,9 +774,8 @@ ng_iface_rcvdata(hook_p hook, item_p item) m_freem(m); return (EAFNOSUPPORT); } - /* First chunk of an mbuf contains good junk */ if (harvest.point_to_point) - random_harvest(m, 16, 3, 0, RANDOM_NET); + random_harvest(&(m->m_data), 12, 3, 0, RANDOM_NET_NG); M_SETFIB(m, ifp->if_fib); netisr_dispatch(isr, m); return (0); diff --git a/sys/netinet/ip_carp.c b/sys/netinet/ip_carp.c index 436385d373d1..a170e34d32d8 100644 --- a/sys/netinet/ip_carp.c +++ b/sys/netinet/ip_carp.c @@ -1605,12 +1605,12 @@ carp_free_if(struct carp_if *cif) IF_ADDR_WLOCK(ifp); ifp->if_carp = NULL; - if_rele(ifp); IF_ADDR_WUNLOCK(ifp); CIF_LOCK_DESTROY(cif); ifpromisc(ifp, 0); + if_rele(ifp); free(cif, M_CARP); } diff --git a/sys/netinet/ip_mroute.c b/sys/netinet/ip_mroute.c index 23f1be7fb872..3a03defe04cd 100644 --- a/sys/netinet/ip_mroute.c +++ b/sys/netinet/ip_mroute.c @@ -609,7 +609,7 @@ static void if_detached_event(void *arg __unused, struct ifnet *ifp) { vifi_t vifi; - int i; + u_long i; MROUTER_LOCK(); @@ -634,8 +634,8 @@ if_detached_event(void *arg __unused, struct ifnet *ifp) continue; for (i = 0; i < mfchashsize; i++) { struct mfc *rt, *nrt; - for (rt = LIST_FIRST(&V_mfchashtbl[i]); rt; rt = nrt) { - nrt = LIST_NEXT(rt, mfc_hash); + + LIST_FOREACH_SAFE(rt, &V_mfchashtbl[i], mfc_hash, nrt) { if (rt->mfc_parent == vifi) { expire_mfc(rt); } @@ -704,10 +704,9 @@ ip_mrouter_init(struct socket *so, int version) static int X_ip_mrouter_done(void) { - vifi_t vifi; - int i; struct ifnet *ifp; - struct ifreq ifr; + u_long i; + vifi_t vifi; MROUTER_LOCK(); @@ -732,11 +731,6 @@ X_ip_mrouter_done(void) for (vifi = 0; vifi < V_numvifs; vifi++) { if (!in_nullhost(V_viftable[vifi].v_lcl_addr) && !(V_viftable[vifi].v_flags & (VIFF_TUNNEL | VIFF_REGISTER))) { - struct sockaddr_in *so = (struct sockaddr_in *)&(ifr.ifr_addr); - - so->sin_len = sizeof(struct sockaddr_in); - so->sin_family = AF_INET; - so->sin_addr.s_addr = INADDR_ANY; ifp = V_viftable[vifi].v_ifp; if_allmulti(ifp, 0); } @@ -759,8 +753,8 @@ X_ip_mrouter_done(void) */ for (i = 0; i < mfchashsize; i++) { struct mfc *rt, *nrt; - for (rt = LIST_FIRST(&V_mfchashtbl[i]); rt; rt = nrt) { - nrt = LIST_NEXT(rt, mfc_hash); + + LIST_FOREACH_SAFE(rt, &V_mfchashtbl[i], mfc_hash, nrt) { expire_mfc(rt); } } @@ -803,7 +797,7 @@ set_assert(int i) int set_api_config(uint32_t *apival) { - int i; + u_long i; /* * We can set the API capabilities only if it is the first operation @@ -1439,7 +1433,7 @@ X_ip_mforward(struct ip *ip, struct ifnet *ifp, struct mbuf *m, static void expire_upcalls(void *arg) { - int i; + u_long i; CURVNET_SET((struct vnet *) arg); @@ -1451,9 +1445,7 @@ expire_upcalls(void *arg) if (V_nexpire[i] == 0) continue; - for (rt = LIST_FIRST(&V_mfchashtbl[i]); rt; rt = nrt) { - nrt = LIST_NEXT(rt, mfc_hash); - + LIST_FOREACH_SAFE(rt, &V_mfchashtbl[i], mfc_hash, nrt) { if (TAILQ_EMPTY(&rt->mfc_stall)) continue; diff --git a/sys/netinet/sctp_indata.c b/sys/netinet/sctp_indata.c index 7ebf7f11b511..26fcf8520950 100644 --- a/sys/netinet/sctp_indata.c +++ b/sys/netinet/sctp_indata.c @@ -789,13 +789,12 @@ sctp_deliver_reasm_check(struct sctp_tcb *stcb, struct sctp_association *asoc) * but should we? */ if (stcb->sctp_socket) { - pd_point = min(SCTP_SB_LIMIT_RCV(stcb->sctp_socket), + pd_point = min(SCTP_SB_LIMIT_RCV(stcb->sctp_socket) >> SCTP_PARTIAL_DELIVERY_SHIFT, stcb->sctp_ep->partial_delivery_point); } else { pd_point = stcb->sctp_ep->partial_delivery_point; } if (sctp_is_all_msg_on_reasm(asoc, &tsize) || (tsize >= pd_point)) { - /* * Yes, we setup to start reception, by * backing down the TSN just in case we @@ -2491,7 +2490,7 @@ sctp_service_queues(struct sctp_tcb *stcb, struct sctp_association *asoc) * delivery queue and something can be delivered. */ if (stcb->sctp_socket) { - pd_point = min(SCTP_SB_LIMIT_RCV(stcb->sctp_socket), + pd_point = min(SCTP_SB_LIMIT_RCV(stcb->sctp_socket) >> SCTP_PARTIAL_DELIVERY_SHIFT, stcb->sctp_ep->partial_delivery_point); } else { pd_point = stcb->sctp_ep->partial_delivery_point; diff --git a/sys/netinet/sctp_output.c b/sys/netinet/sctp_output.c index 3d76b7e121d4..34edf5b0e60b 100644 --- a/sys/netinet/sctp_output.c +++ b/sys/netinet/sctp_output.c @@ -6412,7 +6412,7 @@ sctp_sendall_iterator(struct sctp_inpcb *inp, struct sctp_tcb *stcb, void *ptr, /* TSNH */ return; } - if ((ca->m) && ca->sndlen) { + if (ca->sndlen > 0) { m = SCTP_M_COPYM(ca->m, 0, M_COPYALL, M_NOWAIT); if (m == NULL) { /* can't copy so we are done */ @@ -6441,38 +6441,40 @@ sctp_sendall_iterator(struct sctp_inpcb *inp, struct sctp_tcb *stcb, void *ptr, } if (ca->sndrcv.sinfo_flags & SCTP_ABORT) { /* Abort this assoc with m as the user defined reason */ - if (m) { + if (m != NULL) { + SCTP_BUF_PREPEND(m, sizeof(struct sctp_paramhdr), M_NOWAIT); + } else { + m = sctp_get_mbuf_for_msg(sizeof(struct sctp_paramhdr), + 0, M_NOWAIT, 1, MT_DATA); + SCTP_BUF_LEN(m) = sizeof(struct sctp_paramhdr); + } + if (m != NULL) { struct sctp_paramhdr *ph; - SCTP_BUF_PREPEND(m, sizeof(struct sctp_paramhdr), M_NOWAIT); - if (m) { - ph = mtod(m, struct sctp_paramhdr *); - ph->param_type = htons(SCTP_CAUSE_USER_INITIATED_ABT); - ph->param_length = htons(sizeof(struct sctp_paramhdr) + ca->sndlen); - } - /* - * We add one here to keep the assoc from - * dis-appearing on us. - */ - atomic_add_int(&stcb->asoc.refcnt, 1); - sctp_abort_an_association(inp, stcb, m, SCTP_SO_NOT_LOCKED); - /* - * sctp_abort_an_association calls sctp_free_asoc() - * free association will NOT free it since we - * incremented the refcnt .. we do this to prevent - * it being freed and things getting tricky since we - * could end up (from free_asoc) calling inpcb_free - * which would get a recursive lock call to the - * iterator lock.. But as a consequence of that the - * stcb will return to us un-locked.. since - * free_asoc returns with either no TCB or the TCB - * unlocked, we must relock.. to unlock in the - * iterator timer :-0 - */ - SCTP_TCB_LOCK(stcb); - atomic_add_int(&stcb->asoc.refcnt, -1); - goto no_chunk_output; + ph = mtod(m, struct sctp_paramhdr *); + ph->param_type = htons(SCTP_CAUSE_USER_INITIATED_ABT); + ph->param_length = htons(sizeof(struct sctp_paramhdr) + ca->sndlen); } + /* + * We add one here to keep the assoc from dis-appearing on + * us. + */ + atomic_add_int(&stcb->asoc.refcnt, 1); + sctp_abort_an_association(inp, stcb, m, SCTP_SO_NOT_LOCKED); + /* + * sctp_abort_an_association calls sctp_free_asoc() free + * association will NOT free it since we incremented the + * refcnt .. we do this to prevent it being freed and things + * getting tricky since we could end up (from free_asoc) + * calling inpcb_free which would get a recursive lock call + * to the iterator lock.. But as a consequence of that the + * stcb will return to us un-locked.. since free_asoc + * returns with either no TCB or the TCB unlocked, we must + * relock.. to unlock in the iterator timer :-0 + */ + SCTP_TCB_LOCK(stcb); + atomic_add_int(&stcb->asoc.refcnt, -1); + goto no_chunk_output; } else { if (m) { ret = sctp_msg_append(stcb, net, m, @@ -6566,8 +6568,7 @@ sctp_sendall_iterator(struct sctp_inpcb *inp, struct sctp_tcb *stcb, void *ptr, if ((sctp_is_feature_off(inp, SCTP_PCB_FLAGS_NODELAY)) && (stcb->asoc.total_flight > 0) && - (un_sent < (int)(stcb->asoc.smallest_mtu - SCTP_MIN_OVERHEAD)) - ) { + (un_sent < (int)(stcb->asoc.smallest_mtu - SCTP_MIN_OVERHEAD))) { do_chunk_output = 0; } if (do_chunk_output) @@ -6696,13 +6697,10 @@ sctp_sendall(struct sctp_inpcb *inp, struct uio *uio, struct mbuf *m, /* Gather the length of the send */ struct mbuf *mat; - mat = m; ca->sndlen = 0; - while (m) { - ca->sndlen += SCTP_BUF_LEN(m); - m = SCTP_BUF_NEXT(m); + for (mat = m; mat; mat = SCTP_BUF_NEXT(mat)) { + ca->sndlen += SCTP_BUF_LEN(mat); } - ca->m = mat; } ret = sctp_initiate_iterator(NULL, sctp_sendall_iterator, NULL, SCTP_PCB_ANY_FLAGS, SCTP_PCB_ANY_FEATURES, diff --git a/sys/netinet6/in6.c b/sys/netinet6/in6.c index 9d9993091c7c..e5c62df81a20 100644 --- a/sys/netinet6/in6.c +++ b/sys/netinet6/in6.c @@ -431,6 +431,18 @@ in6_control(struct socket *so, u_long cmd, caddr_t data, case SIOCGIFSTAT_ICMP6: sa6 = &ifr->ifr_addr; break; + case SIOCSIFADDR: + case SIOCSIFBRDADDR: + case SIOCSIFDSTADDR: + case SIOCSIFNETMASK: + /* + * Although we should pass any non-INET6 ioctl requests + * down to driver, we filter some legacy INET requests. + * Drivers trust SIOCSIFADDR et al to come from an already + * privileged layer, and do not perform any credentials + * checks or input validation. + */ + return (EINVAL); default: sa6 = NULL; break; diff --git a/sys/netinet6/ip6_mroute.c b/sys/netinet6/ip6_mroute.c index 96346367aa8b..36d0d6f183d6 100644 --- a/sys/netinet6/ip6_mroute.c +++ b/sys/netinet6/ip6_mroute.c @@ -576,7 +576,7 @@ int X_ip6_mrouter_done(void) { mifi_t mifi; - int i; + u_long i; struct mf6c *rt; struct rtdetq *rte; @@ -1341,7 +1341,7 @@ expire_upcalls(void *unused) { struct rtdetq *rte; struct mf6c *mfc, **nptr; - int i; + u_long i; MFC6_LOCK(); for (i = 0; i < MF6CTBLSIZ; i++) { diff --git a/sys/netnatm/natm.c b/sys/netnatm/natm.c index 681da9cd0595..c61165015536 100644 --- a/sys/netnatm/natm.c +++ b/sys/netnatm/natm.c @@ -339,6 +339,21 @@ natm_usr_control(struct socket *so, u_long cmd, caddr_t arg, npcb = (struct natmpcb *)so->so_pcb; KASSERT(npcb != NULL, ("natm_usr_control: npcb == NULL")); + switch (cmd) { + case SIOCSIFADDR: + case SIOCSIFBRDADDR: + case SIOCSIFDSTADDR: + case SIOCSIFNETMASK: + /* + * Although we should pass any non-ATM ioctl requests + * down to driver, we filter some legacy INET requests. + * Drivers trust SIOCSIFADDR et al to come from an already + * privileged layer, and do not perform any credentials + * checks or input validation. + */ + return (EINVAL); + } + if (ifp == NULL || ifp->if_ioctl == NULL) return (EOPNOTSUPP); return ((*ifp->if_ioctl)(ifp, cmd, arg)); diff --git a/sys/netsmb/smb_dev.c b/sys/netsmb/smb_dev.c index 0efb282ad026..279ae6716e6b 100644 --- a/sys/netsmb/smb_dev.c +++ b/sys/netsmb/smb_dev.c @@ -378,6 +378,7 @@ int smb_dev2share(int fd, int mode, struct smb_cred *scred, struct smb_share **sspp, struct smb_dev **ssdp) { + cap_rights_t rights; struct file *fp, *fptmp; struct smb_dev *sdp; struct smb_share *ssp; @@ -385,7 +386,7 @@ smb_dev2share(int fd, int mode, struct smb_cred *scred, int error; td = curthread; - error = fget(td, fd, CAP_READ, &fp); + error = fget(td, fd, cap_rights_init(&rights, CAP_READ), &fp); if (error) return (error); fptmp = td->td_fpop; diff --git a/sys/nfsserver/nfs_srvkrpc.c b/sys/nfsserver/nfs_srvkrpc.c index db69df95cbc9..85003b7b1be5 100644 --- a/sys/nfsserver/nfs_srvkrpc.c +++ b/sys/nfsserver/nfs_srvkrpc.c @@ -168,6 +168,7 @@ nfssvc_nfsserver(struct thread *td, struct nfssvc_args *uap) struct file *fp; struct nfsd_addsock_args addsockarg; struct nfsd_nfsd_args nfsdarg; + cap_rights_t rights; int error; if (uap->flag & NFSSVC_ADDSOCK) { @@ -175,7 +176,8 @@ nfssvc_nfsserver(struct thread *td, struct nfssvc_args *uap) sizeof(addsockarg)); if (error) return (error); - error = fget(td, addsockarg.sock, CAP_SOCK_SERVER, &fp); + error = fget(td, addsockarg.sock, + cap_rights_init(&rights, CAP_SOCK_SERVER), &fp); if (error) return (error); if (fp->f_type != DTYPE_SOCKET) { diff --git a/sys/nlm/nlm_prot_impl.c b/sys/nlm/nlm_prot_impl.c index dca030067045..387b0090578c 100644 --- a/sys/nlm/nlm_prot_impl.c +++ b/sys/nlm/nlm_prot_impl.c @@ -132,6 +132,11 @@ static time_t nlm_grace_threshold; */ static time_t nlm_next_idle_check; +/* + * A flag to indicate the server is already running. + */ +static int nlm_is_running; + /* * A socket to use for RPC - shared by all IPv4 RPC clients. */ @@ -1526,51 +1531,51 @@ nlm_server_main(int addr_count, char **addrs) struct nlm_waiting_lock *nw; vop_advlock_t *old_nfs_advlock; vop_reclaim_t *old_nfs_reclaim; - int v4_used; -#ifdef INET6 - int v6_used; -#endif - if (nlm_socket) { + if (nlm_is_running != 0) { NLM_ERR("NLM: can't start server - " "it appears to be running already\n"); return (EPERM); } - memset(&opt, 0, sizeof(opt)); + if (nlm_socket == NULL) { + memset(&opt, 0, sizeof(opt)); - nlm_socket = NULL; - error = socreate(AF_INET, &nlm_socket, SOCK_DGRAM, 0, - td->td_ucred, td); - if (error) { - NLM_ERR("NLM: can't create IPv4 socket - error %d\n", error); - return (error); - } - opt.sopt_dir = SOPT_SET; - opt.sopt_level = IPPROTO_IP; - opt.sopt_name = IP_PORTRANGE; - portlow = IP_PORTRANGE_LOW; - opt.sopt_val = &portlow; - opt.sopt_valsize = sizeof(portlow); - sosetopt(nlm_socket, &opt); + error = socreate(AF_INET, &nlm_socket, SOCK_DGRAM, 0, + td->td_ucred, td); + if (error) { + NLM_ERR("NLM: can't create IPv4 socket - error %d\n", + error); + return (error); + } + opt.sopt_dir = SOPT_SET; + opt.sopt_level = IPPROTO_IP; + opt.sopt_name = IP_PORTRANGE; + portlow = IP_PORTRANGE_LOW; + opt.sopt_val = &portlow; + opt.sopt_valsize = sizeof(portlow); + sosetopt(nlm_socket, &opt); #ifdef INET6 - nlm_socket6 = NULL; - error = socreate(AF_INET6, &nlm_socket6, SOCK_DGRAM, 0, - td->td_ucred, td); - if (error) { - NLM_ERR("NLM: can't create IPv6 socket - error %d\n", error); - goto out; - return (error); - } - opt.sopt_dir = SOPT_SET; - opt.sopt_level = IPPROTO_IPV6; - opt.sopt_name = IPV6_PORTRANGE; - portlow = IPV6_PORTRANGE_LOW; - opt.sopt_val = &portlow; - opt.sopt_valsize = sizeof(portlow); - sosetopt(nlm_socket6, &opt); + nlm_socket6 = NULL; + error = socreate(AF_INET6, &nlm_socket6, SOCK_DGRAM, 0, + td->td_ucred, td); + if (error) { + NLM_ERR("NLM: can't create IPv6 socket - error %d\n", + error); + soclose(nlm_socket); + nlm_socket = NULL; + return (error); + } + opt.sopt_dir = SOPT_SET; + opt.sopt_level = IPPROTO_IPV6; + opt.sopt_name = IPV6_PORTRANGE; + portlow = IPV6_PORTRANGE_LOW; + opt.sopt_val = &portlow; + opt.sopt_valsize = sizeof(portlow); + sosetopt(nlm_socket6, &opt); #endif + } nlm_auth = authunix_create(curthread->td_ucred); @@ -1622,6 +1627,7 @@ nlm_server_main(int addr_count, char **addrs) error = EINVAL; goto out; } + nlm_is_running = 1; NLM_DEBUG(1, "NLM: local NSM state is %d\n", smstat.state); nlm_nsm_state = smstat.state; @@ -1638,6 +1644,7 @@ nlm_server_main(int addr_count, char **addrs) nfs_reclaim_p = old_nfs_reclaim; out: + nlm_is_running = 0; if (pool) svcpool_destroy(pool); @@ -1661,13 +1668,8 @@ nlm_server_main(int addr_count, char **addrs) * nlm_hosts to the host (which may remove it from the list * and free it). After this phase, the only entries in the * nlm_host list should be from other threads performing - * client lock requests. We arrange to defer closing the - * sockets until the last RPC client handle is released. + * client lock requests. */ - v4_used = 0; -#ifdef INET6 - v6_used = 0; -#endif mtx_lock(&nlm_global_lock); TAILQ_FOREACH(nw, &nlm_waiting_locks, nw_link) { wakeup(nw); @@ -1678,43 +1680,10 @@ nlm_server_main(int addr_count, char **addrs) nlm_host_release(host); mtx_lock(&nlm_global_lock); } - TAILQ_FOREACH_SAFE(host, &nlm_hosts, nh_link, nhost) { - mtx_lock(&host->nh_lock); - if (host->nh_srvrpc.nr_client - || host->nh_clntrpc.nr_client) { - if (host->nh_addr.ss_family == AF_INET) - v4_used++; -#ifdef INET6 - if (host->nh_addr.ss_family == AF_INET6) - v6_used++; -#endif - /* - * Note that the rpc over udp code copes - * correctly with the fact that a socket may - * be used by many rpc handles. - */ - if (host->nh_srvrpc.nr_client) - CLNT_CONTROL(host->nh_srvrpc.nr_client, - CLSET_FD_CLOSE, 0); - if (host->nh_clntrpc.nr_client) - CLNT_CONTROL(host->nh_clntrpc.nr_client, - CLSET_FD_CLOSE, 0); - } - mtx_unlock(&host->nh_lock); - } mtx_unlock(&nlm_global_lock); AUTH_DESTROY(nlm_auth); - if (!v4_used) - soclose(nlm_socket); - nlm_socket = NULL; -#ifdef INET6 - if (!v6_used) - soclose(nlm_socket6); - nlm_socket6 = NULL; -#endif - return (error); } @@ -2435,7 +2404,15 @@ static int nfslockd_modevent(module_t mod, int type, void *data) { - return (0); + switch (type) { + case MOD_LOAD: + return (0); + case MOD_UNLOAD: + /* The NLM module cannot be safely unloaded. */ + /* FALLTHROUGH */ + default: + return (EOPNOTSUPP); + } } static moduledata_t nfslockd_mod = { "nfslockd", diff --git a/sys/ofed/include/linux/file.h b/sys/ofed/include/linux/file.h index b9bd8b154291..bb9d58d50f8d 100644 --- a/sys/ofed/include/linux/file.h +++ b/sys/ofed/include/linux/file.h @@ -47,8 +47,10 @@ linux_fget(unsigned int fd) { struct file *file; - if (fget_unlocked(curthread->td_proc->p_fd, fd, 0, 0, &file, NULL) != 0) + if (fget_unlocked(curthread->td_proc->p_fd, fd, NULL, 0, &file, + NULL) != 0) { return (NULL); + } return (struct linux_file *)file->f_data; } @@ -70,8 +72,10 @@ put_unused_fd(unsigned int fd) { struct file *file; - if (fget_unlocked(curthread->td_proc->p_fd, fd, 0, 0, &file, NULL) != 0) + if (fget_unlocked(curthread->td_proc->p_fd, fd, NULL, 0, &file, + NULL) != 0) { return; + } fdclose(curthread->td_proc->p_fd, file, fd, curthread); } @@ -80,8 +84,10 @@ fd_install(unsigned int fd, struct linux_file *filp) { struct file *file; - if (fget_unlocked(curthread->td_proc->p_fd, fd, 0, 0, &file, NULL) != 0) + if (fget_unlocked(curthread->td_proc->p_fd, fd, NULL, 0, &file, + NULL) != 0) { file = NULL; + } filp->_file = file; finit(file, filp->f_mode, DTYPE_DEV, filp, &linuxfileops); } diff --git a/sys/powerpc/aim/mmu_oea64.c b/sys/powerpc/aim/mmu_oea64.c index ba1da121b978..e93c65546022 100644 --- a/sys/powerpc/aim/mmu_oea64.c +++ b/sys/powerpc/aim/mmu_oea64.c @@ -263,7 +263,7 @@ uintptr_t moea64_scratchpage_pte[2]; struct mtx moea64_scratchpage_mtx; uint64_t moea64_large_page_mask = 0; -int moea64_large_page_size = 0; +uint64_t moea64_large_page_size = 0; int moea64_large_page_shift = 0; /* @@ -546,12 +546,9 @@ moea64_probe_large_page(void) powerpc_sync(); isync(); /* FALLTHROUGH */ - case IBMCELLBE: + default: moea64_large_page_size = 0x1000000; /* 16 MB */ moea64_large_page_shift = 24; - break; - default: - moea64_large_page_size = 0; } moea64_large_page_mask = moea64_large_page_size - 1; diff --git a/sys/powerpc/aim/mmu_oea64.h b/sys/powerpc/aim/mmu_oea64.h index 101181da5ba3..111d04d6c20d 100644 --- a/sys/powerpc/aim/mmu_oea64.h +++ b/sys/powerpc/aim/mmu_oea64.h @@ -70,6 +70,7 @@ extern u_int moea64_pte_overflow; extern struct pvo_head *moea64_pvo_table; extern int moea64_large_page_shift; +extern uint64_t moea64_large_page_size; extern u_int moea64_pteg_count; extern u_int moea64_pteg_mask; diff --git a/sys/powerpc/aim/nexus.c b/sys/powerpc/aim/nexus.c index 9a6bf470b8e5..109ec52ae6f7 100644 --- a/sys/powerpc/aim/nexus.c +++ b/sys/powerpc/aim/nexus.c @@ -195,7 +195,8 @@ static driver_t nexus_driver = { static devclass_t nexus_devclass; -DRIVER_MODULE(nexus, root, nexus_driver, nexus_devclass, 0, 0); +EARLY_DRIVER_MODULE(nexus, root, nexus_driver, nexus_devclass, 0, 0, + BUS_PASS_BUS); static int nexus_probe(device_t dev) @@ -216,7 +217,7 @@ nexus_attach(device_t dev) sc = device_get_softc(dev); start = 0; - end = MAX_PICS*INTR_VECTORS - 1; + end = ~0; sc->sc_rman.rm_start = start; sc->sc_rman.rm_end = end; diff --git a/sys/powerpc/aim/vm_machdep.c b/sys/powerpc/aim/vm_machdep.c index 2deb4cbfffda..1790ce38d755 100644 --- a/sys/powerpc/aim/vm_machdep.c +++ b/sys/powerpc/aim/vm_machdep.c @@ -187,6 +187,7 @@ cpu_fork(struct thread *td1, struct proc *p2, struct thread *td2, int flags) cf->cf_arg1 = (register_t)tf; pcb->pcb_sp = (register_t)cf; + KASSERT(pcb->pcb_sp % 16 == 0, ("stack misaligned")); #ifdef __powerpc64__ pcb->pcb_lr = ((register_t *)fork_trampoline)[0]; pcb->pcb_toc = ((register_t *)fork_trampoline)[1]; diff --git a/sys/powerpc/include/frame.h b/sys/powerpc/include/frame.h index 196cb6fb8af3..d2100a104a2b 100644 --- a/sys/powerpc/include/frame.h +++ b/sys/powerpc/include/frame.h @@ -94,6 +94,7 @@ struct callframe { register_t cf_func; register_t cf_arg0; register_t cf_arg1; + register_t _padding; /* Maintain 16-byte alignment */ }; #else struct callframe { @@ -102,6 +103,7 @@ struct callframe { register_t cf_func; register_t cf_arg0; register_t cf_arg1; + register_t _padding; /* Maintain 16-byte alignment */ }; #endif diff --git a/sys/powerpc/include/param.h b/sys/powerpc/include/param.h index 25283258abda..7e7c8f153cbe 100644 --- a/sys/powerpc/include/param.h +++ b/sys/powerpc/include/param.h @@ -69,7 +69,7 @@ #if defined(SMP) || defined(KLD_MODULE) #ifndef MAXCPU -#define MAXCPU 8 +#define MAXCPU 32 #endif #else #define MAXCPU 1 diff --git a/sys/powerpc/include/platform.h b/sys/powerpc/include/platform.h index 48ea0e603250..d93088c9b827 100644 --- a/sys/powerpc/include/platform.h +++ b/sys/powerpc/include/platform.h @@ -52,6 +52,7 @@ int platform_smp_first_cpu(struct cpuref *); int platform_smp_next_cpu(struct cpuref *); int platform_smp_get_bsp(struct cpuref *); int platform_smp_start_cpu(struct pcpu *); +void platform_smp_ap_init(void); const char *installed_platform(void); void platform_probe_and_attach(void); diff --git a/sys/powerpc/include/pte.h b/sys/powerpc/include/pte.h index b5d2ecfdbfa4..85f169c18c70 100644 --- a/sys/powerpc/include/pte.h +++ b/sys/powerpc/include/pte.h @@ -96,8 +96,9 @@ struct lpteg { #define LPTE_VSID_SHIFT 12 #define LPTE_AVPN_MASK 0xFFFFFFFFFFFFFF80ULL #define LPTE_API 0x0000000000000F80ULL -#define LPTE_LOCKED 0x0000000000000040ULL -#define LPTE_WIRED 0x0000000000000008ULL +#define LPTE_SWBITS 0x0000000000000078ULL +#define LPTE_WIRED 0x0000000000000010ULL +#define LPTE_LOCKED 0x0000000000000008ULL #define LPTE_BIG 0x0000000000000004ULL /* 4kb/16Mb page */ #define LPTE_HID 0x0000000000000002ULL #define LPTE_VALID 0x0000000000000001ULL diff --git a/sys/powerpc/include/sf_buf.h b/sys/powerpc/include/sf_buf.h index 7ddb981bdc3a..f8a5936f8054 100644 --- a/sys/powerpc/include/sf_buf.h +++ b/sys/powerpc/include/sf_buf.h @@ -45,6 +45,9 @@ struct sf_buf { int ref_count; /* usage of this mapping */ }; +struct sf_buf * sf_buf_alloc(struct vm_page *m, int flags); +void sf_buf_free(struct sf_buf *sf); + /* * On 32-bit OEA, the only purpose for which sf_buf is used is to implement * an opaque pointer required by the machine-independent parts of the kernel. diff --git a/sys/powerpc/ofw/ofw_cpu.c b/sys/powerpc/ofw/ofw_cpu.c index 6fb1126ae3cc..6cc64841cf2f 100644 --- a/sys/powerpc/ofw/ofw_cpu.c +++ b/sys/powerpc/ofw/ofw_cpu.c @@ -158,7 +158,7 @@ static device_method_t ofw_cpu_methods[] = { static driver_t ofw_cpu_driver = { "cpu", ofw_cpu_methods, - 0 + sizeof(struct ofw_cpu_softc) }; static devclass_t ofw_cpu_devclass; diff --git a/sys/powerpc/ofw/rtas.c b/sys/powerpc/ofw/rtas.c index c6d89691a5d0..34b7acfa3a61 100644 --- a/sys/powerpc/ofw/rtas.c +++ b/sys/powerpc/ofw/rtas.c @@ -93,7 +93,7 @@ rtas_setup(void *junk) return; } - mtx_init(&rtas_mtx, "RTAS", MTX_DEF, 0); + mtx_init(&rtas_mtx, "RTAS", NULL, MTX_SPIN); /* RTAS must be called with everything turned off in MSR */ rtasmsr = mfmsr(); @@ -208,7 +208,7 @@ rtas_call_method(cell_t token, int nargs, int nreturns, ...) args.token = token; va_start(ap, nreturns); - mtx_lock(&rtas_mtx); + mtx_lock_spin(&rtas_mtx); rtas_bounce_offset = 0; args.nargs = nargs; @@ -232,7 +232,7 @@ rtas_call_method(cell_t token, int nargs, int nreturns, ...) __asm __volatile ("sync"); rtas_real_unmap(argsptr, &args, sizeof(args)); - mtx_unlock(&rtas_mtx); + mtx_unlock_spin(&rtas_mtx); if (result < 0) return (result); diff --git a/sys/powerpc/powermac/platform_powermac.c b/sys/powerpc/powermac/platform_powermac.c index 52d5c4a3c525..e21a48cbe18f 100644 --- a/sys/powerpc/powermac/platform_powermac.c +++ b/sys/powerpc/powermac/platform_powermac.c @@ -91,8 +91,22 @@ PLATFORM_DEF(powermac_platform); static int powermac_probe(platform_t plat) { - if (OF_finddevice("/memory") != -1 || OF_finddevice("/memory@0") != -1) - return (BUS_PROBE_GENERIC); + char compat[255]; + ssize_t compatlen; + char *curstr; + phandle_t root; + + root = OF_peer(0); + if (root == 0) + return (ENXIO); + + compatlen = OF_getprop(root, "compatible", compat, sizeof(compat)); + + for (curstr = compat; curstr < compat + compatlen; + curstr += strlen(curstr) + 1) { + if (strncmp(curstr, "MacRISC", 7) == 0) + return (BUS_PROBE_SPECIFIC); + } return (ENXIO); } diff --git a/sys/powerpc/powerpc/cpu.c b/sys/powerpc/powerpc/cpu.c index d67f359e41cc..a4467a917274 100644 --- a/sys/powerpc/powerpc/cpu.c +++ b/sys/powerpc/powerpc/cpu.c @@ -127,6 +127,20 @@ static const struct cputab models[] = { { "IBM PowerPC 970MP", IBM970MP, REVFMT_MAJMIN, PPC_FEATURE_64 | PPC_FEATURE_HAS_ALTIVEC | PPC_FEATURE_HAS_FPU, cpu_970_setup }, + { "IBM POWER4", IBMPOWER4, REVFMT_MAJMIN, + PPC_FEATURE_64 | PPC_FEATURE_HAS_FPU, NULL }, + { "IBM POWER4+", IBMPOWER4PLUS, REVFMT_MAJMIN, + PPC_FEATURE_64 | PPC_FEATURE_HAS_FPU, NULL }, + { "IBM POWER5", IBMPOWER5, REVFMT_MAJMIN, + PPC_FEATURE_64 | PPC_FEATURE_HAS_FPU, NULL }, + { "IBM POWER5+", IBMPOWER5PLUS, REVFMT_MAJMIN, + PPC_FEATURE_64 | PPC_FEATURE_HAS_FPU, NULL }, + { "IBM POWER6", IBMPOWER6, REVFMT_MAJMIN, + PPC_FEATURE_64 | PPC_FEATURE_HAS_ALTIVEC | PPC_FEATURE_HAS_FPU, + NULL }, + { "IBM POWER7", IBMPOWER7, REVFMT_MAJMIN, + PPC_FEATURE_64 | PPC_FEATURE_HAS_ALTIVEC | PPC_FEATURE_HAS_FPU, + NULL }, { "Motorola PowerPC 7400", MPC7400, REVFMT_MAJMIN, PPC_FEATURE_HAS_ALTIVEC | PPC_FEATURE_HAS_FPU, cpu_6xx_setup }, { "Motorola PowerPC 7410", MPC7410, REVFMT_MAJMIN, diff --git a/sys/powerpc/powerpc/intr_machdep.c b/sys/powerpc/powerpc/intr_machdep.c index abfe90507792..539d3f6467b6 100644 --- a/sys/powerpc/powerpc/intr_machdep.c +++ b/sys/powerpc/powerpc/intr_machdep.c @@ -176,7 +176,7 @@ intrcnt_add(const char *name, u_long **countp) static struct powerpc_intr * intr_lookup(u_int irq) { - char intrname[8]; + char intrname[16]; struct powerpc_intr *i, *iscan; int vector; diff --git a/sys/powerpc/powerpc/mp_machdep.c b/sys/powerpc/powerpc/mp_machdep.c index b6d977b30981..6835d0c84add 100644 --- a/sys/powerpc/powerpc/mp_machdep.c +++ b/sys/powerpc/powerpc/mp_machdep.c @@ -91,6 +91,9 @@ machdep_ap_bootstrap(void) #endif decr_ap_init(); + /* Give platform code a chance to do anything necessary */ + platform_smp_ap_init(); + /* Serialize console output and AP count increment */ mtx_lock_spin(&ap_boot_mtx); ap_awake++; diff --git a/sys/powerpc/powerpc/platform.c b/sys/powerpc/powerpc/platform.c index 169bbc199e1f..6f7e7b561159 100644 --- a/sys/powerpc/powerpc/platform.c +++ b/sys/powerpc/powerpc/platform.c @@ -141,6 +141,12 @@ platform_smp_start_cpu(struct pcpu *cpu) return (PLATFORM_SMP_START_CPU(plat_obj, cpu)); } +void +platform_smp_ap_init() +{ + PLATFORM_SMP_AP_INIT(plat_obj); +} + #ifdef SMP struct cpu_group * cpu_topo(void) diff --git a/sys/powerpc/powerpc/platform_if.m b/sys/powerpc/powerpc/platform_if.m index 94383c327d6e..cd878e02b6c4 100644 --- a/sys/powerpc/powerpc/platform_if.m +++ b/sys/powerpc/powerpc/platform_if.m @@ -80,6 +80,10 @@ CODE { { return (VM_MAX_ADDRESS); } + static void platform_null_smp_ap_init(platform_t plat) + { + return; + } }; /** @@ -184,6 +188,14 @@ METHOD int smp_start_cpu { struct pcpu *_cpu; }; +/** + * @brief Start a CPU + * + */ +METHOD void smp_ap_init { + platform_t _plat; +} DEFAULT platform_null_smp_ap_init; + /** * @brief Return SMP topology */ diff --git a/sys/rpc/clnt_dg.c b/sys/rpc/clnt_dg.c index a658de9eba53..4c1fe8c3ef2b 100644 --- a/sys/rpc/clnt_dg.c +++ b/sys/rpc/clnt_dg.c @@ -682,6 +682,7 @@ clnt_dg_call( next_sendtime += retransmit_time; goto send_again; } + cu->cu_sent += CWNDSCALE; TAILQ_INSERT_TAIL(&cs->cs_pending, cr, cr_link); } @@ -733,6 +734,7 @@ clnt_dg_call( */ XDR_DESTROY(&xdrs); mtx_lock(&cs->cs_lock); + cu->cu_sent += CWNDSCALE; TAILQ_INSERT_TAIL(&cs->cs_pending, cr, cr_link); cr->cr_mrep = NULL; diff --git a/sys/security/audit/audit.h b/sys/security/audit/audit.h index dd55875be5b4..559d571cbc45 100644 --- a/sys/security/audit/audit.h +++ b/sys/security/audit/audit.h @@ -114,7 +114,7 @@ void audit_arg_auditon(union auditon_udata *udata); void audit_arg_file(struct proc *p, struct file *fp); void audit_arg_argv(char *argv, int argc, int length); void audit_arg_envv(char *envv, int envc, int length); -void audit_arg_rights(cap_rights_t rights); +void audit_arg_rights(cap_rights_t *rightsp); void audit_arg_fcntl_rights(uint32_t fcntlrights); void audit_sysclose(struct thread *td, int fd); void audit_cred_copy(struct ucred *src, struct ucred *dest); diff --git a/sys/security/audit/audit_arg.c b/sys/security/audit/audit_arg.c index 4927be0d1349..2e86842ba439 100644 --- a/sys/security/audit/audit_arg.c +++ b/sys/security/audit/audit_arg.c @@ -861,7 +861,7 @@ audit_arg_envv(char *envv, int envc, int length) } void -audit_arg_rights(cap_rights_t rights) +audit_arg_rights(cap_rights_t *rightsp) { struct kaudit_record *ar; @@ -869,7 +869,7 @@ audit_arg_rights(cap_rights_t rights) if (ar == NULL) return; - ar->k_ar.ar_arg_rights = rights; + ar->k_ar.ar_arg_rights = *rightsp; ARG_SET_VALID(ar, ARG_RIGHTS); } diff --git a/sys/security/audit/audit_bsm.c b/sys/security/audit/audit_bsm.c index 03b3c23e5c42..9f29eceb3ad0 100644 --- a/sys/security/audit/audit_bsm.c +++ b/sys/security/audit/audit_bsm.c @@ -1611,14 +1611,13 @@ kaudit_to_bsm(struct kaudit_record *kar, struct au_record **pau) } break; - case AUE_CAP_NEW: case AUE_CAP_RIGHTS_LIMIT: /* * XXXRW/XXXJA: Would be nice to audit socket/etc information. */ FD_VNODE1_TOKENS; if (ARG_IS_VALID(kar, ARG_RIGHTS)) { - tok = au_to_arg64(2, "rights", ar->ar_arg_rights); + tok = au_to_rights(&ar->ar_arg_rights); kau_write(rec, tok); } break; diff --git a/sys/security/audit/audit_bsm_klib.c b/sys/security/audit/audit_bsm_klib.c index 5f5d58bdff28..d06c7705eafd 100644 --- a/sys/security/audit/audit_bsm_klib.c +++ b/sys/security/audit/audit_bsm_klib.c @@ -496,7 +496,7 @@ audit_canon_path(struct thread *td, int dirfd, char *path, char *cpath) vhold(cvnp); } else { /* XXX: fgetvp() that vhold()s vnode instead of vref()ing it would be better */ - error = fgetvp(td, dirfd, 0, &cvnp); + error = fgetvp(td, dirfd, NULL, &cvnp); if (error) { cpath[0] = '\0'; if (rvnp != NULL) diff --git a/sys/security/audit/audit_pipe.c b/sys/security/audit/audit_pipe.c index dc0df3e8ae4e..b2919753e076 100644 --- a/sys/security/audit/audit_pipe.c +++ b/sys/security/audit/audit_pipe.c @@ -672,14 +672,9 @@ audit_pipe_clone(void *arg, struct ucred *cred, char *name, int namelen, return; i = clone_create(&audit_pipe_clones, &audit_pipe_cdevsw, &u, dev, 0); - if (i) { - *dev = make_dev(&audit_pipe_cdevsw, u, UID_ROOT, - GID_WHEEL, 0600, "%s%d", AUDIT_PIPE_NAME, u); - if (*dev != NULL) { - dev_ref(*dev); - (*dev)->si_flags |= SI_CHEAPCLONE; - } - } + if (i) + *dev = make_dev_credf(MAKEDEV_REF, &audit_pipe_cdevsw, u, cred, + UID_ROOT, GID_WHEEL, 0600, "%s%d", AUDIT_PIPE_NAME, u); } /* diff --git a/sys/security/audit/audit_private.h b/sys/security/audit/audit_private.h index e23ba087ae1d..b5c373ae53ec 100644 --- a/sys/security/audit/audit_private.h +++ b/sys/security/audit/audit_private.h @@ -41,6 +41,7 @@ #error "no user-serviceable parts inside" #endif +#include #include #include #include diff --git a/sys/security/audit/bsm_token.c b/sys/security/audit/bsm_token.c index 6d0d67fcff12..763d59721eb7 100644 --- a/sys/security/audit/bsm_token.c +++ b/sys/security/audit/bsm_token.c @@ -835,6 +835,22 @@ au_to_process_ex(au_id_t auid, uid_t euid, gid_t egid, uid_t ruid, tid)); } +token_t * +au_to_rights(cap_rights_t *rightsp) +{ + token_t *t; + u_char *dptr; + int i; + + GET_TOKEN_AREA(t, dptr, sizeof(u_char) + sizeof(*rightsp)); + + ADD_U_CHAR(dptr, AUT_RIGHTS); + for (i = 0; i < nitems(rightsp->cr_rights); i++) + ADD_U_INT64(dptr, rightsp->cr_rights[i]); + + return (t); +} + /* * token ID 1 byte * error status 1 byte diff --git a/sys/security/mac/mac_syscalls.c b/sys/security/mac/mac_syscalls.c index ff55ec924d3a..64055869767e 100644 --- a/sys/security/mac/mac_syscalls.c +++ b/sys/security/mac/mac_syscalls.c @@ -229,6 +229,7 @@ sys___mac_get_fd(struct thread *td, struct __mac_get_fd_args *uap) struct vnode *vp; struct pipe *pipe; struct socket *so; + cap_rights_t rights; short label_type; int error; @@ -248,7 +249,7 @@ sys___mac_get_fd(struct thread *td, struct __mac_get_fd_args *uap) } buffer = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK | M_ZERO); - error = fget(td, uap->fd, CAP_MAC_GET, &fp); + error = fget(td, uap->fd, cap_rights_init(&rights, CAP_MAC_GET), &fp); if (error) goto out; @@ -425,6 +426,7 @@ sys___mac_set_fd(struct thread *td, struct __mac_set_fd_args *uap) struct mount *mp; struct vnode *vp; struct mac mac; + cap_rights_t rights; char *buffer; int error; @@ -443,7 +445,7 @@ sys___mac_set_fd(struct thread *td, struct __mac_set_fd_args *uap) return (error); } - error = fget(td, uap->fd, CAP_MAC_SET, &fp); + error = fget(td, uap->fd, cap_rights_init(&rights, CAP_MAC_SET), &fp); if (error) goto out; diff --git a/sys/sparc64/include/sf_buf.h b/sys/sparc64/include/sf_buf.h index b6ee1cc20b69..ebbbea8389ce 100644 --- a/sys/sparc64/include/sf_buf.h +++ b/sys/sparc64/include/sf_buf.h @@ -39,6 +39,9 @@ struct sf_buf { vm_offset_t kva; /* va of mapping */ }; +struct sf_buf * sf_buf_alloc(struct vm_page *m, int flags); +void sf_buf_free(struct sf_buf *sf); + static __inline vm_offset_t sf_buf_kva(struct sf_buf *sf) { diff --git a/sys/sparc64/sparc64/pmap.c b/sys/sparc64/sparc64/pmap.c index a84e4c38924d..7e63c6caa57b 100644 --- a/sys/sparc64/sparc64/pmap.c +++ b/sys/sparc64/sparc64/pmap.c @@ -786,7 +786,7 @@ pmap_init(void) continue; if (addr < VM_MIN_PROM_ADDRESS || addr > VM_MAX_PROM_ADDRESS) continue; - result = vm_map_find(kernel_map, NULL, 0, &addr, size, + result = vm_map_find(kernel_map, NULL, 0, &addr, size, 0, VMFS_NO_SPACE, VM_PROT_ALL, VM_PROT_ALL, MAP_NOFAULT); if (result != KERN_SUCCESS || addr != translations[i].om_start) panic("pmap_init: vm_map_find"); diff --git a/sys/sys/_types.h b/sys/sys/_types.h index 34d1edbd8eab..ffef9d8b9abc 100644 --- a/sys/sys/_types.h +++ b/sys/sys/_types.h @@ -38,7 +38,6 @@ typedef __uint32_t __blksize_t; /* file block size */ typedef __int64_t __blkcnt_t; /* file block count */ typedef __int32_t __clockid_t; /* clock_gettime()... */ -typedef __uint64_t __cap_rights_t; /* capability rights */ typedef __uint32_t __fflags_t; /* file flags */ typedef __uint64_t __fsblkcnt_t; typedef __uint64_t __fsfilcnt_t; diff --git a/sys/sys/capability.h b/sys/sys/capability.h index ec63de7ff9e3..e5b9ec721c90 100644 --- a/sys/sys/capability.h +++ b/sys/sys/capability.h @@ -42,9 +42,16 @@ #include #include +#include #include #include +#ifndef _KERNEL +#include +#endif + +#define CAPRIGHT(idx, bit) ((1ULL << (57 + (idx))) | (bit)) + /* * Possible rights on capabilities. * @@ -59,29 +66,31 @@ * involve reads or writes depending a great deal on context. */ -#define CAP_NONE 0x0000000000000000ULL +/* INDEX 0 */ /* * General file I/O. */ /* Allows for openat(O_RDONLY), read(2), readv(2). */ -#define CAP_READ 0x0000000000000001ULL +#define CAP_READ CAPRIGHT(0, 0x0000000000000001ULL) /* Allows for openat(O_WRONLY | O_APPEND), write(2), writev(2). */ -#define CAP_WRITE 0x0000000000000002ULL +#define CAP_WRITE CAPRIGHT(0, 0x0000000000000002ULL) +/* Allows for lseek(fd, 0, SEEK_CUR). */ +#define CAP_SEEK_TELL CAPRIGHT(0, 0x0000000000000004ULL) /* Allows for lseek(2). */ -#define CAP_SEEK 0x0000000000000080ULL +#define CAP_SEEK (CAP_SEEK_TELL | 0x0000000000000008ULL) /* Allows for pread(2), preadv(2). */ #define CAP_PREAD (CAP_SEEK | CAP_READ) /* Allows for openat(O_WRONLY) (without O_APPEND), pwrite(2), pwritev(2). */ #define CAP_PWRITE (CAP_SEEK | CAP_WRITE) /* Allows for mmap(PROT_NONE). */ -#define CAP_MMAP 0x0000000000000004ULL +#define CAP_MMAP CAPRIGHT(0, 0x0000000000000010ULL) /* Allows for mmap(PROT_READ). */ #define CAP_MMAP_R (CAP_MMAP | CAP_SEEK | CAP_READ) /* Allows for mmap(PROT_WRITE). */ #define CAP_MMAP_W (CAP_MMAP | CAP_SEEK | CAP_WRITE) /* Allows for mmap(PROT_EXEC). */ -#define CAP_MMAP_X (CAP_MMAP | CAP_SEEK | 0x0000000000000008ULL) +#define CAP_MMAP_X (CAP_MMAP | CAP_SEEK | 0x0000000000000020ULL) /* Allows for mmap(PROT_READ | PROT_WRITE). */ #define CAP_MMAP_RW (CAP_MMAP_R | CAP_MMAP_W) /* Allows for mmap(PROT_READ | PROT_EXEC). */ @@ -91,67 +100,67 @@ /* Allows for mmap(PROT_READ | PROT_WRITE | PROT_EXEC). */ #define CAP_MMAP_RWX (CAP_MMAP_R | CAP_MMAP_W | CAP_MMAP_X) /* Allows for openat(O_CREAT). */ -#define CAP_CREATE 0x0000000000080000ULL +#define CAP_CREATE CAPRIGHT(0, 0x0000000000000040ULL) /* Allows for openat(O_EXEC) and fexecve(2) in turn. */ -#define CAP_FEXECVE 0x0000000000000010ULL +#define CAP_FEXECVE CAPRIGHT(0, 0x0000000000000080ULL) /* Allows for openat(O_SYNC), openat(O_FSYNC), fsync(2). */ -#define CAP_FSYNC 0x0000000000000020ULL +#define CAP_FSYNC CAPRIGHT(0, 0x0000000000000100ULL) /* Allows for openat(O_TRUNC), ftruncate(2). */ -#define CAP_FTRUNCATE 0x0000000000000040ULL - -/* VFS methods. */ -#define CAP_FCHDIR 0x0000000000000200ULL -#define CAP_FCHFLAGS 0x0000000000000100ULL -#define CAP_CHFLAGSAT CAP_FCHFLAGS -#define CAP_FCHMOD 0x0000000000000400ULL -#define CAP_FCHMODAT CAP_FCHMOD -#define CAP_FCHOWN 0x0000000000000800ULL -#define CAP_FCHOWNAT CAP_FCHOWN -#define CAP_FCNTL 0x0000000000001000ULL -#define CAP_FLOCK 0x0000000000004000ULL -#define CAP_FPATHCONF 0x0000000000002000ULL -#define CAP_FSCK 0x0000000000008000ULL -#define CAP_FSTAT 0x0000000000010000ULL -#define CAP_FSTATAT CAP_FSTAT -#define CAP_FSTATFS 0x0000000000020000ULL -#define CAP_FUTIMES 0x0000000000040000ULL -#define CAP_FUTIMESAT CAP_FUTIMES -#define CAP_LINKAT 0x0000000000400000ULL -#define CAP_MKDIRAT 0x0000000000200000ULL -#define CAP_MKFIFOAT 0x0000000000800000ULL -#define CAP_MKNODAT 0x0080000000000000ULL -#define CAP_RENAMEAT 0x0200000000000000ULL -#define CAP_SYMLINKAT 0x0100000000000000ULL -#define CAP_UNLINKAT 0x0000000000100000ULL +#define CAP_FTRUNCATE CAPRIGHT(0, 0x0000000000000200ULL) /* Lookups - used to constrain *at() calls. */ -#define CAP_LOOKUP 0x0000000001000000ULL +#define CAP_LOOKUP CAPRIGHT(0, 0x0000000000000400ULL) + +/* VFS methods. */ +#define CAP_FCHDIR CAPRIGHT(0, 0x0000000000000800ULL) +#define CAP_FCHFLAGS CAPRIGHT(0, 0x0000000000001000ULL) +#define CAP_CHFLAGSAT (CAP_FCHFLAGS | CAP_LOOKUP) +#define CAP_FCHMOD CAPRIGHT(0, 0x0000000000002000ULL) +#define CAP_FCHMODAT (CAP_FCHMOD | CAP_LOOKUP) +#define CAP_FCHOWN CAPRIGHT(0, 0x0000000000004000ULL) +#define CAP_FCHOWNAT (CAP_FCHOWN | CAP_LOOKUP) +#define CAP_FCNTL CAPRIGHT(0, 0x0000000000008000ULL) +#define CAP_FLOCK CAPRIGHT(0, 0x0000000000010000ULL) +#define CAP_FPATHCONF CAPRIGHT(0, 0x0000000000020000ULL) +#define CAP_FSCK CAPRIGHT(0, 0x0000000000040000ULL) +#define CAP_FSTAT CAPRIGHT(0, 0x0000000000080000ULL) +#define CAP_FSTATAT (CAP_FSTAT | CAP_LOOKUP) +#define CAP_FSTATFS CAPRIGHT(0, 0x0000000000100000ULL) +#define CAP_FUTIMES CAPRIGHT(0, 0x0000000000200000ULL) +#define CAP_FUTIMESAT (CAP_FUTIMES | CAP_LOOKUP) +#define CAP_LINKAT CAPRIGHT(0, 0x0000000000400000ULL) +#define CAP_MKDIRAT CAPRIGHT(0, 0x0000000000800000ULL) +#define CAP_MKFIFOAT CAPRIGHT(0, 0x0000000001000000ULL) +#define CAP_MKNODAT CAPRIGHT(0, 0x0000000002000000ULL) +#define CAP_RENAMEAT CAPRIGHT(0, 0x0000000004000000ULL) +#define CAP_SYMLINKAT CAPRIGHT(0, 0x0000000008000000ULL) +#define CAP_UNLINKAT CAPRIGHT(0, 0x0000000010000000ULL) /* Extended attributes. */ -#define CAP_EXTATTR_DELETE 0x0000000002000000ULL -#define CAP_EXTATTR_GET 0x0000000004000000ULL -#define CAP_EXTATTR_LIST 0x0000000008000000ULL -#define CAP_EXTATTR_SET 0x0000000010000000ULL +#define CAP_EXTATTR_DELETE CAPRIGHT(0, 0x0000000020000000ULL) +#define CAP_EXTATTR_GET CAPRIGHT(0, 0x0000000040000000ULL) +#define CAP_EXTATTR_LIST CAPRIGHT(0, 0x0000000080000000ULL) +#define CAP_EXTATTR_SET CAPRIGHT(0, 0x0000000100000000ULL) /* Access Control Lists. */ -#define CAP_ACL_CHECK 0x0000000020000000ULL -#define CAP_ACL_DELETE 0x0000000040000000ULL -#define CAP_ACL_GET 0x0000000080000000ULL -#define CAP_ACL_SET 0x0000000100000000ULL +#define CAP_ACL_CHECK CAPRIGHT(0, 0x0000000200000000ULL) +#define CAP_ACL_DELETE CAPRIGHT(0, 0x0000000400000000ULL) +#define CAP_ACL_GET CAPRIGHT(0, 0x0000000800000000ULL) +#define CAP_ACL_SET CAPRIGHT(0, 0x0000001000000000ULL) /* Socket operations. */ -#define CAP_ACCEPT 0x0000000200000000ULL -#define CAP_BIND 0x0000000400000000ULL -#define CAP_CONNECT 0x0000000800000000ULL -#define CAP_GETPEERNAME 0x0000001000000000ULL -#define CAP_GETSOCKNAME 0x0000002000000000ULL -#define CAP_GETSOCKOPT 0x0000004000000000ULL -#define CAP_LISTEN 0x0000008000000000ULL -#define CAP_PEELOFF 0x0000010000000000ULL +#define CAP_ACCEPT CAPRIGHT(0, 0x0000002000000000ULL) +#define CAP_BIND CAPRIGHT(0, 0x0000004000000000ULL) +#define CAP_CONNECT CAPRIGHT(0, 0x0000008000000000ULL) +#define CAP_GETPEERNAME CAPRIGHT(0, 0x0000010000000000ULL) +#define CAP_GETSOCKNAME CAPRIGHT(0, 0x0000020000000000ULL) +#define CAP_GETSOCKOPT CAPRIGHT(0, 0x0000040000000000ULL) +#define CAP_LISTEN CAPRIGHT(0, 0x0000080000000000ULL) +#define CAP_PEELOFF CAPRIGHT(0, 0x0000100000000000ULL) #define CAP_RECV CAP_READ #define CAP_SEND CAP_WRITE -#define CAP_SETSOCKOPT 0x0000020000000000ULL -#define CAP_SHUTDOWN 0x0000040000000000ULL +#define CAP_SETSOCKOPT CAPRIGHT(0, 0x0000200000000000ULL) +#define CAP_SHUTDOWN CAPRIGHT(0, 0x0000400000000000ULL) #define CAP_SOCK_CLIENT \ (CAP_CONNECT | CAP_GETPEERNAME | CAP_GETSOCKNAME | CAP_GETSOCKOPT | \ @@ -161,56 +170,69 @@ CAP_GETSOCKOPT | CAP_LISTEN | CAP_PEELOFF | CAP_RECV | CAP_SEND | \ CAP_SETSOCKOPT | CAP_SHUTDOWN) +/* All used bits for index 0. */ +#define CAP_ALL0 CAPRIGHT(0, 0x00007FFFFFFFFFFFULL) + +/* Available bits for index 0. */ +#define CAP_UNUSED0_48 CAPRIGHT(0, 0x0000800000000000ULL) +/* ... */ +#define CAP_UNUSED0_57 CAPRIGHT(0, 0x0100000000000000ULL) + +/* INDEX 1 */ + /* Mandatory Access Control. */ -#define CAP_MAC_GET 0x0000080000000000ULL -#define CAP_MAC_SET 0x0000100000000000ULL +#define CAP_MAC_GET CAPRIGHT(1, 0x0000000000000001ULL) +#define CAP_MAC_SET CAPRIGHT(1, 0x0000000000000002ULL) /* Methods on semaphores. */ -#define CAP_SEM_GETVALUE 0x0000200000000000ULL -#define CAP_SEM_POST 0x0000400000000000ULL -#define CAP_SEM_WAIT 0x0000800000000000ULL +#define CAP_SEM_GETVALUE CAPRIGHT(1, 0x0000000000000004ULL) +#define CAP_SEM_POST CAPRIGHT(1, 0x0000000000000008ULL) +#define CAP_SEM_WAIT CAPRIGHT(1, 0x0000000000000010ULL) /* kqueue events. */ -#define CAP_POLL_EVENT 0x0001000000000000ULL -#define CAP_POST_EVENT 0x0002000000000000ULL +#define CAP_POLL_EVENT CAPRIGHT(1, 0x0000000000000020ULL) +#define CAP_POST_EVENT CAPRIGHT(1, 0x0000000000000040ULL) /* Strange and powerful rights that should not be given lightly. */ -#define CAP_IOCTL 0x0004000000000000ULL -#define CAP_TTYHOOK 0x0008000000000000ULL +#define CAP_IOCTL CAPRIGHT(1, 0x0000000000000080ULL) +#define CAP_TTYHOOK CAPRIGHT(1, 0x0000000000000100ULL) /* Process management via process descriptors. */ -#define CAP_PDGETPID 0x0010000000000000ULL -#define CAP_PDWAIT 0x0020000000000000ULL -#define CAP_PDKILL 0x0040000000000000ULL +#define CAP_PDGETPID CAPRIGHT(1, 0x0000000000000200ULL) +#define CAP_PDWAIT CAPRIGHT(1, 0x0000000000000400ULL) +#define CAP_PDKILL CAPRIGHT(1, 0x0000000000000800ULL) /* * Rights that allow to use bindat(2) and connectat(2) syscalls on a * directory descriptor. */ -#define CAP_BINDAT 0x0400000000000000ULL -#define CAP_CONNECTAT 0x0800000000000000ULL +#define CAP_BINDAT CAPRIGHT(1, 0x0000000000001000ULL) +#define CAP_CONNECTAT CAPRIGHT(1, 0x0000000000002000ULL) -/* The mask of all valid method rights. */ -#define CAP_MASK_VALID 0x0fffffffffffffffULL -#define CAP_ALL CAP_MASK_VALID +/* All used bits for index 1. */ +#define CAP_ALL1 CAPRIGHT(1, 0x0000000000003FFFULL) -/* Available bits. */ -#define CAP_UNUSED3 0x1000000000000000ULL -#define CAP_UNUSED2 0x2000000000000000ULL -#define CAP_UNUSED1 0x4000000000000000ULL -#define CAP_UNUSED0 0x8000000000000000ULL +/* Available bits for index 1. */ +#define CAP_UNUSED1_15 CAPRIGHT(1, 0x0000000000004000ULL) +/* ... */ +#define CAP_UNUSED1_57 CAPRIGHT(1, 0x0100000000000000ULL) -/* - * The following defines are provided for backward API compatibility and - * should not be used in new code. - */ -#define CAP_MAPEXEC CAP_MMAP_X -#define CAP_DELETE CAP_UNLINKAT -#define CAP_MKDIR CAP_MKDIRAT -#define CAP_RMDIR CAP_UNLINKAT -#define CAP_MKFIFO CAP_MKFIFOAT -#define CAP_MKNOD CAP_MKNODAT -#define CAP_SOCK_ALL (CAP_SOCK_CLIENT | CAP_SOCK_SERVER) +#define CAP_ALL(rights) do { \ + (rights)->cr_rights[0] = \ + ((uint64_t)CAP_RIGHTS_VERSION << 62) | CAP_ALL0; \ + (rights)->cr_rights[1] = CAP_ALL1; \ +} while (0) + +#define CAP_NONE(rights) do { \ + (rights)->cr_rights[0] = \ + ((uint64_t)CAP_RIGHTS_VERSION << 62) | CAPRIGHT(0, 0ULL); \ + (rights)->cr_rights[1] = CAPRIGHT(1, 0ULL); \ +} while (0) + +#define CAPRVER(right) ((int)((right) >> 62)) +#define CAPVER(rights) CAPRVER((rights)->cr_rights[0]) +#define CAPARSIZE(rights) (CAPVER(rights) + 2) +#define CAPIDXBIT(right) ((int)(((right) >> 57) & 0x1F)) /* * Allowed fcntl(2) commands. @@ -230,6 +252,27 @@ #define CAP_IOCTLS_ALL SSIZE_MAX +#define cap_rights_init(...) \ + __cap_rights_init(CAP_RIGHTS_VERSION, __VA_ARGS__, 0ULL) +cap_rights_t *__cap_rights_init(int version, cap_rights_t *rights, ...); + +#define cap_rights_set(rights, ...) \ + __cap_rights_set((rights), __VA_ARGS__, 0ULL) +void __cap_rights_set(cap_rights_t *rights, ...); + +#define cap_rights_clear(rights, ...) \ + __cap_rights_clear((rights), __VA_ARGS__, 0ULL) +void __cap_rights_clear(cap_rights_t *rights, ...); + +#define cap_rights_is_set(rights, ...) \ + __cap_rights_is_set((rights), __VA_ARGS__, 0ULL) +bool __cap_rights_is_set(const cap_rights_t *rights, ...); + +bool cap_rights_is_valid(const cap_rights_t *rights); +void cap_rights_merge(cap_rights_t *dst, const cap_rights_t *src); +void cap_rights_remove(cap_rights_t *dst, const cap_rights_t *src); +bool cap_rights_contains(const cap_rights_t *big, const cap_rights_t *little); + #ifdef _KERNEL #include @@ -241,17 +284,17 @@ struct filedesc; /* * Test whether a capability grants the requested rights. */ -int cap_check(cap_rights_t have, cap_rights_t need); +int cap_check(const cap_rights_t *havep, const cap_rights_t *needp); /* * Convert capability rights into VM access flags. */ -u_char cap_rights_to_vmprot(cap_rights_t have); +u_char cap_rights_to_vmprot(cap_rights_t *havep); /* * For the purposes of procstat(1) and similar tools, allow kern_descrip.c to * extract the rights from a capability. */ -cap_rights_t cap_rights(struct filedesc *fdp, int fd); +cap_rights_t *cap_rights(struct filedesc *fdp, int fd); int cap_ioctl_check(struct filedesc *fdp, int fd, u_long cmd); int cap_fcntl_check(struct filedesc *fdp, int fd, int cmd); @@ -259,18 +302,11 @@ int cap_fcntl_check(struct filedesc *fdp, int fd, int cmd); #else /* !_KERNEL */ __BEGIN_DECLS -#include - /* * cap_enter(): Cause the process to enter capability mode, which will * prevent it from directly accessing global namespaces. System calls will * be limited to process-local, process-inherited, or file descriptor * operations. If already in capability mode, a no-op. - * - * Currently, process-inherited operations are not properly handled -- in - * particular, we're interested in things like waitpid(2), kill(2), etc, - * being properly constrained. One possible solution is to introduce process - * descriptors. */ int cap_enter(void); @@ -288,11 +324,12 @@ int cap_getmode(u_int *modep); /* * Limits capability rights for the given descriptor (CAP_*). */ -int cap_rights_limit(int fd, cap_rights_t rights); +int cap_rights_limit(int fd, const cap_rights_t *rights); /* - * Returns bitmask of capability rights for the given descriptor. + * Returns capability rights for the given descriptor. */ -int cap_rights_get(int fd, cap_rights_t *rightsp); +#define cap_rights_get(fd, rights) __cap_rights_get(CAP_RIGHTS_VERSION, (fd), (rights)) +int __cap_rights_get(int version, int fd, cap_rights_t *rightsp); /* * Limits allowed ioctls for the given descriptor. */ @@ -312,10 +349,6 @@ int cap_fcntls_limit(int fd, uint32_t fcntlrights); */ int cap_fcntls_get(int fd, uint32_t *fcntlrightsp); -/* For backward compatibility. */ -int cap_new(int fd, cap_rights_t rights); -#define cap_getrights(fd, rightsp) cap_rights_get((fd), (rightsp)) - __END_DECLS #endif /* !_KERNEL */ diff --git a/sys/sys/caprights.h b/sys/sys/caprights.h new file mode 100644 index 000000000000..eb8e454f1de9 --- /dev/null +++ b/sys/sys/caprights.h @@ -0,0 +1,61 @@ +/*- + * Copyright (c) 2013 FreeBSD Foundation + * All rights reserved. + * + * This software was developed by Pawel Jakub Dawidek under sponsorship from + * the FreeBSD Foundation. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD$ + */ + +#ifndef _SYS_CAPRIGHTS_H_ +#define _SYS_CAPRIGHTS_H_ + +/* + * The top two bits in the first element of the cr_rights[] array contain + * total number of elements in the array - 2. This means if those two bits are + * equal to 0, we have 2 array elements. + * The top two bits in all remaining array elements should be 0. + * The next five bits contain array index. Only one bit is used and bit position + * in this five-bits range defines array index. This means there can be at most + * five array elements. + */ +#define CAP_RIGHTS_VERSION_00 0 +/* +#define CAP_RIGHTS_VERSION_01 1 +#define CAP_RIGHTS_VERSION_02 2 +#define CAP_RIGHTS_VERSION_03 3 +*/ +#define CAP_RIGHTS_VERSION CAP_RIGHTS_VERSION_00 + +struct cap_rights { + uint64_t cr_rights[CAP_RIGHTS_VERSION + 2]; +}; + +#ifndef _CAP_RIGHTS_T_DECLARED +#define _CAP_RIGHTS_T_DECLARED +typedef struct cap_rights cap_rights_t; +#endif + +#endif /* !_SYS_CAPRIGHTS_H_ */ diff --git a/sys/sys/file.h b/sys/sys/file.h index 72c512fb8fce..7b373f0d7091 100644 --- a/sys/sys/file.h +++ b/sys/sys/file.h @@ -217,12 +217,12 @@ extern int maxfiles; /* kernel limit on number of open files */ extern int maxfilesperproc; /* per process limit on number of open files */ extern volatile int openfiles; /* actual number of open files */ -int fget(struct thread *td, int fd, cap_rights_t rights, struct file **fpp); -int fget_mmap(struct thread *td, int fd, cap_rights_t rights, +int fget(struct thread *td, int fd, cap_rights_t *rightsp, struct file **fpp); +int fget_mmap(struct thread *td, int fd, cap_rights_t *rightsp, u_char *maxprotp, struct file **fpp); -int fget_read(struct thread *td, int fd, cap_rights_t rights, +int fget_read(struct thread *td, int fd, cap_rights_t *rightsp, struct file **fpp); -int fget_write(struct thread *td, int fd, cap_rights_t rights, +int fget_write(struct thread *td, int fd, cap_rights_t *rightsp, struct file **fpp); int _fdrop(struct file *fp, struct thread *td); @@ -248,17 +248,18 @@ fo_sendfile_t vn_sendfile; fo_seek_t vn_seek; void finit(struct file *, u_int, short, void *, struct fileops *); -int fgetvp(struct thread *td, int fd, cap_rights_t rights, struct vnode **vpp); -int fgetvp_exec(struct thread *td, int fd, cap_rights_t rights, +int fgetvp(struct thread *td, int fd, cap_rights_t *rightsp, struct vnode **vpp); -int fgetvp_rights(struct thread *td, int fd, cap_rights_t need, +int fgetvp_exec(struct thread *td, int fd, cap_rights_t *rightsp, + struct vnode **vpp); +int fgetvp_rights(struct thread *td, int fd, cap_rights_t *needrightsp, struct filecaps *havecaps, struct vnode **vpp); -int fgetvp_read(struct thread *td, int fd, cap_rights_t rights, +int fgetvp_read(struct thread *td, int fd, cap_rights_t *rightsp, struct vnode **vpp); -int fgetvp_write(struct thread *td, int fd, cap_rights_t rights, +int fgetvp_write(struct thread *td, int fd, cap_rights_t *rightsp, struct vnode **vpp); -int fgetsock(struct thread *td, int fd, cap_rights_t rights, +int fgetsock(struct thread *td, int fd, cap_rights_t *rightsp, struct socket **spp, u_int *fflagp); void fputsock(struct socket *sp); diff --git a/sys/sys/filedesc.h b/sys/sys/filedesc.h index 9f73915b8faa..968ceffe9ffa 100644 --- a/sys/sys/filedesc.h +++ b/sys/sys/filedesc.h @@ -33,6 +33,7 @@ #ifndef _SYS_FILEDESC_H_ #define _SYS_FILEDESC_H_ +#include #include #include #include @@ -108,10 +109,6 @@ struct filedesc_to_leader { #ifdef _KERNEL -#include /* CTASSERT() */ - -CTASSERT(sizeof(cap_rights_t) == sizeof(uint64_t)); - /* Flags for do_dup() */ #define DUP_FIXED 0x1 /* Force fixed allocation. */ #define DUP_FCNTL 0x2 /* fcntl()-style errors. */ @@ -163,13 +160,13 @@ struct filedesc *fdshare(struct filedesc *fdp); struct filedesc_to_leader * filedesc_to_leader_alloc(struct filedesc_to_leader *old, struct filedesc *fdp, struct proc *leader); -int getvnode(struct filedesc *fdp, int fd, cap_rights_t rights, +int getvnode(struct filedesc *fdp, int fd, cap_rights_t *rightsp, struct file **fpp); void mountcheckdirs(struct vnode *olddp, struct vnode *newdp); void setugidsafety(struct thread *td); /* Return a referenced file from an unlocked descriptor. */ -int fget_unlocked(struct filedesc *fdp, int fd, cap_rights_t needrights, +int fget_unlocked(struct filedesc *fdp, int fd, cap_rights_t *needrightsp, int needfcntl, struct file **fpp, cap_rights_t *haverightsp); /* Requires a FILEDESC_{S,X}LOCK held and returns without a ref. */ diff --git a/sys/sys/ktrace.h b/sys/sys/ktrace.h index b3e6be8a7fe2..e9cfa6ef5b80 100644 --- a/sys/sys/ktrace.h +++ b/sys/sys/ktrace.h @@ -33,6 +33,8 @@ #ifndef _SYS_KTRACE_H_ #define _SYS_KTRACE_H_ +#include + /* * operations to ktrace system call (KTROP(op)) */ @@ -264,7 +266,10 @@ void ktrprocexit(struct thread *); void ktrprocfork(struct proc *, struct proc *); void ktruserret(struct thread *); void ktrstruct(const char *, void *, size_t); -void ktrcapfail(enum ktr_cap_fail_type, cap_rights_t, cap_rights_t); +void ktrcapfail(enum ktr_cap_fail_type, const cap_rights_t *, + const cap_rights_t *); +#define ktrcaprights(s) \ + ktrstruct("caprights", (s), sizeof(cap_rights_t)) #define ktrsockaddr(s) \ ktrstruct("sockaddr", (s), ((struct sockaddr *)(s))->sa_len) #define ktrstat(s) \ diff --git a/sys/sys/mman.h b/sys/sys/mman.h index 32f0e7beac2f..eaea818d1512 100644 --- a/sys/sys/mman.h +++ b/sys/sys/mman.h @@ -91,6 +91,9 @@ */ #define MAP_NOCORE 0x00020000 /* dont include these pages in a coredump */ #define MAP_PREFAULT_READ 0x00040000 /* prefault mapping for reading */ +#ifdef __LP64__ +#define MAP_32BIT 0x00080000 /* map in the low 2GB of address space */ +#endif /* * Request specific alignment (n == log2 of the desired alignment). diff --git a/sys/sys/namei.h b/sys/sys/namei.h index a9992f43c68f..f1b1223b6ca5 100644 --- a/sys/sys/namei.h +++ b/sys/sys/namei.h @@ -33,6 +33,7 @@ #ifndef _SYS_NAMEI_H_ #define _SYS_NAMEI_H_ +#include #include #include #include @@ -158,32 +159,14 @@ struct nameidata { NDINIT_ALL(ndp, op, flags, segflg, namep, AT_FDCWD, NULL, 0, td) #define NDINIT_AT(ndp, op, flags, segflg, namep, dirfd, td) \ NDINIT_ALL(ndp, op, flags, segflg, namep, dirfd, NULL, 0, td) -#define NDINIT_ATRIGHTS(ndp, op, flags, segflg, namep, dirfd, rights, td) \ - NDINIT_ALL(ndp, op, flags, segflg, namep, dirfd, NULL, rights, td) +#define NDINIT_ATRIGHTS(ndp, op, flags, segflg, namep, dirfd, rightsp, td) \ + NDINIT_ALL(ndp, op, flags, segflg, namep, dirfd, NULL, rightsp, td) #define NDINIT_ATVP(ndp, op, flags, segflg, namep, vp, td) \ NDINIT_ALL(ndp, op, flags, segflg, namep, AT_FDCWD, vp, 0, td) -static __inline void -NDINIT_ALL(struct nameidata *ndp, - u_long op, u_long flags, - enum uio_seg segflg, - const char *namep, - int dirfd, - struct vnode *startdir, - cap_rights_t rights, - struct thread *td) -{ - ndp->ni_cnd.cn_nameiop = op; - ndp->ni_cnd.cn_flags = flags; - ndp->ni_segflg = segflg; - ndp->ni_dirp = namep; - ndp->ni_dirfd = dirfd; - ndp->ni_startdir = startdir; - ndp->ni_strictrelative = 0; - ndp->ni_rightsneeded = rights; - filecaps_init(&ndp->ni_filecaps); - ndp->ni_cnd.cn_thread = td; -} +void NDINIT_ALL(struct nameidata *ndp, u_long op, u_long flags, + enum uio_seg segflg, const char *namep, int dirfd, struct vnode *startdir, + cap_rights_t *rightsp, struct thread *td); #define NDF_NO_DVP_RELE 0x00000001 #define NDF_NO_DVP_UNLOCK 0x00000002 diff --git a/sys/sys/param.h b/sys/sys/param.h index 88c8d371f077..b29ecb39231a 100644 --- a/sys/sys/param.h +++ b/sys/sys/param.h @@ -58,7 +58,7 @@ * in the range 5 to 9. */ #undef __FreeBSD_version -#define __FreeBSD_version 1000052 /* Master, propagated to newvers */ +#define __FreeBSD_version 1000055 /* Master, propagated to newvers */ /* * __FreeBSD_kernel__ indicates that this system uses the kernel of FreeBSD, diff --git a/sys/sys/procdesc.h b/sys/sys/procdesc.h index cc8b7166f639..4d77a0564033 100644 --- a/sys/sys/procdesc.h +++ b/sys/sys/procdesc.h @@ -92,8 +92,8 @@ struct procdesc { * In-kernel interfaces to process descriptors. */ int procdesc_exit(struct proc *); -int procdesc_find(struct thread *, int fd, cap_rights_t, struct proc **); -int kern_pdgetpid(struct thread *, int fd, cap_rights_t, pid_t *pidp); +int procdesc_find(struct thread *, int fd, cap_rights_t *, struct proc **); +int kern_pdgetpid(struct thread *, int fd, cap_rights_t *, pid_t *pidp); void procdesc_new(struct proc *, int); void procdesc_finit(struct procdesc *, struct file *); pid_t procdesc_pid(struct file *); diff --git a/sys/sys/random.h b/sys/sys/random.h index 5cf1611e359c..2f86c82e854a 100644 --- a/sys/sys/random.h +++ b/sys/sys/random.h @@ -1,5 +1,5 @@ /*- - * Copyright (c) 2000 Mark R. V. Murray + * Copyright (c) 2000-2013 Mark R. V. Murray * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -42,8 +42,11 @@ enum esource { RANDOM_WRITE = 0, RANDOM_KEYBOARD, RANDOM_MOUSE, - RANDOM_NET, + RANDOM_NET_TUN, + RANDOM_NET_ETHER, + RANDOM_NET_NG, RANDOM_INTERRUPT, + RANDOM_SWI, RANDOM_PURE, ENTROPYSOURCE }; @@ -57,6 +60,7 @@ struct harvest_select { int point_to_point; int interrupt; int swi; + int namei; }; extern struct harvest_select harvest; diff --git a/sys/sys/sf_buf.h b/sys/sys/sf_buf.h index 4c37e00caf2a..2e85bc87a9e3 100644 --- a/sys/sys/sf_buf.h +++ b/sys/sys/sf_buf.h @@ -54,6 +54,7 @@ struct sfstat { /* sendfile statistics */ #ifdef _KERNEL #include +#include #include struct mbuf; /* for sf_buf_mext() */ @@ -64,9 +65,6 @@ extern counter_u64_t sfstat[sizeof(struct sfstat) / sizeof(uint64_t)]; #define SFSTAT_INC(name) SFSTAT_ADD(name, 1) #endif /* _KERNEL */ -struct sf_buf * - sf_buf_alloc(struct vm_page *m, int flags); -void sf_buf_free(struct sf_buf *sf); int sf_buf_mext(struct mbuf *mb, void *addr, void *args); #endif /* !_SYS_SF_BUF_H_ */ diff --git a/sys/sys/syscall.h b/sys/sys/syscall.h index b3214164a742..ad3c73a67e00 100644 --- a/sys/sys/syscall.h +++ b/sys/sys/syscall.h @@ -3,7 +3,7 @@ * * DO NOT EDIT-- this file is automatically generated. * $FreeBSD$ - * created from FreeBSD: head/sys/kern/syscalls.master 251526 2013-06-08 13:27:57Z glebius + * created from FreeBSD: head/sys/kern/syscalls.master 255219 2013-09-05 00:09:56Z pjd */ #define SYS_syscall 0 @@ -434,8 +434,8 @@ #define SYS_msgctl 511 #define SYS_shmctl 512 #define SYS_lpathconf 513 -#define SYS_cap_new 514 -#define SYS_cap_rights_get 515 + /* 514 is obsolete cap_new */ +#define SYS___cap_rights_get 515 #define SYS_cap_enter 516 #define SYS_cap_getmode 517 #define SYS_pdfork 518 diff --git a/sys/sys/syscall.mk b/sys/sys/syscall.mk index df7d19f9a535..eaf73787d8db 100644 --- a/sys/sys/syscall.mk +++ b/sys/sys/syscall.mk @@ -1,7 +1,7 @@ # FreeBSD system call names. # DO NOT EDIT-- this file is automatically generated. # $FreeBSD$ -# created from FreeBSD: head/sys/kern/syscalls.master 251526 2013-06-08 13:27:57Z glebius +# created from FreeBSD: head/sys/kern/syscalls.master 255219 2013-09-05 00:09:56Z pjd MIASM = \ syscall.o \ exit.o \ @@ -383,8 +383,7 @@ MIASM = \ msgctl.o \ shmctl.o \ lpathconf.o \ - cap_new.o \ - cap_rights_get.o \ + __cap_rights_get.o \ cap_enter.o \ cap_getmode.o \ pdfork.o \ diff --git a/sys/sys/sysproto.h b/sys/sys/sysproto.h index 6a54152c2b60..5f8a2172234b 100644 --- a/sys/sys/sysproto.h +++ b/sys/sys/sysproto.h @@ -3,7 +3,7 @@ * * DO NOT EDIT-- this file is automatically generated. * $FreeBSD$ - * created from FreeBSD: head/sys/kern/syscalls.master 251526 2013-06-08 13:27:57Z glebius + * created from FreeBSD: head/sys/kern/syscalls.master 255219 2013-09-05 00:09:56Z pjd */ #ifndef _SYS_SYSPROTO_H_ @@ -1672,13 +1672,10 @@ struct lpathconf_args { char path_l_[PADL_(char *)]; char * path; char path_r_[PADR_(char *)]; char name_l_[PADL_(int)]; int name; char name_r_[PADR_(int)]; }; -struct cap_new_args { +struct __cap_rights_get_args { + char version_l_[PADL_(int)]; int version; char version_r_[PADR_(int)]; char fd_l_[PADL_(int)]; int fd; char fd_r_[PADR_(int)]; - char rights_l_[PADL_(uint64_t)]; uint64_t rights; char rights_r_[PADR_(uint64_t)]; -}; -struct cap_rights_get_args { - char fd_l_[PADL_(int)]; int fd; char fd_r_[PADR_(int)]; - char rightsp_l_[PADL_(uint64_t *)]; uint64_t * rightsp; char rightsp_r_[PADR_(uint64_t *)]; + char rightsp_l_[PADL_(cap_rights_t *)]; cap_rights_t * rightsp; char rightsp_r_[PADR_(cap_rights_t *)]; }; struct cap_enter_args { register_t dummy; @@ -1764,7 +1761,7 @@ struct wait6_args { }; struct cap_rights_limit_args { char fd_l_[PADL_(int)]; int fd; char fd_r_[PADR_(int)]; - char rights_l_[PADL_(uint64_t)]; uint64_t rights; char rights_r_[PADR_(uint64_t)]; + char rightsp_l_[PADL_(cap_rights_t *)]; cap_rights_t * rightsp; char rightsp_r_[PADR_(cap_rights_t *)]; }; struct cap_ioctls_limit_args { char fd_l_[PADL_(int)]; int fd; char fd_r_[PADR_(int)]; @@ -2179,8 +2176,7 @@ int sys___semctl(struct thread *, struct __semctl_args *); int sys_msgctl(struct thread *, struct msgctl_args *); int sys_shmctl(struct thread *, struct shmctl_args *); int sys_lpathconf(struct thread *, struct lpathconf_args *); -int sys_cap_new(struct thread *, struct cap_new_args *); -int sys_cap_rights_get(struct thread *, struct cap_rights_get_args *); +int sys___cap_rights_get(struct thread *, struct __cap_rights_get_args *); int sys_cap_enter(struct thread *, struct cap_enter_args *); int sys_cap_getmode(struct thread *, struct cap_getmode_args *); int sys_pdfork(struct thread *, struct pdfork_args *); @@ -2886,8 +2882,7 @@ int freebsd7_shmctl(struct thread *, struct freebsd7_shmctl_args *); #define SYS_AUE_msgctl AUE_MSGCTL #define SYS_AUE_shmctl AUE_SHMCTL #define SYS_AUE_lpathconf AUE_LPATHCONF -#define SYS_AUE_cap_new AUE_CAP_NEW -#define SYS_AUE_cap_rights_get AUE_CAP_RIGHTS_GET +#define SYS_AUE___cap_rights_get AUE_CAP_RIGHTS_GET #define SYS_AUE_cap_enter AUE_CAP_ENTER #define SYS_AUE_cap_getmode AUE_CAP_GETMODE #define SYS_AUE_pdfork AUE_PDFORK diff --git a/sys/sys/systm.h b/sys/sys/systm.h index e3ea9cf20620..f097e83c1f09 100644 --- a/sys/sys/systm.h +++ b/sys/sys/systm.h @@ -212,6 +212,7 @@ u_long strtoul(const char *, char **, int) __nonnull(1); quad_t strtoq(const char *, char **, int) __nonnull(1); u_quad_t strtouq(const char *, char **, int) __nonnull(1); void tprintf(struct proc *p, int pri, const char *, ...) __printflike(3, 4); +void vtprintf(struct proc *, int, const char *, __va_list) __printflike(3, 0); void hexdump(const void *ptr, int length, const char *hdr, int flags); #define HD_COLUMN_MASK 0xff #define HD_DELIM_MASK 0xff00 diff --git a/sys/sys/types.h b/sys/sys/types.h index cc0bca8f33bd..03eaa6002ef6 100644 --- a/sys/sys/types.h +++ b/sys/sys/types.h @@ -88,8 +88,6 @@ typedef __blkcnt_t blkcnt_t; #define _BLKCNT_T_DECLARED #endif -typedef __cap_rights_t cap_rights_t; - #ifndef _CLOCK_T_DECLARED typedef __clock_t clock_t; #define _CLOCK_T_DECLARED @@ -234,6 +232,13 @@ typedef __useconds_t useconds_t; /* microseconds (unsigned) */ #define _USECONDS_T_DECLARED #endif +#ifndef _CAP_RIGHTS_T_DECLARED +#define _CAP_RIGHTS_T_DECLARED +struct cap_rights; + +typedef struct cap_rights cap_rights_t; +#endif + typedef __vm_offset_t vm_offset_t; typedef __vm_ooffset_t vm_ooffset_t; typedef __vm_paddr_t vm_paddr_t; diff --git a/sys/sys/user.h b/sys/sys/user.h index 9389e55e0b08..349003d73daf 100644 --- a/sys/sys/user.h +++ b/sys/sys/user.h @@ -61,6 +61,7 @@ #ifndef _SYS_SOCKET_VAR_H_ #include #endif +#include /* * KERN_PROC subtype ops return arrays of selected proc structure entries: @@ -318,7 +319,7 @@ struct kinfo_ofile { }; #if defined(__amd64__) || defined(__i386__) -#define KINFO_FILE_SIZE 1392 +#define KINFO_FILE_SIZE 1424 #endif struct kinfo_file { @@ -389,6 +390,7 @@ struct kinfo_file { uint16_t kf_pad1; /* Round to 32 bit alignment. */ int _kf_ispare0; /* Space for more stuff. */ cap_rights_t kf_cap_rights; /* Capability rights. */ + uint64_t _kf_cap_spare[3]; /* Space for future cap_rights_t. */ int _kf_ispare[4]; /* Space for more stuff. */ /* Truncated before copyout in sysctl */ char kf_path[PATH_MAX]; /* Path to file, if any. */ diff --git a/sys/ufs/ffs/ffs_alloc.c b/sys/ufs/ffs/ffs_alloc.c index 3063adeb5bd1..19e880c63541 100644 --- a/sys/ufs/ffs/ffs_alloc.c +++ b/sys/ufs/ffs/ffs_alloc.c @@ -2709,6 +2709,7 @@ sysctl_ffs_fsck(SYSCTL_HANDLER_ARGS) long blkcnt, blksize; struct filedesc *fdp; struct file *fp, *vfp; + cap_rights_t rights; int filetype, error; static struct fileops *origops, bufferedops; @@ -2718,8 +2719,8 @@ sysctl_ffs_fsck(SYSCTL_HANDLER_ARGS) return (error); if (cmd.version != FFS_CMD_VERSION) return (ERPCMISMATCH); - if ((error = getvnode(td->td_proc->p_fd, cmd.handle, CAP_FSCK, - &fp)) != 0) + if ((error = getvnode(td->td_proc->p_fd, cmd.handle, + cap_rights_init(&rights, CAP_FSCK), &fp)) != 0) return (error); vp = fp->f_data; if (vp->v_type != VREG && vp->v_type != VDIR) { @@ -3033,7 +3034,7 @@ sysctl_ffs_fsck(SYSCTL_HANDLER_ARGS) } #endif /* DEBUG */ if ((error = getvnode(td->td_proc->p_fd, cmd.value, - CAP_FSCK, &vfp)) != 0) + cap_rights_init(&rights, CAP_FSCK), &vfp)) != 0) break; if (vfp->f_vnode->v_type != VCHR) { fdrop(vfp, td); diff --git a/sys/vm/vm_init.c b/sys/vm/vm_init.c index 0a381d03aefa..30faa5a2aeb2 100644 --- a/sys/vm/vm_init.c +++ b/sys/vm/vm_init.c @@ -111,7 +111,7 @@ kva_import(void *unused, vmem_size_t size, int flags, vmem_addr_t *addrp) int result; addr = vm_map_min(kernel_map); - result = vm_map_find(kernel_map, NULL, 0, &addr, size, + result = vm_map_find(kernel_map, NULL, 0, &addr, size, 0, VMFS_SUPER_SPACE, VM_PROT_ALL, VM_PROT_ALL, MAP_NOFAULT); if (result != KERN_SUCCESS) return (ENOMEM); diff --git a/sys/vm/vm_kern.c b/sys/vm/vm_kern.c index 9790653169bf..dd075c1569a0 100644 --- a/sys/vm/vm_kern.c +++ b/sys/vm/vm_kern.c @@ -285,7 +285,7 @@ kmem_suballoc(vm_map_t parent, vm_offset_t *min, vm_offset_t *max, size = round_page(size); *min = vm_map_min(parent); - ret = vm_map_find(parent, NULL, 0, min, size, superpage_align ? + ret = vm_map_find(parent, NULL, 0, min, size, 0, superpage_align ? VMFS_SUPER_SPACE : VMFS_ANY_SPACE, VM_PROT_ALL, VM_PROT_ALL, MAP_ACC_NO_CHARGE); if (ret != KERN_SUCCESS) diff --git a/sys/vm/vm_map.c b/sys/vm/vm_map.c index 1be62af35a6b..599063006182 100644 --- a/sys/vm/vm_map.c +++ b/sys/vm/vm_map.c @@ -1432,8 +1432,8 @@ vm_map_fixed(vm_map_t map, vm_object_t object, vm_ooffset_t offset, int vm_map_find(vm_map_t map, vm_object_t object, vm_ooffset_t offset, vm_offset_t *addr, /* IN/OUT */ - vm_size_t length, int find_space, vm_prot_t prot, - vm_prot_t max, int cow) + vm_size_t length, vm_offset_t max_addr, int find_space, + vm_prot_t prot, vm_prot_t max, int cow) { vm_offset_t alignment, initial_addr, start; int result; @@ -1452,7 +1452,8 @@ vm_map_find(vm_map_t map, vm_object_t object, vm_ooffset_t offset, vm_map_lock(map); do { if (find_space != VMFS_NO_SPACE) { - if (vm_map_findspace(map, start, length, addr)) { + if (vm_map_findspace(map, start, length, addr) || + (max_addr != 0 && *addr + length > max_addr)) { vm_map_unlock(map); if (find_space == VMFS_OPTIMAL_SPACE) { find_space = VMFS_ANY_SPACE; diff --git a/sys/vm/vm_map.h b/sys/vm/vm_map.h index 054c50624845..850bf257c53b 100644 --- a/sys/vm/vm_map.h +++ b/sys/vm/vm_map.h @@ -366,7 +366,7 @@ boolean_t vm_map_check_protection (vm_map_t, vm_offset_t, vm_offset_t, vm_prot_t vm_map_t vm_map_create(pmap_t, vm_offset_t, vm_offset_t); int vm_map_delete(vm_map_t, vm_offset_t, vm_offset_t); int vm_map_find(vm_map_t, vm_object_t, vm_ooffset_t, vm_offset_t *, vm_size_t, - int, vm_prot_t, vm_prot_t, int); + vm_offset_t, int, vm_prot_t, vm_prot_t, int); int vm_map_fixed(vm_map_t, vm_object_t, vm_ooffset_t, vm_offset_t, vm_size_t, vm_prot_t, vm_prot_t, int); int vm_map_findspace (vm_map_t, vm_offset_t, vm_size_t, vm_offset_t *); diff --git a/sys/vm/vm_mmap.c b/sys/vm/vm_mmap.c index 53a7be51d7f7..95484857c87a 100644 --- a/sys/vm/vm_mmap.c +++ b/sys/vm/vm_mmap.c @@ -94,10 +94,8 @@ SYSCTL_INT(_vm, OID_AUTO, old_mlock, CTLFLAG_RW | CTLFLAG_TUN, &old_mlock, 0, "Do not apply RLIMIT_MEMLOCK on mlockall"); TUNABLE_INT("vm.old_mlock", &old_mlock); -#ifndef _SYS_SYSPROTO_H_ -struct sbrk_args { - int incr; -}; +#ifdef MAP_32BIT +#define MAP_32BIT_MAX_ADDR ((vm_offset_t)1 << 31) #endif static int vm_mmap_vnode(struct thread *, vm_size_t, vm_prot_t, vm_prot_t *, @@ -107,6 +105,12 @@ static int vm_mmap_cdev(struct thread *, vm_size_t, vm_prot_t, vm_prot_t *, static int vm_mmap_shm(struct thread *, vm_size_t, vm_prot_t, vm_prot_t *, int *, struct shmfd *, vm_ooffset_t, vm_object_t *); +#ifndef _SYS_SYSPROTO_H_ +struct sbrk_args { + int incr; +}; +#endif + /* * MPSAFE */ @@ -278,6 +282,18 @@ sys_mmap(td, uap) return (EINVAL); if (addr + size < addr) return (EINVAL); +#ifdef MAP_32BIT + if (flags & MAP_32BIT && addr + size > MAP_32BIT_MAX_ADDR) + return (EINVAL); + } else if (flags & MAP_32BIT) { + /* + * For MAP_32BIT, override the hint if it is too high and + * do not bother moving the mapping past the heap (since + * the heap is usually above 2GB). + */ + if (addr + size > MAP_32BIT_MAX_ADDR) + addr = 0; +#endif } else { /* * XXX for non-fixed mappings where no hint is provided or @@ -311,17 +327,17 @@ sys_mmap(td, uap) * rights, but also return the maximum rights to be combined * with maxprot later. */ - rights = CAP_MMAP; + cap_rights_init(&rights, CAP_MMAP); if (prot & PROT_READ) - rights |= CAP_MMAP_R; + cap_rights_set(&rights, CAP_MMAP_R); if ((flags & MAP_SHARED) != 0) { if (prot & PROT_WRITE) - rights |= CAP_MMAP_W; + cap_rights_set(&rights, CAP_MMAP_W); } if (prot & PROT_EXEC) - rights |= CAP_MMAP_X; - if ((error = fget_mmap(td, uap->fd, rights, &cap_maxprot, - &fp)) != 0) + cap_rights_set(&rights, CAP_MMAP_X); + error = fget_mmap(td, uap->fd, &rights, &cap_maxprot, &fp); + if (error != 0) goto done; if (fp->f_type == DTYPE_SHM) { handle = fp->f_data; @@ -1620,8 +1636,11 @@ vm_mmap(vm_map_t map, vm_offset_t *addr, vm_size_t size, vm_prot_t prot, MAP_ALIGNMENT_SHIFT); else findspace = VMFS_OPTIMAL_SPACE; - rv = vm_map_find(map, object, foff, addr, size, findspace, - prot, maxprot, docow); + rv = vm_map_find(map, object, foff, addr, size, +#ifdef MAP_32BIT + flags & MAP_32BIT ? MAP_32BIT_MAX_ADDR : +#endif + 0, findspace, prot, maxprot, docow); } else rv = vm_map_fixed(map, object, foff, *addr, size, prot, maxprot, docow); diff --git a/sys/vm/vm_object.c b/sys/vm/vm_object.c index 1d7f3212fc0d..9dea3a1cbd9f 100644 --- a/sys/vm/vm_object.c +++ b/sys/vm/vm_object.c @@ -1910,6 +1910,12 @@ vm_object_page_remove(vm_object_t object, vm_pindex_t start, vm_pindex_t end, * not specified. */ vm_page_lock(p); + if (vm_page_xbusied(p)) { + VM_OBJECT_WUNLOCK(object); + vm_page_busy_sleep(p, "vmopax"); + VM_OBJECT_WLOCK(object); + goto again; + } if ((wirings = p->wire_count) != 0 && (wirings = pmap_page_wired_mappings(p)) != p->wire_count) { if ((options & (OBJPR_NOTWIRED | OBJPR_NOTMAPPED)) == diff --git a/sys/vm/vm_page.c b/sys/vm/vm_page.c index 7b4b57cdf236..53ffc725ac39 100644 --- a/sys/vm/vm_page.c +++ b/sys/vm/vm_page.c @@ -602,9 +602,13 @@ vm_page_trysbusy(vm_page_t m) { u_int x; - x = m->busy_lock; - return ((x & VPB_BIT_SHARED) != 0 && - atomic_cmpset_acq_int(&m->busy_lock, x, x + VPB_ONE_SHARER)); + for (;;) { + x = m->busy_lock; + if ((x & VPB_BIT_SHARED) == 0) + return (0); + if (atomic_cmpset_acq_int(&m->busy_lock, x, x + VPB_ONE_SHARER)) + return (1); + } } /* diff --git a/sys/x86/xen/hvm.c b/sys/x86/xen/hvm.c index c689b4787d0e..0404fe9af080 100644 --- a/sys/x86/xen/hvm.c +++ b/sys/x86/xen/hvm.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008 Citrix Systems, Inc. + * Copyright (c) 2008, 2013 Citrix Systems, Inc. * Copyright (c) 2012 Spectra Logic Corporation * All rights reserved. * @@ -33,9 +33,19 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include +#include + +#include +#include #include + #include +#include +#include + +#include #include #include @@ -44,30 +54,450 @@ __FBSDID("$FreeBSD$"); #include #include -#include -#include - #include #include -static MALLOC_DEFINE(M_XENHVM, "xen_hvm", "Xen HVM PV Support"); +/*--------------------------- Forward Declarations ---------------------------*/ +static driver_filter_t xen_smp_rendezvous_action; +static driver_filter_t xen_invltlb; +static driver_filter_t xen_invlpg; +static driver_filter_t xen_invlrng; +static driver_filter_t xen_invlcache; +#ifdef __i386__ +static driver_filter_t xen_lazypmap; +#endif +static driver_filter_t xen_ipi_bitmap_handler; +static driver_filter_t xen_cpustop_handler; +static driver_filter_t xen_cpususpend_handler; +static driver_filter_t xen_cpustophard_handler; -DPCPU_DEFINE(struct vcpu_info, vcpu_local_info); -DPCPU_DEFINE(struct vcpu_info *, vcpu_info); +/*---------------------------- Extern Declarations ---------------------------*/ +/* Variables used by mp_machdep to perform the MMU related IPIs */ +extern volatile int smp_tlb_wait; +extern vm_offset_t smp_tlb_addr2; +#ifdef __i386__ +extern vm_offset_t smp_tlb_addr1; +#else +extern struct invpcid_descr smp_tlb_invpcid; +extern uint64_t pcid_cr3; +extern int invpcid_works; +extern int pmap_pcid_enabled; +extern pmap_t smp_tlb_pmap; +#endif + +#ifdef __i386__ +extern void pmap_lazyfix_action(void); +#endif + +/*---------------------------------- Macros ----------------------------------*/ +#define IPI_TO_IDX(ipi) ((ipi) - APIC_IPI_INTS) + +/*-------------------------------- Local Types -------------------------------*/ +struct xen_ipi_handler +{ + driver_filter_t *filter; + const char *description; +}; /*-------------------------------- Global Data -------------------------------*/ +enum xen_domain_type xen_domain_type = XEN_NATIVE; + +static MALLOC_DEFINE(M_XENHVM, "xen_hvm", "Xen HVM PV Support"); + +static struct xen_ipi_handler xen_ipis[] = +{ + [IPI_TO_IDX(IPI_RENDEZVOUS)] = { xen_smp_rendezvous_action, "r" }, + [IPI_TO_IDX(IPI_INVLTLB)] = { xen_invltlb, "itlb"}, + [IPI_TO_IDX(IPI_INVLPG)] = { xen_invlpg, "ipg" }, + [IPI_TO_IDX(IPI_INVLRNG)] = { xen_invlrng, "irg" }, + [IPI_TO_IDX(IPI_INVLCACHE)] = { xen_invlcache, "ic" }, +#ifdef __i386__ + [IPI_TO_IDX(IPI_LAZYPMAP)] = { xen_lazypmap, "lp" }, +#endif + [IPI_TO_IDX(IPI_BITMAP_VECTOR)] = { xen_ipi_bitmap_handler, "b" }, + [IPI_TO_IDX(IPI_STOP)] = { xen_cpustop_handler, "st" }, + [IPI_TO_IDX(IPI_SUSPEND)] = { xen_cpususpend_handler, "sp" }, + [IPI_TO_IDX(IPI_STOP_HARD)] = { xen_cpustophard_handler, "sth" }, +}; + /** * If non-zero, the hypervisor has been configured to use a direct * IDT event callback for interrupt injection. */ int xen_vector_callback_enabled; +/*------------------------------- Per-CPU Data -------------------------------*/ +DPCPU_DEFINE(struct vcpu_info, vcpu_local_info); +DPCPU_DEFINE(struct vcpu_info *, vcpu_info); +DPCPU_DEFINE(xen_intr_handle_t, ipi_handle[nitems(xen_ipis)]); + /*------------------ Hypervisor Access Shared Memory Regions -----------------*/ /** Hypercall table accessed via HYPERVISOR_*_op() methods. */ char *hypercall_stubs; shared_info_t *HYPERVISOR_shared_info; -enum xen_domain_type xen_domain_type = XEN_NATIVE; +/*---------------------------- XEN PV IPI Handlers ---------------------------*/ +/* + * This are C clones of the ASM functions found in apic_vector.s + */ +static int +xen_ipi_bitmap_handler(void *arg) +{ + struct trapframe *frame; + + frame = arg; + ipi_bitmap_handler(*frame); + return (FILTER_HANDLED); +} + +static int +xen_smp_rendezvous_action(void *arg) +{ +#ifdef COUNT_IPIS + int cpu; + + cpu = PCPU_GET(cpuid); + (*ipi_rendezvous_counts[cpu])++; +#endif /* COUNT_IPIS */ + + smp_rendezvous_action(); + return (FILTER_HANDLED); +} + +static int +xen_invltlb(void *arg) +{ +#if defined(COUNT_XINVLTLB_HITS) || defined(COUNT_IPIS) + int cpu; + + cpu = PCPU_GET(cpuid); +#ifdef COUNT_XINVLTLB_HITS + xhits_gbl[cpu]++; +#endif /* COUNT_XINVLTLB_HITS */ +#ifdef COUNT_IPIS + (*ipi_invltlb_counts[cpu])++; +#endif /* COUNT_IPIS */ +#endif /* COUNT_XINVLTLB_HITS || COUNT_IPIS */ + + invltlb(); + atomic_add_int(&smp_tlb_wait, 1); + return (FILTER_HANDLED); +} + +#ifdef __amd64__ +static int +xen_invltlb_pcid(void *arg) +{ + uint64_t cr3; +#if defined(COUNT_XINVLTLB_HITS) || defined(COUNT_IPIS) + int cpu; + + cpu = PCPU_GET(cpuid); +#ifdef COUNT_XINVLTLB_HITS + xhits_gbl[cpu]++; +#endif /* COUNT_XINVLTLB_HITS */ +#ifdef COUNT_IPIS + (*ipi_invltlb_counts[cpu])++; +#endif /* COUNT_IPIS */ +#endif /* COUNT_XINVLTLB_HITS || COUNT_IPIS */ + + cr3 = rcr3(); + if (smp_tlb_invpcid.pcid != (uint64_t)-1 && + smp_tlb_invpcid.pcid != 0) { + + if (invpcid_works) { + invpcid(&smp_tlb_invpcid, INVPCID_CTX); + } else { + /* Otherwise reload %cr3 twice. */ + if (cr3 != pcid_cr3) { + load_cr3(pcid_cr3); + cr3 |= CR3_PCID_SAVE; + } + load_cr3(cr3); + } + } else { + invltlb_globpcid(); + } + if (smp_tlb_pmap != NULL) + CPU_CLR_ATOMIC(PCPU_GET(cpuid), &smp_tlb_pmap->pm_save); + + atomic_add_int(&smp_tlb_wait, 1); + return (FILTER_HANDLED); +} +#endif + +static int +xen_invlpg(void *arg) +{ +#if defined(COUNT_XINVLTLB_HITS) || defined(COUNT_IPIS) + int cpu; + + cpu = PCPU_GET(cpuid); +#ifdef COUNT_XINVLTLB_HITS + xhits_pg[cpu]++; +#endif /* COUNT_XINVLTLB_HITS */ +#ifdef COUNT_IPIS + (*ipi_invlpg_counts[cpu])++; +#endif /* COUNT_IPIS */ +#endif /* COUNT_XINVLTLB_HITS || COUNT_IPIS */ + +#ifdef __i386__ + invlpg(smp_tlb_addr1); +#else + invlpg(smp_tlb_invpcid.addr); +#endif + atomic_add_int(&smp_tlb_wait, 1); + return (FILTER_HANDLED); +} + +#ifdef __amd64__ +static int +xen_invlpg_pcid(void *arg) +{ +#if defined(COUNT_XINVLTLB_HITS) || defined(COUNT_IPIS) + int cpu; + + cpu = PCPU_GET(cpuid); +#ifdef COUNT_XINVLTLB_HITS + xhits_pg[cpu]++; +#endif /* COUNT_XINVLTLB_HITS */ +#ifdef COUNT_IPIS + (*ipi_invlpg_counts[cpu])++; +#endif /* COUNT_IPIS */ +#endif /* COUNT_XINVLTLB_HITS || COUNT_IPIS */ + + if (invpcid_works) { + invpcid(&smp_tlb_invpcid, INVPCID_ADDR); + } else if (smp_tlb_invpcid.pcid == 0) { + invlpg(smp_tlb_invpcid.addr); + } else if (smp_tlb_invpcid.pcid == (uint64_t)-1) { + invltlb_globpcid(); + } else { + uint64_t cr3; + + /* + * PCID supported, but INVPCID is not. + * Temporarily switch to the target address + * space and do INVLPG. + */ + cr3 = rcr3(); + if (cr3 != pcid_cr3) + load_cr3(pcid_cr3 | CR3_PCID_SAVE); + invlpg(smp_tlb_invpcid.addr); + load_cr3(cr3 | CR3_PCID_SAVE); + } + + atomic_add_int(&smp_tlb_wait, 1); + return (FILTER_HANDLED); +} +#endif + +static inline void +invlpg_range(vm_offset_t start, vm_offset_t end) +{ + do { + invlpg(start); + start += PAGE_SIZE; + } while (start < end); +} + +static int +xen_invlrng(void *arg) +{ + vm_offset_t addr; +#if defined(COUNT_XINVLTLB_HITS) || defined(COUNT_IPIS) + int cpu; + + cpu = PCPU_GET(cpuid); +#ifdef COUNT_XINVLTLB_HITS + xhits_rng[cpu]++; +#endif /* COUNT_XINVLTLB_HITS */ +#ifdef COUNT_IPIS + (*ipi_invlrng_counts[cpu])++; +#endif /* COUNT_IPIS */ +#endif /* COUNT_XINVLTLB_HITS || COUNT_IPIS */ + +#ifdef __i386__ + addr = smp_tlb_addr1; + invlpg_range(addr, smp_tlb_addr2); +#else + addr = smp_tlb_invpcid.addr; + if (pmap_pcid_enabled) { + if (invpcid_works) { + struct invpcid_descr d; + + d = smp_tlb_invpcid; + do { + invpcid(&d, INVPCID_ADDR); + d.addr += PAGE_SIZE; + } while (d.addr < smp_tlb_addr2); + } else if (smp_tlb_invpcid.pcid == 0) { + /* + * kernel pmap - use invlpg to invalidate + * global mapping. + */ + invlpg_range(addr, smp_tlb_addr2); + } else if (smp_tlb_invpcid.pcid != (uint64_t)-1) { + invltlb_globpcid(); + if (smp_tlb_pmap != NULL) { + CPU_CLR_ATOMIC(PCPU_GET(cpuid), + &smp_tlb_pmap->pm_save); + } + } else { + uint64_t cr3; + + cr3 = rcr3(); + if (cr3 != pcid_cr3) + load_cr3(pcid_cr3 | CR3_PCID_SAVE); + invlpg_range(addr, smp_tlb_addr2); + load_cr3(cr3 | CR3_PCID_SAVE); + } + } else { + invlpg_range(addr, smp_tlb_addr2); + } +#endif + + atomic_add_int(&smp_tlb_wait, 1); + return (FILTER_HANDLED); +} + +static int +xen_invlcache(void *arg) +{ +#ifdef COUNT_IPIS + int cpu = PCPU_GET(cpuid); + + cpu = PCPU_GET(cpuid); + (*ipi_invlcache_counts[cpu])++; +#endif /* COUNT_IPIS */ + + wbinvd(); + atomic_add_int(&smp_tlb_wait, 1); + return (FILTER_HANDLED); +} + +#ifdef __i386__ +static int +xen_lazypmap(void *arg) +{ + + pmap_lazyfix_action(); + return (FILTER_HANDLED); +} +#endif + +static int +xen_cpustop_handler(void *arg) +{ + + cpustop_handler(); + return (FILTER_HANDLED); +} + +static int +xen_cpususpend_handler(void *arg) +{ + + cpususpend_handler(); + return (FILTER_HANDLED); +} + +static int +xen_cpustophard_handler(void *arg) +{ + + ipi_nmi_handler(); + return (FILTER_HANDLED); +} + +/* Xen PV IPI sender */ +static void +xen_ipi_vectored(u_int vector, int dest) +{ + xen_intr_handle_t *ipi_handle; + int ipi_idx, to_cpu, self; + + ipi_idx = IPI_TO_IDX(vector); + if (ipi_idx > nitems(xen_ipis)) + panic("IPI out of range"); + + switch(dest) { + case APIC_IPI_DEST_SELF: + ipi_handle = DPCPU_GET(ipi_handle); + xen_intr_signal(ipi_handle[ipi_idx]); + break; + case APIC_IPI_DEST_ALL: + CPU_FOREACH(to_cpu) { + ipi_handle = DPCPU_ID_GET(to_cpu, ipi_handle); + xen_intr_signal(ipi_handle[ipi_idx]); + } + break; + case APIC_IPI_DEST_OTHERS: + self = PCPU_GET(cpuid); + CPU_FOREACH(to_cpu) { + if (to_cpu != self) { + ipi_handle = DPCPU_ID_GET(to_cpu, ipi_handle); + xen_intr_signal(ipi_handle[ipi_idx]); + } + } + break; + default: + to_cpu = apic_cpuid(dest); + ipi_handle = DPCPU_ID_GET(to_cpu, ipi_handle); + xen_intr_signal(ipi_handle[ipi_idx]); + break; + } +} + +static void +xen_cpu_ipi_init(int cpu) +{ + xen_intr_handle_t *ipi_handle; + const struct xen_ipi_handler *ipi; + device_t dev; + int idx, rc; + + ipi_handle = DPCPU_ID_GET(cpu, ipi_handle); + dev = pcpu_find(cpu)->pc_device; + KASSERT((dev != NULL), ("NULL pcpu device_t")); + + for (ipi = xen_ipis, idx = 0; idx < nitems(xen_ipis); ipi++, idx++) { + + if (ipi->filter == NULL) { + ipi_handle[idx] = NULL; + continue; + } + + rc = xen_intr_alloc_and_bind_ipi(dev, cpu, ipi->filter, + INTR_TYPE_TTY, &ipi_handle[idx]); + if (rc != 0) + panic("Unable to allocate a XEN IPI port"); + xen_intr_describe(ipi_handle[idx], "%s", ipi->description); + } +} + +static void +xen_init_ipis(void) +{ + int i; + + if (!xen_hvm_domain() || !xen_vector_callback_enabled) + return; + +#ifdef __amd64__ + if (pmap_pcid_enabled) { + xen_ipis[IPI_TO_IDX(IPI_INVLTLB)].filter = xen_invltlb_pcid; + xen_ipis[IPI_TO_IDX(IPI_INVLPG)].filter = xen_invlpg_pcid; + } +#endif + CPU_FOREACH(i) + xen_cpu_ipi_init(i); + + /* Set the xen pv ipi ops to replace the native ones */ + cpu_ops.ipi_vectored = xen_ipi_vectored; +} + +/*---------------------- XEN Hypervisor Probe and Setup ----------------------*/ static uint32_t xen_hvm_cpuid_base(void) { @@ -253,4 +683,5 @@ void xen_hvm_init_cpu(void) } SYSINIT(xen_hvm_init, SI_SUB_HYPERVISOR, SI_ORDER_FIRST, xen_hvm_init, NULL); +SYSINIT(xen_init_ipis, SI_SUB_SMP, SI_ORDER_FIRST, xen_init_ipis, NULL); SYSINIT(xen_hvm_init_cpu, SI_SUB_INTR, SI_ORDER_FIRST, xen_hvm_init_cpu, NULL); diff --git a/sys/x86/xen/xen_intr.c b/sys/x86/xen/xen_intr.c index 83bf4873f97d..54a6be67800a 100644 --- a/sys/x86/xen/xen_intr.c +++ b/sys/x86/xen/xen_intr.c @@ -1010,7 +1010,7 @@ xen_intr_bind_virq(device_t dev, u_int virq, u_int cpu, } int -xen_intr_bind_ipi(device_t dev, u_int ipi, u_int cpu, +xen_intr_alloc_and_bind_ipi(device_t dev, u_int cpu, driver_filter_t filter, enum intr_type flags, xen_intr_handle_t *port_handlep) { diff --git a/sys/xen/xen_intr.h b/sys/xen/xen_intr.h index 109608ffa81f..3b339a5d12bb 100644 --- a/sys/xen/xen_intr.h +++ b/sys/xen/xen_intr.h @@ -141,21 +141,20 @@ int xen_intr_bind_virq(device_t dev, u_int virq, u_int cpu, void *arg, enum intr_type irqflags, xen_intr_handle_t *handlep); /** - * Associate an interprocessor interrupt vector with an interrupt handler. + * Allocate a local event channel port for servicing interprocessor + * interupts and, if successful, associate the port with the specified + * interrupt handler. * * \param dev The device making this bind request. - * \param ipi The interprocessor interrupt vector number of the - * interrupt source being hooked. * \param cpu The cpu receiving the IPI. - * \param filter An interrupt filter handler. Specify NULL - * to always dispatch to the ithread handler. + * \param filter The interrupt filter servicing this IPI. * \param irqflags Interrupt handler flags. See sys/bus.h. * \param handlep Pointer to an opaque handle used to manage this * registration. * * \returns 0 on success, otherwise an errno. */ -int xen_intr_bind_ipi(device_t dev, u_int ipi, u_int cpu, +int xen_intr_alloc_and_bind_ipi(device_t dev, u_int cpu, driver_filter_t filter, enum intr_type irqflags, xen_intr_handle_t *handlep); diff --git a/tools/build/mk/OptionalObsoleteFiles.inc b/tools/build/mk/OptionalObsoleteFiles.inc index 633ead06974c..036aa5f97b32 100644 --- a/tools/build/mk/OptionalObsoleteFiles.inc +++ b/tools/build/mk/OptionalObsoleteFiles.inc @@ -900,6 +900,11 @@ OLD_FILES+=usr/bin/CC OLD_FILES+=usr/bin/c++ OLD_FILES+=usr/bin/c++filt OLD_FILES+=usr/bin/g++ +OLD_FILES+=usr/libexec/cc1plus +.endif + +.if ${MK_GNUCXX} == no +OLD_FILES+=usr/bin/g++ OLD_FILES+=usr/include/c++/4.2/algorithm OLD_FILES+=usr/include/c++/4.2/backward/algo.h OLD_FILES+=usr/include/c++/4.2/backward/algobase.h @@ -1455,12 +1460,23 @@ OLD_FILES+=usr/include/c++/4.2/utility OLD_FILES+=usr/include/c++/4.2/valarray OLD_FILES+=usr/include/c++/4.2/vector OLD_FILES+=usr/lib/libstdc++.a -# Keep libs to allow bootstrapping g++(1) with gperf(1) -#OLD_LIBS+=usr/lib/libstdc++.so -#OLD_LIBS+=usr/lib/libstdc++.so.6 +OLD_FILES+=usr/lib/libstdc++.so +OLD_LIBS+=usr/lib/libstdc++.so.6 OLD_FILES+=usr/lib/libstdc++_p.a OLD_FILES+=usr/lib/libsupc++.a +OLD_FILES+=usr/lib/libsupc++.so +OLD_LIBS+=usr/lib/libsupc++.so.1 OLD_FILES+=usr/lib/libsupc++_p.a +.if ${TARGET_ARCH} == "amd64" || ${TARGET_ARCH} == "powerpc64" +OLD_FILES+=usr/lib32/libstdc++.a +OLD_FILES+=usr/lib32/libstdc++.so +OLD_LIBS+=usr/lib32/libstdc++.so.6 +OLD_FILES+=usr/lib32/libstdc++_p.a +OLD_FILES+=usr/lib32/libsupc++.a +OLD_FILES+=usr/lib32/libsupc++.so +OLD_LIBS+=usr/lib32/libsupc++.so.1 +OLD_FILES+=usr/lib32/libsupc++_p.a +.endif OLD_FILES+=usr/libexec/cc1plus .endif @@ -1546,19 +1562,25 @@ OLD_FILES+=usr/share/man/man8/unstr.8.gz .endif .if ${MK_GCC} == no +.if ${MK_CXX} == no OLD_FILES+=usr/bin/c++filt +.endif OLD_FILES+=usr/bin/g++ OLD_FILES+=usr/bin/gcc OLD_FILES+=usr/bin/gcov OLD_FILES+=usr/bin/gcpp .if ${TARGET_ARCH} == "amd64" || ${TARGET_ARCH} == "i386" +OLD_FILES+=usr/include/gcc/4.2/__wmmintrin_aes.h +OLD_FILES+=usr/include/gcc/4.2/__wmmintrin_pclmul.h +OLD_FILES+=usr/include/gcc/4.2/ammintrin.h OLD_FILES+=usr/include/gcc/4.2/emmintrin.h +OLD_FILES+=usr/include/gcc/4.2/mm3dnow.h OLD_FILES+=usr/include/gcc/4.2/mm_malloc.h OLD_FILES+=usr/include/gcc/4.2/mmintrin.h OLD_FILES+=usr/include/gcc/4.2/pmmintrin.h OLD_FILES+=usr/include/gcc/4.2/tmmintrin.h +OLD_FILES+=usr/include/gcc/4.2/wmmintrin.h OLD_FILES+=usr/include/gcc/4.2/xmmintrin.h -OLD_FILES+=usr/include/gcc/4.2/mm3dnow.h .elif ${TARGET_ARCH} == "ia64" OLD_FILES+=usr/include/gcc/4.2/ia64intrin.h .elif ${TARGET_ARCH} == "arm" @@ -1568,8 +1590,6 @@ OLD_FILES+=usr/include/gcc/4.2/altivec.h OLD_FILES+=usr/include/gcc/4.2/ppc-asm.h OLD_FILES+=usr/include/gcc/4.2/spe.h .endif -OLD_DIRS+=usr/include/gcc/4.2 -OLD_DIRS+=usr/include/gcc OLD_FILES+=usr/libexec/cc1 OLD_FILES+=usr/libexec/cc1plus OLD_FILES+=usr/share/info/cpp.info.gz @@ -2528,6 +2548,14 @@ OLD_FILES+=usr/lib/pam_krb5.so OLD_LIBS+=usr/lib/pam_krb5.so.5 OLD_FILES+=usr/lib/pam_ksu.so OLD_LIBS+=usr/lib/pam_ksu.so.5 +OLD_FILES+=usr/lib/private/libheimipcc.a +OLD_FILES+=usr/lib/private/libheimipcc.so +OLD_LIBS+=usr/lib/private/libheimipcc.so.11 +OLD_FILES+=usr/lib/private/libheimipcc_p.a +OLD_FILES+=usr/lib/private/libheimipcs.a +OLD_FILES+=usr/lib/private/libheimipcs.so +OLD_LIBS+=usr/lib/private/libheimipcs.so.11 +OLD_FILES+=usr/lib/private/libheimipcs_p.a .if ${TARGET_ARCH} == "amd64" || ${TARGET_ARCH} == "powerpc64" OLD_FILES+=usr/lib32/libasn1.a OLD_FILES+=usr/lib32/libasn1.so @@ -2597,6 +2625,14 @@ OLD_FILES+=usr/lib32/pam_krb5.so OLD_LIBS+=usr/lib32/pam_krb5.so.5 OLD_FILES+=usr/lib32/pam_ksu.so OLD_LIBS+=usr/lib32/pam_ksu.so.5 +OLD_FILES+=usr/lib32/private/libheimipcc.a +OLD_FILES+=usr/lib32/private/libheimipcc.so +OLD_LIBS+=usr/lib32/private/libheimipcc.so.11 +OLD_FILES+=usr/lib32/private/libheimipcc_p.a +OLD_FILES+=usr/lib32/private/libheimipcs.a +OLD_FILES+=usr/lib32/private/libheimipcs.so +OLD_LIBS+=usr/lib32/private/libheimipcs.so.11 +OLD_FILES+=usr/lib32/private/libheimipcs_p.a .endif OLD_FILES+=usr/libexec/digest-service OLD_FILES+=usr/libexec/hprop diff --git a/tools/build/options/WITHOUT_GCC b/tools/build/options/WITHOUT_GCC index 5717f64019e6..7bb21f8b8375 100644 --- a/tools/build/options/WITHOUT_GCC +++ b/tools/build/options/WITHOUT_GCC @@ -1,6 +1,2 @@ .\" $FreeBSD$ -Set to not install gcc and g++. -.Bf -symbolic -The option does not generally work for build targets, unless some alternative -toolchain is enabled. -.Ef +Set to not build and install gcc and g++. diff --git a/tools/build/options/WITHOUT_GNUCXX b/tools/build/options/WITHOUT_GNUCXX new file mode 100644 index 000000000000..ce10636009e2 --- /dev/null +++ b/tools/build/options/WITHOUT_GNUCXX @@ -0,0 +1,3 @@ +.\" $FreeBSD$ +Do not build the GNU C++ stack (g++, libstdc++). +This is the default on platforms where clang is the system compiler. diff --git a/tools/build/options/WITH_GCC b/tools/build/options/WITH_GCC new file mode 100644 index 000000000000..c121fe5ec192 --- /dev/null +++ b/tools/build/options/WITH_GCC @@ -0,0 +1,2 @@ +.\" $FreeBSD$ +Set to build and install gcc and g++. diff --git a/tools/build/options/WITH_GNUCXX b/tools/build/options/WITH_GNUCXX new file mode 100644 index 000000000000..c49e7cd9e1c4 --- /dev/null +++ b/tools/build/options/WITH_GNUCXX @@ -0,0 +1,3 @@ +.\" $FreeBSD$ +Build the GNU C++ stack (g++, libstdc++). +This is the default on platforms where gcc is the system compiler. diff --git a/tools/make_libdeps.sh b/tools/make_libdeps.sh index 3b59488e1cf5..2f5b32b19287 100644 --- a/tools/make_libdeps.sh +++ b/tools/make_libdeps.sh @@ -28,6 +28,7 @@ export PATH=/bin:/usr/bin +LC_ALL=C # make sort deterministic FS=': ' # internal field separator LIBDEPENDS=./_libdeps # intermediate output file USRSRC=${1:-/usr/src} # source root @@ -64,7 +65,7 @@ genlibdepends() { ( cd ${USRSRC} - find ${LIBS} -mindepth 1 -name Makefile | + find -s ${LIBS} -mindepth 1 -name Makefile | xargs grep -l 'bsd\.lib\.mk' | while read makefile; do libdir=$(dirname ${makefile}) diff --git a/tools/regression/bin/sh/builtins/return8.0 b/tools/regression/bin/sh/builtins/return8.0 new file mode 100644 index 000000000000..f00e859a74ce --- /dev/null +++ b/tools/regression/bin/sh/builtins/return8.0 @@ -0,0 +1,13 @@ +# $FreeBSD$ + +if [ "$1" = nested ]; then + return 17 +fi + +f() { + set -- nested + . "$0" + return $(($? ^ 1)) +} +f +exit $(($? ^ 16)) diff --git a/tools/regression/lib/libc/stdio/test-fmemopen.t b/tools/regression/lib/libc/stdio/test-fmemopen.t index 8bdfd03be81b..bd5157b5d8f8 100644 --- a/tools/regression/lib/libc/stdio/test-fmemopen.t +++ b/tools/regression/lib/libc/stdio/test-fmemopen.t @@ -7,4 +7,9 @@ executable=`basename $0 .t` make $executable 2>&1 > /dev/null -exec ./$executable +echo 1..1 +if ./$executable; then + echo ok 1 - $executable successful +else + echo not ok 1 - $executable failed +fi diff --git a/tools/regression/lib/libc/stdio/test-fopen.c b/tools/regression/lib/libc/stdio/test-fopen.c new file mode 100644 index 000000000000..8605717dba52 --- /dev/null +++ b/tools/regression/lib/libc/stdio/test-fopen.c @@ -0,0 +1,113 @@ +/*- + * Copyright (c) 2013 Jilles Tjoelker + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include +__FBSDID("$FreeBSD$"); + +#include +#include +#include + +/* + * O_ACCMODE is currently defined incorrectly. This is what it should be. + * Various code depends on the incorrect value. + */ +#define CORRECT_O_ACCMODE (O_ACCMODE | O_EXEC) + +static int testnum = 1; + +static void +runtest(const char *fname, const char *mode) +{ + FILE *fp; + int fd, flags, wantedflags; + + fp = fopen(fname, mode); + if (fp == NULL) { + printf("not ok %d - fopen(\"%s\", \"%s\") failed\n", + testnum++, fname, mode); + printf("not ok %d - FD_CLOEXEC # SKIP\n", + testnum++); + return; + } + fd = fileno(fp); + if (fd < 0) + printf("not ok %d - fileno() failed\n", testnum++); + else + printf("ok %d - fopen(\"%s\", \"%s\") and fileno() succeeded\n", + testnum++, fname, mode); + if (fcntl(fd, F_GETFD) == (strchr(mode, 'e') != NULL ? FD_CLOEXEC : 0)) + printf("ok %d - FD_CLOEXEC flag correct\n", testnum++); + else + printf("not ok %d - FD_CLOEXEC flag incorrect\n", testnum++); + flags = fcntl(fd, F_GETFL); + if (strchr(mode, '+')) + wantedflags = O_RDWR | (*mode == 'a' ? O_APPEND : 0); + else if (*mode == 'r') + wantedflags = O_RDONLY; + else if (*mode == 'w') + wantedflags = O_WRONLY; + else if (*mode == 'a') + wantedflags = O_WRONLY | O_APPEND; + else + wantedflags = -1; + if (wantedflags == -1) + printf("not ok %d - unrecognized mode\n", testnum++); + else if ((flags & (CORRECT_O_ACCMODE | O_APPEND)) == wantedflags) + printf("ok %d - correct access mode\n", testnum++); + else + printf("not ok %d - incorrect access mode\n", testnum++); + fclose(fp); +} + +/* + * Test program for fopen(). + */ +int +main(int argc, char *argv[]) +{ + printf("1..45\n"); + runtest("/dev/null", "r"); + runtest("/dev/null", "r+"); + runtest("/dev/null", "w"); + runtest("/dev/null", "w+"); + runtest("/dev/null", "a"); + runtest("/dev/null", "a+"); + runtest("/dev/null", "re"); + runtest("/dev/null", "r+e"); + runtest("/dev/null", "we"); + runtest("/dev/null", "w+e"); + runtest("/dev/null", "ae"); + runtest("/dev/null", "a+e"); + runtest("/dev/null", "re+"); + runtest("/dev/null", "we+"); + runtest("/dev/null", "ae+"); + + return 0; +} + +/* vim:ts=8:cin:sw=8 + * */ diff --git a/tools/regression/lib/libc/stdio/test-fopen.t b/tools/regression/lib/libc/stdio/test-fopen.t new file mode 100644 index 000000000000..8bdfd03be81b --- /dev/null +++ b/tools/regression/lib/libc/stdio/test-fopen.t @@ -0,0 +1,10 @@ +#!/bin/sh +# $FreeBSD$ + +cd `dirname $0` + +executable=`basename $0 .t` + +make $executable 2>&1 > /dev/null + +exec ./$executable diff --git a/tools/regression/lib/libc/stdio/test-mkostemp.t b/tools/regression/lib/libc/stdio/test-mkostemp.t new file mode 100644 index 000000000000..8bdfd03be81b --- /dev/null +++ b/tools/regression/lib/libc/stdio/test-mkostemp.t @@ -0,0 +1,10 @@ +#!/bin/sh +# $FreeBSD$ + +cd `dirname $0` + +executable=`basename $0 .t` + +make $executable 2>&1 > /dev/null + +exec ./$executable diff --git a/tools/regression/lib/libc/stdio/test-open_memstream.t b/tools/regression/lib/libc/stdio/test-open_memstream.t index 8bdfd03be81b..bd5157b5d8f8 100644 --- a/tools/regression/lib/libc/stdio/test-open_memstream.t +++ b/tools/regression/lib/libc/stdio/test-open_memstream.t @@ -7,4 +7,9 @@ executable=`basename $0 .t` make $executable 2>&1 > /dev/null -exec ./$executable +echo 1..1 +if ./$executable; then + echo ok 1 - $executable successful +else + echo not ok 1 - $executable failed +fi diff --git a/tools/regression/lib/libc/stdio/test-open_wmemstream.t b/tools/regression/lib/libc/stdio/test-open_wmemstream.t index 8bdfd03be81b..bd5157b5d8f8 100644 --- a/tools/regression/lib/libc/stdio/test-open_wmemstream.t +++ b/tools/regression/lib/libc/stdio/test-open_wmemstream.t @@ -7,4 +7,9 @@ executable=`basename $0 .t` make $executable 2>&1 > /dev/null -exec ./$executable +echo 1..1 +if ./$executable; then + echo ok 1 - $executable successful +else + echo not ok 1 - $executable failed +fi diff --git a/tools/regression/sockets/sendfile/sendfile.c b/tools/regression/sockets/sendfile/sendfile.c index bd8c0c557510..73033d75c15f 100644 --- a/tools/regression/sockets/sendfile/sendfile.c +++ b/tools/regression/sockets/sendfile/sendfile.c @@ -74,12 +74,13 @@ struct sendfile_test { uint32_t hdr_length; uint32_t offset; uint32_t length; + uint32_t file_size; }; -int file_fd; -char path[PATH_MAX]; -int listen_socket; -int accept_socket; +static int file_fd; +static char path[PATH_MAX]; +static int listen_socket; +static int accept_socket; static int test_th(struct test_header *th, uint32_t *header_length, uint32_t *offset, uint32_t *length); @@ -92,6 +93,7 @@ static int new_test_socket(int *connect_socket); static void init_th(struct test_header *th, uint32_t header_length, uint32_t offset, uint32_t length); static int send_test(int connect_socket, struct sendfile_test); +static int write_test_file(size_t file_size); static void run_parent(void); static void cleanup(void); @@ -278,15 +280,12 @@ send_test(int connect_socket, struct sendfile_test test) if (len != 0) FAIL_ERR("lseek") - if (test.length == 0) { - struct stat st; - if (fstat(file_fd, &st) < 0) - FAIL_ERR("fstat") - length = st.st_size - test.offset; - } - else { + struct stat st; + if (fstat(file_fd, &st) < 0) + FAIL_ERR("fstat") + length = st.st_size - test.offset; + if (test.length > 0 && test.length < (uint32_t)length) length = test.length; - } init_th(&th, test.hdr_length, test.offset, length); @@ -336,17 +335,55 @@ send_test(int connect_socket, struct sendfile_test test) return (0); } +static int +write_test_file(size_t file_size) +{ + char *page_buffer; + ssize_t len; + static size_t current_file_size = 0; + + if (file_size == current_file_size) + return (0); + else if (file_size < current_file_size) { + if (ftruncate(file_fd, file_size) != 0) + FAIL_ERR("ftruncate"); + current_file_size = file_size; + return (0); + } + + page_buffer = malloc(file_size); + if (page_buffer == NULL) + FAIL_ERR("malloc") + bzero(page_buffer, file_size); + + len = write(file_fd, page_buffer, file_size); + if (len < 0) + FAIL_ERR("write") + + len = lseek(file_fd, 0, SEEK_SET); + if (len < 0) + FAIL_ERR("lseek") + if (len != 0) + FAIL("len != 0") + + free(page_buffer); + current_file_size = file_size; + return (0); +} + static void run_parent(void) { int connect_socket; int status; int test_num; + int test_count; int pid; + size_t desired_file_size = 0; const int pagesize = getpagesize(); - struct sendfile_test tests[10] = { + struct sendfile_test tests[] = { { .hdr_length = 0, .offset = 0, .length = 1 }, { .hdr_length = 0, .offset = 0, .length = pagesize }, { .hdr_length = 0, .offset = 1, .length = 1 }, @@ -356,12 +393,23 @@ run_parent(void) { .hdr_length = 0, .offset = 0, .length = 0 }, { .hdr_length = 0, .offset = pagesize, .length = 0 }, { .hdr_length = 0, .offset = 2*pagesize, .length = 0 }, - { .hdr_length = 0, .offset = TEST_PAGES*pagesize, .length = 0 } + { .hdr_length = 0, .offset = TEST_PAGES*pagesize, .length = 0 }, + { .hdr_length = 0, .offset = 0, .length = pagesize, + .file_size = 1 } }; - printf("1..10\n"); + test_count = sizeof(tests) / sizeof(tests[0]); + printf("1..%d\n", test_count); - for (test_num = 1; test_num <= 10; test_num++) { + for (test_num = 1; test_num <= test_count; test_num++) { + + desired_file_size = tests[test_num - 1].file_size; + if (desired_file_size == 0) + desired_file_size = TEST_PAGES * pagesize; + if (write_test_file(desired_file_size) != 0) { + printf("not ok %d\n", test_num); + continue; + } pid = fork(); if (pid == -1) { @@ -411,17 +459,11 @@ cleanup(void) int main(int argc, char *argv[]) { - char *page_buffer; int pagesize; - ssize_t len; *path = '\0'; pagesize = getpagesize(); - page_buffer = malloc(TEST_PAGES * pagesize); - if (page_buffer == NULL) - FAIL_ERR("malloc") - bzero(page_buffer, TEST_PAGES * pagesize); if (argc == 1) { snprintf(path, PATH_MAX, "/tmp/sendfile.XXXXXXXXXXXX"); @@ -439,16 +481,6 @@ main(int argc, char *argv[]) atexit(cleanup); - len = write(file_fd, page_buffer, TEST_PAGES * pagesize); - if (len < 0) - FAIL_ERR("write") - - len = lseek(file_fd, 0, SEEK_SET); - if (len < 0) - FAIL_ERR("lseek") - if (len != 0) - FAIL("len != 0") - run_parent(); return (0); } diff --git a/usr.bin/Makefile b/usr.bin/Makefile index a7c72a89f27b..09fb97c66e2f 100644 --- a/usr.bin/Makefile +++ b/usr.bin/Makefile @@ -262,6 +262,10 @@ SUBDIR+= truss SUBDIR+= compile_et .endif +.if ${MK_LDNS_UTILS} != "no" +SUBDIR+= host +.endif + .if ${MK_LIBTHR} != "no" SUBDIR+= csup .endif diff --git a/usr.bin/bmake/Makefile b/usr.bin/bmake/Makefile index f7c403caa482..412955275798 100644 --- a/usr.bin/bmake/Makefile +++ b/usr.bin/bmake/Makefile @@ -14,10 +14,10 @@ CFLAGS+= -I${.CURDIR} CLEANDIRS+= FreeBSD CLEANFILES+= bootstrap -# $Id: Makefile,v 1.17 2013/07/30 19:13:53 sjg Exp $ +# $Id: Makefile,v 1.20 2013/09/04 15:42:03 sjg Exp $ # Base version on src date -MAKE_VERSION= 20130810 +MAKE_VERSION= 20130904 PROG?= ${.CURDIR:T} diff --git a/usr.bin/bmake/unit-tests/Makefile b/usr.bin/bmake/unit-tests/Makefile index 4cbf6a2072ae..be4cd2f77fe5 100644 --- a/usr.bin/bmake/unit-tests/Makefile +++ b/usr.bin/bmake/unit-tests/Makefile @@ -5,9 +5,9 @@ SRCTOP?= ${.CURDIR:H:H:H} -# $Id: Makefile.in,v 1.43 2013/07/16 21:14:30 sjg Exp $ +# $Id: Makefile.in,v 1.44 2013/08/28 22:09:29 sjg Exp $ # -# $NetBSD: Makefile,v 1.37 2013/07/16 19:59:28 sjg Exp $ +# $NetBSD: Makefile,v 1.38 2013/08/28 21:56:50 sjg Exp $ # # Unit tests for make(1) # The main targets are: @@ -52,6 +52,7 @@ SUBFILES= \ phony-end \ posix \ qequals \ + sunshcmd \ sysv \ ternary \ unexport \ diff --git a/usr.bin/host/Makefile b/usr.bin/host/Makefile index d168a9203152..25dfd2d1dff9 100644 --- a/usr.bin/host/Makefile +++ b/usr.bin/host/Makefile @@ -1,5 +1,29 @@ # $FreeBSD$ +.include + +.if ${MK_LDNS_UTILS} != "no" + +LDNSDIR= ${.CURDIR}/../../contrib/ldns +LDNSHOSTDIR= ${.CURDIR}/../../contrib/ldns-host + +.PATH: ${LDNSHOSTDIR} + +PROG= host +SRCS= ldns-host.c +MAN= host.1 + +host.1: ldns-host.1 + sed -e 's/ldns-//gI' <${.ALLSRC} >${.TARGET} || \ + (rm -rf ${.TARGET} ; false) + +CFLAGS+= -I${LDNSDIR} +DPADD+= ${LIBLDNS} ${LIBCRYPTO} +LDADD+= -lldns -lcrypto +USEPRIVATELIB= ldns + +.else + BIND_DIR= ${.CURDIR}/../../contrib/bind9 LIB_BIND_REL= ../../lib/bind LIB_BIND_DIR= ${.CURDIR}/${LIB_BIND_REL} @@ -20,4 +44,6 @@ WARNS?= 0 DPADD+= ${BIND_DPADD} ${CRYPTO_DPADD} ${PTHREAD_DPADD} LDADD+= ${BIND_LDADD} ${CRYPTO_LDADD} ${PTHREAD_LDADD} +.endif + .include diff --git a/usr.bin/kdump/kdump.c b/usr.bin/kdump/kdump.c index 06be0c0a482e..0de183c1a224 100644 --- a/usr.bin/kdump/kdump.c +++ b/usr.bin/kdump/kdump.c @@ -103,6 +103,7 @@ void ktrcsw_old(struct ktr_csw_old *); void ktruser_malloc(unsigned char *); void ktruser_rtld(int, unsigned char *); void ktruser(int, unsigned char *); +void ktrcaprights(cap_rights_t *); void ktrsockaddr(struct sockaddr *); void ktrstat(struct stat *); void ktrstruct(char *, size_t); @@ -379,21 +380,21 @@ limitfd(int fd) cap_rights_t rights; unsigned long cmd; - rights = CAP_FSTAT; + cap_rights_init(&rights, CAP_FSTAT); cmd = -1; switch (fd) { case STDIN_FILENO: - rights |= CAP_READ; + cap_rights_set(&rights, CAP_READ); break; case STDOUT_FILENO: - rights |= CAP_IOCTL | CAP_WRITE; + cap_rights_set(&rights, CAP_IOCTL, CAP_WRITE); cmd = TIOCGETA; /* required by isatty(3) in printf(3) */ break; case STDERR_FILENO: - rights |= CAP_WRITE; + cap_rights_set(&rights, CAP_WRITE); if (!suppressdata) { - rights |= CAP_IOCTL; + cap_rights_set(&rights, CAP_IOCTL); cmd = TIOCGWINSZ; } break; @@ -401,7 +402,7 @@ limitfd(int fd) abort(); } - if (cap_rights_limit(fd, rights) < 0 && errno != ENOSYS) + if (cap_rights_limit(fd, &rights) < 0 && errno != ENOSYS) err(1, "unable to limit rights for descriptor %d", fd); if (cmd != -1 && cap_ioctls_limit(fd, &cmd, 1) < 0 && errno != ENOSYS) err(1, "unable to limit ioctls for descriptor %d", fd); @@ -1120,35 +1121,6 @@ ktrsyscall(struct ktr_syscall *ktr, u_int flags) ip++; narg--; break; - case SYS_cap_new: - case SYS_cap_rights_limit: - print_number(ip, narg, c); - putchar(','); - arg = *ip; - ip++; - narg--; - /* - * Hack: the second argument is a - * cap_rights_t, which 64 bits wide, so on - * 32-bit systems, it is split between two - * registers. - * - * Since sizeof() is not evaluated by the - * preprocessor, we can't use an #ifdef, - * but the compiler will probably optimize - * the code out anyway. - */ - if (sizeof(cap_rights_t) > sizeof(register_t)) { -#if _BYTE_ORDER == _LITTLE_ENDIAN - arg = ((intmax_t)*ip << 32) + arg; -#else - arg = (arg << 32) + *ip; -#endif - ip++; - narg--; - } - capname(arg); - break; case SYS_cap_fcntls_limit: print_number(ip, narg, c); putchar(','); @@ -1535,6 +1507,15 @@ ktruser(int len, unsigned char *p) printf("\n"); } +void +ktrcaprights(cap_rights_t *rightsp) +{ + + printf("cap_rights_t "); + capname(rightsp); + printf("\n"); +} + void ktrsockaddr(struct sockaddr *sa) { @@ -1712,6 +1693,7 @@ ktrstruct(char *buf, size_t buflen) char *name, *data; size_t namelen, datalen; int i; + cap_rights_t rights; struct stat sb; struct sockaddr_storage ss; @@ -1731,7 +1713,12 @@ ktrstruct(char *buf, size_t buflen) for (i = 0; i < (int)namelen; ++i) if (!isalpha(name[i])) goto invalid; - if (strcmp(name, "stat") == 0) { + if (strcmp(name, "caprights") == 0) { + if (datalen != sizeof(cap_rights_t)) + goto invalid; + memcpy(&rights, data, datalen); + ktrcaprights(&rights); + } else if (strcmp(name, "stat") == 0) { if (datalen != sizeof(struct stat)) goto invalid; memcpy(&sb, data, datalen); @@ -1758,16 +1745,16 @@ ktrcapfail(struct ktr_cap_fail *ktr) case CAPFAIL_NOTCAPABLE: /* operation on fd with insufficient capabilities */ printf("operation requires "); - capname((intmax_t)ktr->cap_needed); + capname(&ktr->cap_needed); printf(", process holds "); - capname((intmax_t)ktr->cap_held); + capname(&ktr->cap_held); break; case CAPFAIL_INCREASE: /* requested more capabilities than fd already has */ printf("attempt to increase capabilities from "); - capname((intmax_t)ktr->cap_held); + capname(&ktr->cap_held); printf(" to "); - capname((intmax_t)ktr->cap_needed); + capname(&ktr->cap_needed); break; case CAPFAIL_SYSCALL: /* called restricted syscall */ @@ -1779,9 +1766,9 @@ ktrcapfail(struct ktr_cap_fail *ktr) break; default: printf("unknown capability failure: "); - capname((intmax_t)ktr->cap_needed); + capname(&ktr->cap_needed); printf(" "); - capname((intmax_t)ktr->cap_held); + capname(&ktr->cap_held); break; } printf("\n"); diff --git a/usr.bin/kdump/mksubr b/usr.bin/kdump/mksubr index b10af9426010..2a16e37b8f07 100644 --- a/usr.bin/kdump/mksubr +++ b/usr.bin/kdump/mksubr @@ -385,7 +385,6 @@ _EOF_ auto_or_type "accessmodename" "[A-Z]_OK[[:space:]]+0?x?[0-9A-Fa-f]+" "sys/unistd.h" auto_switch_type "acltypename" "ACL_TYPE_[A-Z4_]+[[:space:]]+0x[0-9]+" "sys/acl.h" -auto_or_type "capname" "CAP_[A-Z]+[[:space:]]+0x[01248]{16}ULL" "sys/capability.h" auto_or_type "capfcntlname" "CAP_FCNTL_[A-Z]+[[:space:]]+\(1" "sys/capability.h" auto_switch_type "extattrctlname" "EXTATTR_NAMESPACE_[A-Z]+[[:space:]]+0x[0-9]+" "sys/extattr.h" auto_switch_type "fadvisebehavname" "POSIX_FADV_[A-Z]+[[:space:]]+[0-9]+" "sys/fcntl.h" @@ -498,6 +497,10 @@ egrep "^#[[:space:]]*define[[:space:]]+MAP_[A-Z_]+[[:space:]]+0x[0-9A-Fa-f]+[[:s ++i; \ printf "\tif (!((flags > 0) ^ ((%s) > 0)))\n\t\tif_print_or(flags, %s, or);\n", $i, $i }' cat <<_EOF_ +#ifdef MAP_32BIT + if (!((flags > 0) ^ ((MAP_32BIT) > 0))) + if_print_or(flags, MAP_32BIT, or); +#endif align = flags & MAP_ALIGNMENT_MASK; if (align != 0) { if (align == MAP_ALIGNED_SUPER) @@ -609,3 +612,26 @@ cat <<_EOF_ } } } + +_EOF_ +egrep '#define[[:space:]]+CAP_[A-Z_]+[[:space:]]+CAPRIGHT\([0-9],[[:space:]]+0x[0-9]{16}ULL\)' \ + $include_dir/sys/capability.h | \ + sed -E 's/[ ]+/ /g' | \ + awk -F '[ \(,\)]' ' + BEGIN { + printf "void\n" + printf "capname(const cap_rights_t *rightsp)\n" + printf "{\n" + printf "\tint comma = 0;\n\n" + printf "\tprintf(\"<\");\n" + } + { + printf "\tif ((rightsp->cr_rights[%s] & %s) == %s) {\n", $4, $2, $2 + printf "\t\tif (comma) printf(\",\"); else comma = 1;\n" + printf "\t\tprintf(\"%s\");\n", $2 + printf "\t}\n" + } + END { + printf "\tprintf(\">\");\n" + printf "}\n" + }' diff --git a/usr.bin/patch/pch.c b/usr.bin/patch/pch.c index c6224e7f234c..eca12ad06f81 100644 --- a/usr.bin/patch/pch.c +++ b/usr.bin/patch/pch.c @@ -1516,15 +1516,12 @@ posix_name(const struct file_name *names, bool assume_exists) return path ? savestr(path) : NULL; } -/* - * Choose the name of the file to be patched based the "best" one - * available. - */ static char * -best_name(const struct file_name *names, bool assume_exists) +compare_names(const struct file_name *names, bool assume_exists, int phase) { size_t min_components, min_baselen, min_len, tmp; char *best = NULL; + char *path; int i; /* @@ -1536,47 +1533,43 @@ best_name(const struct file_name *names, bool assume_exists) */ min_components = min_baselen = min_len = SIZE_MAX; for (i = INDEX_FILE; i >= OLD_FILE; i--) { - if (names[i].path == NULL || - (!names[i].exists && !assume_exists)) + path = names[i].path; + if (path == NULL || + (phase == 1 && !names[i].exists && !assume_exists) || + (phase == 2 && checked_in(path) == NULL)) continue; - if ((tmp = num_components(names[i].path)) > min_components) + if ((tmp = num_components(path)) > min_components) continue; if (tmp < min_components) { min_components = tmp; - best = names[i].path; + best = path; } - if ((tmp = strlen(basename(names[i].path))) > min_baselen) + if ((tmp = strlen(basename(path))) > min_baselen) continue; if (tmp < min_baselen) { min_baselen = tmp; - best = names[i].path; + best = path; } - if ((tmp = strlen(names[i].path)) > min_len) + if ((tmp = strlen(path)) > min_len) continue; min_len = tmp; - best = names[i].path; + best = path; } + return best; +} + +/* + * Choose the name of the file to be patched based the "best" one + * available. + */ +static char * +best_name(const struct file_name *names, bool assume_exists) +{ + char *best; + + best = compare_names(names, assume_exists, 1); if (best == NULL) { - /* - * No files found, look for something we can checkout from - * RCS/SCCS dirs. Logic is identical to that above... - */ - min_components = min_baselen = min_len = SIZE_MAX; - for (i = INDEX_FILE; i >= OLD_FILE; i--) { - if (names[i].path == NULL || - checked_in(names[i].path) == NULL) - continue; - if ((tmp = num_components(names[i].path)) > min_components) - continue; - min_components = tmp; - if ((tmp = strlen(basename(names[i].path))) > min_baselen) - continue; - min_baselen = tmp; - if ((tmp = strlen(names[i].path)) > min_len) - continue; - min_len = tmp; - best = names[i].path; - } + best = compare_names(names, assume_exists, 2); /* * Still no match? Check to see if the diff could be creating * a new file. diff --git a/usr.bin/patch/util.c b/usr.bin/patch/util.c index 28a3cb0cf583..c19918b04e9d 100644 --- a/usr.bin/patch/util.c +++ b/usr.bin/patch/util.c @@ -412,7 +412,7 @@ checked_in(char *file) void version(void) { - fprintf(stderr, "patch 2.0-12u8 FreeBSD\n"); + fprintf(stderr, "patch 2.0-12u9 FreeBSD\n"); my_exit(EXIT_SUCCESS); } diff --git a/usr.bin/procstat/procstat_files.c b/usr.bin/procstat/procstat_files.c index 72600de0bb62..d65c1ae93982 100644 --- a/usr.bin/procstat/procstat_files.c +++ b/usr.bin/procstat/procstat_files.c @@ -133,7 +133,7 @@ print_address(struct sockaddr_storage *ss) } static struct cap_desc { - cap_rights_t cd_right; + uint64_t cd_right; const char *cd_desc; } cap_desc[] = { /* General file I/O. */ @@ -244,14 +244,14 @@ static const u_int cap_desc_count = sizeof(cap_desc) / sizeof(cap_desc[0]); static u_int -width_capability(cap_rights_t rights) +width_capability(cap_rights_t *rightsp) { u_int count, i, width; count = 0; width = 0; for (i = 0; i < cap_desc_count; i++) { - if ((cap_desc[i].cd_right & ~rights) == 0) { + if (cap_rights_is_set(rightsp, cap_desc[i].cd_right)) { width += strlen(cap_desc[i].cd_desc); if (count) width++; @@ -262,20 +262,20 @@ width_capability(cap_rights_t rights) } static void -print_capability(cap_rights_t rights, u_int capwidth) +print_capability(cap_rights_t *rightsp, u_int capwidth) { u_int count, i, width; count = 0; width = 0; - for (i = width_capability(rights); i < capwidth; i++) { - if (rights || i != 0) + for (i = width_capability(rightsp); i < capwidth; i++) { + if (i != 0) printf(" "); else printf("-"); } for (i = 0; i < cap_desc_count; i++) { - if ((cap_desc[i].cd_right & ~rights) == 0) { + if (cap_rights_is_set(rightsp, cap_desc[i].cd_right)) { printf("%s%s", count ? "," : "", cap_desc[i].cd_desc); width += strlen(cap_desc[i].cd_desc); if (count) @@ -306,7 +306,7 @@ procstat_files(struct procstat *procstat, struct kinfo_proc *kipp) head = procstat_getfiles(procstat, kipp, 0); if (head != NULL && Cflag) { STAILQ_FOREACH(fst, head, next) { - width = width_capability(fst->fs_cap_rights); + width = width_capability(&fst->fs_cap_rights); if (width > capwidth) capwidth = width; } @@ -460,7 +460,7 @@ procstat_files(struct procstat *procstat, struct kinfo_proc *kipp) printf("%7c ", '-'); } if (Cflag) { - print_capability(fst->fs_cap_rights, capwidth); + print_capability(&fst->fs_cap_rights, capwidth); printf(" "); } switch (fst->fs_type) { diff --git a/usr.bin/rwho/rwho.c b/usr.bin/rwho/rwho.c index bcb5adb8e919..8c985f0170d1 100644 --- a/usr.bin/rwho/rwho.c +++ b/usr.bin/rwho/rwho.c @@ -93,6 +93,7 @@ main(int argc, char *argv[]) struct whod *w; struct whoent *we; struct myutmp *mp; + cap_rights_t rights; int f, n, i; int d_first; int dfd; @@ -124,7 +125,8 @@ main(int argc, char *argv[]) err(1, "opendir(%s)", _PATH_RWHODIR); dfd = dirfd(dirp); mp = myutmp; - if (cap_rights_limit(dfd, CAP_READ | CAP_LOOKUP) < 0 && errno != ENOSYS) + cap_rights_init(&rights, CAP_READ, CAP_LOOKUP); + if (cap_rights_limit(dfd, &rights) < 0 && errno != ENOSYS) err(1, "cap_rights_limit failed: %s", _PATH_RWHODIR); /* * Cache files required for time(3) and localtime(3) before entering @@ -135,13 +137,14 @@ main(int argc, char *argv[]) if (cap_enter() < 0 && errno != ENOSYS) err(1, "cap_enter"); (void) time(&now); + cap_rights_init(&rights, CAP_READ); while ((dp = readdir(dirp)) != NULL) { if (dp->d_ino == 0 || strncmp(dp->d_name, "whod.", 5) != 0) continue; f = openat(dfd, dp->d_name, O_RDONLY); if (f < 0) continue; - if (cap_rights_limit(f, CAP_READ) < 0 && errno != ENOSYS) + if (cap_rights_limit(f, &rights) < 0 && errno != ENOSYS) err(1, "cap_rights_limit failed: %s", dp->d_name); cc = read(f, (char *)&wd, sizeof(struct whod)); if (cc < WHDRSIZE) { diff --git a/usr.bin/truss/syscalls.c b/usr.bin/truss/syscalls.c index f5e2c46ad03a..99a377f75f0e 100644 --- a/usr.bin/truss/syscalls.c +++ b/usr.bin/truss/syscalls.c @@ -296,7 +296,11 @@ static struct xlat mmap_flags[] = { X(MAP_SHARED) X(MAP_PRIVATE) X(MAP_FIXED) X(MAP_RENAME) X(MAP_NORESERVE) X(MAP_RESERVED0080) X(MAP_RESERVED0100) X(MAP_HASSEMAPHORE) X(MAP_STACK) X(MAP_NOSYNC) X(MAP_ANON) - X(MAP_NOCORE) X(MAP_PREFAULT_READ) XEND + X(MAP_NOCORE) X(MAP_PREFAULT_READ) +#ifdef MAP_32BIT + X(MAP_32BIT) +#endif + XEND }; static struct xlat mprot_flags[] = { diff --git a/usr.bin/uniq/uniq.c b/usr.bin/uniq/uniq.c index d34b0c0a5b37..8e7f40fd14c4 100644 --- a/usr.bin/uniq/uniq.c +++ b/usr.bin/uniq/uniq.c @@ -145,20 +145,19 @@ main (int argc, char *argv[]) ofp = stdout; if (argc > 0 && strcmp(argv[0], "-") != 0) ifp = file(ifn = argv[0], "r"); - if (cap_rights_limit(fileno(ifp), CAP_FSTAT | CAP_READ) < 0 && - errno != ENOSYS) { + cap_rights_init(&rights, CAP_FSTAT, CAP_READ); + if (cap_rights_limit(fileno(ifp), &rights) < 0 && errno != ENOSYS) err(1, "unable to limit rights for %s", ifn); - } - rights = CAP_FSTAT | CAP_WRITE; + cap_rights_init(&rights, CAP_FSTAT, CAP_WRITE); if (argc > 1) ofp = file(argv[1], "w"); else - rights |= CAP_IOCTL; - if (cap_rights_limit(fileno(ofp), rights) < 0 && errno != ENOSYS) { + cap_rights_set(&rights, CAP_IOCTL); + if (cap_rights_limit(fileno(ofp), &rights) < 0 && errno != ENOSYS) { err(1, "unable to limit rights for %s", argc > 1 ? argv[1] : "stdout"); } - if ((rights & CAP_IOCTL) != 0) { + if (cap_rights_is_set(&rights, CAP_IOCTL)) { unsigned long cmd; cmd = TIOCGETA; /* required by isatty(3) in printf(3) */ diff --git a/usr.sbin/bhyve/acpi.c b/usr.sbin/bhyve/acpi.c index ed0c545e5f8e..89c11bce3cbc 100644 --- a/usr.sbin/bhyve/acpi.c +++ b/usr.sbin/bhyve/acpi.c @@ -241,8 +241,9 @@ basl_fwrite_madt(FILE *fp) for (i = 0; i < basl_ncpu; i++) { EFPRINTF(fp, "[0001]\t\tSubtable Type : 00\n"); EFPRINTF(fp, "[0001]\t\tLength : 08\n"); - EFPRINTF(fp, "[0001]\t\tProcessor ID : %02d\n", i); - EFPRINTF(fp, "[0001]\t\tLocal Apic ID : %02d\n", i); + /* iasl expects hex values for the proc and apic id's */ + EFPRINTF(fp, "[0001]\t\tProcessor ID : %02x\n", i); + EFPRINTF(fp, "[0001]\t\tLocal Apic ID : %02x\n", i); EFPRINTF(fp, "[0004]\t\tFlags (decoded below) : 00000001\n"); EFPRINTF(fp, "\t\t\tProcessor Enabled : 1\n"); EFPRINTF(fp, "\n"); @@ -251,7 +252,8 @@ basl_fwrite_madt(FILE *fp) /* Always a single IOAPIC entry, with ID ncpu+1 */ EFPRINTF(fp, "[0001]\t\tSubtable Type : 01\n"); EFPRINTF(fp, "[0001]\t\tLength : 0C\n"); - EFPRINTF(fp, "[0001]\t\tI/O Apic ID : %02d\n", basl_ncpu); + /* iasl expects a hex value for the i/o apic id */ + EFPRINTF(fp, "[0001]\t\tI/O Apic ID : %02x\n", basl_ncpu); EFPRINTF(fp, "[0001]\t\tReserved : 00\n"); EFPRINTF(fp, "[0004]\t\tAddress : fec00000\n"); EFPRINTF(fp, "[0004]\t\tInterrupt : 00000000\n"); diff --git a/usr.sbin/bhyve/ioapic.c b/usr.sbin/bhyve/ioapic.c index c712692c9375..aeb008ea2c23 100644 --- a/usr.sbin/bhyve/ioapic.c +++ b/usr.sbin/bhyve/ioapic.c @@ -101,13 +101,13 @@ ioapic_set_pinstate(struct vmctx *ctx, int pin, bool newstate) * XXX * We only deal with: * - edge triggered interrupts - * - physical destination mode * - fixed delivery mode + * Level-triggered sources will work so long as there is + * no sharing. */ low = ioapic->redtbl[pin]; high = ioapic->redtbl[pin] >> 32; if ((low & IOART_INTMASK) == IOART_INTMCLR && - (low & IOART_TRGRMOD) == IOART_TRGREDG && (low & IOART_DESTMOD) == IOART_DESTPHY && (low & IOART_DELMOD) == IOART_DELFIXED) { vector = low & IOART_INTVEC; diff --git a/usr.sbin/bsdconfig/examples/browse_packages.sh b/usr.sbin/bsdconfig/examples/browse_packages.sh index 6396f4677309..1deb562481e9 100755 --- a/usr.sbin/bsdconfig/examples/browse_packages.sh +++ b/usr.sbin/bsdconfig/examples/browse_packages.sh @@ -17,9 +17,8 @@ if [ ! -e "$TMPDIR/packages/INDEX" ]; then # For older releases, use ftp://ftp-archive.freebsd.org mediaSetFTP mediaOpen - f_show_info "Downloading packages/INDEX from %s" "$_ftpPath" + f_show_info "Downloading packages/INDEX from\n %s" "$_ftpPath" f_device_get media packages/INDEX > $TMPDIR/packages/INDEX - mediaClose fi _directoryPath=$TMPDIR mediaSetDirectory diff --git a/usr.sbin/mergemaster/mergemaster.sh b/usr.sbin/mergemaster/mergemaster.sh index 629d44fbd8ea..361cef9146fa 100755 --- a/usr.sbin/mergemaster/mergemaster.sh +++ b/usr.sbin/mergemaster/mergemaster.sh @@ -707,7 +707,7 @@ case "${RERUN}" in # Build the mtree database in a temporary location. case "${PRE_WORLD}" in '') MTREENEW=`mktemp -t mergemaster.mtree` - mtree -ci -p ${TEMPROOT} -k size,md5digest > ${MTREENEW} 2>/dev/null + mtree -nci -p ${TEMPROOT} -k size,md5digest > ${MTREENEW} 2>/dev/null ;; *) # We don't want to mess with the mtree database on a pre-world run or # when re-scanning a previously-built tree. diff --git a/usr.sbin/pkg/config.c b/usr.sbin/pkg/config.c index 142fd1bb7378..01eaa9f7f94c 100644 --- a/usr.sbin/pkg/config.c +++ b/usr.sbin/pkg/config.c @@ -32,6 +32,7 @@ __FBSDID("$FreeBSD$"); #include #include +#include #include #include #include @@ -100,6 +101,138 @@ elf_corres_to_string(struct _elf_corres *m, int e) return ("unknown"); } +static const char * +aeabi_parse_arm_attributes(void *data, size_t length) +{ + uint32_t sect_len; + uint8_t *section = data; + +#define MOVE(len) do { \ + assert(length >= (len)); \ + section += (len); \ + length -= (len); \ +} while (0) + + if (length == 0 || *section != 'A') + return (NULL); + + MOVE(1); + + /* Read the section length */ + if (length < sizeof(sect_len)) + return (NULL); + + memcpy(§_len, section, sizeof(sect_len)); + + /* + * The section length should be no longer than the section it is within + */ + if (sect_len > length) + return (NULL); + + MOVE(sizeof(sect_len)); + + /* Skip the vendor name */ + while (length != 0) { + if (*section == '\0') + break; + MOVE(1); + } + if (length == 0) + return (NULL); + MOVE(1); + + while (length != 0) { + uint32_t tag_length; + + switch(*section) { + case 1: /* Tag_File */ + MOVE(1); + if (length < sizeof(tag_length)) + return (NULL); + memcpy(&tag_length, section, sizeof(tag_length)); + break; + case 2: /* Tag_Section */ + case 3: /* Tag_Symbol */ + default: + return (NULL); + } + /* At least space for the tag and size */ + if (tag_length <= 5) + return (NULL); + tag_length--; + /* Check the tag fits */ + if (tag_length > length) + return (NULL); + +#define MOVE_TAG(len) do { \ + assert(tag_length >= (len)); \ + MOVE(len); \ + tag_length -= (len); \ +} while(0) + + MOVE(sizeof(tag_length)); + tag_length -= sizeof(tag_length); + + while (tag_length != 0) { + uint8_t tag; + + assert(tag_length >= length); + + tag = *section; + MOVE_TAG(1); + + /* + * These tag values come from: + * + * Addenda to, and Errata in, the ABI for the + * ARM Architecture. Release 2.08, section 2.3. + */ + if (tag == 6) { /* == Tag_CPU_arch */ + uint8_t val; + + val = *section; + /* + * We don't support values that require + * more than one byte. + */ + if (val & (1 << 7)) + return (NULL); + + /* We have an ARMv4 or ARMv5 */ + if (val <= 5) + return ("arm"); + else /* We have an ARMv6+ */ + return ("armv6"); + } else if (tag == 4 || tag == 5 || tag == 32 || + tag == 65 || tag == 67) { + while (*section != '\0' && length != 0) + MOVE_TAG(1); + if (tag_length == 0) + return (NULL); + /* Skip the last byte */ + MOVE_TAG(1); + } else if ((tag >= 7 && tag <= 31) || tag == 34 || + tag == 36 || tag == 38 || tag == 42 || tag == 44 || + tag == 64 || tag == 66 || tag == 68 || tag == 70) { + /* Skip the uleb128 data */ + while (*section & (1 << 7) && length != 0) + MOVE_TAG(1); + if (tag_length == 0) + return (NULL); + /* Skip the last byte */ + MOVE_TAG(1); + } else + return (NULL); +#undef MOVE_TAG + } + + break; + } + return (NULL); +#undef MOVE +} + static int pkg_get_myabi(char *dest, size_t sz) { @@ -108,7 +241,8 @@ pkg_get_myabi(char *dest, size_t sz) Elf_Note note; Elf_Scn *scn; char *src, *osname; - const char *abi, *fpu; + const char *arch, *abi, *fpu, *endian_corres_str; + const char *wordsize_corres_str; GElf_Ehdr elfhdr; GElf_Shdr shdr; int fd, i, ret; @@ -177,21 +311,72 @@ pkg_get_myabi(char *dest, size_t sz) for (i = 0; osname[i] != '\0'; i++) osname[i] = (char)tolower(osname[i]); - snprintf(dest, sz, "%s:%d:%s:%s", - osname, version / 100000, - elf_corres_to_string(mach_corres, (int)elfhdr.e_machine), - elf_corres_to_string(wordsize_corres, - (int)elfhdr.e_ident[EI_CLASS])); + wordsize_corres_str = elf_corres_to_string(wordsize_corres, + (int)elfhdr.e_ident[EI_CLASS]); + + arch = elf_corres_to_string(mach_corres, (int) elfhdr.e_machine); + + snprintf(dest, sz, "%s:%d", + osname, version / 100000); ret = 0; switch (elfhdr.e_machine) { case EM_ARM: + endian_corres_str = elf_corres_to_string(endian_corres, + (int)elfhdr.e_ident[EI_DATA]); + /* FreeBSD doesn't support the hard-float ABI yet */ fpu = "softfp"; if ((elfhdr.e_flags & 0xFF000000) != 0) { + const char *sh_name = NULL; + size_t shstrndx; + /* This is an EABI file, the conformance level is set */ abi = "eabi"; + /* Find which TARGET_ARCH we are building for. */ + elf_getshdrstrndx(elf, &shstrndx); + while ((scn = elf_nextscn(elf, scn)) != NULL) { + sh_name = NULL; + if (gelf_getshdr(scn, &shdr) != &shdr) { + scn = NULL; + break; + } + + sh_name = elf_strptr(elf, shstrndx, + shdr.sh_name); + if (sh_name == NULL) + continue; + if (strcmp(".ARM.attributes", sh_name) == 0) + break; + } + if (scn != NULL && sh_name != NULL) { + data = elf_getdata(scn, NULL); + /* + * Prior to FreeBSD 10.0 libelf would return + * NULL from elf_getdata on the .ARM.attributes + * section. As this was the first release to + * get armv6 support assume a NULL value means + * arm. + * + * This assumption can be removed when 9.x + * is unsupported. + */ + if (data != NULL) { + arch = aeabi_parse_arm_attributes( + data->d_buf, data->d_size); + if (arch == NULL) { + ret = 1; + warn("unknown ARM ARCH"); + goto cleanup; + } + } + } else { + ret = 1; + warn("Unable to find the .ARM.attributes " + "section"); + goto cleanup; + } } else if (elfhdr.e_ident[EI_OSABI] != ELFOSABI_NONE) { /* * EABI executables all have this field set to @@ -200,12 +385,12 @@ pkg_get_myabi(char *dest, size_t sz) abi = "oabi"; } else { ret = 1; + warn("unknown ARM ABI"); goto cleanup; } snprintf(dest + strlen(dest), sz - strlen(dest), - ":%s:%s:%s", elf_corres_to_string(endian_corres, - (int)elfhdr.e_ident[EI_DATA]), - abi, fpu); + ":%s:%s:%s:%s:%s", arch, wordsize_corres_str, + endian_corres_str, abi, fpu); break; case EM_MIPS: /* @@ -230,10 +415,15 @@ pkg_get_myabi(char *dest, size_t sz) abi = "n64"; break; } - snprintf(dest + strlen(dest), sz - strlen(dest), - ":%s:%s", elf_corres_to_string(endian_corres, - (int)elfhdr.e_ident[EI_DATA]), abi); + endian_corres_str = elf_corres_to_string(endian_corres, + (int)elfhdr.e_ident[EI_DATA]); + + snprintf(dest + strlen(dest), sz - strlen(dest), ":%s:%s:%s:%s", + arch, wordsize_corres_str, endian_corres_str, abi); break; + default: + snprintf(dest + strlen(dest), sz - strlen(dest), ":%s:%s", + arch, wordsize_corres_str); } cleanup: diff --git a/usr.sbin/rwhod/rwhod.c b/usr.sbin/rwhod/rwhod.c index 25b86928757b..87a41667be16 100644 --- a/usr.sbin/rwhod/rwhod.c +++ b/usr.sbin/rwhod/rwhod.c @@ -274,21 +274,17 @@ main(int argc, char *argv[]) exit(1); if (!quiet_mode) { pid_child_receiver = pdfork(&fdp, 0); - if (pid_child_receiver == -1) { - if (errno != ENOSYS) { - syslog(LOG_ERR, "pdfork: %m"); - exit(1); - } else { - pid_child_receiver = fork(); - fdp = -1; - } - } if (pid_child_receiver == 0) { receiver_process(); } else if (pid_child_receiver > 0) { sender_process(); } else if (pid_child_receiver == -1) { - syslog(LOG_ERR, "pdfork: %m"); + if (errno == ENOSYS) { + syslog(LOG_ERR, + "The pdfork(2) system call is not available; recompile the kernel with options PROCDESC"); + } else { + syslog(LOG_ERR, "pdfork: %m"); + } exit(1); } } else { @@ -354,6 +350,7 @@ receiver_process(void) { struct sockaddr_in from; struct stat st; + cap_rights_t rights; char path[64]; int dirfd; struct whod wd; @@ -367,8 +364,9 @@ receiver_process(void) syslog(LOG_WARNING, "%s: %m", _PATH_RWHODIR); exit(1); } - if (cap_rights_limit(dirfd, CAP_CREATE | CAP_WRITE | CAP_FTRUNCATE | - CAP_SEEK | CAP_LOOKUP | CAP_FSTAT) < 0 && errno != ENOSYS) { + cap_rights_init(&rights, CAP_CREATE, CAP_FSTAT, CAP_FTRUNCATE, + CAP_LOOKUP, CAP_SEEK, CAP_WRITE); + if (cap_rights_limit(dirfd, &rights) < 0 && errno != ENOSYS) { syslog(LOG_WARNING, "cap_rights_limit: %m"); exit(1); } @@ -413,8 +411,8 @@ receiver_process(void) syslog(LOG_WARNING, "%s: %m", path); continue; } - if (cap_rights_limit(whod, CAP_WRITE | CAP_FTRUNCATE | - CAP_FSTAT) < 0 && errno != ENOSYS) { + cap_rights_init(&rights, CAP_FSTAT, CAP_FTRUNCATE, CAP_WRITE); + if (cap_rights_limit(whod, &rights) < 0 && errno != ENOSYS) { syslog(LOG_WARNING, "cap_rights_limit: %m"); exit(1); } diff --git a/usr.sbin/setfib/setfib.1 b/usr.sbin/setfib/setfib.1 index f0143db9340e..5c36748343fe 100644 --- a/usr.sbin/setfib/setfib.1 +++ b/usr.sbin/setfib/setfib.1 @@ -24,7 +24,7 @@ .\" .\" $FreeBSD$ .\" -.Dd April 9, 2008 +.Dd October 20, 2008 .Dt SETFIB 1 .Os .Sh NAME @@ -39,11 +39,11 @@ .Sh DESCRIPTION The .Nm -utility runs +utility runs another .Ar utility -with an different routing table. +with a different routing table. The table number -.Dq Ar fib +.Ar fib will be used by default for all sockets started by this process or descendants. .Sh ENVIRONMENT @@ -69,8 +69,8 @@ An exit status of 127 indicates .Ar utility could not be found. .Sh EXAMPLES -Execute utility -.Sq netstat +Run +.Xr netstat 1 to view the second routing table. .Pp .Dl "setfib -F 1 netstat -rn" @@ -86,8 +86,9 @@ The .Nm utility is a .Fx -specific extension, however many -.Ux +specific extension. +However, many +.Ux Ns - Ns like systems have an equivalent function. .Sh HISTORY diff --git a/usr.sbin/watch/watch.c b/usr.sbin/watch/watch.c index e69534de55c4..eecf0d32db2a 100644 --- a/usr.sbin/watch/watch.c +++ b/usr.sbin/watch/watch.c @@ -110,7 +110,6 @@ set_tty(void) { struct termios ntty; - tcgetattr(std_in, &otty); ntty = otty; ntty.c_lflag &= ~ICANON; /* disable canonical operation */ ntty.c_lflag &= ~ECHO; @@ -324,6 +323,8 @@ main(int ac, char *av[]) usage(); } + tcgetattr(std_in, &otty); + if (modfind("snp") == -1) if (kldload("snp") == -1 || modfind("snp") == -1) warn("snp module not available");