Last active
December 22, 2021 18:10
-
-
Save mikaeldui/0260d4730a0bc1d1f93770633f6967e1 to your computer and use it in GitHub Desktop.
.NET Client for TP-Link TL-ER6020
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using HtmlAgilityPack; | |
using System; | |
using System.Collections.Generic; | |
using System.Linq; | |
using System.Net.Http; | |
using System.Text; | |
using System.Threading.Tasks; | |
using Windows.Security.Cryptography; | |
using Windows.Security.Cryptography.Core; | |
using Windows.Storage.Streams; | |
namespace Tplink | |
{ | |
internal class TplinkClient : IDisposable | |
{ | |
internal HttpClient _httpClient = new HttpClient(); | |
public TplinkClient(Uri baseAddress) | |
{ | |
_httpClient.BaseAddress = baseAddress; | |
Network = new TplinkClientNetwork(this); | |
Maintenance = new TplinkClientMaintenance(this); | |
} | |
public async Task<HttpResponseMessage> LoginAsync(string username, string password) | |
{ | |
var nonce = await getNonceAsync(); | |
var md5password = _md5(password); | |
var submitStrMd5 = _md5($"{md5password.ToUpper()}:{nonce}"); | |
var request = new HttpRequestMessage(HttpMethod.Post, "logon/loginJump.htm") | |
{ | |
Content = new FormUrlEncodedContent(new Dictionary<string, string> | |
{ | |
{"encoded", $"{username}:{submitStrMd5.ToUpper()}"}, | |
{"nonce", nonce }, | |
{"URL", "../logon/loginJump.htm" } | |
}) | |
}; | |
request.Headers.Add("Referer", "http://192.168.0.1/logon/logon.htm"); | |
var response = await _httpClient.SendAsync(request); | |
response.EnsureSuccessStatusCode(); | |
if ((await response.Content.ReadAsStringAsync()).Contains("/userRpm/Index.htm")) | |
{ | |
var indexResp = await _httpClient.GetAsync("userRpm/Index.htm"); | |
indexResp.EnsureSuccessStatusCode(); | |
return null; | |
} | |
throw new UnauthorizedAccessException("Couldn't login on the TL-ER6020!"); | |
async Task<string> getNonceAsync() | |
{ | |
var logonResponse = await _httpClient.GetAsync("logon/logon.htm"); | |
var cookie = logonResponse.Headers.Single(c => c.Key == "Set-Cookie").Value.Last(); | |
return cookie.Split("; ").First().Split('=')[1]; | |
} | |
} | |
public TplinkClientNetwork Network { get; } | |
public TplinkClientMaintenance Maintenance { get; } | |
private string _md5(string data) | |
{ | |
string strAlgName = HashAlgorithmNames.Md5; | |
IBuffer buffUtf8Msg = CryptographicBuffer.ConvertStringToBinary(data, BinaryStringEncoding.Utf8); | |
HashAlgorithmProvider objAlgProv = HashAlgorithmProvider.OpenAlgorithm(strAlgName); | |
IBuffer buffHash = objAlgProv.HashData(buffUtf8Msg); | |
if (buffHash.Length != objAlgProv.HashLength) | |
{ | |
throw new Exception("There was an error creating the hash"); | |
} | |
string hex = CryptographicBuffer.EncodeToHexString(buffHash); | |
return hex; | |
} | |
public void Dispose() => ((IDisposable)_httpClient).Dispose(); | |
public class TplinkClientNetwork | |
{ | |
internal TplinkClientNetwork(TplinkClient tplinkClient) | |
{ | |
Lan = new TplinkClientNetworkLan(tplinkClient); | |
} | |
public TplinkClientNetworkLan Lan { get; } | |
public class TplinkClientNetworkLan | |
{ | |
private readonly TplinkClient _tplinkClient; | |
internal TplinkClientNetworkLan(TplinkClient tplinkClient) => _tplinkClient = tplinkClient; | |
public async Task<dynamic[]> GetDhcpServerClientListAsync() | |
{ | |
var request = new HttpRequestMessage(HttpMethod.Get, "userRpm/DhcpServer_ClientList.htm?slt_interface=0"); | |
request.Headers.Add("Referer", "http://192.168.0.1/userRpm/Interface_LanSetting.htm"); | |
var response = await _tplinkClient._httpClient.SendAsync(request); | |
var result = new List<dynamic>(); | |
await Task.Run(async () => | |
{ | |
HtmlDocument doc = new HtmlDocument(); doc.LoadHtml(await response.Content.ReadAsStringAsync()); | |
var jsElem = doc.DocumentNode.SelectSingleNode("//script[position()=5]"); | |
var rows = jsElem.InnerText.Split("\n").Skip(2).SkipLast(2).Select((row, index) => new { row, index }) | |
.GroupBy(g => g.index / 4, i => i.row); | |
foreach (var group in rows) | |
{ | |
result.Add(new | |
{ | |
HostName = group.ElementAt(0).Trim(' ', '"', ','), | |
MacAddress = group.ElementAt(1).Trim(' ', '"', ',').Replace('-', ':'), | |
IpAddress = group.ElementAt(2).Trim(' ', '"', ',') | |
}); | |
} | |
}); | |
return result.ToArray(); | |
} | |
} | |
} | |
public class TplinkClientMaintenance | |
{ | |
internal TplinkClientMaintenance(TplinkClient tplinkClient) | |
{ | |
Statistics = new TplinkClientMaintenanceStatistics(tplinkClient); | |
} | |
public TplinkClientMaintenanceStatistics Statistics { get; } | |
public class TplinkClientMaintenanceStatistics | |
{ | |
private TplinkClient _tplinkClient; | |
public TplinkClientMaintenanceStatistics(TplinkClient tplinkClient) => _tplinkClient = tplinkClient; | |
public async Task<dynamic[]> GetIpTrafficStatisticsAsync() | |
{ | |
var request = new HttpRequestMessage(HttpMethod.Get, "userRpm/System_Statics.htm?ch_sta_en=1&btn_save=Save&comindex=0&direct=0"); | |
request.Headers.Add("Referer", "http://192.168.0.1/userRpm/Monitor_bandinfo.htm"); | |
var response = await _tplinkClient._httpClient.SendAsync(request); | |
var result = new List<dynamic>(); | |
await Task.Run(async () => | |
{ | |
HtmlDocument doc = new HtmlDocument(); doc.LoadHtml(await response.Content.ReadAsStringAsync()); | |
var jsElem = doc.DocumentNode.SelectSingleNode("//script[position()=6]"); | |
var rows = jsElem.InnerText.Split("\n").Skip(2).SkipLast(2).Select((row, index) => new { row, index }) | |
.GroupBy(g => g.index / 10, i => i.row); | |
foreach (var group in rows) | |
{ | |
result.Add(new | |
{ | |
IpAddress = group.ElementAt(0).Trim(' ', '"', ','), | |
TransmitingRateUp = decimal.Parse(group.ElementAt(8).Trim(' ', '"', ',')), | |
TransmitingRateDown = decimal.Parse(group.ElementAt(9).Trim(' ', '"', ',')), | |
PacketsRateUp = decimal.Parse(group.ElementAt(6).Trim(' ', '"', ',')), | |
PacketsRateDown = decimal.Parse(group.ElementAt(7).Trim(' ', '"', ',')), | |
TotalPacketsUp = decimal.Parse(group.ElementAt(2).Trim(' ', '"', ',')), | |
TotalPacketsDown = decimal.Parse(group.ElementAt(3).Trim(' ', '"', ',')), | |
TotalBytesUp = decimal.Parse(group.ElementAt(4).Trim(' ', '"', ',')), | |
TotalBytesDown = decimal.Parse(group.ElementAt(5).Trim(' ', '"', ',')), | |
}); | |
} | |
}); | |
return result.ToArray(); | |
} | |
} | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment