version 1.6.6.2, 2012/04/17 00:08:39 |
version 1.6.6.3, 2012/10/30 17:22:44 |
|
|
/* $NetBSD$ */ |
/* $NetBSD$ */ |
|
|
/*- |
/*- |
* Copyright (c) 2010-2011 The NetBSD Foundation, Inc. |
* Copyright (c) 2010-2012 The NetBSD Foundation, Inc. |
* All rights reserved. |
* All rights reserved. |
* |
* |
* This material is based upon work partially supported by The |
* This material is based upon work partially supported by The |
Line 120 struct npf_natpolicy { |
|
Line 120 struct npf_natpolicy { |
|
kmutex_t n_lock; |
kmutex_t n_lock; |
kcondvar_t n_cv; |
kcondvar_t n_cv; |
npf_portmap_t * n_portmap; |
npf_portmap_t * n_portmap; |
|
/* NPF_NP_CMP_START */ |
int n_type; |
int n_type; |
u_int n_flags; |
u_int n_flags; |
size_t n_addr_sz; |
size_t n_addr_sz; |
Line 267 npf_nat_freepolicy(npf_natpolicy_t *np) |
|
Line 268 npf_nat_freepolicy(npf_natpolicy_t *np) |
|
kmem_free(np, sizeof(npf_natpolicy_t)); |
kmem_free(np, sizeof(npf_natpolicy_t)); |
} |
} |
|
|
|
void |
|
npf_nat_freealg(npf_natpolicy_t *np, npf_alg_t *alg) |
|
{ |
|
npf_nat_t *nt; |
|
|
|
mutex_enter(&np->n_lock); |
|
LIST_FOREACH(nt, &np->n_nat_list, nt_entry) { |
|
if (nt->nt_alg != alg) { |
|
continue; |
|
} |
|
nt->nt_alg = NULL; |
|
} |
|
mutex_exit(&np->n_lock); |
|
} |
|
|
/* |
/* |
* npf_nat_matchpolicy: compare two NAT policies. |
* npf_nat_matchpolicy: compare two NAT policies. |
* |
* |
Line 401 npf_nat_putport(npf_natpolicy_t *np, in_ |
|
Line 417 npf_nat_putport(npf_natpolicy_t *np, in_ |
|
* npf_nat_inspect: inspect packet against NAT ruleset and return a policy. |
* npf_nat_inspect: inspect packet against NAT ruleset and return a policy. |
*/ |
*/ |
static npf_natpolicy_t * |
static npf_natpolicy_t * |
npf_nat_inspect(npf_cache_t *npc, nbuf_t *nbuf, ifnet_t *ifp, const int di) |
npf_nat_inspect(npf_cache_t *npc, nbuf_t *nbuf, const ifnet_t *ifp, |
|
const int di) |
{ |
{ |
npf_ruleset_t *rlset; |
npf_ruleset_t *rlset; |
npf_natpolicy_t *np; |
npf_natpolicy_t *np; |
Line 447 npf_nat_create(npf_cache_t *npc, npf_nat |
|
Line 464 npf_nat_create(npf_cache_t *npc, npf_nat |
|
/* Save the original address which may be rewritten. */ |
/* Save the original address which may be rewritten. */ |
if (np->n_type == NPF_NATOUT) { |
if (np->n_type == NPF_NATOUT) { |
/* Source (local) for Outbound NAT. */ |
/* Source (local) for Outbound NAT. */ |
memcpy(&nt->nt_oaddr, npc->npc_srcip, npc->npc_ipsz); |
memcpy(&nt->nt_oaddr, npc->npc_srcip, npc->npc_alen); |
} else { |
} else { |
/* Destination (external) for Inbound NAT. */ |
/* Destination (external) for Inbound NAT. */ |
KASSERT(np->n_type == NPF_NATIN); |
KASSERT(np->n_type == NPF_NATIN); |
memcpy(&nt->nt_oaddr, npc->npc_dstip, npc->npc_ipsz); |
memcpy(&nt->nt_oaddr, npc->npc_dstip, npc->npc_alen); |
} |
} |
|
|
/* |
/* |
Line 504 npf_nat_translate(npf_cache_t *npc, nbuf |
|
Line 521 npf_nat_translate(npf_cache_t *npc, nbuf |
|
|
|
if (forw) { |
if (forw) { |
/* "Forwards" stream: use translation address/port. */ |
/* "Forwards" stream: use translation address/port. */ |
KASSERT( |
|
(np->n_type == NPF_NATIN && di == PFIL_IN) ^ |
|
(np->n_type == NPF_NATOUT && di == PFIL_OUT) |
|
); |
|
addr = &np->n_taddr; |
addr = &np->n_taddr; |
port = nt->nt_tport; |
port = nt->nt_tport; |
} else { |
} else { |
/* "Backwards" stream: use original address/port. */ |
/* "Backwards" stream: use original address/port. */ |
KASSERT( |
|
(np->n_type == NPF_NATIN && di == PFIL_OUT) ^ |
|
(np->n_type == NPF_NATOUT && di == PFIL_IN) |
|
); |
|
addr = &nt->nt_oaddr; |
addr = &nt->nt_oaddr; |
port = nt->nt_oport; |
port = nt->nt_oport; |
} |
} |
Line 574 npf_nat_translate(npf_cache_t *npc, nbuf |
|
Line 583 npf_nat_translate(npf_cache_t *npc, nbuf |
|
*/ |
*/ |
int |
int |
npf_do_nat(npf_cache_t *npc, npf_session_t *se, nbuf_t *nbuf, |
npf_do_nat(npf_cache_t *npc, npf_session_t *se, nbuf_t *nbuf, |
ifnet_t *ifp, const int di) |
const ifnet_t *ifp, const int di) |
{ |
{ |
npf_session_t *nse = NULL; |
npf_session_t *nse = NULL; |
npf_natpolicy_t *np; |
npf_natpolicy_t *np; |
Line 629 npf_do_nat(npf_cache_t *npc, npf_session |
|
Line 638 npf_do_nat(npf_cache_t *npc, npf_session |
|
} |
} |
|
|
/* |
/* |
* If there is no local session (no "keep state" rule - unusual, but |
* If there is no local session (no "stateful" rule - unusual, but |
* possible configuration), establish one before translation. Note |
* possible configuration), establish one before translation. Note |
* that it is not a "pass" session, therefore passing of "backwards" |
* that it is not a "pass" session, therefore passing of "backwards" |
* stream depends on other, stateless filtering rules. |
* stream depends on other, stateless filtering rules. |
*/ |
*/ |
if (se == NULL) { |
if (se == NULL) { |
nse = npf_session_establish(npc, nbuf, di); |
nse = npf_session_establish(npc, nbuf, ifp, di); |
if (nse == NULL) { |
if (nse == NULL) { |
error = ENOMEM; |
error = ENOMEM; |
goto out; |
goto out; |
|
|
/* Will free the structure and return the port. */ |
/* Will free the structure and return the port. */ |
npf_nat_expire(nt); |
npf_nat_expire(nt); |
} |
} |
if (nse != NULL) { |
if (nse) { |
npf_session_release(nse); |
npf_session_release(nse); |
} |
} |
} |
} |
Line 742 npf_nat_save(prop_dictionary_t sedict, p |
|
Line 751 npf_nat_save(prop_dictionary_t sedict, p |
|
prop_object_iterator_t it; |
prop_object_iterator_t it; |
prop_dictionary_t npdict; |
prop_dictionary_t npdict; |
prop_data_t nd, npd; |
prop_data_t nd, npd; |
uintptr_t itnp; |
uint64_t itnp; |
|
|
/* Set NAT entry data. */ |
/* Set NAT entry data. */ |
nd = prop_data_create_data(nt, sizeof(npf_nat_t)); |
nd = prop_data_create_data(nt, sizeof(npf_nat_t)); |
Line 753 npf_nat_save(prop_dictionary_t sedict, p |
|
Line 762 npf_nat_save(prop_dictionary_t sedict, p |
|
it = prop_array_iterator(natlist); |
it = prop_array_iterator(natlist); |
while ((npdict = prop_object_iterator_next(it)) != NULL) { |
while ((npdict = prop_object_iterator_next(it)) != NULL) { |
CTASSERT(sizeof(uintptr_t) <= sizeof(uint64_t)); |
CTASSERT(sizeof(uintptr_t) <= sizeof(uint64_t)); |
prop_dictionary_get_uint64(npdict, "id-ptr", (uint64_t *)&itnp); |
prop_dictionary_get_uint64(npdict, "id-ptr", &itnp); |
if (itnp == (uintptr_t)np) { |
if ((uintptr_t)itnp == (uintptr_t)np) { |
break; |
break; |
} |
} |
} |
} |
Line 831 npf_nat_restore(prop_dictionary_t sedict |
|
Line 840 npf_nat_restore(prop_dictionary_t sedict |
|
#if defined(DDB) || defined(_NPF_TESTING) |
#if defined(DDB) || defined(_NPF_TESTING) |
|
|
void |
void |
npf_nat_dump(npf_nat_t *nt) |
npf_nat_dump(const npf_nat_t *nt) |
{ |
{ |
npf_natpolicy_t *np; |
const npf_natpolicy_t *np; |
struct in_addr ip; |
struct in_addr ip; |
|
|
np = nt->nt_natpolicy; |
np = nt->nt_natpolicy; |