MFC: Add support for the libalias redirect functionality.

Submitted by:   Vadim Goncharov <vadim_nuclight@mail.ru>
This commit is contained in:
mav 2008-03-09 20:02:35 +00:00
parent 6195cc13a0
commit 28e6df5f37
3 changed files with 746 additions and 3 deletions

View File

@ -24,7 +24,7 @@
.\"
.\" $FreeBSD$
.\"
.Dd May 6, 2005
.Dd March 1, 2008
.Dt NG_NAT 4
.Os
.Sh NAME
@ -42,7 +42,6 @@ A
node uses
.Xr libalias 3
engine for packet aliasing.
At this moment it supports only the basic functionality of the library.
.Sh HOOKS
This node type has two hooks:
.Bl -tag -width indent
@ -81,7 +80,194 @@ struct ng_nat_mode {
Configure target address for a node.
When an incoming packet not associated with any pre-existing aliasing
link arrives at the host machine, it will be sent to the specified address.
.It Dv NGM_NAT_REDIRECT_PORT Pq Li redirectport
Redirect incoming connections arriving to given port(s) to
another host and port(s).
The following
.Vt "struct ng_nat_redirect_port"
must be supplied as argument.
.Bd -literal
#define NG_NAT_DESC_LENGTH 64
struct ng_nat_redirect_port {
struct in_addr local_addr;
struct in_addr alias_addr;
struct in_addr remote_addr;
uint16_t local_port;
uint16_t alias_port;
uint16_t remote_port;
uint8_t proto;
char description[NG_NAT_DESC_LENGTH];
};
.Ed
.Pp
Redirection is assigned an unique ID which is returned as
response to this message, and
information about redirection added to
list of static redirects which later can be retrieved by
.Dv NGM_NAT_LIST_REDIRECTS
message.
.It Dv NGM_NAT_REDIRECT_ADDR Pq Li redirectaddr
Redirect traffic for public IP address to a machine on the
local network.
This function is known as
.Em static NAT .
The following
.Vt "struct ng_nat_redirect_addr"
must be supplied as argument.
.Bd -literal
struct ng_nat_redirect_addr {
struct in_addr local_addr;
struct in_addr alias_addr;
char description[NG_NAT_DESC_LENGTH];
};
.Ed
.Pp
Unique ID for this redirection is returned as response to this message.
.It Dv NGM_NAT_REDIRECT_PROTO Pq Li redirectproto
Redirect incoming IP packets of protocol
.Va proto
(see
.Xr protocols 5 )
to a machine on the local network.
The following
.Vt "struct ng_nat_redirect_proto"
must be supplied as argument.
.Bd -literal
struct ng_nat_redirect_proto {
struct in_addr local_addr;
struct in_addr alias_addr;
struct in_addr remote_addr;
uint8_t proto;
char description[NG_NAT_DESC_LENGTH];
};
.Ed
.Pp
Unique ID for this redirection is returned as response to this message.
.It Dv NGM_NAT_REDIRECT_DYNAMIC Pq Li redirectdynamic
Mark redirection with specified ID as dynamic, i.e., it will serve
for exactly one next connection and then will be automatically
deleted from internal links table.
Only fully specified links can be made dynamic.
The redirection with this ID is also immediately deleted from
user-visible list of static redirects (available through
.Dv NGM_NAT_LIST_REDIRECTS
message).
.It Dv NGM_NAT_REDIRECT_DELETE Pq Li redirectdelete
Delete redirection with specified ID (currently active
connections are not affected).
.It Dv NGM_NAT_ADD_SERVER Pq Li addserver
Add another server to a pool.
This is used to transparently offload network load on a single server
and distribute the load across a pool of servers, also known as
.Em LSNAT
(RFC 2391).
The following
.Vt "struct ng_nat_add_server"
must be supplied as argument.
.Bd -literal
struct ng_nat_add_server {
uint32_t id;
struct in_addr addr;
uint16_t port;
};
.Ed
.Pp
First, the redirection is set up by
.Dv NGM_NAT_REDIRECT_PORT
or
.Dv NGM_NAT_REDIRECT_ADDR .
Then, ID of that redirection is used in multiple
.Dv NGM_NAT_ADD_SERVER
messages to add necessary number of servers.
For redirections created by
.Dv NGM_NAT_REDIRECT_ADDR ,
the
.Va port
is ignored and could have any value.
Original redirection's parameters
.Va local_addr
and
.Va local_port
are also ignored after
.Dv NGM_NAT_ADD_SERVER
was used (they are effectively replaced by server pool).
.It Dv NGM_NAT_LIST_REDIRECTS Pq Li listredirects
Return list of configured static redirects as
.Vt "struct ng_nat_list_redirects".
.Bd -literal
struct ng_nat_listrdrs_entry {
uint32_t id; /* Anything except zero */
struct in_addr local_addr;
struct in_addr alias_addr;
struct in_addr remote_addr;
uint16_t local_port;
uint16_t alias_port;
uint16_t remote_port;
uint16_t proto; /* Valid proto or NG_NAT_REDIRPROTO_ADDR */
uint16_t lsnat; /* LSNAT servers count */
char description[NG_NAT_DESC_LENGTH];
};
struct ng_nat_list_redirects {
uint32_t total_count;
struct ng_nat_listrdrs_entry redirects[];
};
#define NG_NAT_REDIRPROTO_ADDR (IPPROTO_MAX + 3)
.Ed
.Pp
Entries of the
.Va redirects
array returned in the unified format for all redirect types.
Ports are meaningful only if protocol is either TCP or UDP
and
.Em static NAT
redirection (created by
.Dv NGM_NAT_REDIRECT_ADDR )
is indicated by
.Va proto
set to
.Dv NG_NAT_REDIRPROTO_ADDR .
If
.Va lsnat
servers counter is greater than zero, then
.Va local_addr
and
.Va local_port
are also meaningless.
.It Dv NGM_NAT_PROXY_RULE Pq Li proxyrule
Specify a transparent proxying rule (string must be
supplied as argument).
See
.Xr libalias 3
for details.
.El
.Pp
In all redirection messages
.Va local_addr
and
.Va local_port
mean address and port of target machine in the internal network,
respectively.
If
.Va alias_addr
is zero, then default aliasing address (set by
.Dv NGM_NAT_SET_IPADDR )
is used.
Connections can also be restricted to be accepted only
from specific external machines by using non-zero
.Va remote_addr
and/or
.Va remote_port .
Each redirection assigned an ID which can be later used for
redirection manipulation on individual basis (e.g., removal).
This ID guaranteed to be unique until the node shuts down
(it will not be reused after deletion), and is returned to
user after making each new redirection or can be found in
the stored list of all redirections.
The
.Va description
passed to and from node unchanged, together with ID providing
a way for several entities to concurrently manipulate
redirections in automated way.
.Sh SHUTDOWN
This node shuts down upon receipt of a
.Dv NGM_SHUTDOWN

View File

@ -65,7 +65,85 @@ static const struct ng_parse_struct_field ng_nat_mode_fields[]
= NG_NAT_MODE_INFO;
static const struct ng_parse_type ng_nat_mode_type = {
&ng_parse_struct_type,
ng_nat_mode_fields
&ng_nat_mode_fields
};
/* Parse type for 'description' field in structs. */
static const struct ng_parse_fixedstring_info ng_nat_description_info
= { NG_NAT_DESC_LENGTH };
static const struct ng_parse_type ng_nat_description_type = {
&ng_parse_fixedstring_type,
&ng_nat_description_info
};
/* Parse type for struct ng_nat_redirect_port. */
static const struct ng_parse_struct_field ng_nat_redirect_port_fields[]
= NG_NAT_REDIRECT_PORT_TYPE_INFO(&ng_nat_description_type);
static const struct ng_parse_type ng_nat_redirect_port_type = {
&ng_parse_struct_type,
&ng_nat_redirect_port_fields
};
/* Parse type for struct ng_nat_redirect_addr. */
static const struct ng_parse_struct_field ng_nat_redirect_addr_fields[]
= NG_NAT_REDIRECT_ADDR_TYPE_INFO(&ng_nat_description_type);
static const struct ng_parse_type ng_nat_redirect_addr_type = {
&ng_parse_struct_type,
&ng_nat_redirect_addr_fields
};
/* Parse type for struct ng_nat_redirect_proto. */
static const struct ng_parse_struct_field ng_nat_redirect_proto_fields[]
= NG_NAT_REDIRECT_PROTO_TYPE_INFO(&ng_nat_description_type);
static const struct ng_parse_type ng_nat_redirect_proto_type = {
&ng_parse_struct_type,
&ng_nat_redirect_proto_fields
};
/* Parse type for struct ng_nat_add_server. */
static const struct ng_parse_struct_field ng_nat_add_server_fields[]
= NG_NAT_ADD_SERVER_TYPE_INFO;
static const struct ng_parse_type ng_nat_add_server_type = {
&ng_parse_struct_type,
&ng_nat_add_server_fields
};
/* Parse type for one struct ng_nat_listrdrs_entry. */
static const struct ng_parse_struct_field ng_nat_listrdrs_entry_fields[]
= NG_NAT_LISTRDRS_ENTRY_TYPE_INFO(&ng_nat_description_type);
static const struct ng_parse_type ng_nat_listrdrs_entry_type = {
&ng_parse_struct_type,
&ng_nat_listrdrs_entry_fields
};
/* Parse type for 'redirects' array in struct ng_nat_list_redirects. */
static int
ng_nat_listrdrs_ary_getLength(const struct ng_parse_type *type,
const u_char *start, const u_char *buf)
{
const struct ng_nat_list_redirects *lr;
lr = (const struct ng_nat_list_redirects *)
(buf - offsetof(struct ng_nat_list_redirects, redirects));
return lr->total_count;
}
static const struct ng_parse_array_info ng_nat_listrdrs_ary_info = {
&ng_nat_listrdrs_entry_type,
&ng_nat_listrdrs_ary_getLength,
NULL
};
static const struct ng_parse_type ng_nat_listrdrs_ary_type = {
&ng_parse_array_type,
&ng_nat_listrdrs_ary_info
};
/* Parse type for struct ng_nat_list_redirects. */
static const struct ng_parse_struct_field ng_nat_list_redirects_fields[]
= NG_NAT_LIST_REDIRECTS_TYPE_INFO(&ng_nat_listrdrs_ary_type);
static const struct ng_parse_type ng_nat_list_redirects_type = {
&ng_parse_struct_type,
&ng_nat_list_redirects_fields
};
/* List of commands and how to convert arguments to/from ASCII. */
@ -91,6 +169,62 @@ static const struct ng_cmdlist ng_nat_cmdlist[] = {
&ng_parse_ipaddr_type,
NULL
},
{
NGM_NAT_COOKIE,
NGM_NAT_REDIRECT_PORT,
"redirectport",
&ng_nat_redirect_port_type,
&ng_parse_uint32_type
},
{
NGM_NAT_COOKIE,
NGM_NAT_REDIRECT_ADDR,
"redirectaddr",
&ng_nat_redirect_addr_type,
&ng_parse_uint32_type
},
{
NGM_NAT_COOKIE,
NGM_NAT_REDIRECT_PROTO,
"redirectproto",
&ng_nat_redirect_proto_type,
&ng_parse_uint32_type
},
{
NGM_NAT_COOKIE,
NGM_NAT_REDIRECT_DYNAMIC,
"redirectdynamic",
&ng_parse_uint32_type,
NULL
},
{
NGM_NAT_COOKIE,
NGM_NAT_REDIRECT_DELETE,
"redirectdelete",
&ng_parse_uint32_type,
NULL
},
{
NGM_NAT_COOKIE,
NGM_NAT_ADD_SERVER,
"addserver",
&ng_nat_add_server_type,
NULL
},
{
NGM_NAT_COOKIE,
NGM_NAT_LIST_REDIRECTS,
"listredirects",
NULL,
&ng_nat_list_redirects_type
},
{
NGM_NAT_COOKIE,
NGM_NAT_PROXY_RULE,
"proxyrule",
&ng_parse_string_type,
NULL
},
{ 0 }
};
@ -109,6 +243,14 @@ static struct ng_type typestruct = {
NETGRAPH_INIT(nat, &typestruct);
MODULE_DEPEND(ng_nat, libalias, 1, 1, 1);
/* Element for list of redirects. */
struct ng_nat_rdr_lst {
STAILQ_ENTRY(ng_nat_rdr_lst) entries;
struct alias_link *lnk;
struct ng_nat_listrdrs_entry rdr;
};
STAILQ_HEAD(rdrhead, ng_nat_rdr_lst);
/* Information we store for each node. */
struct ng_nat_priv {
node_p node; /* back pointer to node */
@ -116,6 +258,9 @@ struct ng_nat_priv {
hook_p out; /* hook for masquerading */
struct libalias *lib; /* libalias handler */
uint32_t flags; /* status flags */
uint32_t rdrcount; /* number or redirects in list */
uint32_t nextid; /* for next in turn in list */
struct rdrhead redirhead; /* redirect list header */
};
typedef struct ng_nat_priv *priv_p;
@ -145,6 +290,11 @@ ng_nat_constructor(node_p node)
(void )LibAliasSetMode(priv->lib, PKT_ALIAS_SAME_PORTS,
PKT_ALIAS_SAME_PORTS);
/* Init redirects housekeeping. */
priv->rdrcount = 0;
priv->nextid = 1;
STAILQ_INIT(&priv->redirhead);
/* Link structs together. */
NG_NODE_SET_PRIVATE(node, priv);
priv->node = node;
@ -234,6 +384,277 @@ ng_nat_rcvmsg(node_p node, item_p item, hook_p lasthook)
LibAliasSetTarget(priv->lib, *ia);
}
break;
case NGM_NAT_REDIRECT_PORT:
{
struct ng_nat_rdr_lst *entry;
struct ng_nat_redirect_port *const rp =
(struct ng_nat_redirect_port *)msg->data;
if (msg->header.arglen < sizeof(*rp)) {
error = EINVAL;
break;
}
if ((entry = malloc(sizeof(struct ng_nat_rdr_lst),
M_NETGRAPH, M_NOWAIT | M_ZERO)) == NULL) {
error = ENOMEM;
break;
}
/* Try actual redirect. */
entry->lnk = LibAliasRedirectPort(priv->lib,
rp->local_addr, htons(rp->local_port),
rp->remote_addr, htons(rp->remote_port),
rp->alias_addr, htons(rp->alias_port),
rp->proto);
if (entry->lnk == NULL) {
error = ENOMEM;
FREE(entry, M_NETGRAPH);
break;
}
/* Successful, save info in our internal list. */
entry->rdr.local_addr = rp->local_addr;
entry->rdr.alias_addr = rp->alias_addr;
entry->rdr.remote_addr = rp->remote_addr;
entry->rdr.local_port = rp->local_port;
entry->rdr.alias_port = rp->alias_port;
entry->rdr.remote_port = rp->remote_port;
entry->rdr.proto = rp->proto;
bcopy(rp->description, entry->rdr.description,
NG_NAT_DESC_LENGTH);
/* Safety precaution. */
entry->rdr.description[NG_NAT_DESC_LENGTH-1] = '\0';
entry->rdr.id = priv->nextid++;
priv->rdrcount++;
/* Link to list of redirects. */
STAILQ_INSERT_TAIL(&priv->redirhead, entry, entries);
/* Response with id of newly added entry. */
NG_MKRESPONSE(resp, msg, sizeof(entry->rdr.id), M_NOWAIT);
if (resp == NULL) {
error = ENOMEM;
break;
}
bcopy(&entry->rdr.id, resp->data, sizeof(entry->rdr.id));
}
break;
case NGM_NAT_REDIRECT_ADDR:
{
struct ng_nat_rdr_lst *entry;
struct ng_nat_redirect_addr *const ra =
(struct ng_nat_redirect_addr *)msg->data;
if (msg->header.arglen < sizeof(*ra)) {
error = EINVAL;
break;
}
if ((entry = malloc(sizeof(struct ng_nat_rdr_lst),
M_NETGRAPH, M_NOWAIT | M_ZERO)) == NULL) {
error = ENOMEM;
break;
}
/* Try actual redirect. */
entry->lnk = LibAliasRedirectAddr(priv->lib,
ra->local_addr, ra->alias_addr);
if (entry->lnk == NULL) {
error = ENOMEM;
FREE(entry, M_NETGRAPH);
break;
}
/* Successful, save info in our internal list. */
entry->rdr.local_addr = ra->local_addr;
entry->rdr.alias_addr = ra->alias_addr;
entry->rdr.proto = NG_NAT_REDIRPROTO_ADDR;
bcopy(ra->description, entry->rdr.description,
NG_NAT_DESC_LENGTH);
/* Safety precaution. */
entry->rdr.description[NG_NAT_DESC_LENGTH-1] = '\0';
entry->rdr.id = priv->nextid++;
priv->rdrcount++;
/* Link to list of redirects. */
STAILQ_INSERT_TAIL(&priv->redirhead, entry, entries);
/* Response with id of newly added entry. */
NG_MKRESPONSE(resp, msg, sizeof(entry->rdr.id), M_NOWAIT);
if (resp == NULL) {
error = ENOMEM;
break;
}
bcopy(&entry->rdr.id, resp->data, sizeof(entry->rdr.id));
}
break;
case NGM_NAT_REDIRECT_PROTO:
{
struct ng_nat_rdr_lst *entry;
struct ng_nat_redirect_proto *const rp =
(struct ng_nat_redirect_proto *)msg->data;
if (msg->header.arglen < sizeof(*rp)) {
error = EINVAL;
break;
}
if ((entry = malloc(sizeof(struct ng_nat_rdr_lst),
M_NETGRAPH, M_NOWAIT | M_ZERO)) == NULL) {
error = ENOMEM;
break;
}
/* Try actual redirect. */
entry->lnk = LibAliasRedirectProto(priv->lib,
rp->local_addr, rp->remote_addr,
rp->alias_addr, rp->proto);
if (entry->lnk == NULL) {
error = ENOMEM;
FREE(entry, M_NETGRAPH);
break;
}
/* Successful, save info in our internal list. */
entry->rdr.local_addr = rp->local_addr;
entry->rdr.alias_addr = rp->alias_addr;
entry->rdr.remote_addr = rp->remote_addr;
entry->rdr.proto = rp->proto;
bcopy(rp->description, entry->rdr.description,
NG_NAT_DESC_LENGTH);
/* Safety precaution. */
entry->rdr.description[NG_NAT_DESC_LENGTH-1] = '\0';
entry->rdr.id = priv->nextid++;
priv->rdrcount++;
/* Link to list of redirects. */
STAILQ_INSERT_TAIL(&priv->redirhead, entry, entries);
/* Response with id of newly added entry. */
NG_MKRESPONSE(resp, msg, sizeof(entry->rdr.id), M_NOWAIT);
if (resp == NULL) {
error = ENOMEM;
break;
}
bcopy(&entry->rdr.id, resp->data, sizeof(entry->rdr.id));
}
break;
case NGM_NAT_REDIRECT_DYNAMIC:
case NGM_NAT_REDIRECT_DELETE:
{
struct ng_nat_rdr_lst *entry;
uint32_t *const id = (uint32_t *)msg->data;
if (msg->header.arglen < sizeof(*id)) {
error = EINVAL;
break;
}
/* Find entry with supplied id. */
STAILQ_FOREACH(entry, &priv->redirhead, entries) {
if (entry->rdr.id == *id)
break;
}
/* Not found. */
if (entry == NULL) {
error = ENOENT;
break;
}
if (msg->header.cmd == NGM_NAT_REDIRECT_DYNAMIC) {
if (LibAliasRedirectDynamic(priv->lib,
entry->lnk) == -1) {
error = ENOTTY; /* XXX Something better? */
break;
}
} else { /* NGM_NAT_REDIRECT_DELETE */
LibAliasRedirectDelete(priv->lib, entry->lnk);
}
/* Delete entry from our internal list. */
priv->rdrcount--;
STAILQ_REMOVE(&priv->redirhead, entry, ng_nat_rdr_lst, entries);
FREE(entry, M_NETGRAPH);
}
break;
case NGM_NAT_ADD_SERVER:
{
struct ng_nat_rdr_lst *entry;
struct ng_nat_add_server *const as =
(struct ng_nat_add_server *)msg->data;
if (msg->header.arglen < sizeof(*as)) {
error = EINVAL;
break;
}
/* Find entry with supplied id. */
STAILQ_FOREACH(entry, &priv->redirhead, entries) {
if (entry->rdr.id == as->id)
break;
}
/* Not found. */
if (entry == NULL) {
error = ENOENT;
break;
}
if (LibAliasAddServer(priv->lib, entry->lnk,
as->addr, htons(as->port)) == -1) {
error = ENOMEM;
break;
}
entry->rdr.lsnat++;
}
break;
case NGM_NAT_LIST_REDIRECTS:
{
struct ng_nat_rdr_lst *entry;
struct ng_nat_list_redirects *ary;
int i = 0;
NG_MKRESPONSE(resp, msg, sizeof(*ary) +
(priv->rdrcount) * sizeof(*entry), M_NOWAIT);
if (resp == NULL) {
error = ENOMEM;
break;
}
ary = (struct ng_nat_list_redirects *)resp->data;
ary->total_count = priv->rdrcount;
STAILQ_FOREACH(entry, &priv->redirhead, entries) {
bcopy(&entry->rdr, &ary->redirects[i++],
sizeof(struct ng_nat_listrdrs_entry));
}
}
break;
case NGM_NAT_PROXY_RULE:
{
char *cmd = (char *)msg->data;
if (msg->header.arglen < 6) {
error = EINVAL;
break;
}
if (LibAliasProxyRule(priv->lib, cmd) != 0)
error = ENOMEM;
}
break;
default:
error = EINVAL; /* unknown command */
break;
@ -361,6 +782,15 @@ ng_nat_shutdown(node_p node)
NG_NODE_SET_PRIVATE(node, NULL);
NG_NODE_UNREF(node);
/* Free redirects list. */
while (!STAILQ_EMPTY(&priv->redirhead)) {
struct ng_nat_rdr_lst *entry = STAILQ_FIRST(&priv->redirhead);
STAILQ_REMOVE_HEAD(&priv->redirhead, entries);
FREE(entry, M_NETGRAPH);
};
/* Final free. */
LibAliasUninit(priv->lib);
FREE(priv, M_NETGRAPH);

View File

@ -53,8 +53,135 @@ struct ng_nat_mode {
#define NG_NAT_PROXY_ONLY 0x40
#define NG_NAT_REVERSE 0x80
#define NG_NAT_DESC_LENGTH 64
#define NG_NAT_REDIRPROTO_ADDR (IPPROTO_MAX + 3) /* LibAlias' LINK_ADDR, also unused in in.h */
/* Arguments for NGM_NAT_REDIRECT_PORT message */
struct ng_nat_redirect_port {
struct in_addr local_addr;
struct in_addr alias_addr;
struct in_addr remote_addr;
uint16_t local_port;
uint16_t alias_port;
uint16_t remote_port;
uint8_t proto;
char description[NG_NAT_DESC_LENGTH];
};
/* Keep this in sync with the above structure definition */
#define NG_NAT_REDIRECT_PORT_TYPE_INFO(desctype) { \
{ "local_addr", &ng_parse_ipaddr_type }, \
{ "alias_addr", &ng_parse_ipaddr_type }, \
{ "remote_addr", &ng_parse_ipaddr_type }, \
{ "local_port", &ng_parse_uint16_type }, \
{ "alias_port", &ng_parse_uint16_type }, \
{ "remote_port", &ng_parse_uint16_type }, \
{ "proto", &ng_parse_uint8_type }, \
{ "description", (desctype) }, \
{ NULL } \
}
/* Arguments for NGM_NAT_REDIRECT_ADDR message */
struct ng_nat_redirect_addr {
struct in_addr local_addr;
struct in_addr alias_addr;
char description[NG_NAT_DESC_LENGTH];
};
/* Keep this in sync with the above structure definition */
#define NG_NAT_REDIRECT_ADDR_TYPE_INFO(desctype) { \
{ "local_addr", &ng_parse_ipaddr_type }, \
{ "alias_addr", &ng_parse_ipaddr_type }, \
{ "description", (desctype) }, \
{ NULL } \
}
/* Arguments for NGM_NAT_REDIRECT_PROTO message */
struct ng_nat_redirect_proto {
struct in_addr local_addr;
struct in_addr alias_addr;
struct in_addr remote_addr;
uint8_t proto;
char description[NG_NAT_DESC_LENGTH];
};
/* Keep this in sync with the above structure definition */
#define NG_NAT_REDIRECT_PROTO_TYPE_INFO(desctype) { \
{ "local_addr", &ng_parse_ipaddr_type }, \
{ "alias_addr", &ng_parse_ipaddr_type }, \
{ "remote_addr", &ng_parse_ipaddr_type }, \
{ "proto", &ng_parse_uint8_type }, \
{ "description", (desctype) }, \
{ NULL } \
}
/* Arguments for NGM_NAT_ADD_SERVER message */
struct ng_nat_add_server {
uint32_t id;
struct in_addr addr;
uint16_t port;
};
/* Keep this in sync with the above structure definition */
#define NG_NAT_ADD_SERVER_TYPE_INFO { \
{ "id", &ng_parse_uint32_type }, \
{ "addr", &ng_parse_ipaddr_type }, \
{ "port", &ng_parse_uint16_type }, \
{ NULL } \
}
/* List entry of array returned in NGM_NAT_LIST_REDIRECTS message */
struct ng_nat_listrdrs_entry {
uint32_t id; /* Anything except zero */
struct in_addr local_addr;
struct in_addr alias_addr;
struct in_addr remote_addr;
uint16_t local_port;
uint16_t alias_port;
uint16_t remote_port;
uint16_t proto; /* Valid proto or NG_NAT_REDIRPROTO_ADDR */
uint16_t lsnat; /* LSNAT servers count */
char description[NG_NAT_DESC_LENGTH];
};
/* Keep this in sync with the above structure definition */
#define NG_NAT_LISTRDRS_ENTRY_TYPE_INFO(desctype) { \
{ "id", &ng_parse_uint32_type }, \
{ "local_addr", &ng_parse_ipaddr_type }, \
{ "alias_addr", &ng_parse_ipaddr_type }, \
{ "remote_addr", &ng_parse_ipaddr_type }, \
{ "local_port", &ng_parse_uint16_type }, \
{ "alias_port", &ng_parse_uint16_type }, \
{ "remote_port", &ng_parse_uint16_type }, \
{ "proto", &ng_parse_uint16_type }, \
{ "lsnat", &ng_parse_uint16_type }, \
{ "description", (desctype) }, \
{ NULL } \
}
/* Structure returned by NGM_NAT_LIST_REDIRECTS */
struct ng_nat_list_redirects {
uint32_t total_count;
struct ng_nat_listrdrs_entry redirects[];
};
/* Keep this in sync with the above structure definition */
#define NG_NAT_LIST_REDIRECTS_TYPE_INFO(redirtype) { \
{ "total_count", &ng_parse_uint32_type }, \
{ "redirects", (redirtype) }, \
{ NULL } \
}
enum {
NGM_NAT_SET_IPADDR = 1,
NGM_NAT_SET_MODE,
NGM_NAT_SET_TARGET,
NGM_NAT_REDIRECT_PORT,
NGM_NAT_REDIRECT_ADDR,
NGM_NAT_REDIRECT_PROTO,
NGM_NAT_REDIRECT_DYNAMIC,
NGM_NAT_REDIRECT_DELETE,
NGM_NAT_ADD_SERVER,
NGM_NAT_LIST_REDIRECTS,
NGM_NAT_PROXY_RULE,
};