/// <summary> /// Get the port control URL from the gateway. /// </summary> bool GetControlURL(string url) { string response = Tools.GetResponse(WebRequest.Create(url)); if (string.IsNullOrEmpty(response)) { return(false); } // For me the full hierarchy of nodes was: // root -> device -> deviceList -> device (again) -> deviceList (again) -> service, // where the <serviceType> node had an identifier ending in one of the prefixes below. // The service node with this type then contained <controlURL> node with the actual URL. // TLDR: It's just a hell of a lot easier to go straight for the prize instead. // IP gateway (Router, cable modem) mServiceType = "WANIPConnection"; int offset = response.IndexOf(mServiceType); // PPP gateway (ADSL modem) if (offset == -1) { mServiceType = "WANPPPConnection"; offset = response.IndexOf(mServiceType); if (offset == -1) { return(false); } } int end = response.IndexOf("</service>", offset); if (end == -1) { return(false); } int start = response.IndexOf("<controlURL>", offset, end - offset); if (start == -1) { return(false); } start += 12; end = response.IndexOf("</controlURL>", start, end - start); if (end == -1) { return(false); } // Final URL mControlURL = mGatewayURL + response.Substring(start, end - start); return(true); }
/// <summary> /// Send a SOAP request to the gateway. /// Some routers (like my NETGEAR RangeMax) seem to fail requests for no reason, so repetition may be needed. /// </summary> string SendRequest(string action, string content, int timeout, int repeat) { string request = "<?xml version=\"1.0\"?>\n" + "<s:Envelope xmlns:s=\"http://schemas.xmlsoap.org/soap/envelope/\" s:encodingStyle=" + "\"http://schemas.xmlsoap.org/soap/encoding/\">\n<s:Body>\n" + "<m:" + action + " xmlns:m=\"urn:schemas-upnp-org:service:" + mServiceType + ":1\">\n"; if (!string.IsNullOrEmpty(content)) { request += content; } request += "</m:" + action + ">\n</s:Body>\n</s:Envelope>\n"; byte[] b = Encoding.UTF8.GetBytes(request); string response = null; try { for (int i = 0; i < repeat; ++i) { WebRequest web = HttpWebRequest.Create(mControlURL); web.Timeout = timeout; web.Method = "POST"; web.Headers.Add("SOAPACTION", "\"urn:schemas-upnp-org:service:" + mServiceType + ":1#" + action + "\""); web.ContentType = "text/xml; charset=\"utf-8\""; web.ContentLength = b.Length; web.GetRequestStream().Write(b, 0, b.Length); response = Tools.GetResponse(web); if (!string.IsNullOrEmpty(response)) { return(response); } } } catch (System.Exception) { } return(null); }