DhcpProgram.cs 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144
  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 (DhcpEntryManager.CreateDefaultEntryIfNoExist()) 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. var pooled = false;
  44. while (_isRunning)
  45. {
  46. Console.CursorLeft = 0;
  47. if (false == socket.Poll(500 * 1000, SelectMode.SelectRead))
  48. {
  49. var timeSpan = DateTime.Now - polling;
  50. var up = DateTime.Now - upTime;
  51. Console.Write("Polling sockets..." +
  52. $" {timeSpan.Days:00}D {timeSpan.Hours:00}H {timeSpan.Minutes:00}M {timeSpan.Seconds:00}S {timeSpan.Milliseconds:000}" +
  53. $" / UP {up.Days:00}D {up.Hours:00}H {up.Minutes:00}M {up.Seconds:00}S {up.Milliseconds:000}");
  54. pooled = true;
  55. }
  56. else
  57. {
  58. polling = DateTime.Now;
  59. if (pooled)
  60. {
  61. pooled = false;
  62. Console.WriteLine();
  63. }
  64. var bytes = socket.ReceiveFrom(buffer, 0, buffer.Length, SocketFlags.None, ref remoteEndPoint);
  65. Console.Write($"Receive {bytes} byte From {remoteEndPoint}");
  66. try
  67. {
  68. var packet = new DhcpPacket(buffer);
  69. var mac = packet.ClientMacAddressHex;
  70. Console.Write($" {packet.MessageType} by {mac}");
  71. var entry = DhcpEntryManager.GetClientEntry(mac);
  72. if (entry.Enable == false)
  73. {
  74. Console.WriteLine(" ** No enabled, please edit config file.");
  75. }
  76. else
  77. {
  78. packet.OpCode = DhcpOpCode.BootReply;
  79. DhcpMessageType reply;
  80. switch (packet.MessageType)
  81. {
  82. default:
  83. reply = DhcpMessageType.Unknown;
  84. break;
  85. case DhcpMessageType.Discover:
  86. reply = DhcpMessageType.Offer;
  87. break;
  88. case DhcpMessageType.Request:
  89. reply = DhcpMessageType.Ack;
  90. break;
  91. }
  92. if (reply != DhcpMessageType.Unknown)
  93. {
  94. var userClass = packet.UserClass;
  95. packet.Options.Clear();
  96. packet.DhcpServerIdentifier = listenEndPoint.Address;
  97. packet.MessageType = reply;
  98. packet.LoadClientEntry(DhcpEntryManager.GetDefaultEntry());
  99. packet.LoadClientEntry(DhcpEntryManager.GetDefaultEntry(userClass));
  100. packet.LoadClientEntry(entry);
  101. packet.LoadClientEntry(DhcpEntryManager.GetClientEntry(mac, userClass));
  102. bytes = packet.WriteToBuffer(buffer);
  103. var to = new IPEndPoint(IPAddress.Broadcast, 68);
  104. Console.WriteLine();
  105. Console.WriteLine($"Send {bytes} bytes to {to} {packet.MessageType} by {mac}");
  106. socket.SendTo(buffer, 0, bytes, SocketFlags.None, to);
  107. }
  108. }
  109. }
  110. catch (Exception e)
  111. {
  112. Console.WriteLine(e);
  113. }
  114. }
  115. }
  116. socket.Close();
  117. }
  118. }
  119. }