DhcpProgram.cs 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132
  1. using System;
  2. using System.Net;
  3. using System.Net.Sockets;
  4. using System.Threading;
  5. namespace DhcpServer
  6. {
  7. internal class DhcpProgram
  8. {
  9. private static bool _isRunning;
  10. private static void Main(string[] args)
  11. {
  12. Console.WriteLine("Starting...");
  13. if (AppConfigs.CreateDefaultClientEntryIfNoExist()) Console.WriteLine("Default client entry config created.");
  14. var tWorker = new Thread(Working);
  15. _isRunning = true;
  16. tWorker.Start();
  17. Console.WriteLine("Press ENTER to Stop.");
  18. Console.ReadLine();
  19. Console.Write("Shutting down...");
  20. _isRunning = false;
  21. tWorker.Join();
  22. Console.Write("Stopped.");
  23. Console.WriteLine();
  24. Console.Write("Press ENTER to Exit.");
  25. Console.ReadLine();
  26. }
  27. private static void Working(object obj)
  28. {
  29. var listenEndPoint = new IPEndPoint(IPAddress.Parse(Properties.Settings.Default.ListenOn), 67);
  30. var socket = new Socket(listenEndPoint.AddressFamily, SocketType.Dgram, ProtocolType.Udp)
  31. {
  32. EnableBroadcast = true,
  33. SendBufferSize = 65536,
  34. ReceiveBufferSize = 65536
  35. };
  36. socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, 1);
  37. socket.Bind(listenEndPoint);
  38. var upTime = DateTime.Now;
  39. Console.WriteLine($"DHCP Server started, listing on: {listenEndPoint}");
  40. var buffer = new byte[65536];
  41. EndPoint remoteEndPoint = new IPEndPoint(IPAddress.Any, 68);
  42. var polling = DateTime.Now;
  43. while (_isRunning)
  44. {
  45. Console.CursorLeft = 0;
  46. if (false == socket.Poll(500 * 1000, SelectMode.SelectRead))
  47. {
  48. var timeSpan = DateTime.Now - polling;
  49. var up = DateTime.Now - upTime;
  50. Console.Write($"Polling..." +
  51. $" {timeSpan.Days:00}D {timeSpan.Hours:00}H {timeSpan.Minutes:00}M {timeSpan.Seconds:00}S {timeSpan.Milliseconds:000}" +
  52. $" / UP {up.Days:00}D {up.Hours:00}H {up.Minutes:00}M {up.Seconds:00}S {up.Milliseconds:000}");
  53. }
  54. else
  55. {
  56. polling = DateTime.Now;
  57. Console.WriteLine();
  58. var bytes = socket.ReceiveFrom(buffer, 0, buffer.Length, SocketFlags.None, ref remoteEndPoint);
  59. Console.Write($"Receive {bytes} byte From {remoteEndPoint}");
  60. try
  61. {
  62. var packet = new DhcpPacket(buffer);
  63. var mac = packet.ClientMacAddressHex;
  64. Console.Write($" {packet.MessageType} by {mac}");
  65. var entry = AppConfigs.GetClientEntry(mac);
  66. if (entry.Enable == false)
  67. {
  68. Console.WriteLine(" ** No enabled, please edit config file.");
  69. }
  70. else
  71. {
  72. packet.OpCode = DhcpOpCode.BootReply;
  73. DhcpMessageType reply;
  74. switch (packet.MessageType)
  75. {
  76. default:
  77. reply = DhcpMessageType.Unknown;
  78. break;
  79. case DhcpMessageType.Discover:
  80. reply = DhcpMessageType.Offer;
  81. break;
  82. case DhcpMessageType.Request:
  83. reply = DhcpMessageType.Ack;
  84. break;
  85. }
  86. if (reply != DhcpMessageType.Unknown)
  87. {
  88. packet.Options.Clear();
  89. packet.DhcpServerIdentifier = listenEndPoint.Address;
  90. packet.MessageType = reply;
  91. packet.LoadClientEntry(AppConfigs.GetDefaultClientEntry());
  92. packet.LoadClientEntry(entry);
  93. bytes = packet.WriteToBuffer(buffer);
  94. var to = new IPEndPoint(IPAddress.Broadcast, 68);
  95. Console.WriteLine();
  96. Console.WriteLine($"Send {bytes} bytes to {to} {packet.MessageType} by {mac}");
  97. socket.SendTo(buffer, 0, bytes, SocketFlags.None, to);
  98. }
  99. }
  100. }
  101. catch (Exception e)
  102. {
  103. Console.WriteLine(e);
  104. }
  105. }
  106. }
  107. socket.Close();
  108. }
  109. }
  110. }