Remove these files from src/contrib/ipfilter as they are already present
in src/sys/contrib/ipfilter/netinet. Makefile's reachover bits find what they need so building is unaffected. Approved by: re (dwhite)
This commit is contained in:
parent
721c3c7cc6
commit
0e6e3d9f1c
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=147548
@ -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 ?
|
||||
*/
|
@ -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
|
File diff suppressed because it is too large
Load Diff
@ -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 */
|
@ -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__ */
|
@ -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);
|
||||
}
|
@ -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 */
|
@ -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__ */
|
@ -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 */
|
@ -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__ */
|
@ -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;
|
||||
}
|
||||
}
|
File diff suppressed because it is too large
Load Diff
@ -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 */
|
@ -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__ */
|
File diff suppressed because it is too large
Load Diff
@ -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 */
|
Loading…
Reference in New Issue
Block a user