Преглед на файлове

commit: deal with UserClass in DHCP

HOME преди 5 години
родител
ревизия
0e2a8da845
променени са 6 файла, в които са добавени 58 реда и са изтрити 20 реда
  1. 4 1
      DhcpServer/App/DhcpPacket.cs
  2. 39 15
      DhcpServer/AppConfigs.cs
  3. 5 0
      DhcpServer/DhcpProgram.cs
  4. 1 0
      DhcpServer/Protocol/DhcpOption.cs
  5. 6 0
      DhcpServer/Protocol/DhcpPacket.cs
  6. 3 4
      TftpServer/TftpServer.csproj

+ 4 - 1
DhcpServer/App/DhcpPacket.cs

@@ -1,4 +1,5 @@
-using System.Linq;
+using System;
+using System.Linq;
 using System.Net;
 
 namespace DhcpServer
@@ -9,6 +10,8 @@ namespace DhcpServer
 
         internal void LoadClientEntry(ClientEntry entry)
         {
+            if (entry == null) throw new ArgumentNullException(nameof(entry));
+
             if (entry.IpAddress != null) YourIpAddress = IPAddress.Parse(entry.IpAddress);
             if (entry.SubNetMask != null) SubNetMask = IPAddress.Parse(entry.SubNetMask);
             if (entry.GateWay != null) Router = IPAddress.Parse(entry.GateWay);

+ 39 - 15
DhcpServer/AppConfigs.cs

@@ -1,39 +1,63 @@
-using System;
+using Newtonsoft.Json;
+using System;
+using System.Collections.Generic;
 using System.IO;
-using Newtonsoft.Json;
+using System.Text;
 
 namespace DhcpServer
 {
     internal static class AppConfigs
     {
-        private const string DefaultConfigFileName = "Default.json";
+        private static readonly string ConfigFileDir = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Configs");
 
-        public static readonly string ConfigFileDir = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Configs");
-        public static readonly string DefaultConfigFilePath = Path.Combine(ConfigFileDir, DefaultConfigFileName);
+        private static readonly HashSet<char> InvalidFileNameChars = new HashSet<char>(Path.GetInvalidFileNameChars());
 
-        public static string GetClientEntryPath(string mac)
+        private static string FilterUserClass(string input)
         {
-            return Path.Combine(ConfigFileDir, mac + ".json");
+            if (input == null) return null;
+
+            var sb = new StringBuilder(input);
+            for (int i = 0; i < sb.Length; i++)
+            {
+                if (InvalidFileNameChars.Contains(sb[i])) sb[i] = '_';
+            }
+
+            sb.Insert(0, '-');
+            return sb.ToString();
+        }
+
+        private static string GetClientEntryPath(string mac, string userClass = null)
+        {
+            return Path.Combine(ConfigFileDir, mac + FilterUserClass(userClass) + ".json");
+        }
+
+        private static string GetDefaultEntryPath(string userClass = null)
+        {
+            return Path.Combine(ConfigFileDir, "Default" + FilterUserClass(userClass) + ".json");
         }
 
         public static bool CreateDefaultClientEntryIfNoExist()
         {
-            if (File.Exists(DefaultConfigFilePath)) return false;
+            var path = GetDefaultEntryPath();
+            if (File.Exists(path)) return false;
             if (false == Directory.Exists(ConfigFileDir)) Directory.CreateDirectory(ConfigFileDir);
-            File.WriteAllText(DefaultConfigFilePath, JsonConvert.SerializeObject(new ClientEntry(), Formatting.Indented));
+            File.WriteAllText(path, JsonConvert.SerializeObject(new ClientEntry(), Formatting.Indented));
             return true;
         }
 
-        public static ClientEntry GetDefaultClientEntry()
+        public static ClientEntry GetDefaultClientEntry(string userClass = null)
         {
-            return File.Exists(DefaultConfigFilePath)
-                ? JsonConvert.DeserializeObject<ClientEntry>(File.ReadAllText(DefaultConfigFilePath))
-                : null;
+            var path = GetDefaultEntryPath(userClass);
+            if (File.Exists(path)) return JsonConvert.DeserializeObject<ClientEntry>(File.ReadAllText(path));
+            
+            var createNew = new ClientEntry();
+            File.WriteAllText(path, JsonConvert.SerializeObject(new ClientEntry(), Formatting.Indented));
+            return createNew;
         }
 
-        public static ClientEntry GetClientEntry(string mac)
+        public static ClientEntry GetClientEntry(string mac, string userClass = null)
         {
-            var path = GetClientEntryPath(mac);
+            var path = GetClientEntryPath(mac, userClass);
             if (File.Exists(path)) return JsonConvert.DeserializeObject<ClientEntry>(File.ReadAllText(path));
 
             var createNew = new ClientEntry();

+ 5 - 0
DhcpServer/DhcpProgram.cs

@@ -105,11 +105,16 @@ namespace DhcpServer
 
                             if (reply != DhcpMessageType.Unknown)
                             {
+                                var userClass = packet.UserClass;
                                 packet.Options.Clear();
                                 packet.DhcpServerIdentifier = listenEndPoint.Address;
                                 packet.MessageType = reply;
+
                                 packet.LoadClientEntry(AppConfigs.GetDefaultClientEntry());
+                                packet.LoadClientEntry(AppConfigs.GetDefaultClientEntry(userClass));
+
                                 packet.LoadClientEntry(entry);
+                                packet.LoadClientEntry(AppConfigs.GetClientEntry(mac, userClass));
 
                                 bytes = packet.WriteToBuffer(buffer);
                                 var to = new IPEndPoint(IPAddress.Broadcast, 68);

+ 1 - 0
DhcpServer/Protocol/DhcpOption.cs

@@ -8,5 +8,6 @@
         DhcpMessageType = 53,
         DhcpServerIdentifier = 54,
         TftpServer = 66,
+        UserClass = 77,
     }
 }

+ 6 - 0
DhcpServer/Protocol/DhcpPacket.cs

@@ -71,6 +71,12 @@ namespace DhcpServer
             set => Options[DhcpOption.DhcpServerIdentifier] = value.GetAddressBytes();
         }
 
+        public string UserClass
+        {
+            get => Options.MapValue(DhcpOption.UserClass, value => Encoding.ASCII.GetString(value));
+            set => Options[DhcpOption.UserClass] = Encoding.ASCII.GetBytes(value);
+        }
+
         public DhcpPacket(byte[] buffer)
         {
             using var stream = new MemoryStream(buffer);

+ 3 - 4
TftpServer/TftpServer.csproj

@@ -60,10 +60,6 @@
     <Compile Include="Utils\ExtensionMethods.cs" />
   </ItemGroup>
   <ItemGroup>
-    <None Include="..\..\..\PxeWorkingSpace\sample1\ipxe-bin\undionly.kpxe">
-      <Link>Root\undionly.kpxe</Link>
-      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
-    </None>
     <None Include="App.config" />
     <None Include="Properties\Settings.settings">
       <Generator>SettingsSingleFileGenerator</Generator>
@@ -76,5 +72,8 @@
       <Name>Utils</Name>
     </ProjectReference>
   </ItemGroup>
+  <ItemGroup>
+    <Folder Include="Root\" />
+  </ItemGroup>
   <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
 </Project>