/// <summary> /// Deletes port mapping. /// </summary> /// <param name="protocol">Port mapping protocol. Nomrally this value TCP or UDP.</param> /// <param name="remoteHost">Remote host IP address.</param> /// <param name="publicPort">Public port number.</param> /// <exception cref="ArgumentNullException">Is raised when <b>protocol</b> is null reference.</exception> /// <exception cref="UPnP_Exception">Is raised when UPnP device returns error.</exception> public void DeletePortMapping(string protocol, string remoteHost, int publicPort) { /* http://upnp.org DeletePortMapping. * This action deletes a previously instantiated port mapping. As each entry is deleted, the array is * compacted, and the evented variable PortMappingNumberOfEntries is decremented. * * Arguments for DeletePortMapping: * NewRemoteHost * NewExternalPort * NewProtocol */ if (protocol == null) { throw new ArgumentNullException("protocol"); } try { string soapBody = "<s:Envelope xmlns:s=\"http://schemas.xmlsoap.org/soap/envelope/\" s:encodingStyle=\"http://schemas.xmlsoap.org/soap/encoding/\">\r\n" + "<s:Body>\r\n" + "<u:DeletePortMapping xmlns:u=\"" + m_ServiceType + "\">\r\n" + "<NewRemoteHost>" + remoteHost + "</NewRemoteHost>\r\n" + "<NewExternalPort>" + publicPort.ToString() + "</NewExternalPort>\r\n" + "<NewProtocol>" + protocol + "</NewProtocol>\r\n" + "</u:DeletePortMapping>\r\n" + "</s:Body>\r\n" + "</s:Envelope>\r\n"; SendCommand("DeletePortMapping", soapBody); } catch (WebException x) { // We have UPnP exception. if (x.Response.ContentType.ToLower().IndexOf("text/xml") > -1) { throw UPnP_Exception.Parse(x.Response.GetResponseStream()); } } }
/// <summary> /// This method creates a new port mapping or overwrites an existing mapping. /// </summary> /// <param name="enabled">Specifies if port mapping is enabled.</param> /// <param name="description">Port mapping description.</param> /// <param name="protocol">Port mapping protocol. Nomrally this value TCP or UDP.</param> /// <param name="remoteHost">Remote host IP address.</param> /// <param name="publicPort">Desired public port.</param> /// <param name="localEP">Local IP end point.</param> /// <param name="leaseDuration">Lease duration in seconds. Value null means never expires.</param> /// <exception cref="ArgumentNullException">Is raised when <b>description</b>,<b>protocol</b> or <b>localEP</b> is null reference.</exception> /// <exception cref="UPnP_Exception">Is raised when UPnP device returns error.</exception> public void AddPortMapping(bool enabled, string description, string protocol, string remoteHost, int publicPort, IPEndPoint localEP, int leaseDuration) { if (description == null) { throw new ArgumentNullException("description"); } if (protocol == null) { throw new ArgumentNullException("protocol"); } if (localEP == null) { throw new ArgumentNullException("localEP"); } /* http://upnp.org AddPortMapping. * This action creates a new port mapping or overwrites an existing mapping with the same internal * client. If the ExternalPort and PortMappingProtocol pair is already mapped to another * internal client, an error is returned. * * NOTE: Not all NAT implementations will support: * • Wildcard value (i.e. 0) for ExternalPort * • InternalPort values that are different from ExternalPort * • Dynamic port mappings i.e. with non-Infinite PortMappingLeaseDuration * * Arguments for AddPortMapping: * NewRemoteHost * NewExternalPort * NewProtocol * NewInternalPort * NewInternalClient * NewEnabled * NewPortMappingDescription * NewLeaseDuration */ try { string soapBody = "<s:Envelope xmlns:s=\"http://schemas.xmlsoap.org/soap/envelope/\" s:encodingStyle=\"http://schemas.xmlsoap.org/soap/encoding/\">\r\n" + "<s:Body>\r\n" + "<u:AddPortMapping xmlns:u=\"" + m_ServiceType + "\">\r\n" + "<NewRemoteHost>" + remoteHost + "</NewRemoteHost>\r\n" + "<NewExternalPort>" + publicPort.ToString() + "</NewExternalPort>\r\n" + "<NewProtocol>" + protocol + "</NewProtocol>\r\n" + "<NewInternalPort>" + localEP.Port.ToString() + "</NewInternalPort>\r\n" + "<NewInternalClient>" + localEP.Address.ToString() + "</NewInternalClient>\r\n" + "<NewEnabled>" + Convert.ToInt32(enabled) + "</NewEnabled>\r\n" + "<NewPortMappingDescription>" + description + "</NewPortMappingDescription>\r\n" + "<NewLeaseDuration>" + leaseDuration + "</NewLeaseDuration>\r\n" + "</u:AddPortMapping>\r\n" + "</s:Body>\r\n" + "</s:Envelope>\r\n"; string soapResponse = SendCommand("AddPortMapping", soapBody); } catch (WebException x) { // We have UPnP exception. if (x.Response.ContentType.ToLower().IndexOf("text/xml") > -1) { throw UPnP_Exception.Parse(x.Response.GetResponseStream()); } } }
/// <summary> /// Gets all existing port mappings. /// </summary> /// <returns>Returns all existing port mappings.</returns> public UPnP_NAT_Map[] GetPortMappings() { /* http://upnp.org GetGenericPortMappingEntry. * This action retrieves NAT port mappings one entry at a time. Control points can call this action * with an incrementing array index until no more entries are found on the gateway. If * PortMappingNumberOfEntries is updated during a call, the process may have to start over. * Entries in the array are contiguous. As entries are deleted, the array is compacted, and the * evented variable PortMappingNumberOfEntries is decremented. Port mappings are logically * stored as an array on the IGD and retrieved using an array index ranging from 0 to * PortMappingNumberOfEntries-1. * * Arguments for GetGenericPortMappingEntry: * NewPortMappingIndex * * Returns: * NewRemoteHost * NewExternalPort * NewProtocol * NewInternalPort * NewInternalClient * NewEnabled * NewPortMappingDescription * NewLeaseDuration */ List <UPnP_NAT_Map> retVal = new List <UPnP_NAT_Map>(); for (int i = 0; i < 100; i++) { try { string soapBody = "<s:Envelope xmlns:s=\"http://schemas.xmlsoap.org/soap/envelope/\" s:encodingStyle=\"http://schemas.xmlsoap.org/soap/encoding/\">\r\n" + "<s:Body>\r\n" + "<u:GetGenericPortMappingEntry xmlns:u=\"" + m_ServiceType + "\">\r\n" + "<NewPortMappingIndex>" + i + "</NewPortMappingIndex>\r\n" + "</u:GetGenericPortMappingEntry>\r\n" + "</s:Body>\r\n" + "</s:Envelope>\r\n"; string soapResponse = SendCommand("GetGenericPortMappingEntry", soapBody); bool enabled = false; string protocol = ""; string remoteHost = ""; string externalPort = ""; string internalHost = ""; int internalPort = 0; string description = ""; int leaseDuration = 0; XmlReader reader = XmlReader.Create(new System.IO.StringReader(soapResponse)); while (reader.Read()) { if (String2.Equals("NewRemoteHost", reader.Name, StringComparison2.InvariantCultureIgnoreCase)) { remoteHost = reader.ReadString(); } else if (String2.Equals("NewExternalPort", reader.Name, StringComparison2.InvariantCultureIgnoreCase)) { externalPort = reader.ReadString(); } else if (String2.Equals("NewProtocol", reader.Name, StringComparison2.InvariantCultureIgnoreCase)) { protocol = reader.ReadString(); } else if (String2.Equals("NewInternalPort", reader.Name, StringComparison2.InvariantCultureIgnoreCase)) { internalPort = Convert.ToInt32(reader.ReadString()); } else if (String2.Equals("NewInternalClient", reader.Name, StringComparison2.InvariantCultureIgnoreCase)) { internalHost = reader.ReadString(); } else if (String2.Equals("NewEnabled", reader.Name, StringComparison2.InvariantCultureIgnoreCase)) { enabled = Convert.ToBoolean(Convert.ToInt32(reader.ReadString())); } else if (String2.Equals("NewPortMappingDescription", reader.Name, StringComparison2.InvariantCultureIgnoreCase)) { description = reader.ReadString(); } else if (String2.Equals("NewLeaseDuration", reader.Name, StringComparison2.InvariantCultureIgnoreCase)) { leaseDuration = Convert.ToInt32(reader.ReadString()); } } retVal.Add(new UPnP_NAT_Map(enabled, protocol, remoteHost, externalPort, internalHost, internalPort, description, leaseDuration)); } catch (WebException x) { // We should see what error we got. We expect "Array out of index", other exceptions we must pass through. // We have UPnP exception. if (x.Response.ContentType.ToLower().IndexOf("text/xml") > -1) { UPnP_Exception uX = UPnP_Exception.Parse(x.Response.GetResponseStream()); // Other error than "Index out of range", we pass it through. if (uX.ErrorCode != 713) { throw uX; } } // Unknown http error. else { throw x; } break; } } return(retVal.ToArray()); }