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 $
27 * $DragonFly: src/sys/netgraph7/ng_nat.c,v 1.2 2008/06/26 23:05:35 dillon Exp $
30 #include <sys/param.h>
31 #include <sys/systm.h>
32 #include <sys/kernel.h>
34 #include <sys/malloc.h>
35 #include <sys/ctype.h>
36 #include <sys/errno.h>
37 #include <sys/syslog.h>
39 #include <netinet/in_systm.h>
40 #include <netinet/in.h>
41 #include <netinet/ip.h>
42 #include <netinet/ip_var.h>
43 #include <netinet/tcp.h>
44 #include <machine/in_cksum.h>
46 #include <netinet/libalias/alias.h>
48 #include "ng_message.h"
53 static ng_constructor_t ng_nat_constructor
;
54 static ng_rcvmsg_t ng_nat_rcvmsg
;
55 static ng_shutdown_t ng_nat_shutdown
;
56 static ng_newhook_t ng_nat_newhook
;
57 static ng_rcvdata_t ng_nat_rcvdata
;
58 static ng_disconnect_t ng_nat_disconnect
;
60 static unsigned int ng_nat_translate_flags(unsigned int x
);
62 /* Parse type for struct ng_nat_mode. */
63 static const struct ng_parse_struct_field ng_nat_mode_fields
[]
65 static const struct ng_parse_type ng_nat_mode_type
= {
66 &ng_parse_struct_type
,
70 /* Parse type for 'description' field in structs. */
71 static const struct ng_parse_fixedstring_info ng_nat_description_info
72 = { NG_NAT_DESC_LENGTH
};
73 static const struct ng_parse_type ng_nat_description_type
= {
74 &ng_parse_fixedstring_type
,
75 &ng_nat_description_info
78 /* Parse type for struct ng_nat_redirect_port. */
79 static const struct ng_parse_struct_field ng_nat_redirect_port_fields
[]
80 = NG_NAT_REDIRECT_PORT_TYPE_INFO(&ng_nat_description_type
);
81 static const struct ng_parse_type ng_nat_redirect_port_type
= {
82 &ng_parse_struct_type
,
83 &ng_nat_redirect_port_fields
86 /* Parse type for struct ng_nat_redirect_addr. */
87 static const struct ng_parse_struct_field ng_nat_redirect_addr_fields
[]
88 = NG_NAT_REDIRECT_ADDR_TYPE_INFO(&ng_nat_description_type
);
89 static const struct ng_parse_type ng_nat_redirect_addr_type
= {
90 &ng_parse_struct_type
,
91 &ng_nat_redirect_addr_fields
94 /* Parse type for struct ng_nat_redirect_proto. */
95 static const struct ng_parse_struct_field ng_nat_redirect_proto_fields
[]
96 = NG_NAT_REDIRECT_PROTO_TYPE_INFO(&ng_nat_description_type
);
97 static const struct ng_parse_type ng_nat_redirect_proto_type
= {
98 &ng_parse_struct_type
,
99 &ng_nat_redirect_proto_fields
102 /* Parse type for struct ng_nat_add_server. */
103 static const struct ng_parse_struct_field ng_nat_add_server_fields
[]
104 = NG_NAT_ADD_SERVER_TYPE_INFO
;
105 static const struct ng_parse_type ng_nat_add_server_type
= {
106 &ng_parse_struct_type
,
107 &ng_nat_add_server_fields
110 /* Parse type for one struct ng_nat_listrdrs_entry. */
111 static const struct ng_parse_struct_field ng_nat_listrdrs_entry_fields
[]
112 = NG_NAT_LISTRDRS_ENTRY_TYPE_INFO(&ng_nat_description_type
);
113 static const struct ng_parse_type ng_nat_listrdrs_entry_type
= {
114 &ng_parse_struct_type
,
115 &ng_nat_listrdrs_entry_fields
118 /* Parse type for 'redirects' array in struct ng_nat_list_redirects. */
120 ng_nat_listrdrs_ary_getLength(const struct ng_parse_type
*type
,
121 const u_char
*start
, const u_char
*buf
)
123 const struct ng_nat_list_redirects
*lr
;
125 lr
= (const struct ng_nat_list_redirects
*)
126 (buf
- offsetof(struct ng_nat_list_redirects
, redirects
));
127 return lr
->total_count
;
130 static const struct ng_parse_array_info ng_nat_listrdrs_ary_info
= {
131 &ng_nat_listrdrs_entry_type
,
132 &ng_nat_listrdrs_ary_getLength
,
135 static const struct ng_parse_type ng_nat_listrdrs_ary_type
= {
136 &ng_parse_array_type
,
137 &ng_nat_listrdrs_ary_info
140 /* Parse type for struct ng_nat_list_redirects. */
141 static const struct ng_parse_struct_field ng_nat_list_redirects_fields
[]
142 = NG_NAT_LIST_REDIRECTS_TYPE_INFO(&ng_nat_listrdrs_ary_type
);
143 static const struct ng_parse_type ng_nat_list_redirects_type
= {
144 &ng_parse_struct_type
,
145 &ng_nat_list_redirects_fields
148 /* List of commands and how to convert arguments to/from ASCII. */
149 static const struct ng_cmdlist ng_nat_cmdlist
[] = {
154 &ng_parse_ipaddr_type
,
168 &ng_parse_ipaddr_type
,
173 NGM_NAT_REDIRECT_PORT
,
175 &ng_nat_redirect_port_type
,
176 &ng_parse_uint32_type
180 NGM_NAT_REDIRECT_ADDR
,
182 &ng_nat_redirect_addr_type
,
183 &ng_parse_uint32_type
187 NGM_NAT_REDIRECT_PROTO
,
189 &ng_nat_redirect_proto_type
,
190 &ng_parse_uint32_type
194 NGM_NAT_REDIRECT_DYNAMIC
,
196 &ng_parse_uint32_type
,
201 NGM_NAT_REDIRECT_DELETE
,
203 &ng_parse_uint32_type
,
210 &ng_nat_add_server_type
,
215 NGM_NAT_LIST_REDIRECTS
,
218 &ng_nat_list_redirects_type
224 &ng_parse_string_type
,
230 /* Netgraph node type descriptor. */
231 static struct ng_type typestruct
= {
232 .version
= NG_ABI_VERSION
,
233 .name
= NG_NAT_NODE_TYPE
,
234 .constructor
= ng_nat_constructor
,
235 .rcvmsg
= ng_nat_rcvmsg
,
236 .shutdown
= ng_nat_shutdown
,
237 .newhook
= ng_nat_newhook
,
238 .rcvdata
= ng_nat_rcvdata
,
239 .disconnect
= ng_nat_disconnect
,
240 .cmdlist
= ng_nat_cmdlist
,
242 NETGRAPH_INIT(nat
, &typestruct
);
243 MODULE_DEPEND(ng_nat
, libalias
, 1, 1, 1);
245 /* Element for list of redirects. */
246 struct ng_nat_rdr_lst
{
247 STAILQ_ENTRY(ng_nat_rdr_lst
) entries
;
248 struct alias_link
*lnk
;
249 struct ng_nat_listrdrs_entry rdr
;
251 STAILQ_HEAD(rdrhead
, ng_nat_rdr_lst
);
253 /* Information we store for each node. */
255 node_p node
; /* back pointer to node */
256 hook_p in
; /* hook for demasquerading */
257 hook_p out
; /* hook for masquerading */
258 struct libalias
*lib
; /* libalias handler */
259 uint32_t flags
; /* status flags */
260 uint32_t rdrcount
; /* number or redirects in list */
261 uint32_t nextid
; /* for next in turn in list */
262 struct rdrhead redirhead
; /* redirect list header */
264 typedef struct ng_nat_priv
*priv_p
;
266 /* Values of flags */
267 #define NGNAT_CONNECTED 0x1 /* We have both hooks connected */
268 #define NGNAT_ADDR_DEFINED 0x2 /* NGM_NAT_SET_IPADDR happened */
271 ng_nat_constructor(node_p node
)
275 /* Initialize private descriptor. */
276 MALLOC(priv
, priv_p
, sizeof(*priv
), M_NETGRAPH
,
277 M_WAITOK
| M_NULLOK
| M_ZERO
);
281 /* Init aliasing engine. */
282 priv
->lib
= LibAliasInit(NULL
);
283 if (priv
->lib
== NULL
) {
284 FREE(priv
, M_NETGRAPH
);
288 /* Set same ports on. */
289 (void )LibAliasSetMode(priv
->lib
, PKT_ALIAS_SAME_PORTS
,
290 PKT_ALIAS_SAME_PORTS
);
292 /* Init redirects housekeeping. */
295 STAILQ_INIT(&priv
->redirhead
);
297 /* Link structs together. */
298 NG_NODE_SET_PRIVATE(node
, priv
);
302 * libalias is not thread safe, so our node
303 * must be single threaded.
305 NG_NODE_FORCE_WRITER(node
);
311 ng_nat_newhook(node_p node
, hook_p hook
, const char *name
)
313 const priv_p priv
= NG_NODE_PRIVATE(node
);
315 if (strcmp(name
, NG_NAT_HOOK_IN
) == 0) {
317 } else if (strcmp(name
, NG_NAT_HOOK_OUT
) == 0) {
322 if (priv
->out
!= NULL
&&
324 priv
->flags
|= NGNAT_CONNECTED
;
330 ng_nat_rcvmsg(node_p node
, item_p item
, hook_p lasthook
)
332 const priv_p priv
= NG_NODE_PRIVATE(node
);
333 struct ng_mesg
*resp
= NULL
;
337 NGI_GET_MSG(item
, msg
);
339 switch (msg
->header
.typecookie
) {
341 switch (msg
->header
.cmd
) {
342 case NGM_NAT_SET_IPADDR
:
344 struct in_addr
*const ia
= (struct in_addr
*)msg
->data
;
346 if (msg
->header
.arglen
< sizeof(*ia
)) {
351 LibAliasSetAddress(priv
->lib
, *ia
);
353 priv
->flags
|= NGNAT_ADDR_DEFINED
;
356 case NGM_NAT_SET_MODE
:
358 struct ng_nat_mode
*const mode
=
359 (struct ng_nat_mode
*)msg
->data
;
361 if (msg
->header
.arglen
< sizeof(*mode
)) {
366 if (LibAliasSetMode(priv
->lib
,
367 ng_nat_translate_flags(mode
->flags
),
368 ng_nat_translate_flags(mode
->mask
)) < 0) {
374 case NGM_NAT_SET_TARGET
:
376 struct in_addr
*const ia
= (struct in_addr
*)msg
->data
;
378 if (msg
->header
.arglen
< sizeof(*ia
)) {
383 LibAliasSetTarget(priv
->lib
, *ia
);
386 case NGM_NAT_REDIRECT_PORT
:
388 struct ng_nat_rdr_lst
*entry
;
389 struct ng_nat_redirect_port
*const rp
=
390 (struct ng_nat_redirect_port
*)msg
->data
;
392 if (msg
->header
.arglen
< sizeof(*rp
)) {
397 if ((entry
= kmalloc(sizeof(struct ng_nat_rdr_lst
),
398 M_NETGRAPH
, M_WAITOK
| M_NULLOK
| M_ZERO
)) == NULL
) {
403 /* Try actual redirect. */
404 entry
->lnk
= LibAliasRedirectPort(priv
->lib
,
405 rp
->local_addr
, htons(rp
->local_port
),
406 rp
->remote_addr
, htons(rp
->remote_port
),
407 rp
->alias_addr
, htons(rp
->alias_port
),
410 if (entry
->lnk
== NULL
) {
412 FREE(entry
, M_NETGRAPH
);
416 /* Successful, save info in our internal list. */
417 entry
->rdr
.local_addr
= rp
->local_addr
;
418 entry
->rdr
.alias_addr
= rp
->alias_addr
;
419 entry
->rdr
.remote_addr
= rp
->remote_addr
;
420 entry
->rdr
.local_port
= rp
->local_port
;
421 entry
->rdr
.alias_port
= rp
->alias_port
;
422 entry
->rdr
.remote_port
= rp
->remote_port
;
423 entry
->rdr
.proto
= rp
->proto
;
424 bcopy(rp
->description
, entry
->rdr
.description
,
427 /* Safety precaution. */
428 entry
->rdr
.description
[NG_NAT_DESC_LENGTH
-1] = '\0';
430 entry
->rdr
.id
= priv
->nextid
++;
433 /* Link to list of redirects. */
434 STAILQ_INSERT_TAIL(&priv
->redirhead
, entry
, entries
);
436 /* Response with id of newly added entry. */
437 NG_MKRESPONSE(resp
, msg
, sizeof(entry
->rdr
.id
), M_WAITOK
| M_NULLOK
);
442 bcopy(&entry
->rdr
.id
, resp
->data
, sizeof(entry
->rdr
.id
));
445 case NGM_NAT_REDIRECT_ADDR
:
447 struct ng_nat_rdr_lst
*entry
;
448 struct ng_nat_redirect_addr
*const ra
=
449 (struct ng_nat_redirect_addr
*)msg
->data
;
451 if (msg
->header
.arglen
< sizeof(*ra
)) {
456 if ((entry
= kmalloc(sizeof(struct ng_nat_rdr_lst
),
457 M_NETGRAPH
, M_WAITOK
| M_NULLOK
| M_ZERO
)) == NULL
) {
462 /* Try actual redirect. */
463 entry
->lnk
= LibAliasRedirectAddr(priv
->lib
,
464 ra
->local_addr
, ra
->alias_addr
);
466 if (entry
->lnk
== NULL
) {
468 FREE(entry
, M_NETGRAPH
);
472 /* Successful, save info in our internal list. */
473 entry
->rdr
.local_addr
= ra
->local_addr
;
474 entry
->rdr
.alias_addr
= ra
->alias_addr
;
475 entry
->rdr
.proto
= NG_NAT_REDIRPROTO_ADDR
;
476 bcopy(ra
->description
, entry
->rdr
.description
,
479 /* Safety precaution. */
480 entry
->rdr
.description
[NG_NAT_DESC_LENGTH
-1] = '\0';
482 entry
->rdr
.id
= priv
->nextid
++;
485 /* Link to list of redirects. */
486 STAILQ_INSERT_TAIL(&priv
->redirhead
, entry
, entries
);
488 /* Response with id of newly added entry. */
489 NG_MKRESPONSE(resp
, msg
, sizeof(entry
->rdr
.id
), M_WAITOK
| M_NULLOK
);
494 bcopy(&entry
->rdr
.id
, resp
->data
, sizeof(entry
->rdr
.id
));
497 case NGM_NAT_REDIRECT_PROTO
:
499 struct ng_nat_rdr_lst
*entry
;
500 struct ng_nat_redirect_proto
*const rp
=
501 (struct ng_nat_redirect_proto
*)msg
->data
;
503 if (msg
->header
.arglen
< sizeof(*rp
)) {
508 if ((entry
= kmalloc(sizeof(struct ng_nat_rdr_lst
),
509 M_NETGRAPH
, M_WAITOK
| M_NULLOK
| M_ZERO
)) == NULL
) {
514 /* Try actual redirect. */
515 entry
->lnk
= LibAliasRedirectProto(priv
->lib
,
516 rp
->local_addr
, rp
->remote_addr
,
517 rp
->alias_addr
, rp
->proto
);
519 if (entry
->lnk
== NULL
) {
521 FREE(entry
, M_NETGRAPH
);
525 /* Successful, save info in our internal list. */
526 entry
->rdr
.local_addr
= rp
->local_addr
;
527 entry
->rdr
.alias_addr
= rp
->alias_addr
;
528 entry
->rdr
.remote_addr
= rp
->remote_addr
;
529 entry
->rdr
.proto
= rp
->proto
;
530 bcopy(rp
->description
, entry
->rdr
.description
,
533 /* Safety precaution. */
534 entry
->rdr
.description
[NG_NAT_DESC_LENGTH
-1] = '\0';
536 entry
->rdr
.id
= priv
->nextid
++;
539 /* Link to list of redirects. */
540 STAILQ_INSERT_TAIL(&priv
->redirhead
, entry
, entries
);
542 /* Response with id of newly added entry. */
543 NG_MKRESPONSE(resp
, msg
, sizeof(entry
->rdr
.id
), M_WAITOK
| M_NULLOK
);
548 bcopy(&entry
->rdr
.id
, resp
->data
, sizeof(entry
->rdr
.id
));
551 case NGM_NAT_REDIRECT_DYNAMIC
:
552 case NGM_NAT_REDIRECT_DELETE
:
554 struct ng_nat_rdr_lst
*entry
;
555 uint32_t *const id
= (uint32_t *)msg
->data
;
557 if (msg
->header
.arglen
< sizeof(*id
)) {
562 /* Find entry with supplied id. */
563 STAILQ_FOREACH(entry
, &priv
->redirhead
, entries
) {
564 if (entry
->rdr
.id
== *id
)
574 if (msg
->header
.cmd
== NGM_NAT_REDIRECT_DYNAMIC
) {
575 if (LibAliasRedirectDynamic(priv
->lib
,
577 error
= ENOTTY
; /* XXX Something better? */
580 } else { /* NGM_NAT_REDIRECT_DELETE */
581 LibAliasRedirectDelete(priv
->lib
, entry
->lnk
);
584 /* Delete entry from our internal list. */
586 STAILQ_REMOVE(&priv
->redirhead
, entry
, ng_nat_rdr_lst
, entries
);
587 FREE(entry
, M_NETGRAPH
);
590 case NGM_NAT_ADD_SERVER
:
592 struct ng_nat_rdr_lst
*entry
;
593 struct ng_nat_add_server
*const as
=
594 (struct ng_nat_add_server
*)msg
->data
;
596 if (msg
->header
.arglen
< sizeof(*as
)) {
601 /* Find entry with supplied id. */
602 STAILQ_FOREACH(entry
, &priv
->redirhead
, entries
) {
603 if (entry
->rdr
.id
== as
->id
)
613 if (LibAliasAddServer(priv
->lib
, entry
->lnk
,
614 as
->addr
, htons(as
->port
)) == -1) {
622 case NGM_NAT_LIST_REDIRECTS
:
624 struct ng_nat_rdr_lst
*entry
;
625 struct ng_nat_list_redirects
*ary
;
628 NG_MKRESPONSE(resp
, msg
, sizeof(*ary
) +
629 (priv
->rdrcount
) * sizeof(*entry
), M_WAITOK
| M_NULLOK
);
635 ary
= (struct ng_nat_list_redirects
*)resp
->data
;
636 ary
->total_count
= priv
->rdrcount
;
638 STAILQ_FOREACH(entry
, &priv
->redirhead
, entries
) {
639 bcopy(&entry
->rdr
, &ary
->redirects
[i
++],
640 sizeof(struct ng_nat_listrdrs_entry
));
644 case NGM_NAT_PROXY_RULE
:
646 char *cmd
= (char *)msg
->data
;
648 if (msg
->header
.arglen
< 6) {
653 if (LibAliasProxyRule(priv
->lib
, cmd
) != 0)
658 error
= EINVAL
; /* unknown command */
663 error
= EINVAL
; /* unknown cookie type */
667 NG_RESPOND_MSG(error
, node
, item
, resp
);
673 ng_nat_rcvdata(hook_p hook
, item_p item
)
675 const priv_p priv
= NG_NODE_PRIVATE(NG_HOOK_NODE(hook
));
681 /* We have no required hooks. */
682 if (!(priv
->flags
& NGNAT_CONNECTED
)) {
687 /* We have no alias address yet to do anything. */
688 if (!(priv
->flags
& NGNAT_ADDR_DEFINED
))
693 if ((m
= m_megapullup(m
, m
->m_pkthdr
.len
)) == NULL
) {
694 NGI_M(item
) = NULL
; /* avoid double free */
702 ip
= mtod(m
, struct ip
*);
704 KASSERT(m
->m_pkthdr
.len
== ntohs(ip
->ip_len
),
705 ("ng_nat: ip_len != m_pkthdr.len"));
707 if (hook
== priv
->in
) {
708 rval
= LibAliasIn(priv
->lib
, c
, m
->m_len
+ M_TRAILINGSPACE(m
));
709 if (rval
!= PKT_ALIAS_OK
&&
710 rval
!= PKT_ALIAS_FOUND_HEADER_FRAGMENT
) {
714 } else if (hook
== priv
->out
) {
715 rval
= LibAliasOut(priv
->lib
, c
, m
->m_len
+ M_TRAILINGSPACE(m
));
716 if (rval
!= PKT_ALIAS_OK
) {
721 panic("ng_nat: unknown hook!\n");
723 m
->m_pkthdr
.len
= m
->m_len
= ntohs(ip
->ip_len
);
725 if ((ip
->ip_off
& htons(IP_OFFMASK
)) == 0 &&
726 ip
->ip_p
== IPPROTO_TCP
) {
727 struct tcphdr
*th
= (struct tcphdr
*)((caddr_t
)ip
+
731 * Here is our terrible HACK.
733 * Sometimes LibAlias edits contents of TCP packet.
734 * In this case it needs to recompute full TCP
735 * checksum. However, the problem is that LibAlias
736 * doesn't have any idea about checksum offloading
737 * in kernel. To workaround this, we do not do
738 * checksumming in LibAlias, but only mark the
739 * packets in th_x2 field. If we receive a marked
740 * packet, we calculate correct checksum for it
741 * aware of offloading.
743 * Why do I do such a terrible hack instead of
744 * recalculating checksum for each packet?
745 * Because the previous checksum was not checked!
746 * Recalculating checksums for EVERY packet will
747 * hide ALL transmission errors. Yes, marked packets
748 * still suffer from this problem. But, sigh, natd(8)
749 * has this problem, too.
754 ip
->ip_len
= ntohs(ip
->ip_len
);
755 th
->th_sum
= in_pseudo(ip
->ip_src
.s_addr
,
756 ip
->ip_dst
.s_addr
, htons(IPPROTO_TCP
+
757 ip
->ip_len
- (ip
->ip_hl
<< 2)));
759 if ((m
->m_pkthdr
.csum_flags
& CSUM_TCP
) == 0) {
760 m
->m_pkthdr
.csum_data
= offsetof(struct tcphdr
,
764 ip
->ip_len
= htons(ip
->ip_len
);
769 if (hook
== priv
->in
)
770 NG_FWD_ITEM_HOOK(error
, item
, priv
->out
);
772 NG_FWD_ITEM_HOOK(error
, item
, priv
->in
);
778 ng_nat_shutdown(node_p node
)
780 const priv_p priv
= NG_NODE_PRIVATE(node
);
782 NG_NODE_SET_PRIVATE(node
, NULL
);
785 /* Free redirects list. */
786 while (!STAILQ_EMPTY(&priv
->redirhead
)) {
787 struct ng_nat_rdr_lst
*entry
= STAILQ_FIRST(&priv
->redirhead
);
788 STAILQ_REMOVE_HEAD(&priv
->redirhead
, entries
);
789 FREE(entry
, M_NETGRAPH
);
793 LibAliasUninit(priv
->lib
);
794 FREE(priv
, M_NETGRAPH
);
800 ng_nat_disconnect(hook_p hook
)
802 const priv_p priv
= NG_NODE_PRIVATE(NG_HOOK_NODE(hook
));
804 priv
->flags
&= ~NGNAT_CONNECTED
;
806 if (hook
== priv
->out
)
808 if (hook
== priv
->in
)
811 if (priv
->out
== NULL
&& priv
->in
== NULL
)
812 ng_rmnode_self(NG_HOOK_NODE(hook
));
818 ng_nat_translate_flags(unsigned int x
)
820 unsigned int res
= 0;
823 res
|= PKT_ALIAS_LOG
;
824 if (x
& NG_NAT_DENY_INCOMING
)
825 res
|= PKT_ALIAS_DENY_INCOMING
;
826 if (x
& NG_NAT_SAME_PORTS
)
827 res
|= PKT_ALIAS_SAME_PORTS
;
828 if (x
& NG_NAT_UNREGISTERED_ONLY
)
829 res
|= PKT_ALIAS_UNREGISTERED_ONLY
;
830 if (x
& NG_NAT_RESET_ON_ADDR_CHANGE
)
831 res
|= PKT_ALIAS_RESET_ON_ADDR_CHANGE
;
832 if (x
& NG_NAT_PROXY_ONLY
)
833 res
|= PKT_ALIAS_PROXY_ONLY
;
834 if (x
& NG_NAT_REVERSE
)
835 res
|= PKT_ALIAS_REVERSE
;