public override async Task<Mapping> GetSpecificMappingAsync (Protocol protocol, int port) { Guard.IsTrue(protocol == Protocol.Tcp || protocol == Protocol.Udp, "protocol"); Guard.IsInRange(port, 0, ushort.MaxValue, "port"); NatDiscoverer.TraceSource.LogInfo("GetSpecificMappingAsync - Getting mapping for protocol: {0} port: {1}", Enum.GetName(typeof(Protocol), protocol), port); try { var message = new GetSpecificPortMappingEntryRequestMessage(protocol, port); var responseData = await _soapClient .InvokeAsync("GetSpecificPortMappingEntry", message.ToXml()) .TimeoutAfter(TimeSpan.FromSeconds(4)).ConfigureAwait(false); var messageResponse = new GetPortMappingEntryResponseMessage(responseData, DeviceInfo.ServiceType, false); return new Mapping(messageResponse.Protocol , IPAddress.Parse(messageResponse.InternalClient) , messageResponse.InternalPort , messageResponse.ExternalPort , messageResponse.LeaseDuration , messageResponse.PortMappingDescription); } catch (MappingException e) { if (e.ErrorCode == UpnpConstants.NoSuchEntryInArray ) return null; // DD-WRT Linux base router (and others probably) fails with 402-InvalidArgument // when no mapping is found in the mappings table if (e.ErrorCode == UpnpConstants.InvalidArguments) { NatDiscoverer.TraceSource.LogWarn("Router failed with 402-InvalidArgument. Mapping not found is assumed."); return null; } throw; } }
public override async Task<IEnumerable<Mapping>> GetAllMappingsAsync() { var index = 0; var mappings = new List<Mapping>(); NatDiscoverer.TraceSource.LogInfo("GetAllMappingsAsync - Getting all mappings"); while (true) { try { var message = new GetGenericPortMappingEntry(index++); var responseData = await _soapClient .InvokeAsync("GetGenericPortMappingEntry", message.ToXml()) .TimeoutAfter(TimeSpan.FromSeconds(4)).ConfigureAwait(false); var responseMessage = new GetPortMappingEntryResponseMessage(responseData, DeviceInfo.ServiceType, true); IPAddress internalClientIp; if(!IPAddress.TryParse(responseMessage.InternalClient, out internalClientIp)) { NatDiscoverer.TraceSource.LogWarn("InternalClient is not an IP address. Mapping ignored!"); continue; } var mapping = new Mapping(responseMessage.Protocol , internalClientIp , responseMessage.InternalPort , responseMessage.ExternalPort , responseMessage.LeaseDuration , responseMessage.PortMappingDescription); mappings.Add(mapping); } catch (MappingException e) { if (e.ErrorCode == UpnpConstants.SpecifiedArrayIndexInvalid || e.ErrorCode == UpnpConstants.NoSuchEntryInArray) break; // there are no more mappings // DD-WRT Linux base router (and others probably) fails with 402-InvalidArgument when index is out of range if (e.ErrorCode == UpnpConstants.InvalidArguments) { NatDiscoverer.TraceSource.LogWarn("Router failed with 402-InvalidArgument. No more mappings is assumed."); break; } throw; } } return mappings.ToArray(); }