net: verify NAT port usage in tcp_selectport

Signed-off-by: Zhe Weng <wengzhe@xiaomi.com>
This commit is contained in:
Zhe Weng 2022-10-26 14:31:04 +08:00 committed by Xiang Xiao
parent b595430578
commit 0a4e01d712
4 changed files with 62 additions and 3 deletions

View File

@ -321,4 +321,34 @@ int ipv4_nat_outbound(FAR struct net_driver_s *dev,
return OK; return OK;
} }
/****************************************************************************
* Name: ipv4_nat_port_inuse
*
* Description:
* Check whether a port is currently used by NAT.
*
* Input Parameters:
* protocol - The L4 protocol of the packet.
* ip - The IP bind with the port (in network byte order).
* port - The port number to check (in network byte order).
*
* Returned Value:
* True if the port is already used by NAT, otherwise false.
*
****************************************************************************/
bool ipv4_nat_port_inuse(uint8_t protocol, in_addr_t ip, uint16_t port)
{
FAR struct ipv4_nat_entry *entry =
ipv4_nat_inbound_entry_find(protocol, port);
/* Not checking ip is enough for single NAT device, may save external_ip in
* entry for multiple device support in future.
*/
UNUSED(ip);
return entry != NULL;
}
#endif /* CONFIG_NET_NAT && CONFIG_NET_IPv4 */ #endif /* CONFIG_NET_NAT && CONFIG_NET_IPv4 */

View File

@ -62,7 +62,6 @@ 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: Implement this, need to consider local ports and nat ports.
* TODO: Shall we let the chosen port same as local_port if possible? * 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 # warning Missing logic

View File

@ -27,6 +27,7 @@
#include <nuttx/config.h> #include <nuttx/config.h>
#include <stdbool.h>
#include <stdint.h> #include <stdint.h>
#include <netinet/in.h> #include <netinet/in.h>
@ -156,6 +157,24 @@ int ipv4_nat_inbound(FAR struct net_driver_s *dev,
int ipv4_nat_outbound(FAR struct net_driver_s *dev, int ipv4_nat_outbound(FAR struct net_driver_s *dev,
FAR struct ipv4_hdr_s *ipv4); FAR struct ipv4_hdr_s *ipv4);
/****************************************************************************
* Name: ipv4_nat_port_inuse
*
* Description:
* Check whether a port is currently used by NAT.
*
* Input Parameters:
* protocol - The L4 protocol of the packet.
* ip - The IP bind with the port (in network byte order).
* port - The port number to check (in network byte order).
*
* Returned Value:
* True if the port is already used by NAT, otherwise false.
*
****************************************************************************/
bool ipv4_nat_port_inuse(uint8_t protocol, in_addr_t ip, uint16_t port);
/**************************************************************************** /****************************************************************************
* Name: ipv4_nat_inbound_entry_find * Name: ipv4_nat_inbound_entry_find
* *

View File

@ -68,6 +68,7 @@
#include "tcp/tcp.h" #include "tcp/tcp.h"
#include "arp/arp.h" #include "arp/arp.h"
#include "icmpv6/icmpv6.h" #include "icmpv6/icmpv6.h"
#include "nat/nat.h"
/**************************************************************************** /****************************************************************************
* Private Data * Private Data
@ -244,7 +245,12 @@ static int tcp_selectport(uint8_t domain,
portno = HTONS(g_last_tcp_port); portno = HTONS(g_last_tcp_port);
} }
while (tcp_listener(domain, ipaddr, portno)); while (tcp_listener(domain, ipaddr, portno)
#if defined(CONFIG_NET_NAT) && defined(CONFIG_NET_IPv4)
|| (domain == PF_INET &&
ipv4_nat_port_inuse(IP_PROTO_TCP, ipaddr->ipv4, portno))
#endif
);
} }
else else
{ {
@ -252,7 +258,12 @@ static int tcp_selectport(uint8_t domain,
* connection is using this local port. * connection is using this local port.
*/ */
if (tcp_listener(domain, ipaddr, portno)) if (tcp_listener(domain, ipaddr, portno)
#if defined(CONFIG_NET_NAT) && defined(CONFIG_NET_IPv4)
|| (domain == PF_INET &&
ipv4_nat_port_inuse(IP_PROTO_TCP, ipaddr->ipv4, portno))
#endif
)
{ {
/* It is in use... return EADDRINUSE */ /* It is in use... return EADDRINUSE */