Open ports for NAT using NAT-PMP and UPnP IGD

Earlier, I heard many times that UPnP somehow can independently open ports (perform Port Forwarding on a router) on request from a host from the local network. However, exactly how this is happening, and which protocols are used for this, have until now been covered in a veil of fog for me.
In this article I want to briefly describe how two mechanisms for port forwarding work, namely NAT Port Mapping Protocol and Internet Gateway Device (IGD) Protocol , which is part of the UPnP protocol suite. To my surprise, I found that in RuNet information on this issue is more than scarce, which prompted me to write this note.
To begin with, I’ll give a brief FAQ:
Q: What are these protocols for?
A: To create a rule for forwarding a specific TCP / UDP port (Port Forwarding) on a router, not manually, but “automatically”, i.e. on request from the host on the internal network.
Q: How is this implemented?
A: The device behind NAT sends a request to the router indicating the internal and external port numbers and protocol type (TCP / UDP). If the specified external port is free, the router forms a broadcast rule for itself and reports to the requesting computer about the successful completion of the request.
Q: Does the router authenticate / authorize requests to open a port?
A: No, not carried out.
Now, let's consider the operation of these protocols in more detail (under the cut).
Port mapping protocol
NAT-PMP is described in RFC 6886. For its work, it uses the UDP port of server 5351.
Let us consider the protocol using a specific example - the Vuze 5.7 torrent client for Windows 7.
Note: NAT-PMP in Vuze is turned off by default. It must be activated in the plugin settings.
1. Launch Wireshark. In the filter line, enter nat-pmp
2. Runs Vuze.
3. Stop packet capture, see the results.
I got the following:

In total, we see 6 packets (3 requests and 3 responses).
The first 2 are a request for an external address of the router and a response indicating this address. We will not dwell on them in detail and better consider how port mapping occurs on the example of packets 3-4.
Request:

Here we see that a request is made to forward the external UDP port 48166 to the same internal port. Interestingly, the protocol does not indicate the address of the host to which the broadcast should take place (Inside Local in Cisco terminology). This means that the router must take the packet source address from the IP header and use it as the Inside Local.
The Requested Port Mapping Lifetime parameter is expected to mean the lifetime of the entry in the translation table.
Answer:

As we can see, the router supposedly created the requested broadcast and responded with the Success code . The Seconds Since Start of Epoch parameter means the time since the translation table was initialized (i.e., since the last reboot of the router).
Mapping of TCP ports occurs in exactly the same way and differs only in the value of the Opcode field .
After the application has stopped using these ports, it can send a request to the router to remove the broadcast.
The main difference between a delete request and a create request is that the Lifetime parameter is set to zero.
Here's what happens if we close Vuze.
Request:

Answer:

This is the end of the NAT-PMP review; I propose moving on to the somewhat more sophisticated UPnP IGD.
Internet Group Device Protocol
This protocol uses SOAP to exchange its messages.
However, unlike NAT-PMP, IGD does not use a fixed server port number, therefore, before exchanging messages, you must first find out this port. This is done using the SSDP protocol (this protocol is part of UPnP and is used to discover services).
We launch a torrent client. It generates an SSDP request and sends it to the multicast address 239.255.255.250.

The router forms the response and sends it already unicast:

Inside the response, we can see the URL for interaction with the router via the IGD protocol.
Next, Vuze connects to the router at the specified URL and receives XML with information about this device, including a set of URIs for managing some functions of the router. After the desired URI is found in rootDesc.xml, Vuze sends a SOAP request to create a NAT translation for the found URI.
Note: before requesting the creation of a broadcast, Vuze forced the router to list all available Port Forwardings. Why this was done, I can only guess.
SOAP request for creating a UDP port translation:

As mentioned earlier, Vuze took the required URI (immediately after POST) from rootDesc.xml. To add a translation, use a function called AddPortMapping .
It can also be noted that, in contrast to NAT-PMP, the Inside Local address is indicated inside the protocol itself.
Similar to NAT-PMP, when closing a torrent client, the mappings of forwarded ports are deleted. This is done by the DeletePortMapping function :

You can notice that to delete a rule it is enough to specify only the protocol type (UDP) and the external port number, without specifying the rest of the parameters.
Conclusion
In this article, we examined two fairly simple ways to create Port Forwarding rules on a home router by command from a host on the local network. It remains only to note that if you consider the work of these protocols as a threat to the security of your home network, you can try to turn them off (although, of course, it is much better to entrust security issues to the utility that is designed for this - the firewall). In the case of my Zyxel Giga II, on which, by the way, all tests were carried out, this is done by the no service upnp CLI command (it is noteworthy that the UPnP enable / disable option is not available in the web interface).