WebServiceDhcpApi.cs 36 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856
  1. /*
  2. Technitium DNS Server
  3. Copyright (C) 2024 Shreyas Zare (shreyas@technitium.com)
  4. This program is free software: you can redistribute it and/or modify
  5. it under the terms of the GNU General Public License as published by
  6. the Free Software Foundation, either version 3 of the License, or
  7. (at your option) any later version.
  8. This program is distributed in the hope that it will be useful,
  9. but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. GNU General Public License for more details.
  12. You should have received a copy of the GNU General Public License
  13. along with this program. If not, see <http://www.gnu.org/licenses/>.
  14. */
  15. using DnsServerCore.Auth;
  16. using DnsServerCore.Dhcp;
  17. using DnsServerCore.Dhcp.Options;
  18. using Microsoft.AspNetCore.Http;
  19. using System;
  20. using System.Collections.Generic;
  21. using System.Net;
  22. using System.Text.Json;
  23. using System.Threading.Tasks;
  24. using TechnitiumLibrary;
  25. namespace DnsServerCore
  26. {
  27. class WebServiceDhcpApi
  28. {
  29. #region variables
  30. static readonly char[] _commaSeparator = new char[] { ',' };
  31. readonly DnsWebService _dnsWebService;
  32. #endregion
  33. #region constructor
  34. public WebServiceDhcpApi(DnsWebService dnsWebService)
  35. {
  36. _dnsWebService = dnsWebService;
  37. }
  38. #endregion
  39. #region public
  40. public void ListDhcpLeases(HttpContext context)
  41. {
  42. UserSession session = context.GetCurrentSession();
  43. if (!_dnsWebService._authManager.IsPermitted(PermissionSection.DhcpServer, session.User, PermissionFlag.View))
  44. throw new DnsWebServiceException("Access was denied.");
  45. IReadOnlyDictionary<string, Scope> scopes = _dnsWebService.DhcpServer.Scopes;
  46. //sort by name
  47. List<Scope> sortedScopes = new List<Scope>(scopes.Count);
  48. foreach (KeyValuePair<string, Scope> entry in scopes)
  49. sortedScopes.Add(entry.Value);
  50. sortedScopes.Sort();
  51. Utf8JsonWriter jsonWriter = context.GetCurrentJsonWriter();
  52. jsonWriter.WritePropertyName("leases");
  53. jsonWriter.WriteStartArray();
  54. foreach (Scope scope in sortedScopes)
  55. {
  56. IReadOnlyDictionary<ClientIdentifierOption, Lease> leases = scope.Leases;
  57. //sort by address
  58. List<Lease> sortedLeases = new List<Lease>(leases.Count);
  59. foreach (KeyValuePair<ClientIdentifierOption, Lease> entry in leases)
  60. sortedLeases.Add(entry.Value);
  61. sortedLeases.Sort();
  62. foreach (Lease lease in sortedLeases)
  63. {
  64. jsonWriter.WriteStartObject();
  65. jsonWriter.WriteString("scope", scope.Name);
  66. jsonWriter.WriteString("type", lease.Type.ToString());
  67. jsonWriter.WriteString("hardwareAddress", BitConverter.ToString(lease.HardwareAddress));
  68. jsonWriter.WriteString("clientIdentifier", lease.ClientIdentifier.ToString());
  69. jsonWriter.WriteString("address", lease.Address.ToString());
  70. jsonWriter.WriteString("hostName", lease.HostName);
  71. jsonWriter.WriteString("leaseObtained", lease.LeaseObtained);
  72. jsonWriter.WriteString("leaseExpires", lease.LeaseExpires);
  73. jsonWriter.WriteEndObject();
  74. }
  75. }
  76. jsonWriter.WriteEndArray();
  77. }
  78. public void ListDhcpScopes(HttpContext context)
  79. {
  80. UserSession session = context.GetCurrentSession();
  81. if (!_dnsWebService._authManager.IsPermitted(PermissionSection.DhcpServer, session.User, PermissionFlag.View))
  82. throw new DnsWebServiceException("Access was denied.");
  83. IReadOnlyDictionary<string, Scope> scopes = _dnsWebService.DhcpServer.Scopes;
  84. //sort by name
  85. List<Scope> sortedScopes = new List<Scope>(scopes.Count);
  86. foreach (KeyValuePair<string, Scope> entry in scopes)
  87. sortedScopes.Add(entry.Value);
  88. sortedScopes.Sort();
  89. Utf8JsonWriter jsonWriter = context.GetCurrentJsonWriter();
  90. jsonWriter.WritePropertyName("scopes");
  91. jsonWriter.WriteStartArray();
  92. foreach (Scope scope in sortedScopes)
  93. {
  94. jsonWriter.WriteStartObject();
  95. jsonWriter.WriteString("name", scope.Name);
  96. jsonWriter.WriteBoolean("enabled", scope.Enabled);
  97. jsonWriter.WriteString("startingAddress", scope.StartingAddress.ToString());
  98. jsonWriter.WriteString("endingAddress", scope.EndingAddress.ToString());
  99. jsonWriter.WriteString("subnetMask", scope.SubnetMask.ToString());
  100. jsonWriter.WriteString("networkAddress", scope.NetworkAddress.ToString());
  101. jsonWriter.WriteString("broadcastAddress", scope.BroadcastAddress.ToString());
  102. if (scope.InterfaceAddress is not null)
  103. jsonWriter.WriteString("interfaceAddress", scope.InterfaceAddress.ToString());
  104. jsonWriter.WriteEndObject();
  105. }
  106. jsonWriter.WriteEndArray();
  107. }
  108. public void GetDhcpScope(HttpContext context)
  109. {
  110. UserSession session = context.GetCurrentSession();
  111. if (!_dnsWebService._authManager.IsPermitted(PermissionSection.DhcpServer, session.User, PermissionFlag.View))
  112. throw new DnsWebServiceException("Access was denied.");
  113. string scopeName = context.Request.GetQueryOrForm("name");
  114. Scope scope = _dnsWebService.DhcpServer.GetScope(scopeName);
  115. if (scope is null)
  116. throw new DnsWebServiceException("DHCP scope was not found: " + scopeName);
  117. Utf8JsonWriter jsonWriter = context.GetCurrentJsonWriter();
  118. jsonWriter.WriteString("name", scope.Name);
  119. jsonWriter.WriteString("startingAddress", scope.StartingAddress.ToString());
  120. jsonWriter.WriteString("endingAddress", scope.EndingAddress.ToString());
  121. jsonWriter.WriteString("subnetMask", scope.SubnetMask.ToString());
  122. jsonWriter.WriteNumber("leaseTimeDays", scope.LeaseTimeDays);
  123. jsonWriter.WriteNumber("leaseTimeHours", scope.LeaseTimeHours);
  124. jsonWriter.WriteNumber("leaseTimeMinutes", scope.LeaseTimeMinutes);
  125. jsonWriter.WriteNumber("offerDelayTime", scope.OfferDelayTime);
  126. jsonWriter.WriteBoolean("pingCheckEnabled", scope.PingCheckEnabled);
  127. jsonWriter.WriteNumber("pingCheckTimeout", scope.PingCheckTimeout);
  128. jsonWriter.WriteNumber("pingCheckRetries", scope.PingCheckRetries);
  129. if (!string.IsNullOrEmpty(scope.DomainName))
  130. jsonWriter.WriteString("domainName", scope.DomainName);
  131. if (scope.DomainSearchList is not null)
  132. {
  133. jsonWriter.WritePropertyName("domainSearchList");
  134. jsonWriter.WriteStartArray();
  135. foreach (string domainSearchString in scope.DomainSearchList)
  136. jsonWriter.WriteStringValue(domainSearchString);
  137. jsonWriter.WriteEndArray();
  138. }
  139. jsonWriter.WriteBoolean("dnsUpdates", scope.DnsUpdates);
  140. jsonWriter.WriteNumber("dnsTtl", scope.DnsTtl);
  141. if (scope.ServerAddress is not null)
  142. jsonWriter.WriteString("serverAddress", scope.ServerAddress.ToString());
  143. if (scope.ServerHostName is not null)
  144. jsonWriter.WriteString("serverHostName", scope.ServerHostName);
  145. if (scope.BootFileName is not null)
  146. jsonWriter.WriteString("bootFileName", scope.BootFileName);
  147. if (scope.RouterAddress is not null)
  148. jsonWriter.WriteString("routerAddress", scope.RouterAddress.ToString());
  149. jsonWriter.WriteBoolean("useThisDnsServer", scope.UseThisDnsServer);
  150. if (scope.DnsServers is not null)
  151. {
  152. jsonWriter.WritePropertyName("dnsServers");
  153. jsonWriter.WriteStartArray();
  154. foreach (IPAddress dnsServer in scope.DnsServers)
  155. jsonWriter.WriteStringValue(dnsServer.ToString());
  156. jsonWriter.WriteEndArray();
  157. }
  158. if (scope.WinsServers is not null)
  159. {
  160. jsonWriter.WritePropertyName("winsServers");
  161. jsonWriter.WriteStartArray();
  162. foreach (IPAddress winsServer in scope.WinsServers)
  163. jsonWriter.WriteStringValue(winsServer.ToString());
  164. jsonWriter.WriteEndArray();
  165. }
  166. if (scope.NtpServers is not null)
  167. {
  168. jsonWriter.WritePropertyName("ntpServers");
  169. jsonWriter.WriteStartArray();
  170. foreach (IPAddress ntpServer in scope.NtpServers)
  171. jsonWriter.WriteStringValue(ntpServer.ToString());
  172. jsonWriter.WriteEndArray();
  173. }
  174. if (scope.NtpServerDomainNames is not null)
  175. {
  176. jsonWriter.WritePropertyName("ntpServerDomainNames");
  177. jsonWriter.WriteStartArray();
  178. foreach (string ntpServerDomainName in scope.NtpServerDomainNames)
  179. jsonWriter.WriteStringValue(ntpServerDomainName);
  180. jsonWriter.WriteEndArray();
  181. }
  182. if (scope.StaticRoutes is not null)
  183. {
  184. jsonWriter.WritePropertyName("staticRoutes");
  185. jsonWriter.WriteStartArray();
  186. foreach (ClasslessStaticRouteOption.Route route in scope.StaticRoutes)
  187. {
  188. jsonWriter.WriteStartObject();
  189. jsonWriter.WriteString("destination", route.Destination.ToString());
  190. jsonWriter.WriteString("subnetMask", route.SubnetMask.ToString());
  191. jsonWriter.WriteString("router", route.Router.ToString());
  192. jsonWriter.WriteEndObject();
  193. }
  194. jsonWriter.WriteEndArray();
  195. }
  196. if (scope.VendorInfo is not null)
  197. {
  198. jsonWriter.WritePropertyName("vendorInfo");
  199. jsonWriter.WriteStartArray();
  200. foreach (KeyValuePair<string, VendorSpecificInformationOption> entry in scope.VendorInfo)
  201. {
  202. jsonWriter.WriteStartObject();
  203. jsonWriter.WriteString("identifier", entry.Key);
  204. jsonWriter.WriteString("information", BitConverter.ToString(entry.Value.Information).Replace('-', ':'));
  205. jsonWriter.WriteEndObject();
  206. }
  207. jsonWriter.WriteEndArray();
  208. }
  209. if (scope.CAPWAPAcIpAddresses is not null)
  210. {
  211. jsonWriter.WritePropertyName("capwapAcIpAddresses");
  212. jsonWriter.WriteStartArray();
  213. foreach (IPAddress acIpAddress in scope.CAPWAPAcIpAddresses)
  214. jsonWriter.WriteStringValue(acIpAddress.ToString());
  215. jsonWriter.WriteEndArray();
  216. }
  217. if (scope.TftpServerAddresses is not null)
  218. {
  219. jsonWriter.WritePropertyName("tftpServerAddresses");
  220. jsonWriter.WriteStartArray();
  221. foreach (IPAddress address in scope.TftpServerAddresses)
  222. jsonWriter.WriteStringValue(address.ToString());
  223. jsonWriter.WriteEndArray();
  224. }
  225. if (scope.GenericOptions is not null)
  226. {
  227. jsonWriter.WritePropertyName("genericOptions");
  228. jsonWriter.WriteStartArray();
  229. foreach (DhcpOption genericOption in scope.GenericOptions)
  230. {
  231. jsonWriter.WriteStartObject();
  232. jsonWriter.WriteNumber("code", (byte)genericOption.Code);
  233. jsonWriter.WriteString("value", BitConverter.ToString(genericOption.RawValue).Replace('-', ':'));
  234. jsonWriter.WriteEndObject();
  235. }
  236. jsonWriter.WriteEndArray();
  237. }
  238. if (scope.Exclusions is not null)
  239. {
  240. jsonWriter.WritePropertyName("exclusions");
  241. jsonWriter.WriteStartArray();
  242. foreach (Exclusion exclusion in scope.Exclusions)
  243. {
  244. jsonWriter.WriteStartObject();
  245. jsonWriter.WriteString("startingAddress", exclusion.StartingAddress.ToString());
  246. jsonWriter.WriteString("endingAddress", exclusion.EndingAddress.ToString());
  247. jsonWriter.WriteEndObject();
  248. }
  249. jsonWriter.WriteEndArray();
  250. }
  251. jsonWriter.WritePropertyName("reservedLeases");
  252. jsonWriter.WriteStartArray();
  253. foreach (Lease reservedLease in scope.ReservedLeases)
  254. {
  255. jsonWriter.WriteStartObject();
  256. jsonWriter.WriteString("hostName", reservedLease.HostName);
  257. jsonWriter.WriteString("hardwareAddress", BitConverter.ToString(reservedLease.HardwareAddress));
  258. jsonWriter.WriteString("address", reservedLease.Address.ToString());
  259. jsonWriter.WriteString("comments", reservedLease.Comments);
  260. jsonWriter.WriteEndObject();
  261. }
  262. jsonWriter.WriteEndArray();
  263. jsonWriter.WriteBoolean("allowOnlyReservedLeases", scope.AllowOnlyReservedLeases);
  264. jsonWriter.WriteBoolean("blockLocallyAdministeredMacAddresses", scope.BlockLocallyAdministeredMacAddresses);
  265. jsonWriter.WriteBoolean("ignoreClientIdentifierOption", scope.IgnoreClientIdentifierOption);
  266. }
  267. public async Task SetDhcpScopeAsync(HttpContext context)
  268. {
  269. UserSession session = context.GetCurrentSession();
  270. if (!_dnsWebService._authManager.IsPermitted(PermissionSection.DhcpServer, session.User, PermissionFlag.Modify))
  271. throw new DnsWebServiceException("Access was denied.");
  272. HttpRequest request = context.Request;
  273. string scopeName = request.GetQueryOrForm("name");
  274. string strStartingAddress = request.QueryOrForm("startingAddress");
  275. string strEndingAddress = request.QueryOrForm("endingAddress");
  276. string strSubnetMask = request.QueryOrForm("subnetMask");
  277. bool scopeExists;
  278. Scope scope = _dnsWebService.DhcpServer.GetScope(scopeName);
  279. if (scope is null)
  280. {
  281. //scope does not exists; create new scope
  282. if (string.IsNullOrEmpty(strStartingAddress))
  283. throw new DnsWebServiceException("Parameter 'startingAddress' missing.");
  284. if (string.IsNullOrEmpty(strEndingAddress))
  285. throw new DnsWebServiceException("Parameter 'endingAddress' missing.");
  286. if (string.IsNullOrEmpty(strSubnetMask))
  287. throw new DnsWebServiceException("Parameter 'subnetMask' missing.");
  288. scopeExists = false;
  289. scope = new Scope(scopeName, true, IPAddress.Parse(strStartingAddress), IPAddress.Parse(strEndingAddress), IPAddress.Parse(strSubnetMask), _dnsWebService._log, _dnsWebService.DhcpServer);
  290. scope.IgnoreClientIdentifierOption = true;
  291. }
  292. else
  293. {
  294. scopeExists = true;
  295. IPAddress startingAddress = string.IsNullOrEmpty(strStartingAddress) ? scope.StartingAddress : IPAddress.Parse(strStartingAddress);
  296. IPAddress endingAddress = string.IsNullOrEmpty(strEndingAddress) ? scope.EndingAddress : IPAddress.Parse(strEndingAddress);
  297. IPAddress subnetMask = string.IsNullOrEmpty(strSubnetMask) ? scope.SubnetMask : IPAddress.Parse(strSubnetMask);
  298. //validate scope address
  299. foreach (KeyValuePair<string, Scope> entry in _dnsWebService.DhcpServer.Scopes)
  300. {
  301. Scope existingScope = entry.Value;
  302. if (existingScope.Equals(scope))
  303. continue;
  304. if (existingScope.IsAddressInRange(startingAddress) || existingScope.IsAddressInRange(endingAddress))
  305. throw new DhcpServerException("Scope with overlapping range already exists: " + existingScope.StartingAddress.ToString() + "-" + existingScope.EndingAddress.ToString());
  306. }
  307. scope.ChangeNetwork(startingAddress, endingAddress, subnetMask);
  308. }
  309. if (request.TryGetQueryOrForm("leaseTimeDays", ushort.Parse, out ushort leaseTimeDays))
  310. scope.LeaseTimeDays = leaseTimeDays;
  311. if (request.TryGetQueryOrForm("leaseTimeHours", byte.Parse, out byte leaseTimeHours))
  312. scope.LeaseTimeHours = leaseTimeHours;
  313. if (request.TryGetQueryOrForm("leaseTimeMinutes", byte.Parse, out byte leaseTimeMinutes))
  314. scope.LeaseTimeMinutes = leaseTimeMinutes;
  315. if (request.TryGetQueryOrForm("offerDelayTime", ushort.Parse, out ushort offerDelayTime))
  316. scope.OfferDelayTime = offerDelayTime;
  317. if (request.TryGetQueryOrForm("pingCheckEnabled", bool.Parse, out bool pingCheckEnabled))
  318. scope.PingCheckEnabled = pingCheckEnabled;
  319. if (request.TryGetQueryOrForm("pingCheckTimeout", ushort.Parse, out ushort pingCheckTimeout))
  320. scope.PingCheckTimeout = pingCheckTimeout;
  321. if (request.TryGetQueryOrForm("pingCheckRetries", byte.Parse, out byte pingCheckRetries))
  322. scope.PingCheckRetries = pingCheckRetries;
  323. string domainName = request.QueryOrForm("domainName");
  324. if (domainName is not null)
  325. scope.DomainName = domainName.Length == 0 ? null : domainName;
  326. string domainSearchList = request.QueryOrForm("domainSearchList");
  327. if (domainSearchList is not null)
  328. {
  329. if (domainSearchList.Length == 0)
  330. scope.DomainSearchList = null;
  331. else
  332. scope.DomainSearchList = domainSearchList.Split(_commaSeparator, StringSplitOptions.RemoveEmptyEntries);
  333. }
  334. if (request.TryGetQueryOrForm("dnsUpdates", bool.Parse, out bool dnsUpdates))
  335. scope.DnsUpdates = dnsUpdates;
  336. if (request.TryGetQueryOrForm("dnsTtl", uint.Parse, out uint dnsTtl))
  337. scope.DnsTtl = dnsTtl;
  338. string serverAddress = request.QueryOrForm("serverAddress");
  339. if (serverAddress is not null)
  340. scope.ServerAddress = serverAddress.Length == 0 ? null : IPAddress.Parse(serverAddress);
  341. string serverHostName = request.QueryOrForm("serverHostName");
  342. if (serverHostName is not null)
  343. scope.ServerHostName = serverHostName.Length == 0 ? null : serverHostName;
  344. string bootFileName = request.QueryOrForm("bootFileName");
  345. if (bootFileName is not null)
  346. scope.BootFileName = bootFileName.Length == 0 ? null : bootFileName;
  347. string routerAddress = request.QueryOrForm("routerAddress");
  348. if (routerAddress is not null)
  349. scope.RouterAddress = routerAddress.Length == 0 ? null : IPAddress.Parse(routerAddress);
  350. if (request.TryGetQueryOrForm("useThisDnsServer", bool.Parse, out bool useThisDnsServer))
  351. scope.UseThisDnsServer = useThisDnsServer;
  352. if (!scope.UseThisDnsServer)
  353. {
  354. string dnsServers = request.QueryOrForm("dnsServers");
  355. if (dnsServers is not null)
  356. {
  357. if (dnsServers.Length == 0)
  358. scope.DnsServers = null;
  359. else
  360. scope.DnsServers = dnsServers.Split(IPAddress.Parse, ',');
  361. }
  362. }
  363. string winsServers = request.QueryOrForm("winsServers");
  364. if (winsServers is not null)
  365. {
  366. if (winsServers.Length == 0)
  367. scope.WinsServers = null;
  368. else
  369. scope.WinsServers = winsServers.Split(IPAddress.Parse, ',');
  370. }
  371. string ntpServers = request.QueryOrForm("ntpServers");
  372. if (ntpServers is not null)
  373. {
  374. if (ntpServers.Length == 0)
  375. scope.NtpServers = null;
  376. else
  377. scope.NtpServers = ntpServers.Split(IPAddress.Parse, ',');
  378. }
  379. string ntpServerDomainNames = request.QueryOrForm("ntpServerDomainNames");
  380. if (ntpServerDomainNames is not null)
  381. {
  382. if (ntpServerDomainNames.Length == 0)
  383. scope.NtpServerDomainNames = null;
  384. else
  385. scope.NtpServerDomainNames = ntpServerDomainNames.Split(_commaSeparator, StringSplitOptions.RemoveEmptyEntries);
  386. }
  387. string strStaticRoutes = request.QueryOrForm("staticRoutes");
  388. if (strStaticRoutes is not null)
  389. {
  390. if (strStaticRoutes.Length == 0)
  391. {
  392. scope.StaticRoutes = null;
  393. }
  394. else
  395. {
  396. string[] strStaticRoutesParts = strStaticRoutes.Split('|');
  397. List<ClasslessStaticRouteOption.Route> staticRoutes = new List<ClasslessStaticRouteOption.Route>();
  398. for (int i = 0; i < strStaticRoutesParts.Length; i += 3)
  399. staticRoutes.Add(new ClasslessStaticRouteOption.Route(IPAddress.Parse(strStaticRoutesParts[i + 0]), IPAddress.Parse(strStaticRoutesParts[i + 1]), IPAddress.Parse(strStaticRoutesParts[i + 2])));
  400. scope.StaticRoutes = staticRoutes;
  401. }
  402. }
  403. string strVendorInfo = request.QueryOrForm("vendorInfo");
  404. if (strVendorInfo is not null)
  405. {
  406. if (strVendorInfo.Length == 0)
  407. {
  408. scope.VendorInfo = null;
  409. }
  410. else
  411. {
  412. string[] strVendorInfoParts = strVendorInfo.Split('|');
  413. Dictionary<string, VendorSpecificInformationOption> vendorInfo = new Dictionary<string, VendorSpecificInformationOption>();
  414. for (int i = 0; i < strVendorInfoParts.Length; i += 2)
  415. vendorInfo.Add(strVendorInfoParts[i + 0], new VendorSpecificInformationOption(strVendorInfoParts[i + 1]));
  416. scope.VendorInfo = vendorInfo;
  417. }
  418. }
  419. string capwapAcIpAddresses = request.QueryOrForm("capwapAcIpAddresses");
  420. if (capwapAcIpAddresses is not null)
  421. {
  422. if (capwapAcIpAddresses.Length == 0)
  423. scope.CAPWAPAcIpAddresses = null;
  424. else
  425. scope.CAPWAPAcIpAddresses = capwapAcIpAddresses.Split(IPAddress.Parse, ',');
  426. }
  427. string tftpServerAddresses = request.QueryOrForm("tftpServerAddresses");
  428. if (tftpServerAddresses is not null)
  429. {
  430. if (tftpServerAddresses.Length == 0)
  431. scope.TftpServerAddresses = null;
  432. else
  433. scope.TftpServerAddresses = tftpServerAddresses.Split(IPAddress.Parse, ',');
  434. }
  435. string strGenericOptions = request.QueryOrForm("genericOptions");
  436. if (strGenericOptions is not null)
  437. {
  438. if (strGenericOptions.Length == 0)
  439. {
  440. scope.GenericOptions = null;
  441. }
  442. else
  443. {
  444. string[] strGenericOptionsParts = strGenericOptions.Split('|');
  445. List<DhcpOption> genericOptions = new List<DhcpOption>();
  446. for (int i = 0; i < strGenericOptionsParts.Length; i += 2)
  447. genericOptions.Add(new DhcpOption((DhcpOptionCode)byte.Parse(strGenericOptionsParts[i + 0]), strGenericOptionsParts[i + 1]));
  448. scope.GenericOptions = genericOptions;
  449. }
  450. }
  451. string strExclusions = request.QueryOrForm("exclusions");
  452. if (strExclusions is not null)
  453. {
  454. if (strExclusions.Length == 0)
  455. {
  456. scope.Exclusions = null;
  457. }
  458. else
  459. {
  460. string[] strExclusionsParts = strExclusions.Split('|');
  461. List<Exclusion> exclusions = new List<Exclusion>();
  462. for (int i = 0; i < strExclusionsParts.Length; i += 2)
  463. exclusions.Add(new Exclusion(IPAddress.Parse(strExclusionsParts[i + 0]), IPAddress.Parse(strExclusionsParts[i + 1])));
  464. scope.Exclusions = exclusions;
  465. }
  466. }
  467. string strReservedLeases = request.QueryOrForm("reservedLeases");
  468. if (strReservedLeases is not null)
  469. {
  470. if (strReservedLeases.Length == 0)
  471. {
  472. scope.ReservedLeases = null;
  473. }
  474. else
  475. {
  476. string[] strReservedLeaseParts = strReservedLeases.Split('|');
  477. List<Lease> reservedLeases = new List<Lease>();
  478. for (int i = 0; i < strReservedLeaseParts.Length; i += 4)
  479. reservedLeases.Add(new Lease(LeaseType.Reserved, strReservedLeaseParts[i + 0], DhcpMessageHardwareAddressType.Ethernet, strReservedLeaseParts[i + 1], IPAddress.Parse(strReservedLeaseParts[i + 2]), strReservedLeaseParts[i + 3]));
  480. scope.ReservedLeases = reservedLeases;
  481. }
  482. }
  483. if (request.TryGetQueryOrForm("allowOnlyReservedLeases", bool.Parse, out bool allowOnlyReservedLeases))
  484. scope.AllowOnlyReservedLeases = allowOnlyReservedLeases;
  485. if (request.TryGetQueryOrForm("blockLocallyAdministeredMacAddresses", bool.Parse, out bool blockLocallyAdministeredMacAddresses))
  486. scope.BlockLocallyAdministeredMacAddresses = blockLocallyAdministeredMacAddresses;
  487. if (request.TryGetQueryOrForm("ignoreClientIdentifierOption", bool.Parse, out bool ignoreClientIdentifierOption))
  488. scope.IgnoreClientIdentifierOption = ignoreClientIdentifierOption;
  489. if (scopeExists)
  490. {
  491. _dnsWebService.DhcpServer.SaveScope(scopeName);
  492. _dnsWebService._log.Write(context.GetRemoteEndPoint(), "[" + session.User.Username + "] DHCP scope was updated successfully: " + scopeName);
  493. }
  494. else
  495. {
  496. await _dnsWebService.DhcpServer.AddScopeAsync(scope);
  497. _dnsWebService._log.Write(context.GetRemoteEndPoint(), "[" + session.User.Username + "] DHCP scope was added successfully: " + scopeName);
  498. }
  499. if (request.TryGetQueryOrForm("newName", out string newName) && !newName.Equals(scopeName))
  500. {
  501. _dnsWebService.DhcpServer.RenameScope(scopeName, newName);
  502. _dnsWebService._log.Write(context.GetRemoteEndPoint(), "[" + session.User.Username + "] DHCP scope was renamed successfully: '" + scopeName + "' to '" + newName + "'");
  503. }
  504. }
  505. public void AddReservedLease(HttpContext context)
  506. {
  507. UserSession session = context.GetCurrentSession();
  508. if (!_dnsWebService._authManager.IsPermitted(PermissionSection.DhcpServer, session.User, PermissionFlag.Modify))
  509. throw new DnsWebServiceException("Access was denied.");
  510. HttpRequest request = context.Request;
  511. string scopeName = request.GetQueryOrForm("name");
  512. Scope scope = _dnsWebService.DhcpServer.GetScope(scopeName);
  513. if (scope is null)
  514. throw new DnsWebServiceException("No such scope exists: " + scopeName);
  515. string hostName = request.QueryOrForm("hostName");
  516. string hardwareAddress = request.GetQueryOrForm("hardwareAddress");
  517. string strIpAddress = request.GetQueryOrForm("ipAddress");
  518. string comments = request.QueryOrForm("comments");
  519. Lease reservedLease = new Lease(LeaseType.Reserved, hostName, DhcpMessageHardwareAddressType.Ethernet, hardwareAddress, IPAddress.Parse(strIpAddress), comments);
  520. if (!scope.AddReservedLease(reservedLease))
  521. throw new DnsWebServiceException("Failed to add reserved lease for scope: " + scopeName);
  522. _dnsWebService.DhcpServer.SaveScope(scopeName);
  523. _dnsWebService._log.Write(context.GetRemoteEndPoint(), "[" + session.User.Username + "] DHCP scope reserved lease was added successfully: " + scopeName);
  524. }
  525. public void RemoveReservedLease(HttpContext context)
  526. {
  527. UserSession session = context.GetCurrentSession();
  528. if (!_dnsWebService._authManager.IsPermitted(PermissionSection.DhcpServer, session.User, PermissionFlag.Modify))
  529. throw new DnsWebServiceException("Access was denied.");
  530. HttpRequest request = context.Request;
  531. string scopeName = request.GetQueryOrForm("name");
  532. Scope scope = _dnsWebService.DhcpServer.GetScope(scopeName);
  533. if (scope is null)
  534. throw new DnsWebServiceException("No such scope exists: " + scopeName);
  535. string hardwareAddress = request.GetQueryOrForm("hardwareAddress");
  536. if (!scope.RemoveReservedLease(hardwareAddress))
  537. throw new DnsWebServiceException("Failed to remove reserved lease for scope: " + scopeName);
  538. _dnsWebService.DhcpServer.SaveScope(scopeName);
  539. _dnsWebService._log.Write(context.GetRemoteEndPoint(), "[" + session.User.Username + "] DHCP scope reserved lease was removed successfully: " + scopeName);
  540. }
  541. public async Task EnableDhcpScopeAsync(HttpContext context)
  542. {
  543. UserSession session = context.GetCurrentSession();
  544. if (!_dnsWebService._authManager.IsPermitted(PermissionSection.DhcpServer, session.User, PermissionFlag.Modify))
  545. throw new DnsWebServiceException("Access was denied.");
  546. string scopeName = context.Request.GetQueryOrForm("name");
  547. await _dnsWebService.DhcpServer.EnableScopeAsync(scopeName, true);
  548. _dnsWebService._log.Write(context.GetRemoteEndPoint(), "[" + session.User.Username + "] DHCP scope was enabled successfully: " + scopeName);
  549. }
  550. public void DisableDhcpScope(HttpContext context)
  551. {
  552. UserSession session = context.GetCurrentSession();
  553. if (!_dnsWebService._authManager.IsPermitted(PermissionSection.DhcpServer, session.User, PermissionFlag.Modify))
  554. throw new DnsWebServiceException("Access was denied.");
  555. string scopeName = context.Request.GetQueryOrForm("name");
  556. _dnsWebService.DhcpServer.DisableScope(scopeName, true);
  557. _dnsWebService._log.Write(context.GetRemoteEndPoint(), "[" + session.User.Username + "] DHCP scope was disabled successfully: " + scopeName);
  558. }
  559. public void DeleteDhcpScope(HttpContext context)
  560. {
  561. UserSession session = context.GetCurrentSession();
  562. if (!_dnsWebService._authManager.IsPermitted(PermissionSection.DhcpServer, session.User, PermissionFlag.Delete))
  563. throw new DnsWebServiceException("Access was denied.");
  564. string scopeName = context.Request.GetQueryOrForm("name");
  565. _dnsWebService.DhcpServer.DeleteScope(scopeName);
  566. _dnsWebService._log.Write(context.GetRemoteEndPoint(), "[" + session.User.Username + "] DHCP scope was deleted successfully: " + scopeName);
  567. }
  568. public void RemoveDhcpLease(HttpContext context)
  569. {
  570. UserSession session = context.GetCurrentSession();
  571. if (!_dnsWebService._authManager.IsPermitted(PermissionSection.DhcpServer, session.User, PermissionFlag.Delete))
  572. throw new DnsWebServiceException("Access was denied.");
  573. HttpRequest request = context.Request;
  574. string scopeName = request.GetQueryOrForm("name");
  575. Scope scope = _dnsWebService.DhcpServer.GetScope(scopeName);
  576. if (scope is null)
  577. throw new DnsWebServiceException("DHCP scope does not exists: " + scopeName);
  578. string clientIdentifier = request.QueryOrForm("clientIdentifier");
  579. string hardwareAddress = request.QueryOrForm("hardwareAddress");
  580. if (!string.IsNullOrEmpty(clientIdentifier))
  581. scope.RemoveLease(ClientIdentifierOption.Parse(clientIdentifier));
  582. else if (!string.IsNullOrEmpty(hardwareAddress))
  583. scope.RemoveLease(hardwareAddress);
  584. else
  585. throw new DnsWebServiceException("Parameter 'hardwareAddress' or 'clientIdentifier' missing. At least one of them must be specified.");
  586. _dnsWebService.DhcpServer.SaveScope(scopeName);
  587. _dnsWebService._log.Write(context.GetRemoteEndPoint(), "[" + session.User.Username + "] DHCP scope's lease was removed successfully: " + scopeName);
  588. }
  589. public void ConvertToReservedLease(HttpContext context)
  590. {
  591. UserSession session = context.GetCurrentSession();
  592. if (!_dnsWebService._authManager.IsPermitted(PermissionSection.DhcpServer, session.User, PermissionFlag.Modify))
  593. throw new DnsWebServiceException("Access was denied.");
  594. HttpRequest request = context.Request;
  595. string scopeName = request.GetQueryOrForm("name");
  596. Scope scope = _dnsWebService.DhcpServer.GetScope(scopeName);
  597. if (scope == null)
  598. throw new DnsWebServiceException("DHCP scope does not exists: " + scopeName);
  599. string clientIdentifier = request.QueryOrForm("clientIdentifier");
  600. string hardwareAddress = request.QueryOrForm("hardwareAddress");
  601. if (!string.IsNullOrEmpty(clientIdentifier))
  602. scope.ConvertToReservedLease(ClientIdentifierOption.Parse(clientIdentifier));
  603. else if (!string.IsNullOrEmpty(hardwareAddress))
  604. scope.ConvertToReservedLease(hardwareAddress);
  605. else
  606. throw new DnsWebServiceException("Parameter 'hardwareAddress' or 'clientIdentifier' missing. At least one of them must be specified.");
  607. _dnsWebService.DhcpServer.SaveScope(scopeName);
  608. _dnsWebService._log.Write(context.GetRemoteEndPoint(), "[" + session.User.Username + "] DHCP scope's lease was reserved successfully: " + scopeName);
  609. }
  610. public void ConvertToDynamicLease(HttpContext context)
  611. {
  612. UserSession session = context.GetCurrentSession();
  613. if (!_dnsWebService._authManager.IsPermitted(PermissionSection.DhcpServer, session.User, PermissionFlag.Modify))
  614. throw new DnsWebServiceException("Access was denied.");
  615. HttpRequest request = context.Request;
  616. string scopeName = request.GetQueryOrForm("name");
  617. Scope scope = _dnsWebService.DhcpServer.GetScope(scopeName);
  618. if (scope == null)
  619. throw new DnsWebServiceException("DHCP scope does not exists: " + scopeName);
  620. string clientIdentifier = request.QueryOrForm("clientIdentifier");
  621. string hardwareAddress = request.QueryOrForm("hardwareAddress");
  622. if (!string.IsNullOrEmpty(clientIdentifier))
  623. scope.ConvertToDynamicLease(ClientIdentifierOption.Parse(clientIdentifier));
  624. else if (!string.IsNullOrEmpty(hardwareAddress))
  625. scope.ConvertToDynamicLease(hardwareAddress);
  626. else
  627. throw new DnsWebServiceException("Parameter 'hardwareAddress' or 'clientIdentifier' missing. At least one of them must be specified.");
  628. _dnsWebService.DhcpServer.SaveScope(scopeName);
  629. _dnsWebService._log.Write(context.GetRemoteEndPoint(), "[" + session.User.Username + "] DHCP scope's lease was unreserved successfully: " + scopeName);
  630. }
  631. #endregion
  632. }
  633. }