public static void ForwardPort() { try { bool lbCompleted; Services lsServices = Discovery.FindServices( null, 2000, 0, out lbCompleted, AddressFamilyFlags.IPvBoth); string ip = GetExternalIP(lsServices); if (ip != null) { WanEndPoint = new IPEndPoint(IPAddress.Parse(ip), ListenPort); } RemovePort(lsServices, ListenPort); ForwardPort(lsServices, ListenPort); } catch (Exception ex) { } }
/// <summary> /// Performs the search of the services. /// </summary> /// <param name="timeout">The timeout in milliseconds for the search.</param> /// <param name="checkForAction">True to check for action before execution.</param> /// <param name="verboseLog">True to write verbose UPnP log information.</param> static void Search(int timeout, bool checkForAction, bool verboseLog) { // Write the settings Console.WriteLine("Searching for UPnP services..."); Console.WriteLine(string.Format(" Timeout: {0}", (timeout == -1 ? "Indefinite" : string.Format("{0} ms", timeout)))); Console.WriteLine(string.Format(" Check service for action: {0}", checkForAction)); Console.WriteLine(string.Format(" Verbose UPnP Log: {0}", verboseLog)); Console.WriteLine(); if (verboseLog) { Console.WriteLine("Enabling verbose log..."); ManagedUPnP.Logging.Enabled = true; ManagedUPnP.Logging.LogLines += new LogLinesEventHandler(Logging_LogLines); Console.WriteLine(); } const string csGetExternalIPAddressAction = "GetExternalIPAddress"; // Used in cache two services on a device return the same IP information HashSet <string> lhsDone = new HashSet <string>(); // Find the services bool lbCompleted; Services lsServices = Discovery.FindServices( null, timeout, 0, out lbCompleted, AddressFamilyFlags.IPvBoth); Console.WriteLine(string.Format("Found {0} services, Search Completed: {1}", lsServices.Count, lbCompleted)); Console.WriteLine(); // Scan the services and write the IP address foreach (Service lsService in lsServices) { try { // Check for action if required if (!checkForAction || lsService.Description().Actions.ContainsKey(csGetExternalIPAddressAction)) { // Invoke the action string lsIP; lsService.InvokeAction <string>(csGetExternalIPAddressAction, out lsIP); // Build the info string string lsInfo = String.Format( "{0} => {1} - IP Address: {2}", lsService.Device.RootDevice.FriendlyName, lsService.Device.FriendlyName, lsIP); // If we havnt alread reported this info if (!lhsDone.Contains(lsInfo)) { // Report and add it Console.WriteLine(lsInfo); lhsDone.Add(lsInfo); } } } catch { } } }
/// <summary> /// Enabled NAT Forwarding on all UPnP devices on the network (and opens Firewall) for the specified port on the local machine /// </summary> /// <param name="onPort">Port number to map</param> /// <param name="verbose">Write detailed logs</param> public static void EnableUPnP(int onPort, bool verbose) { try { bool searchCompleted; if (verbose) { Log.AppLog.WriteEntry("UPnP", "Enabling Firewall for UPnP", Log.LogEntryType.Debug, true); } // Enable windows firewall for allowing UPnP (if it's not already enabled) if (WindowsFirewall.UPnPPortsOpen != WindowsFirewall.Status.Open) { WindowsFirewall.UPnPPortsOpen = WindowsFirewall.Status.Open; if (WindowsFirewall.UPnPPortsOpen != WindowsFirewall.Status.Open) { Log.AppLog.WriteEntry("UPnP", "Unable to open Windows Firewall UPnP ports, please MANUALLY ALLOW/ENABLE the UPnP ports (TCP:2869 and UDP:1900)", Log.LogEntryType.Warning, true); Log.AppLog.WriteEntry("UPnP", "Windows Firewall Status -> " + WindowsFirewall.UPnPPortsOpen.ToString(), Log.LogEntryType.Warning, true); } } if (verbose) { Log.AppLog.WriteEntry("UPnP", "Searching for UPnP devices", Log.LogEntryType.Debug, true); } // Search for UPnP devices Services lsServices = Discovery.FindServices(null, int.MaxValue, int.MaxValue, out searchCompleted, AddressFamilyFlags.IPvBoth, true); // Check for an incomplete search if (!searchCompleted) { if (verbose) { Log.AppLog.WriteEntry("UPnP", "UPnP search incomplete, retrying again", Log.LogEntryType.Information, true); } lsServices = Discovery.FindServices(null, int.MaxValue, int.MaxValue, out searchCompleted, AddressFamilyFlags.IPvBoth, false); if (!searchCompleted) { Log.AppLog.WriteEntry("UPnP", "UPnP search incomplete, UPnP enablement may not succeed", Log.LogEntryType.Warning, true); } } foreach (ManagedUPnP.Service lsService in lsServices) { ServiceDescription lsdDesc = lsService.Description(); if (lsdDesc.Actions.ContainsKey("AddPortMapping")) // Check to see if is a WAN UPnP device that supports Port Mappings, if we so need to enable Port Forwarding for each such device { object[] inParams; try { inParams = new object[] { "", onPort, "tcp" }; lsService.InvokeAction("DeletePortMapping", inParams); // Delete the port mapping (we will create a fresh one later) } catch (Exception) { } // For the UPnP device, add a port mapping for each network interface adapter/IPaddress that can connect to the device foreach (IPAddress ifAddress in lsService.Device.AdapterIPAddresses) { // IPv4 addressed UPnP devices cannot handle IPv6 address entries, so skip it (even if there is one IPv6 Host address, we can then process an IPv6 entry) if (lsService.Device.RootHostAddresses.All(hostAddress => ((hostAddress.AddressFamily == System.Net.Sockets.AddressFamily.InterNetwork) && (ifAddress.AddressFamily == System.Net.Sockets.AddressFamily.InterNetworkV6)))) { if (verbose) { Log.AppLog.WriteEntry("UPnP", "Skipping Port Mapping due to incompatible IPAddress Types. UPnP Device : " + lsService.Device.RootHostAddresses[0].ToString() + ", Adapter : " + ifAddress.ToString(), Log.LogEntryType.Debug, true); } continue; } try { // For some IPv6 addresses we need to remove the Interface Identifier from the string (%x at the end of the ip6 address) if present if (verbose) { Log.AppLog.WriteEntry("UPnP", "Adding Port Mapping to " + (ifAddress.ToString().Contains("%") ? ifAddress.ToString().Substring(0, ifAddress.ToString().IndexOf("%")) : ifAddress.ToString()) + " Port " + onPort.ToString(), Log.LogEntryType.Debug, true); } // Now we add the port mapping for the current MCEBuddy server inParams = new object[] { "", onPort, "tcp", onPort, (ifAddress.ToString().Contains("%") ? ifAddress.ToString().Substring(0, ifAddress.ToString().IndexOf("%")) : ifAddress.ToString()), true, "mcebuddy2x", 0 }; lsService.InvokeAction("AddPortMapping", inParams); } catch (Exception e) { if (verbose) { Log.AppLog.WriteEntry("UPnP", "Unable to Add Port Mapping to " + lsService.Device.RootHostName, Log.LogEntryType.Warning, true); Log.AppLog.WriteEntry("UPnP", "Add Error " + e.ToString(), Log.LogEntryType.Warning, true); } } } } lsService.Dispose(); // need to dispose else it causes a memory leakage } } catch (Exception e) { Log.AppLog.WriteEntry("UPnP", "Error trying to enable UPnP -> " + e.ToString(), Log.LogEntryType.Warning, true); } }
/// <summary> /// Disable NAT Forwarding on all UPnP devices on the network for the specified port on the local machine /// </summary> /// <param name="onPort">Port number to map</param> /// <param name="verbose">Write detailed logs</param> public static void DisableUPnP(int onPort, bool verbose) { try { bool searchCompleted; if (verbose) { Log.AppLog.WriteEntry("UPnP", "Searching for UPnP devices", Log.LogEntryType.Debug, true); } // Search for UPnP devices Services lsServices = Discovery.FindServices(null, int.MaxValue, int.MaxValue, out searchCompleted, AddressFamilyFlags.IPvBoth, false); // Check for an incomplete search if (!searchCompleted) { if (verbose) { Log.AppLog.WriteEntry("UPnP", "UPnP search incomplete, retrying again", Log.LogEntryType.Information, true); } lsServices = Discovery.FindServices(null, int.MaxValue, int.MaxValue, out searchCompleted, AddressFamilyFlags.IPvBoth, false); if (!searchCompleted) { Log.AppLog.WriteEntry("UPnP", "UPnP search incomplete, UPnP enablement may not succeed", Log.LogEntryType.Warning, true); } } foreach (ManagedUPnP.Service lsService in lsServices) { ServiceDescription lsdDesc = lsService.Description(); if (lsdDesc.Actions.ContainsKey("DeletePortMapping")) // Check to see if is a WAN UPnP device that supports Port Mappings, if we so need to disable Port Forwarding for each such device { object[] inParams; try { if (verbose) { Log.AppLog.WriteEntry("UPnP", "Deleting Port Mapping from " + lsService.Device.RootHostName + " Port " + onPort.ToString(), Log.LogEntryType.Debug, true); } inParams = new object[] { "", onPort, "tcp" }; lsService.InvokeAction("DeletePortMapping", inParams); // Delete the port mapping (we will create a fresh one later) } catch (Exception e) { if (verbose) { Log.AppLog.WriteEntry("UPnP", "Unable to Delete Port Mapping from " + lsService.Device.RootHostName, Log.LogEntryType.Warning, true); Log.AppLog.WriteEntry("UPnP", "Delete Error " + e.ToString(), Log.LogEntryType.Warning, true); } } } lsService.Dispose(); // need to dispose else it causes a memory leakage } } catch (Exception e) { Log.AppLog.WriteEntry("UPnP", "Error trying to disable UPnP -> " + e.ToString(), Log.LogEntryType.Warning, true); } }