DhcpPacket.cs 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153
  1. using DhcpServer.Utils;
  2. using System;
  3. using System.Collections.Generic;
  4. using System.IO;
  5. using System.Net;
  6. using System.Text;
  7. namespace DhcpServer
  8. {
  9. public partial class DhcpPacket
  10. {
  11. public DhcpOpCode OpCode { get; set; }
  12. public DhcpHardwareType HardwareType { get; set; }
  13. public byte Hops { get; set; }
  14. public int TransactionId { get; set; }
  15. public short SecondsElapsed { get; set; }
  16. public DhcpBootpFlag BootpFlags { get; set; }
  17. public IPAddress ClientIpAddress { get; set; }
  18. public IPAddress YourIpAddress { get; set; }
  19. public IPAddress NextServerIpAddress { get; set; }
  20. public IPAddress RelayAgentIpAddress { get; set; }
  21. public byte[] ClientMacAddress { get; set; }
  22. public string ServerHostName { get; set; }
  23. public string BootFileName { get; set; }
  24. public int MagicCookie { get; set; } = 0x63825363;
  25. public Dictionary<DhcpOption, byte[]> Options { get; set; } = new Dictionary<DhcpOption, byte[]>();
  26. public DhcpMessageType MessageType
  27. {
  28. get => Options.MapValue(DhcpOption.DhcpMessageType, value => (DhcpMessageType)value[0]);
  29. set => Options[DhcpOption.DhcpMessageType] = new[] { (byte)value };
  30. }
  31. public IPAddress SubNetMask
  32. {
  33. get => Options.MapValue(DhcpOption.SubNetMask, value => new IPAddress(value));
  34. set => Options[DhcpOption.SubNetMask] = value.GetAddressBytes();
  35. }
  36. public IPAddress Router
  37. {
  38. get => Options.MapValue(DhcpOption.Router, value => new IPAddress(value));
  39. set => Options[DhcpOption.Router] = value.GetAddressBytes();
  40. }
  41. public IPAddress DnsServer
  42. {
  43. get => Options.MapValue(DhcpOption.DnsServer, value => new IPAddress(value));
  44. set => Options[DhcpOption.DnsServer] = value.GetAddressBytes();
  45. }
  46. public string TftpServer
  47. {
  48. get => Options.MapValue(DhcpOption.TftpServer, value => Encoding.ASCII.GetString(value));
  49. set => Options[DhcpOption.TftpServer] = Encoding.ASCII.GetBytes(value);
  50. }
  51. public IPAddress DhcpServerIdentifier
  52. {
  53. get => Options.MapValue(DhcpOption.DhcpServerIdentifier, value => new IPAddress(value));
  54. set => Options[DhcpOption.DhcpServerIdentifier] = value.GetAddressBytes();
  55. }
  56. public DhcpPacket(byte[] buffer)
  57. {
  58. using var stream = new MemoryStream(buffer);
  59. using var reader = new BinaryReader(stream);
  60. OpCode = (DhcpOpCode)reader.ReadByte();
  61. HardwareType = (DhcpHardwareType)reader.ReadByte();
  62. var hardwareAddressLength = reader.ReadByte();
  63. Hops = reader.ReadByte();
  64. TransactionId = reader.ReadInt32();
  65. SecondsElapsed = IPAddress.NetworkToHostOrder(reader.ReadInt16());
  66. BootpFlags = (DhcpBootpFlag)IPAddress.NetworkToHostOrder(reader.ReadInt16());
  67. ClientIpAddress = new IPAddress(reader.ReadBytes(4));
  68. YourIpAddress = new IPAddress(reader.ReadBytes(4));
  69. NextServerIpAddress = new IPAddress(reader.ReadBytes(4));
  70. RelayAgentIpAddress = new IPAddress(reader.ReadBytes(4));
  71. ClientMacAddress = reader.ReadBytes(hardwareAddressLength);
  72. stream.Position += 16 - hardwareAddressLength; // Skip padding bytes
  73. ServerHostName = Encoding.ASCII.GetString(reader.ReadBytes(64)).Trim('\0');
  74. BootFileName = Encoding.ASCII.GetString(reader.ReadBytes(128)).Trim('\0');
  75. MagicCookie = reader.ReadInt32();
  76. do
  77. {
  78. var option = reader.ReadByte();
  79. if (option == 0xFF) break;
  80. Options[(DhcpOption)option] = reader.ReadBytes(reader.ReadByte());
  81. } while (true);
  82. }
  83. public int WriteToBuffer(byte[] buffer)
  84. {
  85. using var stream = new MemoryStream(buffer);
  86. using var writer = new BinaryWriter(stream);
  87. writer.Write((byte)OpCode);
  88. writer.Write((byte)HardwareType);
  89. writer.Write((byte)ClientMacAddress.Length);
  90. writer.Write(Hops);
  91. writer.Write(TransactionId);
  92. writer.Write(IPAddress.HostToNetworkOrder(SecondsElapsed));
  93. writer.Write(IPAddress.HostToNetworkOrder((short)BootpFlags));
  94. writer.Write(ClientIpAddress.GetAddressBytes());
  95. writer.Write(YourIpAddress.GetAddressBytes());
  96. writer.Write(NextServerIpAddress.GetAddressBytes());
  97. writer.Write(RelayAgentIpAddress.GetAddressBytes());
  98. writer.Write(ClientMacAddress);
  99. stream.Position += 16 - ClientMacAddress.Length;
  100. var buf = Encoding.ASCII.GetBytes(ServerHostName);
  101. writer.Write(buf);
  102. stream.Position += 64 - buf.Length;
  103. buf = Encoding.ASCII.GetBytes(BootFileName);
  104. writer.Write(buf);
  105. stream.Position += 128 - buf.Length;
  106. writer.Write(MagicCookie);
  107. foreach (var option in Options)
  108. {
  109. writer.Write((byte)option.Key);
  110. writer.Write((byte)option.Value.Length);
  111. writer.Write(option.Value);
  112. }
  113. writer.Write((byte)0xFF);
  114. return (int)(stream.Position);
  115. }
  116. public DhcpPacket()
  117. {
  118. }
  119. public int GetByteCount()
  120. {
  121. throw new NotImplementedException();
  122. }
  123. }
  124. }