From fffba935e4085724c899c44c9fb5a10dede5016e Mon Sep 17 00:00:00 2001 From: Alexander Motin Date: Sat, 1 Mar 2008 17:14:02 +0000 Subject: [PATCH] Add support for the libalias redirect functionality. Submitted by: Vadim Goncharov --- share/man/man4/ng_nat.4 | 190 +++++++++++++++++- sys/netgraph/ng_nat.c | 432 +++++++++++++++++++++++++++++++++++++++- sys/netgraph/ng_nat.h | 127 ++++++++++++ 3 files changed, 746 insertions(+), 3 deletions(-) diff --git a/share/man/man4/ng_nat.4 b/share/man/man4/ng_nat.4 index dcb521f7fa7b..cc8970338a23 100644 --- a/share/man/man4/ng_nat.4 +++ b/share/man/man4/ng_nat.4 @@ -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 diff --git a/sys/netgraph/ng_nat.c b/sys/netgraph/ng_nat.c index fb6e947ad4ba..0d1e5132cbb2 100644 --- a/sys/netgraph/ng_nat.c +++ b/sys/netgraph/ng_nat.c @@ -63,7 +63,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. */ @@ -89,6 +167,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 } }; @@ -107,6 +241,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 */ @@ -114,6 +256,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; @@ -143,6 +288,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; @@ -232,6 +382,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; @@ -359,6 +780,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); diff --git a/sys/netgraph/ng_nat.h b/sys/netgraph/ng_nat.h index a548cd261e7b..f5eba597295a 100644 --- a/sys/netgraph/ng_nat.h +++ b/sys/netgraph/ng_nat.h @@ -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 }, \ + { "udp", &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, };