diff --git a/include/net/if.h b/include/net/if.h index aa6adcf3a6a..299bfdc763b 100644 --- a/include/net/if.h +++ b/include/net/if.h @@ -53,6 +53,7 @@ #define IFF_LOOPBACK (1 << 5) /* Is a loopback net */ #define IFF_POINTOPOINT (1 << 6) /* Is point-to-point link */ #define IFF_NOARP (1 << 7) /* ARP is not required for this packet */ +#define IFF_NAT (1 << 8) /* NAT is enabled for this interface */ #define IFF_MULTICAST (1 << 12) /* Supports multicast. */ #define IFF_BROADCAST (1 << 13) /* Broadcast address valid. */ @@ -61,6 +62,7 @@ #define IFF_SET_UP(f) do { (f) |= IFF_UP; } while (0) #define IFF_SET_RUNNING(f) do { (f) |= IFF_RUNNING; } while (0) #define IFF_SET_NOARP(f) do { (f) |= IFF_NOARP; } while (0) +#define IFF_SET_NAT(f) do { (f) |= IFF_NAT; } while (0) #define IFF_SET_LOOPBACK(f) do { (f) |= IFF_LOOPBACK; } while (0) #define IFF_SET_POINTOPOINT(f) do { (f) |= IFF_POINTOPOINT; } while (0) #define IFF_SET_MULTICAST(f) do { (f) |= IFF_MULTICAST; } while (0) @@ -69,6 +71,7 @@ #define IFF_CLR_UP(f) do { (f) &= ~IFF_UP; } while (0) #define IFF_CLR_RUNNING(f) do { (f) &= ~IFF_RUNNING; } while (0) #define IFF_CLR_NOARP(f) do { (f) &= ~IFF_NOARP; } while (0) +#define IFF_CLR_NAT(f) do { (f) &= ~IFF_NAT; } while (0) #define IFF_CLR_LOOPBACK(f) do { (f) &= ~IFF_LOOPBACK; } while (0) #define IFF_CLR_POINTOPOINT(f) do { (f) &= ~IFF_POINTOPOINT; } while (0) #define IFF_CLR_MULTICAST(f) do { (f) &= ~IFF_MULTICAST; } while (0) @@ -77,6 +80,7 @@ #define IFF_IS_UP(f) (((f) & IFF_UP) != 0) #define IFF_IS_RUNNING(f) (((f) & IFF_RUNNING) != 0) #define IFF_IS_NOARP(f) (((f) & IFF_NOARP) != 0) +#define IFF_IS_NAT(f) (((f) & IFF_NAT) != 0) #define IFF_IS_LOOPBACK(f) (((f) & IFF_LOOPBACK) != 0) #define IFF_IS_POINTOPOINT(f) (((f) & IFF_POINTOPOINT) != 0) #define IFF_IS_MULTICAST(f) (((f) & IFF_MULTICAST) != 0) diff --git a/net/Kconfig b/net/Kconfig index 8dcd20d18ad..c38539fcbf7 100644 --- a/net/Kconfig +++ b/net/Kconfig @@ -320,6 +320,7 @@ menuconfig NET_6LOWPAN source "net/sixlowpan/Kconfig" source "net/ipforward/Kconfig" +source "net/nat/Kconfig" endmenu # Internet Protocol Selection diff --git a/net/Makefile b/net/Makefile index b9b596a80a8..e9e80904db1 100644 --- a/net/Makefile +++ b/net/Makefile @@ -47,6 +47,7 @@ include bluetooth/Make.defs include ieee802154/Make.defs include devif/Make.defs include ipforward/Make.defs +include nat/Make.defs include route/Make.defs include procfs/Make.defs include usrsock/Make.defs diff --git a/net/devif/ipv4_input.c b/net/devif/ipv4_input.c index 338d18f3656..d492fff50d8 100644 --- a/net/devif/ipv4_input.c +++ b/net/devif/ipv4_input.c @@ -103,6 +103,7 @@ #include "ipforward/ipforward.h" #include "devif/devif.h" +#include "nat/nat.h" /**************************************************************************** * Private Data @@ -206,6 +207,16 @@ int ipv4_input(FAR struct net_driver_s *dev) goto drop; } +#ifdef CONFIG_NET_NAT + /* Try NAT inbound, rule matching will be performed in NAT module. */ + + if (ipv4_nat_inbound(dev, ipv4) < 0) + { + nwarn("WARNING: Performing NAT inbound failed!\n"); + goto drop; + } +#endif + /* Get the destination IP address in a friendlier form */ destipaddr = net_ip4addr_conv32(ipv4->destipaddr); diff --git a/net/ipforward/ipv4_forward.c b/net/ipforward/ipv4_forward.c index c0c549dc83d..8da46a528cb 100644 --- a/net/ipforward/ipv4_forward.c +++ b/net/ipforward/ipv4_forward.c @@ -38,6 +38,7 @@ #include "utils/utils.h" #include "sixlowpan/sixlowpan.h" #include "ipforward/ipforward.h" +#include "nat/nat.h" #include "devif/devif.h" #if defined(CONFIG_NET_IPFORWARD) && defined(CONFIG_NET_IPv4) @@ -312,6 +313,18 @@ static int ipv4_dev_forward(FAR struct net_driver_s *dev, goto errout_with_iobchain; } +#ifdef CONFIG_NET_NAT + /* Try NAT outbound, rule matching will be performed in NAT module. */ + + ret = ipv4_nat_outbound(fwd->f_dev, + (FAR struct ipv4_hdr_s *)fwd->f_iob->io_data); + if (ret < 0) + { + nwarn("WARNING: Performing NAT outbound failed, dropping!\n"); + goto errout_with_iobchain; + } +#endif + /* Then set up to forward the packet according to the protocol. */ ret = ipfwd_forward(fwd); diff --git a/net/nat/Kconfig b/net/nat/Kconfig new file mode 100644 index 00000000000..f50d2376952 --- /dev/null +++ b/net/nat/Kconfig @@ -0,0 +1,11 @@ +# +# For a description of the syntax of this configuration file, +# see the file kconfig-language.txt in the NuttX tools repository. +# + +config NET_NAT + bool "Network Address Translation (NAT)" + default n + depends on NET_IPFORWARD + ---help--- + Enable or disable Network Address Translation (NAT) function. diff --git a/net/nat/Make.defs b/net/nat/Make.defs new file mode 100644 index 00000000000..43d185837e3 --- /dev/null +++ b/net/nat/Make.defs @@ -0,0 +1,34 @@ +############################################################################ +# net/nat/Make.defs +# +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. The +# ASF licenses this file to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance with the +# License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. +# +############################################################################ + +# NAT source files + +ifeq ($(CONFIG_NET_NAT),y) + +ifeq ($(CONFIG_NET_IPv4),y) +NET_CSRCS += ipv4_nat.c ipv4_nat_entry.c +endif + +# Include NAT build support + +DEPPATH += --dep-path nat +VPATH += :nat + +endif diff --git a/net/nat/ipv4_nat.c b/net/nat/ipv4_nat.c new file mode 100644 index 00000000000..f1d44155fcc --- /dev/null +++ b/net/nat/ipv4_nat.c @@ -0,0 +1,324 @@ +/**************************************************************************** + * net/nat/ipv4_nat.c + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include + +#include + +#include "nat/nat.h" +#include "utils/utils.h" + +#if defined(CONFIG_NET_NAT) && defined(CONFIG_NET_IPv4) + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* Adjust checksums in headers. */ + +#define chksum_adjust(chksum,old_data,new_data) \ + net_chksum_adjust((FAR uint16_t *)&(chksum), \ + (FAR uint16_t *)&(old_data), sizeof(old_data), \ + (FAR uint16_t *)&(new_data), sizeof(new_data)) + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: ipv4_nat_inbound_tcp + * + * Description: + * Check if a received TCP packet belongs to a NAT entry. If so, translate + * it. + * + * Input Parameters: + * ipv4 - Points to the IPv4 header with dev->d_buf. + * + * Returned Value: + * Zero is returned if NAT is successfully applied, or is not enabled for + * this packet; + * A negated errno value is returned if error occured. + * + * Assumptions: + * Packet is received on NAT device and is targeting at the address + * assigned to the device. + * + ****************************************************************************/ + +#ifdef CONFIG_NET_TCP +static int ipv4_nat_inbound_tcp(FAR struct ipv4_hdr_s *ipv4) +{ + uint16_t iphdrlen = (ipv4->vhl & IPv4_HLMASK) << 2; + FAR struct tcp_hdr_s *tcp = + (FAR struct tcp_hdr_s *)((FAR uint8_t *)ipv4 + iphdrlen); + FAR struct ipv4_nat_entry *entry = + ipv4_nat_inbound_entry_find(IP_PROTO_TCP, tcp->destport); + if (!entry) + { + /* Inbound without entry is OK (e.g. towards NuttX itself), skip NAT. */ + + return OK; + } + + /* Modify port and checksum. */ + + chksum_adjust(tcp->tcpchksum, tcp->destport, entry->local_port); + tcp->destport = entry->local_port; + + /* Modify address and checksum. */ + + chksum_adjust(tcp->tcpchksum, ipv4->destipaddr, entry->local_ip); + chksum_adjust(ipv4->ipchksum, ipv4->destipaddr, entry->local_ip); + net_ipv4addr_hdrcopy(ipv4->destipaddr, &entry->local_ip); + + return OK; +} +#endif + +/**************************************************************************** + * Name: ipv4_nat_outbound_tcp + * + * Description: + * Check if we want to perform NAT with this outbound TCP packet before + * sending it. If so, translate it. + * + * Input Parameters: + * dev - The device to sent the packet. + * ipv4 - Points to the IPv4 header to be filled into dev->d_buf later. + * + * Returned Value: + * Zero is returned if NAT is successfully applied, or is not enabled for + * this packet; + * A negated errno value is returned if error occured. + * + * Assumptions: + * Packet will be sent on NAT device. + * + ****************************************************************************/ + +#ifdef CONFIG_NET_TCP +static int ipv4_nat_outbound_tcp(FAR struct net_driver_s *dev, + FAR struct ipv4_hdr_s *ipv4) +{ + uint16_t iphdrlen = (ipv4->vhl & IPv4_HLMASK) << 2; + FAR struct tcp_hdr_s *tcp = + (FAR struct tcp_hdr_s *)((FAR uint8_t *)ipv4 + iphdrlen); + FAR struct ipv4_nat_entry *entry = ipv4_nat_outbound_entry_find( + IP_PROTO_TCP, net_ip4addr_conv32(ipv4->srcipaddr), tcp->srcport); + if (!entry) + { + /* Outbound entry creation failed, should have corresponding entry. */ + + return -ENOMEM; + } + + /* Modify port and checksum. */ + + chksum_adjust(tcp->tcpchksum, tcp->srcport, entry->external_port); + tcp->srcport = entry->external_port; + + /* Modify address and checksum. */ + + chksum_adjust(tcp->tcpchksum, ipv4->srcipaddr, dev->d_ipaddr); + chksum_adjust(ipv4->ipchksum, ipv4->srcipaddr, dev->d_ipaddr); + net_ipv4addr_hdrcopy(ipv4->srcipaddr, &dev->d_ipaddr); + + return OK; +} +#endif + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: ipv4_nat_enable + * + * Description: + * Enable NAT function on a network device. + * + * Input Parameters: + * dev - The device on which the outbound packets will be masqueraded. + * + * Returned Value: + * Zero is returned if NAT function is successfully enabled on the device; + * A negated errno value is returned if failed. + * + * Assumptions: + * NAT will only be enabled on at most one device. + * + * Limitations: + * External ports are not isolated between devices yet, so if NAT is + * enabled on more than one device, an external port used on one device + * will also be used by same local ip:port on another device. + * + * TODO: + * Support multiple NAT devices with isolated external port mapping. + ****************************************************************************/ + +int ipv4_nat_enable(FAR struct net_driver_s *dev) +{ + if (IFF_IS_NAT(dev->d_flags)) + { + nwarn("WARNING: NAT was already enabled for %s!\n", dev->d_ifname); + return -EEXIST; + } + + IFF_SET_NAT(dev->d_flags); + return OK; +} + +/**************************************************************************** + * Name: ipv4_nat_disable + * + * Description: + * Disable NAT function on a network device. + * + * Input Parameters: + * dev - The device on which the NAT function will be disabled. + * + * Returned Value: + * Zero is returned if NAT function is successfully disabled on the device; + * A negated errno value is returned if failed. + * + ****************************************************************************/ + +int ipv4_nat_disable(FAR struct net_driver_s *dev) +{ + if (!IFF_IS_NAT(dev->d_flags)) + { + nwarn("WARNING: NAT was not enabled for %s!\n", dev->d_ifname); + return -ENODEV; + } + + /* TODO: Clear entries related to dev. */ + + IFF_CLR_NAT(dev->d_flags); + return OK; +} + +/**************************************************************************** + * Name: ipv4_nat_inbound + * + * Description: + * Check if a received packet belongs to a NAT entry. If so, translate it. + * + * Input Parameters: + * dev - The device on which the packet is received. + * ipv4 - Points to the IPv4 header with dev->d_buf. + * + * Returned Value: + * Zero is returned if NAT is successfully applied, or is not enabled for + * this packet; + * A negated errno value is returned if error occured. + * + ****************************************************************************/ + +int ipv4_nat_inbound(FAR struct net_driver_s *dev, + FAR struct ipv4_hdr_s *ipv4) +{ + /* We only process packets from NAT device and targeting at the address + * assigned to the device. + */ + + if (IFF_IS_NAT(dev->d_flags) && + net_ipv4addr_hdrcmp(ipv4->destipaddr, &dev->d_ipaddr)) + { + switch (ipv4->proto) + { +#ifdef CONFIG_NET_TCP + case IP_PROTO_TCP: + return ipv4_nat_inbound_tcp(ipv4); +#endif + +#ifdef CONFIG_NET_UDP +# warning Missing logic +#endif + +#ifdef CONFIG_NET_ICMP +# warning Missing logic +#endif + } + } + + return OK; +} + +/**************************************************************************** + * Name: ipv4_nat_outbound + * + * Description: + * Check if we want to perform NAT with this outbound packet before sending + * it. If so, translate it. + * + * Input Parameters: + * dev - The device on which the packet will be sent. + * ipv4 - Points to the IPv4 header to be filled into dev->d_buf later. + * + * Returned Value: + * Zero is returned if NAT is successfully applied, or is not enabled for + * this packet; + * A negated errno value is returned if error occured. + * + ****************************************************************************/ + +int ipv4_nat_outbound(FAR struct net_driver_s *dev, + FAR struct ipv4_hdr_s *ipv4) +{ + /* We only process packets targeting at NAT device but not targeting at the + * address assigned to the device. + */ + + if (IFF_IS_NAT(dev->d_flags) && + !net_ipv4addr_hdrcmp(ipv4->destipaddr, &dev->d_ipaddr)) + { + /* TODO: Skip broadcast? */ + + switch (ipv4->proto) + { +#ifdef CONFIG_NET_TCP + case IP_PROTO_TCP: + return ipv4_nat_outbound_tcp(dev, ipv4); +#endif + +#ifdef CONFIG_NET_UDP +# warning Missing logic +#endif + +#ifdef CONFIG_NET_ICMP +# warning Missing logic +#endif + } + } + + return OK; +} + +#endif /* CONFIG_NET_NAT && CONFIG_NET_IPv4 */ diff --git a/net/nat/ipv4_nat_entry.c b/net/nat/ipv4_nat_entry.c new file mode 100644 index 00000000000..e0f7e925131 --- /dev/null +++ b/net/nat/ipv4_nat_entry.c @@ -0,0 +1,203 @@ +/**************************************************************************** + * net/nat/ipv4_nat_entry.c + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include + +#include +#include + +#include "nat/nat.h" + +#if defined(CONFIG_NET_NAT) && defined(CONFIG_NET_IPv4) + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +static sq_queue_t g_entries; + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: ipv4_nat_select_port + * + * Description: + * Select an available port number for TCP/UDP protocol, or id for ICMP. + * + * Input Parameters: + * protocol - The L4 protocol of the packet. + * local_port - The local port of the packet, as reference. + * + * Returned Value: + * port number on success; 0 on failure + * + ****************************************************************************/ + +static uint16_t ipv4_nat_select_port(uint8_t protocol, uint16_t local_port) +{ + /* TODO: Implement this, need to consider local ports and nat ports. + * TODO: Shall we let the chosen port same as local_port if possible? + * TODO: Also need to modify local port number assignment. + */ + +# warning Missing logic + + return local_port; +} + +/**************************************************************************** + * Name: ipv4_nat_entry_create + * + * Description: + * Create a NAT entry and insert into entry list. + * + * Input Parameters: + * protocol - The L4 protocol of the packet. + * external_port - The external port of the packet. + * local_ip - The local ip of the packet. + * local_port - The local port of the packet. + * + * Returned Value: + * Pointer to entry on success; null on failure + * + ****************************************************************************/ + +static FAR struct ipv4_nat_entry * +ipv4_nat_entry_create(uint8_t protocol, uint16_t external_port, + in_addr_t local_ip, uint16_t local_port) +{ + FAR struct ipv4_nat_entry *entry = + (FAR struct ipv4_nat_entry *)kmm_malloc(sizeof(struct ipv4_nat_entry)); + if (entry == NULL) + { + nwarn("WARNING: Failed to allocate IPv4 NAT entry\n"); + return NULL; + } + + entry->protocol = protocol; + entry->external_port = external_port; + entry->local_ip = local_ip; + entry->local_port = local_port; + + sq_addfirst((FAR sq_entry_t *)entry, &g_entries); + return entry; +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: ipv4_nat_inbound_entry_find + * + * Description: + * Find the inbound entry in NAT entry list. + * + * Input Parameters: + * protocol - The L4 protocol of the packet. + * external_port - The external port of the packet. + * + * Returned Value: + * Pointer to entry on success; null on failure + * + ****************************************************************************/ + +FAR struct ipv4_nat_entry * +ipv4_nat_inbound_entry_find(uint8_t protocol, uint16_t external_port) +{ + FAR sq_entry_t *p; + sq_for_every(&g_entries, p) + { + FAR struct ipv4_nat_entry *entry = (FAR struct ipv4_nat_entry *)p; + if (entry->protocol == protocol && + entry->external_port == external_port) + { + /* TODO: Use hash table, or move recent node to head. */ + + return entry; + } + } + + nwarn("WARNING: Failed to find IPv4 inbound NAT entry for " + "proto=%d, external_port=%d\n", protocol, external_port); + return NULL; +} + +/**************************************************************************** + * Name: ipv4_nat_outbound_entry_find + * + * Description: + * Find the outbound entry in NAT entry list. Create one if corresponding + * entry does not exist. + * + * Input Parameters: + * protocol - The L4 protocol of the packet. + * local_ip - The local ip of the packet. + * local_port - The local port of the packet. + * + * Returned Value: + * Pointer to entry on success; null on failure + * + ****************************************************************************/ + +FAR struct ipv4_nat_entry * +ipv4_nat_outbound_entry_find(uint8_t protocol, in_addr_t local_ip, + uint16_t local_port) +{ + FAR sq_entry_t *p; + sq_for_every(&g_entries, p) + { + FAR struct ipv4_nat_entry *entry = (FAR struct ipv4_nat_entry *)p; + if (entry->protocol == protocol && + net_ipv4addr_cmp(entry->local_ip, local_ip) && + entry->local_port == local_port) + { + /* TODO: Use hash table, or move recent node to head. */ + + return entry; + } + } + + /* Failed to find the entry, create one. */ + + ninfo("INFO: Failed to find IPv4 outbound NAT entry for " + "proto=%d, local=%x:%d, try creating one.\n", + protocol, local_ip, local_port); + + uint16_t external_port = ipv4_nat_select_port(protocol, local_port); + if (!external_port) + { + nwarn("WARNING: Failed to find an available port!\n"); + return NULL; + } + + return ipv4_nat_entry_create(protocol, external_port, local_ip, + local_port); +} + +#endif /* CONFIG_NET_NAT && CONFIG_NET_IPv4 */ diff --git a/net/nat/nat.h b/net/nat/nat.h new file mode 100644 index 00000000000..c5b13e5a3ec --- /dev/null +++ b/net/nat/nat.h @@ -0,0 +1,199 @@ +/**************************************************************************** + * net/nat/nat.h + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +#ifndef __NET_NAT_NAT_H +#define __NET_NAT_NAT_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include + +#include + +#include +#include + +#if defined(CONFIG_NET_NAT) && defined(CONFIG_NET_IPv4) + +/**************************************************************************** + * Public Types + ****************************************************************************/ + +struct ipv4_nat_entry +{ + /* Support for single-linked lists. + * + * TODO: Implement a general hash table, and use it to optimize performance + * here. + */ + + FAR struct ipv4_nat_entry *flink; + + /* Local Network External Network + * |----------------| + * | | external port> peer port> + * |----------------| + * + * Full cone NAT on single WAN only need to save local ip:port and external + * port. For ICMP, save id in port field. + */ + + in_addr_t local_ip; /* IP address of the local (private) host. */ + uint16_t local_port; /* Port of the local (private) host. */ + uint16_t external_port; /* The external port of local (private) host. */ + uint8_t protocol; /* L4 protocol (TCP, UDP etc). */ + + /* TODO: Timeout check and remove outdated entry. */ +}; + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Name: ipv4_nat_enable + * + * Description: + * Enable NAT function on a network device. + * + * Input Parameters: + * dev - The device on which the outbound packets will be masqueraded. + * + * Returned Value: + * Zero is returned if NAT function is successfully enabled on the device; + * A negated errno value is returned if failed. + * + * Assumptions: + * NAT will only be enabled on at most one device. + * + * Limitations: + * External ports are not isolated between devices yet, so if NAT is + * enabled on more than one device, an external port used on one device + * will also be used by same local ip:port on another device. + * + ****************************************************************************/ + +int ipv4_nat_enable(FAR struct net_driver_s *dev); + +/**************************************************************************** + * Name: ipv4_nat_disable + * + * Description: + * Disable NAT function on a network device. + * + * Input Parameters: + * dev - The device on which the NAT function will be disabled. + * + * Returned Value: + * Zero is returned if NAT function is successfully disabled on the device; + * A negated errno value is returned if failed. + * + ****************************************************************************/ + +int ipv4_nat_disable(FAR struct net_driver_s *dev); + +/**************************************************************************** + * Name: ipv4_nat_inbound + * + * Description: + * Check if a received packet belongs to a NAT entry. If so, translate it. + * + * Input Parameters: + * dev - The device on which the packet is received. + * ipv4 - Points to the IPv4 header with dev->d_buf. + * + * Returned Value: + * Zero is returned if NAT is successfully applied, or is not enabled for + * this packet; + * A negated errno value is returned if error occured. + * + ****************************************************************************/ + +int ipv4_nat_inbound(FAR struct net_driver_s *dev, + FAR struct ipv4_hdr_s *ipv4); + +/**************************************************************************** + * Name: ipv4_nat_outbound + * + * Description: + * Check if we want to perform NAT with this outbound packet before sending + * it. If so, translate it. + * + * Input Parameters: + * dev - The device on which the packet will be sent. + * ipv4 - Points to the IPv4 header to be filled into dev->d_buf later. + * + * Returned Value: + * Zero is returned if NAT is successfully applied, or is not enabled for + * this packet; + * A negated errno value is returned if error occured. + * + ****************************************************************************/ + +int ipv4_nat_outbound(FAR struct net_driver_s *dev, + FAR struct ipv4_hdr_s *ipv4); + +/**************************************************************************** + * Name: ipv4_nat_inbound_entry_find + * + * Description: + * Find the inbound entry in NAT entry list. + * + * Input Parameters: + * protocol - The L4 protocol of the packet. + * external_port - The external port of the packet. + * + * Returned Value: + * Pointer to entry on success; null on failure + * + ****************************************************************************/ + +FAR struct ipv4_nat_entry * +ipv4_nat_inbound_entry_find(uint8_t protocol, uint16_t external_port); + +/**************************************************************************** + * Name: ipv4_nat_outbound_entry_find + * + * Description: + * Find the outbound entry in NAT entry list. Create one if corresponding + * entry does not exist. + * + * Input Parameters: + * protocol - The L4 protocol of the packet. + * local_ip - The local ip of the packet. + * local_port - The local port of the packet. + * + * Returned Value: + * Pointer to entry on success; null on failure + * + ****************************************************************************/ + +FAR struct ipv4_nat_entry * +ipv4_nat_outbound_entry_find(uint8_t protocol, in_addr_t local_ip, + uint16_t local_port); + +#endif /* CONFIG_NET_NAT && CONFIG_NET_IPv4 */ +#endif /* __NET_NAT_NAT_H */