2 * Copyright 2005, Gleb Smirnoff <glebius@FreeBSD.org>
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26 * $FreeBSD: src/sys/netgraph/ng_nat.c,v 1.12 2008/06/01 15:13:32 mav Exp $
29 #include <sys/param.h>
30 #include <sys/systm.h>
31 #include <sys/kernel.h>
33 #include <sys/malloc.h>
34 #include <sys/ctype.h>
35 #include <sys/errno.h>
36 #include <sys/syslog.h>
38 #include <netinet/in_systm.h>
39 #include <netinet/in.h>
40 #include <netinet/ip.h>
41 #include <netinet/ip_var.h>
42 #include <netinet/tcp.h>
43 #include <machine/in_cksum.h>
45 #include <netinet/libalias/alias.h>
47 #include "ng_message.h"
52 static ng_constructor_t ng_nat_constructor
;
53 static ng_rcvmsg_t ng_nat_rcvmsg
;
54 static ng_shutdown_t ng_nat_shutdown
;
55 static ng_newhook_t ng_nat_newhook
;
56 static ng_rcvdata_t ng_nat_rcvdata
;
57 static ng_disconnect_t ng_nat_disconnect
;
59 static unsigned int ng_nat_translate_flags(unsigned int x
);
61 /* Parse type for struct ng_nat_mode. */
62 static const struct ng_parse_struct_field ng_nat_mode_fields
[]
64 static const struct ng_parse_type ng_nat_mode_type
= {
65 &ng_parse_struct_type
,
69 /* Parse type for 'description' field in structs. */
70 static const struct ng_parse_fixedstring_info ng_nat_description_info
71 = { NG_NAT_DESC_LENGTH
};
72 static const struct ng_parse_type ng_nat_description_type
= {
73 &ng_parse_fixedstring_type
,
74 &ng_nat_description_info
77 /* Parse type for struct ng_nat_redirect_port. */
78 static const struct ng_parse_struct_field ng_nat_redirect_port_fields
[]
79 = NG_NAT_REDIRECT_PORT_TYPE_INFO(&ng_nat_description_type
);
80 static const struct ng_parse_type ng_nat_redirect_port_type
= {
81 &ng_parse_struct_type
,
82 &ng_nat_redirect_port_fields
85 /* Parse type for struct ng_nat_redirect_addr. */
86 static const struct ng_parse_struct_field ng_nat_redirect_addr_fields
[]
87 = NG_NAT_REDIRECT_ADDR_TYPE_INFO(&ng_nat_description_type
);
88 static const struct ng_parse_type ng_nat_redirect_addr_type
= {
89 &ng_parse_struct_type
,
90 &ng_nat_redirect_addr_fields
93 /* Parse type for struct ng_nat_redirect_proto. */
94 static const struct ng_parse_struct_field ng_nat_redirect_proto_fields
[]
95 = NG_NAT_REDIRECT_PROTO_TYPE_INFO(&ng_nat_description_type
);
96 static const struct ng_parse_type ng_nat_redirect_proto_type
= {
97 &ng_parse_struct_type
,
98 &ng_nat_redirect_proto_fields
101 /* Parse type for struct ng_nat_add_server. */
102 static const struct ng_parse_struct_field ng_nat_add_server_fields
[]
103 = NG_NAT_ADD_SERVER_TYPE_INFO
;
104 static const struct ng_parse_type ng_nat_add_server_type
= {
105 &ng_parse_struct_type
,
106 &ng_nat_add_server_fields
109 /* Parse type for one struct ng_nat_listrdrs_entry. */
110 static const struct ng_parse_struct_field ng_nat_listrdrs_entry_fields
[]
111 = NG_NAT_LISTRDRS_ENTRY_TYPE_INFO(&ng_nat_description_type
);
112 static const struct ng_parse_type ng_nat_listrdrs_entry_type
= {
113 &ng_parse_struct_type
,
114 &ng_nat_listrdrs_entry_fields
117 /* Parse type for 'redirects' array in struct ng_nat_list_redirects. */
119 ng_nat_listrdrs_ary_getLength(const struct ng_parse_type
*type
,
120 const u_char
*start
, const u_char
*buf
)
122 const struct ng_nat_list_redirects
*lr
;
124 lr
= (const struct ng_nat_list_redirects
*)
125 (buf
- offsetof(struct ng_nat_list_redirects
, redirects
));
126 return lr
->total_count
;
129 static const struct ng_parse_array_info ng_nat_listrdrs_ary_info
= {
130 &ng_nat_listrdrs_entry_type
,
131 &ng_nat_listrdrs_ary_getLength
,
134 static const struct ng_parse_type ng_nat_listrdrs_ary_type
= {
135 &ng_parse_array_type
,
136 &ng_nat_listrdrs_ary_info
139 /* Parse type for struct ng_nat_list_redirects. */
140 static const struct ng_parse_struct_field ng_nat_list_redirects_fields
[]
141 = NG_NAT_LIST_REDIRECTS_TYPE_INFO(&ng_nat_listrdrs_ary_type
);
142 static const struct ng_parse_type ng_nat_list_redirects_type
= {
143 &ng_parse_struct_type
,
144 &ng_nat_list_redirects_fields
147 /* List of commands and how to convert arguments to/from ASCII. */
148 static const struct ng_cmdlist ng_nat_cmdlist
[] = {
153 &ng_parse_ipaddr_type
,
167 &ng_parse_ipaddr_type
,
172 NGM_NAT_REDIRECT_PORT
,
174 &ng_nat_redirect_port_type
,
175 &ng_parse_uint32_type
179 NGM_NAT_REDIRECT_ADDR
,
181 &ng_nat_redirect_addr_type
,
182 &ng_parse_uint32_type
186 NGM_NAT_REDIRECT_PROTO
,
188 &ng_nat_redirect_proto_type
,
189 &ng_parse_uint32_type
193 NGM_NAT_REDIRECT_DYNAMIC
,
195 &ng_parse_uint32_type
,
200 NGM_NAT_REDIRECT_DELETE
,
202 &ng_parse_uint32_type
,
209 &ng_nat_add_server_type
,
214 NGM_NAT_LIST_REDIRECTS
,
217 &ng_nat_list_redirects_type
223 &ng_parse_string_type
,
229 /* Netgraph node type descriptor. */
230 static struct ng_type typestruct
= {
231 .version
= NG_ABI_VERSION
,
232 .name
= NG_NAT_NODE_TYPE
,
233 .constructor
= ng_nat_constructor
,
234 .rcvmsg
= ng_nat_rcvmsg
,
235 .shutdown
= ng_nat_shutdown
,
236 .newhook
= ng_nat_newhook
,
237 .rcvdata
= ng_nat_rcvdata
,
238 .disconnect
= ng_nat_disconnect
,
239 .cmdlist
= ng_nat_cmdlist
,
241 NETGRAPH_INIT(nat
, &typestruct
);
242 MODULE_DEPEND(ng_nat
, libalias
, 1, 1, 1);
244 /* Element for list of redirects. */
245 struct ng_nat_rdr_lst
{
246 STAILQ_ENTRY(ng_nat_rdr_lst
) entries
;
247 struct alias_link
*lnk
;
248 struct ng_nat_listrdrs_entry rdr
;
250 STAILQ_HEAD(rdrhead
, ng_nat_rdr_lst
);
252 /* Information we store for each node. */
254 node_p node
; /* back pointer to node */
255 hook_p in
; /* hook for demasquerading */
256 hook_p out
; /* hook for masquerading */
257 struct libalias
*lib
; /* libalias handler */
258 uint32_t flags
; /* status flags */
259 uint32_t rdrcount
; /* number or redirects in list */
260 uint32_t nextid
; /* for next in turn in list */
261 struct rdrhead redirhead
; /* redirect list header */
263 typedef struct ng_nat_priv
*priv_p
;
265 /* Values of flags */
266 #define NGNAT_CONNECTED 0x1 /* We have both hooks connected */
267 #define NGNAT_ADDR_DEFINED 0x2 /* NGM_NAT_SET_IPADDR happened */
270 ng_nat_constructor(node_p node
)
274 /* Initialize private descriptor. */
275 priv
= kmalloc(sizeof(*priv
), M_NETGRAPH
,
276 M_WAITOK
| M_NULLOK
| M_ZERO
);
280 /* Init aliasing engine. */
281 priv
->lib
= LibAliasInit(NULL
);
282 if (priv
->lib
== NULL
) {
283 kfree(priv
, M_NETGRAPH
);
287 /* Set same ports on. */
288 (void )LibAliasSetMode(priv
->lib
, PKT_ALIAS_SAME_PORTS
,
289 PKT_ALIAS_SAME_PORTS
);
291 /* Init redirects housekeeping. */
294 STAILQ_INIT(&priv
->redirhead
);
296 /* Link structs together. */
297 NG_NODE_SET_PRIVATE(node
, priv
);
301 * libalias is not thread safe, so our node
302 * must be single threaded.
304 NG_NODE_FORCE_WRITER(node
);
310 ng_nat_newhook(node_p node
, hook_p hook
, const char *name
)
312 const priv_p priv
= NG_NODE_PRIVATE(node
);
314 if (strcmp(name
, NG_NAT_HOOK_IN
) == 0) {
316 } else if (strcmp(name
, NG_NAT_HOOK_OUT
) == 0) {
321 if (priv
->out
!= NULL
&&
323 priv
->flags
|= NGNAT_CONNECTED
;
329 ng_nat_rcvmsg(node_p node
, item_p item
, hook_p lasthook
)
331 const priv_p priv
= NG_NODE_PRIVATE(node
);
332 struct ng_mesg
*resp
= NULL
;
336 NGI_GET_MSG(item
, msg
);
338 switch (msg
->header
.typecookie
) {
340 switch (msg
->header
.cmd
) {
341 case NGM_NAT_SET_IPADDR
:
343 struct in_addr
*const ia
= (struct in_addr
*)msg
->data
;
345 if (msg
->header
.arglen
< sizeof(*ia
)) {
350 LibAliasSetAddress(priv
->lib
, *ia
);
352 priv
->flags
|= NGNAT_ADDR_DEFINED
;
355 case NGM_NAT_SET_MODE
:
357 struct ng_nat_mode
*const mode
=
358 (struct ng_nat_mode
*)msg
->data
;
360 if (msg
->header
.arglen
< sizeof(*mode
)) {
365 if (LibAliasSetMode(priv
->lib
,
366 ng_nat_translate_flags(mode
->flags
),
367 ng_nat_translate_flags(mode
->mask
)) < 0) {
373 case NGM_NAT_SET_TARGET
:
375 struct in_addr
*const ia
= (struct in_addr
*)msg
->data
;
377 if (msg
->header
.arglen
< sizeof(*ia
)) {
382 LibAliasSetTarget(priv
->lib
, *ia
);
385 case NGM_NAT_REDIRECT_PORT
:
387 struct ng_nat_rdr_lst
*entry
;
388 struct ng_nat_redirect_port
*const rp
=
389 (struct ng_nat_redirect_port
*)msg
->data
;
391 if (msg
->header
.arglen
< sizeof(*rp
)) {
396 if ((entry
= kmalloc(sizeof(struct ng_nat_rdr_lst
),
397 M_NETGRAPH
, M_WAITOK
| M_NULLOK
| M_ZERO
)) == NULL
) {
402 /* Try actual redirect. */
403 entry
->lnk
= LibAliasRedirectPort(priv
->lib
,
404 rp
->local_addr
, htons(rp
->local_port
),
405 rp
->remote_addr
, htons(rp
->remote_port
),
406 rp
->alias_addr
, htons(rp
->alias_port
),
409 if (entry
->lnk
== NULL
) {
411 kfree(entry
, M_NETGRAPH
);
415 /* Successful, save info in our internal list. */
416 entry
->rdr
.local_addr
= rp
->local_addr
;
417 entry
->rdr
.alias_addr
= rp
->alias_addr
;
418 entry
->rdr
.remote_addr
= rp
->remote_addr
;
419 entry
->rdr
.local_port
= rp
->local_port
;
420 entry
->rdr
.alias_port
= rp
->alias_port
;
421 entry
->rdr
.remote_port
= rp
->remote_port
;
422 entry
->rdr
.proto
= rp
->proto
;
423 bcopy(rp
->description
, entry
->rdr
.description
,
426 /* Safety precaution. */
427 entry
->rdr
.description
[NG_NAT_DESC_LENGTH
-1] = '\0';
429 entry
->rdr
.id
= priv
->nextid
++;
432 /* Link to list of redirects. */
433 STAILQ_INSERT_TAIL(&priv
->redirhead
, entry
, entries
);
435 /* Response with id of newly added entry. */
436 NG_MKRESPONSE(resp
, msg
, sizeof(entry
->rdr
.id
), M_WAITOK
| M_NULLOK
);
441 bcopy(&entry
->rdr
.id
, resp
->data
, sizeof(entry
->rdr
.id
));
444 case NGM_NAT_REDIRECT_ADDR
:
446 struct ng_nat_rdr_lst
*entry
;
447 struct ng_nat_redirect_addr
*const ra
=
448 (struct ng_nat_redirect_addr
*)msg
->data
;
450 if (msg
->header
.arglen
< sizeof(*ra
)) {
455 if ((entry
= kmalloc(sizeof(struct ng_nat_rdr_lst
),
456 M_NETGRAPH
, M_WAITOK
| M_NULLOK
| M_ZERO
)) == NULL
) {
461 /* Try actual redirect. */
462 entry
->lnk
= LibAliasRedirectAddr(priv
->lib
,
463 ra
->local_addr
, ra
->alias_addr
);
465 if (entry
->lnk
== NULL
) {
467 kfree(entry
, M_NETGRAPH
);
471 /* Successful, save info in our internal list. */
472 entry
->rdr
.local_addr
= ra
->local_addr
;
473 entry
->rdr
.alias_addr
= ra
->alias_addr
;
474 entry
->rdr
.proto
= NG_NAT_REDIRPROTO_ADDR
;
475 bcopy(ra
->description
, entry
->rdr
.description
,
478 /* Safety precaution. */
479 entry
->rdr
.description
[NG_NAT_DESC_LENGTH
-1] = '\0';
481 entry
->rdr
.id
= priv
->nextid
++;
484 /* Link to list of redirects. */
485 STAILQ_INSERT_TAIL(&priv
->redirhead
, entry
, entries
);
487 /* Response with id of newly added entry. */
488 NG_MKRESPONSE(resp
, msg
, sizeof(entry
->rdr
.id
), M_WAITOK
| M_NULLOK
);
493 bcopy(&entry
->rdr
.id
, resp
->data
, sizeof(entry
->rdr
.id
));
496 case NGM_NAT_REDIRECT_PROTO
:
498 struct ng_nat_rdr_lst
*entry
;
499 struct ng_nat_redirect_proto
*const rp
=
500 (struct ng_nat_redirect_proto
*)msg
->data
;
502 if (msg
->header
.arglen
< sizeof(*rp
)) {
507 if ((entry
= kmalloc(sizeof(struct ng_nat_rdr_lst
),
508 M_NETGRAPH
, M_WAITOK
| M_NULLOK
| M_ZERO
)) == NULL
) {
513 /* Try actual redirect. */
514 entry
->lnk
= LibAliasRedirectProto(priv
->lib
,
515 rp
->local_addr
, rp
->remote_addr
,
516 rp
->alias_addr
, rp
->proto
);
518 if (entry
->lnk
== NULL
) {
520 kfree(entry
, M_NETGRAPH
);
524 /* Successful, save info in our internal list. */
525 entry
->rdr
.local_addr
= rp
->local_addr
;
526 entry
->rdr
.alias_addr
= rp
->alias_addr
;
527 entry
->rdr
.remote_addr
= rp
->remote_addr
;
528 entry
->rdr
.proto
= rp
->proto
;
529 bcopy(rp
->description
, entry
->rdr
.description
,
532 /* Safety precaution. */
533 entry
->rdr
.description
[NG_NAT_DESC_LENGTH
-1] = '\0';
535 entry
->rdr
.id
= priv
->nextid
++;
538 /* Link to list of redirects. */
539 STAILQ_INSERT_TAIL(&priv
->redirhead
, entry
, entries
);
541 /* Response with id of newly added entry. */
542 NG_MKRESPONSE(resp
, msg
, sizeof(entry
->rdr
.id
), M_WAITOK
| M_NULLOK
);
547 bcopy(&entry
->rdr
.id
, resp
->data
, sizeof(entry
->rdr
.id
));
550 case NGM_NAT_REDIRECT_DYNAMIC
:
551 case NGM_NAT_REDIRECT_DELETE
:
553 struct ng_nat_rdr_lst
*entry
;
554 uint32_t *const id
= (uint32_t *)msg
->data
;
556 if (msg
->header
.arglen
< sizeof(*id
)) {
561 /* Find entry with supplied id. */
562 STAILQ_FOREACH(entry
, &priv
->redirhead
, entries
) {
563 if (entry
->rdr
.id
== *id
)
573 if (msg
->header
.cmd
== NGM_NAT_REDIRECT_DYNAMIC
) {
574 if (LibAliasRedirectDynamic(priv
->lib
,
576 error
= ENOTTY
; /* XXX Something better? */
579 } else { /* NGM_NAT_REDIRECT_DELETE */
580 LibAliasRedirectDelete(priv
->lib
, entry
->lnk
);
583 /* Delete entry from our internal list. */
585 STAILQ_REMOVE(&priv
->redirhead
, entry
, ng_nat_rdr_lst
, entries
);
586 kfree(entry
, M_NETGRAPH
);
589 case NGM_NAT_ADD_SERVER
:
591 struct ng_nat_rdr_lst
*entry
;
592 struct ng_nat_add_server
*const as
=
593 (struct ng_nat_add_server
*)msg
->data
;
595 if (msg
->header
.arglen
< sizeof(*as
)) {
600 /* Find entry with supplied id. */
601 STAILQ_FOREACH(entry
, &priv
->redirhead
, entries
) {
602 if (entry
->rdr
.id
== as
->id
)
612 if (LibAliasAddServer(priv
->lib
, entry
->lnk
,
613 as
->addr
, htons(as
->port
)) == -1) {
621 case NGM_NAT_LIST_REDIRECTS
:
623 struct ng_nat_rdr_lst
*entry
;
624 struct ng_nat_list_redirects
*ary
;
627 NG_MKRESPONSE(resp
, msg
, sizeof(*ary
) +
628 (priv
->rdrcount
) * sizeof(*entry
), M_WAITOK
| M_NULLOK
);
634 ary
= (struct ng_nat_list_redirects
*)resp
->data
;
635 ary
->total_count
= priv
->rdrcount
;
637 STAILQ_FOREACH(entry
, &priv
->redirhead
, entries
) {
638 bcopy(&entry
->rdr
, &ary
->redirects
[i
++],
639 sizeof(struct ng_nat_listrdrs_entry
));
643 case NGM_NAT_PROXY_RULE
:
645 char *cmd
= (char *)msg
->data
;
647 if (msg
->header
.arglen
< 6) {
652 if (LibAliasProxyRule(priv
->lib
, cmd
) != 0)
657 error
= EINVAL
; /* unknown command */
662 error
= EINVAL
; /* unknown cookie type */
666 NG_RESPOND_MSG(error
, node
, item
, resp
);
672 ng_nat_rcvdata(hook_p hook
, item_p item
)
674 const priv_p priv
= NG_NODE_PRIVATE(NG_HOOK_NODE(hook
));
680 /* We have no required hooks. */
681 if (!(priv
->flags
& NGNAT_CONNECTED
)) {
686 /* We have no alias address yet to do anything. */
687 if (!(priv
->flags
& NGNAT_ADDR_DEFINED
))
692 if ((m
= m_megapullup(m
, m
->m_pkthdr
.len
)) == NULL
) {
693 NGI_M(item
) = NULL
; /* avoid double free */
701 ip
= mtod(m
, struct ip
*);
703 KASSERT(m
->m_pkthdr
.len
== ntohs(ip
->ip_len
),
704 ("ng_nat: ip_len != m_pkthdr.len"));
706 if (hook
== priv
->in
) {
707 rval
= LibAliasIn(priv
->lib
, c
, m
->m_len
+ M_TRAILINGSPACE(m
));
708 if (rval
!= PKT_ALIAS_OK
&&
709 rval
!= PKT_ALIAS_FOUND_HEADER_FRAGMENT
) {
713 } else if (hook
== priv
->out
) {
714 rval
= LibAliasOut(priv
->lib
, c
, m
->m_len
+ M_TRAILINGSPACE(m
));
715 if (rval
!= PKT_ALIAS_OK
) {
720 panic("ng_nat: unknown hook!");
722 m
->m_pkthdr
.len
= m
->m_len
= ntohs(ip
->ip_len
);
724 if ((ip
->ip_off
& htons(IP_OFFMASK
)) == 0 &&
725 ip
->ip_p
== IPPROTO_TCP
) {
726 struct tcphdr
*th
= (struct tcphdr
*)((caddr_t
)ip
+
730 * Here is our terrible HACK.
732 * Sometimes LibAlias edits contents of TCP packet.
733 * In this case it needs to recompute full TCP
734 * checksum. However, the problem is that LibAlias
735 * doesn't have any idea about checksum offloading
736 * in kernel. To workaround this, we do not do
737 * checksumming in LibAlias, but only mark the
738 * packets in th_x2 field. If we receive a marked
739 * packet, we calculate correct checksum for it
740 * aware of offloading.
742 * Why do I do such a terrible hack instead of
743 * recalculating checksum for each packet?
744 * Because the previous checksum was not checked!
745 * Recalculating checksums for EVERY packet will
746 * hide ALL transmission errors. Yes, marked packets
747 * still suffer from this problem. But, sigh, natd(8)
748 * has this problem, too.
753 ip
->ip_len
= ntohs(ip
->ip_len
);
754 th
->th_sum
= in_pseudo(ip
->ip_src
.s_addr
,
755 ip
->ip_dst
.s_addr
, htons(IPPROTO_TCP
+
756 ip
->ip_len
- (ip
->ip_hl
<< 2)));
758 if ((m
->m_pkthdr
.csum_flags
& CSUM_TCP
) == 0) {
759 m
->m_pkthdr
.csum_data
= offsetof(struct tcphdr
,
763 ip
->ip_len
= htons(ip
->ip_len
);
768 if (hook
== priv
->in
)
769 NG_FWD_ITEM_HOOK(error
, item
, priv
->out
);
771 NG_FWD_ITEM_HOOK(error
, item
, priv
->in
);
777 ng_nat_shutdown(node_p node
)
779 const priv_p priv
= NG_NODE_PRIVATE(node
);
781 NG_NODE_SET_PRIVATE(node
, NULL
);
784 /* Free redirects list. */
785 while (!STAILQ_EMPTY(&priv
->redirhead
)) {
786 struct ng_nat_rdr_lst
*entry
= STAILQ_FIRST(&priv
->redirhead
);
787 STAILQ_REMOVE_HEAD(&priv
->redirhead
, entries
);
788 kfree(entry
, M_NETGRAPH
);
792 LibAliasUninit(priv
->lib
);
793 kfree(priv
, M_NETGRAPH
);
799 ng_nat_disconnect(hook_p hook
)
801 const priv_p priv
= NG_NODE_PRIVATE(NG_HOOK_NODE(hook
));
803 priv
->flags
&= ~NGNAT_CONNECTED
;
805 if (hook
== priv
->out
)
807 if (hook
== priv
->in
)
810 if (priv
->out
== NULL
&& priv
->in
== NULL
)
811 ng_rmnode_self(NG_HOOK_NODE(hook
));
817 ng_nat_translate_flags(unsigned int x
)
819 unsigned int res
= 0;
822 res
|= PKT_ALIAS_LOG
;
823 if (x
& NG_NAT_DENY_INCOMING
)
824 res
|= PKT_ALIAS_DENY_INCOMING
;
825 if (x
& NG_NAT_SAME_PORTS
)
826 res
|= PKT_ALIAS_SAME_PORTS
;
827 if (x
& NG_NAT_UNREGISTERED_ONLY
)
828 res
|= PKT_ALIAS_UNREGISTERED_ONLY
;
829 if (x
& NG_NAT_RESET_ON_ADDR_CHANGE
)
830 res
|= PKT_ALIAS_RESET_ON_ADDR_CHANGE
;
831 if (x
& NG_NAT_PROXY_ONLY
)
832 res
|= PKT_ALIAS_PROXY_ONLY
;
833 if (x
& NG_NAT_REVERSE
)
834 res
|= PKT_ALIAS_REVERSE
;