[BUG] nat_port_select() returned value not safe
Description / Steps to reproduce the issue
Returned Value:
- External port number on success; 0 on failure In some cases,when the return value is 0, it may indicate success.
ipv4_nat_outbound_icmp() use icmp->id as port, but some careless applications may send ICMP request packets with icmp->id == 0, in this case, nat_port_select() will return a port number of 0, this 0 is a selected result, not a failure to find a port.
The return value of 0 is interpreted as an error here, preventing subsequent processes from proceeding.
On which OS does this issue occur?
[OS: Other]
What is the version of your OS?
.
NuttX Version
all
Issue Architecture
[Arch: arm]
Issue Area
[Area: Networking]
Host information
No response
Verification
- [x] I have verified before submitting the report.
@wengzhe could you look at this problem?
@zhhyu7 I think we have two ways to fix it, which way do you think is better?
- Don't allow choosing
icmp->idas0, that is, return a positive number whenlocal_port == 0. - Change the return value type, and use a negative number as an error.
@zhhyu7 I think we have two ways to fix it, which way do you think is better?
- Don't allow choosing
icmp->idas0, that is, return a positive number whenlocal_port == 0.- Change the return value type, and use a negative number as an error.
I believe the second way is better. I'm currently working on a router project using NuttX. During debugging on a PC with Wireshark, I observed that the icmp->id between certain clients and servers are indeed 0. However, as a router, we cannot simply drop these packets.
@zhhyu7 I think we have two ways to fix it, which way do you think is better?
- Don't allow choosing
icmp->idas0, that is, return a positive number whenlocal_port == 0.- Change the return value type, and use a negative number as an error.
I believe the second way is better. I'm currently working on a router project using NuttX. During debugging on a PC with Wireshark, I observed that the
icmp->idbetween certain clients and servers are indeed 0. However, as a router, we cannot simply drop these packets.
@CosmicRoach Both methods will allow clients and servers to communicate. You can try setting local_port in nat_port_select to local_port = MAX(local_port, 1) and see what happens. If nat_port_select returns 1, the NAT will change icmp->id to 1 and continue the remaining steps, and the communication will succeed.
@zhhyu7 I think we have two ways to fix it, which way do you think is better?
- Don't allow choosing
icmp->idas0, that is, return a positive number whenlocal_port == 0.- Change the return value type, and use a negative number as an error.
I believe the second way is better. I'm currently working on a router project using NuttX. During debugging on a PC with Wireshark, I observed that the
icmp->idbetween certain clients and servers are indeed 0. However, as a router, we cannot simply drop these packets.@CosmicRoach Both methods will allow clients and servers to communicate. You can try setting
local_portinnat_port_selecttolocal_port = MAX(local_port, 1)and see what happens. Ifnat_port_selectreturns1, the NAT will changeicmp->idto1and continue the remaining steps, and the communication will succeed.
Got it.
@CosmicRoach could you create PR to fix it?
@CosmicRoach could you create PR to fix it?
Although our ideas are meaningful, after careful consideration and attempts at modification, this may not pose an issue:
-
As an operating system, NuttX should manage Port usage, and I've noticed that the NuttX code already prevents the generation of port 0.
-
In my usage scenario, I only employ the NAT module, where the TCP/IP transport layer and above operate outside NuttX's control. The observed confusion is likely rooted in non-standard usage patterns, which NuttX need not address.
-
Moreover, since this interface is widely used across various scenarios—including UDP, TCP, and environments with or without a TCP/IP stack—making isolated modifications to the ICMP portion would be difficult to maintain compatibility.