Ejemplo n.º 1
0
		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));

                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;
            }
        }
Ejemplo n.º 2
0
		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));

                    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();
        }