404 lines
17 KiB
C#
404 lines
17 KiB
C#
|
// Decompiled with JetBrains decompiler
|
|||
|
// Type: Rei.Net.HttpServer.UPnPManager
|
|||
|
// Assembly: Rei.Net.HttpServer, Version=1.13.2.9297, Culture=neutral, PublicKeyToken=null
|
|||
|
// MVID: 6174F8E9-E7BA-46AD-8F2E-196645884F28
|
|||
|
// Assembly location: F:\Eigene Dateien\Dropbox\portable Collection\Progs\CarotDAV\Rei.Net.HttpServer.dll
|
|||
|
|
|||
|
using Microsoft.VisualBasic.CompilerServices;
|
|||
|
using System;
|
|||
|
using System.Collections.Generic;
|
|||
|
using System.Diagnostics;
|
|||
|
using System.IO;
|
|||
|
using System.Net;
|
|||
|
using System.Net.NetworkInformation;
|
|||
|
using System.Net.Sockets;
|
|||
|
using System.Text;
|
|||
|
|
|||
|
namespace Rei.Net.HttpServer
|
|||
|
{
|
|||
|
public class UPnPManager : IDisposable
|
|||
|
{
|
|||
|
private static string servicetype_1 = "urn:schemas-upnp-org:service:WANIPConnection:1";
|
|||
|
private static string servicetype_2 = "urn:schemas-upnp-org:service:WANPPPConnection:1";
|
|||
|
private List<UPnPManager.portmappingentry> mappinglist;
|
|||
|
private bool disposedValue;
|
|||
|
|
|||
|
private static Uri GetDeviceDocumentUri(IPAddress gatewayip)
|
|||
|
{
|
|||
|
IPEndPoint ipEndPoint = new IPEndPoint(gatewayip, 1900);
|
|||
|
EndPoint remoteEP = (EndPoint) new IPEndPoint(IPAddress.Any, 0);
|
|||
|
byte[] bytes = Encoding.UTF8.GetBytes("M-SEARCH * HTTP/1.1\r\nHost: " + gatewayip.ToString() + ":1900\r\nSt: upnp:rootdevice\r\nMan: \"ssdp:discover\"\r\nMx: 3\r\n\r\n\r\n");
|
|||
|
string str1;
|
|||
|
using (Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp))
|
|||
|
{
|
|||
|
socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReceiveTimeout, 3000);
|
|||
|
socket.SendTo(bytes, 0, bytes.Length, SocketFlags.None, (EndPoint) ipEndPoint);
|
|||
|
byte[] numArray = new byte[1025];
|
|||
|
int from = socket.ReceiveFrom(numArray, 0, numArray.Length, SocketFlags.None, ref remoteEP);
|
|||
|
str1 = Encoding.UTF8.GetString(numArray, 0, from);
|
|||
|
}
|
|||
|
if (string.IsNullOrEmpty(str1))
|
|||
|
return (Uri) null;
|
|||
|
string[] strArray = str1.Split(new char[2]
|
|||
|
{
|
|||
|
'\r',
|
|||
|
'\n'
|
|||
|
}, StringSplitOptions.RemoveEmptyEntries);
|
|||
|
int index = 0;
|
|||
|
while (index < strArray.Length)
|
|||
|
{
|
|||
|
string str2 = strArray[index];
|
|||
|
if (str2.StartsWith("Location:", StringComparison.InvariantCultureIgnoreCase))
|
|||
|
{
|
|||
|
string uriString = str2.Substring(9).Trim();
|
|||
|
Uri result = (Uri) null;
|
|||
|
if (Uri.TryCreate(uriString, UriKind.Absolute, out result))
|
|||
|
return result;
|
|||
|
return (Uri) null;
|
|||
|
}
|
|||
|
checked { ++index; }
|
|||
|
}
|
|||
|
return (Uri) null;
|
|||
|
}
|
|||
|
|
|||
|
private static string GetDeviceDocument(Uri u)
|
|||
|
{
|
|||
|
HttpWebRequest httpWebRequest = (HttpWebRequest) WebRequest.Create(u);
|
|||
|
httpWebRequest.Method = "GET";
|
|||
|
httpWebRequest.KeepAlive = false;
|
|||
|
httpWebRequest.Proxy = (IWebProxy) null;
|
|||
|
httpWebRequest.Timeout = 3000;
|
|||
|
string str = (string) null;
|
|||
|
try
|
|||
|
{
|
|||
|
using (HttpWebResponse response = (HttpWebResponse) httpWebRequest.GetResponse())
|
|||
|
{
|
|||
|
using (StreamReader streamReader = new StreamReader(response.GetResponseStream()))
|
|||
|
str = streamReader.ReadToEnd();
|
|||
|
}
|
|||
|
}
|
|||
|
catch (Exception ex)
|
|||
|
{
|
|||
|
ProjectData.SetProjectError(ex);
|
|||
|
ProjectData.ClearProjectError();
|
|||
|
}
|
|||
|
return str;
|
|||
|
}
|
|||
|
|
|||
|
private static Uri FindControlUri(Uri baseuri, string document, string servicename)
|
|||
|
{
|
|||
|
int startIndex1 = document.IndexOf(servicename);
|
|||
|
if (startIndex1 < 0)
|
|||
|
return (Uri) null;
|
|||
|
int startIndex2 = document.IndexOf("<controlURL>", startIndex1);
|
|||
|
int num = document.IndexOf("</controlURL>", startIndex2);
|
|||
|
return new Uri(baseuri, document.Substring(checked (startIndex2 + 12), checked (num - startIndex2 - 12)));
|
|||
|
}
|
|||
|
|
|||
|
private static bool AddPortMapping(Uri controluri, string servicename, int externalport, IPAddress internalip, int internalport)
|
|||
|
{
|
|||
|
string s = "<?xml version=\"1.0\"?><s:Envelope xmlns:s:=\"http://schemas.xmlsoap.org/soap/envelope/\" s:encodingStyle=\"http://schemas.xmlsoap.org/soap/encoding/\"> <s:Body> <m:AddPortMapping xmlns:m=\"" + servicename + "\"> <NewRemoteHost></NewRemoteHost> <NewExternalPort>" + externalport.ToString() + "</NewExternalPort> <NewProtocol>TCP</NewProtocol> <NewInternalPort>" + internalport.ToString() + "</NewInternalPort> <NewInternalClient>" + internalip.ToString() + "</NewInternalClient> <NewEnabled>1</NewEnabled> <NewPortMappingDescription></NewPortMappingDescription> <NewLeaseDuration>0</NewLeaseDuration> </m:AddPortMapping> </s:Body></s:Envelope>";
|
|||
|
Encoding.UTF8.GetBytes(s);
|
|||
|
HttpWebRequest httpWebRequest = (HttpWebRequest) WebRequest.Create(controluri);
|
|||
|
httpWebRequest.Method = "POST";
|
|||
|
httpWebRequest.KeepAlive = false;
|
|||
|
httpWebRequest.Proxy = (IWebProxy) null;
|
|||
|
httpWebRequest.Timeout = 3000;
|
|||
|
httpWebRequest.AllowWriteStreamBuffering = true;
|
|||
|
httpWebRequest.SendChunked = false;
|
|||
|
httpWebRequest.Headers.Add("Soapaction", servicename + "#AddPortMapping");
|
|||
|
httpWebRequest.ContentType = "text/xml;charset=\\\"utf-8\\\"";
|
|||
|
string str = (string) null;
|
|||
|
try
|
|||
|
{
|
|||
|
using (StreamWriter streamWriter = new StreamWriter(httpWebRequest.GetRequestStream()))
|
|||
|
streamWriter.Write(s);
|
|||
|
using (HttpWebResponse response = (HttpWebResponse) httpWebRequest.GetResponse())
|
|||
|
{
|
|||
|
using (StreamReader streamReader = new StreamReader(response.GetResponseStream()))
|
|||
|
str = streamReader.ReadToEnd();
|
|||
|
if (response.StatusCode >= HttpStatusCode.OK)
|
|||
|
{
|
|||
|
if (response.StatusCode < HttpStatusCode.MultipleChoices)
|
|||
|
goto label_18;
|
|||
|
}
|
|||
|
return false;
|
|||
|
}
|
|||
|
label_18:
|
|||
|
return true;
|
|||
|
}
|
|||
|
catch (Exception ex)
|
|||
|
{
|
|||
|
ProjectData.SetProjectError(ex);
|
|||
|
ProjectData.ClearProjectError();
|
|||
|
}
|
|||
|
return false;
|
|||
|
}
|
|||
|
|
|||
|
private static bool DeletePortMapping(Uri controluri, string servicename, int externalport)
|
|||
|
{
|
|||
|
string s = "<?xml version=\"1.0\"?><s:Envelope xmlns:s:=\"http://schemas.xmlsoap.org/soap/envelope/\" s:encodingStyle=\"http://schemas.xmlsoap.org/soap/encoding/\"> <s:Body> <m:DeletePortMapping xmlns:m=\"" + servicename + "\"> <NewRemoteHost></NewRemoteHost> <NewExternalPort>" + externalport.ToString() + "</NewExternalPort> <NewProtocol>TCP</NewProtocol> </m:DeletePortMapping> </s:Body></s:Envelope>";
|
|||
|
Encoding.UTF8.GetBytes(s);
|
|||
|
HttpWebRequest httpWebRequest = (HttpWebRequest) WebRequest.Create(controluri);
|
|||
|
httpWebRequest.Method = "POST";
|
|||
|
httpWebRequest.KeepAlive = false;
|
|||
|
httpWebRequest.Proxy = (IWebProxy) null;
|
|||
|
httpWebRequest.Timeout = 3000;
|
|||
|
httpWebRequest.AllowWriteStreamBuffering = true;
|
|||
|
httpWebRequest.SendChunked = false;
|
|||
|
httpWebRequest.Headers.Add("Soapaction", servicename + "#DeletePortMapping");
|
|||
|
httpWebRequest.ContentType = "text/xml;charset=\\\"utf-8\\\"";
|
|||
|
string str = (string) null;
|
|||
|
try
|
|||
|
{
|
|||
|
using (StreamWriter streamWriter = new StreamWriter(httpWebRequest.GetRequestStream()))
|
|||
|
streamWriter.Write(s);
|
|||
|
using (HttpWebResponse response = (HttpWebResponse) httpWebRequest.GetResponse())
|
|||
|
{
|
|||
|
using (StreamReader streamReader = new StreamReader(response.GetResponseStream()))
|
|||
|
str = streamReader.ReadToEnd();
|
|||
|
if (response.StatusCode >= HttpStatusCode.OK)
|
|||
|
{
|
|||
|
if (response.StatusCode < HttpStatusCode.MultipleChoices)
|
|||
|
goto label_18;
|
|||
|
}
|
|||
|
return false;
|
|||
|
}
|
|||
|
label_18:
|
|||
|
return true;
|
|||
|
}
|
|||
|
catch (Exception ex)
|
|||
|
{
|
|||
|
ProjectData.SetProjectError(ex);
|
|||
|
ProjectData.ClearProjectError();
|
|||
|
}
|
|||
|
return false;
|
|||
|
}
|
|||
|
|
|||
|
private static IPAddress GetExternalIPAddress(Uri controluri, string servicename)
|
|||
|
{
|
|||
|
string s = "<?xml version=\"1.0\"?><s:Envelope xmlns:s:=\"http://schemas.xmlsoap.org/soap/envelope/\" s:encodingStyle=\"http://schemas.xmlsoap.org/soap/encoding/\"> <s:Body> <m:GetExternalIPAddress xmlns:m=\"" + servicename + "\"> </m:GetExternalIPAddress> </s:Body></s:Envelope>";
|
|||
|
Encoding.UTF8.GetBytes(s);
|
|||
|
HttpWebRequest httpWebRequest = (HttpWebRequest) WebRequest.Create(controluri);
|
|||
|
httpWebRequest.Method = "POST";
|
|||
|
httpWebRequest.KeepAlive = false;
|
|||
|
httpWebRequest.Proxy = (IWebProxy) null;
|
|||
|
httpWebRequest.Timeout = 3000;
|
|||
|
httpWebRequest.AllowWriteStreamBuffering = true;
|
|||
|
httpWebRequest.SendChunked = false;
|
|||
|
httpWebRequest.Headers.Add("Soapaction", servicename + "#GetExternalIPAddress");
|
|||
|
httpWebRequest.ContentType = "text/xml;charset=\\\"utf-8\\\"";
|
|||
|
string str = (string) null;
|
|||
|
try
|
|||
|
{
|
|||
|
using (StreamWriter streamWriter = new StreamWriter(httpWebRequest.GetRequestStream()))
|
|||
|
streamWriter.Write(s);
|
|||
|
using (HttpWebResponse response = (HttpWebResponse) httpWebRequest.GetResponse())
|
|||
|
{
|
|||
|
using (StreamReader streamReader = new StreamReader(response.GetResponseStream()))
|
|||
|
str = streamReader.ReadToEnd();
|
|||
|
if (response.StatusCode >= HttpStatusCode.OK)
|
|||
|
{
|
|||
|
if (response.StatusCode < HttpStatusCode.MultipleChoices)
|
|||
|
goto label_18;
|
|||
|
}
|
|||
|
return (IPAddress) null;
|
|||
|
}
|
|||
|
label_18:
|
|||
|
int startIndex = str.IndexOf("<NewExternalIPAddress>");
|
|||
|
int num = str.IndexOf("</NewExternalIPAddress>", startIndex);
|
|||
|
IPAddress address = (IPAddress) null;
|
|||
|
if (IPAddress.TryParse(str.Substring(checked (startIndex + 22), checked (num - startIndex - 22)), out address))
|
|||
|
return address;
|
|||
|
}
|
|||
|
catch (Exception ex)
|
|||
|
{
|
|||
|
ProjectData.SetProjectError(ex);
|
|||
|
ProjectData.ClearProjectError();
|
|||
|
}
|
|||
|
return (IPAddress) null;
|
|||
|
}
|
|||
|
|
|||
|
public UPnPManager()
|
|||
|
{
|
|||
|
this.mappinglist = new List<UPnPManager.portmappingentry>();
|
|||
|
this.disposedValue = false;
|
|||
|
}
|
|||
|
|
|||
|
public IPEndPoint[] GetExternalEndpoints()
|
|||
|
{
|
|||
|
List<IPEndPoint> ipEndPointList = new List<IPEndPoint>();
|
|||
|
List<UPnPManager.portmappingentry>.Enumerator enumerator;
|
|||
|
try
|
|||
|
{
|
|||
|
enumerator = this.mappinglist.GetEnumerator();
|
|||
|
while (enumerator.MoveNext())
|
|||
|
{
|
|||
|
UPnPManager.portmappingentry current = enumerator.Current;
|
|||
|
ipEndPointList.Add(new IPEndPoint(current.externalip, current.externalport));
|
|||
|
}
|
|||
|
}
|
|||
|
finally
|
|||
|
{
|
|||
|
enumerator.Dispose();
|
|||
|
}
|
|||
|
return ipEndPointList.ToArray();
|
|||
|
}
|
|||
|
|
|||
|
public void AddPortMapping(bool all, int internalport)
|
|||
|
{
|
|||
|
Random random = new Random();
|
|||
|
List<IPAddress> ipAddressList = new List<IPAddress>();
|
|||
|
NetworkInterface[] networkInterfaces = NetworkInterface.GetAllNetworkInterfaces();
|
|||
|
int index = 0;
|
|||
|
while (index < networkInterfaces.Length)
|
|||
|
{
|
|||
|
NetworkInterface networkInterface = networkInterfaces[index];
|
|||
|
try
|
|||
|
{
|
|||
|
if (networkInterface.NetworkInterfaceType != NetworkInterfaceType.Loopback)
|
|||
|
{
|
|||
|
if (networkInterface.NetworkInterfaceType != NetworkInterfaceType.Tunnel)
|
|||
|
{
|
|||
|
if (networkInterface.OperationalStatus == OperationalStatus.Up)
|
|||
|
{
|
|||
|
IPInterfaceProperties ipProperties = networkInterface.GetIPProperties();
|
|||
|
IPAddress internalip = (IPAddress) null;
|
|||
|
IEnumerator<UnicastIPAddressInformation> enumerator1;
|
|||
|
try
|
|||
|
{
|
|||
|
enumerator1 = ipProperties.UnicastAddresses.GetEnumerator();
|
|||
|
while (enumerator1.MoveNext())
|
|||
|
{
|
|||
|
UnicastIPAddressInformation current = enumerator1.Current;
|
|||
|
if (current.Address.AddressFamily == AddressFamily.InterNetwork && !IPAddress.IsLoopback(current.Address))
|
|||
|
{
|
|||
|
internalip = current.Address;
|
|||
|
break;
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
finally
|
|||
|
{
|
|||
|
if (enumerator1 != null)
|
|||
|
enumerator1.Dispose();
|
|||
|
}
|
|||
|
IEnumerator<GatewayIPAddressInformation> enumerator2;
|
|||
|
if (internalip != null)
|
|||
|
{
|
|||
|
try
|
|||
|
{
|
|||
|
enumerator2 = ipProperties.GatewayAddresses.GetEnumerator();
|
|||
|
while (enumerator2.MoveNext())
|
|||
|
{
|
|||
|
GatewayIPAddressInformation current = enumerator2.Current;
|
|||
|
if (!object.Equals((object) current.Address, (object) IPAddress.None) && !object.Equals((object) current.Address, (object) IPAddress.Any) && (!object.Equals((object) current.Address, (object) IPAddress.Broadcast) && !object.Equals((object) current.Address, (object) IPAddress.Loopback)))
|
|||
|
{
|
|||
|
UPnPManager.portmappingentry portmappingentry = new UPnPManager.portmappingentry();
|
|||
|
Uri deviceDocumentUri = UPnPManager.GetDeviceDocumentUri(current.Address);
|
|||
|
string deviceDocument = UPnPManager.GetDeviceDocument(deviceDocumentUri);
|
|||
|
portmappingentry.servicename = UPnPManager.servicetype_1;
|
|||
|
portmappingentry.controluri = UPnPManager.FindControlUri(deviceDocumentUri, deviceDocument, portmappingentry.servicename);
|
|||
|
if ((object) portmappingentry.controluri == null)
|
|||
|
{
|
|||
|
portmappingentry.servicename = UPnPManager.servicetype_2;
|
|||
|
portmappingentry.controluri = UPnPManager.FindControlUri(deviceDocumentUri, deviceDocument, portmappingentry.servicename);
|
|||
|
}
|
|||
|
if ((object) portmappingentry.controluri != null)
|
|||
|
{
|
|||
|
portmappingentry.externalip = UPnPManager.GetExternalIPAddress(portmappingentry.controluri, portmappingentry.servicename);
|
|||
|
if (portmappingentry.externalip != null)
|
|||
|
{
|
|||
|
portmappingentry.externalport = internalport;
|
|||
|
int num = 0;
|
|||
|
do
|
|||
|
{
|
|||
|
try
|
|||
|
{
|
|||
|
if (UPnPManager.AddPortMapping(portmappingentry.controluri, portmappingentry.servicename, portmappingentry.externalport, internalip, internalport))
|
|||
|
{
|
|||
|
this.mappinglist.Add(portmappingentry);
|
|||
|
if (!all)
|
|||
|
return;
|
|||
|
break;
|
|||
|
}
|
|||
|
}
|
|||
|
catch (Exception ex)
|
|||
|
{
|
|||
|
ProjectData.SetProjectError(ex);
|
|||
|
ProjectData.ClearProjectError();
|
|||
|
}
|
|||
|
portmappingentry.externalport = random.Next(30000, 60000);
|
|||
|
checked { ++num; }
|
|||
|
}
|
|||
|
while (num <= 10);
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
finally
|
|||
|
{
|
|||
|
if (enumerator2 != null)
|
|||
|
enumerator2.Dispose();
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
catch (Exception ex)
|
|||
|
{
|
|||
|
ProjectData.SetProjectError(ex);
|
|||
|
ProjectData.ClearProjectError();
|
|||
|
}
|
|||
|
checked { ++index; }
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
public void DeletePortMapping()
|
|||
|
{
|
|||
|
while (this.mappinglist.Count > 0)
|
|||
|
{
|
|||
|
UPnPManager.portmappingentry portmappingentry = this.mappinglist[checked (this.mappinglist.Count - 1)];
|
|||
|
try
|
|||
|
{
|
|||
|
UPnPManager.DeletePortMapping(portmappingentry.controluri, portmappingentry.servicename, portmappingentry.externalport);
|
|||
|
}
|
|||
|
catch (Exception ex)
|
|||
|
{
|
|||
|
ProjectData.SetProjectError(ex);
|
|||
|
ProjectData.ClearProjectError();
|
|||
|
}
|
|||
|
this.mappinglist.RemoveAt(checked (this.mappinglist.Count - 1));
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
protected virtual void Dispose(bool disposing)
|
|||
|
{
|
|||
|
if (!this.disposedValue && disposing)
|
|||
|
this.DeletePortMapping();
|
|||
|
this.disposedValue = true;
|
|||
|
}
|
|||
|
|
|||
|
public void Dispose()
|
|||
|
{
|
|||
|
this.Dispose(true);
|
|||
|
GC.SuppressFinalize((object) this);
|
|||
|
}
|
|||
|
|
|||
|
private class portmappingentry
|
|||
|
{
|
|||
|
public string servicename;
|
|||
|
public Uri controluri;
|
|||
|
public IPAddress externalip;
|
|||
|
public int externalport;
|
|||
|
|
|||
|
[DebuggerNonUserCode]
|
|||
|
public portmappingentry()
|
|||
|
{
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
}
|