ClasslessStaticRouteOption.cs 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146
  1. /*
  2. Technitium DNS Server
  3. Copyright (C) 2023 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 System;
  16. using System.Collections.Generic;
  17. using System.IO;
  18. using System.Net;
  19. using TechnitiumLibrary.IO;
  20. using TechnitiumLibrary.Net;
  21. namespace DnsServerCore.Dhcp.Options
  22. {
  23. public class ClasslessStaticRouteOption : DhcpOption
  24. {
  25. #region variables
  26. IReadOnlyCollection<Route> _routes;
  27. #endregion
  28. #region constructor
  29. public ClasslessStaticRouteOption(IReadOnlyCollection<Route> routes)
  30. : base(DhcpOptionCode.ClasslessStaticRoute)
  31. {
  32. _routes = routes;
  33. }
  34. public ClasslessStaticRouteOption(Stream s)
  35. : base(DhcpOptionCode.ClasslessStaticRoute, s)
  36. { }
  37. #endregion
  38. #region protected
  39. protected override void ParseOptionValue(Stream s)
  40. {
  41. if (s.Length < 5)
  42. throw new InvalidDataException();
  43. List<Route> routes = new List<Route>();
  44. while (s.Position < s.Length)
  45. {
  46. routes.Add(new Route(s));
  47. }
  48. _routes = routes;
  49. }
  50. protected override void WriteOptionValue(Stream s)
  51. {
  52. foreach (Route route in _routes)
  53. route.WriteTo(s);
  54. }
  55. #endregion
  56. #region properties
  57. public IReadOnlyCollection<Route> Routes
  58. { get { return _routes; } }
  59. #endregion
  60. public class Route
  61. {
  62. #region private
  63. readonly IPAddress _destination;
  64. readonly IPAddress _subnetMask;
  65. readonly IPAddress _router;
  66. #endregion
  67. #region constructor
  68. public Route(IPAddress destination, IPAddress subnetMask, IPAddress router)
  69. {
  70. _destination = destination;
  71. _subnetMask = subnetMask;
  72. _router = router;
  73. }
  74. public Route(Stream s)
  75. {
  76. int subnetMaskWidth = s.ReadByte();
  77. if (subnetMaskWidth < 0)
  78. throw new EndOfStreamException();
  79. byte[] destinationBuffer = new byte[4];
  80. s.ReadBytes(destinationBuffer, 0, Convert.ToInt32(Math.Ceiling(Convert.ToDecimal(subnetMaskWidth) / 8)));
  81. _destination = new IPAddress(destinationBuffer);
  82. _subnetMask = IPAddressExtensions.GetSubnetMask(subnetMaskWidth);
  83. _router = new IPAddress(s.ReadBytes(4));
  84. }
  85. #endregion
  86. #region public
  87. public void WriteTo(Stream s)
  88. {
  89. byte subnetMaskWidth = (byte)_subnetMask.GetSubnetMaskWidth();
  90. s.WriteByte(subnetMaskWidth);
  91. s.Write(_destination.GetAddressBytes(), 0, Convert.ToInt32(Math.Ceiling(Convert.ToDecimal(subnetMaskWidth) / 8)));
  92. s.Write(_router.GetAddressBytes());
  93. }
  94. #endregion
  95. #region properties
  96. public IPAddress Destination
  97. { get { return _destination; } }
  98. public IPAddress SubnetMask
  99. { get { return _subnetMask; } }
  100. public IPAddress Router
  101. { get { return _router; } }
  102. #endregion
  103. }
  104. }
  105. }