ClasslessStaticRouteOption.cs 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144
  1. /*
  2. Technitium DNS Server
  3. Copyright (C) 2019 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. ICollection<Route> _routes;
  27. #endregion
  28. #region constructor
  29. public ClasslessStaticRouteOption(ICollection<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. _routes = new List<Route>();
  44. while (s.Position < s.Length)
  45. {
  46. _routes.Add(new Route(s));
  47. }
  48. }
  49. protected override void WriteOptionValue(Stream s)
  50. {
  51. foreach (Route route in _routes)
  52. route.WriteTo(s);
  53. }
  54. #endregion
  55. #region properties
  56. public ICollection<Route> Routes
  57. { get { return _routes; } }
  58. #endregion
  59. public class Route
  60. {
  61. #region private
  62. readonly IPAddress _destination;
  63. readonly IPAddress _subnetMask;
  64. readonly IPAddress _router;
  65. #endregion
  66. #region constructor
  67. public Route(IPAddress destination, IPAddress subnetMask, IPAddress router)
  68. {
  69. _destination = destination;
  70. _subnetMask = subnetMask;
  71. _router = router;
  72. }
  73. public Route(Stream s)
  74. {
  75. int subnetMaskWidth = s.ReadByte();
  76. if (subnetMaskWidth < 0)
  77. throw new EndOfStreamException();
  78. byte[] destinationBuffer = new byte[4];
  79. s.ReadBytes(destinationBuffer, 0, Convert.ToInt32(Math.Ceiling(Convert.ToDecimal(subnetMaskWidth) / 8)));
  80. _destination = new IPAddress(destinationBuffer);
  81. _subnetMask = IPAddressExtension.GetSubnetMask(subnetMaskWidth);
  82. _router = new IPAddress(s.ReadBytes(4));
  83. }
  84. #endregion
  85. #region public
  86. public void WriteTo(Stream s)
  87. {
  88. byte subnetMaskWidth = (byte)_subnetMask.GetSubnetMaskWidth();
  89. s.WriteByte(subnetMaskWidth);
  90. s.Write(_destination.GetAddressBytes(), 0, Convert.ToInt32(Math.Ceiling(Convert.ToDecimal(subnetMaskWidth) / 8)));
  91. s.Write(_router.GetAddressBytes());
  92. }
  93. #endregion
  94. #region properties
  95. public IPAddress Destination
  96. { get { return _destination; } }
  97. public IPAddress SubnetMask
  98. { get { return _subnetMask; } }
  99. public IPAddress Router
  100. { get { return _router; } }
  101. #endregion
  102. }
  103. }
  104. }