NPF: add support for IPv6-to-IPv6 Network Prefix Translation (NPTv6),
as per RFC 6296. Add a unit test. Also, bump NPF_VERSION. Thanks to S.P.Zeidler for the help with NPTv6 work!
This commit is contained in:
parent
82f6ff32b1
commit
068cee2998
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: npf.c,v 1.27 2014/02/07 23:45:22 rmind Exp $ */
|
||||
/* $NetBSD: npf.c,v 1.28 2014/02/13 03:34:41 rmind Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2010-2014 The NetBSD Foundation, Inc.
|
||||
|
@ -30,7 +30,7 @@
|
|||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: npf.c,v 1.27 2014/02/07 23:45:22 rmind Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: npf.c,v 1.28 2014/02/13 03:34:41 rmind Exp $");
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <netinet/in_systm.h>
|
||||
|
@ -802,7 +802,7 @@ npf_rproc_getname(nl_rproc_t *rp)
|
|||
|
||||
nl_nat_t *
|
||||
npf_nat_create(int type, u_int flags, const char *ifname,
|
||||
npf_addr_t *addr, int af, in_port_t port)
|
||||
int af, npf_addr_t *addr, npf_netmask_t mask, in_port_t port)
|
||||
{
|
||||
nl_rule_t *rl;
|
||||
prop_dictionary_t rldict;
|
||||
|
@ -832,13 +832,14 @@ npf_nat_create(int type, u_int flags, const char *ifname,
|
|||
prop_dictionary_set_int32(rldict, "type", type);
|
||||
prop_dictionary_set_uint32(rldict, "flags", flags);
|
||||
|
||||
/* Translation IP. */
|
||||
/* Translation IP and mask. */
|
||||
addrdat = prop_data_create_data(addr, sz);
|
||||
if (addrdat == NULL) {
|
||||
npf_rule_destroy(rl);
|
||||
return NULL;
|
||||
}
|
||||
prop_dictionary_set(rldict, "translation-ip", addrdat);
|
||||
prop_dictionary_set_uint32(rldict, "translation-mask", mask);
|
||||
prop_object_release(addrdat);
|
||||
|
||||
/* Translation port (for redirect case). */
|
||||
|
@ -864,6 +865,27 @@ npf_nat_iterate(nl_config_t *ncf)
|
|||
return _npf_rule_iterate1(ncf, ncf->ncf_nat_list, &level);
|
||||
}
|
||||
|
||||
int
|
||||
npf_nat_setalgo(nl_nat_t *nt, u_int algo)
|
||||
{
|
||||
prop_dictionary_t rldict = nt->nrl_dict;
|
||||
prop_dictionary_set_uint32(rldict, "translation-algo", algo);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
npf_nat_setnpt66(nl_nat_t *nt, uint16_t adj)
|
||||
{
|
||||
prop_dictionary_t rldict = nt->nrl_dict;
|
||||
int error;
|
||||
|
||||
if ((error = npf_nat_setalgo(nt, NPF_ALGO_NPT66)) != 0) {
|
||||
return error;
|
||||
}
|
||||
prop_dictionary_set_uint16(rldict, "npt66-adjustment", adj);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
npf_nat_gettype(nl_nat_t *nt)
|
||||
{
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/* $NetBSD: npf.h,v 1.24 2014/02/07 23:45:22 rmind Exp $ */
|
||||
/* $NetBSD: npf.h,v 1.25 2014/02/13 03:34:41 rmind Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2011-2013 The NetBSD Foundation, Inc.
|
||||
* Copyright (c) 2011-2014 The NetBSD Foundation, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This material is based upon work partially supported by The
|
||||
|
@ -105,7 +105,7 @@ bool npf_rproc_exists_p(nl_config_t *, const char *);
|
|||
int npf_rproc_insert(nl_config_t *, nl_rproc_t *);
|
||||
|
||||
nl_nat_t * npf_nat_create(int, u_int, const char *,
|
||||
npf_addr_t *, int, in_port_t);
|
||||
int, npf_addr_t *, npf_netmask_t, in_port_t);
|
||||
int npf_nat_insert(nl_config_t *, nl_nat_t *, pri_t);
|
||||
|
||||
nl_table_t * npf_table_create(const char *, u_int, int);
|
||||
|
@ -139,6 +139,9 @@ int npf_nat_gettype(nl_nat_t *);
|
|||
unsigned npf_nat_getflags(nl_nat_t *);
|
||||
void npf_nat_getmap(nl_nat_t *, npf_addr_t *, size_t *, in_port_t *);
|
||||
|
||||
int npf_nat_setalgo(nl_nat_t *, u_int);
|
||||
int npf_nat_setnpt66(nl_nat_t *, uint16_t);
|
||||
|
||||
nl_rproc_t * npf_rproc_iterate(nl_config_t *);
|
||||
const char * npf_rproc_getname(nl_rproc_t *);
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/* $NetBSD: npf.h,v 1.36 2014/02/07 23:45:22 rmind Exp $ */
|
||||
/* $NetBSD: npf.h,v 1.37 2014/02/13 03:34:40 rmind Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2009-2013 The NetBSD Foundation, Inc.
|
||||
* Copyright (c) 2009-2014 The NetBSD Foundation, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This material is based upon work partially supported by The
|
||||
|
@ -45,7 +45,7 @@
|
|||
#include <netinet/in_systm.h>
|
||||
#include <netinet/in.h>
|
||||
|
||||
#define NPF_VERSION 12
|
||||
#define NPF_VERSION 13
|
||||
|
||||
/*
|
||||
* Public declarations and definitions.
|
||||
|
@ -237,6 +237,8 @@ bool npf_autounload_p(void);
|
|||
#define NPF_NAT_PORTMAP 0x02
|
||||
#define NPF_NAT_STATIC 0x04
|
||||
|
||||
#define NPF_ALGO_NPT66 1
|
||||
|
||||
/* Table types. */
|
||||
#define NPF_TABLE_HASH 1
|
||||
#define NPF_TABLE_TREE 2
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/* $NetBSD: npf_impl.h,v 1.46 2014/02/06 02:51:28 rmind Exp $ */
|
||||
/* $NetBSD: npf_impl.h,v 1.47 2014/02/13 03:34:40 rmind Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2009-2013 The NetBSD Foundation, Inc.
|
||||
* Copyright (c) 2009-2014 The NetBSD Foundation, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This material is based upon work partially supported by The
|
||||
|
@ -192,6 +192,8 @@ bool npf_rwrip(const npf_cache_t *, u_int, const npf_addr_t *);
|
|||
bool npf_rwrport(const npf_cache_t *, u_int, const in_port_t);
|
||||
bool npf_rwrcksum(const npf_cache_t *, u_int,
|
||||
const npf_addr_t *, const in_port_t);
|
||||
int npf_npt66_rwr(const npf_cache_t *, u_int, const npf_addr_t *,
|
||||
npf_netmask_t, uint16_t);
|
||||
|
||||
uint16_t npf_fixup16_cksum(uint16_t, uint16_t, uint16_t);
|
||||
uint16_t npf_fixup32_cksum(uint16_t, uint32_t, uint32_t);
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/* $NetBSD: npf_inet.c,v 1.28 2013/12/06 01:33:37 rmind Exp $ */
|
||||
/* $NetBSD: npf_inet.c,v 1.29 2014/02/13 03:34:40 rmind Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2009-2012 The NetBSD Foundation, Inc.
|
||||
* Copyright (c) 2009-2014 The NetBSD Foundation, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This material is based upon work partially supported by The
|
||||
|
@ -39,7 +39,7 @@
|
|||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: npf_inet.c,v 1.28 2013/12/06 01:33:37 rmind Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: npf_inet.c,v 1.29 2014/02/13 03:34:40 rmind Exp $");
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/types.h>
|
||||
|
@ -616,6 +616,79 @@ npf_rwrcksum(const npf_cache_t *npc, u_int which,
|
|||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
* IPv6-to-IPv6 Network Prefix Translation (NPTv6), as per RFC 6296.
|
||||
*/
|
||||
|
||||
int
|
||||
npf_npt66_rwr(const npf_cache_t *npc, u_int which, const npf_addr_t *pref,
|
||||
npf_netmask_t len, uint16_t adj)
|
||||
{
|
||||
npf_addr_t *addr = npc->npc_ips[which];
|
||||
unsigned remnant, word, preflen = len >> 4;
|
||||
uint32_t sum;
|
||||
|
||||
KASSERT(which == NPF_SRC || which == NPF_DST);
|
||||
|
||||
if (!npf_iscached(npc, NPC_IP6)) {
|
||||
return EINVAL;
|
||||
}
|
||||
if (len <= 48) {
|
||||
/*
|
||||
* The word to adjust. Cannot translate the 0xffff
|
||||
* subnet if /48 or shorter.
|
||||
*/
|
||||
word = 3;
|
||||
if (addr->s6_addr16[word] == 0xffff) {
|
||||
return EINVAL;
|
||||
}
|
||||
} else {
|
||||
/*
|
||||
* Also, all 0s or 1s in the host part are disallowed for
|
||||
* longer than /48 prefixes.
|
||||
*/
|
||||
if ((addr->s6_addr32[2] == 0 && addr->s6_addr32[3] == 0) ||
|
||||
(addr->s6_addr32[2] == ~0U && addr->s6_addr32[3] == ~0U))
|
||||
return EINVAL;
|
||||
|
||||
/* Determine the 16-bit word to adjust. */
|
||||
for (word = 4; word < 8; word++)
|
||||
if (addr->s6_addr16[word] != 0xffff)
|
||||
break;
|
||||
}
|
||||
|
||||
/* Rewrite the prefix. */
|
||||
for (unsigned i = 0; i < preflen; i++) {
|
||||
addr->s6_addr16[i] = pref->s6_addr16[i];
|
||||
}
|
||||
|
||||
/*
|
||||
* If prefix length is within a 16-bit word (not dividable by 16),
|
||||
* then prepare a mask, determine the word and adjust it.
|
||||
*/
|
||||
if ((remnant = len - (preflen << 4)) != 0) {
|
||||
const uint16_t wordmask = (1U << remnant) - 1;
|
||||
const unsigned i = preflen;
|
||||
|
||||
addr->s6_addr16[i] = (pref->s6_addr16[i] & wordmask) |
|
||||
(addr->s6_addr16[i] & ~wordmask);
|
||||
}
|
||||
|
||||
/*
|
||||
* Performing 1's complement sum/difference.
|
||||
*/
|
||||
sum = addr->s6_addr16[word] + adj;
|
||||
while (sum >> 16) {
|
||||
sum = (sum >> 16) + (sum & 0xffff);
|
||||
}
|
||||
if (sum == 0xffff) {
|
||||
/* RFC 1071. */
|
||||
sum = 0x0000;
|
||||
}
|
||||
addr->s6_addr16[word] = sum;
|
||||
return 0;
|
||||
}
|
||||
|
||||
#if defined(DDB) || defined(_NPF_TESTING)
|
||||
|
||||
void
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
/* $NetBSD: npf_nat.c,v 1.24 2014/02/07 23:45:22 rmind Exp $ */
|
||||
/* $NetBSD: npf_nat.c,v 1.25 2014/02/13 03:34:40 rmind Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2014 Mindaugas Rasiukevicius <rmind at netbsd org>
|
||||
* Copyright (c) 2010-2013 The NetBSD Foundation, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
|
@ -70,7 +71,7 @@
|
|||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: npf_nat.c,v 1.24 2014/02/07 23:45:22 rmind Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: npf_nat.c,v 1.25 2014/02/13 03:34:40 rmind Exp $");
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/types.h>
|
||||
|
@ -100,7 +101,7 @@ typedef struct {
|
|||
/* Portmap range: [ 1024 .. 65535 ] */
|
||||
#define PORTMAP_FIRST (1024)
|
||||
#define PORTMAP_SIZE ((65536 - PORTMAP_FIRST) / 32)
|
||||
#define PORTMAP_FILLED ((uint32_t)~0)
|
||||
#define PORTMAP_FILLED ((uint32_t)~0U)
|
||||
#define PORTMAP_MASK (31)
|
||||
#define PORTMAP_SHIFT (5)
|
||||
|
||||
|
@ -121,7 +122,12 @@ struct npf_natpolicy {
|
|||
u_int n_flags;
|
||||
size_t n_addr_sz;
|
||||
npf_addr_t n_taddr;
|
||||
npf_netmask_t n_tmask;
|
||||
in_port_t n_tport;
|
||||
u_int n_algo;
|
||||
union {
|
||||
uint16_t n_npt66_adj;
|
||||
};
|
||||
};
|
||||
|
||||
#define NPF_NP_CMP_START offsetof(npf_natpolicy_t, n_type)
|
||||
|
@ -186,22 +192,34 @@ npf_nat_newpolicy(prop_dictionary_t natdict, npf_ruleset_t *nrlset)
|
|||
|
||||
/* Should be exclusively either inbound or outbound NAT. */
|
||||
if (((np->n_type == NPF_NATIN) ^ (np->n_type == NPF_NATOUT)) == 0) {
|
||||
kmem_free(np, sizeof(npf_natpolicy_t));
|
||||
return NULL;
|
||||
goto err;
|
||||
}
|
||||
mutex_init(&np->n_lock, MUTEX_DEFAULT, IPL_SOFTNET);
|
||||
cv_init(&np->n_cv, "npfnatcv");
|
||||
LIST_INIT(&np->n_nat_list);
|
||||
|
||||
/* Translation IP. */
|
||||
/* Translation IP, mask and port (if applicable). */
|
||||
obj = prop_dictionary_get(natdict, "translation-ip");
|
||||
np->n_addr_sz = prop_data_size(obj);
|
||||
KASSERT(np->n_addr_sz > 0 && np->n_addr_sz <= sizeof(npf_addr_t));
|
||||
if (np->n_addr_sz == 0 || np->n_addr_sz > sizeof(npf_addr_t)) {
|
||||
goto err;
|
||||
}
|
||||
memcpy(&np->n_taddr, prop_data_data_nocopy(obj), np->n_addr_sz);
|
||||
|
||||
/* Translation port (for redirect case). */
|
||||
prop_dictionary_get_uint8(natdict, "translation-mask", &np->n_tmask);
|
||||
prop_dictionary_get_uint16(natdict, "translation-port", &np->n_tport);
|
||||
|
||||
prop_dictionary_get_uint32(natdict, "translation-algo", &np->n_algo);
|
||||
switch (np->n_algo) {
|
||||
case NPF_ALGO_NPT66:
|
||||
prop_dictionary_get_uint16(natdict, "npt66-adjustment",
|
||||
&np->n_npt66_adj);
|
||||
break;
|
||||
default:
|
||||
if (np->n_tmask != NPF_NO_NETMASK)
|
||||
goto err;
|
||||
break;
|
||||
}
|
||||
|
||||
/* Determine if port map is needed. */
|
||||
np->n_portmap = NULL;
|
||||
if ((np->n_flags & NPF_NAT_PORTMAP) == 0) {
|
||||
|
@ -223,6 +241,9 @@ npf_nat_newpolicy(prop_dictionary_t natdict, npf_ruleset_t *nrlset)
|
|||
KASSERT(np->n_portmap != NULL);
|
||||
}
|
||||
return np;
|
||||
err:
|
||||
kmem_free(np, sizeof(npf_natpolicy_t));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -606,6 +627,29 @@ npf_nat_translate(npf_cache_t *npc, nbuf_t *nbuf, npf_nat_t *nt, bool forw)
|
|||
return npf_nat_rwr(npc, np, addr, port, forw);
|
||||
}
|
||||
|
||||
/*
|
||||
* npf_nat_algo: perform the translation given the algorithm.
|
||||
*/
|
||||
static inline int
|
||||
npf_nat_algo(npf_cache_t *npc, const npf_natpolicy_t *np, bool forw)
|
||||
{
|
||||
u_int which;
|
||||
int error;
|
||||
|
||||
switch (np->n_algo) {
|
||||
case NPF_ALGO_NPT66:
|
||||
which = npf_nat_which(np->n_type, forw);
|
||||
error = npf_npt66_rwr(npc, which, &np->n_taddr,
|
||||
np->n_tmask, np->n_npt66_adj);
|
||||
break;
|
||||
default:
|
||||
error = npf_nat_rwr(npc, np, &np->n_taddr, np->n_tport, forw);
|
||||
break;
|
||||
}
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
/*
|
||||
* npf_do_nat:
|
||||
* - Inspect packet for a NAT policy, unless a session with a NAT
|
||||
|
@ -656,7 +700,7 @@ npf_do_nat(npf_cache_t *npc, npf_session_t *se, nbuf_t *nbuf, const int di)
|
|||
if (nbuf_cksum_barrier(nbuf, di)) {
|
||||
npf_recache(npc, nbuf);
|
||||
}
|
||||
error = npf_nat_rwr(npc, np, &np->n_taddr, np->n_tport, forw);
|
||||
error = npf_nat_algo(npc, np, forw);
|
||||
atomic_dec_uint(&np->n_refcnt);
|
||||
return error;
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: npf_build.c,v 1.35 2014/02/07 23:45:22 rmind Exp $ */
|
||||
/* $NetBSD: npf_build.c,v 1.36 2014/02/13 03:34:40 rmind Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2011-2014 The NetBSD Foundation, Inc.
|
||||
|
@ -34,7 +34,7 @@
|
|||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__RCSID("$NetBSD: npf_build.c,v 1.35 2014/02/07 23:45:22 rmind Exp $");
|
||||
__RCSID("$NetBSD: npf_build.c,v 1.36 2014/02/13 03:34:40 rmind Exp $");
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/mman.h>
|
||||
|
@ -533,24 +533,15 @@ npfctl_build_rule(uint32_t attr, const char *ifname, sa_family_t family,
|
|||
* npfctl_build_nat: create a single NAT policy of a specified
|
||||
* type with a given filter options.
|
||||
*/
|
||||
static void
|
||||
npfctl_build_nat(int type, const char *ifname, sa_family_t family,
|
||||
const addr_port_t *ap, const filt_opts_t *fopts, u_int flags)
|
||||
static nl_nat_t *
|
||||
npfctl_build_nat(int type, const char *ifname, const addr_port_t *ap,
|
||||
const filt_opts_t *fopts, u_int flags)
|
||||
{
|
||||
const opt_proto_t op = { .op_proto = -1, .op_opts = NULL };
|
||||
fam_addr_mask_t *am;
|
||||
fam_addr_mask_t *am = npfctl_get_singlefam(ap->ap_netaddr);
|
||||
in_port_t port;
|
||||
nl_nat_t *nat;
|
||||
|
||||
if (!ap->ap_netaddr) {
|
||||
yyerror("%s network segment is not specified",
|
||||
type == NPF_NATIN ? "inbound" : "outbound");
|
||||
}
|
||||
am = npfctl_get_singlefam(ap->ap_netaddr);
|
||||
if (am->fam_family != family) {
|
||||
yyerror("IPv6 NAT is not supported");
|
||||
}
|
||||
|
||||
if (ap->ap_portrange) {
|
||||
port = npfctl_get_singleport(ap->ap_portrange);
|
||||
flags &= ~NPF_NAT_PORTMAP;
|
||||
|
@ -559,10 +550,11 @@ npfctl_build_nat(int type, const char *ifname, sa_family_t family,
|
|||
port = 0;
|
||||
}
|
||||
|
||||
nat = npf_nat_create(type, flags, ifname,
|
||||
&am->fam_addr, am->fam_family, port);
|
||||
npfctl_build_code(nat, family, &op, fopts);
|
||||
nat = npf_nat_create(type, flags, ifname, am->fam_family,
|
||||
&am->fam_addr, am->fam_mask, port);
|
||||
npfctl_build_code(nat, am->fam_family, &op, fopts);
|
||||
npf_nat_insert(npf_conf, nat, NPF_PRI_LAST);
|
||||
return nat;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -571,10 +563,12 @@ npfctl_build_nat(int type, const char *ifname, sa_family_t family,
|
|||
void
|
||||
npfctl_build_natseg(int sd, int type, const char *ifname,
|
||||
const addr_port_t *ap1, const addr_port_t *ap2,
|
||||
const filt_opts_t *fopts)
|
||||
const filt_opts_t *fopts, u_int algo)
|
||||
{
|
||||
sa_family_t af = AF_INET;
|
||||
fam_addr_mask_t *am1 = NULL, *am2 = NULL;
|
||||
nl_nat_t *nt1 = NULL, *nt2 = NULL;
|
||||
filt_opts_t imfopts;
|
||||
uint16_t adj = 0;
|
||||
u_int flags;
|
||||
bool binat;
|
||||
|
||||
|
@ -602,6 +596,38 @@ npfctl_build_natseg(int sd, int type, const char *ifname,
|
|||
abort();
|
||||
}
|
||||
|
||||
/*
|
||||
* Validate the mappings and their configuration.
|
||||
*/
|
||||
|
||||
if ((type & NPF_NATIN) != 0) {
|
||||
if (!ap1->ap_netaddr)
|
||||
yyerror("inbound network segment is not specified");
|
||||
am1 = npfctl_get_singlefam(ap1->ap_netaddr);
|
||||
}
|
||||
if ((type & NPF_NATOUT) != 0) {
|
||||
if (!ap2->ap_netaddr)
|
||||
yyerror("outbound network segment is not specified");
|
||||
am2 = npfctl_get_singlefam(ap2->ap_netaddr);
|
||||
}
|
||||
|
||||
switch (algo) {
|
||||
case NPF_ALGO_NPT66:
|
||||
if (am1 == NULL || am2 == NULL)
|
||||
yyerror("1:1 mapping of two segments must be "
|
||||
"used for NPTv6");
|
||||
if (am1->fam_mask != am2->fam_mask)
|
||||
yyerror("asymmetric translation is not supported");
|
||||
adj = npfctl_npt66_calcadj(am1->fam_mask,
|
||||
&am1->fam_addr, &am2->fam_addr);
|
||||
break;
|
||||
default:
|
||||
if ((am1 && am1->fam_mask != NPF_NO_NETMASK) ||
|
||||
(am2 && am2->fam_mask != NPF_NO_NETMASK))
|
||||
yyerror("net-to-net translation is not supported");
|
||||
break;
|
||||
}
|
||||
|
||||
/*
|
||||
* If the filter criteria is not specified explicitly, apply implicit
|
||||
* filtering according to the given network segments.
|
||||
|
@ -615,12 +641,17 @@ npfctl_build_natseg(int sd, int type, const char *ifname,
|
|||
if (type & NPF_NATIN) {
|
||||
memset(&imfopts, 0, sizeof(filt_opts_t));
|
||||
memcpy(&imfopts.fo_to, ap2, sizeof(addr_port_t));
|
||||
npfctl_build_nat(NPF_NATIN, ifname, af, ap1, fopts, flags);
|
||||
nt1 = npfctl_build_nat(NPF_NATIN, ifname, ap1, fopts, flags);
|
||||
}
|
||||
if (type & NPF_NATOUT) {
|
||||
memset(&imfopts, 0, sizeof(filt_opts_t));
|
||||
memcpy(&imfopts.fo_from, ap1, sizeof(addr_port_t));
|
||||
npfctl_build_nat(NPF_NATOUT, ifname, af, ap2, fopts, flags);
|
||||
nt2 = npfctl_build_nat(NPF_NATOUT, ifname, ap2, fopts, flags);
|
||||
}
|
||||
|
||||
if (algo == NPF_ALGO_NPT66) {
|
||||
npf_nat_setnpt66(nt1, ~adj);
|
||||
npf_nat_setnpt66(nt2, adj);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/* $NetBSD: npf_data.c,v 1.24 2014/02/03 02:21:52 rmind Exp $ */
|
||||
/* $NetBSD: npf_data.c,v 1.25 2014/02/13 03:34:40 rmind Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2009-2012 The NetBSD Foundation, Inc.
|
||||
* Copyright (c) 2009-2014 The NetBSD Foundation, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
|
@ -31,7 +31,7 @@
|
|||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__RCSID("$NetBSD: npf_data.c,v 1.24 2014/02/03 02:21:52 rmind Exp $");
|
||||
__RCSID("$NetBSD: npf_data.c,v 1.25 2014/02/13 03:34:40 rmind Exp $");
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/null.h>
|
||||
|
@ -585,3 +585,49 @@ out:
|
|||
npfvar_destroy(vp);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* npfctl_npt66_calcadj: calculate the adjustment for NPTv6 as per RFC 6296.
|
||||
*/
|
||||
uint16_t
|
||||
npfctl_npt66_calcadj(npf_netmask_t len, const npf_addr_t *pref_in,
|
||||
const npf_addr_t *pref_out)
|
||||
{
|
||||
const uint16_t *addr6_in = (const uint16_t *)pref_in;
|
||||
const uint16_t *addr6_out = (const uint16_t *)pref_out;
|
||||
unsigned i, remnant, wordmask, preflen = len >> 4;
|
||||
uint32_t adj, isum = 0, osum = 0;
|
||||
|
||||
/*
|
||||
* Extract the bits within a 16-bit word (when prefix length is
|
||||
* not dividable by 16) and include them into the sum.
|
||||
*/
|
||||
remnant = len - (preflen << 4);
|
||||
wordmask = (1U << remnant) - 1;
|
||||
assert(wordmask == 0 || (len % 16) != 0);
|
||||
|
||||
/* Inner prefix - sum and fold. */
|
||||
for (i = 0; i < preflen; i++) {
|
||||
isum += addr6_in[i];
|
||||
}
|
||||
isum += addr6_in[i] & wordmask;
|
||||
while (isum >> 16) {
|
||||
isum = (isum >> 16) + (isum & 0xffff);
|
||||
}
|
||||
|
||||
/* Outer prefix - sum and fold. */
|
||||
for (i = 0; i < preflen; i++) {
|
||||
osum += addr6_out[i];
|
||||
}
|
||||
osum += addr6_out[i] & wordmask;
|
||||
while (osum >> 16) {
|
||||
osum = (osum >> 16) + (osum & 0xffff);
|
||||
}
|
||||
|
||||
/* Calculate 1's complement difference. */
|
||||
adj = isum + ~osum;
|
||||
while (adj >> 16) {
|
||||
adj = (adj >> 16) + (adj & 0xffff);
|
||||
}
|
||||
return (uint16_t)adj;
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/* $NetBSD: npf_parse.y,v 1.31 2014/02/08 01:20:09 rmind Exp $ */
|
||||
/* $NetBSD: npf_parse.y,v 1.32 2014/02/13 03:34:40 rmind Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2011-2013 The NetBSD Foundation, Inc.
|
||||
* Copyright (c) 2011-2014 The NetBSD Foundation, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This code is derived from software contributed to The NetBSD Foundation
|
||||
|
@ -84,6 +84,7 @@ yyerror(const char *fmt, ...)
|
|||
%}
|
||||
|
||||
%token ALG
|
||||
%token ALGO
|
||||
%token ALL
|
||||
%token ANY
|
||||
%token APPLY
|
||||
|
@ -115,6 +116,7 @@ yyerror(const char *fmt, ...)
|
|||
%token MAP
|
||||
%token MINUS
|
||||
%token NAME
|
||||
%token NPT66
|
||||
%token ON
|
||||
%token OUT
|
||||
%token PAR_CLOSE
|
||||
|
@ -156,7 +158,8 @@ yyerror(const char *fmt, ...)
|
|||
%type <str> proc_param_val, opt_apply, ifname, on_ifname, ifref
|
||||
%type <num> port, opt_final, number, afamily, opt_family
|
||||
%type <num> block_or_pass, rule_dir, group_dir, block_opts
|
||||
%type <num> opt_stateful, icmp_type, table_type, map_sd, map_type
|
||||
%type <num> opt_stateful, icmp_type, table_type
|
||||
%type <num> map_sd, map_algo, map_type
|
||||
%type <var> ifaddrs, addr_or_ifaddr, port_range, icmp_type_and_code
|
||||
%type <var> filt_addr, addr_and_mask, tcp_flags, tcp_flags_and_mask
|
||||
%type <var> procs, proc_call, proc_param_list, proc_param
|
||||
|
@ -296,6 +299,11 @@ map_sd
|
|||
| { $$ = NPFCTL_NAT_DYNAMIC; }
|
||||
;
|
||||
|
||||
map_algo
|
||||
: ALGO NPT66 { $$ = NPF_ALGO_NPT66; }
|
||||
| { $$ = 0; }
|
||||
;
|
||||
|
||||
map_type
|
||||
: ARROWBOTH { $$ = NPF_NATIN | NPF_NATOUT; }
|
||||
| ARROWLEFT { $$ = NPF_NATIN; }
|
||||
|
@ -311,13 +319,13 @@ mapseg
|
|||
;
|
||||
|
||||
map
|
||||
: MAP ifref map_sd mapseg map_type mapseg PASS filt_opts
|
||||
: MAP ifref map_sd map_algo mapseg map_type mapseg PASS filt_opts
|
||||
{
|
||||
npfctl_build_natseg($3, $5, $2, &$4, &$6, &$8);
|
||||
npfctl_build_natseg($3, $6, $2, &$5, &$7, &$9, $4);
|
||||
}
|
||||
| MAP ifref map_sd mapseg map_type mapseg
|
||||
| MAP ifref map_sd map_algo mapseg map_type mapseg
|
||||
{
|
||||
npfctl_build_natseg($3, $5, $2, &$4, &$6, NULL);
|
||||
npfctl_build_natseg($3, $6, $2, &$5, &$7, NULL, $4);
|
||||
}
|
||||
| MAP RULESET group_opts
|
||||
{
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: npf_scan.l,v 1.18 2014/02/08 01:20:09 rmind Exp $ */
|
||||
/* $NetBSD: npf_scan.l,v 1.19 2014/02/13 03:34:40 rmind Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2011-2012 The NetBSD Foundation, Inc.
|
||||
|
@ -99,6 +99,8 @@ map return MAP;
|
|||
"<->" return ARROWBOTH;
|
||||
"<-" return ARROWLEFT;
|
||||
"->" return ARROWRIGHT;
|
||||
algo return ALGO;
|
||||
npt66 return NPT66;
|
||||
"-" return MINUS;
|
||||
procedure return PROCEDURE;
|
||||
\\\n yylineno++; yycolumn = 0;
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: npfctl.h,v 1.35 2014/02/03 02:21:52 rmind Exp $ */
|
||||
/* $NetBSD: npfctl.h,v 1.36 2014/02/13 03:34:40 rmind Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2009-2013 The NetBSD Foundation, Inc.
|
||||
|
@ -126,6 +126,8 @@ npfvar_t * npfctl_parse_port_range_variable(const char *);
|
|||
npfvar_t * npfctl_parse_fam_addr_mask(const char *, const char *,
|
||||
unsigned long *);
|
||||
bool npfctl_parse_cidr(char *, fam_addr_mask_t *, int *);
|
||||
uint16_t npfctl_npt66_calcadj(npf_netmask_t, const npf_addr_t *,
|
||||
const npf_addr_t *);
|
||||
|
||||
/*
|
||||
* NPF extension loading.
|
||||
|
@ -193,7 +195,7 @@ void npfctl_build_rule(uint32_t, const char *, sa_family_t,
|
|||
const char *, const char *);
|
||||
void npfctl_build_natseg(int, int, const char *,
|
||||
const addr_port_t *, const addr_port_t *,
|
||||
const filt_opts_t *);
|
||||
const filt_opts_t *, unsigned);
|
||||
void npfctl_build_maprset(const char *, int, const char *);
|
||||
void npfctl_build_table(const char *, u_int, const char *);
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: npf_mbuf_subr.c,v 1.4 2012/12/24 19:05:47 rmind Exp $ */
|
||||
/* $NetBSD: npf_mbuf_subr.c,v 1.5 2014/02/13 03:34:40 rmind Exp $ */
|
||||
|
||||
/*
|
||||
* NPF testing - helper routines.
|
||||
|
@ -136,6 +136,15 @@ mbuf_return_hdrs(struct mbuf *m, bool ether, struct ip **ip)
|
|||
return (void *)(iphdr + 1);
|
||||
}
|
||||
|
||||
void *
|
||||
mbuf_return_hdrs6(struct mbuf *m, struct ip6_hdr **ip6)
|
||||
{
|
||||
struct ip6_hdr *ip6hdr = mtod(m, struct ip6_hdr *);
|
||||
|
||||
*ip6 = ip6hdr;
|
||||
return (void *)(ip6hdr + 1);
|
||||
}
|
||||
|
||||
void
|
||||
mbuf_icmp_append(struct mbuf *m, struct mbuf *m_orig)
|
||||
{
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: npf_nat_test.c,v 1.7 2014/02/07 23:45:22 rmind Exp $ */
|
||||
/* $NetBSD: npf_nat_test.c,v 1.8 2014/02/13 03:34:40 rmind Exp $ */
|
||||
|
||||
/*
|
||||
* NPF NAT test.
|
||||
|
@ -27,6 +27,7 @@ static const struct test_case {
|
|||
const char * ifname;
|
||||
int di;
|
||||
int ret;
|
||||
int af;
|
||||
const char * taddr;
|
||||
in_port_t tport;
|
||||
} test_cases[] = {
|
||||
|
@ -38,32 +39,32 @@ static const struct test_case {
|
|||
{
|
||||
LOCAL_IP1, 15000, REMOTE_IP1, 7000,
|
||||
NPF_NATOUT, IFNAME_EXT, PFIL_OUT,
|
||||
RESULT_PASS, PUB_IP1, RANDOM_PORT
|
||||
RESULT_PASS, AF_INET, PUB_IP1, RANDOM_PORT
|
||||
},
|
||||
{
|
||||
LOCAL_IP1, 15000, REMOTE_IP1, 7000,
|
||||
NPF_NATOUT, IFNAME_EXT, PFIL_OUT,
|
||||
RESULT_PASS, PUB_IP1, RANDOM_PORT
|
||||
RESULT_PASS, AF_INET, PUB_IP1, RANDOM_PORT
|
||||
},
|
||||
{
|
||||
LOCAL_IP1, 15000, REMOTE_IP1, 7000,
|
||||
NPF_NATOUT, IFNAME_EXT, PFIL_IN,
|
||||
RESULT_BLOCK, NULL, 0
|
||||
RESULT_BLOCK, AF_INET, NULL, 0
|
||||
},
|
||||
{
|
||||
REMOTE_IP1, 7000, LOCAL_IP1, 15000,
|
||||
NPF_NATOUT, IFNAME_EXT, PFIL_IN,
|
||||
RESULT_BLOCK, NULL, 0
|
||||
RESULT_BLOCK, AF_INET, NULL, 0
|
||||
},
|
||||
{
|
||||
REMOTE_IP1, 7000, PUB_IP1, RANDOM_PORT,
|
||||
NPF_NATOUT, IFNAME_INT, PFIL_IN,
|
||||
RESULT_BLOCK, NULL, 0
|
||||
RESULT_BLOCK, AF_INET, NULL, 0
|
||||
},
|
||||
{
|
||||
REMOTE_IP1, 7000, PUB_IP1, RANDOM_PORT,
|
||||
NPF_NATOUT, IFNAME_EXT, PFIL_IN,
|
||||
RESULT_PASS, LOCAL_IP1, 15000
|
||||
RESULT_PASS, AF_INET, LOCAL_IP1, 15000
|
||||
},
|
||||
|
||||
/*
|
||||
|
@ -73,12 +74,12 @@ static const struct test_case {
|
|||
{
|
||||
REMOTE_IP2, 16000, PUB_IP1, 8000,
|
||||
NPF_NATIN, IFNAME_EXT, PFIL_IN,
|
||||
RESULT_PASS, LOCAL_IP1, 6000
|
||||
RESULT_PASS, AF_INET, LOCAL_IP1, 6000
|
||||
},
|
||||
{
|
||||
LOCAL_IP1, 6000, REMOTE_IP2, 16000,
|
||||
NPF_NATIN, IFNAME_EXT, PFIL_OUT,
|
||||
RESULT_PASS, PUB_IP1, 8000
|
||||
RESULT_PASS, AF_INET, PUB_IP1, 8000
|
||||
},
|
||||
|
||||
/*
|
||||
|
@ -88,22 +89,22 @@ static const struct test_case {
|
|||
{
|
||||
REMOTE_IP2, 17000, PUB_IP2, 9000,
|
||||
NPF_BINAT, IFNAME_EXT, PFIL_IN,
|
||||
RESULT_PASS, LOCAL_IP2, 9000
|
||||
RESULT_PASS, AF_INET, LOCAL_IP2, 9000
|
||||
},
|
||||
{
|
||||
LOCAL_IP2, 9000, REMOTE_IP2, 17000,
|
||||
NPF_BINAT, IFNAME_EXT, PFIL_OUT,
|
||||
RESULT_PASS, PUB_IP2, 9000
|
||||
RESULT_PASS, AF_INET, PUB_IP2, 9000
|
||||
},
|
||||
{
|
||||
LOCAL_IP2, 18000, REMOTE_IP2, 9000,
|
||||
NPF_BINAT, IFNAME_EXT, PFIL_OUT,
|
||||
RESULT_PASS, PUB_IP2, 18000
|
||||
RESULT_PASS, AF_INET, PUB_IP2, 18000
|
||||
},
|
||||
{
|
||||
REMOTE_IP2, 9000, PUB_IP2, 18000,
|
||||
NPF_BINAT, IFNAME_EXT, PFIL_IN,
|
||||
RESULT_PASS, LOCAL_IP2, 18000
|
||||
RESULT_PASS, AF_INET, LOCAL_IP2, 18000
|
||||
},
|
||||
|
||||
/*
|
||||
|
@ -113,21 +114,40 @@ static const struct test_case {
|
|||
{
|
||||
LOCAL_IP3, 19000, REMOTE_IP3, 10000,
|
||||
NPF_BINAT, IFNAME_EXT, PFIL_OUT,
|
||||
RESULT_PASS, PUB_IP3, 19000
|
||||
RESULT_PASS, AF_INET, PUB_IP3, 19000
|
||||
},
|
||||
{
|
||||
REMOTE_IP3, 10000, PUB_IP3, 19000,
|
||||
NPF_BINAT, IFNAME_EXT, PFIL_IN,
|
||||
RESULT_PASS, LOCAL_IP3, 19000
|
||||
RESULT_PASS, AF_INET, LOCAL_IP3, 19000
|
||||
},
|
||||
|
||||
/*
|
||||
* NPTv6 case:
|
||||
* map $ext_if static algo npt66 $net6_inner <-> $net6_outer
|
||||
*/
|
||||
{
|
||||
LOCAL_IP6, 1000, REMOTE_IP6, 1001,
|
||||
NPF_BINAT, IFNAME_EXT, PFIL_OUT,
|
||||
RESULT_PASS, AF_INET6, EXPECTED_IP6, 1000
|
||||
},
|
||||
{
|
||||
REMOTE_IP6, 1001, EXPECTED_IP6, 1000,
|
||||
NPF_BINAT, IFNAME_EXT, PFIL_IN,
|
||||
RESULT_PASS, AF_INET6, LOCAL_IP6, 1000
|
||||
},
|
||||
|
||||
};
|
||||
|
||||
static bool
|
||||
nmatch_addr(const char *saddr, const struct in_addr *addr2)
|
||||
nmatch_addr(int af, const char *saddr, const npf_addr_t *addr2)
|
||||
{
|
||||
const in_addr_t addr1 = inet_addr(saddr);
|
||||
return memcmp(&addr1, &addr2->s_addr, sizeof(in_addr_t)) != 0;
|
||||
npf_addr_t addr1;
|
||||
size_t len;
|
||||
|
||||
npf_inet_pton(af, saddr, &addr1);
|
||||
len = af == AF_INET ? sizeof(struct in_addr) : sizeof(struct in6_addr);
|
||||
return memcmp(&addr1, addr2, len) != 0;
|
||||
}
|
||||
|
||||
static bool
|
||||
|
@ -135,6 +155,7 @@ checkresult(bool verbose, unsigned i, struct mbuf *m, ifnet_t *ifp, int error)
|
|||
{
|
||||
const struct test_case *t = &test_cases[i];
|
||||
npf_cache_t npc = { .npc_info = 0 };
|
||||
const int af = t->af;
|
||||
nbuf_t nbuf;
|
||||
|
||||
if (verbose) {
|
||||
|
@ -150,14 +171,17 @@ checkresult(bool verbose, unsigned i, struct mbuf *m, ifnet_t *ifp, int error)
|
|||
return false;
|
||||
}
|
||||
|
||||
const struct ip *ip = npc.npc_ip.v4;
|
||||
const struct udphdr *uh = npc.npc_l4.udp;
|
||||
|
||||
if (verbose) {
|
||||
printf("\tpost-translation: src %s (%d)",
|
||||
inet_ntoa(ip->ip_src), ntohs(uh->uh_sport));
|
||||
printf(" dst %s (%d)\n",
|
||||
inet_ntoa(ip->ip_dst), ntohs(uh->uh_dport));
|
||||
char sbuf[64], dbuf[64];
|
||||
|
||||
npf_inet_ntop(af, npc.npc_ips[NPF_SRC], sbuf, sizeof(sbuf));
|
||||
npf_inet_ntop(af, npc.npc_ips[NPF_DST], dbuf, sizeof(dbuf));
|
||||
|
||||
printf("\tpost-translation:");
|
||||
printf("src %s (%d) ", sbuf, ntohs(uh->uh_sport));
|
||||
printf("dst %s (%d)\n", dbuf, ntohs(uh->uh_dport));
|
||||
}
|
||||
if (error != t->ret) {
|
||||
return false;
|
||||
|
@ -170,10 +194,11 @@ checkresult(bool verbose, unsigned i, struct mbuf *m, ifnet_t *ifp, int error)
|
|||
in_addr_t dport = forw ? t->dport : t->tport;
|
||||
|
||||
bool defect = false;
|
||||
defect |= nmatch_addr(saddr, &ip->ip_src);
|
||||
defect |= nmatch_addr(af, saddr, npc.npc_ips[NPF_SRC]);
|
||||
defect |= sport != ntohs(uh->uh_sport);
|
||||
defect |= nmatch_addr(daddr, &ip->ip_dst);
|
||||
defect |= nmatch_addr(af, daddr, npc.npc_ips[NPF_DST]);
|
||||
defect |= dport != ntohs(uh->uh_dport);
|
||||
|
||||
return !defect;
|
||||
}
|
||||
|
||||
|
@ -181,13 +206,25 @@ static struct mbuf *
|
|||
fill_packet(const struct test_case *t)
|
||||
{
|
||||
struct mbuf *m;
|
||||
struct ip *ip;
|
||||
void *ipsrc, *ipdst;
|
||||
struct udphdr *uh;
|
||||
|
||||
m = mbuf_construct(IPPROTO_UDP);
|
||||
uh = mbuf_return_hdrs(m, false, &ip);
|
||||
ip->ip_src.s_addr = inet_addr(t->src);
|
||||
ip->ip_dst.s_addr = inet_addr(t->dst);
|
||||
if (t->af == AF_INET6) {
|
||||
struct ip6_hdr *ip6;
|
||||
|
||||
m = mbuf_construct6(IPPROTO_UDP);
|
||||
uh = mbuf_return_hdrs6(m, &ip6);
|
||||
ipsrc = &ip6->ip6_src, ipdst = &ip6->ip6_dst;
|
||||
} else {
|
||||
struct ip *ip;
|
||||
|
||||
m = mbuf_construct(IPPROTO_UDP);
|
||||
uh = mbuf_return_hdrs(m, false, &ip);
|
||||
ipsrc = &ip->ip_src.s_addr, ipdst = &ip->ip_dst.s_addr;
|
||||
}
|
||||
|
||||
npf_inet_pton(t->af, t->src, ipsrc);
|
||||
npf_inet_pton(t->af, t->dst, ipdst);
|
||||
uh->uh_sport = htons(t->sport);
|
||||
uh->uh_dport = htons(t->dport);
|
||||
return m;
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: npf_test.h,v 1.14 2014/02/07 23:45:22 rmind Exp $ */
|
||||
/* $NetBSD: npf_test.h,v 1.15 2014/02/13 03:34:40 rmind Exp $ */
|
||||
|
||||
/*
|
||||
* Public Domain.
|
||||
|
@ -42,7 +42,13 @@
|
|||
#define REMOTE_IP2 "192.0.2.102"
|
||||
#define REMOTE_IP3 "192.0.2.103"
|
||||
|
||||
void npf_test_init(long (*)(void));
|
||||
#define LOCAL_IP6 "fd01:203:405:1::1234"
|
||||
#define REMOTE_IP6 "2001:db8:fefe::1010"
|
||||
#define EXPECTED_IP6 "2001:db8:1:d550::1234"
|
||||
|
||||
void npf_test_init(int (*)(int, const char *, void *),
|
||||
const char *(*)(int, const void *, char *, socklen_t),
|
||||
long (*)(void));
|
||||
int npf_test_load(const void *);
|
||||
ifnet_t * npf_test_addif(const char *, bool, bool);
|
||||
ifnet_t * npf_test_getif(const char *);
|
||||
|
@ -56,6 +62,7 @@ struct mbuf * mbuf_construct_ether(int);
|
|||
struct mbuf * mbuf_construct(int);
|
||||
struct mbuf * mbuf_construct6(int);
|
||||
void * mbuf_return_hdrs(struct mbuf *, bool, struct ip **);
|
||||
void * mbuf_return_hdrs6(struct mbuf *, struct ip6_hdr **);
|
||||
void mbuf_icmp_append(struct mbuf *, struct mbuf *);
|
||||
|
||||
bool npf_nbuf_test(bool);
|
||||
|
@ -66,4 +73,7 @@ bool npf_state_test(bool);
|
|||
bool npf_rule_test(bool);
|
||||
bool npf_nat_test(bool);
|
||||
|
||||
int npf_inet_pton(int, const char *, void *);
|
||||
const char * npf_inet_ntop(int, const void *, char *, socklen_t);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: npf_test_subr.c,v 1.8 2014/02/05 03:49:48 rmind Exp $ */
|
||||
/* $NetBSD: npf_test_subr.c,v 1.9 2014/02/13 03:34:40 rmind Exp $ */
|
||||
|
||||
/*
|
||||
* NPF initialisation and handler routines.
|
||||
|
@ -19,14 +19,21 @@ static npf_state_t cstream_state;
|
|||
static void * cstream_ptr;
|
||||
static bool cstream_retval;
|
||||
|
||||
static long (*_random_func)(void);
|
||||
static int (*_pton_func)(int, const char *, void *);
|
||||
static const char * (*_ntop_func)(int, const void *, char *, socklen_t);
|
||||
|
||||
static void npf_state_sample(npf_state_t *, bool);
|
||||
static long (*npf_random_func)(void) = NULL;
|
||||
|
||||
void
|
||||
npf_test_init(long (*rndfunc)(void))
|
||||
npf_test_init(int (*pton_func)(int, const char *, void *),
|
||||
const char *(*ntop_func)(int, const void *, char *, socklen_t),
|
||||
long (*rndfunc)(void))
|
||||
{
|
||||
npf_state_setsampler(npf_state_sample);
|
||||
npf_random_func = rndfunc;
|
||||
_pton_func = pton_func;
|
||||
_ntop_func = ntop_func;
|
||||
_random_func = rndfunc;
|
||||
}
|
||||
|
||||
int
|
||||
|
@ -118,11 +125,23 @@ npf_test_statetrack(const void *data, size_t len, ifnet_t *ifp,
|
|||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
npf_inet_pton(int af, const char *src, void *dst)
|
||||
{
|
||||
return _pton_func(af, src, dst);
|
||||
}
|
||||
|
||||
const char *
|
||||
npf_inet_ntop(int af, const void *src, char *dst, socklen_t size)
|
||||
{
|
||||
return _ntop_func(af, src, dst, size);
|
||||
}
|
||||
|
||||
/*
|
||||
* Need to override for cprng_fast32() -- we need deterministic PRNG.
|
||||
*/
|
||||
uint32_t
|
||||
_arc4random(void)
|
||||
{
|
||||
return (uint32_t)(npf_random_func ? npf_random_func() : random());
|
||||
return (uint32_t)(_random_func ? _random_func() : random());
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: npftest.c,v 1.16 2014/02/06 02:51:28 rmind Exp $ */
|
||||
/* $NetBSD: npftest.c,v 1.17 2014/02/13 03:34:40 rmind Exp $ */
|
||||
|
||||
/*
|
||||
* NPF testing framework.
|
||||
|
@ -255,7 +255,7 @@ main(int argc, char **argv)
|
|||
rump_init();
|
||||
rump_schedule();
|
||||
|
||||
rumpns_npf_test_init(random);
|
||||
rumpns_npf_test_init(inet_pton, inet_ntop, random);
|
||||
|
||||
if (config) {
|
||||
load_npf_config(config);
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
# $NetBSD: npftest.conf,v 1.4 2014/02/07 23:45:22 rmind Exp $
|
||||
# $NetBSD: npftest.conf,v 1.5 2014/02/13 03:34:40 rmind Exp $
|
||||
|
||||
$ext_if = "npftest0"
|
||||
$int_if = "npftest1"
|
||||
|
@ -19,15 +19,23 @@ $local_ip4 = 10.1.1.4
|
|||
$local_net = { 10.1.1.0/24 }
|
||||
$ports = { 8000, 9000 }
|
||||
|
||||
$net6_inner = fd01:203:405::/48
|
||||
$net6_outer = 2001:db8:1::/48
|
||||
|
||||
map $ext_if static $local_ip3 <-> $pub_ip3
|
||||
map $ext_if dynamic $local_ip2 <-> $pub_ip2
|
||||
map $ext_if dynamic $local_net -> $pub_ip1
|
||||
map $ext_if dynamic $local_ip1 port 6000 <- $pub_ip1 port 8000
|
||||
|
||||
map $ext_if static algo npt66 $net6_inner <-> $net6_outer
|
||||
|
||||
group "ext" on $ext_if {
|
||||
pass out final from $local_ip3
|
||||
pass in final to $pub_ip3
|
||||
|
||||
pass out final from $net6_inner
|
||||
pass in final to $net6_outer
|
||||
|
||||
pass stateful out final proto tcp flags S/SA all
|
||||
pass stateful out final from $local_net
|
||||
pass stateful in final to any port $ports
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: npftest.h,v 1.12 2014/02/06 02:51:28 rmind Exp $ */
|
||||
/* $NetBSD: npftest.h,v 1.13 2014/02/13 03:34:40 rmind Exp $ */
|
||||
|
||||
/*
|
||||
* Public Domain.
|
||||
|
@ -12,7 +12,9 @@
|
|||
|
||||
#include <net/if.h>
|
||||
|
||||
void rumpns_npf_test_init(long (*)(void));
|
||||
void rumpns_npf_test_init(int (*)(int, const char *, void *),
|
||||
const char *(*)(int, const void *, char *, socklen_t),
|
||||
long (*)(void));
|
||||
int rumpns_npf_test_load(const void *);
|
||||
ifnet_t * rumpns_npf_test_addif(const char *, bool, bool);
|
||||
ifnet_t * rumpns_npf_test_getif(const char *);
|
||||
|
|
Loading…
Reference in New Issue