OpenPort.Net is a lightweight cross-platform .NET library for automatic NAT port mapping. It lets desktop apps, game servers, voice chat servers, P2P apps and self-hosted tools open router ports automatically using UPnP IGD, NAT-PMP and PCP. No external binaries are required.
dotnet add package OpenPort.NetTarget frameworks:
net8.0netstandard2.1
Current package version: 1.0.0.
using System.Net;
using OpenPort.Net;
using OpenPort.Net.Models;
var client = new OpenPortClient();
var result = await client.OpenAsync(new PortMapping
{
InternalPort = 19132,
ExternalPort = 19132,
Protocol = PortProtocol.Udp,
Description = "My App",
Lifetime = TimeSpan.FromHours(1)
});
if (result.Status is OpenPortStatus.Success or OpenPortStatus.ExternalPortChanged)
{
Console.WriteLine($"Opened with {result.Provider} on external port {result.ExternalPort}");
await client.CloseAsync(result.Mapping!);
}For automatic renew and cleanup:
await using var lease = await client.OpenLeaseAsync(new PortMapping
{
InternalPort = 19132,
ExternalPort = 19132,
Protocol = PortProtocol.Udp,
Description = "My App",
Lifetime = TimeSpan.FromHours(1)
});OpenPortLease renews temporary mappings and closes the mapping when disposed.
The default order is:
- PCP
- NAT-PMP
- UPnP IGD
For full customisation, pass provider instances. This controls both order and implementation:
using OpenPort.Net.Providers;
var client = new OpenPortClient(new OpenPortOptions
{
Providers =
[
new UpnpIgdProvider(TimeSpan.FromSeconds(5)),
new NatPmpProvider(TimeSpan.FromSeconds(5)),
new PcpProvider(TimeSpan.FromSeconds(5))
],
Timeout = TimeSpan.FromSeconds(5)
});You can also implement IPortMappingProvider and put your own provider in the list.
For simple built-in provider reordering, PreferredProtocols is still available:
var client = new OpenPortClient(new OpenPortOptions
{
PreferredProtocols =
[
PortMappingProtocol.UpnpIgd,
PortMappingProtocol.NatPmp,
PortMappingProtocol.Pcp
]
});If you already know the gateway or UPnP root device URL, provide hints:
var client = new OpenPortClient(new OpenPortOptions
{
GatewayAddress = IPAddress.Parse("192.168.1.1"),
UpnpRootDeviceUris = [new Uri("http://192.168.1.1:5000/root.xml")]
});- All operations are async and accept
CancellationToken. - A mapping is not considered open until the gateway reports success.
- If a gateway assigns a different external port, the result status is
ExternalPortChangedandresult.Mappingcontains the assigned port. - Mappings opened by an
OpenPortClientinstance are renewed and closed through the same provider that opened them. - UPnP supports
WANIPConnection:1,WANIPConnection:2andWANPPPConnection:1. - NAT-PMP supports external address lookup, TCP/UDP map, renew and delete.
- PCP supports ANNOUNCE and MAP for TCP/UDP.
dotnet run --project samples/OpenPort.Net.Sample -- 19132 19132 udpdotnet build OpenPort.Net.sln
dotnet test OpenPort.Net.sln
dotnet pack OpenPort.Net/OpenPort.Net.csproj -c Release -o artifactsThe test suite includes protocol codec tests and mocked UPnP, NAT-PMP and PCP routers.
MIT