struct ifnet is private to kernel code and is hidden from the userland
code unless you define a macro _KERNEL_STRUCTURES. Although other people
argue that it should be exposed as it is on other BSDs, that's the way
it is on DragonFly BSD.
Thanks to YONETANI Tomokazu for DragonFly BSD patches
This change causes CreatePCPMap to return a PCP_ERR_NO_RESOURCES
response when upnp_redirect_internal does not succeed;
previously, no error code was returned in this case.
The eport_first variable now gets initialized in the first
iteration of the while loop; the assignment right before the
loop should have been removed in the previous commit.
The find_available_eport function that was intended to check if
at least one eport is allowed for a given iaddr/iport does not
work as intended; for example, it does not properly handle rule
precedence (i.e., it considers allow rules even if they are
effectively masked by earlier deny rules), and it also does not
handle the case where no rules are specified at all (which
should default to accept in order to be consistent with
check_upnp_rule_against_permissions). The present change removes
this function and instead integrates the check into the existing
while loop that iterates over all eports.
When skipping ports that are in use or not allowed, the existing
NAT-PMP code will consider port zero as a candidate eport after
wraparound occurs. Since this is not a legal port, we skip over it.
port zero as an eport value.
These two break statements are redundant: The subsequent continue
statement will cause the loop condition to be re-evaluated, at which
point the loop will terminate if resp[3] != 0.
Instead of returning code 3 ("Network Failure"), we should the
more appropriate code 4 ("Out of resources") when no external
port is available for a mapping.
The NAT-PMP code attempts to find a different eport if the
requested one is already in use. If all eports are in use, that
would previously cause the code to iterate through the range of
eports forever. To avoid this case, we keep track of the first
eport we attempted to use and abort the loop once we've cycled
through all possible values exactly once (which takes us back
to the initial eport).