diff options
-rw-r--r-- | contrib/ipfilter/IPFILTER.LICENCE | 29 | ||||
-rw-r--r-- | contrib/ipfilter/QNX_OCL.txt | 275 | ||||
-rw-r--r-- | contrib/ipfilter/ip_fil_freebsd.c | 1692 | ||||
-rw-r--r-- | contrib/ipfilter/ip_htable.c | 455 | ||||
-rw-r--r-- | contrib/ipfilter/ip_htable.h | 71 | ||||
-rw-r--r-- | contrib/ipfilter/ip_irc_pxy.c | 435 | ||||
-rw-r--r-- | contrib/ipfilter/ip_lookup.c | 530 | ||||
-rw-r--r-- | contrib/ipfilter/ip_lookup.h | 65 | ||||
-rw-r--r-- | contrib/ipfilter/ip_pool.c | 786 | ||||
-rw-r--r-- | contrib/ipfilter/ip_pool.h | 87 | ||||
-rw-r--r-- | contrib/ipfilter/ip_pptp_pxy.c | 527 | ||||
-rw-r--r-- | contrib/ipfilter/ip_rpcb_pxy.c | 1460 | ||||
-rw-r--r-- | contrib/ipfilter/ip_scan.c | 594 | ||||
-rw-r--r-- | contrib/ipfilter/ip_scan.h | 108 | ||||
-rw-r--r-- | contrib/ipfilter/ip_sync.c | 1001 | ||||
-rw-r--r-- | contrib/ipfilter/ip_sync.h | 117 |
16 files changed, 0 insertions, 8232 deletions
diff --git a/contrib/ipfilter/IPFILTER.LICENCE b/contrib/ipfilter/IPFILTER.LICENCE deleted file mode 100644 index 41c151c..0000000 --- a/contrib/ipfilter/IPFILTER.LICENCE +++ /dev/null @@ -1,29 +0,0 @@ -/* - * Copyright (C) 1993-2001 by Darren Reed. - * - * The author accepts no responsibility for the use of this software and - * provides it on an ``as is'' basis without express or implied warranty. - * - * Redistribution and use, with or without modification, in source and binary - * forms, are permitted provided that this notice is preserved in its entirety - * and due credit is given to the original author and the contributors. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied, in part or in whole, and put under another distribution licence - * [including the GNU Public Licence.] - * - * 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. - * - * I hate legalese, don't you ? - */ diff --git a/contrib/ipfilter/QNX_OCL.txt b/contrib/ipfilter/QNX_OCL.txt deleted file mode 100644 index 6aa33ea..0000000 --- a/contrib/ipfilter/QNX_OCL.txt +++ /dev/null @@ -1,275 +0,0 @@ - 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/contrib/ipfilter/ip_fil_freebsd.c b/contrib/ipfilter/ip_fil_freebsd.c deleted file mode 100644 index 4ee0d3b..0000000 --- a/contrib/ipfilter/ip_fil_freebsd.c +++ /dev/null @@ -1,1692 +0,0 @@ -/* $FreeBSD$ */ - -/* - * Copyright (C) 1993-2003 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.25 2005/02/01 03:15:56 darrenr Exp"; -#endif - -#if defined(KERNEL) || defined(_KERNEL) -# undef KERNEL -# undef _KERNEL -# define KERNEL 1 -# define _KERNEL 1 -#endif -#if defined(__FreeBSD_version) && (__FreeBSD_version >= 400000) && \ - !defined(KLD_MODULE) && !defined(IPFILTER_LKM) -# include "opt_inet6.h" -#endif -#if defined(__FreeBSD_version) && (__FreeBSD_version >= 440000) && \ - !defined(KLD_MODULE) && !defined(IPFILTER_LKM) -# include "opt_random_ip_id.h" -#endif -#include <sys/param.h> -#if defined(__FreeBSD__) && !defined(__FreeBSD_version) -# if defined(IPFILTER_LKM) -# ifndef __FreeBSD_cc_version -# include <osreldate.h> -# else -# if __FreeBSD_cc_version < 430000 -# include <osreldate.h> -# endif -# endif -# endif -#endif -#include <sys/errno.h> -#include <sys/types.h> -#include <sys/file.h> -#if __FreeBSD_version >= 220000 -# include <sys/fcntl.h> -# include <sys/filio.h> -#else -# include <sys/ioctl.h> -#endif -#include <sys/time.h> -#include <sys/systm.h> -#if (__FreeBSD_version >= 300000) -# include <sys/dirent.h> -#else -# include <sys/dir.h> -#endif -#if !defined(__hpux) -# include <sys/mbuf.h> -#endif -#include <sys/protosw.h> -#include <sys/socket.h> - -#include <net/if.h> -#if __FreeBSD_version >= 300000 -# include <net/if_var.h> -# if !defined(IPFILTER_LKM) -# include "opt_ipfilter.h" -# endif -#endif -#include <net/route.h> -#include <netinet/in.h> -#include <netinet/in_var.h> -#include <netinet/in_systm.h> -#include <netinet/ip.h> -#include <netinet/ip_var.h> -#include <netinet/tcp.h> -#if defined(__osf__) -# include <netinet/tcp_timer.h> -#endif -#include <netinet/udp.h> -#include <netinet/tcpip.h> -#include <netinet/ip_icmp.h> -#ifndef _KERNEL -# include "netinet/ipf.h" -#endif -#include "netinet/ip_compat.h" -#ifdef USE_INET6 -# include <netinet/icmp6.h> -#endif -#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" -#if defined(__FreeBSD_version) && (__FreeBSD_version >= 300000) -# include <sys/malloc.h> -#endif -#include <sys/kernel.h> -#ifdef CSUM_DATA_VALID -#include <machine/in_cksum.h> -#endif -extern int ip_optcopy __P((struct ip *, struct ip *)); - -#if (__FreeBSD_version > 460000) -extern int path_mtu_discovery; -#endif - -# ifdef IPFILTER_M_IPFILTER -MALLOC_DEFINE(M_IPFILTER, "IP Filter", "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; -ipfrwlock_t ipf_frag, ipf_state, ipf_nat, ipf_natfrag, ipf_auth; -# endif -int ipf_locks_done = 0; - -#if (__FreeBSD_version >= 300000) -struct callout_handle fr_slowtimer_ch; -#endif - -#if (__FreeBSD_version >= 500011) -# include <sys/conf.h> -# if defined(NETBSD_PF) -# include <net/pfil.h> -# include <netinet/ipprotosw.h> -/* - * 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 */ - - -#if (__FreeBSD_version >= 501108) && defined(_KERNEL) - -static int -fr_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); -} - -# ifdef USE_INET6 -# include <netinet/ip6.h> - -static int -fr_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)); -} -# endif -#endif /* __FreeBSD_version >= 501108 */ -#if defined(IPFILTER_LKM) -int iplidentify(s) -char *s; -{ - if (strcmp(s, "ipl") == 0) - return 1; - return 0; -} -#endif /* IPFILTER_LKM */ - - -int iplattach() -{ -#ifdef USE_SPL - int s; -#endif -#if defined(NETBSD_PF) && (__FreeBSD_version >= 500011) - int error = 0; -# if __FreeBSD_version >= 501108 - struct pfil_head *ph_inet; -# ifdef USE_INET6 - struct pfil_head *ph_inet6; -# endif -# endif -#endif - - SPL_NET(s); - if (fr_running > 0) { - SPL_X(s); - return EBUSY; - } - - MUTEX_INIT(&ipf_rw, "ipf rw mutex"); - RWLOCK_INIT(&ipf_global, "ipf filter load/unload mutex"); - MUTEX_INIT(&ipf_timeoutlock, "ipf timeout queue mutex"); - RWLOCK_INIT(&ipf_mutex, "ipf filter rwlock"); - RWLOCK_INIT(&ipf_ipidfrag, "ipf IP NAT-Frag rwlock"); - ipf_locks_done = 1; - - if (fr_initialise() < 0) { - SPL_X(s); - return EIO; - } - - -# 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); -# endif - if (ph_inet == NULL -# ifdef USE_INET6 - && ph_inet6 == NULL -# endif - ) - return ENODEV; - - if (ph_inet != NULL) - error = pfil_add_hook((void *)fr_check_wrapper, NULL, - PFIL_IN|PFIL_OUT, ph_inet); - else - error = 0; -# else - error = pfil_add_hook((void *)fr_check, PFIL_IN|PFIL_OUT, - &inetsw[ip_protox[IPPROTO_IP]].pr_pfh); -# endif - if (error) { -# ifdef USE_INET6 - goto pfil_error; -# else - fr_deinitialise(); - SPL_X(s); - return error; -# endif - } -# else - pfil_add_hook((void *)fr_check, PFIL_IN|PFIL_OUT); -# endif -# ifdef USE_INET6 -# if __FreeBSD_version >= 501108 - if (ph_inet6 != NULL) - error = pfil_add_hook((void *)fr_check_wrapper6, NULL, - PFIL_IN|PFIL_OUT, ph_inet6); - else - error = 0; - if (error) { - pfil_remove_hook((void *)fr_check_wrapper6, NULL, - PFIL_IN|PFIL_OUT, ph_inet6); -# else - error = pfil_add_hook((void *)fr_check, PFIL_IN|PFIL_OUT, - &inet6sw[ip6_protox[IPPROTO_IPV6]].pr_pfh); - if (error) { - pfil_remove_hook((void *)fr_check, PFIL_IN|PFIL_OUT, - &inetsw[ip_protox[IPPROTO_IP]].pr_pfh); -# endif -pfil_error: - fr_deinitialise(); - SPL_X(s); - return error; - } -# endif -# endif - if (fr_checkp != fr_check) { - fr_savep = fr_checkp; - fr_checkp = fr_check; - } - - bzero((char *)frcache, sizeof(frcache)); - fr_running = 1; - - if (fr_control_forwarding & 1) - ipforwarding = 1; - - 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 - return 0; -} - - -/* - * Disable the filter by removing the hooks from the IP input/output - * stream. - */ -int ipldetach() -{ -#ifdef USE_SPL - int s; -#endif -#if defined(NETBSD_PF) && (__FreeBSD_version >= 500011) - int error = 0; -# if __FreeBSD_version >= 501108 - struct pfil_head *ph_inet; -# ifdef USE_INET6 - struct pfil_head *ph_inet6; -# endif -# endif -#endif - - if (fr_control_forwarding & 2) - 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 */ - -#ifndef NETBSD_PF - if (fr_checkp != NULL) - fr_checkp = fr_savep; - fr_savep = NULL; -#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) - error = pfil_remove_hook((void *)fr_check_wrapper, NULL, - PFIL_IN|PFIL_OUT, ph_inet); - else - error = 0; -# else - error = pfil_remove_hook((void *)fr_check, PFIL_IN|PFIL_OUT, - &inetsw[ip_protox[IPPROTO_IP]].pr_pfh); -# endif - if (error) { - SPL_X(s); - return error; - } -# else - pfil_remove_hook((void *)fr_check, PFIL_IN|PFIL_OUT); -# endif -# ifdef USE_INET6 -# if (__FreeBSD_version >= 501108) - ph_inet6 = pfil_head_get(PFIL_TYPE_AF, AF_INET6); - if (ph_inet6 != NULL) - error = pfil_remove_hook((void *)fr_check_wrapper6, NULL, - PFIL_IN|PFIL_OUT, ph_inet6); - else - error = 0; -# else - error = pfil_remove_hook((void *)fr_check, PFIL_IN|PFIL_OUT, - &inet6sw[ip6_protox[IPPROTO_IPV6]].pr_pfh); -# endif - if (error) { - SPL_X(s); - return error; - } -# endif -#endif - fr_deinitialise(); - - 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_mutex); - RW_DESTROY(&ipf_ipidfrag); - RW_DESTROY(&ipf_global); - ipf_locks_done = 0; - } - - SPL_X(s); - - return 0; -} - - -/* - * Filter ioctl interface. - */ -int iplioctl(dev, cmd, data, mode -# if defined(_KERNEL) && ((BSD >= 199506) || (__FreeBSD_version >= 220000)) -, p) -# 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 -ioctlcmd_t cmd; -caddr_t data; -int mode; -{ -#ifdef USE_SPL - int s; -#endif - int error = 0, unit = 0, tmp; - friostat_t fio; - -#if (BSD >= 199306) && defined(_KERNEL) - if ((securelevel >= 2) && (mode & FWRITE)) - return EPERM; -#endif - - unit = GET_MINOR(dev); - if ((IPL_LOGMAX < unit) || (unit < 0)) - return ENXIO; - - if (fr_running <= 0) { - if (unit != IPL_LOGIPF) - return EIO; - if (cmd != SIOCIPFGETNEXT && cmd != SIOCIPFGET && - cmd != SIOCIPFSET && cmd != SIOCFRENB && - cmd != SIOCGETFS && cmd != SIOCGETFF) - return EIO; - } - - SPL_NET(s); - - error = fr_ioctlswitch(unit, data, cmd, mode); - if (error != -1) { - SPL_X(s); - return error; - } - error = 0; - - switch (cmd) - { - case FIONREAD : -#ifdef IPFILTER_LOG - BCOPYOUT(&iplused[IPL_LOGIPF], (caddr_t)data, - sizeof(iplused[IPL_LOGIPF])); -#endif - break; - case SIOCFRENB : - if (!(mode & FWRITE)) - error = EPERM; - else { - BCOPYIN(data, &tmp, sizeof(tmp)); - if (tmp) { - if (fr_running > 0) - error = 0; - else - error = iplattach(); - if (error == 0) - fr_running = 1; - else - (void) ipldetach(); - } else { - error = ipldetach(); - if (error == 0) - fr_running = -1; - } - } - break; - case SIOCIPFSET : - if (!(mode & FWRITE)) { - error = EPERM; - break; - } - case SIOCIPFGETNEXT : - case SIOCIPFGET : - error = fr_ipftune(cmd, data); - break; - case SIOCSETFF : - if (!(mode & FWRITE)) - error = EPERM; - else - BCOPYIN(data, &fr_flags, sizeof(fr_flags)); - break; - case SIOCGETFF : - BCOPYOUT(&fr_flags, data, sizeof(fr_flags)); - break; - case SIOCFUNCL : - error = fr_resolvefunc(data); - break; - case SIOCINAFR : - case SIOCRMAFR : - case SIOCADAFR : - case SIOCZRLST : - if (!(mode & FWRITE)) - error = EPERM; - else - error = frrequest(unit, cmd, data, fr_active, 1); - break; - case SIOCINIFR : - case SIOCRMIFR : - case SIOCADIFR : - if (!(mode & FWRITE)) - error = EPERM; - else - error = frrequest(unit, cmd, data, 1 - fr_active, 1); - break; - case SIOCSWAPA : - if (!(mode & FWRITE)) - error = EPERM; - else { - bzero((char *)frcache, sizeof(frcache[0]) * 2); - *(u_int *)data = fr_active; - fr_active = 1 - fr_active; - } - break; - case SIOCGETFS : - fr_getstat(&fio); - error = fr_outobj(data, &fio, IPFOBJ_IPFSTAT); - break; - case SIOCFRZST : - if (!(mode & FWRITE)) - error = EPERM; - else - error = fr_zerostats(data); - break; - case SIOCIPFFL : - if (!(mode & FWRITE)) - error = EPERM; - else { - BCOPYIN(data, &tmp, sizeof(tmp)); - tmp = frflush(unit, 4, tmp); - BCOPYOUT(&tmp, data, sizeof(tmp)); - } - break; -#ifdef USE_INET6 - case SIOCIPFL6 : - if (!(mode & FWRITE)) - error = EPERM; - else { - BCOPYIN(data, &tmp, sizeof(tmp)); - tmp = frflush(unit, 6, tmp); - BCOPYOUT(&tmp, data, sizeof(tmp)); - } - break; -#endif - case SIOCSTLCK : - BCOPYIN(data, &tmp, sizeof(tmp)); - fr_state_lock = tmp; - fr_nat_lock = tmp; - fr_frag_lock = tmp; - fr_auth_lock = tmp; - break; -#ifdef IPFILTER_LOG - case SIOCIPFFB : - if (!(mode & FWRITE)) - error = EPERM; - else - *(int *)data = ipflog_clear(unit); - break; -#endif /* IPFILTER_LOG */ - case SIOCGFRST : - error = fr_outobj(data, fr_fragstats(), IPFOBJ_FRAGSTAT); - break; - case SIOCFRSYN : - if (!(mode & FWRITE)) - error = EPERM; - else { - frsync(NULL); - } - break; - default : - error = EINVAL; - break; - } - SPL_X(s); - return error; -} - - -#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; -{ - -# ifdef IPFILTER_SYNC - if (GET_MINOR(dev) == IPL_LOGSYNC) - return ipfsync_read(uio); -# endif - -#ifdef IPFILTER_LOG - return ipflog_read(GET_MINOR(dev), 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; -{ - -#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 - * requires a large amount of setting up and isn't any more efficient. - */ -int fr_send_reset(fin) -fr_info_t *fin; -{ - struct tcphdr *tcp, *tcp2; - int tlen = 0, hlen; - struct mbuf *m; -#ifdef USE_INET6 - ip6_t *ip6; -#endif - ip_t *ip; - - tcp = fin->fin_dp; - if (tcp->th_flags & TH_RST) - return -1; /* feedback loop */ - -#ifndef IPFILTER_CKSUM - if (fr_checkl4sum(fin) == -1) - return -1; -#endif - - tlen = fin->fin_dlen - (TCP_OFF(tcp) << 2) + - ((tcp->th_flags & TH_SYN) ? 1 : 0) + - ((tcp->th_flags & TH_FIN) ? 1 : 0); - -#ifdef USE_INET6 - hlen = (fin->fin_v == 6) ? sizeof(ip6_t) : sizeof(ip_t); -#else - hlen = sizeof(ip_t); -#endif -#ifdef MGETHDR - MGETHDR(m, M_DONTWAIT, MT_HEADER); -#else - MGET(m, M_DONTWAIT, MT_HEADER); -#endif - if (m == NULL) - return -1; - if (sizeof(*tcp2) + hlen > MLEN) { - MCLGET(m, M_DONTWAIT); - if ((m->m_flags & M_EXT) == 0) { - FREE_MB_T(m); - return -1; - } - } - - m->m_len = sizeof(*tcp2) + hlen; -#if (BSD >= 199103) - m->m_data += max_linkhdr; - m->m_pkthdr.len = m->m_len; - m->m_pkthdr.rcvif = (struct ifnet *)0; -#endif - ip = mtod(m, struct ip *); - bzero((char *)ip, hlen); -#ifdef USE_INET6 - ip6 = (ip6_t *)ip; -#endif - tcp2 = (struct tcphdr *)((char *)ip + hlen); - tcp2->th_sport = tcp->th_dport; - tcp2->th_dport = tcp->th_sport; - - if (tcp->th_flags & TH_ACK) { - tcp2->th_seq = tcp->th_ack; - tcp2->th_flags = TH_RST; - tcp2->th_ack = 0; - } else { - tcp2->th_seq = 0; - tcp2->th_ack = ntohl(tcp->th_seq); - tcp2->th_ack += tlen; - tcp2->th_ack = htonl(tcp2->th_ack); - tcp2->th_flags = TH_RST|TH_ACK; - } - TCP_X2_A(tcp2, 0); - TCP_OFF_A(tcp2, sizeof(*tcp2) >> 2); - tcp2->th_win = tcp->th_win; - tcp2->th_sum = 0; - tcp2->th_urp = 0; - -#ifdef USE_INET6 - if (fin->fin_v == 6) { - ip6->ip6_flow = ((ip6_t *)fin->fin_ip)->ip6_flow; - 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; - tcp2->th_sum = in6_cksum(m, IPPROTO_TCP, - sizeof(*ip6), sizeof(*tcp2)); - return fr_send_ip(fin, m, &m); - } -#endif - ip->ip_p = IPPROTO_TCP; - ip->ip_len = htons(sizeof(struct tcphdr)); - 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); -} - - -static int fr_send_ip(fin, m, mpp) -fr_info_t *fin; -mb_t *m, **mpp; -{ - fr_info_t fnew; - ip_t *ip, *oip; - int hlen; - - ip = mtod(m, ip_t *); - bzero((char *)&fnew, sizeof(fnew)); - - IP_V_A(ip, fin->fin_v); - switch (fin->fin_v) - { - case 4 : - fnew.fin_v = 4; - oip = fin->fin_ip; - 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 = path_mtu_discovery ? IP_DF : 0; -#else - ip->ip_off = 0; -#endif - ip->ip_ttl = ip_defttl; - ip->ip_sum = 0; - hlen = sizeof(*oip); - break; -#ifdef USE_INET6 - case 6 : - { - ip6_t *ip6 = (ip6_t *)ip; - - ip6->ip6_vfc = 0x60; - ip6->ip6_hlim = IPDEFTTL; - - fnew.fin_v = 6; - hlen = sizeof(*ip6); - break; - } -#endif - default : - return EINVAL; - } -#ifdef IPSEC - m->m_pkthdr.rcvif = NULL; -#endif - - fnew.fin_ifp = fin->fin_ifp; - fnew.fin_flx = FI_NOCKSUM; - fnew.fin_m = m; - fnew.fin_ip = ip; - fnew.fin_mp = mpp; - fnew.fin_hlen = hlen; - fnew.fin_dp = (char *)ip + hlen; - (void) fr_makefrip(hlen, ip, &fnew); - - return fr_fastroute(m, mpp, &fnew, NULL); -} - - -int fr_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; - void *ifp; -#ifdef USE_INET6 - ip6_t *ip6; - struct in6_addr dst6; -#endif - ip_t *ip, *ip2; - - if ((type < 0) || (type > ICMP_MAXTYPE)) - return -1; - - code = fin->fin_icode; -#ifdef USE_INET6 - if ((code < 0) || (code > sizeof(icmptoicmp6unreach)/sizeof(int))) - return -1; -#endif - -#ifndef IPFILTER_CKSUM - if (fr_checkl4sum(fin) == -1) - return -1; -#endif -#ifdef MGETHDR - MGETHDR(m, M_DONTWAIT, MT_HEADER); -#else - MGET(m, M_DONTWAIT, MT_HEADER); -#endif - if (m == NULL) - return -1; - avail = MHLEN; - - xtra = 0; - hlen = 0; - ohlen = 0; - ifp = fin->fin_ifp; - if (fin->fin_v == 4) { - if ((fin->fin_p == IPPROTO_ICMP) && - !(fin->fin_flx & FI_SHORT)) - switch (ntohs(fin->fin_data[0]) >> 8) - { - case ICMP_ECHO : - case ICMP_TSTAMP : - case ICMP_IREQ : - case ICMP_MASKREQ : - break; - default : - FREE_MB_T(m); - return 0; - } - - if (dst == 0) { - if (fr_ifpaddr(4, FRI_NORMAL, ifp, - &dst4, NULL) == -1) { - FREE_MB_T(m); - return -1; - } - } else - dst4.s_addr = fin->fin_daddr; - - hlen = sizeof(ip_t); - ohlen = fin->fin_hlen; - if (fin->fin_hlen < fin->fin_plen) - xtra = MIN(fin->fin_dlen, 8); - else - xtra = 0; - } - -#ifdef USE_INET6 - else if (fin->fin_v == 6) { - hlen = sizeof(ip6_t); - ohlen = sizeof(ip6_t); - type = icmptoicmp6types[type]; - if (type == ICMP6_DST_UNREACH) - code = icmptoicmp6unreach[code]; - - if (hlen + sizeof(*icmp) + max_linkhdr + - fin->fin_plen > avail) { - MCLGET(m, M_DONTWAIT); - if ((m->m_flags & M_EXT) == 0) { - FREE_MB_T(m); - return -1; - } - avail = MCLBYTES; - } - xtra = MIN(fin->fin_plen, - avail - hlen - sizeof(*icmp) - max_linkhdr); - if (dst == 0) { - if (fr_ifpaddr(6, FRI_NORMAL, ifp, - (struct in_addr *)&dst6, NULL) == -1) { - FREE_MB_T(m); - return -1; - } - } else - dst6 = fin->fin_dst6; - } -#endif - else { - FREE_MB_T(m); - return -1; - } - - iclen = hlen + sizeof(*icmp); - avail -= (max_linkhdr + iclen); - if (avail < 0) { - FREE_MB_T(m); - return -1; - } - if (xtra > avail) - xtra = avail; - iclen += xtra; - m->m_data += max_linkhdr; - m->m_pkthdr.rcvif = (struct ifnet *)0; - m->m_pkthdr.len = iclen; - m->m_len = iclen; - ip = mtod(m, ip_t *); - icmp = (struct icmp *)((char *)ip + hlen); - ip2 = (ip_t *)&icmp->icmp_ip; - - icmp->icmp_type = type; - 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); -#endif - - bcopy((char *)fin->fin_ip, (char *)ip2, ohlen); - -#ifdef USE_INET6 - ip6 = (ip6_t *)ip; - if (fin->fin_v == 6) { - ip6->ip6_flow = ((ip6_t *)fin->fin_ip)->ip6_flow; - 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; - if (xtra > 0) - bcopy((char *)fin->fin_ip + ohlen, - (char *)&icmp->icmp_ip + ohlen, xtra); - icmp->icmp_cksum = in6_cksum(m, IPPROTO_ICMPV6, - sizeof(*ip6), iclen - hlen); - } 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; - - if (xtra > 0) - bcopy((char *)fin->fin_ip + ohlen, - (char *)&icmp->icmp_ip + ohlen, xtra); - icmp->icmp_cksum = ipf_cksum((u_short *)icmp, - sizeof(*icmp) + 8); - ip->ip_len = iclen; - ip->ip_p = IPPROTO_ICMP; - } - err = fr_send_ip(fin, m, &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 (iplattach() != 0) - printf("IP Filter failed to attach\n"); - ip_init(); -} -#endif /* __FreeBSD_version < 300000 */ - - -int fr_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 = m0; - register struct route *ro; - int len, off, error = 0, hlen, code; - struct ifnet *ifp, *sifp; - struct sockaddr_in *dst; - struct route iproute; - u_short ip_off; - frentry_t *fr; - -#ifdef M_WRITABLE - /* - * HOT FIX/KLUDGE: - * - * If the mbuf we're about to send is not writable (because of - * a cluster reference, for example) we'll need to make a copy - * of it since this routine modifies the contents. - * - * If you have non-crappy network hardware that can transmit data - * from the mbuf, rather than making a copy, this is gonna be a - * problem. - */ - if (M_WRITABLE(m) == 0) { - if ((m0 = m_dup(m, M_DONTWAIT)) != 0) { - FREE_MB_T(m); - m = m0; - *mpp = m; - } else { - error = ENOBUFS; - FREE_MB_T(m); - *mpp = NULL; - fr_frouteok[1]++; - } - } -#endif - -#ifdef USE_INET6 - if (fin->fin_v == 6) { - /* - * currently "to <if>" and "to <if>: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 - } -#endif - - hlen = fin->fin_hlen; - ip = mtod(m0, struct ip *); - - /* - * Route packet. - */ - ro = &iproute; - bzero((caddr_t)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 (fdp != NULL) - ifp = fdp->fd_ifp; - else - ifp = fin->fin_ifp; - - if ((ifp == NULL) && (!fr || !(fr->fr_flags & FR_FASTROUTE))) { - error = -2; - goto bad; - } - - /* - * In case we're here due to "to <if>" being used with "keep state", - * check that we're going in the correct direction. - */ - if ((fr != NULL) && (fin->fin_rev != 0)) { - if ((ifp != NULL) && (fdp == &fr->fr_tif)) - return -1; - } - if (fdp != NULL) { - if (fdp->fd_ip.s_addr != 0) - dst->sin_addr = fdp->fd_ip; - } - - dst->sin_len = sizeof(*dst); - rtalloc(ro); - - if ((ifp == NULL) && (ro->ro_rt != NULL)) - ifp = ro->ro_rt->rt_ifp; - - if ((ro->ro_rt == NULL) || (ifp == NULL)) { - if (in_localaddr(ip->ip_dst)) - error = EHOSTUNREACH; - else - error = ENETUNREACH; - goto bad; - } - if (ro->ro_rt->rt_flags & RTF_GATEWAY) - dst = (struct sockaddr_in *)ro->ro_rt->rt_gateway; - if (ro->ro_rt) - ro->ro_rt->rt_use++; - - /* - * For input packets which are being "fastrouted", they won't - * go back through output filtering and miss their chance to get - * NAT'd and counted. - */ - if (fin->fin_out == 0) { - sifp = fin->fin_ifp; - fin->fin_ifp = ifp; - fin->fin_out = 1; - (void) fr_acctpkt(fin, NULL); - fin->fin_fr = NULL; - if (!fr || !(fr->fr_flags & FR_RETMASK)) { - u_32_t pass; - - (void) fr_checkstate(fin, &pass); - } - - switch (fr_checknatout(fin, NULL)) - { - case 0 : - break; - case 1 : - ip->ip_sum = 0; - break; - case -1 : - error = -1; - goto done; - break; - } - - fin->fin_ifp = sifp; - fin->fin_out = 0; - } else - ip->ip_sum = 0; - /* - * 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 (!ip->ip_sum) - ip->ip_sum = in_cksum(m, hlen); - error = (*ifp->if_output)(ifp, m, (struct sockaddr *)dst, - ro->ro_rt); - goto done; - } - /* - * Too large for interface; fragment if possible. - * Must be able to put at least 8 bytes per fragment. - */ - ip_off = ntohs(ip->ip_off); - if (ip_off & IP_DF) { - error = EMSGSIZE; - goto bad; - } - len = (ifp->if_mtu - hlen) &~ 7; - if (len < 8) { - error = EMSGSIZE; - goto bad; - } - - { - int mhlen, firstlen = len; - struct mbuf **mnext = &m->m_act; - - /* - * Loop through length of segment after first fragment, - * make new header and copy data of each part and link onto chain. - */ - m0 = m; - mhlen = sizeof (struct ip); - for (off = hlen + len; off < ip->ip_len; off += len) { -#ifdef MGETHDR - MGETHDR(m, M_DONTWAIT, MT_HEADER); -#else - MGET(m, M_DONTWAIT, MT_HEADER); -#endif - if (m == 0) { - m = m0; - error = ENOBUFS; - goto bad; - } - m->m_data += max_linkhdr; - mhip = mtod(m, struct ip *); - bcopy((char *)ip, (char *)mhip, sizeof(*ip)); - if (hlen > sizeof (struct ip)) { - mhlen = ip_optcopy(ip, mhip) + sizeof (struct ip); - IP_HL_A(mhip, mhlen >> 2); - } - m->m_len = mhlen; - mhip->ip_off = ((off - hlen) >> 3) + ip_off; - if (off + len >= ip->ip_len) - len = ip->ip_len - off; - else - mhip->ip_off |= IP_MF; - mhip->ip_len = htons((u_short)(len + mhlen)); - m->m_next = m_copy(m0, off, len); - if (m->m_next == 0) { - error = ENOBUFS; /* ??? */ - goto sendorfree; - } - m->m_pkthdr.len = mhlen + len; - m->m_pkthdr.rcvif = NULL; - mhip->ip_off = htons((u_short)mhip->ip_off); - mhip->ip_sum = 0; - mhip->ip_sum = in_cksum(m, mhlen); - *mnext = m; - mnext = &m->m_act; - } - /* - * Update first fragment by trimming what's been copied out - * and updating header, then send each fragment (in order). - */ - m_adj(m0, hlen + firstlen - ip->ip_len); - ip->ip_len = htons((u_short)(hlen + firstlen)); - ip->ip_off = htons((u_short)IP_MF); - ip->ip_sum = 0; - ip->ip_sum = in_cksum(m0, hlen); -sendorfree: - for (m = m0; m; m = m0) { - m0 = m->m_act; - m->m_act = 0; - if (error == 0) - error = (*ifp->if_output)(ifp, m, - (struct sockaddr *)dst, ro->ro_rt); - else - FREE_MB_T(m); - } - } -done: - if (!error) - fr_frouteok[0]++; - else - fr_frouteok[1]++; - - if (ro->ro_rt) { - RTFREE(ro->ro_rt); - } - *mpp = NULL; - return 0; -bad: - if (error == EMSGSIZE) { - sifp = fin->fin_ifp; - code = fin->fin_icode; - fin->fin_icode = ICMP_UNREACH_NEEDFRAG; - fin->fin_ifp = ifp; - (void) fr_send_icmp_err(ICMP_UNREACH, fin, 1); - fin->fin_ifp = sifp; - fin->fin_icode = code; - } - FREE_MB_T(m); - goto done; -} - - -int fr_verifysrc(fin) -fr_info_t *fin; -{ - struct sockaddr_in *dst; - struct route iproute; - - bzero((char *)&iproute, sizeof(iproute)); - dst = (struct sockaddr_in *)&iproute.ro_dst; - dst->sin_len = sizeof(*dst); - dst->sin_family = AF_INET; - dst->sin_addr = fin->fin_src; - rtalloc(&iproute); - if (iproute.ro_rt == NULL) - return 0; - return (fin->fin_ifp == iproute.ro_rt->rt_ifp); -} - - -/* - * 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; -{ -#ifdef USE_INET6 - struct in6_addr *inp6 = NULL; -#endif - struct sockaddr *sock, *mask; - struct sockaddr_in *sin; - struct ifaddr *ifa; - struct ifnet *ifp; - - if ((ifptr == NULL) || (ifptr == (void *)-1)) - return -1; - - sin = NULL; - ifp = ifptr; - - if (v == 4) - inp->s_addr = 0; -#ifdef USE_INET6 - else if (v == 6) - bzero((char *)inp, sizeof(struct in6_addr)); -#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) { - sin = (struct sockaddr_in *)sock; - if ((v == 4) && (sin->sin_family == AF_INET)) - break; -#ifdef USE_INET6 - if ((v == 6) && (sin->sin_family == AF_INET6)) { - inp6 = &((struct sockaddr_in6 *)sin)->sin6_addr; - if (!IN6_IS_ADDR_LINKLOCAL(inp6) && - !IN6_IS_ADDR_LOOPBACK(inp6)) - 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; - } - - if (ifa == NULL || sin == NULL) - return -1; - - mask = ifa->ifa_netmask; - if (atype == FRI_BROADCAST) - sock = ifa->ifa_broadaddr; - else if (atype == FRI_PEERADDR) - sock = ifa->ifa_dstaddr; - -#ifdef USE_INET6 - if (v == 6) { - return fr_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); -} - - -u_32_t fr_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 */ -/* 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; -{ -#ifndef RANDOM_IP_ID - static u_short ipid = 0; - u_short id; - - MUTEX_ENTER(&ipf_rw); - id = ipid++; - MUTEX_EXIT(&ipf_rw); -#else - u_short id; - - id = ip_randomid(); -#endif - - return id; -} - - -INLINE void fr_checkv4sum(fin) -fr_info_t *fin; -{ -#ifdef CSUM_DATA_VALID - int manual = 0; - u_short sum; - ip_t *ip; - mb_t *m; - - if ((fin->fin_flx & FI_NOCKSUM) != 0) - return; - - m = fin->fin_m; - if (m == NULL) { - manual = 1; - goto skipauto; - } - ip = fin->fin_ip; - - 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_p)); - sum ^= 0xffff; - if (sum != 0) - fin->fin_flx |= FI_BAD; - } else - manual = 1; -skipauto: -# ifdef IPFILTER_CKSUM - if (manual != 0) - if (fr_checkl4sum(fin) == -1) - fin->fin_flx |= FI_BAD; -# else - ; -# endif -#else -# ifdef IPFILTER_CKSUM - if (fr_checkl4sum(fin) == -1) - fin->fin_flx |= FI_BAD; -# endif -#endif -} - - -#ifdef USE_INET6 -INLINE void fr_checkv6sum(fin) -fr_info_t *fin; -{ -# ifdef IPFILTER_CKSUM - if (fr_checkl4sum(fin) == -1) - fin->fin_flx |= FI_BAD; -# endif -} -#endif /* USE_INET6 */ - - -size_t mbufchainlen(m0) -struct mbuf *m0; -{ - size_t len; - - if ((m0->m_flags & M_PKTHDR) != 0) { - len = m0->m_pkthdr.len; - } else { - struct mbuf *m; - - for (m = m0, len = 0; m != NULL; m = m->m_next) - len += m->m_len; - } - return len; -} - - -/* ------------------------------------------------------------------------ */ -/* Function: fr_pullup */ -/* Returns: NULL == pullup failed, else pointer to protocol header */ -/* Parameters: m(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 */ -/* 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 */ -/* of buffers that starts at *fin->fin_mp. */ -/* ------------------------------------------------------------------------ */ -void *fr_pullup(min, fin, len) -mb_t *min; -fr_info_t *fin; -int len; -{ - int out = fin->fin_out, dpoff, ipoff; - mb_t *m = min; - char *ip; - - if (m == NULL) - return NULL; - - ip = (char *)fin->fin_ip; - if ((fin->fin_flx & FI_COALESCE) != 0) - return ip; - - ipoff = fin->fin_ipoff; - if (fin->fin_dp != NULL) - dpoff = (char *)fin->fin_dp - (char *)ip; - else - dpoff = 0; - - if (M_LEN(m) < len) { -#ifdef MHLEN - /* - * Assume that M_PKTHDR is set and just work with what is left - * rather than check.. - * Should not make any real difference, anyway. - */ - if (len > MHLEN) -#else - if (len > MLEN) -#endif - { -#ifdef HAVE_M_PULLDOWN - if (m_pulldown(m, 0, len, NULL) == NULL) - m = NULL; -#else - FREE_MB_T(*fin->fin_mp); - m = NULL; -#endif - } else - { - m = m_pullup(m, len); - } - *fin->fin_mp = m; - fin->fin_m = m; - if (m == NULL) { - ATOMIC_INCL(frstats[out].fr_pull[1]); - return NULL; - } - 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; - - if (len == fin->fin_plen) - fin->fin_flx |= FI_COALESCE; - return ip; -} diff --git a/contrib/ipfilter/ip_htable.c b/contrib/ipfilter/ip_htable.c deleted file mode 100644 index 22acbec..0000000 --- a/contrib/ipfilter/ip_htable.c +++ /dev/null @@ -1,455 +0,0 @@ -/* $FreeBSD$ */ - -/* - * Copyright (C) 1993-2001, 2003 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 <sys/param.h> -#include <sys/types.h> -#include <sys/errno.h> -#include <sys/time.h> -#include <sys/file.h> -#if !defined(_KERNEL) -# include <stdlib.h> -# include <string.h> -# define _KERNEL -# ifdef __OpenBSD__ -struct file; -# endif -# include <sys/uio.h> -# undef _KERNEL -#endif -#include <sys/socket.h> -#if defined(__FreeBSD_version) && (__FreeBSD_version >= 300000) -# include <sys/malloc.h> -#endif -#if defined(__FreeBSD__) -# include <sys/cdefs.h> -# include <sys/proc.h> -#endif -#if !defined(__svr4__) && !defined(__SVR4) && !defined(__hpux) && \ - !defined(linux) -# include <sys/mbuf.h> -#endif -#if defined(_KERNEL) -# include <sys/systm.h> -#else -# include <stdio.h> -#endif -#include <netinet/in.h> -#include <net/if.h> - -#include "netinet/ip_compat.h" -#include "netinet/ip_fil.h" -#include "netinet/ip_lookup.h" -#include "netinet/ip_htable.h" -/* END OF INCLUDES */ - -#if !defined(lint) -static const char rcsid[] = "@(#)Id: ip_htable.c,v 2.34.2.2 2004/10/17 15:49:15 darrenr Exp"; -#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 }; - - -void fr_htable_unload() -{ - iplookupflush_t fop; - - fop.iplf_unit = IPL_LOGALL; - (void)fr_flushhtable(&fop); -} - - -int fr_gethtablestat(op) -iplookupop_t *op; -{ - iphtstat_t stats; - - if (op->iplo_size != sizeof(stats)) - 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]; - - return COPYOUT(&stats, op->iplo_struct, sizeof(stats)); - -} - - -/* - * Create a new hash table using the template passed. - */ -int fr_newhtable(op) -iplookupop_t *op; -{ - iphtable_t *iph, *oiph; - char name[FR_GROUPLEN]; - int err, i, unit; - - KMALLOC(iph, iphtable_t *); - if (iph == NULL) - return ENOMEM; - - err = COPYIN(op->iplo_struct, iph, sizeof(*iph)); - if (err != 0) { - KFREE(iph); - return EFAULT; - } - - unit = op->iplo_unit; - if (iph->iph_unit != unit) { - KFREE(iph); - return EINVAL; - } - - if ((op->iplo_arg & IPHASH_ANON) == 0) { - if (fr_findhtable(op->iplo_unit, op->iplo_name) != NULL) { - KFREE(iph); - return EEXIST; - } - } else { - i = IPHASH_ANON; - do { - i++; -#if defined(SNPRINTF) && defined(_KERNEL) - SNPRINTF(name, sizeof(name), "%u", i); -#else - (void)sprintf(name, "%u", i); -#endif - for (oiph = ipf_htables[unit]; oiph != NULL; - oiph = oiph->iph_next) - if (strncmp(oiph->iph_name, name, - sizeof(oiph->iph_name)) == 0) - break; - } while (oiph != NULL); - (void)strncpy(iph->iph_name, name, sizeof(iph->iph_name)); - err = COPYOUT(iph, op->iplo_struct, sizeof(*iph)); - if (err != 0) { - KFREE(iph); - return EFAULT; - } - iph->iph_type |= IPHASH_ANON; - } - - KMALLOCS(iph->iph_table, iphtent_t **, - iph->iph_size * sizeof(*iph->iph_table)); - if (iph->iph_table == NULL) { - KFREE(iph); - ipht_nomem[unit]++; - return ENOMEM; - } - - bzero((char *)iph->iph_table, iph->iph_size * sizeof(*iph->iph_table)); - iph->iph_masks = 0; - - 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]++; - - return 0; -} - - -/* - */ -int fr_removehtable(op) -iplookupop_t *op; -{ - iphtable_t *iph; - - - iph = fr_findhtable(op->iplo_unit, op->iplo_name); - if (iph == NULL) - return ESRCH; - - if (iph->iph_unit != op->iplo_unit) { - return EINVAL; - } - - if (iph->iph_ref != 0) { - return EBUSY; - } - - fr_delhtable(iph); - - return 0; -} - - -void fr_delhtable(iph) -iphtable_t *iph; -{ - iphtent_t *ipe; - int i; - - for (i = 0; i < iph->iph_size; i++) - while ((ipe = iph->iph_table[i]) != NULL) - if (fr_delhtent(iph, ipe) != 0) - return; - - *iph->iph_pnext = iph->iph_next; - if (iph->iph_next != NULL) - iph->iph_next->iph_pnext = iph->iph_pnext; - - ipf_nhtables[iph->iph_unit]--; - - if (iph->iph_ref == 0) { - KFREES(iph->iph_table, iph->iph_size * sizeof(*iph->iph_table)); - KFREE(iph); - } -} - - -void fr_derefhtable(iph) -iphtable_t *iph; -{ - iph->iph_ref--; - if (iph->iph_ref == 0) - fr_delhtable(iph); -} - - -iphtable_t *fr_findhtable(unit, name) -int unit; -char *name; -{ - 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; - return iph; -} - - -size_t fr_flushhtable(op) -iplookupflush_t *op; -{ - iphtable_t *iph; - size_t freed; - int i; - - freed = 0; - - for (i = 0; i <= IPL_LOGMAX; i++) { - if (op->iplf_unit == i || op->iplf_unit == IPL_LOGALL) { - while ((iph = ipf_htables[i]) != NULL) { - fr_delhtable(iph); - freed++; - } - } - } - - return freed; -} - - -/* - * Add an entry to a hash table. - */ -int fr_addhtent(iph, ipeo) -iphtable_t *iph; -iphtent_t *ipeo; -{ - iphtent_t *ipe; - u_int hv; - int bits; - - KMALLOC(ipe, iphtent_t *); - if (ipe == NULL) - 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); - - hv = IPE_HASH_FN(ipe->ipe_addr.in4_addr, ipe->ipe_mask.in4_addr, - iph->iph_size); - ipe->ipe_ref = 0; - ipe->ipe_next = iph->iph_table[hv]; - ipe->ipe_pnext = iph->iph_table + hv; - - if (iph->iph_table[hv] != NULL) - iph->iph_table[hv]->ipe_pnext = &ipe->ipe_next; - iph->iph_table[hv] = ipe; - if ((bits >= 0) && (bits != 32)) - iph->iph_masks |= 1 << bits; - - switch (iph->iph_type & ~IPHASH_ANON) - { - case IPHASH_GROUPMAP : - ipe->ipe_ptr = fr_addgroup(ipe->ipe_group, NULL, - iph->iph_flags, IPL_LOGIPF, - fr_active); - break; - - default : - ipe->ipe_ptr = NULL; - ipe->ipe_value = 0; - break; - } - - ipf_nhtnodes[iph->iph_unit]++; - - return 0; -} - - -/* - * Delete an entry from a hash table. - */ -int fr_delhtent(iph, ipe) -iphtable_t *iph; -iphtent_t *ipe; -{ - - if (ipe->ipe_ref != 0) - return EBUSY; - - - *ipe->ipe_pnext = ipe->ipe_next; - if (ipe->ipe_next != NULL) - ipe->ipe_next->ipe_pnext = ipe->ipe_pnext; - - switch (iph->iph_type & ~IPHASH_ANON) - { - case IPHASH_GROUPMAP : - if (ipe->ipe_group != NULL) - fr_delgroup(ipe->ipe_group, IPL_LOGIPF, fr_active); - break; - - default : - ipe->ipe_ptr = NULL; - ipe->ipe_value = 0; - break; - } - - KFREE(ipe); - - ipf_nhtnodes[iph->iph_unit]--; - - return 0; -} - - -void *fr_iphmfindgroup(tptr, aptr) -void *tptr, *aptr; -{ - struct in_addr *addr; - iphtable_t *iph; - iphtent_t *ipe; - void *rval; - - READ_ENTER(&ip_poolrw); - iph = tptr; - addr = aptr; - - ipe = fr_iphmfind(iph, addr); - if (ipe != NULL) - rval = ipe->ipe_ptr; - else - rval = NULL; - RWLOCK_EXIT(&ip_poolrw); - return rval; -} - - -/* ------------------------------------------------------------------------ */ -/* Function: fr_iphmfindip */ -/* Returns: int - 0 == +ve match, -1 == error, 1 == -ve/no match */ -/* Parameters: tptr(I) - pointer to the pool to search */ -/* version(I) - IP protocol version (4 or 6) */ -/* aptr(I) - pointer to address information */ -/* */ -/* Search the hash table for a given address and return a search result. */ -/* ------------------------------------------------------------------------ */ -int fr_iphmfindip(tptr, version, aptr) -void *tptr, *aptr; -int version; -{ - struct in_addr *addr; - iphtable_t *iph; - iphtent_t *ipe; - int rval; - - if (version != 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) - rval = 0; - else - rval = 1; - RWLOCK_EXIT(&ip_poolrw); - return rval; -} - - -/* Locks: ip_poolrw */ -static iphtent_t *fr_iphmfind(iph, addr) -iphtable_t *iph; -struct in_addr *addr; -{ - u_32_t hmsk, msk, ips; - iphtent_t *ipe; - u_int hv; - - hmsk = iph->iph_masks; - msk = 0xffffffff; -maskloop: - ips = ntohl(addr->s_addr) & msk; - hv = IPE_HASH_FN(ips, msk, iph->iph_size); - for (ipe = iph->iph_table[hv]; (ipe != NULL); ipe = ipe->ipe_next) { - if (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; - goto maskloop; - } - } - return ipe; -} - -#endif /* IPFILTER_LOOKUP */ diff --git a/contrib/ipfilter/ip_htable.h b/contrib/ipfilter/ip_htable.h deleted file mode 100644 index 1bc4087..0000000 --- a/contrib/ipfilter/ip_htable.h +++ /dev/null @@ -1,71 +0,0 @@ -/* $FreeBSD$ */ - -#ifndef __IP_HTABLE_H__ -#define __IP_HTABLE_H__ - -#include "netinet/ip_lookup.h" - -typedef struct iphtent_s { - struct iphtent_s *ipe_next, **ipe_pnext; - void *ipe_ptr; - i6addr_t ipe_addr; - i6addr_t ipe_mask; - int ipe_ref; - union { - char ipeu_char[16]; - u_long ipeu_long; - u_int ipeu_int; - }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)) - - -typedef struct iphtable_s { - ipfrwlock_t iph_rwlock; - struct iphtable_s *iph_next, **iph_pnext; - struct iphtent_s **iph_table; - 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 */ - char iph_name[FR_GROUPLEN]; /* hash table number */ -} iphtable_t; - -/* iph_type */ -#define IPHASH_LOOKUP 0 -#define IPHASH_GROUPMAP 1 -#define IPHASH_ANON 0x80000000 - - -typedef struct iphtstat_s { - iphtable_t *iphs_tables; - u_long iphs_numtables; - u_long iphs_numnodes; - u_long iphs_nomem; - u_long iphs_pad[16]; -} iphtstat_t; - - -extern iphtable_t *ipf_htables[IPL_LOGSIZE]; - -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((iplookupop_t *)); -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 void fr_derefhtable __P((iphtable_t *)); -extern void 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 *)); - -#endif /* __IP_HTABLE_H__ */ diff --git a/contrib/ipfilter/ip_irc_pxy.c b/contrib/ipfilter/ip_irc_pxy.c deleted file mode 100644 index 0f61d76..0000000 --- a/contrib/ipfilter/ip_irc_pxy.c +++ /dev/null @@ -1,435 +0,0 @@ -/* $FreeBSD$ */ - -/* - * Copyright (C) 2000-2003 Darren Reed - * - * See the IPFILTER.LICENCE file for details on licencing. - * - * Id: ip_irc_pxy.c,v 2.39.2.4 2005/02/04 10:22:55 darrenr Exp - */ - -#define IPF_IRC_PROXY - -#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)); -u_short ipf_irc_atoi __P((char **)); - -static frentry_t ircnatfr; - -int irc_proxy_init = 0; - - -/* - * Initialize local structures. - */ -int ippr_irc_init() -{ - 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() -{ - if (irc_proxy_init == 1) { - MUTEX_DESTROY(&ircnatfr.fr_lock); - irc_proxy_init = 0; - } -} - - -char *ippr_irc_dcctypes[] = { - "CHAT ", /* CHAT chat ipnumber portnumber */ - "SEND ", /* SEND filename ipnumber portnumber */ - "MOVE ", - "TSEND ", - "SCHAT ", - NULL, -}; - - -/* - * :A PRIVMSG B :^ADCC CHAT chat 0 0^A\r\n - * PRIVMSG B ^ADCC CHAT chat 0 0^A\r\n - */ - - -int ippr_irc_complete(ircp, buf, len) -ircinfo_t *ircp; -char *buf; -size_t len; -{ - register char *s, c; - register size_t i; - u_32_t l; - int j, k; - - ircp->irc_ipnum = 0; - ircp->irc_port = 0; - - if (len < 31) - return 0; - s = buf; - c = *s++; - i = len - 1; - - if ((c != ':') && (c != 'P')) - return 0; - - if (c == ':') { - /* - * Loosely check that the source is a nickname of some sort - */ - s++; - c = *s; - ircp->irc_snick = s; - if (!ISALPHA(c)) - return 0; - i--; - for (c = *s; !ISSPACE(c) && (i > 0); i--) - c = *s++; - if (i < 31) - return 0; - if (c != 'P') - return 0; - } else - ircp->irc_snick = NULL; - - /* - * Check command string - */ - if (strncmp(s, "PRIVMSG ", 8)) - return 0; - i -= 8; - s += 8; - c = *s; - ircp->irc_dnick = s; - - /* - * Loosely check that the destination is a nickname of some sort - */ - if (!ISALPHA(c)) - return 0; - for (; !ISSPACE(c) && (i > 0); i--) - c = *s++; - if (i < 20) - return 0; - s++, - i--; - - /* - * Look for a ^A to start the DCC - */ - c = *s; - if (c == ':') { - s++; - c = *s; - } - - if (strncmp(s, "\001DCC ", 4)) - return 0; - - i -= 4; - s += 4; - - /* - * 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)) - break; - } - if (!ippr_irc_dcctypes[j]) - return 0; - - ircp->irc_type = s; - i -= k; - s += k; - - if (i < 11) - return 0; - - /* - * Check for the arg - */ - c = *s; - if (ISSPACE(c)) - return 0; - ircp->irc_arg = s; - for (; (c != ' ') && (c != '\001') && (i > 0); i--) - c = *s++; - - if (c == '\001') /* In reality a ^A can quote another ^A...*/ - return 0; - - if (i < 5) - return 0; - - s++; - i--; - c = *s; - if (!ISDIGIT(c)) - return 0; - ircp->irc_addr = s; - /* - * Get the IP# - */ - for (l = 0; ISDIGIT(c) && (i > 0); i--) { - l *= 10; - l += c - '0'; - c = *s++; - } - - if (i < 4) - return 0; - - if (c != ' ') - return 0; - - ircp->irc_ipnum = l; - s++; - i--; - c = *s; - if (!ISDIGIT(c)) - return 0; - /* - * Get the port# - */ - for (l = 0; ISDIGIT(c) && (i > 0); i--) { - l *= 10; - l += c - '0'; - c = *s++; - } - if (i < 3) - return 0; - if (strncmp(s, "\001\r\n", 3)) - return 0; - s += 3; - ircp->irc_len = s - buf; - ircp->irc_port = l; - return 1; -} - - -int ippr_irc_new(fin, aps, nat) -fr_info_t *fin; -ap_session_t *aps; -nat_t *nat; -{ - ircinfo_t *irc; - - KMALLOC(irc, ircinfo_t *); - if (irc == NULL) - return -1; - - fin = fin; /* LINT */ - nat = nat; /* LINT */ - - aps->aps_data = irc; - aps->aps_psiz = sizeof(ircinfo_t); - - bzero((char *)irc, sizeof(*irc)); - return 0; -} - - -int ippr_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; - size_t nlen = 0, olen; - struct in_addr swip; - u_short a5, sp; - ircinfo_t *irc; - fr_info_t fi; - nat_t *nat2; - u_int a1; - ip_t *ip; - mb_t *m; -#ifdef MENTAT - mb_t *m1; -#endif - - m = fin->fin_m; - ip = fin->fin_ip; - tcp = (tcphdr_t *)fin->fin_dp; - bzero(ctcpbuf, sizeof(ctcpbuf)); - off = (char *)tcp - (char *)ip + (TCP_OFF(tcp) << 2) + fin->fin_ipoff; - -#ifdef __sgi - dlen = fin->fin_plen - off; -#else - dlen = MSGDSIZE(m) - off; -#endif - if (dlen <= 0) - return 0; - COPYDATA(m, off, MIN(sizeof(ctcpbuf), dlen), ctcpbuf); - - if (dlen <= 0) - return 0; - ctcpbuf[sizeof(ctcpbuf) - 1] = '\0'; - *newbuf = '\0'; - - irc = nat->nat_aps->aps_data; - if (ippr_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. - */ - if (irc->irc_ipnum != ntohl(nat->nat_inip.s_addr)) - return 0; - - a5 = irc->irc_port; - - /* - * Calculate new address parts for the DCC command - */ - a1 = ntohl(ip->ip_src.s_addr); - olen = irc->irc_len; - i = irc->irc_addr - ctcpbuf; - i++; - (void) strncpy(newbuf, ctcpbuf, i); - /* DO NOT change these! */ -#if defined(SNPRINTF) && defined(KERNEL) - SNPRINTF(newbuf, sizeof(newbuf) - i, "%u %u\001\r\n", a1, a5); -#else - (void) sprintf(newbuf, "%u %u\001\r\n", a1, a5); -#endif - - nlen = strlen(newbuf); - inc = nlen - olen; - - if ((inc + ip->ip_len) > 65535) - return 0; - -#ifdef MENTAT - for (m1 = m; m1->b_cont; m1 = m1->b_cont) - ; - if ((inc > 0) && (m1->b_datap->db_lim - m1->b_wptr < inc)) { - mblk_t *nm; - - /* alloc enough to keep same trailer space for lower driver */ - nm = allocb(nlen, BPRI_MED); - PANIC((!nm),("ippr_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")); - - linkb(m1, nm); - } else { -# if SOLARIS && defined(ICK_VALID) - if (m1->b_datap->db_struiolim == m1->b_wptr) - m1->b_datap->db_struiolim += inc; - m1->b_datap->db_struioflag &= ~STRUIO_IP; -# endif - m1->b_wptr += inc; - } -#else - if (inc < 0) - m_adj(m, inc); - /* the mbuf chain will be extended if necessary by m_copyback() */ -#endif - COPYBACK(m, off, nlen, newbuf); - - if (inc != 0) { -#if defined(MENTAT) || defined(__sgi) - register u_32_t sum1, sum2; - - sum1 = ip->ip_len; - sum2 = ip->ip_len + inc; - - /* Because ~1 == -2, We really need ~1 == -1 */ - if (sum1 > sum2) - sum2--; - sum2 -= sum1; - sum2 = (sum2 & 0xffff) + (sum2 >> 16); - - fix_outcksum(fin, &ip->ip_sum, sum2); -#endif - ip->ip_len += inc; - } - - /* - * Add skeleton NAT entry for connection which will come back the - * other way. - */ - sp = htons(a5); - /* - * Don't allow the PORT command to specify a port < 1024 due to - * security crap. - */ - if (ntohs(sp) < 1024) - 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((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, - ip->ip_dst); - if (nat2 == NULL) { - 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; - fi.fin_fr = &ircnatfr; - 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, - NAT_SLAVE|IPN_TCP|SI_W_DPORT, NAT_OUTBOUND); - if (nat2 != NULL) { - (void) nat_proto(&fi, nat2, 0); - nat_update(&fi, nat2, nat2->nat_ptr); - - (void) fr_addstate(&fi, NULL, SI_W_DPORT); - if (fi.fin_state != NULL) - fr_statederef(&fi, (ipstate_t **)&fi.fin_state); - } - ip->ip_src = swip; - } - return inc; -} - - -int ippr_irc_out(fin, aps, nat) -fr_info_t *fin; -ap_session_t *aps; -nat_t *nat; -{ - aps = aps; /* LINT */ - return ippr_irc_send(fin, nat); -} diff --git a/contrib/ipfilter/ip_lookup.c b/contrib/ipfilter/ip_lookup.c deleted file mode 100644 index 2f404ee..0000000 --- a/contrib/ipfilter/ip_lookup.c +++ /dev/null @@ -1,530 +0,0 @@ -/* $FreeBSD$ */ - -/* - * Copyright (C) 2002-2003 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 <sys/param.h> -#include <sys/errno.h> -#include <sys/types.h> -#include <sys/time.h> -#include <sys/file.h> -#if __FreeBSD_version >= 220000 && defined(_KERNEL) -# include <sys/fcntl.h> -# include <sys/filio.h> -#else -# include <sys/ioctl.h> -#endif -#if !defined(_KERNEL) -# include <string.h> -# define _KERNEL -# ifdef __OpenBSD__ -struct file; -# endif -# include <sys/uio.h> -# undef _KERNEL -#endif -#include <sys/socket.h> -#if (defined(__osf__) || defined(__hpux) || defined(__sgi)) && defined(_KERNEL) -# ifdef __osf__ -# include <net/radix.h> -# endif -# include "radix_ipf_local.h" -# define _RADIX_H_ -#endif -#include <net/if.h> -#if defined(__FreeBSD__) -# include <sys/cdefs.h> -# include <sys/proc.h> -#endif -#if defined(_KERNEL) -# include <sys/systm.h> -# if !defined(__SVR4) && !defined(__svr4__) -# include <sys/mbuf.h> -# endif -#endif -#include <netinet/in.h> - -#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" -/* END OF INCLUDES */ - -#if !defined(lint) -static const char rcsid[] = "@(#)Id: ip_lookup.c,v 2.35.2.5 2004/07/06 11:16:25 darrenr Exp"; -#endif - -#ifdef IPFILTER_LOOKUP -int ip_lookup_inited = 0; - -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)); - - -/* ------------------------------------------------------------------------ */ -/* Function: iplookup_init */ -/* Returns: int - 0 = success, else error */ -/* Parameters: Nil */ -/* */ -/* Initialise all of the subcomponents of the lookup infrstructure. */ -/* ------------------------------------------------------------------------ */ -int ip_lookup_init() -{ - - if (ip_pool_init() == -1) - return -1; - - RWLOCK_INIT(&ip_poolrw, "ip pool rwlock"); - - ip_lookup_inited = 1; - - return 0; -} - - -/* ------------------------------------------------------------------------ */ -/* Function: iplookup_unload */ -/* Returns: int - 0 = success, else error */ -/* Parameters: Nil */ -/* */ -/* 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. */ -/* ------------------------------------------------------------------------ */ -void ip_lookup_unload() -{ - ip_pool_fini(); - fr_htable_unload(); - - if (ip_lookup_inited == 1) { - RW_DESTROY(&ip_poolrw); - ip_lookup_inited = 0; - } -} - - -/* ------------------------------------------------------------------------ */ -/* Function: iplookup_ioctl */ -/* Returns: int - 0 = success, else error */ -/* Parameters: 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 */ -/* */ -/* 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) -caddr_t data; -ioctlcmd_t cmd; -int mode; -{ - int err; -# if defined(_KERNEL) && !defined(MENTAT) && defined(USE_SPL) - int s; -# endif - - mode = mode; /* LINT */ - - SPL_NET(s); - - switch (cmd) - { - case SIOCLOOKUPADDNODE : - case SIOCLOOKUPADDNODEW : - WRITE_ENTER(&ip_poolrw); - err = iplookup_addnode(data); - RWLOCK_EXIT(&ip_poolrw); - break; - - case SIOCLOOKUPDELNODE : - case SIOCLOOKUPDELNODEW : - WRITE_ENTER(&ip_poolrw); - err = iplookup_delnode(data); - RWLOCK_EXIT(&ip_poolrw); - break; - - case SIOCLOOKUPADDTABLE : - WRITE_ENTER(&ip_poolrw); - err = iplookup_addtable(data); - RWLOCK_EXIT(&ip_poolrw); - break; - - case SIOCLOOKUPDELTABLE : - WRITE_ENTER(&ip_poolrw); - err = iplookup_deltable(data); - RWLOCK_EXIT(&ip_poolrw); - break; - - case SIOCLOOKUPSTAT : - case SIOCLOOKUPSTATW : - WRITE_ENTER(&ip_poolrw); - err = iplookup_stats(data); - RWLOCK_EXIT(&ip_poolrw); - break; - - case SIOCLOOKUPFLUSH : - WRITE_ENTER(&ip_poolrw); - err = iplookup_flush(data); - RWLOCK_EXIT(&ip_poolrw); - break; - - default : - err = EINVAL; - break; - } - SPL_X(s); - return err; -} - - -/* ------------------------------------------------------------------------ */ -/* Function: iplookup_addnode */ -/* Returns: int - 0 = success, else error */ -/* Parameters: 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; -{ - ip_pool_node_t node, *m; - iplookupop_t op; - iphtable_t *iph; - iphtent_t hte; - ip_pool_t *p; - int err; - - err = 0; - BCOPYIN(data, &op, sizeof(op)); - 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; - } - return err; -} - - -/* ------------------------------------------------------------------------ */ -/* Function: iplookup_delnode */ -/* Returns: int - 0 = success, else error */ -/* Parameters: 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; -{ - ip_pool_node_t node, *m; - iplookupop_t op; - iphtable_t *iph; - iphtent_t hte; - ip_pool_t *p; - int err; - - err = 0; - BCOPYIN(data, &op, sizeof(op)); - - 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) - 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 : - err = EINVAL; - break; - } - return err; -} - - -/* ------------------------------------------------------------------------ */ -/* Function: iplookup_addtable */ -/* Returns: int - 0 = success, else error */ -/* Parameters: 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; -{ - iplookupop_t op; - int err; - - err = 0; - BCOPYIN(data, &op, sizeof(op)); - - 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; - - case IPLT_HASH : - if (fr_findhtable(op.iplo_unit, op.iplo_name) != NULL) - err = EEXIST; - else - err = fr_newhtable(&op); - break; - - default : - err = EINVAL; - break; - } - return err; -} - - -/* ------------------------------------------------------------------------ */ -/* Function: iplookup_deltable */ -/* Returns: int - 0 = success, else error */ -/* Parameters: 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; -{ - iplookupop_t op; - int err; - - BCOPYIN(data, &op, sizeof(op)); - op.iplo_name[sizeof(op.iplo_name) - 1] = '\0'; - - if (op.iplo_arg & IPLT_ANON) - op.iplo_arg &= IPLT_ANON; - - /* - * create a new pool - fail if one already exists with - * the same # - */ - switch (op.iplo_type) - { - case IPLT_POOL : - err = ip_pool_destroy(&op); - break; - - case IPLT_HASH : - err = fr_removehtable(&op); - break; - - default : - err = EINVAL; - break; - } - return err; -} - - -/* ------------------------------------------------------------------------ */ -/* Function: iplookup_stats */ -/* Returns: int - 0 = success, else error */ -/* Parameters: 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; -{ - iplookupop_t op; - int err; - - err = 0; - BCOPYIN(data, &op, sizeof(op)); - - 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; - } - return err; -} - - -/* ------------------------------------------------------------------------ */ -/* Function: iplookup_flush */ -/* Returns: int - 0 = success, else error */ -/* Parameters: 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; -{ - int err, unit, num, type; - iplookupflush_t flush; - - err = 0; - BCOPYIN(data, &flush, sizeof(flush)); - - flush.iplf_name[sizeof(flush.iplf_name) - 1] = '\0'; - - unit = flush.iplf_unit; - if ((unit < 0 || unit > IPL_LOGMAX) && (unit != IPLT_ALL)) - return EINVAL; - - type = flush.iplf_type; - 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); - } - - if (err == 0) { - flush.iplf_count = num; - err = COPYOUT(&flush, data, sizeof(flush)); - } - return err; -} - - -void ip_lookup_deref(type, ptr) -int type; -void *ptr; -{ - 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; - } - RWLOCK_EXIT(&ip_poolrw); -} - - -#else /* IPFILTER_LOOKUP */ - -/*ARGSUSED*/ -int ip_lookup_ioctl(data, cmd, mode) -caddr_t data; -ioctlcmd_t cmd; -int mode; -{ - return EIO; -} -#endif /* IPFILTER_LOOKUP */ diff --git a/contrib/ipfilter/ip_lookup.h b/contrib/ipfilter/ip_lookup.h deleted file mode 100644 index 7d9acad..0000000 --- a/contrib/ipfilter/ip_lookup.h +++ /dev/null @@ -1,65 +0,0 @@ -/* $FreeBSD$ */ - - -#ifndef __IP_LOOKUP_H__ -#define __IP_LOOKUP_H__ - -#if defined(__STDC__) || defined(__GNUC__) -# define SIOCLOOKUPADDTABLE _IOWR('r', 60, struct iplookupop) -# define SIOCLOOKUPDELTABLE _IOWR('r', 61, struct iplookupop) -# define SIOCLOOKUPSTAT _IOWR('r', 64, struct iplookupop) -# define SIOCLOOKUPSTATW _IOW('r', 64, struct iplookupop) -# define SIOCLOOKUPFLUSH _IOWR('r', 65, struct iplookupflush) -# define SIOCLOOKUPADDNODE _IOWR('r', 67, struct iplookupop) -# define SIOCLOOKUPADDNODEW _IOW('r', 67, struct iplookupop) -# define SIOCLOOKUPDELNODE _IOWR('r', 68, struct iplookupop) -# define SIOCLOOKUPDELNODEW _IOW('r', 68, struct iplookupop) -#else -# define SIOCLOOKUPADDTABLE _IOWR(r, 60, struct iplookupop) -# define SIOCLOOKUPDELTABLE _IOWR(r, 61, struct iplookupop) -# define SIOCLOOKUPSTAT _IOWR(r, 64, struct iplookupop) -# define SIOCLOOKUPSTATW _IOW(r, 64, struct iplookupop) -# define SIOCLOOKUPFLUSH _IOWR(r, 65, struct iplookupflush) -# define SIOCLOOKUPADDNODE _IOWR(r, 67, struct iplookupop) -# define SIOCLOOKUPADDNODEW _IOW(r, 67, struct iplookupop) -# define SIOCLOOKUPDELNODE _IOWR(r, 68, struct iplookupop) -# define SIOCLOOKUPDELNODEW _IOW(r, 68, struct iplookupop) -#endif - -typedef struct iplookupop { - int iplo_type; /* IPLT_* */ - int iplo_unit; /* IPL_LOG* */ - u_int iplo_arg; - char iplo_name[FR_GROUPLEN]; - size_t iplo_size; /* sizeof struct at iplo_struct */ - void *iplo_struct; -} iplookupop_t; - -typedef struct iplookupflush { - int iplf_type; /* IPLT_* */ - int iplf_unit; /* IPL_LOG* */ - u_int iplf_arg; - size_t iplf_count; - char iplf_name[FR_GROUPLEN]; -} iplookupflush_t; - -typedef struct iplookuplink { - int ipll_type; /* IPLT_* */ - int ipll_unit; /* IPL_LOG* */ - u_int ipll_num; - char ipll_group[FR_GROUPLEN]; -} iplookuplink_t; - -#define IPLT_ALL -1 -#define IPLT_NONE 0 -#define IPLT_POOL 1 -#define IPLT_HASH 2 - -#define IPLT_ANON 0x80000000 - -extern int ip_lookup_init __P((void)); -extern int ip_lookup_ioctl __P((caddr_t, ioctlcmd_t, int)); -extern void ip_lookup_unload __P((void)); -extern void ip_lookup_deref __P((int, void *)); - -#endif /* __IP_LOOKUP_H__ */ diff --git a/contrib/ipfilter/ip_pool.c b/contrib/ipfilter/ip_pool.c deleted file mode 100644 index 9880c9d..0000000 --- a/contrib/ipfilter/ip_pool.c +++ /dev/null @@ -1,786 +0,0 @@ -/* $FreeBSD$ */ - -/* - * Copyright (C) 1993-2001, 2003 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 <sys/errno.h> -#include <sys/types.h> -#include <sys/param.h> -#include <sys/file.h> -#if !defined(_KERNEL) && !defined(__KERNEL__) -# include <stdio.h> -# include <stdlib.h> -# include <string.h> -# define _KERNEL -# ifdef __OpenBSD__ -struct file; -# endif -# include <sys/uio.h> -# undef _KERNEL -#else -# include <sys/systm.h> -# if defined(NetBSD) && (__NetBSD_Version__ >= 104000000) -# include <sys/proc.h> -# endif -#endif -#include <sys/time.h> -#if !defined(linux) -# include <sys/protosw.h> -#endif -#include <sys/socket.h> -#if defined(_KERNEL) && (!defined(__SVR4) && !defined(__svr4__)) -# include <sys/mbuf.h> -#endif -#if defined(__SVR4) || defined(__svr4__) -# include <sys/filio.h> -# include <sys/byteorder.h> -# ifdef _KERNEL -# include <sys/dditypes.h> -# endif -# include <sys/stream.h> -# include <sys/kmem.h> -#endif -#if defined(__FreeBSD_version) && (__FreeBSD_version >= 300000) -# include <sys/malloc.h> -#endif - -#if (defined(__osf__) || defined(__hpux) || defined(__sgi)) && defined(_KERNEL) -# ifdef __osf__ -# include <net/radix.h> -# endif -# include "radix_ipf_local.h" -# define _RADIX_H_ -#endif -#include <net/if.h> -#include <netinet/in.h> - -#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 - -/* 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.12 2005/02/01 04:04:46 darrenr Exp"; -#endif - -#ifdef IPFILTER_LOOKUP - -# ifndef RADIX_NODE_HEAD_LOCK -# define RADIX_NODE_HEAD_LOCK(x) ; -# endif -# ifndef RADIX_NODE_HEAD_UNLOCK -# define RADIX_NODE_HEAD_UNLOCK(x) ; -# endif - -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 }; - - -#ifdef TEST_POOL -void treeprint __P((ip_pool_t *)); - -int -main(argc, argv) - int argc; - char *argv[]; -{ - addrfamily_t a, b; - iplookupop_t op; - ip_pool_t *ipo; - i6addr_t ip; - - RWLOCK_INIT(&ip_poolrw, "poolrw"); - ip_pool_init(); - - bzero((char *)&a, sizeof(a)); - bzero((char *)&b, sizeof(b)); - bzero((char *)&ip, sizeof(ip)); - bzero((char *)&op, sizeof(op)); - strcpy(op.iplo_name, "0"); - - if (ip_pool_create(&op) == 0) - ipo = ip_pool_find(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); - - 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); - - 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); - - 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); - - 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); - - 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); -#ifdef DEBUG_POOL -treeprint(ipo); -#endif - ip.in4.s_addr = 0x0a00aabb; - printf("search(%#x) = %d (0)\n", ip.in4.s_addr, - ip_pool_search(ipo, 4, &ip)); - - ip.in4.s_addr = 0x0a000001; - printf("search(%#x) = %d (0)\n", ip.in4.s_addr, - ip_pool_search(ipo, 4, &ip)); - - ip.in4.s_addr = 0x0a000101; - printf("search(%#x) = %d (0)\n", ip.in4.s_addr, - ip_pool_search(ipo, 4, &ip)); - - ip.in4.s_addr = 0x0a010001; - printf("search(%#x) = %d (1)\n", ip.in4.s_addr, - ip_pool_search(ipo, 4, &ip)); - - ip.in4.s_addr = 0x0a010101; - printf("search(%#x) = %d (1)\n", ip.in4.s_addr, - ip_pool_search(ipo, 4, &ip)); - - ip.in4.s_addr = 0x0a010201; - printf("search(%#x) = %d (0)\n", ip.in4.s_addr, - ip_pool_search(ipo, 4, &ip)); - - ip.in4.s_addr = 0x0a010203; - printf("search(%#x) = %d (1)\n", ip.in4.s_addr, - ip_pool_search(ipo, 4, &ip)); - - ip.in4.s_addr = 0x0a01020f; - printf("search(%#x) = %d (1)\n", ip.in4.s_addr, - ip_pool_search(ipo, 4, &ip)); - - ip.in4.s_addr = 0x0b00aabb; - printf("search(%#x) = %d (-1)\n", ip.in4.s_addr, - ip_pool_search(ipo, 4, &ip)); - -#ifdef DEBUG_POOL -treeprint(ipo); -#endif - - ip_pool_fini(); - - return 0; -} - - -void -treeprint(ipo) -ip_pool_t *ipo; -{ - ip_pool_node_t *c; - - for (c = ipo->ipo_list; c != NULL; c = c->ipn_next) - printf("Node %p(%s) (%#x/%#x) = %d hits %lu\n", - c, c->ipn_name, c->ipn_addr.adf_addr.in4.s_addr, - c->ipn_mask.adf_addr.in4.s_addr, - c->ipn_info, c->ipn_hits); -} -#endif /* TEST_POOL */ - - -/* ------------------------------------------------------------------------ */ -/* Function: ip_pool_init */ -/* Returns: int - 0 = success, else error */ -/* */ -/* Initialise the routing table data structures where required. */ -/* ------------------------------------------------------------------------ */ -int ip_pool_init() -{ - - bzero((char *)&ipoolstat, sizeof(ipoolstat)); - -#if (!defined(_KERNEL) || (BSD < 199306)) - rn_init(); -#endif - return 0; -} - - -/* ------------------------------------------------------------------------ */ -/* Function: ip_pool_fini */ -/* Returns: int - 0 = success, else error */ -/* 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*/ -/* used to delete the pools one by one to ensure they're properly freed up. */ -/* ------------------------------------------------------------------------ */ -void ip_pool_fini() -{ - ip_pool_t *p, *q; - iplookupop_t op; - int i; - - ASSERT(rw_read_locked(&ipf_global.ipf_lk) == 0); - - for (i = 0; i <= IPL_LOGMAX; i++) { - 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)); - q = p->ipo_next; - (void) ip_pool_destroy(&op); - } - } - -#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 */ -/* */ -/* Copy the current statistics out into user space, collecting pool list */ -/* pointers as appropriate for later use. */ -/* ------------------------------------------------------------------------ */ -int ip_pool_statistics(op) -iplookupop_t *op; -{ - ip_pool_stat_t stats; - int unit, i, err = 0; - - if (op->iplo_size != sizeof(ipoolstat)) - return EINVAL; - - 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_find(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_find */ -/* Returns: int - 0 = success, else error */ -/* Parameters: ipo(I) - pointer to the pool getting the new node. */ -/* */ -/* Find a matching pool inside the collection of pools for a particular */ -/* device, indicated by the unit number. */ -/* ------------------------------------------------------------------------ */ -void *ip_pool_find(unit, name) -int unit; -char *name; -{ - ip_pool_t *p; - - for (p = ip_pool_list[unit]; p != NULL; p = p->ipo_next) - if (strncmp(p->ipo_name, name, sizeof(p->ipo_name)) == 0) - break; - return p; -} - - -/* ------------------------------------------------------------------------ */ -/* Function: ip_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) - */ -/* */ -/* 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; -{ - struct radix_node *n; -#ifdef USE_SPL - int s; - - SPL_NET(s); -#endif - 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); - return (ip_pool_node_t *)n; -} - - -/* ------------------------------------------------------------------------ */ -/* Function: ip_pool_search */ -/* Returns: int - 0 == +ve match, -1 == error, 1 == -ve/no match */ -/* Parameters: tptr(I) - pointer to the pool to search */ -/* version(I) - IP protocol version (4 or 6) */ -/* dptr(I) - pointer to address information */ -/* */ -/* Search the pool for a given address and return a search result. */ -/* ------------------------------------------------------------------------ */ -int ip_pool_search(tptr, version, dptr) -void *tptr; -int version; -void *dptr; -{ - struct radix_node *rn; - ip_pool_node_t *m; - i6addr_t *addr; - addrfamily_t v; - ip_pool_t *ipo; - int rv; - - ipo = tptr; - if (ipo == NULL) - return -1; - - rv = 1; - m = NULL; - addr = (i6addr_t *)dptr; - bzero(&v, sizeof(v)); - v.adf_len = offsetof(addrfamily_t, adf_addr); - - if (version == 4) { - v.adf_len += sizeof(addr->in4); - v.adf_addr.in4 = addr->in4; -#ifdef USE_INET6 - } else if (version == 6) { - v.adf_len += sizeof(addr->in6); - v.adf_addr.in6 = addr->in6; -#endif - } else - return -1; - - READ_ENTER(&ip_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); - - if ((rn != NULL) && ((rn->rn_flags & RNF_ROOT) == 0)) { - m = (ip_pool_node_t *)rn; - ipo->ipo_hits++; - m->ipn_hits++; - rv = m->ipn_info; - } - RWLOCK_EXIT(&ip_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) */ -/* */ -/* 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; -{ - struct radix_node *rn; - ip_pool_node_t *x; - - ASSERT(rw_read_locked(&ip_poolrw.ipf_lk) == 0); - - KMALLOC(x, ip_pool_node_t *); - if (x == NULL) { - return ENOMEM; - } - - bzero(x, sizeof(*x)); - - x->ipn_info = info; - (void)strncpy(x->ipn_name, ipo->ipo_name, sizeof(x->ipn_name)); - - 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); - - 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); -#ifdef DEBUG_POOL - printf("Added %p at %p\n", x, rn); -#endif - - if (rn == NULL) { - KFREE(x); - return ENOMEM; - } - - 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; - - ipoolstat.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) */ -/* */ -/* Creates a new group according to the paramters passed in via the */ -/* iplookupop structure. Does not check to see if the group already exists */ -/* when being inserted - assume this has already been done. If the pool is */ -/* marked as being anonymous, give it a new, unique, identifier. Call any */ -/* other functions required to initialise the structure. */ -/* ------------------------------------------------------------------------ */ -int ip_pool_create(op) -iplookupop_t *op; -{ - char name[FR_GROUPLEN]; - int poolnum, unit; - ip_pool_t *h; - - ASSERT(rw_read_locked(&ip_poolrw.ipf_lk) == 0); - - KMALLOC(h, ip_pool_t *); - if (h == NULL) - return ENOMEM; - bzero(h, sizeof(*h)); - - if (rn_inithead((void **)&h->ipo_head, - offsetof(addrfamily_t, adf_addr) << 3) == 0) { - KFREE(h); - return ENOMEM; - } - - unit = op->iplo_unit; - - if ((op->iplo_arg & IPOOL_ANON) != 0) { - ip_pool_t *p; - - poolnum = IPOOL_ANON; - -#if defined(SNPRINTF) && defined(_KERNEL) - SNPRINTF(name, sizeof(name), "%x", poolnum); -#else - (void)sprintf(name, "%x", poolnum); -#endif - - for (p = ip_pool_list[unit]; p != NULL; ) { - if (strncmp(name, p->ipo_name, - sizeof(p->ipo_name)) == 0) { - poolnum++; -#if defined(SNPRINTF) && defined(_KERNEL) - SNPRINTF(name, sizeof(name), "%x", poolnum); -#else - (void)sprintf(name, "%x", poolnum); -#endif - p = ip_pool_list[unit]; - } else - p = p->ipo_next; - } - - (void)strncpy(h->ipo_name, name, sizeof(h->ipo_name)); - } else { - (void) strncpy(h->ipo_name, op->iplo_name, sizeof(h->ipo_name)); - } - - h->ipo_ref = 1; - h->ipo_list = NULL; - 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; - - ipoolstat.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) */ -/* */ -/* 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_remove(ipo, ipe) -ip_pool_t *ipo; -ip_pool_node_t *ipe; -{ - ip_pool_node_t **ipp, *n; - - ASSERT(rw_read_locked(&ip_poolrw.ipf_lk) == 0); - - for (ipp = &ipo->ipo_list; (n = *ipp) != NULL; ipp = &n->ipn_next) { - if (ipe == n) { - *n->ipn_pnext = n->ipn_next; - if (n->ipn_next) - n->ipn_next->ipn_pnext = n->ipn_pnext; - break; - } - } - - if (n == NULL) - return ENOENT; - - RADIX_NODE_HEAD_LOCK(ipo->ipo_head); - ipo->ipo_head->rnh_deladdr(&n->ipn_addr, &n->ipn_mask, - ipo->ipo_head); - RADIX_NODE_HEAD_UNLOCK(ipo->ipo_head); - KFREE(n); - - ipoolstat.ipls_nodes--; - - return 0; -} - - -/* ------------------------------------------------------------------------ */ -/* Function: ip_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) */ -/* */ -/* Search for a pool using paramters passed in and if it's not otherwise */ -/* busy, free it. */ -/* */ -/* NOTE: Because this function is called out of ipldetach() where ip_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. */ -/* ------------------------------------------------------------------------ */ -int ip_pool_destroy(op) -iplookupop_t *op; -{ - ip_pool_t *ipo; - - ipo = ip_pool_find(op->iplo_unit, op->iplo_name); - if (ipo == NULL) - return ESRCH; - - if (ipo->ipo_ref != 1) - return EBUSY; - - ip_pool_free(ipo); - return 0; -} - - -/* ------------------------------------------------------------------------ */ -/* Function: ip_pool_flush */ -/* Returns: int - number of pools deleted */ -/* Parameters: fp(I) - which pool(s) to flush */ -/* Locks: WRITE(ip_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 ipldetach() where ip_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. */ -/* ------------------------------------------------------------------------ */ -int ip_pool_flush(fp) -iplookupflush_t *fp; -{ - 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++) { - 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)); - q = p->ipo_next; - err = ip_pool_destroy(&op); - if (err == 0) - num++; - else - break; - } - } - return num; -} - - -/* ------------------------------------------------------------------------ */ -/* Function: ip_pool_free */ -/* Returns: void */ -/* Parameters: ipo(I) - pointer to pool structure */ -/* Locks: WRITE(ip_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 ipldetach() where ip_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. */ -/* ------------------------------------------------------------------------ */ -void ip_pool_free(ipo) -ip_pool_t *ipo; -{ - ip_pool_node_t *n; - - 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); - - ipo->ipo_list = NULL; - if (ipo->ipo_next != NULL) - ipo->ipo_next->ipo_pnext = ipo->ipo_pnext; - *ipo->ipo_pnext = ipo->ipo_next; - rn_freehead(ipo->ipo_head); - KFREE(ipo); - - ipoolstat.ipls_pools--; -} - - -/* ------------------------------------------------------------------------ */ -/* Function: ip_pool_deref */ -/* Returns: void */ -/* Parameters: ipo(I) - pointer to pool structure */ -/* Locks: WRITE(ip_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; -{ - - ASSERT(rw_read_locked(&ip_poolrw.ipf_lk) == 0); - - ipo->ipo_ref--; - if (ipo->ipo_ref == 0) - ip_pool_free(ipo); -} - - -# 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; -{ - - 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); -} -# endif - -#endif /* IPFILTER_LOOKUP */ diff --git a/contrib/ipfilter/ip_pool.h b/contrib/ipfilter/ip_pool.h deleted file mode 100644 index 5ddc74e..0000000 --- a/contrib/ipfilter/ip_pool.h +++ /dev/null @@ -1,87 +0,0 @@ -/* $FreeBSD$ */ - -/* - * Copyright (C) 1993-2001, 2003 by Darren Reed. - * - * See the IPFILTER.LICENCE file for details on licencing. - * - * Id: ip_pool.h,v 2.26.2.2 2004/03/23 12:44:34 darrenr Exp - */ - -#ifndef __IP_POOL_H__ -#define __IP_POOL_H__ - -#if defined(_KERNEL) && !defined(__osf__) && !defined(__hpux) && \ - !defined(linux) && !defined(sun) -# include <net/radix.h> -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) -# 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" - -#define IP_POOL_NOMATCH 0 -#define IP_POOL_POSITIVE 1 - -typedef struct ip_pool_node { - struct radix_node ipn_nodes[2]; - addrfamily_t ipn_addr; - addrfamily_t ipn_mask; - int ipn_info; - char ipn_name[FR_GROUPLEN]; - u_long ipn_hits; - struct ip_pool_node *ipn_next, **ipn_pnext; -} 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]; -} ip_pool_t; - -#define IPOOL_ANON 0x80000000 - - -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; - - -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((iplookupop_t *)); -extern void ip_pool_free __P((ip_pool_t *)); -extern void ip_pool_deref __P((ip_pool_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 *)); - -#endif /* __IP_POOL_H__ */ diff --git a/contrib/ipfilter/ip_pptp_pxy.c b/contrib/ipfilter/ip_pptp_pxy.c deleted file mode 100644 index b7ec697..0000000 --- a/contrib/ipfilter/ip_pptp_pxy.c +++ /dev/null @@ -1,527 +0,0 @@ -/* $FreeBSD$ */ - -/* - * Copyright (C) 2002-2003 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.9 2005/03/16 18:17:34 darrenr Exp - * - */ -#define IPF_PPTP_PROXY - -typedef struct pptp_hdr { - u_short pptph_len; - u_short pptph_type; - u_32_t pptph_cookie; -} pptp_hdr_t; - -#define PPTP_MSGTYPE_CTL 1 -#define PPTP_MTCTL_STARTREQ 1 -#define PPTP_MTCTL_STARTREP 2 -#define PPTP_MTCTL_STOPREQ 3 -#define PPTP_MTCTL_STOPREP 4 -#define PPTP_MTCTL_ECHOREQ 5 -#define PPTP_MTCTL_ECHOREP 6 -#define PPTP_MTCTL_OUTREQ 7 -#define PPTP_MTCTL_OUTREP 8 -#define PPTP_MTCTL_INREQ 9 -#define PPTP_MTCTL_INREP 10 -#define PPTP_MTCTL_INCONNECT 11 -#define PPTP_MTCTL_CLEAR 12 -#define PPTP_MTCTL_DISCONNECT 13 -#define PPTP_MTCTL_WANERROR 14 -#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 *)); - -static frentry_t pptpfr; - -int pptp_proxy_init = 0; -int ippr_pptp_debug = 0; -int ippr_pptp_gretimeout = IPF_TTLVAL(120); /* 2 minutes */ - - -/* - * PPTP application proxy initialization. - */ -int ippr_pptp_init() -{ - 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_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() -{ - if (pptp_proxy_init == 1) { - MUTEX_DESTROY(&pptpfr.fr_lock); - pptp_proxy_init = 0; - } -} - - -/* - * Setup for a new PPTP proxy. - */ -int ippr_pptp_new(fin, aps, nat) -fr_info_t *fin; -ap_session_t *aps; -nat_t *nat; -{ - pptp_pxy_t *pptp; - ipnat_t *ipn; - ip_t *ip; - int off; - - ip = fin->fin_ip; - off = fin->fin_hlen + sizeof(udphdr_t); - - if (nat_outlookup(fin, 0, IPPROTO_GRE, nat->nat_inip, - ip->ip_dst) != NULL) { - if (ippr_pptp_debug > 0) - printf("ippr_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 failed\n"); - return -1; - } - - /* - * 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_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; - - pptp->pptp_side[0].pptps_wptr = pptp->pptp_side[0].pptps_buffer; - pptp->pptp_side[1].pptps_wptr = pptp->pptp_side[1].pptps_buffer; - return 0; -} - - -void ippr_pptp_donatstate(fin, nat, pptp) -fr_info_t *fin; -nat_t *nat; -pptp_pxy_t *pptp; -{ - fr_info_t fi; - grehdr_t gre; - nat_t *nat2; - u_char p; - ip_t *ip; - - ip = fin->fin_ip; - p = ip->ip_p; - - nat2 = pptp->pptp_nat; - 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) || - (nat->nat_dir == NAT_INBOUND && !fin->fin_out)) { - fi.fin_data[0] = pptp->pptp_call[0]; - fi.fin_data[1] = pptp->pptp_call[1]; - } else { - fi.fin_data[0] = pptp->pptp_call[1]; - fi.fin_data[1] = pptp->pptp_call[0]; - } - ip = fin->fin_ip; - ip->ip_p = IPPROTO_GRE; - fi.fin_flx &= ~(FI_TCPUDP|FI_STATE|FI_FRAG); - 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; - } - } - - /* - * Update NAT timeout/create NAT if missing. - */ - if (nat2 != NULL) - fr_queueback(&nat2->nat_tqe); - else { - nat2 = nat_new(&fi, &pptp->pptp_rule, &pptp->pptp_nat, - NAT_SLAVE, nat->nat_dir); - pptp->pptp_nat = nat2; - if (nat2 != NULL) { - (void) nat_proto(&fi, nat2, 0); - nat_update(&fi, nat2, nat2->nat_ptr); - } - } - - READ_ENTER(&ipf_state); - if (pptp->pptp_state != NULL) { - fr_queueback(&pptp->pptp_state->is_sti); - RWLOCK_EXIT(&ipf_state); - } else { - RWLOCK_EXIT(&ipf_state); - if (nat->nat_dir == NAT_INBOUND) - fi.fin_fi.fi_daddr = nat2->nat_inip.s_addr; - else - fi.fin_fi.fi_saddr = nat2->nat_inip.s_addr; - fi.fin_ifp = NULL; - pptp->pptp_state = fr_addstate(&fi, &pptp->pptp_state, - 0); - if (fi.fin_state != NULL) - fr_statederef(&fi, (ipstate_t **)&fi.fin_state); - } - ip->ip_p = p; - return; -} - - -/* - * Try and build up the next PPTP message in the TCP stream and if we can - * 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; -{ - static char *funcname = "ippr_pptp_nextmessage"; - pptp_side_t *pptps; - u_32_t start, end; - pptp_hdr_t *hdr; - tcphdr_t *tcp; - int dlen, off; - u_short len; - char *msg; - - tcp = fin->fin_dp; - dlen = fin->fin_dlen - (TCP_OFF(tcp) << 2); - start = ntohl(tcp->th_seq); - pptps = &pptp->pptp_side[rev]; - off = (char *)tcp - (char *)fin->fin_ip + (TCP_OFF(tcp) << 2) + - fin->fin_ipoff; - - if (dlen <= 0) - return 0; - /* - * If the complete data packet is before what we expect to see - * "next", just ignore it as the chances are we've already seen it. - * The next if statement following this one really just causes packets - * ahead of what we've seen to be dropped, implying that something in - * the middle went missing and we want to see that first. - */ - end = start + dlen; - if (pptps->pptps_next > end && pptps->pptps_next > start) - return 0; - - if (pptps->pptps_next != start) { - if (ippr_pptp_debug > 5) - printf("%s: next (%x) != start (%x)\n", funcname, - pptps->pptps_next, start); - return -1; - } - - msg = (char *)fin->fin_dp + (TCP_OFF(tcp) << 2); - - while (dlen > 0) { - off += pptps->pptps_bytes; - if (pptps->pptps_gothdr == 0) { - /* - * PPTP has an 8 byte header that inclues the cookie. - * The start of every message should include one and - * it should match 1a2b3c4d. Byte order is ignored, - * deliberately, when printing out the error. - */ - len = MIN(8 - pptps->pptps_bytes, dlen); - COPYDATA(fin->fin_m, off, len, pptps->pptps_wptr); - pptps->pptps_bytes += len; - pptps->pptps_wptr += len; - hdr = (pptp_hdr_t *)pptps->pptps_buffer; - if (pptps->pptps_bytes == 8) { - pptps->pptps_next += 8; - if (ntohl(hdr->pptph_cookie) != 0x1a2b3c4d) { - if (ippr_pptp_debug > 1) - printf("%s: bad cookie (%x)\n", - funcname, - hdr->pptph_cookie); - return -1; - } - } - dlen -= len; - msg += len; - off += len; - - pptps->pptps_gothdr = 1; - len = ntohs(hdr->pptph_len); - pptps->pptps_len = len; - pptps->pptps_nexthdr += len; - - /* - * If a message is too big for the buffer, just set - * the fields for the next message to come along. - * The messages defined in RFC 2637 will not exceed - * 512 bytes (in total length) so this is likely a - * bad data packet, anyway. - */ - if (len > sizeof(pptps->pptps_buffer)) { - if (ippr_pptp_debug > 3) - printf("%s: message too big (%d)\n", - funcname, len); - pptps->pptps_next = pptps->pptps_nexthdr; - pptps->pptps_wptr = pptps->pptps_buffer; - pptps->pptps_gothdr = 0; - pptps->pptps_bytes = 0; - pptps->pptps_len = 0; - break; - } - } - - len = MIN(pptps->pptps_len - pptps->pptps_bytes, dlen); - COPYDATA(fin->fin_m, off, len, pptps->pptps_wptr); - pptps->pptps_bytes += len; - pptps->pptps_wptr += len; - pptps->pptps_next += len; - - if (pptps->pptps_len > pptps->pptps_bytes) - break; - - ippr_pptp_message(fin, nat, pptp, pptps); - pptps->pptps_wptr = pptps->pptps_buffer; - pptps->pptps_gothdr = 0; - pptps->pptps_bytes = 0; - pptps->pptps_len = 0; - - start += len; - msg += len; - dlen -= len; - } - - return 0; -} - - -/* - * 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; -{ - 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); - break; - - default : - break; - } - return 0; -} - - -/* - * 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; -{ - u_short *buffer = (u_short *)(pptps->pptps_buffer); - pptp_side_t *pptpo; - - if (pptps == &pptp->pptp_side[0]) - pptpo = &pptp->pptp_side[1]; - else - pptpo = &pptp->pptp_side[0]; - - /* - * Breakout to handle all the various messages. Most are just state - * transition. - */ - switch (ntohs(buffer[4])) - { - case PPTP_MTCTL_STARTREQ : - pptps->pptps_state = PPTP_MTCTL_STARTREQ; - break; - case PPTP_MTCTL_STARTREP : - if (pptpo->pptps_state == PPTP_MTCTL_STARTREQ) - pptps->pptps_state = PPTP_MTCTL_STARTREP; - break; - case PPTP_MTCTL_STOPREQ : - pptps->pptps_state = PPTP_MTCTL_STOPREQ; - break; - case PPTP_MTCTL_STOPREP : - if (pptpo->pptps_state == PPTP_MTCTL_STOPREQ) - pptps->pptps_state = PPTP_MTCTL_STOPREP; - break; - case PPTP_MTCTL_ECHOREQ : - pptps->pptps_state = PPTP_MTCTL_ECHOREQ; - break; - case PPTP_MTCTL_ECHOREP : - if (pptpo->pptps_state == PPTP_MTCTL_ECHOREQ) - pptps->pptps_state = PPTP_MTCTL_ECHOREP; - break; - case PPTP_MTCTL_OUTREQ : - pptps->pptps_state = PPTP_MTCTL_OUTREQ; - break; - case PPTP_MTCTL_OUTREP : - if (pptpo->pptps_state == PPTP_MTCTL_OUTREQ) { - pptps->pptps_state = PPTP_MTCTL_OUTREP; - pptp->pptp_call[0] = buffer[7]; - pptp->pptp_call[1] = buffer[6]; - ippr_pptp_donatstate(fin, nat, pptp); - } - break; - case PPTP_MTCTL_INREQ : - pptps->pptps_state = PPTP_MTCTL_INREQ; - break; - case PPTP_MTCTL_INREP : - if (pptpo->pptps_state == PPTP_MTCTL_INREQ) { - pptps->pptps_state = PPTP_MTCTL_INREP; - pptp->pptp_call[0] = buffer[7]; - pptp->pptp_call[1] = buffer[6]; - ippr_pptp_donatstate(fin, nat, pptp); - } - break; - case PPTP_MTCTL_INCONNECT : - pptps->pptps_state = PPTP_MTCTL_INCONNECT; - break; - case PPTP_MTCTL_CLEAR : - pptps->pptps_state = PPTP_MTCTL_CLEAR; - break; - case PPTP_MTCTL_DISCONNECT : - pptps->pptps_state = PPTP_MTCTL_DISCONNECT; - break; - case PPTP_MTCTL_WANERROR : - pptps->pptps_state = PPTP_MTCTL_WANERROR; - break; - case PPTP_MTCTL_LINKINFO : - pptps->pptps_state = PPTP_MTCTL_LINKINFO; - break; - } - - return 0; -} - - -/* - * 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; -{ - pptp_pxy_t *pptp; - tcphdr_t *tcp; - int rev; - - if ((fin->fin_out == 1) && (nat->nat_dir == NAT_INBOUND)) - rev = 1; - else if ((fin->fin_out == 0) && (nat->nat_dir == NAT_OUTBOUND)) - rev = 1; - else - rev = 0; - - tcp = (tcphdr_t *)fin->fin_dp; - if ((tcp->th_flags & TH_OPENING) == TH_OPENING) { - pptp = (pptp_pxy_t *)aps->aps_data; - pptp->pptp_side[1 - rev].pptps_next = ntohl(tcp->th_ack); - pptp->pptp_side[1 - rev].pptps_nexthdr = ntohl(tcp->th_ack); - 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, - rev); -} - - -/* - * clean up after ourselves. - */ -void ippr_pptp_del(aps) -ap_session_t *aps; -{ - pptp_pxy_t *pptp; - - pptp = aps->aps_data; - - if (pptp != NULL) { - /* - * Don't bother changing any of the NAT structure details, - * *_del() is on a callback from aps_free(), from nat_delete() - */ - - READ_ENTER(&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); - } - RWLOCK_EXIT(&ipf_state); - - pptp->pptp_state = NULL; - pptp->pptp_nat = NULL; - } -} diff --git a/contrib/ipfilter/ip_rpcb_pxy.c b/contrib/ipfilter/ip_rpcb_pxy.c deleted file mode 100644 index 4c01223..0000000 --- a/contrib/ipfilter/ip_rpcb_pxy.c +++ /dev/null @@ -1,1460 +0,0 @@ -/* $FreeBSD$ */ - -/* - * Copyright (C) 2002-2003 by Ryan Beasley <ryanb@goddamnbastard.org> - * - * See the IPFILTER.LICENCE file for details on licencing. - */ -/* - * Overview: - * This is an in-kernel application proxy for Sun's RPCBIND (nee portmap) - * protocol as defined in RFC1833. It is far from complete, mostly - * lacking in less-likely corner cases, but it's definitely functional. - * - * Invocation: - * rdr <int> <e_ip>/32 port <e_p> -> <i_ip> port <i_p> udp proxy rpcbu - * - * If the host running IP Filter is the same as the RPC server, it's - * perfectly legal for both the internal and external addresses and ports - * to match. - * - * When triggered by appropriate IP NAT rules, this proxy works by - * examining data contained in received packets. Requests and replies are - * modified, NAT and state table entries created, etc., as necessary. - */ -/* - * TODO / NOTES - * - * o Must implement locking to protect proxy session data. - * o Fragmentation isn't supported. - * o Only supports UDP. - * o Doesn't support multiple RPC records in a single request. - * o Errors should be more fine-grained. (e.g., malloc failure vs. - * illegal RPCB request / reply) - * o Even with the limit on the total amount of recorded transactions, - * should there be a timeout on transaction removal? - * o There is a potential collision between cloning, wildcard NAT and - * state entries. There should be an appr_getport routine for - * to avoid this. - * o The enclosed hack of STREAMS support is pretty sick and most likely - * broken. - * - * Id: ip_rpcb_pxy.c,v 2.25.2.3 2005/02/04 10:22:56 darrenr Exp - */ - -#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 *)); - -static void ippr_rpcb_flush __P((rpcb_session_t *)); -static int ippr_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 *, - 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 *, - mb_t *, u_int)); -static int ippr_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 *, - 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 *, - mb_t *, u_int)); -static int ippr_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)); - -/* - * Global variables - */ -static frentry_t rpcbfr; /* Skeleton rule for reference by entities - this proxy creates. */ -static int rpcbcnt; /* Upper bound of allocated RPCB sessions. */ - /* XXX rpcbcnt still requires locking. */ - -int rpcb_proxy_init = 0; - - -/* - * Since rpc_msg contains only pointers, one should use this macro as a - * handy way to get to the goods. (In case you're wondering about the name, - * this started as BYTEREF -> BREF -> B.) - */ -#define B(r) (u_32_t)ntohl(*(r)) - -/* - * Public subroutines - */ - -/* -------------------------------------------------------------------- */ -/* Function: ippr_rpcb_init */ -/* Returns: int - 0 == success */ -/* Parameters: (void) */ -/* */ -/* Initialize the filter rule entry and session limiter. */ -/* -------------------------------------------------------------------- */ -int -ippr_rpcb_init() -{ - rpcbcnt = 0; - - bzero((char *)&rpcbfr, sizeof(rpcbfr)); - rpcbfr.fr_ref = 1; - 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. */ -/* -------------------------------------------------------------------- */ -void -ippr_rpcb_fini() -{ - if (rpcb_proxy_init == 1) { - MUTEX_DESTROY(&rpcbfr.fr_lock); - rpcb_proxy_init = 0; - } -} - -/* -------------------------------------------------------------------- */ -/* Function: ippr_rpcb_new */ -/* Returns: int - -1 == failure, 0 == success */ -/* Parameters: fin(I) - pointer to packet information */ -/* aps(I) - pointer to proxy session structure */ -/* nat(I) - pointer to NAT session structure */ -/* */ -/* Allocate resources for per-session proxy structures. */ -/* -------------------------------------------------------------------- */ -int -ippr_rpcb_new(fin, aps, nat) - fr_info_t *fin; - ap_session_t *aps; - nat_t *nat; -{ - rpcb_session_t *rs; - - fin = fin; /* LINT */ - nat = nat; /* LINT */ - - KMALLOC(rs, rpcb_session_t *); - if (rs == NULL) - return(-1); - - bzero((char *)rs, sizeof(*rs)); - MUTEX_INIT(&rs->rs_rxlock, "ipf Sun RPCB proxy session lock"); - - aps->aps_data = rs; - - return(0); -} - -/* -------------------------------------------------------------------- */ -/* Function: ippr_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) - ap_session_t *aps; -{ - rpcb_session_t *rs; - rs = (rpcb_session_t *)aps->aps_data; - - MUTEX_ENTER(&rs->rs_rxlock); - ippr_rpcb_flush(rs); - MUTEX_EXIT(&rs->rs_rxlock); - MUTEX_DESTROY(&rs->rs_rxlock); -} - -/* -------------------------------------------------------------------- */ -/* Function: ippr_rpcb_in */ -/* Returns: int - APR_ERR(1) == drop the packet, */ -/* APR_ERR(2) == kill the proxy session, */ -/* else change in packet length (in bytes) */ -/* Parameters: fin(I) - pointer to packet information */ -/* ip(I) - pointer to packet header */ -/* aps(I) - pointer to proxy session structure */ -/* nat(I) - pointer to NAT session structure */ -/* */ -/* Given a presumed RPCB request, perform some minor tests and pass off */ -/* for decoding. Also pass packet off for a rewrite if necessary. */ -/* -------------------------------------------------------------------- */ -int -ippr_rpcb_in(fin, aps, nat) - fr_info_t *fin; - ap_session_t *aps; - nat_t *nat; -{ - rpc_msg_t rpcmsg, *rm; - rpcb_session_t *rs; - u_int off, dlen; - mb_t *m; - int rv; - - /* Disallow fragmented or illegally short packets. */ - if ((fin->fin_flx & (FI_FRAG|FI_SHORT)) != 0) - return(APR_ERR(1)); - - /* Perform basic variable initialization. */ - rs = (rpcb_session_t *)aps->aps_data; - - m = fin->fin_m; - off = (char *)fin->fin_dp - (char *)fin->fin_ip; - off += sizeof(udphdr_t) + fin->fin_ipoff; - dlen = fin->fin_dlen - sizeof(udphdr_t); - - /* Disallow packets outside legal range for supported requests. */ - if ((dlen < RPCB_REQMIN) || (dlen > RPCB_REQMAX)) - return(APR_ERR(1)); - - /* Copy packet over to convenience buffer. */ - rm = &rpcmsg; - bzero((char *)rm, sizeof(*rm)); - COPYDATA(m, off, dlen, (caddr_t)&rm->rm_msgbuf); - rm->rm_buflen = dlen; - - /* Send off to decode request. */ - rv = ippr_rpcb_decodereq(fin, nat, rs, rm); - - switch(rv) - { - case -1: - return(APR_ERR(1)); - /*NOTREACHED*/ - break; - case 0: - break; - case 1: - rv = ippr_rpcb_modreq(fin, nat, rm, m, off); - break; - default: - /*CONSTANTCONDITION*/ - IPF_PANIC(1, ("illegal rv %d (ippr_rpcb_req)", rv)); - } - - return(rv); -} - -/* -------------------------------------------------------------------- */ -/* Function: ippr_rpcb_out */ -/* Returns: int - APR_ERR(1) == drop the packet, */ -/* APR_ERR(2) == kill the proxy session, */ -/* else change in packet length (in bytes) */ -/* Parameters: fin(I) - pointer to packet information */ -/* ip(I) - pointer to packet header */ -/* aps(I) - pointer to proxy session structure */ -/* nat(I) - pointer to NAT session structure */ -/* */ -/* Given a presumed RPCB reply, perform some minor tests and pass off */ -/* for decoding. If the message indicates a successful request with */ -/* valid addressing information, create NAT and state structures to */ -/* allow direct communication between RPC client and server. */ -/* -------------------------------------------------------------------- */ -int -ippr_rpcb_out(fin, aps, nat) - fr_info_t *fin; - ap_session_t *aps; - nat_t *nat; -{ - rpc_msg_t rpcmsg, *rm; - rpcb_session_t *rs; - rpcb_xact_t *rx; - u_int off, dlen; - int rv, diff; - mb_t *m; - - /* Disallow fragmented or illegally short packets. */ - if ((fin->fin_flx & (FI_FRAG|FI_SHORT)) != 0) - return(APR_ERR(1)); - - /* Perform basic variable initialization. */ - rs = (rpcb_session_t *)aps->aps_data; - - m = fin->fin_m; - off = (char *)fin->fin_dp - (char *)fin->fin_ip; - off += sizeof(udphdr_t) + fin->fin_ipoff; - dlen = fin->fin_dlen - sizeof(udphdr_t); - diff = 0; - - /* Disallow packets outside legal range for supported requests. */ - if ((dlen < RPCB_REPMIN) || (dlen > RPCB_REPMAX)) - return(APR_ERR(1)); - - /* Copy packet over to convenience buffer. */ - rm = &rpcmsg; - bzero((char *)rm, sizeof(*rm)); - COPYDATA(m, off, dlen, (caddr_t)&rm->rm_msgbuf); - rm->rm_buflen = dlen; - - /* Send off to decode reply. */ - rv = ippr_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); - MUTEX_EXIT(&rs->rs_rxlock); - } - return(APR_ERR(1)); - /*NOTREACHED*/ - break; - case 0: /* Negative reply / request rejected */ - break; - case 1: /* Positive reply */ - /* - * With the IP address embedded in a GETADDR(LIST) reply, - * we'll need to rewrite the packet in the very possible - * event that the internal & external addresses aren't the - * 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 (rx->rx_type == RPCB_RES_STRING) - diff = ippr_rpcb_modv3(fin, nat, rm, m, off); - else if (rx->rx_type == RPCB_RES_LIST) - diff = ippr_rpcb_modv4(fin, nat, rm, m, off); - } - break; - default: - /*CONSTANTCONDITION*/ - IPF_PANIC(1, ("illegal rv %d (ippr_rpcb_decoderep)", rv)); - } - - if (rx != NULL) { - MUTEX_ENTER(&rs->rs_rxlock); - /* XXX Gross hack - I'm overloading the reference - * counter to deal with both threads and retransmitted - * requests. One deref signals that this thread is - * finished with rx, and the other signals that we've - * processed its reply. - */ - ippr_rpcb_deref(rs, rx); - ippr_rpcb_deref(rs, rx); - MUTEX_EXIT(&rs->rs_rxlock); - } - - return(diff); -} - -/* - * Private support subroutines - */ - -/* -------------------------------------------------------------------- */ -/* Function: ippr_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) - rpcb_session_t *rs; -{ - rpcb_xact_t *r1, *r2; - - r1 = rs->rs_rxlist; - if (r1 == NULL) - return; - - while (r1 != NULL) { - r2 = r1; - r1 = r1->rx_next; - KFREE(r2); - } -} - -/* -------------------------------------------------------------------- */ -/* Function: ippr_rpcb_decodereq */ -/* Returns: int - -1 == bad request or critical failure, */ -/* 0 == request successfully decoded, */ -/* 1 == request successfully decoded; requires */ -/* address rewrite/modification */ -/* Parameters: fin(I) - pointer to packet information */ -/* nat(I) - pointer to NAT session structure */ -/* rs(I) - pointer to RPCB session structure */ -/* rm(I) - pointer to RPC message structure */ -/* */ -/* Take a presumed RPCB request, decode it, and store the results in */ -/* the transaction list. If the internal target address needs to be */ -/* modified, store its location in ptr. */ -/* WARNING: It's the responsibility of the caller to make sure there */ -/* is enough room in rs_buf for the basic RPC message "preamble". */ -/* -------------------------------------------------------------------- */ -static int -ippr_rpcb_decodereq(fin, nat, rs, rm) - fr_info_t *fin; - nat_t *nat; - rpcb_session_t *rs; - rpc_msg_t *rm; -{ - rpcb_args_t *ra; - u_32_t xdr, *p; - rpc_call_t *rc; - rpcb_xact_t rx; - int mod; - - p = (u_32_t *)rm->rm_msgbuf; - mod = 0; - - bzero((char *)&rx, sizeof(rx)); - rc = &rm->rm_call; - - rm->rm_xid = p; - rx.rx_xid = B(p++); /* Record this message's XID. */ - - /* Parse out and test the RPC header. */ - if ((B(p++) != RPCB_CALL) || - (B(p++) != RPCB_MSG_VERSION) || - (B(p++) != RPCB_PROG)) - return(-1); - - /* Record the RPCB version and procedure. */ - rc->rc_vers = p++; - rc->rc_proc = p++; - - /* Bypass RPC authentication stuff. */ - if (ippr_rpcb_skipauth(rm, &rc->rc_authcred, &p) != 0) - return(-1); - if (ippr_rpcb_skipauth(rm, &rc->rc_authverf, &p) != 0) - return(-1); - - /* Compare RPCB version and procedure numbers. */ - switch(B(rc->rc_vers)) - { - case 2: - /* This proxy only supports PMAP_GETPORT. */ - if (B(rc->rc_proc) != RPCB_GETPORT) - return(-1); - - /* Portmap requests contain four 4 byte parameters. */ - if (RPCB_BUF_EQ(rm, p, 16) == 0) - return(-1); - - p += 2; /* Skip requested program and version numbers. */ - - /* Sanity check the requested protocol. */ - xdr = B(p); - if (!(xdr == IPPROTO_UDP || xdr == IPPROTO_TCP)) - return(-1); - - rx.rx_type = RPCB_RES_PMAP; - rx.rx_proto = xdr; - break; - case 3: - case 4: - /* GETADDRLIST is exclusive to v4; GETADDR for v3 & v4 */ - switch(B(rc->rc_proc)) - { - case RPCB_GETADDR: - rx.rx_type = RPCB_RES_STRING; - rx.rx_proto = (u_int)fin->fin_p; - break; - case RPCB_GETADDRLIST: - if (B(rc->rc_vers) != 4) - return(-1); - rx.rx_type = RPCB_RES_LIST; - break; - default: - return(-1); - } - - ra = &rc->rc_rpcbargs; - - /* Decode the 'struct rpcb' request. */ - if (ippr_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)) - 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)) - mod = 1; - break; - default: - return(-1); - } - - MUTEX_ENTER(&rs->rs_rxlock); - if (ippr_rpcb_insert(rs, &rx) != 0) { - MUTEX_EXIT(&rs->rs_rxlock); - return(-1); - } - MUTEX_EXIT(&rs->rs_rxlock); - - return(mod); -} - -/* -------------------------------------------------------------------- */ -/* Function: ippr_rpcb_skipauth */ -/* Returns: int -- -1 == illegal auth parameters (lengths) */ -/* 0 == valid parameters, pointer advanced */ -/* Parameters: rm(I) - pointer to RPC message structure */ -/* auth(I) - pointer to RPC auth structure */ -/* buf(IO) - pointer to location within convenience buffer */ -/* */ -/* Record auth data length & location of auth data, then advance past */ -/* it. */ -/* -------------------------------------------------------------------- */ -static int -ippr_rpcb_skipauth(rm, auth, buf) - rpc_msg_t *rm; - xdr_auth_t *auth; - u_32_t **buf; -{ - u_32_t *p, xdr; - - p = *buf; - - /* Make sure we have enough space for expected fixed auth parms. */ - if (RPCB_BUF_GEQ(rm, p, 8) == 0) - return(-1); - - p++; /* We don't care about auth_flavor. */ - - auth->xa_string.xs_len = p; - xdr = B(p++); /* Length of auth_data */ - - /* Test for absurdity / illegality of auth_data length. */ - if ((XDRALIGN(xdr) < xdr) || (RPCB_BUF_GEQ(rm, p, XDRALIGN(xdr)) == 0)) - return(-1); - - auth->xa_string.xs_str = (char *)p; - - p += XDRALIGN(xdr); /* Advance our location. */ - - *buf = (u_32_t *)p; - - return(0); -} - -/* -------------------------------------------------------------------- */ -/* Function: ippr_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) - rpcb_session_t *rs; - rpcb_xact_t *rx; -{ - rpcb_xact_t *rxp; - - rxp = ippr_rpcb_lookup(rs, rx->rx_xid); - if (rxp != NULL) { - ++rxp->rx_ref; - return(0); - } - - if (rpcbcnt == RPCB_MAXREQS) - return(-1); - - KMALLOC(rxp, rpcb_xact_t *); - if (rxp == NULL) - return(-1); - - bcopy((char *)rx, (char *)rxp, sizeof(*rx)); - - if (rs->rs_rxlist != NULL) - rs->rs_rxlist->rx_pnext = &rxp->rx_next; - - rxp->rx_pnext = &rs->rs_rxlist; - rxp->rx_next = rs->rs_rxlist; - rs->rs_rxlist = rxp; - - rxp->rx_ref = 1; - - ++rpcbcnt; - - return(0); -} - -/* -------------------------------------------------------------------- */ -/* Function: ippr_rpcb_xdrrpcb */ -/* Returns: int -- -1 == failure to properly decode the request */ -/* 0 == rpcb successfully decoded */ -/* Parameters: rs(I) - pointer to RPCB session structure */ -/* p(I) - pointer to location within session buffer */ -/* rpcb(O) - pointer to rpcb (xdr type) structure */ -/* */ -/* Decode a XDR encoded rpcb structure and record its contents in rpcb */ -/* within only the context of TCP/UDP over IP networks. */ -/* -------------------------------------------------------------------- */ -static int -ippr_rpcb_xdrrpcb(rm, p, ra) - rpc_msg_t *rm; - u_32_t *p; - rpcb_args_t *ra; -{ - if (!RPCB_BUF_GEQ(rm, p, 20)) - return(-1); - - /* Bypass target program & version. */ - p += 2; - - /* Decode r_netid. Must be "tcp" or "udp". */ - if (ippr_rpcb_getproto(rm, &ra->ra_netid, &p) != 0) - return(-1); - - /* Decode r_maddr. */ - if (ippr_rpcb_getuaddr(rm, &ra->ra_maddr, &p) != 0) - return(-1); - - /* Advance to r_owner and make sure it's empty. */ - if (!RPCB_BUF_EQ(rm, p, 4) || (B(p) != 0)) - return(-1); - - return(0); -} - -/* -------------------------------------------------------------------- */ -/* Function: ippr_rpcb_getuaddr */ -/* Returns: int -- -1 == illegal string, */ -/* 0 == string parsed; contents recorded */ -/* Parameters: rm(I) - pointer to RPC message structure */ -/* xu(I) - pointer to universal address structure */ -/* p(IO) - pointer to location within message buffer */ -/* */ -/* Decode the IP address / port at p and record them in xu. */ -/* -------------------------------------------------------------------- */ -static int -ippr_rpcb_getuaddr(rm, xu, p) - rpc_msg_t *rm; - xdr_uaddr_t *xu; - u_32_t **p; -{ - char *c, *i, *b, *pp; - u_int d, dd, l, t; - char uastr[24]; - - /* Test for string length. */ - if (!RPCB_BUF_GEQ(rm, *p, 4)) - return(-1); - - xu->xu_xslen = (*p)++; - xu->xu_xsstr = (char *)*p; - - /* Length check */ - l = B(xu->xu_xslen); - if (l < 11 || l > 23 || !RPCB_BUF_GEQ(rm, *p, XDRALIGN(l))) - return(-1); - - /* Advance p */ - *(char **)p += XDRALIGN(l); - - /* Copy string to local buffer & terminate C style */ - bcopy(xu->xu_xsstr, uastr, l); - uastr[l] = '\0'; - - i = (char *)&xu->xu_ip; - pp = (char *)&xu->xu_port; - - /* - * Expected format: a.b.c.d.e.f where [a-d] correspond to bytes of - * an IP address and [ef] are the bytes of a L4 port. - */ - if (!(ISDIGIT(uastr[0]) && ISDIGIT(uastr[l-1]))) - return(-1); - b = uastr; - for (c = &uastr[1], d = 0, dd = 0; c < &uastr[l-1]; c++) { - if (ISDIGIT(*c)) { - dd = 0; - continue; - } - if (*c == '.') { - if (dd != 0) - return(-1); - - /* Check for ASCII byte. */ - *c = '\0'; - t = ippr_rpcb_atoi(b); - if (t > 255) - return(-1); - - /* Aim b at beginning of the next byte. */ - b = c + 1; - - /* Switch off IP addr vs port parsing. */ - if (d < 4) - i[d++] = t & 0xff; - else - pp[d++ - 4] = t & 0xff; - - dd = 1; - continue; - } - return(-1); - } - if (d != 5) /* String must contain exactly 5 periods. */ - return(-1); - - /* Handle the last byte (port low byte) */ - t = ippr_rpcb_atoi(b); - if (t > 255) - return(-1); - pp[d - 4] = t & 0xff; - - return(0); -} - -/* -------------------------------------------------------------------- */ -/* Function: ippr_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) - char *ptr; -{ - register char *s = ptr, c; - register u_int i = 0; - - while (((c = *s++) != '\0') && ISDIGIT(c)) { - i *= 10; - i += c - '0'; - } - return i; -} - -/* -------------------------------------------------------------------- */ -/* Function: ippr_rpcb_modreq */ -/* Returns: int -- change in datagram length */ -/* APR_ERR(2) - critical failure */ -/* Parameters: fin(I) - pointer to packet information */ -/* nat(I) - pointer to NAT session */ -/* rm(I) - pointer to RPC message structure */ -/* m(I) - pointer to mbuf chain */ -/* off(I) - current offset within mbuf chain */ -/* */ -/* When external and internal addresses differ, we rewrite the former */ -/* with the latter. (This is exclusive to protocol versions 3 & 4). */ -/* -------------------------------------------------------------------- */ -static int -ippr_rpcb_modreq(fin, nat, rm, m, off) - fr_info_t *fin; - nat_t *nat; - rpc_msg_t *rm; - mb_t *m; - u_int off; -{ - u_int len, xlen, pos, bogo; - rpcb_args_t *ra; - char uaddr[24]; - udphdr_t *udp; - char *i, *p; - int diff; - - ra = &rm->rm_call.rc_rpcbargs; - i = (char *)&nat->nat_inip.s_addr; - p = (char *)&nat->nat_inport; - - /* Form new string. */ - bzero(uaddr, sizeof(uaddr)); /* Just in case we need padding. */ -#if defined(SNPRINTF) && defined(_KERNEL) - SNPRINTF(uaddr, sizeof(uaddr), -#else - (void) sprintf(uaddr, -#endif - "%u.%u.%u.%u.%u.%u", i[0] & 0xff, i[1] & 0xff, - i[2] & 0xff, i[3] & 0xff, p[0] & 0xff, p[1] & 0xff); - len = strlen(uaddr); - xlen = XDRALIGN(len); - - /* Determine mbuf offset to start writing to. */ - pos = (char *)ra->ra_maddr.xu_xslen - rm->rm_msgbuf; - off += pos; - - /* Write new string length. */ - bogo = htonl(len); - COPYBACK(m, off, 4, (caddr_t)&bogo); - off += 4; - - /* Write new string. */ - COPYBACK(m, off, xlen, uaddr); - off += xlen; - - /* Write in zero r_owner. */ - bogo = 0; - COPYBACK(m, off, 4, (caddr_t)&bogo); - - /* Determine difference in data lengths. */ - diff = xlen - XDRALIGN(B(ra->ra_maddr.xu_xslen)); - - /* - * If our new string has a different length, make necessary - * adjustments. - */ - 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; - /* XXX Storage lengths. */ - } - - return(diff); -} - -/* -------------------------------------------------------------------- */ -/* Function: ippr_rpcb_decoderep */ -/* Returns: int - -1 == bad request or critical failure, */ -/* 0 == valid, negative reply */ -/* 1 == vaddlid, positive reply; needs no changes */ -/* Parameters: fin(I) - pointer to packet information */ -/* nat(I) - pointer to NAT session structure */ -/* rs(I) - pointer to RPCB session structure */ -/* rm(I) - pointer to RPC message structure */ -/* rxp(O) - pointer to RPCB transaction structure */ -/* */ -/* Take a presumed RPCB reply, extract the XID, search for the original */ -/* request information, and determine whether the request was accepted */ -/* or rejected. With a valid accepted reply, go ahead and create NAT */ -/* and state entries, and finish up by rewriting the packet as */ -/* required. */ -/* */ -/* WARNING: It's the responsibility of the caller to make sure there */ -/* is enough room in rs_buf for the basic RPC message "preamble". */ -/* -------------------------------------------------------------------- */ -static int -ippr_rpcb_decoderep(fin, nat, rs, rm, rxp) - fr_info_t *fin; - nat_t *nat; - rpcb_session_t *rs; - rpc_msg_t *rm; - rpcb_xact_t **rxp; -{ - rpcb_listp_t *rl; - rpcb_entry_t *re; - rpcb_xact_t *rx; - u_32_t xdr, *p; - rpc_resp_t *rr; - int rv, cnt; - - p = (u_32_t *)rm->rm_msgbuf; - - bzero((char *)&rx, sizeof(rx)); - rr = &rm->rm_resp; - - rm->rm_xid = p; - xdr = B(p++); /* Record this message's XID. */ - - /* Lookup XID */ - MUTEX_ENTER(&rs->rs_rxlock); - if ((rx = ippr_rpcb_lookup(rs, xdr)) == NULL) { - MUTEX_EXIT(&rs->rs_rxlock); - return(-1); - } - ++rx->rx_ref; /* per thread reference */ - MUTEX_EXIT(&rs->rs_rxlock); - - *rxp = rx; - - /* Test call vs reply */ - if (B(p++) != RPCB_REPLY) - return(-1); - - /* Test reply_stat */ - switch(B(p++)) - { - case RPCB_MSG_DENIED: - return(0); - case RPCB_MSG_ACCEPTED: - break; - default: - return(-1); - } - - /* Bypass RPC authentication stuff. */ - if (ippr_rpcb_skipauth(rm, &rr->rr_authverf, &p) != 0) - return(-1); - - /* Test accept status */ - if (!RPCB_BUF_GEQ(rm, p, 4)) - return(-1); - if (B(p++) != 0) - return(0); - - /* Parse out the expected reply */ - switch(rx->rx_type) - { - case RPCB_RES_PMAP: - /* 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) - return(-1); - break; - case RPCB_RES_STRING: - /* Expecting a XDR string; need 4 bytes for length */ - if (!RPCB_BUF_GEQ(rm, p, 4)) - return(-1); - - rr->rr_v3.xu_str.xs_len = p++; - rr->rr_v3.xu_str.xs_str = (char *)p; - - xdr = B(rr->rr_v3.xu_xslen); - - /* A null string indicates an unregistered service */ - if ((xdr == 0) && RPCB_BUF_EQ(rm, p, 0)) - return(0); - - /* Decode the target IP address / port. */ - if (ippr_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) - return(-1); - - /* Create NAT & state table entries. */ - if (ippr_rpcb_getnat(fin, nat, rx->rx_proto, - (u_int)rr->rr_v3.xu_port) != 0) - return(-1); - break; - case RPCB_RES_LIST: - if (!RPCB_BUF_GEQ(rm, p, 4)) - return(-1); - /* rpcb_entry_list_ptr */ - switch(B(p)) - { - case 0: - return(0); - /*NOTREACHED*/ - break; - case 1: - break; - default: - return(-1); - } - rl = &rr->rr_v4; - rl->rl_list = p++; - cnt = 0; - - for(;;) { - re = &rl->rl_entries[rl->rl_cnt]; - if (ippr_rpcb_getuaddr(rm, &re->re_maddr, &p) != 0) - return(-1); - if (ippr_rpcb_getproto(rm, &re->re_netid, &p) != 0) - return(-1); - /* re_semantics & re_pfamily length */ - if (!RPCB_BUF_GEQ(rm, p, 12)) - return(-1); - p++; /* Skipping re_semantics. */ - xdr = B(p++); - if ((xdr != 4) || strncmp((char *)p, "inet", 4)) - return(-1); - p++; - if (ippr_rpcb_getproto(rm, &re->re_proto, &p) != 0) - return(-1); - if (!RPCB_BUF_GEQ(rm, p, 4)) - return(-1); - re->re_more = p; - if (B(re->re_more) > 1) /* 0,1 only legal values */ - return(-1); - ++rl->rl_cnt; - ++cnt; - if (B(re->re_more) == 0) - break; - /* Replies in max out at 2; TCP and/or UDP */ - if (cnt > 2) - return(-1); - p++; - } - - 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, - re->re_proto.xp_proto, - (u_int)re->re_maddr.xu_port); - if (rv != 0) - return(-1); - } - break; - default: - /*CONSTANTCONDITION*/ - IPF_PANIC(1, ("illegal rx_type %d", rx->rx_type)); - } - - return(1); -} - -/* -------------------------------------------------------------------- */ -/* Function: ippr_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) - rpcb_session_t *rs; - u_32_t xid; -{ - rpcb_xact_t *rx; - - if (rs->rs_rxlist == NULL) - return(NULL); - - for (rx = rs->rs_rxlist; rx != NULL; rx = rx->rx_next) - if (rx->rx_xid == xid) - break; - - return(rx); -} - -/* -------------------------------------------------------------------- */ -/* Function: ippr_rpcb_deref */ -/* Returns: (void) */ -/* Parameters: rs(I) - pointer to RPCB session */ -/* rx(I) - pointer to RPC transaction struct to remove */ -/* force(I) - indicates to delete entry regardless of */ -/* reference count */ -/* Locking: rs->rs_rxlock must be held write only */ -/* */ -/* Free the RPCB transaction record rx from the chain of entries. */ -/* -------------------------------------------------------------------- */ -static void -ippr_rpcb_deref(rs, rx) - rpcb_session_t *rs; - rpcb_xact_t *rx; -{ - rs = rs; /* LINT */ - - if (rx == NULL) - return; - - if (--rx->rx_ref != 0) - return; - - if (rx->rx_next != NULL) - rx->rx_next->rx_pnext = rx->rx_pnext; - - *rx->rx_pnext = rx->rx_next; - - KFREE(rx); - - --rpcbcnt; -} - -/* -------------------------------------------------------------------- */ -/* Function: ippr_rpcb_getproto */ -/* Returns: int - -1 == illegal protocol/netid, */ -/* 0 == legal protocol/netid */ -/* Parameters: rm(I) - pointer to RPC message structure */ -/* xp(I) - pointer to netid structure */ -/* p(IO) - pointer to location within packet buffer */ -/* */ -/* Decode netid/proto stored at p and record its numeric value. */ -/* -------------------------------------------------------------------- */ -static int -ippr_rpcb_getproto(rm, xp, p) - rpc_msg_t *rm; - xdr_proto_t *xp; - u_32_t **p; -{ - u_int len; - - /* Must have 4 bytes for length & 4 bytes for "tcp" or "udp". */ - if (!RPCB_BUF_GEQ(rm, p, 8)) - return(-1); - - xp->xp_xslen = (*p)++; - xp->xp_xsstr = (char *)*p; - - /* Test the string length. */ - len = B(xp->xp_xslen); - if (len != 3) - return(-1); - - /* Test the actual string & record the protocol accordingly. */ - if (!strncmp((char *)xp->xp_xsstr, "tcp\0", 4)) - xp->xp_proto = IPPROTO_TCP; - else if (!strncmp((char *)xp->xp_xsstr, "udp\0", 4)) - xp->xp_proto = IPPROTO_UDP; - else { - return(-1); - } - - /* Advance past the string. */ - (*p)++; - - return(0); -} - -/* -------------------------------------------------------------------- */ -/* Function: ippr_rpcb_getnat */ -/* Returns: int -- -1 == failed to create table entries, */ -/* 0 == success */ -/* Parameters: fin(I) - pointer to packet information */ -/* nat(I) - pointer to NAT table entry */ -/* proto(I) - transport protocol for new entries */ -/* port(I) - new port to use w/ wildcard table entries */ -/* */ -/* Create state and NAT entries to handle an anticipated connection */ -/* attempt between RPC client and server. */ -/* -------------------------------------------------------------------- */ -static int -ippr_rpcb_getnat(fin, nat, proto, port) - fr_info_t *fin; - nat_t *nat; - u_int proto; - u_int port; -{ - ipnat_t *ipn, ipnat; - tcphdr_t tcp; - ipstate_t *is; - fr_info_t fi; - nat_t *natl; - int nflags; - - ipn = nat->nat_ptr; - - /* Generate dummy fr_info */ - bcopy((char *)fin, (char *)&fi, sizeof(fi)); - 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; - - bzero((char *)&tcp, sizeof(tcp)); - tcp.th_dport = htons(port); - - if (proto == IPPROTO_TCP) { - tcp.th_win = htons(8192); - TCP_OFF_A(&tcp, sizeof(tcphdr_t) >> 2); - fi.fin_dlen = sizeof(tcphdr_t); - tcp.th_flags = TH_SYN; - nflags = NAT_TCP; - } else { - fi.fin_dlen = sizeof(udphdr_t); - nflags = NAT_UDP; - } - - nflags |= SI_W_SPORT|NAT_SEARCH; - fi.fin_dp = &tcp; - fi.fin_plen = fi.fin_hlen + fi.fin_dlen; - - /* - * Search for existing NAT & state entries. Pay close attention to - * mutexes / locks grabbed from lookup routines, as not doing so could - * lead to bad things. - * - * 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); - if (is != NULL) - RWLOCK_EXIT(&ipf_state); - - RWLOCK_EXIT(&ipf_nat); - - WRITE_ENTER(&ipf_nat); - natl = nat_inlookup(&fi, nflags, proto, fi.fin_src, fi.fin_dst); - - if ((natl != NULL) && (is != NULL)) { - MUTEX_DOWNGRADE(&ipf_nat); - return(0); - } - - /* Slightly modify the following structures for actual use in creating - * NAT and/or state entries. We're primarily concerned with stripping - * flags that may be detrimental to the creation process or simply - * shouldn't be associated with a table entry. - */ - fi.fin_fr = &rpcbfr; - fi.fin_flx &= ~FI_IGNORE; - nflags &= ~NAT_SEARCH; - - if (natl == NULL) { - /* 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? - */ - /* Generate template/bogus NAT rule. */ - 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_space = 1; - ipn->in_ippip = 1; - if (ipn->in_flags & IPN_FILTER) { - ipn->in_scmp = 0; - ipn->in_dcmp = 0; - } - *ipn->in_plabel = '\0'; - - /* Create NAT entry. return NULL if this fails. */ - natl = nat_new(&fi, ipn, NULL, nflags|SI_CLONE|NAT_SLAVE, - NAT_INBOUND); - - bcopy((char *)&ipnat, (char *)ipn, sizeof(ipnat)); - - if (natl == NULL) { - MUTEX_DOWNGRADE(&ipf_nat); - return(-1); - } - - ipn->in_use++; - (void) nat_proto(&fi, natl, nflags); - nat_update(&fi, natl, natl->nat_ptr); - } - MUTEX_DOWNGRADE(&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) { - /* - * XXX nat_delete is private to ip_nat.c. Should - * check w/ Darren about this one. - * - * nat_delete(natl, NL_EXPIRE); - */ - return(-1); - } - if (fi.fin_state != NULL) - fr_statederef(&fi, (ipstate_t **)&fi.fin_state); - } - - return(0); -} - -/* -------------------------------------------------------------------- */ -/* Function: ippr_rpcb_modv3 */ -/* Returns: int -- change in packet length */ -/* Parameters: fin(I) - pointer to packet information */ -/* nat(I) - pointer to NAT session */ -/* rm(I) - pointer to RPC message structure */ -/* m(I) - pointer to mbuf chain */ -/* off(I) - offset within mbuf chain */ -/* */ -/* Write a new universal address string to this packet, adjusting */ -/* lengths as necessary. */ -/* -------------------------------------------------------------------- */ -static int -ippr_rpcb_modv3(fin, nat, rm, m, off) - fr_info_t *fin; - nat_t *nat; - rpc_msg_t *rm; - mb_t *m; - u_int off; -{ - u_int len, xlen, pos, bogo; - rpc_resp_t *rr; - char uaddr[24]; - char *i, *p; - int diff; - - rr = &rm->rm_resp; - i = (char *)&nat->nat_outip.s_addr; - p = (char *)&rr->rr_v3.xu_port; - - /* Form new string. */ - bzero(uaddr, sizeof(uaddr)); /* Just in case we need padding. */ -#if defined(SNPRINTF) && defined(_KERNEL) - SNPRINTF(uaddr, sizeof(uaddr), -#else - (void) sprintf(uaddr, -#endif - "%u.%u.%u.%u.%u.%u", i[0] & 0xff, i[1] & 0xff, - i[2] & 0xff, i[3] & 0xff, p[0] & 0xff, p[1] & 0xff); - len = strlen(uaddr); - xlen = XDRALIGN(len); - - /* Determine mbuf offset to write to. */ - pos = (char *)rr->rr_v3.xu_xslen - rm->rm_msgbuf; - off += pos; - - /* Write new string length. */ - bogo = htonl(len); - COPYBACK(m, off, 4, (caddr_t)&bogo); - off += 4; - - /* Write new string. */ - COPYBACK(m, off, xlen, uaddr); - - /* Determine difference in data lengths. */ - diff = xlen - XDRALIGN(B(rr->rr_v3.xu_xslen)); - - /* - * If our new string has a different length, make necessary - * adjustments. - */ - if (diff != 0) - ippr_rpcb_fixlen(fin, diff); - - return(diff); -} - -/* -------------------------------------------------------------------- */ -/* Function: ippr_rpcb_modv4 */ -/* Returns: int -- change in packet length */ -/* Parameters: fin(I) - pointer to packet information */ -/* nat(I) - pointer to NAT session */ -/* rm(I) - pointer to RPC message structure */ -/* m(I) - pointer to mbuf chain */ -/* off(I) - offset within mbuf chain */ -/* */ -/* Write new rpcb_entry list, adjusting lengths as necessary. */ -/* -------------------------------------------------------------------- */ -static int -ippr_rpcb_modv4(fin, nat, rm, m, off) - fr_info_t *fin; - nat_t *nat; - rpc_msg_t *rm; - mb_t *m; - u_int off; -{ - u_int len, xlen, pos, bogo; - rpcb_listp_t *rl; - rpcb_entry_t *re; - rpc_resp_t *rr; - char uaddr[24]; - int diff, cnt; - char *i, *p; - - diff = 0; - rr = &rm->rm_resp; - rl = &rr->rr_v4; - - i = (char *)&nat->nat_outip.s_addr; - - /* Determine mbuf offset to write to. */ - re = &rl->rl_entries[0]; - pos = (char *)re->re_maddr.xu_xslen - rm->rm_msgbuf; - off += pos; - - for (cnt = 0; cnt < rl->rl_cnt; cnt++) { - re = &rl->rl_entries[cnt]; - p = (char *)&re->re_maddr.xu_port; - - /* Form new string. */ - bzero(uaddr, sizeof(uaddr)); /* Just in case we need - padding. */ -#if defined(SNPRINTF) && defined(_KERNEL) - SNPRINTF(uaddr, sizeof(uaddr), -#else - (void) sprintf(uaddr, -#endif - "%u.%u.%u.%u.%u.%u", i[0] & 0xff, - i[1] & 0xff, i[2] & 0xff, i[3] & 0xff, - p[0] & 0xff, p[1] & 0xff); - len = strlen(uaddr); - xlen = XDRALIGN(len); - - /* Write new string length. */ - bogo = htonl(len); - COPYBACK(m, off, 4, (caddr_t)&bogo); - off += 4; - - /* Write new string. */ - COPYBACK(m, off, xlen, uaddr); - off += xlen; - - /* Record any change in length. */ - diff += xlen - XDRALIGN(B(re->re_maddr.xu_xslen)); - - /* If the length changed, copy back the rest of this entry. */ - len = ((char *)re->re_more + 4) - - (char *)re->re_netid.xp_xslen; - if (diff != 0) { - COPYBACK(m, off, len, (caddr_t)re->re_netid.xp_xslen); - } - off += len; - } - - /* - * If our new string has a different length, make necessary - * adjustments. - */ - if (diff != 0) - ippr_rpcb_fixlen(fin, diff); - - return(diff); -} - - -/* -------------------------------------------------------------------- */ -/* Function: ippr_rpcb_fixlen */ -/* Returns: (void) */ -/* Parameters: fin(I) - pointer to packet information */ -/* len(I) - change in packet length */ -/* */ -/* Adjust various packet related lengths held in structure and packet */ -/* header fields. */ -/* -------------------------------------------------------------------- */ -static void -ippr_rpcb_fixlen(fin, len) - fr_info_t *fin; - int len; -{ - udphdr_t *udp; - - 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; -} - -#undef B diff --git a/contrib/ipfilter/ip_scan.c b/contrib/ipfilter/ip_scan.c deleted file mode 100644 index b36fccf..0000000 --- a/contrib/ipfilter/ip_scan.c +++ /dev/null @@ -1,594 +0,0 @@ -/* $FreeBSD$ */ - -/* - * Copyright (C) 1995-2001 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 <sys/param.h> -#if defined(__hpux) && (HPUXREV >= 1111) && !defined(_KERNEL) -# include <sys/kern_svcs.h> -#endif -#include <sys/types.h> -#include <sys/time.h> -#include <sys/errno.h> -#if !defined(_KERNEL) -# include <stdlib.h> -# include <string.h> -# define _KERNEL -# ifdef __OpenBSD__ -struct file; -# endif -# include <sys/uio.h> -# undef _KERNEL -#else -# include <sys/systm.h> -# if !defined(__svr4__) && !defined(__SVR4) -# include <sys/mbuf.h> -# endif -#endif -#include <sys/socket.h> -#if !defined(__hpux) && !defined(__osf__) && !defined(linux) -# include <sys/ioccom.h> -#endif -#ifdef __FreeBSD__ -# include <sys/filio.h> -# include <sys/malloc.h> -#else -# include <sys/ioctl.h> -#endif - -#include <netinet/in.h> -#include <netinet/in_systm.h> -#include <netinet/ip.h> -#include <netinet/tcp.h> - -#include <net/if.h> - - -#include "netinet/ip_compat.h" -#include "netinet/ip_fil.h" -#include "netinet/ip_state.h" -#include "netinet/ip_scan.h" -/* END OF INCLUDES */ - -#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.2 2005/01/18 10:13:16 darrenr Exp"; -#endif - -#ifdef IPFILTER_SCAN /* endif at bottom of file */ - - -ipscan_t *ipsc_list = NULL, - *ipsc_tail = NULL; -ipscanstat_t ipsc_stat; -# ifdef USE_MUTEXES -ipfrwlock_t ipsc_rwlock; -# endif - -# ifndef isalpha -# define isalpha(x) (((x) >= 'A' && 'Z' >= (x)) || \ - ((x) >= 'a' && 'z' >= (x))) -# 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 ipsc_init() -{ - RWLOCK_INIT(&ipsc_rwlock, "ip scan rwlock"); - return 0; -} - - -void fr_scanunload() -{ - RW_DESTROY(&ipsc_rwlock); -} - - -int ipsc_add(data) -caddr_t data; -{ - ipscan_t *i, *isc; - int err; - - KMALLOC(isc, ipscan_t *); - if (!isc) - return ENOMEM; - - err = copyinptr(data, isc, sizeof(*isc)); - if (err) - return err; - - WRITE_ENTER(&ipsc_rwlock); - - i = ipsc_lookup(isc->ipsc_tag); - if (i) { - RWLOCK_EXIT(&ipsc_rwlock); - KFREE(isc); - return EEXIST; - } - - if (ipsc_tail) { - ipsc_tail->ipsc_next = isc; - isc->ipsc_pnext = &ipsc_tail->ipsc_next; - ipsc_tail = isc; - } else { - ipsc_list = isc; - ipsc_tail = isc; - isc->ipsc_pnext = &ipsc_list; - } - isc->ipsc_next = NULL; - - isc->ipsc_hits = 0; - isc->ipsc_fref = 0; - isc->ipsc_sref = 0; - isc->ipsc_active = 0; - - ipsc_stat.iscs_entries++; - RWLOCK_EXIT(&ipsc_rwlock); - return 0; -} - - -int ipsc_delete(data) -caddr_t data; -{ - ipscan_t isc, *i; - int err; - - err = copyinptr(data, &isc, sizeof(isc)); - if (err) - return err; - - WRITE_ENTER(&ipsc_rwlock); - - i = ipsc_lookup(isc.ipsc_tag); - if (i == NULL) - err = ENOENT; - else { - if (i->ipsc_fref) { - RWLOCK_EXIT(&ipsc_rwlock); - return EBUSY; - } - - *i->ipsc_pnext = i->ipsc_next; - if (i->ipsc_next) - i->ipsc_next->ipsc_pnext = i->ipsc_pnext; - else { - if (i->ipsc_pnext == &ipsc_list) - ipsc_tail = NULL; - else - ipsc_tail = *(*i->ipsc_pnext)->ipsc_pnext; - } - - ipsc_stat.iscs_entries--; - KFREE(i); - } - RWLOCK_EXIT(&ipsc_rwlock); - return err; -} - - -struct ipscan *ipsc_lookup(tag) -char *tag; -{ - ipscan_t *i; - - for (i = ipsc_list; i; i = i->ipsc_next) - if (!strcmp(i->ipsc_tag, tag)) - return i; - return NULL; -} - - -int ipsc_attachfr(fr) -struct frentry *fr; -{ - ipscan_t *i; - - if (fr->fr_isctag[0]) { - READ_ENTER(&ipsc_rwlock); - i = ipsc_lookup(fr->fr_isctag); - if (i != NULL) { - ATOMIC_INC32(i->ipsc_fref); - } - RWLOCK_EXIT(&ipsc_rwlock); - if (i == NULL) - return ENOENT; - fr->fr_isc = i; - } - return 0; -} - - -int ipsc_attachis(is) -struct ipstate *is; -{ - frentry_t *fr; - ipscan_t *i; - - READ_ENTER(&ipsc_rwlock); - fr = is->is_rule; - if (fr) { - i = fr->fr_isc; - if (!i || (i != (ipscan_t *)-1)) { - is->is_isc = i; - if (i) { - ATOMIC_INC32(i->ipsc_sref); - if (i->ipsc_clen) - is->is_flags |= IS_SC_CLIENT; - else - is->is_flags |= IS_SC_MATCHC; - if (i->ipsc_slen) - is->is_flags |= IS_SC_SERVER; - else - is->is_flags |= IS_SC_MATCHS; - } else - is->is_flags |= (IS_SC_CLIENT|IS_SC_SERVER); - } - } - RWLOCK_EXIT(&ipsc_rwlock); - return 0; -} - - -int ipsc_detachfr(fr) -struct frentry *fr; -{ - ipscan_t *i; - - i = fr->fr_isc; - if (i != NULL) { - ATOMIC_DEC32(i->ipsc_fref); - } - return 0; -} - - -int ipsc_detachis(is) -struct ipstate *is; -{ - ipscan_t *i; - - READ_ENTER(&ipsc_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); - return 0; -} - - -/* - * 'string' compare for scanning - */ -int ipsc_matchstr(sp, str, n) -sinfo_t *sp; -char *str; -int n; -{ - char *s, *t, *up; - int i = n; - - if (i > sp->s_len) - i = sp->s_len; - up = str; - - for (s = sp->s_txt, t = sp->s_msk; i; i--, s++, t++, up++) - switch ((int)*t) - { - case '.' : - if (*s != *up) - return 1; - break; - case '?' : - if (!ISALPHA(*up) || ((*s & 0x5f) != (*up & 0x5f))) - return 1; - break; - case '*' : - break; - } - return 0; -} - - -/* - * 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 i, j, k, n, ret = 0, flags; - - flags = is->is_flags; - - /* - * If we've already matched more than what is on offer, then - * assume we have a better match already and forget this one. - */ - if (maxm != NULL) { - if (isc->ipsc_clen < maxm[0]) - return 0; - if (isc->ipsc_slen < maxm[1]) - return 0; - j = maxm[0]; - k = maxm[1]; - } else { - j = 0; - k = 0; - } - - if (!isc->ipsc_clen) - ret = 1; - else if (((flags & (IS_SC_MATCHC|IS_SC_CLIENT)) == IS_SC_CLIENT) && - cl && isc->ipsc_clen) { - 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)) { - i++; - ret |= 1; - if (n > j) - j = n; - } - } - } - - if (!isc->ipsc_slen) - ret |= 2; - else if (((flags & (IS_SC_MATCHS|IS_SC_SERVER)) == IS_SC_SERVER) && - sl && isc->ipsc_slen) { - 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)) { - i++; - ret |= 2; - if (n > k) - k = n; - } - } - } - - if (maxm && (ret == 3)) { - maxm[0] = j; - maxm[1] = k; - } - return ret; -} - - -int ipsc_match(is) -ipstate_t *is; -{ - int i, j, k, n, cl, sl, maxm[2]; - ipscan_t *isc, *lm; - tcpdata_t *t; - - for (cl = 0, n = is->is_smsk[0]; n & 1; n >>= 1) - cl++; - for (sl = 0, n = is->is_smsk[1]; n & 1; n >>= 1) - sl++; - - j = 0; - isc = is->is_isc; - if (isc != NULL) { - /* - * Known object to scan for. - */ - i = ipsc_matchisc(isc, is, cl, sl, NULL); - if (i & 1) { - is->is_flags |= IS_SC_MATCHC; - is->is_flags &= ~IS_SC_CLIENT; - } else if (cl >= isc->ipsc_clen) - is->is_flags &= ~IS_SC_CLIENT; - if (i & 2) { - is->is_flags |= IS_SC_MATCHS; - is->is_flags &= ~IS_SC_SERVER; - } else if (sl >= isc->ipsc_slen) - is->is_flags &= ~IS_SC_SERVER; - } else { - i = 0; - 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); - if (i) { - /* - * We only want to remember the best match - * and the number of times we get a best - * match. - */ - if ((j == 3) && (i < 3)) - continue; - if ((i == 3) && (j != 3)) - k = 1; - else - k++; - j = i; - lm = isc; - } - } - if (k == 1) - isc = lm; - - /* - * No matches or partial matches, so reset the respective - * search flag. - */ - if (!(j & 1)) - is->is_flags &= ~IS_SC_CLIENT; - - if (!(j & 2)) - is->is_flags &= ~IS_SC_SERVER; - - /* - * If we found the best match, then set flags appropriately. - */ - if ((j == 3) && (k == 1)) { - is->is_flags &= ~(IS_SC_SERVER|IS_SC_CLIENT); - is->is_flags |= (IS_SC_MATCHS|IS_SC_MATCHC); - } - } - - /* - * If the acknowledged side of a connection has moved past the data in - * which we are interested, then reset respective flag. - */ - t = &is->is_tcp.ts_data[0]; - if (t->td_end > is->is_s0[0] + 15) - is->is_flags &= ~IS_SC_CLIENT; - - t = &is->is_tcp.ts_data[1]; - if (t->td_end > is->is_s0[1] + 15) - is->is_flags &= ~IS_SC_SERVER; - - /* - * Matching complete ? - */ - j = ISC_A_NONE; - if ((is->is_flags & IS_SC_MATCHALL) == IS_SC_MATCHALL) { - j = isc->ipsc_action; - ipsc_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))) { - /* - * Matching failed... - */ - j = isc->ipsc_else; - ipsc_stat.iscs_else++; - } - - switch (j) - { - case ISC_A_CLOSE : - /* - * If as a result of a successful match we are to - * close a connection, change the "keep state" info. - * to block packets and generate TCP RST's. - */ - is->is_pass &= ~FR_RETICMP; - is->is_pass |= FR_RETRST; - break; - default : - break; - } - - return i; -} - - -/* - * check if a packet matches what we're scanning for - */ -int ipsc_packet(fin, is) -fr_info_t *fin; -ipstate_t *is; -{ - int i, j, rv, dlen, off, thoff; - u_32_t seq, s0; - tcphdr_t *tcp; - - rv = !IP6_EQ(&fin->fin_fi.fi_src, &is->is_src); - tcp = fin->fin_dp; - seq = ntohl(tcp->th_seq); - - if (!is->is_s0[rv]) - return 1; - - /* - * check if this packet has more data that falls within the first - * 16 bytes sent in either direction. - */ - s0 = is->is_s0[rv]; - off = seq - s0; - if ((off > 15) || (off < 0)) - return 1; - thoff = TCP_OFF(tcp) << 2; - dlen = fin->fin_dlen - thoff; - if (dlen <= 0) - return 1; - if (dlen > 16) - dlen = 16; - if (off + dlen > 16) - dlen = 16 - off; - - j = 0xffff >> (16 - dlen); - i = (0xffff & j) << off; -#ifdef _KERNEL - COPYDATA(*(mb_t **)fin->fin_mp, fin->fin_hlen + thoff, dlen, - (caddr_t)is->is_sbuf[rv] + off); -#endif - is->is_smsk[rv] |= i; - for (j = 0, i = is->is_smsk[rv]; i & 1; i >>= 1) - j++; - if (j == 0) - return 1; - - (void) ipsc_match(is); -#if 0 - /* - * There is the potential here for plain text passwords to get - * buffered and stored for some time... - */ - if (!(is->is_flags & IS_SC_CLIENT)) - bzero(is->is_sbuf[0], sizeof(is->is_sbuf[0])); - if (!(is->is_flags & IS_SC_SERVER)) - bzero(is->is_sbuf[1], sizeof(is->is_sbuf[1])); -#endif - return 0; -} - - -int fr_scan_ioctl(data, cmd, mode) -caddr_t data; -ioctlcmd_t cmd; -int mode; -{ - ipscanstat_t ipscs; - int err = 0; - - switch (cmd) - { - case SIOCADSCA : - err = ipsc_add(data); - break; - case SIOCRMSCA : - err = ipsc_delete(data); - break; - case SIOCGSCST : - bcopy((char *)&ipsc_stat, (char *)&ipscs, sizeof(ipscs)); - ipscs.iscs_list = ipsc_list; - BCOPYOUT(&ipscs, data, sizeof(ipscs)); - break; - default : - err = EINVAL; - break; - } - - return err; -} -#endif /* IPFILTER_SCAN */ diff --git a/contrib/ipfilter/ip_scan.h b/contrib/ipfilter/ip_scan.h deleted file mode 100644 index 8891367..0000000 --- a/contrib/ipfilter/ip_scan.h +++ /dev/null @@ -1,108 +0,0 @@ -/* $FreeBSD$ */ - -/* - * Copyright (C) 1993-2001 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 2003/07/25 22:05:01 darrenr Exp - */ - -#ifndef __IP_SCAN_H__ -#define __IP_SCAN_H__ 1 - -#ifdef sun -# include <sys/ioccom.h> -#endif - -#define IPSCAN_NAME "/dev/ipscan" -#define IPL_SCAN IPSCAN_NAME -#define ISC_TLEN 16 - - -struct fr_info; -struct frentry; -struct ip; -struct ipstate; - - -#if defined(__STDC__) || defined(__GNUC__) -# define SIOCADSCA _IOWR('r', 60, struct ipscan *) -# define SIOCRMSCA _IOWR('r', 61, struct ipscan *) -# define SIOCGSCST _IOWR('r', 62, struct ipscan *) -#else -# define SIOCADSCA _IOWR(r, 60, struct ipscan *) -# define SIOCRMSCA _IOWR(r, 61, struct ipscan *) -# define SIOCGSCST _IOWR(r, 62, struct ipscan *) -#endif - -struct action { - int act_val; /* what to do */ - struct in_addr act_ip; /* redirect IP# */ - u_short act_port; /* redirect port number */ - int act_else; /* what to do */ - struct in_addr act_eip; /* redirect IP# */ - u_short act_eport; /* redirect port number */ -}; - - -typedef struct sinfo { - char s_txt[ISC_TLEN]; /* text to match */ - char s_msk[ISC_TLEN]; /* mask of the above to check */ - int s_len; /* length of server text */ -} sinfo_t; - - -typedef struct ipscan { - struct ipscan *ipsc_next; - struct ipscan **ipsc_pnext; - char ipsc_tag[ISC_TLEN]; /* table entry protocol tag */ - sinfo_t ipsc_si[2]; /* client/server side information */ - int ipsc_hits; /* times this has been matched */ - int ipsc_active; /* # of active matches */ - int ipsc_fref; /* # of references from filter rules */ - int ipsc_sref; /* # of references from state entries */ - struct action ipsc_act; -} ipscan_t; - - -#define ipsc_cl ipsc_si[0] -#define ipsc_sl ipsc_si[1] -#define ipsc_ctxt ipsc_cl.s_txt -#define ipsc_cmsk ipsc_cl.s_msk -#define ipsc_clen ipsc_cl.s_len -#define ipsc_stxt ipsc_sl.s_txt -#define ipsc_smsk ipsc_sl.s_msk -#define ipsc_slen ipsc_sl.s_len -#define ipsc_action ipsc_act.act_val -#define ipsc_ip ipsc_act.act_ip -#define ipsc_port ipsc_act.act_port -#define ipsc_else ipsc_act.act_else -#define ipsc_eip ipsc_act.act_eip -#define ipsc_eport ipsc_act.act_eport - -#define ISC_A_NONE 0 -#define ISC_A_TRACK 1 -#define ISC_A_CLOSE 2 -#define ISC_A_REDIRECT 3 - - -typedef struct ipscanstat { - struct ipscan *iscs_list; - u_long iscs_acted; - u_long iscs_else; - int iscs_entries; -} ipscanstat_t; - - -extern int fr_scan_ioctl __P((caddr_t, ioctlcmd_t, int)); -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)); - -#endif /* __IP_SCAN_H__ */ diff --git a/contrib/ipfilter/ip_sync.c b/contrib/ipfilter/ip_sync.c deleted file mode 100644 index 40a027e..0000000 --- a/contrib/ipfilter/ip_sync.c +++ /dev/null @@ -1,1001 +0,0 @@ -/* $FreeBSD$ */ - -/* - * Copyright (C) 1995-1998 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 <sys/errno.h> -#include <sys/types.h> -#include <sys/param.h> -#include <sys/file.h> -#if !defined(_KERNEL) && !defined(__KERNEL__) -# include <stdio.h> -# include <stdlib.h> -# include <string.h> -# define _KERNEL -# define KERNEL -# ifdef __OpenBSD__ -struct file; -# endif -# include <sys/uio.h> -# undef _KERNEL -# undef KERNEL -#else -# include <sys/systm.h> -# if !defined(__SVR4) && !defined(__svr4__) -# include <sys/mbuf.h> -# endif -#endif -#if defined(__NetBSD__) && (__NetBSD_Version__ >= 104000000) -# include <sys/proc.h> -#endif -#if defined(_KERNEL) && (__FreeBSD_version >= 220000) -# include <sys/filio.h> -# include <sys/fcntl.h> -# if (__FreeBSD_version >= 300000) && !defined(IPFILTER_LKM) -# include "opt_ipfilter.h" -# endif -#else -# include <sys/ioctl.h> -#endif -#include <sys/time.h> -#if !defined(linux) -# include <sys/protosw.h> -#endif -#include <sys/socket.h> -#if defined(__SVR4) || defined(__svr4__) -# include <sys/filio.h> -# include <sys/byteorder.h> -# ifdef _KERNEL -# include <sys/dditypes.h> -# endif -# include <sys/stream.h> -# include <sys/kmem.h> -#endif - -#include <net/if.h> -#ifdef sun -# include <net/af.h> -#endif -#include <net/route.h> -#include <netinet/in.h> -#include <netinet/in_systm.h> -#include <netinet/ip.h> -#include <netinet/tcp.h> -#if !defined(linux) -# include <netinet/ip_var.h> -#endif -#if !defined(__hpux) && !defined(linux) -# include <netinet/tcp_fsm.h> -#endif -#include <netinet/udp.h> -#include <netinet/ip_icmp.h> -#include "netinet/ip_compat.h" -#include <netinet/tcpip.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_sync.h" -#ifdef USE_INET6 -#include <netinet/icmp6.h> -#endif -#if (__FreeBSD_version >= 300000) -# include <sys/malloc.h> -# if defined(_KERNEL) && !defined(IPFILTER_LKM) -# include <sys/libkern.h> -# include <sys/systm.h> -# endif -#endif -/* END OF INCLUDES */ - -#if !defined(lint) -static const char rcsid[] = "@(#)Id: ip_sync.c,v 2.40.2.3 2005/02/18 13:06:29 darrenr Exp"; -#endif - -#define SYNC_STATETABSZ 256 -#define SYNC_NATTABSZ 256 - -#ifdef IPFILTER_SYNC -ipfmutex_t ipf_syncadd, ipsl_mutex; -ipfrwlock_t ipf_syncstate, ipf_syncnat; -#if SOLARIS && defined(_KERNEL) -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(sparc) && !defined(__hppa) -void ipfsync_tcporder __P((int, struct tcpdata *)); -void ipfsync_natorder __P((int, struct nat *)); -void ipfsync_storder __P((int, struct ipstate *)); -# endif - - -/* ------------------------------------------------------------------------ */ -/* Function: ipfsync_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() -{ - 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 - - bzero((char *)syncnattab, sizeof(syncnattab)); - bzero((char *)syncstatetab, sizeof(syncstatetab)); - - return 0; -} - - -# if !defined(sparc) && !defined(__hppa) -/* ------------------------------------------------------------------------ */ -/* Function: ipfsync_tcporder */ -/* Returns: Nil */ -/* Parameters: way(I) - direction of byte order conversion. */ -/* td(IO) - pointer to data to be converted. */ -/* */ -/* 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; -{ - if (way) { - td->td_maxwin = htons(td->td_maxwin); - td->td_end = htonl(td->td_end); - td->td_maxend = htonl(td->td_maxend); - } else { - td->td_maxwin = ntohs(td->td_maxwin); - td->td_end = ntohl(td->td_end); - td->td_maxend = ntohl(td->td_maxend); - } -} - - -/* ------------------------------------------------------------------------ */ -/* Function: ipfsync_natorder */ -/* Returns: Nil */ -/* Parameters: way(I) - direction of byte order conversion. */ -/* nat(IO) - pointer to data to be converted. */ -/* */ -/* 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; -{ - if (way) { - n->nat_age = htonl(n->nat_age); - n->nat_flags = htonl(n->nat_flags); - n->nat_ipsumd = htonl(n->nat_ipsumd); - n->nat_use = htonl(n->nat_use); - n->nat_dir = htonl(n->nat_dir); - } else { - n->nat_age = ntohl(n->nat_age); - n->nat_flags = ntohl(n->nat_flags); - n->nat_ipsumd = ntohl(n->nat_ipsumd); - n->nat_use = ntohl(n->nat_use); - n->nat_dir = ntohl(n->nat_dir); - } -} - - -/* ------------------------------------------------------------------------ */ -/* Function: ipfsync_storder */ -/* Returns: Nil */ -/* Parameters: way(I) - direction of byte order conversion. */ -/* ips(IO) - pointer to data to be converted. */ -/* */ -/* 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; -{ - ipfsync_tcporder(way, &ips->is_tcp.ts_data[0]); - ipfsync_tcporder(way, &ips->is_tcp.ts_data[1]); - - if (way) { - ips->is_hv = htonl(ips->is_hv); - ips->is_die = htonl(ips->is_die); - ips->is_pass = htonl(ips->is_pass); - ips->is_flags = htonl(ips->is_flags); - ips->is_opt = htonl(ips->is_opt); - ips->is_optmsk = htonl(ips->is_optmsk); - ips->is_sec = htons(ips->is_sec); - ips->is_secmsk = htons(ips->is_secmsk); - ips->is_auth = htons(ips->is_auth); - ips->is_authmsk = htons(ips->is_authmsk); - ips->is_s0[0] = htonl(ips->is_s0[0]); - ips->is_s0[1] = htonl(ips->is_s0[1]); - ips->is_smsk[0] = htons(ips->is_smsk[0]); - ips->is_smsk[1] = htons(ips->is_smsk[1]); - } else { - ips->is_hv = ntohl(ips->is_hv); - ips->is_die = ntohl(ips->is_die); - ips->is_pass = ntohl(ips->is_pass); - ips->is_flags = ntohl(ips->is_flags); - ips->is_opt = ntohl(ips->is_opt); - ips->is_optmsk = ntohl(ips->is_optmsk); - ips->is_sec = ntohs(ips->is_sec); - ips->is_secmsk = ntohs(ips->is_secmsk); - ips->is_auth = ntohs(ips->is_auth); - ips->is_authmsk = ntohs(ips->is_authmsk); - ips->is_s0[0] = ntohl(ips->is_s0[0]); - ips->is_s0[1] = ntohl(ips->is_s0[1]); - ips->is_smsk[0] = ntohl(ips->is_smsk[0]); - ips->is_smsk[1] = ntohl(ips->is_smsk[1]); - } -} -# else /* !defined(sparc) && !defined(__hppa) */ -# define ipfsync_tcporder(x,y) -# define ipfsync_natorder(x,y) -# define ipfsync_storder(x,y) -# endif /* !defined(sparc) && !defined(__hppa) */ - -/* enable this for debugging */ - -# ifdef _KERNEL -/* ------------------------------------------------------------------------ */ -/* Function: ipfsync_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; -{ - synchdr_t sh; - - /* - * THIS MUST BE SUFFICIENT LARGE TO STORE - * ANY POSSIBLE DATA TYPE - */ - char data[2048]; - - int err = 0; - -# if (BSD >= 199306) || defined(__FreeBSD__) || defined(__osf__) - uio->uio_rw = UIO_WRITE; -# endif - - /* Try to get bytes */ - while (uio->uio_resid > 0) { - - if (uio->uio_resid >= sizeof(sh)) { - - err = UIOMOVE((caddr_t)&sh, sizeof(sh), UIO_WRITE, uio); - - if (err) { - if (ipf_sync_debug > 2) - printf("uiomove(header) failed: %d\n", - err); - return err; - } - - /* convert to host order */ - sh.sm_magic = ntohl(sh.sm_magic); - sh.sm_len = ntohl(sh.sm_len); - sh.sm_num = ntohl(sh.sm_num); - - if (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", - "magic"); - return EINVAL; - } - - if (sh.sm_v != 4 && sh.sm_v != 6) { - if (ipf_sync_debug > 2) - printf("uiomove(header) invalid %s\n", - "protocol"); - return EINVAL; - } - - if (sh.sm_cmd > SMC_MAXCMD) { - if (ipf_sync_debug > 2) - printf("uiomove(header) invalid %s\n", - "command"); - return EINVAL; - } - - - if (sh.sm_table > SMC_MAXTBL) { - if (ipf_sync_debug > 2) - printf("uiomove(header) invalid %s\n", - "table"); - return EINVAL; - } - - } else { - /* unsufficient data, wait until next call */ - if (ipf_sync_debug > 2) - printf("uiomove(header) insufficient data"); - return EAGAIN; - } - - - /* - * 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) - printf("uiomove(data zero length %s\n", - "not supported"); - return EINVAL; - } - - if (uio->uio_resid >= sh.sm_len) { - - err = UIOMOVE((caddr_t)data, sh.sm_len, UIO_WRITE, uio); - - if (err) { - if (ipf_sync_debug > 2) - printf("uiomove(data) failed: %d\n", - err); - return err; - } - - if (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); - else if (sh.sm_table == SMC_NAT) - err = ipfsync_nat(&sh, data); - if (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) - printf("uiomove(data) %s %d bytes, got %d\n", - "insufficient data, need", - sh.sm_len, uio->uio_resid); - return EAGAIN; - } - } - - /* no more data */ - return 0; -} - - -/* ------------------------------------------------------------------------ */ -/* Function: ipfsync_read */ -/* Returns: int - 0 == success, else error value. */ -/* Parameters: uio(O) - pointer to information about where to store data */ -/* */ -/* This function is called when a user program wants to read some data */ -/* 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; -{ - syncupdent_t *su; - synclogent_t *sl; - int err = 0; - - if ((uio->uio_resid & 3) || (uio->uio_resid < 8)) - return EINVAL; - -# if (BSD >= 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); - return EINTR; - } -# else -# ifdef __hpux - { - lock_t *l; - - l = get_sleep_lock(&sl_tail); - err = sleep(&sl_tail, PZERO+1); - spinunlock(l); - } -# else /* __hpux */ -# ifdef __osf__ - err = mpsleep(&sl_tail, PSUSP|PCATCH, "ipl sleep", 0, - &ipsl_mutex, MS_LOCK_SIMPLE); -# else - MUTEX_EXIT(&ipsl_mutex); - err = SLEEP(&sl_tail, "ipl sleep"); -# endif /* __osf__ */ -# endif /* __hpux */ - if (err) { - MUTEX_EXIT(&ipsl_mutex); - return err; - } -# endif /* SOLARIS */ - } - MUTEX_EXIT(&ipsl_mutex); - - READ_ENTER(&ipf_syncstate); - while ((sl_tail < sl_idx) && (uio->uio_resid > sizeof(*sl))) { - sl = synclog + sl_tail++; - err = UIOMOVE((caddr_t)sl, sizeof(*sl), UIO_READ, uio); - if (err != 0) - break; - } - - while ((su_tail < su_idx) && (uio->uio_resid > sizeof(*su))) { - su = syncupd + su_tail; - su_tail++; - err = UIOMOVE((caddr_t)su, sizeof(*su), UIO_READ, uio); - if (err != 0) - break; - 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); - return err; -} - - -/* ------------------------------------------------------------------------ */ -/* Function: ipfsync_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 */ -/* */ -/* Updates the state table according to information passed in the sync */ -/* header. As required, more data is fetched from the uio structure but */ -/* varies depending on the contents of the sync header. This function can */ -/* 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; -{ - synctcp_update_t su; - ipstate_t *is, sn; - synclist_t *sl; - frentry_t *fr; - u_int hv; - int err = 0; - - hv = sp->sm_num & (SYNC_STATETABSZ - 1); - - switch (sp->sm_cmd) - { - case SMC_CREATE : - - bcopy(data, &sn, sizeof(sn)); - KMALLOC(is, ipstate_t *); - if (is == NULL) { - err = ENOMEM; - break; - } - - KMALLOC(sl, synclist_t *); - if (sl == NULL) { - err = ENOMEM; - KFREE(is); - break; - } - - 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); - - /* - * 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); - if (fr != NULL) { - MUTEX_ENTER(&fr->fr_lock); - fr->fr_ref++; - fr->fr_statecnt++; - MUTEX_EXIT(&fr->fr_lock); - } - RWLOCK_EXIT(&ipf_mutex); - - if (ipf_sync_debug > 4) - printf("[%d] Filter rules = %p\n", sp->sm_num, fr); - - is->is_rule = fr; - is->is_sync = sl; - - sl->sl_idx = -1; - sl->sl_ips = is; - bcopy(sp, &sl->sl_hdr, sizeof(struct synchdr)); - - WRITE_ENTER(&ipf_syncstate); - WRITE_ENTER(&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); - /* - * Do not initialise the interface pointers for the state - * entry as the full complement of interface names may not - * be present. - * - * Put this state entry on its timeout queue. - */ - /*fr_setstatequeue(is, sp->sm_rev);*/ - break; - - case SMC_UPDATE : - bcopy(data, &su, sizeof(su)); - - if (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) - if (sl->sl_hdr.sm_num == sp->sm_num) - break; - if (sl == NULL) { - if (ipf_sync_debug > 1) - printf("[%d] State not found - can't update\n", - sp->sm_num); - RWLOCK_EXIT(&ipf_syncstate); - err = ENOENT; - break; - } - - READ_ENTER(&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, - sl->sl_hdr.sm_cmd, sl->sl_hdr.sm_table, - sl->sl_hdr.sm_rev); - - is = sl->sl_ips; - - MUTEX_ENTER(&is->is_lock); - switch (sp->sm_p) - { - case IPPROTO_TCP : - /* XXX FV --- shouldn't we do ntohl/htonl???? XXX */ - is->is_send = su.stu_data[0].td_end; - is->is_maxsend = su.stu_data[0].td_maxend; - is->is_maxswin = su.stu_data[0].td_maxwin; - is->is_state[0] = su.stu_state[0]; - is->is_dend = su.stu_data[1].td_end; - is->is_maxdend = su.stu_data[1].td_maxend; - is->is_maxdwin = su.stu_data[1].td_maxwin; - is->is_state[1] = su.stu_state[1]; - break; - default : - break; - } - - if (ipf_sync_debug > 6) - printf("[%d] Setting timers for state\n", sp->sm_num); - - fr_setstatequeue(is, sp->sm_rev); - - MUTEX_EXIT(&is->is_lock); - break; - - default : - err = EINVAL; - break; - } - - if (err == 0) { - RWLOCK_EXIT(&ipf_state); - RWLOCK_EXIT(&ipf_syncstate); - } - - if (ipf_sync_debug > 6) - printf("[%d] Update completed with error %d\n", - sp->sm_num, err); - - return err; -} -# endif /* _KERNEL */ - - -/* ------------------------------------------------------------------------ */ -/* Function: ipfsync_del */ -/* Returns: Nil */ -/* Parameters: sl(I) - pointer to synclist object to delete */ -/* */ -/* Deletes an object from the synclist table and free's its memory. */ -/* ------------------------------------------------------------------------ */ -void ipfsync_del(sl) -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); - KFREE(sl); -} - - -/* ------------------------------------------------------------------------ */ -/* Function: ipfsync_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 */ -/* */ -/* Updates the NAT table according to information passed in the sync */ -/* header. As required, more data is fetched from the uio structure but */ -/* varies depending on the contents of the sync header. This function can */ -/* 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; -{ - synclogent_t sle; - syncupdent_t su; - nat_t *n, *nat; - synclist_t *sl; - u_int hv = 0; - int err; - - READ_ENTER(&ipf_syncstate); - - switch (sp->sm_cmd) - { - case SMC_CREATE : - bcopy(data, &sle, sizeof(sle)); - - KMALLOC(n, nat_t *); - if (n == NULL) { - err = ENOMEM; - break; - } - - KMALLOC(sl, synclist_t *); - if (sl == NULL) { - err = ENOMEM; - KFREE(n); - break; - } - - WRITE_ENTER(&ipf_nat); - - nat = &sle.sle_un.sleu_ipn; - 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); - n->nat_sync = sl; - - sl->sl_idx = -1; - sl->sl_ipn = n; - sl->sl_num = ntohl(sp->sm_num); - 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); - break; - - case SMC_UPDATE : - bcopy(data, &su, sizeof(su)); - - READ_ENTER(&ipf_syncstate); - for (sl = syncstatetab[hv]; (sl != NULL); sl = sl->sl_next) - if (sl->sl_hdr.sm_num == sp->sm_num) - break; - if (sl == NULL) { - err = ENOENT; - break; - } - - READ_ENTER(&ipf_nat); - - nat = sl->sl_ipn; - - MUTEX_ENTER(&nat->nat_lock); - fr_setnatqueue(nat, sl->sl_rev); - MUTEX_EXIT(&nat->nat_lock); - - RWLOCK_EXIT(&ipf_nat); - - break; - - default : - err = EINVAL; - break; - } - - RWLOCK_EXIT(&ipf_syncstate); - return 0; -} - - -/* ------------------------------------------------------------------------ */ -/* Function: ipfsync_new */ -/* Returns: synclist_t* - NULL == failure, else pointer to new synclist */ -/* data structure. */ -/* Parameters: tab(I) - type of synclist_t to create */ -/* fin(I) - pointer to packet information */ -/* ptr(I) - pointer to owning object */ -/* */ -/* 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 *sl, *ss; - synclogent_t *sle; - u_int hv, sz; - - if (sl_idx == SYNCLOG_SZ) - return NULL; - KMALLOC(sl, synclist_t *); - if (sl == NULL) - return NULL; - - MUTEX_ENTER(&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; - } - - 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. - * XXX - an attacker could lunch an DoS attack, of sorts, if they are - * the only one causing new table entries by only keeping open every - * 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); - - sl->sl_magic = htonl(SYNHDRMAGIC); - sl->sl_v = fin->fin_v; - sl->sl_p = fin->fin_p; - sl->sl_cmd = SMC_CREATE; - sl->sl_idx = -1; - sl->sl_table = tab; - sl->sl_rev = fin->fin_rev; - if (tab == SMC_STATE) { - sl->sl_ips = ptr; - sz = sizeof(*sl->sl_ips); - } else if (tab == SMC_NAT) { - sl->sl_ipn = ptr; - sz = sizeof(*sl->sl_ipn); - } else { - ptr = NULL; - sz = 0; - } - sl->sl_len = sz; - - /* - * 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++; - bcopy((char *)&sl->sl_hdr, (char *)&sle->sle_hdr, - sizeof(sle->sle_hdr)); - sle->sle_hdr.sm_num = htonl(sle->sle_hdr.sm_num); - sle->sle_hdr.sm_len = htonl(sle->sle_hdr.sm_len); - if (ptr != NULL) { - bcopy((char *)ptr, (char *)&sle->sle_un, sz); - if (tab == SMC_STATE) { - ipfsync_storder(1, &sle->sle_un.sleu_ips); - } else if (tab == SMC_NAT) { - ipfsync_natorder(1, &sle->sle_un.sleu_ipn); - } - } - MUTEX_EXIT(&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 - return sl; -} - - -/* ------------------------------------------------------------------------ */ -/* Function: ipfsync_update */ -/* Returns: Nil */ -/* Parameters: tab(I) - type of synclist_t to create */ -/* fin(I) - pointer to packet information */ -/* sl(I) - pointer to synchronisation object */ -/* */ -/* 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; -{ - synctcp_update_t *st; - syncupdent_t *slu; - ipstate_t *ips; - nat_t *nat; - - if (fin->fin_out == 0 || sl == NULL) - return; - - WRITE_ENTER(&ipf_syncstate); - MUTEX_ENTER(&ipf_syncadd); - if (sl->sl_idx == -1) { - slu = syncupd + su_idx; - sl->sl_idx = su_idx++; - bcopy((char *)&sl->sl_hdr, (char *)&slu->sup_hdr, - sizeof(slu->sup_hdr)); - slu->sup_hdr.sm_magic = htonl(SYNHDRMAGIC); - slu->sup_hdr.sm_sl = sl; - slu->sup_hdr.sm_cmd = SMC_UPDATE; - slu->sup_hdr.sm_table = tab; - slu->sup_hdr.sm_num = htonl(sl->sl_num); - slu->sup_hdr.sm_len = htonl(sizeof(struct synctcp_update)); - slu->sup_hdr.sm_rev = fin->fin_rev; -# if 0 - if (fin->fin_p == IPPROTO_TCP) { - st->stu_len[0] = 0; - st->stu_len[1] = 0; - } -# endif - } else - slu = syncupd + sl->sl_idx; - MUTEX_EXIT(&ipf_syncadd); - MUTEX_DOWNGRADE(&ipf_syncstate); - - /* - * Only TCP has complex timeouts, others just use default timeouts. - * For TCP, we only need to track the connection state and window. - */ - if (fin->fin_p == IPPROTO_TCP) { - st = &slu->sup_tcp; - if (tab == SMC_STATE) { - ips = sl->sl_ips; - st->stu_age = htonl(ips->is_die); - st->stu_data[0].td_end = ips->is_send; - st->stu_data[0].td_maxend = ips->is_maxsend; - st->stu_data[0].td_maxwin = ips->is_maxswin; - st->stu_state[0] = ips->is_state[0]; - st->stu_data[1].td_end = ips->is_dend; - st->stu_data[1].td_maxend = ips->is_maxdend; - st->stu_data[1].td_maxwin = ips->is_maxdwin; - st->stu_state[1] = ips->is_state[1]; - } else if (tab == SMC_NAT) { - nat = sl->sl_ipn; - st->stu_age = htonl(nat->nat_age); - } - } - RWLOCK_EXIT(&ipf_syncstate); - - 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 -} - - -/* ------------------------------------------------------------------------ */ -/* Function: fr_sync_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 */ -/* */ -/* This function currently does not handle any ioctls and so just returns */ -/* EINVAL on all occasions. */ -/* ------------------------------------------------------------------------ */ -int fr_sync_ioctl(data, cmd, mode) -caddr_t data; -ioctlcmd_t cmd; -int mode; -{ - return EINVAL; -} -#endif /* IPFILTER_SYNC */ diff --git a/contrib/ipfilter/ip_sync.h b/contrib/ipfilter/ip_sync.h deleted file mode 100644 index 25ad708..0000000 --- a/contrib/ipfilter/ip_sync.h +++ /dev/null @@ -1,117 +0,0 @@ -/* $FreeBSD$ */ - -/* - * Copyright (C) 1993-2001 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.2 2004/11/04 19:29:07 darrenr Exp - */ - -#ifndef __IP_SYNC_H__ -#define __IP_SYNC_H__ - -typedef struct synchdr { - u_32_t sm_magic; /* magic */ - u_char sm_v; /* version: 4,6 */ - u_char sm_p; /* protocol */ - u_char sm_cmd; /* command */ - u_char sm_table; /* NAT, STATE, etc */ - u_int sm_num; /* table entry number */ - int sm_rev; /* forward/reverse */ - int sm_len; /* length of the data section */ - struct synclist *sm_sl; /* back pointer to parent */ -} synchdr_t; - - -#define SYNHDRMAGIC 0x0FF51DE5 - -/* - * Commands - * No delete required as expirey will take care of that! - */ -#define SMC_CREATE 0 /* pass ipstate_t after synchdr_t */ -#define SMC_UPDATE 1 -#define SMC_MAXCMD 1 - -/* - * Tables - */ -#define SMC_NAT 0 -#define SMC_STATE 1 -#define SMC_MAXTBL 1 - - -/* - * Only TCP requires "more" information than just a reference to the entry - * for which an update is being made. - */ -typedef struct synctcp_update { - u_long stu_age; - tcpdata_t stu_data[2]; - int stu_state[2]; -} synctcp_update_t; - - -typedef struct synclist { - struct synclist *sl_next; - struct synclist **sl_pnext; - int sl_idx; /* update index */ - struct synchdr sl_hdr; - union { - struct ipstate *slu_ips; - struct nat *slu_ipn; - void *slu_ptr; - } sl_un; -} synclist_t; - -#define sl_ptr sl_un.slu_ptr -#define sl_ips sl_un.slu_ips -#define sl_ipn sl_un.slu_ipn -#define sl_magic sl_hdr.sm_magic -#define sl_v sl_hdr.sm_v -#define sl_p sl_hdr.sm_p -#define sl_cmd sl_hdr.sm_cmd -#define sl_rev sl_hdr.sm_rev -#define sl_table sl_hdr.sm_table -#define sl_num sl_hdr.sm_num -#define sl_len sl_hdr.sm_len - -/* - * NOTE: SYNCLOG_SZ is defined *low*. It should be the next power of two - * up for whatever number of packets per second you expect to see. Be - * warned: this index's a table of large elements (upto 272 bytes in size - * each), and thus a size of 8192, for example, results in a 2MB table. - * The lesson here is not to use small machines for running fast firewalls - * (100BaseT) in sync, where you might have upwards of 10k pps. - */ -#define SYNCLOG_SZ 256 - -typedef struct synclogent { - struct synchdr sle_hdr; - union { - struct ipstate sleu_ips; - struct nat sleu_ipn; - } sle_un; -} synclogent_t; - -typedef struct syncupdent { /* 28 or 32 bytes */ - struct synchdr sup_hdr; - struct synctcp_update sup_tcp; -} syncupdent_t; - -extern synclogent_t synclog[SYNCLOG_SZ]; - - -extern int fr_sync_ioctl __P((caddr_t, ioctlcmd_t, int)); -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)); - -#endif /* IP_SYNC */ |